1 ;;- Machine description for ROMP chip for GNU C compiler
2 ;; Copyright (C) 1988, 1991 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@nyu.edu)
5 ;; This file is part of GNU CC.
7 ;; GNU CC 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 ;; GNU CC 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 GNU CC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; Define the attributes for the ROMP.
26 ;; Insn type. Used to default other attribute values.
29 "branch,return,fp,load,loadz,store,call,address,arith,compare,multi,misc"
30 (const_string "arith"))
34 (define_attr "length" ""
35 (cond [(eq_attr "type" "branch")
36 (if_then_else (and (ge (minus (pc) (match_dup 0))
38 (le (minus (pc) (match_dup 0))
42 (eq_attr "type" "return") (const_int 2)
43 (eq_attr "type" "fp") (const_int 10)
44 (eq_attr "type" "call") (const_int 4)
45 (eq_attr "type" "load")
46 (cond [(match_operand 1 "short_memory_operand" "") (const_int 2)
47 (match_operand 1 "symbolic_memory_operand" "") (const_int 8)]
49 (eq_attr "type" "loadz")
50 (cond [(match_operand 1 "zero_memory_operand" "") (const_int 2)
51 (match_operand 1 "symbolic_memory_operand" "") (const_int 8)]
53 (eq_attr "type" "store")
54 (cond [(match_operand 0 "short_memory_operand" "") (const_int 2)
55 (match_operand 0 "symbolic_memory_operand" "") (const_int 8)]
59 ;; Whether insn can be placed in a delay slot.
61 (define_attr "in_delay_slot" "yes,no"
62 (cond [(eq_attr "length" "8,10,38") (const_string "no")
63 (eq_attr "type" "branch,return,call,multi") (const_string "no")]
64 (const_string "yes")))
66 ;; Whether insn needs a delay slot.
67 (define_attr "needs_delay_slot" "yes,no"
68 (if_then_else (eq_attr "type" "branch,return,call")
69 (const_string "yes") (const_string "no")))
71 ;; What insn does to the condition code.
74 "clobber,none,sets,change0,copy1to0,compare,tbit"
75 (cond [(eq_attr "type" "load,loadz") (const_string "change0")
76 (eq_attr "type" "store") (const_string "none")
77 (eq_attr "type" "fp,call") (const_string "clobber")
78 (eq_attr "type" "branch,return") (const_string "none")
79 (eq_attr "type" "address") (const_string "change0")
80 (eq_attr "type" "compare") (const_string "compare")
81 (eq_attr "type" "arith") (const_string "sets")]
82 (const_string "clobber")))
84 ;; Define attributes for `asm' insns.
86 (define_asm_attributes [(set_attr "type" "misc")
87 (set_attr "length" "8")
88 (set_attr "in_delay_slot" "no")
89 (set_attr "cc" "clobber")])
91 ;; Define the delay slot requirements for branches and calls. We don't have
92 ;; any annulled insns.
94 (define_delay (eq_attr "needs_delay_slot" "yes")
95 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
97 ;; We cannot give a floating-point comparison a delay slot, even though it
98 ;; could make use of it. This is because it would confuse next_cc0_user
99 ;; to do so. Other fp insns can't get a delay slow because they set their
100 ;; result and use their input after the delay slot insn is executed. This
101 ;; isn't what reorg.c expects.
103 ;; Define load & store delays. These were obtained by measurements done by
104 ;; jfc@athena.mit.edu.
106 ;; In general, the memory unit can support at most two simultaneous operations.
108 ;; Loads take 5 cycles to return the data and can be pipelined up to the
109 ;; limit of two simultaneous operations.
110 (define_function_unit "memory" 1 2 (eq_attr "type" "load,loadz") 5 0)
112 ;; Stores do not return data, but tie up the memory unit for 2 cycles if the
113 ;; next insn is also a store.
114 (define_function_unit "memory" 1 2 (eq_attr "type" "store") 1 2
115 [(eq_attr "type" "store")])
117 ;; Move word instructions.
119 ;; If destination is memory but source is not register, force source to
122 ;; If source is a constant that is too large to load in a single insn, build
125 ;; If destination is memory and source is a register, a temporary register
126 ;; will be needed. In that case, make a PARALLEL of the SET and a
127 ;; CLOBBER of a SCRATCH to allocate the required temporary.
129 ;; This temporary is ACTUALLY only needed when the destination is a
130 ;; relocatable expression. For generating RTL, however, we always
131 ;; place the CLOBBER. In insns where it is not needed, the SCRATCH will
132 ;; not be allocated to a register.
134 ;; Also, avoid creating pseudo-registers or SCRATCH rtx's during reload as
135 ;; they will not be correctly handled. We never need pseudos for that
138 ;; We do not use DEFINE_SPLIT for loading constants because the number
139 ;; of cases in the resulting unsplit insn would be too high to deal
141 (define_expand "movsi"
142 [(set (match_operand:SI 0 "general_operand" "")
143 (match_operand:SI 1 "general_operand" ""))]
146 { rtx op0 = operands[0];
147 rtx op1 = operands[1];
149 if (GET_CODE (op1) == REG && REGNO (op1) == 16)
152 if (GET_CODE (op0) == REG && REGNO (op0) == 16)
155 if (GET_CODE (op0) == MEM && ! reload_in_progress)
157 emit_insn (gen_storesi (operands[0], force_reg (SImode, operands[1])));
160 else if (GET_CODE (op1) == CONST_INT)
162 int const_val = INTVAL (op1);
164 /* Try a number of cases to see how to best load the constant. */
165 if ((const_val & 0xffff) == 0
166 || (const_val & 0xffff0000) == 0
167 || (unsigned) (const_val + 0x8000) < 0x10000)
168 /* Can do this in one insn, so generate it. */
170 else if (((- const_val) & 0xffff) == 0
171 || ((- const_val) & 0xffff0000) == 0
172 || (unsigned) ((- const_val) + 0x8000) < 0x10000)
174 /* Can do this by loading the negative constant and then negating. */
175 emit_move_insn (operands[0],
176 gen_rtx (CONST_INT, VOIDmode, - const_val));
177 emit_insn (gen_negsi2 (operands[0], operands[0]));
181 /* Do this the long way. */
183 unsigned int high_part = const_val & 0xffff0000;
184 unsigned int low_part = const_val & 0xffff;
187 if (low_part >= 0x10 && exact_log2 (low_part) >= 0)
188 i = high_part, high_part = low_part, low_part = i;
190 emit_move_insn (operands[0],
191 gen_rtx (CONST_INT, VOIDmode, low_part));
192 emit_insn (gen_iorsi3 (operands[0], operands[0],
193 gen_rtx (CONST_INT, VOIDmode, high_part)));
199 ;; Move from a symbolic memory location to a register is special. In this
200 ;; case, we know in advance that the register cannot be r0, so we can improve
201 ;; register allocation by treating it separately.
204 [(set (match_operand:SI 0 "register_operand" "=b")
205 (match_operand:SI 1 "symbolic_memory_operand" "m"))]
208 [(set_attr "type" "load")])
210 ;; Generic single-word move insn. We avoid the case where the destination is
211 ;; a symbolic address, as that needs a temporary register.
214 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,r,r,r,b,Q")
215 (match_operand:SI 1 "romp_operand" "rR,I,K,L,M,S,s,Q,m,r"))]
216 "register_operand (operands[0], SImode)
217 || register_operand (operands[1], SImode)"
229 [(set_attr "type" "address,address,address,address,address,arith,misc,load,load,store")
230 (set_attr "length" "2,2,4,4,4,4,8,*,*,*")])
232 (define_insn "storesi"
233 [(set (match_operand:SI 0 "memory_operand" "=Q,m")
234 (match_operand:SI 1 "register_operand" "r,r"))
235 (clobber (match_scratch:SI 2 "=X,&b"))]
240 [(set_attr "type" "store")])
242 ;; This pattern is used by reload when we store into a symbolic address. It
243 ;; provides the temporary register required. This pattern is only used
244 ;; when SECONDARY_OUTPUT_RELOAD_CLASS returns something other than
245 ;; NO_REGS, so we need not have any predicates here.
247 (define_expand "reload_outsi"
248 [(parallel [(set (match_operand:SI 0 "symbolic_memory_operand" "=m")
249 (match_operand:SI 1 "" "r"))
250 (clobber (match_operand:SI 2 "" "=&b"))])]
254 ;; Now do the same for the QI move instructions.
255 (define_expand "movqi"
256 [(set (match_operand:QI 0 "general_operand" "")
257 (match_operand:QI 1 "general_operand" ""))]
260 { rtx op0 = operands[0];
262 if (GET_CODE (op0) == MEM && ! reload_in_progress)
264 emit_insn (gen_storeqi (operands[0], force_reg (QImode, operands[1])));
270 [(set (match_operand:QI 0 "register_operand" "=b")
271 (match_operand:QI 1 "symbolic_memory_operand" "m"))]
274 [(set_attr "type" "load")])
277 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,b,Q")
278 (match_operand:QI 1 "romp_operand" "r,I,n,s,Q,m,r"))]
279 "register_operand (operands[0], QImode)
280 || register_operand (operands[1], QImode)"
289 [(set_attr "type" "address,address,address,misc,load,load,store")
290 (set_attr "length" "2,2,4,8,*,*,*")])
292 (define_insn "storeqi"
293 [(set (match_operand:QI 0 "memory_operand" "=Q,m")
294 (match_operand:QI 1 "register_operand" "r,r"))
295 (clobber (match_scratch:SI 2 "=X,&b"))]
300 [(set_attr "type" "store")])
302 (define_expand "reload_outqi"
303 [(set (match_operand:QI 0 "symbolic_memory_operand" "=m")
304 (match_operand:QI 1 "" "r"))
305 (match_operand:SI 2 "" "=&b")]
309 ;; Finally, the HI instructions.
310 (define_expand "movhi"
311 [(set (match_operand:HI 0 "general_operand" "")
312 (match_operand:HI 1 "general_operand" ""))]
315 { rtx op0 = operands[0];
317 if (GET_CODE (op0) == MEM && ! reload_in_progress)
319 emit_insn (gen_storehi (operands[0], force_reg (HImode, operands[1])));
325 [(set (match_operand:HI 0 "register_operand" "=b")
326 (match_operand:HI 1 "symbolic_memory_operand" "m"))]
329 [(set_attr "type" "load")])
332 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,b,Q")
333 (match_operand:HI 1 "romp_operand" "r,I,n,s,Q,m,r"))]
334 "register_operand (operands[0], HImode)
335 || register_operand (operands[1], HImode)"
344 [(set_attr "type" "address,address,address,misc,loadz,loadz,store")
345 (set_attr "length" "2,2,4,8,*,*,*")])
347 (define_insn "storehi"
348 [(set (match_operand:HI 0 "memory_operand" "=Q,m")
349 (match_operand:HI 1 "register_operand" "r,r"))
350 (clobber (match_scratch:SI 2 "=X,&b"))]
355 [(set_attr "type" "store")])
357 (define_expand "reload_outhi"
358 [(set (match_operand:HI 0 "symbolic_memory_operand" "=m")
359 (match_operand:HI 1 "" "r"))
360 (match_operand:SI 2 "" "=&b")]
364 ;; For DI move, if we have a constant, break the operation apart into
365 ;; two SImode moves because the optimizer may be able to do a better job
366 ;; with the resulting code.
368 ;; For memory stores, make the required pseudo for a temporary in case we
369 ;; are storing into an absolute address.
371 ;; We need to be careful about the cases where the output is a register that is
372 ;; the second register of the input.
374 (define_expand "movdi"
375 [(set (match_operand:DI 0 "general_operand" "")
376 (match_operand:DI 1 "general_operand" ""))]
379 { rtx op0 = operands[0];
380 rtx op1 = operands[1];
382 if (CONSTANT_P (op1))
387 emit_move_insn (operand_subword (op0, 0, 1, DImode),
388 operand_subword (op1, 0, 1, DImode));
389 emit_move_insn (operand_subword (op0, 1, 1, DImode),
390 operand_subword (op1, 1, 1, DImode));
391 insns = get_insns ();
394 emit_no_conflict_block (insns, op0, op1, 0, op1);
398 if (GET_CODE (op0) == MEM && ! reload_in_progress)
400 emit_insn (gen_storedi (operands[0], force_reg (DImode, operands[1])));
406 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
407 (match_operand:DI 1 "reg_or_mem_operand" "r,Q,m,r"))]
408 "register_operand (operands[0], DImode)
409 || register_operand (operands[1], DImode)"
412 switch (which_alternative)
415 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
416 return \"cas %O0,%O1,r0\;cas %0,%1,r0\";
418 return \"cas %0,%1,r0\;cas %O0,%O1,r0\";
420 /* Here we must see which word to load first. We default to the
421 low-order word unless it occurs in the address. */
422 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
424 return \"l%M1 %O0,%O1\;l%M1 %0,%1\";
426 return \"l%M1 %0,%1\;l%M1 %O0,%O1\";
428 return \"get %O0,$%1\;ls %0,0(%O0)\;ls %O0,4(%O0)\";
430 return \"st%M0 %1,%0\;st%M0 %O1,%O0\";
433 [(set_attr "type" "multi")
434 (set_attr "cc" "change0,change0,change0,none")
435 (set_attr "length" "4,12,8,8")])
437 (define_insn "storedi"
438 [(set (match_operand:DI 0 "memory_operand" "=Q,m")
439 (match_operand:DI 1 "register_operand" "r,r"))
440 (clobber (match_scratch:SI 2 "=X,&b"))]
443 st%M0 %1,%0\;st%M0 %O1,%O0
444 get %2,$%0\;sts %1,0(%2)\;sts %O1,4(%2)"
445 [(set_attr "type" "multi,multi")
446 (set_attr "cc" "none,none")
447 (set_attr "length" "8,12")])
449 (define_expand "reload_outdi"
450 [(set (match_operand:DI 0 "symbolic_memory_operand" "=m")
451 (match_operand:DI 1 "" "r"))
452 (match_operand:SI 2 "" "=&b")]
456 ;; Split symbolic memory operands differently. We first load the address
457 ;; into a register and then do the two loads or stores. We can only do
458 ;; this if operand_subword won't produce a SUBREG, which is only when
459 ;; operands[0] is a hard register. Thus, these won't be used during the
460 ;; first insn scheduling pass.
462 [(set (match_operand:DI 0 "register_operand" "")
463 (match_operand:DI 1 "symbolic_memory_operand" ""))]
464 "GET_CODE (operands[0]) == REG
465 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER"
466 [(set (match_dup 2) (match_dup 3))
467 (set (match_dup 4) (match_dup 5))
468 (set (match_dup 6) (match_dup 7))]
470 { operands[2] = operand_subword (operands[0], 1, 0, DImode);
471 operands[3] = XEXP (operands[1], 0);
472 operands[4] = operand_subword (operands[0], 0, 0, DImode);
473 operands[5] = gen_rtx (MEM, SImode, operands[2]);
474 operands[6] = operands[2];
475 operands[7] = gen_rtx (MEM, SImode,
476 gen_rtx (PLUS, SImode, operands[2],
477 gen_rtx (CONST_INT, VOIDmode, 4)));
479 if (operands[2] == 0 || operands[4] == 0)
484 [(set (match_operand:DI 0 "symbolic_memory_operand" "")
485 (match_operand:DI 1 "register_operand" ""))
486 (clobber (match_operand:SI 2 "register_operand" ""))]
487 "GET_CODE (operands[0]) == REG
488 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER"
489 [(set (match_dup 2) (match_dup 3))
490 (set (match_dup 4) (match_dup 5))
491 (set (match_dup 6) (match_dup 7))]
493 { operands[3] = XEXP (operands[0], 0);
494 operands[4] = gen_rtx (MEM, SImode, operands[2]);
495 operands[5] = operand_subword (operands[1], 0, 0, DImode);
496 operands[6] = gen_rtx (MEM, SImode,
497 gen_rtx (PLUS, SImode, operands[2],
498 gen_rtx (CONST_INT, VOIDmode, 4)));
499 operands[7] = operand_subword (operands[1], 1, 0, DImode);
501 if (operands[5] == 0 || operands[7] == 0)
505 ;; If the output is a register and the input is memory, we have to be careful
506 ;; and see which word needs to be loaded first.
508 ;; Note that this case doesn't have a CLOBBER. Therefore, we must either
509 ;; be after reload or operand[0] must not be a MEM. So we don't need a
510 ;; CLOBBER on the new insns either.
512 ;; Due to a bug in sched.c, we do not want to split this insn if both
513 ;; operands are registers and they overlap unless reload has completed.
515 [(set (match_operand:DI 0 "general_operand" "")
516 (match_operand:DI 1 "general_operand" ""))]
517 "! symbolic_memory_operand (operands[0], DImode)
518 && ! symbolic_memory_operand (operands[1], DImode)
519 && ! (GET_CODE (operands[0]) == REG
520 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
521 && ! (GET_CODE (operands[1]) == REG
522 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
523 && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
524 && ! reload_completed
525 && reg_overlap_mentioned_p (operands[0], operands[1]))"
526 [(set (match_dup 2) (match_dup 3))
527 (set (match_dup 4) (match_dup 5))]
529 { if (GET_CODE (operands[0]) != REG
530 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
533 operands[2] = operand_subword (operands[0], 0, 0, DImode);
534 operands[3] = operand_subword (operands[1], 0, 0, DImode);
535 operands[4] = operand_subword (operands[0], 1, 0, DImode);
536 operands[5] = operand_subword (operands[1], 1, 0, DImode);
540 operands[2] = operand_subword (operands[0], 1, 0, DImode);
541 operands[3] = operand_subword (operands[1], 1, 0, DImode);
542 operands[4] = operand_subword (operands[0], 0, 0, DImode);
543 operands[5] = operand_subword (operands[1], 0, 0, DImode);
546 if (operands[2] == 0 || operands[3] == 0
547 || operands[4] == 0 || operands[5] == 0)
552 [(set (match_operand:DI 0 "general_operand" "")
553 (match_operand:DI 1 "general_operand" ""))
554 (clobber (match_operand:SI 6 "register_operand" ""))]
555 "! symbolic_memory_operand (operands[0], DImode)
556 && ! symbolic_memory_operand (operands[1], DImode)
557 && ! (GET_CODE (operands[0]) == REG
558 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
559 && ! (GET_CODE (operands[1]) == REG
560 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
561 && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
562 && ! reload_completed
563 && reg_overlap_mentioned_p (operands[0], operands[1]))"
564 [(parallel [(set (match_dup 2) (match_dup 3))
565 (clobber (match_dup 7))])
566 (parallel [(set (match_dup 4) (match_dup 5))
567 (clobber (match_dup 8))])]
569 { if (GET_CODE (operands[0]) != REG
570 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
573 operands[2] = operand_subword (operands[0], 0, 0, DImode);
574 operands[3] = operand_subword (operands[1], 0, 0, DImode);
575 operands[4] = operand_subword (operands[0], 1, 0, DImode);
576 operands[5] = operand_subword (operands[1], 1, 0, DImode);
580 operands[2] = operand_subword (operands[0], 1, 0, DImode);
581 operands[3] = operand_subword (operands[1], 1, 0, DImode);
582 operands[4] = operand_subword (operands[0], 0, 0, DImode);
583 operands[5] = operand_subword (operands[1], 0, 0, DImode);
586 if (operands[2] == 0 || operands[3] == 0
587 || operands[4] == 0 || operands[5] == 0)
590 /* We must be sure to make two different SCRATCH operands, since they
591 are not allowed to be shared. After reload, however, we only have
592 a SCRATCH if we won't use the operand, so it is allowed to share it
594 if (reload_completed || GET_CODE (operands[6]) != SCRATCH)
595 operands[7] = operands[8] = operands[6];
598 operands[7] = gen_rtx (SCRATCH, SImode);
599 operands[8] = gen_rtx (SCRATCH, SImode);
603 ;; Define move insns for SF, and DF.
605 ;; For register-register copies or a copy of something to itself, emit a
606 ;; single SET insn since it will likely be optimized away.
608 ;; Otherwise, emit a floating-point move operation unless both input and
609 ;; output are either constant, memory, or a non-floating-point hard register.
610 (define_expand "movdf"
611 [(parallel [(set (match_operand:DF 0 "general_operand" "")
612 (match_operand:DF 1 "general_operand" ""))
614 (clobber (reg:SI 15))])]
617 { rtx op0 = operands[0];
618 rtx op1 = operands[1];
622 emit_insn (gen_rtx (SET, VOIDmode, op0, op1));
626 if ((GET_CODE (op0) == MEM
627 || (GET_CODE (op0) == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER
628 && ! FP_REGNO_P (REGNO (op0))))
629 && (GET_CODE (op1) == MEM
630 || GET_CODE (op1) == CONST_DOUBLE
631 || (GET_CODE (op1) == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER
632 && ! FP_REGNO_P (REGNO (op1)) && ! rtx_equal_p (op0, op1))))
636 if (GET_CODE (op1) == CONST_DOUBLE)
637 op1 = force_const_mem (DFmode, op1);
640 if (GET_CODE (operands[0]) != REG
641 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
644 emit_move_insn (operand_subword (op0, 0, 1, DFmode),
645 operand_subword_force (op1, 0, DFmode));
646 emit_move_insn (operand_subword (op0, 1, 1, DFmode),
647 operand_subword_force (op1, 1, DFmode));
651 emit_move_insn (operand_subword (op0, 1, 1, DFmode),
652 operand_subword_force (op1, 1, DFmode));
653 emit_move_insn (operand_subword (op0, 0, 1, DFmode),
654 operand_subword_force (op1, 0, DFmode));
657 insns = get_insns ();
660 emit_no_conflict_block (insns, op0, op1, 0, op1);
665 (define_expand "movsf"
666 [(parallel [(set (match_operand:SF 0 "general_operand" "")
667 (match_operand:SF 1 "general_operand" ""))
669 (clobber (reg:SI 15))])]
672 { rtx op0 = operands[0];
673 rtx op1 = operands[1];
677 emit_insn (gen_rtx (SET, VOIDmode, op0, op1));
681 if ((GET_CODE (op0) == MEM
682 || (GET_CODE (op0) == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER
683 && ! FP_REGNO_P (REGNO (op0))))
684 && (GET_CODE (op1) == MEM
685 || GET_CODE (op1) == CONST_DOUBLE
686 || (GET_CODE (op1) == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER
687 && ! FP_REGNO_P (REGNO (op1)))))
691 if (GET_CODE (op1) == CONST_DOUBLE)
692 op1 = force_const_mem (SFmode, op1);
694 last = emit_move_insn (operand_subword (op0, 0, 1, SFmode),
695 operand_subword_force (op1, 0, SFmode));
697 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, op1, REG_NOTES (last));
702 ;; Define the move insns for SF and DF. Check for all general regs
703 ;; in the FP insns and make them non-FP if so. Do the same if the input and
704 ;; output are the same (the insn will be deleted in this case and we don't
705 ;; want to think there are FP insns when there might not be).
707 [(set (match_operand:SF 0 "general_operand" "=*frg")
711 [(set_attr "type" "address")
712 (set_attr "length" "2")])
715 [(set (match_operand:SF 0 "general_operand" "=r,*fr,r,r,Q,m,frg")
716 (match_operand:SF 1 "general_operand" "r,0,Q,m,r,r,frg"))
717 (clobber (match_operand:SI 2 "reg_0_operand" "=&z,z,z,z,z,z,z"))
718 (clobber (match_operand:SI 3 "reg_15_operand" "=&t,t,t,t,t,t,t"))]
721 { switch (which_alternative)
724 return \"cas %0,%1,r0\";
728 return \"l%M1 %0,%1\";
730 return \"load %0,%1\";
732 return \"st%M0 %1,%0\";
734 return \"store %1,%0,%3\";
736 return output_fpop (SET, operands[0], operands[1], 0, insn);
739 [(set_attr "type" "address,address,load,load,store,store,fp")
740 (set_attr "length" "2,2,*,*,*,*,*")])
743 [(set (match_operand:DF 0 "general_operand" "=*frg")
747 [(set_attr "type" "address")
748 (set_attr "length" "2")])
751 [(set (match_operand:DF 0 "general_operand" "=r,*fr,r,r,Q,m,frg")
752 (match_operand:DF 1 "general_operand" "r,0,Q,m,r,r,*frg"))
753 (clobber (match_operand:SI 2 "reg_0_operand" "=&z,z,z,z,z,z,z"))
754 (clobber (match_operand:SI 3 "reg_15_operand" "=&t,t,t,t,t,t,t"))]
757 { switch (which_alternative)
760 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
761 return \"cas %O0,%O1,r0\;cas %0,%1,r0\";
763 return \"cas %0,%1,r0\;cas %O0,%O1,r0\";
767 /* Here we must see which word to load first. We default to the
768 low-order word unless it occurs in the address. */
769 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
771 return \"l%M1 %O0,%O1\;l%M1 %0,%1\";
773 return \"l%M1 %0,%1\;l%M1 %O0,%O1\";
775 return \"get %3,$%1\;ls %0,0(%3)\;ls %O0,4(%3)\";
777 return \"st%M0 %1,%0\;st%M0 %O1,%O0\";
779 return \"get %3,$%0\;sts %1,0(%3)\;sts %O1,4(%3)\";
781 return output_fpop (SET, operands[0], operands[1], 0, insn);
784 [(set_attr "type" "address,multi,multi,multi,multi,multi,fp")
785 (set_attr "length" "2,4,*,*,*,*,*")])
787 ;; Split all the above cases that involve multiple insns and no floating-point
788 ;; data block. If before reload, we can make a SCRATCH. Otherwise, use
792 [(set (match_operand:DF 0 "register_operand" "")
793 (match_operand:DF 1 "symbolic_memory_operand" ""))
795 (clobber (reg:SI 15))]
796 "GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 16"
797 [(set (reg:SI 15) (match_dup 2))
798 (set (match_dup 3) (match_dup 4))
799 (set (match_dup 5) (match_dup 6))]
801 { operands[2] = XEXP (operands[1], 0);
802 operands[3] = operand_subword (operands[0], 0, 0, DFmode);
803 operands[4] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 15));
804 operands[5] = operand_subword (operands[0], 0, 1, DFmode);
805 operands[6] = gen_rtx (MEM, SImode,
806 gen_rtx (PLUS, SImode, gen_rtx (REG, SImode, 15),
807 gen_rtx (CONST_INT, VOIDmode, 4)));
809 if (operands[3] == 0 || operands[5] == 0)
814 [(set (match_operand:DF 0 "symbolic_memory_operand" "")
815 (match_operand:DF 1 "register_operand" ""))
817 (clobber (reg:SI 15))]
818 "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 16"
819 [(set (reg:SI 15) (match_dup 2))
820 (set (match_dup 3) (match_dup 4))
821 (set (match_dup 5) (match_dup 6))]
823 { operands[2] = XEXP (operands[0], 0);
824 operands[3] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 15));
825 operands[4] = operand_subword (operands[1], 0, 0, DFmode);
826 operands[5] = gen_rtx (MEM, SImode,
827 gen_rtx (PLUS, SImode, gen_rtx (REG, SImode, 15),
828 gen_rtx (CONST_INT, VOIDmode, 4)));
829 operands[6] = operand_subword (operands[1], 1, 0, DFmode);
831 if (operands[4] == 0 || operands[6] == 0)
835 ;; If the output is a register and the input is memory, we have to be careful
836 ;; and see which word needs to be loaded first. We also cannot to the
837 ;; split if the input is a constant because it would result in invalid
838 ;; insns. When the output is a MEM, we must put a CLOBBER on each of the
839 ;; resulting insn, when it is not a MEM, we must not.
841 [(set (match_operand:DF 0 "memory_operand" "")
842 (match_operand:DF 1 "register_operand" ""))
844 (clobber (reg:SI 15))]
845 "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 15"
846 [(parallel [(set (match_dup 2) (match_dup 3))
847 (clobber (match_dup 6))])
848 (parallel [(set (match_dup 4) (match_dup 5))
849 (clobber (match_dup 7))])]
851 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
852 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
853 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
854 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
856 if (operands[2] == 0 || operands[3] == 0
857 || operands[4] == 0 || operands[5] == 0)
860 if (reload_completed)
861 operands[6] = operands[7] = gen_rtx (REG, SImode, 15);
864 operands[6] = gen_rtx (SCRATCH, SImode);
865 operands[7] = gen_rtx (SCRATCH, SImode);
870 [(set (match_operand:DF 0 "nonmemory_operand" "")
871 (match_operand:DF 1 "general_operand" ""))
873 (clobber (reg:SI 15))]
874 "! symbolic_memory_operand (operands[1], DFmode)
875 && GET_CODE (operands[1]) != CONST_DOUBLE
876 && (GET_CODE (operands[0]) != REG || REGNO (operands[0]) < 15)
877 && (GET_CODE (operands[1]) != REG || REGNO (operands[1]) < 15)
878 && (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
879 && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
880 && ! reload_completed
881 && reg_overlap_mentioned_p (operands[0], operands[1]))"
882 [(set (match_dup 2) (match_dup 3))
883 (set (match_dup 4) (match_dup 5))]
885 { if (GET_CODE (operands[0]) != REG
886 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
889 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
890 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
891 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
892 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
896 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
897 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
898 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
899 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
902 if (operands[2] == 0 || operands[3] == 0
903 || operands[4] == 0 || operands[5] == 0)
907 ;; Conversions from one integer mode to another.
908 ;; It is possible sometimes to sign- or zero-extend while fetching from memory.
910 ;; First, sign-extensions:
911 (define_expand "extendhisi2"
912 [(set (match_operand:SI 0 "register_operand" "")
913 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
918 [(set (match_operand:SI 0 "register_operand" "=b")
919 (sign_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))]
922 [(set_attr "type" "load")])
925 [(set (match_operand:SI 0 "register_operand" "=r,r,b")
926 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))]
932 [(set_attr "type" "arith,load,load")
933 (set_attr "length" "2,*,*")])
935 (define_expand "extendqisi2"
937 (ashift:SI (match_operand:QI 1 "register_operand" "")
939 (set (match_operand:SI 0 "register_operand" "")
940 (ashiftrt:SI (match_dup 2)
944 { operands[1] = gen_lowpart (SImode, operands[1]);
945 operands[2] = gen_reg_rtx (SImode); }")
947 (define_expand "extendqihi2"
949 (ashift:SI (match_operand:QI 1 "register_operand" "")
951 (set (match_operand:HI 0 "register_operand" "")
952 (ashiftrt:SI (match_dup 2)
956 { operands[0] = gen_lowpart (SImode, operands[0]);
957 operands[1] = gen_lowpart (SImode, operands[1]);
958 operands[2] = gen_reg_rtx (SImode); }")
960 ;; Define peepholes to eliminate an instruction when we are doing a sign
961 ;; extension but cannot clobber the input.
963 ;; In this case we will shift left 24 bits, but need a copy first. The shift
964 ;; can be replaced by a "mc03" instruction, but this can only be done if
965 ;; followed by the right shift of 24 or more bits.
967 [(set (match_operand:SI 0 "register_operand" "")
968 (subreg:SI (match_operand:QI 1 "register_operand" "") 0))
970 (ashift:SI (match_dup 0)
973 (ashiftrt:SI (match_dup 0)
974 (match_operand:SI 2 "const_int_operand" "")))]
975 "INTVAL (operands[2]) >= 24"
976 "mc03 %0,%1\;sari16 %0,%S2"
977 [(set_attr "type" "multi")
978 (set_attr "length" "4")
979 (set_attr "cc" "sets")])
981 ;; Now zero extensions:
982 (define_expand "zero_extendhisi2"
983 [(set (match_operand:SI 0 "register_operand" "b")
984 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
989 [(set (match_operand:SI 0 "register_operand" "=b")
990 (zero_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))]
993 [(set_attr "type" "load")])
996 [(set (match_operand:SI 0 "register_operand" "=r,r,b")
997 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))]
1003 [(set_attr "type" "arith,loadz,load")])
1005 (define_expand "zero_extendqisi2"
1006 [(set (match_operand:SI 0 "register_operand" "")
1007 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1012 [(set (match_operand:SI 0 "register_operand" "=b")
1013 (zero_extend:SI (match_operand:QI 1 "symbolic_memory_operand" "m")))]
1016 [(set_attr "type" "load")])
1019 [(set (match_operand:SI 0 "register_operand" "=r,r,b")
1020 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))]
1026 [(set_attr "type" "arith,load,load")])
1028 (define_expand "zero_extendqihi2"
1029 [(set (match_operand:HI 0 "register_operand" "")
1030 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1035 [(set (match_operand:HI 0 "register_operand" "=b")
1036 (zero_extend:HI (match_operand:QI 1 "symbolic_memory_operand" "m")))]
1039 [(set_attr "type" "load")])
1042 [(set (match_operand:HI 0 "register_operand" "=r,r,b")
1043 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))]
1049 [(set_attr "type" "arith,load,load")])
1051 ;; Various extract and insertion operations.
1052 (define_expand "extzv"
1053 [(set (match_operand:SI 0 "register_operand" "")
1054 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
1055 (match_operand:SI 2 "const_int_operand" "")
1056 (match_operand:SI 3 "const_int_operand" "")))]
1060 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
1063 if (GET_CODE (operands[3]) != CONST_INT)
1066 if (INTVAL (operands[3]) != 0 && INTVAL (operands[3]) != 8
1067 && INTVAL (operands[3]) != 16 && INTVAL (operands[3]) != 24)
1072 [(set (match_operand:SI 0 "register_operand" "=&r")
1073 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1075 (match_operand:SI 2 "const_int_operand" "n")))]
1076 "(INTVAL (operands[2]) & 7) == 0"
1077 "lis %0,0\;mc3%B2 %0,%1"
1078 [(set_attr "type" "multi")
1079 (set_attr "cc" "change0")])
1082 [(set (match_operand:SI 0 "register_operand" "=&r")
1083 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1085 (match_operand:SI 2 "const_int_operand" "n")))]
1086 "(INTVAL (operands[2]) & 7) == 0"
1087 [(set (match_dup 0) (const_int 0))
1088 (set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 24))
1089 (zero_extract:SI (match_dup 1) (const_int 8) (match_dup 2)))]
1093 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1096 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1098 (match_operand:SI 2 "const_int_operand" "n")))]
1099 "(INTVAL (operands[2]) & 7) == 0"
1101 [(set_attr "type" "address")
1102 (set_attr "length" "2")])
1104 (define_expand "insv"
1105 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
1106 (match_operand:SI 1 "const_int_operand" "")
1107 (match_operand:SI 2 "const_int_operand" ""))
1108 (match_operand:SI 3 "register_operand" ""))]
1112 if (GET_CODE (operands[2]) != CONST_INT)
1115 if (GET_CODE (operands[1]) != CONST_INT)
1118 if (INTVAL (operands[1]) == 1)
1120 emit_insn (gen_bit_insv (operands[0], operands[1], operands[2],
1124 else if (INTVAL (operands[1]) == 8
1125 && (INTVAL (operands[2]) % 8 == 0))
1126 ; /* Accept aligned byte-wide field. */
1131 ;; For a single-bit insert, it is better to explicitly generate references
1132 ;; to the T bit. We will call the T bit "CC0" because it can be clobbered
1133 ;; by some CC0 sets (single-bit tests).
1135 (define_expand "bit_insv"
1137 (zero_extract:SI (match_operand:SI 3 "register_operand" "")
1140 (parallel [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
1141 (match_operand:SI 1 "const_int_operand" "")
1142 (match_operand:SI 2 "const_int_operand" ""))
1143 (ne (cc0) (const_int 0)))
1144 (clobber (match_scratch:SI 4 ""))])]
1149 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1151 (match_operand:SI 1 "const_int_operand" "n"))
1152 (match_operand:SI 2 "register_operand" "r"))]
1153 "(INTVAL (operands[1]) & 7) == 0"
1155 [(set_attr "type" "address")
1156 (set_attr "length" "2")])
1158 ;; This pattern cannot have any input reloads since if references CC0.
1159 ;; So we have to add code to support memory, which is the only other
1160 ;; thing that a "register_operand" can become. There is still a problem
1161 ;; if the address isn't valid and *it* needs a reload, but there is no
1162 ;; way to solve that problem, so let's hope it never happens.
1165 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,m")
1167 (match_operand:SI 1 "const_int_operand" "n,m"))
1168 (ne (cc0) (const_int 0)))
1169 (clobber (match_scratch:SI 2 "=X,b"))]
1173 l%M0 %2,%0\;mftb%t1 %2,%S1\;st%M0 %2,%0"
1174 [(set_attr "type" "*,multi")
1175 (set_attr "cc" "none,none")
1176 (set_attr "length" "2,10")])
1178 ;; Arithmetic instructions. First, add and subtract.
1180 ;; It may be that the second input is either large or small enough that
1181 ;; the operation cannot be done in a single insn. In that case, emit two.
1182 (define_expand "addsi3"
1183 [(set (match_operand:SI 0 "register_operand" "")
1184 (plus:SI (match_operand:SI 1 "register_operand" "")
1185 (match_operand:SI 2 "nonmemory_operand" "")))]
1189 if (GET_CODE (operands[2]) == CONST_INT
1190 && (unsigned) (INTVAL (operands[2]) + 0x8000) >= 0x10000
1191 && (INTVAL (operands[2]) & 0xffff) != 0)
1193 int low = INTVAL (operands[2]) & 0xffff;
1194 int high = (unsigned) INTVAL (operands[2]) >> 16;
1197 high++, low |= 0xffff0000;
1199 emit_insn (gen_addsi3 (operands[0], operands[1],
1200 gen_rtx (CONST_INT, VOIDmode, high << 16)));
1201 operands[1] = operands[0];
1202 operands[2] = gen_rtx (CONST_INT, VOIDmode, low);
1206 ;; Put the insn to add a symbolic constant to a register separately to
1207 ;; improve register allocation since it has different register requirements.
1209 [(set (match_operand:SI 0 "register_operand" "=b")
1210 (plus:SI (match_operand:SI 1 "register_operand" "%b")
1211 (match_operand:SI 2 "romp_symbolic_operand" "s")))]
1214 [(set_attr "type" "address")
1215 (set_attr "length" "8")])
1218 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,b")
1219 (plus:SI (match_operand:SI 1 "reg_or_add_operand" "%0,0,r,b,0,r,b")
1220 (match_operand:SI 2 "reg_or_add_operand" "I,J,K,M,r,b,s")))]
1221 "register_operand (operands[1], SImode)
1222 || register_operand (operands[2], SImode)"
1231 [(set_attr "type" "arith,arith,arith,address,arith,address,misc")
1232 (set_attr "length" "2,2,4,4,2,2,8")])
1236 ;; 1. If third operand is constant integer, convert it to add of the negative
1238 ;; 2. If the second operand is not a valid constant integer, force it into a
1240 (define_expand "subsi3"
1241 [(set (match_operand:SI 0 "register_operand" "")
1242 (minus:SI (match_operand:SI 1 "reg_or_any_cint_operand" "")
1243 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1247 if (GET_CODE (operands [2]) == CONST_INT)
1249 emit_insn (gen_addsi3 (operands[0], operands[1],
1251 VOIDmode, - INTVAL (operands[2]))));
1255 operands[2] = force_reg (SImode, operands[2]);
1257 if (GET_CODE (operands[1]) != CONST_INT
1258 || (unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000)
1259 operands[1] = force_reg (SImode, operands[1]);
1263 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1264 (minus:SI (match_operand:SI 1 "reg_or_D_operand" "K,0,r")
1265 (match_operand:SI 2 "register_operand" "r,r,0")))]
1271 [(set_attr "length" "4,2,2")])
1273 ;; Multiply either calls a special RT routine or is done in-line, depending
1274 ;; on the value of a -m flag.
1276 ;; First define the way we call the subroutine.
1277 (define_expand "mulsi3_subr"
1278 [(set (reg:SI 2) (match_operand:SI 1 "register_operand" ""))
1279 (set (reg:SI 3) (match_operand:SI 2 "register_operand" ""))
1280 (parallel [(set (reg:SI 2) (mult:SI (reg:SI 2) (reg:SI 3)))
1281 (clobber (reg:SI 0))
1282 (clobber (reg:SI 15))])
1283 (set (match_operand:SI 0 "register_operand" "")
1288 (define_expand "mulsi3"
1289 [(set (match_operand:SI 0 "register_operand" "")
1290 (mult:SI (match_operand:SI 1 "register_operand" "")
1291 (match_operand:SI 2 "register_operand" "")))]
1295 if (! TARGET_IN_LINE_MUL)
1297 emit_insn (gen_mulsi3_subr (operands[0], operands[1], operands[2]));
1302 ;; Define the patterns to match.
1303 ;; We would like to provide a delay slot for the insns that call internal
1304 ;; routines, but doing so is risky since reorg will think that the use of
1305 ;; r2 and r3 is completed in the insn needing the delay slot. Also, it
1306 ;; won't know that the cc will be clobbered. So take the safe approach
1307 ;; and don't give them delay slots.
1310 (mult:SI (reg:SI 2) (reg:SI 3)))
1311 (clobber (reg:SI 0))
1312 (clobber (reg:SI 15))]
1313 "! TARGET_IN_LINE_MUL"
1315 [(set_attr "type" "misc")
1316 (set_attr "in_delay_slot" "no")])
1319 [(set (match_operand:SI 0 "register_operand" "=&r")
1320 (mult:SI (match_operand:SI 1 "register_operand" "%r")
1321 (match_operand:SI 2 "register_operand" "r")))]
1322 "TARGET_IN_LINE_MUL"
1324 { return output_in_line_mul (); }"
1325 [(set_attr "length" "38")
1326 (set_attr "type" "multi")])
1328 ;; Handle divide and modulus. The same function returns both values,
1329 ;; so use divmodsi4. This divides arg 1 by arg 2 with quotient to go
1330 ;; into arg 0 and remainder in arg 3.
1332 ;; We want to put REG_EQUAL notes for the two outputs. So we need a
1333 ;; function to do everything else.
1334 (define_expand "divmodsi4_doit"
1336 (match_operand:SI 0 "register_operand" ""))
1338 (match_operand:SI 1 "register_operand" ""))
1339 (parallel [(set (reg:SI 2) (div:SI (reg:SI 2) (reg:SI 3)))
1340 (set (reg:SI 3) (mod:SI (reg:SI 2) (reg:SI 3)))
1341 (clobber (reg:SI 0))
1342 (clobber (reg:SI 15))])]
1346 (define_expand "divmodsi4"
1347 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1348 (div:SI (match_operand:SI 1 "register_operand" "")
1349 (match_operand:SI 2 "register_operand" "")))
1350 (set (match_operand:SI 3 "register_operand" "")
1351 (mod:SI (match_dup 1) (match_dup 2)))])]
1357 emit_insn (gen_divmodsi4_doit (operands[1], operands[2]));
1358 insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2));
1359 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1360 gen_rtx (DIV, SImode, operands[1],
1363 insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3));
1364 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1365 gen_rtx (MOD, SImode, operands[1],
1373 (div:SI (reg:SI 2) (reg:SI 3)))
1375 (mod:SI (reg:SI 2) (reg:SI 3)))
1376 (clobber (reg:SI 0))
1377 (clobber (reg:SI 15))]
1380 [(set_attr "type" "misc")
1381 (set_attr "in_delay_slot" "no")])
1383 ;; Similarly for unsigned divide.
1384 (define_expand "udivmodsi4_doit"
1386 (match_operand:SI 0 "register_operand" ""))
1388 (match_operand:SI 1 "register_operand" ""))
1389 (parallel [(set (reg:SI 2) (udiv:SI (reg:SI 2) (reg:SI 3)))
1390 (set (reg:SI 3) (umod:SI (reg:SI 2) (reg:SI 3)))
1391 (clobber (reg:SI 0))
1392 (clobber (reg:SI 15))])]
1396 (define_expand "udivmodsi4"
1397 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1398 (udiv:SI (match_operand:SI 1 "register_operand" "")
1399 (match_operand:SI 2 "register_operand" "")))
1400 (set (match_operand:SI 3 "register_operand" "")
1401 (umod:SI (match_dup 1) (match_dup 2)))])]
1407 emit_insn (gen_udivmodsi4_doit (operands[1], operands[2]));
1408 insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2));
1409 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1410 gen_rtx (UDIV, SImode, operands[1],
1413 insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3));
1414 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1415 gen_rtx (UMOD, SImode, operands[1],
1423 (udiv:SI (reg:SI 2) (reg:SI 3)))
1425 (umod:SI (reg:SI 2) (reg:SI 3)))
1426 (clobber (reg:SI 0))
1427 (clobber (reg:SI 15))]
1429 "bali%# r15,uldiv$$"
1430 [(set_attr "type" "misc")
1431 (set_attr "in_delay_slot" "no")])
1433 ;; Define DImode arithmetic operations.
1435 ;; It is possible to do certain adds and subtracts with constants in a single
1436 ;; insn, but it doesn't seem worth the trouble.
1438 ;; Don't use DEFINE_SPLIT on these because the dependency on CC can't be
1439 ;; easily tracked in that case!
1440 (define_insn "adddi3"
1441 [(set (match_operand:DI 0 "register_operand" "=r")
1442 (plus:DI (match_operand:DI 1 "register_operand" "%0")
1443 (match_operand:DI 2 "register_operand" "r")))]
1445 "a %O0,%O2\;ae %0,%2"
1446 [(set_attr "type" "multi")])
1448 (define_insn "subdi3"
1449 [(set (match_operand:DI 0 "register_operand" "=r")
1450 (minus:DI (match_operand:DI 1 "register_operand" "0")
1451 (match_operand:DI 2 "register_operand" "r")))]
1453 "s %O0,%O2\;se %0,%2"
1454 [(set_attr "type" "multi")])
1456 (define_insn "negdi2"
1457 [(set (match_operand:DI 0 "register_operand" "=r,&r")
1458 (neg:DI (match_operand:DI 1 "register_operand" "0,r")))]
1460 "twoc %O0,%O1\;onec %0,%1\;aei %0,%0,0"
1461 [(set_attr "type" "multi")
1462 (set_attr "length" "8")])
1464 ;; Unary arithmetic operations.
1465 (define_insn "abssi2"
1466 [(set (match_operand:SI 0 "register_operand" "=r")
1467 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1470 [(set_attr "length" "2")])
1472 (define_insn "negsi2"
1473 [(set (match_operand:SI 0 "register_operand" "=r")
1474 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1477 [(set_attr "length" "2")])
1479 (define_insn "one_cmplsi2"
1480 [(set (match_operand:SI 0 "register_operand" "=r")
1481 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1484 [(set_attr "length" "2")])
1487 ;; Logical insns: AND, IOR, and XOR
1489 ;; If the operation is being performed on a 32-bit constant such that
1490 ;; it cannot be done in one insn, do it in two. We may lose a bit on
1491 ;; CSE in pathological cases, but it seems better doing it this way.
1492 (define_expand "andsi3"
1493 [(set (match_operand:SI 0 "register_operand" "")
1494 (and:SI (match_operand:SI 1 "register_operand" "")
1495 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1499 if (GET_CODE (operands[2]) == CONST_INT)
1501 int top = (unsigned) INTVAL (operands[2]) >> 16;
1502 int bottom = INTVAL (operands[2]) & 0xffff;
1504 if (top != 0 && top != 0xffff && bottom != 0 && bottom != 0xffff)
1506 emit_insn (gen_andsi3 (operands[0], operands[1],
1507 gen_rtx (CONST_INT, VOIDmode,
1508 (top << 16) | 0xffff)));
1509 operands[1] = operands[0];
1510 operands[2] = gen_rtx (CONST_INT, VOIDmode, 0xffff0000 | bottom);
1516 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1517 (and:SI (match_operand:SI 1 "reg_or_and_operand" "%0,r,0")
1518 (match_operand:SI 2 "reg_or_and_operand" "P,LMO,r")))]
1519 "register_operand (operands[1], SImode)
1520 || register_operand (operands[2], SImode)"
1525 [(set_attr "length" "2,4,2")])
1528 (define_expand "iorsi3"
1529 [(set (match_operand:SI 0 "register_operand" "")
1530 (ior:SI (match_operand:SI 1 "register_operand" "")
1531 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1535 if (GET_CODE (operands[2]) == CONST_INT)
1537 int top = (unsigned) INTVAL (operands[2]) >> 16;
1538 int bottom = INTVAL (operands[2]) & 0xffff;
1540 if (top != 0 && bottom != 0)
1542 emit_insn (gen_iorsi3 (operands[0], operands[1],
1543 gen_rtx (CONST_INT, VOIDmode, (top << 16))));
1544 operands[1] = operands[0];
1545 operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom);
1551 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1552 (ior:SI (match_operand:SI 1 "reg_or_cint_operand" "%0,r,0")
1553 (match_operand:SI 2 "reg_or_cint_operand" "N,LM,r")))]
1554 "register_operand (operands[1], SImode)
1555 || register_operand (operands[2], SImode)"
1560 [(set_attr "length" "2,4,2")])
1562 ;; exclusive-or (XOR)
1563 (define_expand "xorsi3"
1564 [(set (match_operand:SI 0 "register_operand" "")
1565 (xor:SI (match_operand:SI 1 "register_operand" "")
1566 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1570 if (GET_CODE (operands[2]) == CONST_INT)
1572 int top = (unsigned) INTVAL (operands[2]) >> 16;
1573 int bottom = INTVAL (operands[2]) & 0xffff;
1575 if (top == 0xffff && bottom == 0xffff)
1577 emit_insn (gen_one_cmplsi2 (operands[0], operands[1]));
1580 else if (top != 0 && bottom != 0)
1582 emit_insn (gen_xorsi3 (operands[0], operands[1],
1583 gen_rtx (CONST_INT, VOIDmode, (top << 16))));
1584 operands[1] = operands[0];
1585 operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom);
1591 [(set (match_operand:SI 0 "register_operand" "=r,r")
1592 (xor:SI (match_operand:SI 1 "reg_or_cint_operand" "%r,0")
1593 (match_operand:SI 2 "reg_or_cint_operand" "LM,r")))]
1594 "register_operand (operands[1], SImode)
1595 || register_operand (operands[2], SImode)"
1599 [(set_attr "length" "4,2")])
1601 ;; Various shift insns
1602 (define_insn "ashrsi3"
1603 [(set (match_operand:SI 0 "register_operand" "=r,r")
1604 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1605 (match_operand:QI 2 "reg_or_cint_operand" "r,n")))]
1610 [(set_attr "length" "2")])
1612 (define_insn "lshrsi3"
1613 [(set (match_operand:SI 0 "register_operand" "=r,r")
1614 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1615 (match_operand:QI 2 "reg_or_cint_operand" "r,n")))]
1620 [(set_attr "length" "2")])
1623 [(set (match_operand:SI 0 "register_operand" "=r")
1624 (ashift:SI (match_operand:SI 1 "register_operand" "b")
1628 [(set_attr "length" "2")
1629 (set_attr "type" "address")])
1631 (define_insn "ashlsi3"
1632 [(set (match_operand:SI 0 "register_operand" "=r,r")
1633 (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1634 (match_operand:QI 2 "reg_or_cint_operand" "r,n")))]
1639 [(set_attr "length" "2")])
1641 ;; Function call insns:
1643 ;; On the ROMP, &fcn is actually a pointer to the data area, which is passed
1644 ;; to the function in r0. &.fcn is the actual starting address of the
1645 ;; function. Also, the word at &fcn contains &.fcn.
1647 ;; For both functions that do and don't return values, there are two cases:
1648 ;; where the function's address is a constant, and where it isn't.
1650 ;; Operand 1 (2 for `call_value') is the number of arguments and is not used.
1651 (define_expand "call"
1653 (parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
1654 (match_operand 1 "" ""))
1655 (clobber (reg:SI 15))])]
1659 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
1662 operands[0] = XEXP (operands[0], 0);
1663 if (GET_CODE (operands[0]) == SYMBOL_REF)
1665 extern rtx get_symref ();
1666 char *real_fcnname =
1667 (char *) alloca (strlen (XSTR (operands[0], 0)) + 2);
1669 /* Copy the data area address to r0. */
1670 emit_move_insn (gen_rtx (REG, SImode, 0),
1671 force_reg (SImode, operands[0]));
1672 strcpy (real_fcnname, \".\");
1673 strcat (real_fcnname, XSTR (operands[0], 0));
1674 operands[0] = get_symref (real_fcnname);
1680 emit_move_insn (gen_rtx (REG, SImode, 0),
1681 force_reg (SImode, operands[0]));
1682 data_access = gen_rtx (MEM, SImode, operands[0]);
1683 RTX_UNCHANGING_P (data_access) = 1;
1684 operands[0] = copy_to_reg (data_access);
1689 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
1690 (match_operand 1 "" "g"))
1691 (clobber (reg:SI 15))]
1694 [(set_attr "type" "call")
1695 (set_attr "length" "2")])
1698 [(call (mem:SI (match_operand:SI 0 "romp_symbolic_operand" "i"))
1699 (match_operand 1 "" "g"))
1700 (clobber (reg:SI 15))]
1701 "GET_CODE (operands[0]) == SYMBOL_REF"
1703 [(set_attr "type" "call")])
1705 ;; Call a function and return a value.
1706 (define_expand "call_value"
1708 (parallel [(set (match_operand 0 "" "=fg")
1709 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
1710 (match_operand 2 "" "")))
1711 (clobber (reg:SI 15))])]
1715 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
1718 operands[1] = XEXP (operands[1], 0);
1719 if (GET_CODE (operands[1]) == SYMBOL_REF)
1721 extern rtx get_symref ();
1722 char *real_fcnname =
1723 (char *) alloca (strlen (XSTR (operands[1], 0)) + 2);
1725 /* Copy the data area address to r0. */
1726 emit_move_insn (gen_rtx (REG, SImode, 0),
1727 force_reg (SImode, operands[1]));
1728 strcpy (real_fcnname, \".\");
1729 strcat (real_fcnname, XSTR (operands[1], 0));
1730 operands[1] = get_symref (real_fcnname);
1736 emit_move_insn (gen_rtx (REG, SImode, 0),
1737 force_reg (SImode, operands[1]));
1738 data_access = gen_rtx (MEM, SImode, operands[1]);
1739 RTX_UNCHANGING_P (data_access) = 1;
1740 operands[1] = copy_to_reg (data_access);
1745 [(set (match_operand 0 "" "=fg")
1746 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
1747 (match_operand 2 "" "g")))
1748 (clobber (reg:SI 15))]
1751 [(set_attr "length" "2")
1752 (set_attr "type" "call")])
1755 [(set (match_operand 0 "" "=fg")
1756 (call (mem:SI (match_operand:SI 1 "romp_symbolic_operand" "i"))
1757 (match_operand 2 "" "g")))
1758 (clobber (reg:SI 15))]
1759 "GET_CODE (operands[1]) == SYMBOL_REF"
1761 [(set_attr "type" "call")])
1763 ;; No operation insn.
1768 [(set_attr "type" "address")
1769 (set_attr "length" "2")
1770 (set_attr "cc" "none")])
1772 ;; Here are the floating-point operations.
1774 ;; Start by providing DEFINE_EXPAND for each operation.
1775 ;; The insns will be handled with MATCH_OPERATOR; the methodology will be
1778 ;; First the conversion operations.
1780 (define_expand "truncdfsf2"
1781 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1782 (float_truncate:SF (match_operand:DF 1 "general_operand" "")))
1783 (clobber (reg:SI 0))
1784 (clobber (reg:SI 15))])]
1788 (define_expand "extendsfdf2"
1789 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1790 (float_extend:DF (match_operand:SF 1 "general_operand" "")))
1791 (clobber (reg:SI 0))
1792 (clobber (reg:SI 15))])]
1796 (define_expand "floatsisf2"
1797 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1798 (float:SF (match_operand:SI 1 "general_operand" "")))
1799 (clobber (reg:SI 0))
1800 (clobber (reg:SI 15))])]
1804 (define_expand "floatsidf2"
1805 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1806 (float:DF (match_operand:SI 1 "general_operand" "")))
1807 (clobber (reg:SI 0))
1808 (clobber (reg:SI 15))])]
1812 (define_expand "fix_truncsfsi2"
1813 [(parallel [(set (match_operand:SI 0 "general_operand" "")
1814 (fix:SI (match_operand:SF 1 "general_operand" "")))
1815 (clobber (reg:SI 0))
1816 (clobber (reg:SI 15))])]
1820 (define_expand "fix_truncdfsi2"
1821 [(parallel [(set (match_operand:SI 0 "general_operand" "")
1822 (fix:SI (match_operand:DF 1 "general_operand" "")))
1823 (clobber (reg:SI 0))
1824 (clobber (reg:SI 15))])]
1828 ;; Now the binary operations.
1830 (define_expand "addsf3"
1831 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1832 (plus:SF (match_operand:SF 1 "general_operand" "")
1833 (match_operand:SF 2 "general_operand" "")))
1834 (clobber (reg:SI 0))
1835 (clobber (reg:SI 15))])]
1839 (define_expand "adddf3"
1840 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1841 (plus:DF (match_operand:DF 1 "general_operand" "")
1842 (match_operand:DF 2 "general_operand" "")))
1843 (clobber (reg:SI 0))
1844 (clobber (reg:SI 15))])]
1848 (define_expand "subsf3"
1849 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1850 (minus:SF (match_operand:SF 1 "general_operand" "")
1851 (match_operand:SF 2 "general_operand" "")))
1852 (clobber (reg:SI 0))
1853 (clobber (reg:SI 15))])]
1857 (define_expand "subdf3"
1858 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1859 (minus:DF (match_operand:DF 1 "general_operand" "")
1860 (match_operand:DF 2 "general_operand" "")))
1861 (clobber (reg:SI 0))
1862 (clobber (reg:SI 15))])]
1866 (define_expand "mulsf3"
1867 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1868 (mult:SF (match_operand:SF 1 "general_operand" "")
1869 (match_operand:SF 2 "general_operand" "")))
1870 (clobber (reg:SI 0))
1871 (clobber (reg:SI 15))])]
1875 (define_expand "muldf3"
1876 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1877 (mult:DF (match_operand:DF 1 "general_operand" "")
1878 (match_operand:DF 2 "general_operand" "")))
1879 (clobber (reg:SI 0))
1880 (clobber (reg:SI 15))])]
1884 (define_expand "divsf3"
1885 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1886 (div:SF (match_operand:SF 1 "general_operand" "")
1887 (match_operand:SF 2 "general_operand" "")))
1888 (clobber (reg:SI 0))
1889 (clobber (reg:SI 15))])]
1893 (define_expand "divdf3"
1894 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1895 (div:DF (match_operand:DF 1 "general_operand" "")
1896 (match_operand:DF 2 "general_operand" "")))
1897 (clobber (reg:SI 0))
1898 (clobber (reg:SI 15))])]
1902 ;; Unary floating-point operations.
1904 ;; Negations can be done without floating-point, since this is IEEE.
1905 ;; But we cannot do this if an operand is a hard FP register, since
1906 ;; the SUBREG we create would not be valid.
1907 (define_expand "negsf2"
1908 [(set (match_operand:SF 0 "register_operand" "")
1909 (neg:SF (match_operand:SF 1 "register_operand" "")))]
1913 if (! (GET_CODE (operands[0]) == REG
1914 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
1915 && FP_REGNO_P (REGNO (operands[0])))
1916 && ! (GET_CODE (operands[1]) == REG
1917 && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
1918 && FP_REGNO_P (REGNO (operands[1]))))
1921 rtx target = operand_subword (operands[0], 0, 1, SFmode);
1923 result = expand_binop (SImode, xor_optab,
1924 operand_subword_force (operands[1], 0, SFmode),
1925 gen_rtx (CONST_INT, VOIDmode, 0x80000000),
1926 target, 0, OPTAB_WIDEN);
1930 if (result != target)
1931 emit_move_insn (result, target);
1933 /* Make a place for REG_EQUAL. */
1934 emit_move_insn (operands[0], operands[0]);
1939 (define_expand "negdf2"
1940 [(set (match_operand:DF 0 "register_operand" "")
1941 (neg:DF (match_operand:DF 1 "register_operand" "")))]
1945 if (! (GET_CODE (operands[0]) == REG
1946 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
1947 && FP_REGNO_P (REGNO (operands[0])))
1948 && ! (GET_CODE (operands[1]) == REG
1949 && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
1950 && FP_REGNO_P (REGNO (operands[1]))))
1953 rtx target = operand_subword (operands[0], 0, 1, DFmode);
1957 result = expand_binop (SImode, xor_optab,
1958 operand_subword_force (operands[1], 0, DFmode),
1959 gen_rtx (CONST_INT, VOIDmode, 0x80000000),
1960 target, 0, OPTAB_WIDEN);
1964 if (result != target)
1965 emit_move_insn (result, target);
1967 emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
1968 operand_subword_force (operands[1], 1, DFmode));
1970 insns = get_insns ();
1973 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1978 (define_expand "abssf2"
1979 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1980 (abs:SF (match_operand:SF 1 "general_operand" "")))
1981 (clobber (reg:SI 0))
1982 (clobber (reg:SI 15))])]
1986 (define_expand "absdf2"
1987 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1988 (abs:DF (match_operand:DF 1 "general_operand" "")))
1989 (clobber (reg:SI 0))
1990 (clobber (reg:SI 15))])]
1994 ;; Any floating-point operation can be either SFmode or DFmode, and each
1995 ;; operand (including the output) can be either a normal operand or a
1996 ;; conversion from a normal operand.
1998 ;; We use MATCH_OPERATOR to match a floating-point binary or unary operator
1999 ;; and input and output conversions. So we need 2^N patterns for each type
2000 ;; of operation, where N is the number of operands, including the output.
2001 ;; There are thus a total of 14 patterns, 8 for binary operations, 4 for
2002 ;; unary operations and two for conversion/move operations (only one
2003 ;; operand can have a conversion for move operations). In addition, we have
2004 ;; to be careful that a floating-point reload register doesn't get allocated
2005 ;; for an integer. We take care of this for inputs with PREFERRED_RELOAD_CLASS
2006 ;; but need to have two different constraints for outputs. This means that
2007 ;; we have to duplicate each pattern where the output could be an integer.
2008 ;; This adds another 7 patterns, for a total of 21.
2010 ;; Start with conversion operations (moves are done above).
2013 [(set (match_operand:SI 0 "general_operand" "=g")
2014 (match_operator 1 "float_conversion"
2015 [(match_operand 2 "general_operand" "frg")]))
2016 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2017 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2020 { return output_fpop (SET, operands[0], operands[2], 0, insn);
2022 [(set_attr "type" "fp")])
2025 [(set (match_operand 0 "general_operand" "=frg")
2026 (match_operator 1 "float_conversion"
2027 [(match_operand 2 "general_operand" "frg")]))
2028 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2029 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2032 { return output_fpop (SET, operands[0], operands[2], 0, insn);
2034 [(set_attr "type" "fp")])
2036 ;; Next, binary floating-point operations.
2039 [(set (match_operand 0 "general_operand" "=frg")
2040 (match_operator 1 "float_binary"
2041 [(match_operand 2 "general_operand" "frg")
2042 (match_operand 3 "general_operand" "frg")]))
2043 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2044 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2045 "check_precision (GET_MODE (operands[1]), operands[2], operands[3])"
2047 { return output_fpop (GET_CODE (operands[1]), operands[0],
2048 operands[2], operands[3], insn);
2050 [(set_attr "type" "fp")])
2053 [(set (match_operand 0 "general_operand" "=frg")
2054 (match_operator 1 "float_binary"
2055 [(match_operand 2 "general_operand" "frg")
2056 (match_operator 3 "float_conversion"
2057 [(match_operand 4 "general_operand" "frg")])]))
2058 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2059 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2060 "check_precision (GET_MODE (operands[1]), operands[2], operands[4])"
2062 { return output_fpop (GET_CODE (operands[1]), operands[0],
2063 operands[2], operands[4], insn);
2065 [(set_attr "type" "fp")])
2068 [(set (match_operand 0 "general_operand" "=frg")
2069 (match_operator 1 "float_binary"
2070 [(match_operator 2 "float_conversion"
2071 [(match_operand 3 "general_operand" "frg")])
2072 (match_operand 4 "general_operand" "frg")]))
2073 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2074 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2075 "check_precision (GET_MODE (operands[1]), operands[3], operands[4])"
2077 { return output_fpop (GET_CODE (operands[1]), operands[0],
2078 operands[3], operands[4], insn);
2080 [(set_attr "type" "fp")])
2083 [(set (match_operand 0 "general_operand" "=frg")
2084 (match_operator 1 "float_binary"
2085 [(match_operator 2 "float_conversion"
2086 [(match_operand 3 "general_operand" "frg")])
2087 (match_operator 4 "float_conversion"
2088 [(match_operand 5 "general_operand" "frg")])]))
2089 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2090 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2091 "check_precision (GET_MODE (operands[1]), operands[3], operands[5])"
2093 { return output_fpop (GET_CODE (operands[1]), operands[0],
2094 operands[3], operands[5], insn);
2096 [(set_attr "type" "fp")])
2099 [(set (match_operand:SI 0 "general_operand" "=g")
2100 (match_operator 1 "float_conversion"
2101 [(match_operator 2 "float_binary"
2102 [(match_operand 3 "general_operand" "frg")
2103 (match_operand 4 "general_operand" "frg")])]))
2104 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2105 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2106 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2108 { return output_fpop (GET_CODE (operands[2]), operands[0],
2109 operands[3], operands[4], insn);
2111 [(set_attr "type" "fp")])
2114 [(set (match_operand 0 "general_operand" "=frg")
2115 (match_operator 1 "float_conversion"
2116 [(match_operator 2 "float_binary"
2117 [(match_operand 3 "general_operand" "frg")
2118 (match_operand 4 "general_operand" "frg")])]))
2119 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2120 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2121 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2123 { return output_fpop (GET_CODE (operands[2]), operands[0],
2124 operands[3], operands[4], insn);
2126 [(set_attr "type" "fp")])
2129 [(set (match_operand:SI 0 "general_operand" "=g")
2130 (match_operator 1 "float_conversion"
2131 [(match_operator 2 "float_binary"
2132 [(match_operand 3 "general_operand" "frg")
2133 (match_operator 4 "float_conversion"
2134 [(match_operand 5 "general_operand" "frg")])])]))
2135 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2136 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2137 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2139 { return output_fpop (GET_CODE (operands[2]), operands[0],
2140 operands[3], operands[5], insn);
2142 [(set_attr "type" "fp")])
2145 [(set (match_operand 0 "general_operand" "=frg")
2146 (match_operator 1 "float_conversion"
2147 [(match_operator 2 "float_binary"
2148 [(match_operand 3 "general_operand" "frg")
2149 (match_operator 4 "float_conversion"
2150 [(match_operand 5 "general_operand" "frg")])])]))
2151 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2152 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2153 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2155 { return output_fpop (GET_CODE (operands[2]), operands[0],
2156 operands[3], operands[5], insn);
2158 [(set_attr "type" "fp")])
2161 [(set (match_operand:SI 0 "general_operand" "=g")
2162 (match_operator 1 "float_conversion"
2163 [(match_operator 2 "float_binary"
2164 [(match_operator 3 "float_conversion"
2165 [(match_operand 4 "general_operand" "frg")])
2166 (match_operand 5 "general_operand" "frg")])]))
2167 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2168 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2169 "check_precision (GET_MODE (operands[2]), operands[4], operands[5])"
2171 { return output_fpop (GET_CODE (operands[2]), operands[0],
2172 operands[4], operands[5], insn);
2174 [(set_attr "type" "fp")])
2177 [(set (match_operand 0 "general_operand" "=frg")
2178 (match_operator 1 "float_conversion"
2179 [(match_operator 2 "float_binary"
2180 [(match_operator 3 "float_conversion"
2181 [(match_operand 4 "general_operand" "frg")])
2182 (match_operand 5 "general_operand" "frg")])]))
2183 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2184 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2185 "check_precision (GET_MODE (operands[2]), operands[4], operands[5])"
2187 { return output_fpop (GET_CODE (operands[2]), operands[0],
2188 operands[4], operands[5], insn);
2190 [(set_attr "type" "fp")])
2193 [(set (match_operand:SI 0 "general_operand" "=g")
2194 (match_operator 1 "float_conversion"
2195 [(match_operator 2 "float_binary"
2196 [(match_operator 3 "float_conversion"
2197 [(match_operand 4 "general_operand" "frg")])
2198 (match_operator 5 "float_conversion"
2199 [(match_operand 6 "general_operand" "frg")])])]))
2200 (clobber (match_operand:SI 7 "reg_0_operand" "=&z"))
2201 (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))]
2202 "check_precision (GET_MODE (operands[2]), operands[4], operands[6])"
2204 { return output_fpop (GET_CODE (operands[2]), operands[0],
2205 operands[4], operands[6], insn);
2207 [(set_attr "type" "fp")])
2210 [(set (match_operand 0 "general_operand" "=frg")
2211 (match_operator 1 "float_conversion"
2212 [(match_operator 2 "float_binary"
2213 [(match_operator 3 "float_conversion"
2214 [(match_operand 4 "general_operand" "frg")])
2215 (match_operator 5 "float_conversion"
2216 [(match_operand 6 "general_operand" "frg")])])]))
2217 (clobber (match_operand:SI 7 "reg_0_operand" "=&z"))
2218 (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))]
2219 "check_precision (GET_MODE (operands[2]), operands[4], operands[6])"
2221 { return output_fpop (GET_CODE (operands[2]), operands[0],
2222 operands[4], operands[6], insn);
2224 [(set_attr "type" "fp")])
2226 ;; Unary floating-point operations.
2229 [(set (match_operand 0 "general_operand" "=frg")
2230 (match_operator 1 "float_unary"
2231 [(match_operand 2 "general_operand" "frg")]))
2232 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2233 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2234 "check_precision (GET_MODE (operands[1]), operands[2], 0)"
2236 { return output_fpop (GET_CODE (operands[1]), operands[0], operands[2],
2239 [(set_attr "type" "fp")])
2242 [(set (match_operand 0 "general_operand" "=frg")
2243 (match_operator 1 "float_unary"
2244 [(match_operator 2 "float_conversion"
2245 [(match_operand 3 "general_operand" "frg")])]))
2246 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2247 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2248 "check_precision (GET_MODE (operands[1]), operands[3], 0)"
2250 { return output_fpop (GET_CODE (operands[1]), operands[0], operands[3],
2253 [(set_attr "type" "fp")])
2256 [(set (match_operand:SI 0 "general_operand" "=g")
2257 (match_operator 1 "float_conversion"
2258 [(match_operator 2 "float_unary"
2259 [(match_operand 3 "general_operand" "frg")])]))
2260 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2261 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2262 "check_precision (GET_MODE (operands[2]), operands[3], 0)"
2264 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3],
2267 [(set_attr "type" "fp")])
2270 [(set (match_operand 0 "general_operand" "=frg")
2271 (match_operator 1 "float_conversion"
2272 [(match_operator 2 "float_unary"
2273 [(match_operand 3 "general_operand" "frg")])]))
2274 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2275 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2276 "check_precision (GET_MODE (operands[2]), operands[3], 0)"
2278 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3],
2281 [(set_attr "type" "fp")])
2284 [(set (match_operand:SI 0 "general_operand" "=g")
2285 (match_operator 1 "float_conversion"
2286 [(match_operator 2 "float_unary"
2287 [(match_operator 3 "float_conversion"
2288 [(match_operand 4 "general_operand" "frg")])])]))
2289 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2290 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2291 "check_precision (GET_MODE (operands[2]), operands[4], 0)"
2293 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4],
2296 [(set_attr "type" "fp")])
2299 [(set (match_operand 0 "general_operand" "=frg")
2300 (match_operator 1 "float_conversion"
2301 [(match_operator 2 "float_unary"
2302 [(match_operator 3 "float_conversion"
2303 [(match_operand 4 "general_operand" "frg")])])]))
2304 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2305 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2306 "check_precision (GET_MODE (operands[2]), operands[4], 0)"
2308 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4],
2311 [(set_attr "type" "fp")])
2313 ;; Compare insns are next. Note that the ROMP has two types of compares,
2314 ;; signed & unsigned, and one type of branch. Use the routine
2315 ;; `next_insn_tests_no_unsigned' to see which type to use.
2316 (define_expand "tstsi"
2318 (match_operand:SI 0 "register_operand" "r"))]
2322 (define_expand "cmpsi"
2324 (compare (match_operand:SI 0 "register_operand" "")
2325 (match_operand:SI 1 "reg_or_cint_operand" "")))]
2329 ;; Signed compare, `test' first.
2333 (match_operand:SI 0 "register_operand" "r"))]
2334 "next_insn_tests_no_unsigned (insn)"
2336 [(set_attr "length" "2")
2337 (set_attr "type" "compare")])
2340 [(set (cc0) (match_operand:SI 0 "register_operand" "r,r,r"))
2341 (set (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "=0,r,Q")
2343 "next_insn_tests_no_unsigned (insn)"
2347 st%M1 %0,%1\;cis %0,0"
2348 [(set_attr "type" "compare,compare,store")
2349 (set_attr "length" "2,4,6")
2350 (set_attr "cc" "compare")])
2354 (compare (match_operand:SI 0 "register_operand" "r,r,r")
2355 (match_operand:SI 1 "reg_or_cint_operand" "I,K,r")))]
2356 "next_insn_tests_no_unsigned (insn)"
2361 [(set_attr "length" "2,4,2")
2362 (set_attr "type" "compare")])
2364 ;; Unsigned comparisons, `test' first, again.
2367 (match_operand:SI 0 "register_operand" "r"))]
2368 "! next_insn_tests_no_unsigned (insn)"
2370 [(set_attr "type" "compare")])
2374 (compare (match_operand:SI 0 "register_operand" "r,r")
2375 (match_operand:SI 1 "reg_or_cint_operand" "K,r")))]
2376 "! next_insn_tests_no_unsigned (insn)"
2380 [(set_attr "length" "4,2")
2381 (set_attr "type" "compare")])
2383 ;; Bit test insn. Many cases are converted into this by combine. This
2384 ;; uses the ROMP test bit.
2388 (zero_extract (match_operand:SI 0 "register_operand" "r,r")
2390 (match_operand:SI 1 "reg_or_any_cint_operand" "r,n")))]
2391 "next_insn_tests_no_inequality (insn)"
2395 [(set_attr "length" "2")
2396 (set_attr "type" "compare")
2397 (set_attr "cc" "tbit")])
2399 ;; Floating-point comparisons. There are two, equality and order.
2400 ;; The difference will be that a trap for NaN will be given on the orderr
2401 ;; comparisons only.
2403 (define_expand "cmpsf"
2404 [(parallel [(set (cc0) (compare (match_operand:SF 0 "general_operand" "")
2405 (match_operand:SF 1 "general_operand" "")))
2406 (clobber (reg:SI 0))
2407 (clobber (reg:SI 15))])]
2411 (define_expand "cmpdf"
2412 [(parallel [(set (cc0) (compare (match_operand:DF 0 "general_operand" "")
2413 (match_operand:DF 1 "general_operand" "")))
2414 (clobber (reg:SI 0))
2415 (clobber (reg:SI 15))])]
2419 (define_expand "tstsf"
2420 [(parallel [(set (cc0) (match_operand:SF 0 "general_operand" ""))
2421 (clobber (reg:SI 0))
2422 (clobber (reg:SI 15))])]
2426 (define_expand "tstdf"
2427 [(parallel [(set (cc0) (match_operand:DF 0 "general_operand" ""))
2428 (clobber (reg:SI 0))
2429 (clobber (reg:SI 15))])]
2433 ;; There are four cases for compare and two for test. These correspond
2434 ;; to each input having a floating-point conversion or not.
2437 [(set (cc0) (compare (match_operand 0 "general_operand" "frg")
2438 (match_operand 1 "general_operand" "frg")))
2439 (clobber (match_operand:SI 2 "reg_0_operand" "=&z"))
2440 (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))]
2441 "GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode"
2443 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2444 operands[0], operands[1], 0, insn);
2446 [(set_attr "type" "fp")
2447 (set_attr "cc" "compare")])
2450 [(set (cc0) (compare (match_operand 0 "general_operand" "frg")
2451 (match_operator 1 "float_conversion"
2452 [(match_operand 2 "general_operand" "frg")])))
2453 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2454 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2457 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2458 operands[0], operands[2], 0, insn);
2460 [(set_attr "type" "fp")
2461 (set_attr "cc" "compare")])
2464 [(set (cc0) (compare (match_operator 0 "float_conversion"
2465 [(match_operand 1 "general_operand" "frg")])
2466 (match_operand 2 "general_operand" "frg")))
2467 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2468 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2471 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2472 operands[1], operands[2], 0, insn);
2474 [(set_attr "type" "fp")
2475 (set_attr "cc" "compare")])
2478 [(set (cc0) (compare (match_operator 0 "float_conversion"
2479 [(match_operand 1 "general_operand" "frg")])
2480 (match_operator 2 "float_conversion"
2481 [(match_operand 3 "general_operand" "frg")])))
2482 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2483 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2486 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2487 operands[1], operands[3], 0, insn);
2489 [(set_attr "type" "fp")
2490 (set_attr "cc" "compare")])
2493 [(set (cc0) (match_operand 0 "general_operand" "frg"))
2494 (clobber (match_operand:SI 1 "reg_0_operand" "=&z"))
2495 (clobber (match_operand:SI 2 "reg_15_operand" "=&t"))]
2496 "GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode"
2498 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2499 operands[0], immed_real_const_1 (0, 0,
2500 GET_MODE (operands[0])),
2503 [(set_attr "type" "fp")
2504 (set_attr "cc" "compare")])
2507 [(set (cc0) (match_operator 0 "float_conversion"
2508 [(match_operand 1 "general_operand" "frg")]))
2509 (clobber (match_operand:SI 2 "reg_0_operand" "=&z"))
2510 (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))]
2513 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2514 operands[1], immed_real_const_1 (0, 0,
2515 GET_MODE (operands[1])),
2518 [(set_attr "type" "fp")
2519 (set_attr "cc" "compare")])
2521 ;; Branch insns. Unsigned vs. signed have already
2522 ;; been taken care of. The only insns that need to be concerned about the
2523 ;; test bit are beq and bne because the rest are either always true,
2524 ;; always false, or converted to EQ or NE.
2526 ;; For conditional branches, we use `define_expand' and just have two patterns
2527 ;; that match them. Operand printing does most of the work.
2529 (define_expand "beq"
2531 (if_then_else (eq (cc0)
2533 (label_ref (match_operand 0 "" ""))
2538 (define_expand "bne"
2540 (if_then_else (ne (cc0)
2542 (label_ref (match_operand 0 "" ""))
2547 (define_expand "bgt"
2549 (if_then_else (gt (cc0)
2551 (label_ref (match_operand 0 "" ""))
2556 (define_expand "bgtu"
2558 (if_then_else (gtu (cc0)
2560 (label_ref (match_operand 0 "" ""))
2565 (define_expand "blt"
2567 (if_then_else (lt (cc0)
2569 (label_ref (match_operand 0 "" ""))
2574 (define_expand "bltu"
2576 (if_then_else (ltu (cc0)
2578 (label_ref (match_operand 0 "" ""))
2583 (define_expand "bge"
2585 (if_then_else (ge (cc0)
2587 (label_ref (match_operand 0 "" ""))
2592 (define_expand "bgeu"
2594 (if_then_else (geu (cc0)
2596 (label_ref (match_operand 0 "" ""))
2601 (define_expand "ble"
2603 (if_then_else (le (cc0)
2605 (label_ref (match_operand 0 "" ""))
2610 (define_expand "bleu"
2612 (if_then_else (leu (cc0)
2614 (label_ref (match_operand 0 "" ""))
2619 ;; Define both directions of branch and return.
2623 (if_then_else (match_operator 1 "comparison_operator"
2624 [(cc0) (const_int 0)])
2625 (label_ref (match_operand 0 "" ""))
2630 if (restore_compare_p (operands[1]))
2632 else if (get_attr_length (insn) == 2)
2633 return \"j%j1 %l0\";
2635 return \"b%j1%# %l0\";
2637 [(set_attr "type" "branch")])
2641 (if_then_else (match_operator 0 "comparison_operator"
2642 [(cc0) (const_int 0)])
2648 if (restore_compare_p (operands[0]))
2651 return \"b%j0r%# r15\";
2653 [(set_attr "type" "return")])
2657 (if_then_else (match_operator 1 "comparison_operator"
2658 [(cc0) (const_int 0)])
2660 (label_ref (match_operand 0 "" ""))))]
2664 if (restore_compare_p (operands[1]))
2666 else if (get_attr_length (insn) == 2)
2667 return \"j%J1 %l0\";
2669 return \"b%J1%# %l0\";
2671 [(set_attr "type" "branch")])
2675 (if_then_else (match_operator 0 "comparison_operator"
2676 [(cc0) (const_int 0)])
2682 if (restore_compare_p (operands[0]))
2685 return \"b%J0r%# r15\";
2687 [(set_attr "type" "return")])
2689 ;; Unconditional branch and return.
2693 (label_ref (match_operand 0 "" "")))]
2697 if (get_attr_length (insn) == 2)
2702 [(set_attr "type" "branch")])
2704 (define_insn "return"
2708 [(set_attr "type" "return")])
2710 (define_insn "indirect_jump"
2711 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2714 [(set_attr "type" "branch")
2715 (set_attr "length" "2")])
2717 ;; Table jump for switch statements:
2718 (define_insn "tablejump"
2720 (match_operand:SI 0 "register_operand" "r"))
2721 (use (label_ref (match_operand 1 "" "")))]
2724 [(set_attr "type" "branch")
2725 (set_attr "length" "2")])
2727 ;;- Local variables:
2729 ;;- comment-start: ";;- "
2730 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2731 ;;- eval: (modify-syntax-entry ?[ "(]")
2732 ;;- eval: (modify-syntax-entry ?] ")[")
2733 ;;- eval: (modify-syntax-entry ?{ "(}")
2734 ;;- eval: (modify-syntax-entry ?} "){")