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 [(parallel [(set (match_dup 2) (match_dup 3))
562 (clobber (match_dup 7))])
563 (parallel [(set (match_dup 4) (match_dup 5))
564 (clobber (match_dup 8))])]
566 { if (GET_CODE (operands[0]) != REG
567 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
570 operands[2] = operand_subword (operands[0], 0, 0, DImode);
571 operands[3] = operand_subword (operands[1], 0, 0, DImode);
572 operands[4] = operand_subword (operands[0], 1, 0, DImode);
573 operands[5] = operand_subword (operands[1], 1, 0, DImode);
577 operands[2] = operand_subword (operands[0], 1, 0, DImode);
578 operands[3] = operand_subword (operands[1], 1, 0, DImode);
579 operands[4] = operand_subword (operands[0], 0, 0, DImode);
580 operands[5] = operand_subword (operands[1], 0, 0, DImode);
583 if (operands[2] == 0 || operands[3] == 0
584 || operands[4] == 0 || operands[5] == 0)
587 /* We must be sure to make two different SCRATCH operands, since they
588 are not allowed to be shared. After reload, however, we only have
589 a SCRATCH if we won't use the operand, so it is allowed to share it
591 if (reload_completed || GET_CODE (operands[6]) != SCRATCH)
592 operands[7] = operands[8] = operands[6];
595 operands[7] = gen_rtx (SCRATCH, SImode);
596 operands[8] = gen_rtx (SCRATCH, SImode);
600 ;; Define move insns for SF, and DF.
602 ;; For register-register copies or a copy of something to itself, emit a
603 ;; single SET insn since it will likely be optimized away.
605 ;; Otherwise, emit a floating-point move operation unless both input and
606 ;; output are either constant, memory, or a non-floating-point hard register.
607 (define_expand "movdf"
608 [(parallel [(set (match_operand:DF 0 "general_operand" "")
609 (match_operand:DF 1 "general_operand" ""))
611 (clobber (reg:SI 15))])]
614 { rtx op0 = operands[0];
615 rtx op1 = operands[1];
619 emit_insn (gen_rtx (SET, VOIDmode, op0, op1));
623 if ((GET_CODE (op0) == MEM
624 || (GET_CODE (op0) == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER
625 && ! FP_REGNO_P (REGNO (op0))))
626 && (GET_CODE (op1) == MEM
627 || GET_CODE (op1) == CONST_DOUBLE
628 || (GET_CODE (op1) == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER
629 && ! FP_REGNO_P (REGNO (op1)) && ! rtx_equal_p (op0, op1))))
633 if (GET_CODE (op1) == CONST_DOUBLE)
634 op1 = force_const_mem (DFmode, op1);
637 if (GET_CODE (operands[0]) != REG
638 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
641 emit_move_insn (operand_subword (op0, 0, 1, DFmode),
642 operand_subword_force (op1, 0, DFmode));
643 emit_move_insn (operand_subword (op0, 1, 1, DFmode),
644 operand_subword_force (op1, 1, DFmode));
648 emit_move_insn (operand_subword (op0, 1, 1, DFmode),
649 operand_subword_force (op1, 1, DFmode));
650 emit_move_insn (operand_subword (op0, 0, 1, DFmode),
651 operand_subword_force (op1, 0, DFmode));
654 insns = get_insns ();
657 emit_no_conflict_block (insns, op0, op1, 0, op1);
662 (define_expand "movsf"
663 [(parallel [(set (match_operand:SF 0 "general_operand" "")
664 (match_operand:SF 1 "general_operand" ""))
666 (clobber (reg:SI 15))])]
669 { rtx op0 = operands[0];
670 rtx op1 = operands[1];
674 emit_insn (gen_rtx (SET, VOIDmode, op0, op1));
678 if ((GET_CODE (op0) == MEM
679 || (GET_CODE (op0) == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER
680 && ! FP_REGNO_P (REGNO (op0))))
681 && (GET_CODE (op1) == MEM
682 || GET_CODE (op1) == CONST_DOUBLE
683 || (GET_CODE (op1) == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER
684 && ! FP_REGNO_P (REGNO (op1)))))
688 if (GET_CODE (op1) == CONST_DOUBLE)
689 op1 = force_const_mem (SFmode, op1);
691 last = emit_move_insn (operand_subword (op0, 0, 1, SFmode),
692 operand_subword_force (op1, 0, SFmode));
694 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, op1, REG_NOTES (last));
699 ;; Define the move insns for SF and DF. Check for all general regs
700 ;; in the FP insns and make them non-FP if so. Do the same if the input and
701 ;; output are the same (the insn will be deleted in this case and we don't
702 ;; want to think there are FP insns when there might not be).
704 [(set (match_operand:SF 0 "general_operand" "=*frg")
708 [(set_attr "type" "address")
709 (set_attr "length" "2")])
712 [(set (match_operand:SF 0 "general_operand" "=r,*fr,r,r,Q,m,frg")
713 (match_operand:SF 1 "general_operand" "r,0,Q,m,r,r,frg"))
714 (clobber (match_operand:SI 2 "reg_0_operand" "=&z,z,z,z,z,z,z"))
715 (clobber (match_operand:SI 3 "reg_15_operand" "=&t,t,t,t,t,t,t"))]
718 { switch (which_alternative)
721 return \"cas %0,%1,r0\";
725 return \"l%M1 %0,%1\";
727 return \"load %0,%1\";
729 return \"st%M0 %1,%0\";
731 return \"store %1,%0,%3\";
733 return output_fpop (SET, operands[0], operands[1], 0, insn);
736 [(set_attr "type" "address,address,load,load,store,store,fp")
737 (set_attr "length" "2,2,*,*,*,*,*")])
740 [(set (match_operand:DF 0 "general_operand" "=*frg")
744 [(set_attr "type" "address")
745 (set_attr "length" "2")])
748 [(set (match_operand:DF 0 "general_operand" "=r,*fr,r,r,Q,m,frg")
749 (match_operand:DF 1 "general_operand" "r,0,Q,m,r,r,*frg"))
750 (clobber (match_operand:SI 2 "reg_0_operand" "=&z,z,z,z,z,z,z"))
751 (clobber (match_operand:SI 3 "reg_15_operand" "=&t,t,t,t,t,t,t"))]
754 { switch (which_alternative)
757 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
758 return \"cas %O0,%O1,r0\;cas %0,%1,r0\";
760 return \"cas %0,%1,r0\;cas %O0,%O1,r0\";
764 /* Here we must see which word to load first. We default to the
765 low-order word unless it occurs in the address. */
766 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
768 return \"l%M1 %O0,%O1\;l%M1 %0,%1\";
770 return \"l%M1 %0,%1\;l%M1 %O0,%O1\";
772 return \"get %3,$%1\;ls %0,0(%3)\;ls %O0,4(%3)\";
774 return \"st%M0 %1,%0\;st%M0 %O1,%O0\";
776 return \"get %3,$%0\;sts %1,0(%3)\;sts %O1,4(%3)\";
778 return output_fpop (SET, operands[0], operands[1], 0, insn);
781 [(set_attr "type" "address,multi,multi,multi,multi,multi,fp")
782 (set_attr "length" "2,4,*,*,*,*,*")])
784 ;; Split all the above cases that involve multiple insns and no floating-point
785 ;; data block. If before reload, we can make a SCRATCH. Otherwise, use
789 [(set (match_operand:DF 0 "register_operand" "")
790 (match_operand:DF 1 "symbolic_memory_operand" ""))
792 (clobber (reg:SI 15))]
793 "GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 16"
794 [(set (reg:SI 15) (match_dup 2))
795 (set (match_dup 3) (match_dup 4))
796 (set (match_dup 5) (match_dup 6))]
798 { operands[2] = XEXP (operands[1], 0);
799 operands[3] = operand_subword (operands[0], 0, 0, DFmode);
800 operands[4] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 15));
801 operands[5] = operand_subword (operands[0], 0, 1, DFmode);
802 operands[6] = gen_rtx (MEM, SImode,
803 gen_rtx (PLUS, SImode, gen_rtx (REG, SImode, 15),
804 gen_rtx (CONST_INT, VOIDmode, 4)));
806 if (operands[3] == 0 || operands[5] == 0)
811 [(set (match_operand:DF 0 "symbolic_memory_operand" "")
812 (match_operand:DF 1 "register_operand" ""))
814 (clobber (reg:SI 15))]
815 "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 16"
816 [(set (reg:SI 15) (match_dup 2))
817 (set (match_dup 3) (match_dup 4))
818 (set (match_dup 5) (match_dup 6))]
820 { operands[2] = XEXP (operands[0], 0);
821 operands[3] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 15));
822 operands[4] = operand_subword (operands[1], 0, 0, DFmode);
823 operands[5] = gen_rtx (MEM, SImode,
824 gen_rtx (PLUS, SImode, gen_rtx (REG, SImode, 15),
825 gen_rtx (CONST_INT, VOIDmode, 4)));
826 operands[6] = operand_subword (operands[1], 1, 0, DFmode);
828 if (operands[4] == 0 || operands[6] == 0)
832 ;; If the output is a register and the input is memory, we have to be careful
833 ;; and see which word needs to be loaded first. We also cannot to the
834 ;; split if the input is a constant because it would result in invalid
835 ;; insns. When the output is a MEM, we must put a CLOBBER on each of the
836 ;; resulting insn, when it is not a MEM, we must not.
838 [(set (match_operand:DF 0 "memory_operand" "")
839 (match_operand:DF 1 "register_operand" ""))
841 (clobber (reg:SI 15))]
842 "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 15"
843 [(parallel [(set (match_dup 2) (match_dup 3))
844 (clobber (match_dup 6))])
845 (parallel [(set (match_dup 4) (match_dup 5))
846 (clobber (match_dup 7))])]
848 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
849 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
850 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
851 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
853 if (operands[2] == 0 || operands[3] == 0
854 || operands[4] == 0 || operands[5] == 0)
857 if (reload_completed)
858 operands[6] = operands[7] = gen_rtx (REG, SImode, 15);
861 operands[6] = gen_rtx (SCRATCH, SImode);
862 operands[7] = gen_rtx (SCRATCH, SImode);
867 [(set (match_operand:DF 0 "nonmemory_operand" "")
868 (match_operand:DF 1 "general_operand" ""))
870 (clobber (reg:SI 15))]
871 "! symbolic_memory_operand (operands[1], DFmode)
872 && GET_CODE (operands[1]) != CONST_DOUBLE
873 && (GET_CODE (operands[0]) != REG || REGNO (operands[0]) < 15)
874 && (GET_CODE (operands[1]) != REG || REGNO (operands[1]) < 15)
875 && (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)"
876 [(set (match_dup 2) (match_dup 3))
877 (set (match_dup 4) (match_dup 5))]
879 { if (GET_CODE (operands[0]) != REG
880 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
883 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
884 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
885 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
886 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
890 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
891 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
892 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
893 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
896 if (operands[2] == 0 || operands[3] == 0
897 || operands[4] == 0 || operands[5] == 0)
901 ;; Conversions from one integer mode to another.
902 ;; It is possible sometimes to sign- or zero-extend while fetching from memory.
904 ;; First, sign-extensions:
905 (define_expand "extendhisi2"
906 [(set (match_operand:SI 0 "register_operand" "")
907 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
912 [(set (match_operand:SI 0 "register_operand" "=b")
913 (sign_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))]
916 [(set_attr "type" "load")])
919 [(set (match_operand:SI 0 "register_operand" "=r,r,b")
920 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))]
926 [(set_attr "type" "arith,load,load")
927 (set_attr "length" "2,*,*")])
929 (define_expand "extendqisi2"
931 (ashift:SI (match_operand:QI 1 "register_operand" "")
933 (set (match_operand:SI 0 "register_operand" "")
934 (ashiftrt:SI (match_dup 2)
938 { operands[1] = gen_lowpart (SImode, operands[1]);
939 operands[2] = gen_reg_rtx (SImode); }")
941 (define_expand "extendqihi2"
943 (ashift:SI (match_operand:QI 1 "register_operand" "")
945 (set (match_operand:HI 0 "register_operand" "")
946 (ashiftrt:SI (match_dup 2)
950 { operands[0] = gen_lowpart (SImode, operands[0]);
951 operands[1] = gen_lowpart (SImode, operands[1]);
952 operands[2] = gen_reg_rtx (SImode); }")
954 ;; Define peepholes to eliminate an instruction when we are doing a sign
955 ;; extension but cannot clobber the input.
957 ;; In this case we will shift left 24 bits, but need a copy first. The shift
958 ;; can be replaced by a "mc03" instruction, but this can only be done if
959 ;; followed by the right shift of 24 or more bits.
961 [(set (match_operand:SI 0 "register_operand" "")
962 (subreg:SI (match_operand:QI 1 "register_operand" "") 0))
964 (ashift:SI (match_dup 0)
967 (ashiftrt:SI (match_dup 0)
968 (match_operand:SI 2 "const_int_operand" "")))]
969 "INTVAL (operands[2]) >= 24"
970 "mc03 %0,%1\;sari16 %0,%S2"
971 [(set_attr "type" "multi")
972 (set_attr "length" "4")
973 (set_attr "cc" "sets")])
975 ;; Now zero extensions:
976 (define_expand "zero_extendhisi2"
977 [(set (match_operand:SI 0 "register_operand" "b")
978 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
983 [(set (match_operand:SI 0 "register_operand" "=b")
984 (zero_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))]
987 [(set_attr "type" "load")])
990 [(set (match_operand:SI 0 "register_operand" "=r,r,b")
991 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))]
997 [(set_attr "type" "arith,loadz,load")])
999 (define_expand "zero_extendqisi2"
1000 [(set (match_operand:SI 0 "register_operand" "")
1001 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1006 [(set (match_operand:SI 0 "register_operand" "=b")
1007 (zero_extend:SI (match_operand:QI 1 "symbolic_memory_operand" "m")))]
1010 [(set_attr "type" "load")])
1013 [(set (match_operand:SI 0 "register_operand" "=r,r,b")
1014 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))]
1020 [(set_attr "type" "arith,load,load")])
1022 (define_expand "zero_extendqihi2"
1023 [(set (match_operand:HI 0 "register_operand" "")
1024 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1029 [(set (match_operand:HI 0 "register_operand" "=b")
1030 (zero_extend:HI (match_operand:QI 1 "symbolic_memory_operand" "m")))]
1033 [(set_attr "type" "load")])
1036 [(set (match_operand:HI 0 "register_operand" "=r,r,b")
1037 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))]
1043 [(set_attr "type" "arith,load,load")])
1045 ;; Various extract and insertion operations.
1046 (define_expand "extzv"
1047 [(set (match_operand:SI 0 "register_operand" "")
1048 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
1049 (match_operand:SI 2 "const_int_operand" "")
1050 (match_operand:SI 3 "const_int_operand" "")))]
1054 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
1057 if (GET_CODE (operands[3]) != CONST_INT)
1060 if (INTVAL (operands[3]) != 0 && INTVAL (operands[3]) != 8
1061 && INTVAL (operands[3]) != 16 && INTVAL (operands[3]) != 24)
1066 [(set (match_operand:SI 0 "register_operand" "=&r")
1067 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1069 (match_operand:SI 2 "const_int_operand" "n")))]
1070 "(INTVAL (operands[2]) & 7) == 0"
1071 "lis %0,0\;mc3%B2 %0,%1"
1072 [(set_attr "type" "multi")
1073 (set_attr "cc" "change0")])
1076 [(set (match_operand:SI 0 "register_operand" "=&r")
1077 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1079 (match_operand:SI 2 "const_int_operand" "n")))]
1080 "(INTVAL (operands[2]) & 7) == 0"
1081 [(set (match_dup 0) (const_int 0))
1082 (set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 24))
1083 (zero_extract:SI (match_dup 1) (const_int 8) (match_dup 2)))]
1087 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1090 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1092 (match_operand:SI 2 "const_int_operand" "n")))]
1093 "(INTVAL (operands[2]) & 7) == 0"
1095 [(set_attr "type" "address")
1096 (set_attr "length" "2")])
1098 (define_expand "insv"
1099 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
1100 (match_operand:SI 1 "const_int_operand" "")
1101 (match_operand:SI 2 "const_int_operand" ""))
1102 (match_operand:SI 3 "register_operand" ""))]
1106 if (GET_CODE (operands[2]) != CONST_INT)
1109 if (GET_CODE (operands[1]) != CONST_INT)
1112 if (INTVAL (operands[1]) == 1)
1114 emit_insn (gen_bit_insv (operands[0], operands[1], operands[2],
1118 else if (INTVAL (operands[1]) == 8
1119 && (INTVAL (operands[2]) % 8 == 0))
1120 ; /* Accept aligned byte-wide field. */
1125 ;; For a single-bit insert, it is better to explicitly generate references
1126 ;; to the T bit. We will call the T bit "CC0" because it can be clobbered
1127 ;; by some CC0 sets (single-bit tests).
1129 (define_expand "bit_insv"
1131 (zero_extract:SI (match_operand:SI 3 "register_operand" "")
1134 (parallel [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
1135 (match_operand:SI 1 "const_int_operand" "")
1136 (match_operand:SI 2 "const_int_operand" ""))
1137 (ne (cc0) (const_int 0)))
1138 (clobber (match_scratch:SI 4 ""))])]
1143 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1145 (match_operand:SI 1 "const_int_operand" "n"))
1146 (match_operand:SI 2 "register_operand" "r"))]
1147 "(INTVAL (operands[1]) & 7) == 0"
1149 [(set_attr "type" "address")
1150 (set_attr "length" "2")])
1152 ;; This pattern cannot have any input reloads since if references CC0.
1153 ;; So we have to add code to support memory, which is the only other
1154 ;; thing that a "register_operand" can become. There is still a problem
1155 ;; if the address isn't valid and *it* needs a reload, but there is no
1156 ;; way to solve that problem, so let's hope it never happens.
1159 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,m")
1161 (match_operand:SI 1 "const_int_operand" "n,m"))
1162 (ne (cc0) (const_int 0)))
1163 (clobber (match_scratch:SI 2 "=X,b"))]
1167 l%M0 %2,%0\;mftb%t1 %2,%S1\;st%M0 %2,%0"
1168 [(set_attr "type" "*,multi")
1169 (set_attr "cc" "none,none")
1170 (set_attr "length" "2,10")])
1172 ;; Arithmetic instructions. First, add and subtract.
1174 ;; It may be that the second input is either large or small enough that
1175 ;; the operation cannot be done in a single insn. In that case, emit two.
1176 (define_expand "addsi3"
1177 [(set (match_operand:SI 0 "register_operand" "")
1178 (plus:SI (match_operand:SI 1 "register_operand" "")
1179 (match_operand:SI 2 "nonmemory_operand" "")))]
1183 if (GET_CODE (operands[2]) == CONST_INT
1184 && (unsigned) (INTVAL (operands[2]) + 0x8000) >= 0x10000
1185 && (INTVAL (operands[2]) & 0xffff) != 0)
1187 int low = INTVAL (operands[2]) & 0xffff;
1188 int high = (unsigned) INTVAL (operands[2]) >> 16;
1191 high++, low |= 0xffff0000;
1193 emit_insn (gen_addsi3 (operands[0], operands[1],
1194 gen_rtx (CONST_INT, VOIDmode, high << 16)));
1195 operands[1] = operands[0];
1196 operands[2] = gen_rtx (CONST_INT, VOIDmode, low);
1200 ;; Put the insn to add a symbolic constant to a register separately to
1201 ;; improve register allocation since it has different register requirements.
1203 [(set (match_operand:SI 0 "register_operand" "=b")
1204 (plus:SI (match_operand:SI 1 "register_operand" "%b")
1205 (match_operand:SI 2 "romp_symbolic_operand" "s")))]
1208 [(set_attr "type" "address")
1209 (set_attr "length" "8")])
1212 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,b")
1213 (plus:SI (match_operand:SI 1 "reg_or_add_operand" "%0,0,r,b,0,r,b")
1214 (match_operand:SI 2 "reg_or_add_operand" "I,J,K,M,r,b,s")))]
1215 "register_operand (operands[1], SImode)
1216 || register_operand (operands[2], SImode)"
1225 [(set_attr "type" "arith,arith,arith,address,arith,address,misc")
1226 (set_attr "length" "2,2,4,4,2,2,8")])
1230 ;; 1. If third operand is constant integer, convert it to add of the negative
1232 ;; 2. If the second operand is not a valid constant integer, force it into a
1234 (define_expand "subsi3"
1235 [(set (match_operand:SI 0 "register_operand" "")
1236 (minus:SI (match_operand:SI 1 "reg_or_any_cint_operand" "")
1237 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1241 if (GET_CODE (operands [2]) == CONST_INT)
1243 emit_insn (gen_addsi3 (operands[0], operands[1],
1245 VOIDmode, - INTVAL (operands[2]))));
1249 operands[2] = force_reg (SImode, operands[2]);
1251 if (GET_CODE (operands[1]) != CONST_INT
1252 || (unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000)
1253 operands[1] = force_reg (SImode, operands[1]);
1257 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1258 (minus:SI (match_operand:SI 1 "reg_or_D_operand" "K,0,r")
1259 (match_operand:SI 2 "register_operand" "r,r,0")))]
1265 [(set_attr "length" "4,2,2")])
1267 ;; Multiply either calls a special RT routine or is done in-line, depending
1268 ;; on the value of a -m flag.
1270 ;; First define the way we call the subroutine.
1271 (define_expand "mulsi3_subr"
1272 [(set (reg:SI 2) (match_operand:SI 1 "register_operand" ""))
1273 (set (reg:SI 3) (match_operand:SI 2 "register_operand" ""))
1274 (parallel [(set (reg:SI 2) (mult:SI (reg:SI 2) (reg:SI 3)))
1275 (clobber (reg:SI 0))
1276 (clobber (reg:SI 15))])
1277 (set (match_operand:SI 0 "register_operand" "")
1282 (define_expand "mulsi3"
1283 [(set (match_operand:SI 0 "register_operand" "")
1284 (mult:SI (match_operand:SI 1 "register_operand" "")
1285 (match_operand:SI 2 "register_operand" "")))]
1289 if (! TARGET_IN_LINE_MUL)
1291 emit_insn (gen_mulsi3_subr (operands[0], operands[1], operands[2]));
1296 ;; Define the patterns to match.
1297 ;; We would like to provide a delay slot for the insns that call internal
1298 ;; routines, but doing so is risky since reorg will think that the use of
1299 ;; r2 and r3 is completed in the insn needing the delay slot. Also, it
1300 ;; won't know that the cc will be clobbered. So take the safe approach
1301 ;; and don't give them delay slots.
1304 (mult:SI (reg:SI 2) (reg:SI 3)))
1305 (clobber (reg:SI 0))
1306 (clobber (reg:SI 15))]
1307 "! TARGET_IN_LINE_MUL"
1309 [(set_attr "type" "misc")
1310 (set_attr "in_delay_slot" "no")])
1313 [(set (match_operand:SI 0 "register_operand" "=&r")
1314 (mult:SI (match_operand:SI 1 "register_operand" "%r")
1315 (match_operand:SI 2 "register_operand" "r")))]
1316 "TARGET_IN_LINE_MUL"
1318 { return output_in_line_mul (); }"
1319 [(set_attr "length" "38")
1320 (set_attr "type" "multi")])
1322 ;; Handle divide and modulus. The same function returns both values,
1323 ;; so use divmodsi4. This divides arg 1 by arg 2 with quotient to go
1324 ;; into arg 0 and remainder in arg 3.
1326 ;; We want to put REG_EQUAL notes for the two outputs. So we need a
1327 ;; function to do everything else.
1328 (define_expand "divmodsi4_doit"
1330 (match_operand:SI 0 "register_operand" ""))
1332 (match_operand:SI 1 "register_operand" ""))
1333 (parallel [(set (reg:SI 2) (div:SI (reg:SI 2) (reg:SI 3)))
1334 (set (reg:SI 3) (mod:SI (reg:SI 2) (reg:SI 3)))
1335 (clobber (reg:SI 0))
1336 (clobber (reg:SI 15))])]
1340 (define_expand "divmodsi4"
1341 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1342 (div:SI (match_operand:SI 1 "register_operand" "")
1343 (match_operand:SI 2 "register_operand" "")))
1344 (set (match_operand:SI 3 "register_operand" "")
1345 (mod:SI (match_dup 1) (match_dup 2)))])]
1351 emit_insn (gen_divmodsi4_doit (operands[1], operands[2]));
1352 insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2));
1353 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1354 gen_rtx (DIV, SImode, operands[1],
1357 insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3));
1358 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1359 gen_rtx (MOD, SImode, operands[1],
1367 (div:SI (reg:SI 2) (reg:SI 3)))
1369 (mod:SI (reg:SI 2) (reg:SI 3)))
1370 (clobber (reg:SI 0))
1371 (clobber (reg:SI 15))]
1374 [(set_attr "type" "misc")
1375 (set_attr "in_delay_slot" "no")])
1377 ;; Similarly for unsigned divide.
1378 (define_expand "udivmodsi4_doit"
1380 (match_operand:SI 0 "register_operand" ""))
1382 (match_operand:SI 1 "register_operand" ""))
1383 (parallel [(set (reg:SI 2) (udiv:SI (reg:SI 2) (reg:SI 3)))
1384 (set (reg:SI 3) (umod:SI (reg:SI 2) (reg:SI 3)))
1385 (clobber (reg:SI 0))
1386 (clobber (reg:SI 15))])]
1390 (define_expand "udivmodsi4"
1391 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1392 (udiv:SI (match_operand:SI 1 "register_operand" "")
1393 (match_operand:SI 2 "register_operand" "")))
1394 (set (match_operand:SI 3 "register_operand" "")
1395 (umod:SI (match_dup 1) (match_dup 2)))])]
1401 emit_insn (gen_udivmodsi4_doit (operands[1], operands[2]));
1402 insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2));
1403 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1404 gen_rtx (UDIV, SImode, operands[1],
1407 insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3));
1408 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1409 gen_rtx (UMOD, SImode, operands[1],
1417 (udiv:SI (reg:SI 2) (reg:SI 3)))
1419 (umod:SI (reg:SI 2) (reg:SI 3)))
1420 (clobber (reg:SI 0))
1421 (clobber (reg:SI 15))]
1423 "bali%# r15,uldiv$$"
1424 [(set_attr "type" "misc")
1425 (set_attr "in_delay_slot" "no")])
1427 ;; Define DImode arithmetic operations.
1429 ;; It is possible to do certain adds and subtracts with constants in a single
1430 ;; insn, but it doesn't seem worth the trouble.
1432 ;; Don't use DEFINE_SPLIT on these because the dependency on CC can't be
1433 ;; easily tracked in that case!
1434 (define_insn "adddi3"
1435 [(set (match_operand:DI 0 "register_operand" "=r")
1436 (plus:DI (match_operand:DI 1 "register_operand" "%0")
1437 (match_operand:DI 2 "register_operand" "r")))]
1439 "a %O0,%O2\;ae %0,%2"
1440 [(set_attr "type" "multi")])
1442 (define_insn "subdi3"
1443 [(set (match_operand:DI 0 "register_operand" "=r")
1444 (minus:DI (match_operand:DI 1 "register_operand" "0")
1445 (match_operand:DI 2 "register_operand" "r")))]
1447 "s %O0,%O2\;se %0,%2"
1448 [(set_attr "type" "multi")])
1450 (define_insn "negdi2"
1451 [(set (match_operand:DI 0 "register_operand" "=r,&r")
1452 (neg:DI (match_operand:DI 1 "register_operand" "0,r")))]
1454 "twoc %O0,%O1\;onec %0,%1\;aei %0,%0,0"
1455 [(set_attr "type" "multi")
1456 (set_attr "length" "8")])
1458 ;; Unary arithmetic operations.
1459 (define_insn "abssi2"
1460 [(set (match_operand:SI 0 "register_operand" "=r")
1461 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1464 [(set_attr "length" "2")])
1466 (define_insn "negsi2"
1467 [(set (match_operand:SI 0 "register_operand" "=r")
1468 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1471 [(set_attr "length" "2")])
1473 (define_insn "one_cmplsi2"
1474 [(set (match_operand:SI 0 "register_operand" "=r")
1475 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1478 [(set_attr "length" "2")])
1481 ;; Logical insns: AND, IOR, and XOR
1483 ;; If the operation is being performed on a 32-bit constant such that
1484 ;; it cannot be done in one insn, do it in two. We may lose a bit on
1485 ;; CSE in pathological cases, but it seems better doing it this way.
1486 (define_expand "andsi3"
1487 [(set (match_operand:SI 0 "register_operand" "")
1488 (and:SI (match_operand:SI 1 "register_operand" "")
1489 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1493 if (GET_CODE (operands[2]) == CONST_INT)
1495 int top = (unsigned) INTVAL (operands[2]) >> 16;
1496 int bottom = INTVAL (operands[2]) & 0xffff;
1498 if (top != 0 && top != 0xffff && bottom != 0 && bottom != 0xffff)
1500 emit_insn (gen_andsi3 (operands[0], operands[1],
1501 gen_rtx (CONST_INT, VOIDmode,
1502 (top << 16) | 0xffff)));
1503 operands[1] = operands[0];
1504 operands[2] = gen_rtx (CONST_INT, VOIDmode, 0xffff0000 | bottom);
1510 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1511 (and:SI (match_operand:SI 1 "reg_or_and_operand" "%0,r,0")
1512 (match_operand:SI 2 "reg_or_and_operand" "P,LMO,r")))]
1513 "register_operand (operands[1], SImode)
1514 || register_operand (operands[2], SImode)"
1519 [(set_attr "length" "2,4,2")])
1522 (define_expand "iorsi3"
1523 [(set (match_operand:SI 0 "register_operand" "")
1524 (ior:SI (match_operand:SI 1 "register_operand" "")
1525 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1529 if (GET_CODE (operands[2]) == CONST_INT)
1531 int top = (unsigned) INTVAL (operands[2]) >> 16;
1532 int bottom = INTVAL (operands[2]) & 0xffff;
1534 if (top != 0 && bottom != 0)
1536 emit_insn (gen_iorsi3 (operands[0], operands[1],
1537 gen_rtx (CONST_INT, VOIDmode, (top << 16))));
1538 operands[1] = operands[0];
1539 operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom);
1545 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1546 (ior:SI (match_operand:SI 1 "reg_or_cint_operand" "%0,r,0")
1547 (match_operand:SI 2 "reg_or_cint_operand" "N,LM,r")))]
1548 "register_operand (operands[1], SImode)
1549 || register_operand (operands[2], SImode)"
1554 [(set_attr "length" "2,4,2")])
1556 ;; exclusive-or (XOR)
1557 (define_expand "xorsi3"
1558 [(set (match_operand:SI 0 "register_operand" "")
1559 (xor:SI (match_operand:SI 1 "register_operand" "")
1560 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1564 if (GET_CODE (operands[2]) == CONST_INT)
1566 int top = (unsigned) INTVAL (operands[2]) >> 16;
1567 int bottom = INTVAL (operands[2]) & 0xffff;
1569 if (top == 0xffff && bottom == 0xffff)
1571 emit_insn (gen_one_cmplsi2 (operands[0], operands[1]));
1574 else if (top != 0 && bottom != 0)
1576 emit_insn (gen_xorsi3 (operands[0], operands[1],
1577 gen_rtx (CONST_INT, VOIDmode, (top << 16))));
1578 operands[1] = operands[0];
1579 operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom);
1585 [(set (match_operand:SI 0 "register_operand" "=r,r")
1586 (xor:SI (match_operand:SI 1 "reg_or_cint_operand" "%r,0")
1587 (match_operand:SI 2 "reg_or_cint_operand" "LM,r")))]
1588 "register_operand (operands[1], SImode)
1589 || register_operand (operands[2], SImode)"
1593 [(set_attr "length" "4,2")])
1595 ;; Various shift insns
1596 (define_insn "ashrsi3"
1597 [(set (match_operand:SI 0 "register_operand" "=r,r")
1598 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1599 (match_operand:QI 2 "reg_or_cint_operand" "r,n")))]
1604 [(set_attr "length" "2")])
1606 (define_insn "lshrsi3"
1607 [(set (match_operand:SI 0 "register_operand" "=r,r")
1608 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1609 (match_operand:QI 2 "reg_or_cint_operand" "r,n")))]
1614 [(set_attr "length" "2")])
1617 [(set (match_operand:SI 0 "register_operand" "=r")
1618 (ashift:SI (match_operand:SI 1 "register_operand" "b")
1622 [(set_attr "length" "2")
1623 (set_attr "type" "address")])
1625 (define_insn "ashlsi3"
1626 [(set (match_operand:SI 0 "register_operand" "=r,r")
1627 (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1628 (match_operand:QI 2 "reg_or_cint_operand" "r,n")))]
1633 [(set_attr "length" "2")])
1635 ;; Function call insns:
1637 ;; On the ROMP, &fcn is actually a pointer to the data area, which is passed
1638 ;; to the function in r0. &.fcn is the actual starting address of the
1639 ;; function. Also, the word at &fcn contains &.fcn.
1641 ;; For both functions that do and don't return values, there are two cases:
1642 ;; where the function's address is a constant, and where it isn't.
1644 ;; Operand 1 (2 for `call_value') is the number of arguments and is not used.
1645 (define_expand "call"
1647 (parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
1648 (match_operand 1 "" ""))
1649 (clobber (reg:SI 15))])]
1653 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
1656 operands[0] = XEXP (operands[0], 0);
1657 if (GET_CODE (operands[0]) == SYMBOL_REF)
1659 extern rtx get_symref ();
1660 char *real_fcnname =
1661 (char *) alloca (strlen (XSTR (operands[0], 0)) + 2);
1663 /* Copy the data area address to r0. */
1664 emit_move_insn (gen_rtx (REG, SImode, 0),
1665 force_reg (SImode, operands[0]));
1666 strcpy (real_fcnname, \".\");
1667 strcat (real_fcnname, XSTR (operands[0], 0));
1668 operands[0] = get_symref (real_fcnname);
1674 emit_move_insn (gen_rtx (REG, SImode, 0),
1675 force_reg (SImode, operands[0]));
1676 data_access = gen_rtx (MEM, SImode, operands[0]);
1677 RTX_UNCHANGING_P (data_access) = 1;
1678 operands[0] = copy_to_reg (data_access);
1683 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
1684 (match_operand 1 "" "g"))
1685 (clobber (reg:SI 15))]
1688 [(set_attr "type" "call")
1689 (set_attr "length" "2")])
1692 [(call (mem:SI (match_operand:SI 0 "romp_symbolic_operand" "i"))
1693 (match_operand 1 "" "g"))
1694 (clobber (reg:SI 15))]
1695 "GET_CODE (operands[0]) == SYMBOL_REF"
1697 [(set_attr "type" "call")])
1699 ;; Call a function and return a value.
1700 (define_expand "call_value"
1702 (parallel [(set (match_operand 0 "" "=fg")
1703 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
1704 (match_operand 2 "" "")))
1705 (clobber (reg:SI 15))])]
1709 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
1712 operands[1] = XEXP (operands[1], 0);
1713 if (GET_CODE (operands[1]) == SYMBOL_REF)
1715 extern rtx get_symref ();
1716 char *real_fcnname =
1717 (char *) alloca (strlen (XSTR (operands[1], 0)) + 2);
1719 /* Copy the data area address to r0. */
1720 emit_move_insn (gen_rtx (REG, SImode, 0),
1721 force_reg (SImode, operands[1]));
1722 strcpy (real_fcnname, \".\");
1723 strcat (real_fcnname, XSTR (operands[1], 0));
1724 operands[1] = get_symref (real_fcnname);
1730 emit_move_insn (gen_rtx (REG, SImode, 0),
1731 force_reg (SImode, operands[1]));
1732 data_access = gen_rtx (MEM, SImode, operands[1]);
1733 RTX_UNCHANGING_P (data_access) = 1;
1734 operands[1] = copy_to_reg (data_access);
1739 [(set (match_operand 0 "" "=fg")
1740 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
1741 (match_operand 2 "" "g")))
1742 (clobber (reg:SI 15))]
1745 [(set_attr "length" "2")
1746 (set_attr "type" "call")])
1749 [(set (match_operand 0 "" "=fg")
1750 (call (mem:SI (match_operand:SI 1 "romp_symbolic_operand" "i"))
1751 (match_operand 2 "" "g")))
1752 (clobber (reg:SI 15))]
1753 "GET_CODE (operands[1]) == SYMBOL_REF"
1755 [(set_attr "type" "call")])
1757 ;; No operation insn.
1762 [(set_attr "type" "address")
1763 (set_attr "length" "2")
1764 (set_attr "cc" "none")])
1766 ;; Here are the floating-point operations.
1768 ;; Start by providing DEFINE_EXPAND for each operation.
1769 ;; The insns will be handled with MATCH_OPERATOR; the methodology will be
1772 ;; First the conversion operations.
1774 (define_expand "truncdfsf2"
1775 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1776 (float_truncate:SF (match_operand:DF 1 "general_operand" "")))
1777 (clobber (reg:SI 0))
1778 (clobber (reg:SI 15))])]
1782 (define_expand "extendsfdf2"
1783 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1784 (float_extend:DF (match_operand:SF 1 "general_operand" "")))
1785 (clobber (reg:SI 0))
1786 (clobber (reg:SI 15))])]
1790 (define_expand "floatsisf2"
1791 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1792 (float:SF (match_operand:SI 1 "general_operand" "")))
1793 (clobber (reg:SI 0))
1794 (clobber (reg:SI 15))])]
1798 (define_expand "floatsidf2"
1799 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1800 (float:DF (match_operand:SI 1 "general_operand" "")))
1801 (clobber (reg:SI 0))
1802 (clobber (reg:SI 15))])]
1806 (define_expand "fix_truncsfsi2"
1807 [(parallel [(set (match_operand:SI 0 "general_operand" "")
1808 (fix:SI (match_operand:SF 1 "general_operand" "")))
1809 (clobber (reg:SI 0))
1810 (clobber (reg:SI 15))])]
1814 (define_expand "fix_truncdfsi2"
1815 [(parallel [(set (match_operand:SI 0 "general_operand" "")
1816 (fix:SI (match_operand:DF 1 "general_operand" "")))
1817 (clobber (reg:SI 0))
1818 (clobber (reg:SI 15))])]
1822 ;; Now the binary operations.
1824 (define_expand "addsf3"
1825 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1826 (plus:SF (match_operand:SF 1 "general_operand" "")
1827 (match_operand:SF 2 "general_operand" "")))
1828 (clobber (reg:SI 0))
1829 (clobber (reg:SI 15))])]
1833 (define_expand "adddf3"
1834 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1835 (plus:DF (match_operand:DF 1 "general_operand" "")
1836 (match_operand:DF 2 "general_operand" "")))
1837 (clobber (reg:SI 0))
1838 (clobber (reg:SI 15))])]
1842 (define_expand "subsf3"
1843 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1844 (minus:SF (match_operand:SF 1 "general_operand" "")
1845 (match_operand:SF 2 "general_operand" "")))
1846 (clobber (reg:SI 0))
1847 (clobber (reg:SI 15))])]
1851 (define_expand "subdf3"
1852 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1853 (minus:DF (match_operand:DF 1 "general_operand" "")
1854 (match_operand:DF 2 "general_operand" "")))
1855 (clobber (reg:SI 0))
1856 (clobber (reg:SI 15))])]
1860 (define_expand "mulsf3"
1861 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1862 (mult:SF (match_operand:SF 1 "general_operand" "")
1863 (match_operand:SF 2 "general_operand" "")))
1864 (clobber (reg:SI 0))
1865 (clobber (reg:SI 15))])]
1869 (define_expand "muldf3"
1870 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1871 (mult:DF (match_operand:DF 1 "general_operand" "")
1872 (match_operand:DF 2 "general_operand" "")))
1873 (clobber (reg:SI 0))
1874 (clobber (reg:SI 15))])]
1878 (define_expand "divsf3"
1879 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1880 (div:SF (match_operand:SF 1 "general_operand" "")
1881 (match_operand:SF 2 "general_operand" "")))
1882 (clobber (reg:SI 0))
1883 (clobber (reg:SI 15))])]
1887 (define_expand "divdf3"
1888 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1889 (div:DF (match_operand:DF 1 "general_operand" "")
1890 (match_operand:DF 2 "general_operand" "")))
1891 (clobber (reg:SI 0))
1892 (clobber (reg:SI 15))])]
1896 ;; Unary floating-point operations.
1898 ;; Negations can be done without floating-point, since this is IEEE.
1899 ;; But we cannot do this if an operand is a hard FP register, since
1900 ;; the SUBREG we create would not be valid.
1901 (define_expand "negsf2"
1902 [(set (match_operand:SF 0 "register_operand" "")
1903 (neg:SF (match_operand:SF 1 "register_operand" "")))]
1907 if (! (GET_CODE (operands[0]) == REG
1908 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
1909 && FP_REGNO_P (REGNO (operands[0])))
1910 && ! (GET_CODE (operands[1]) == REG
1911 && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
1912 && FP_REGNO_P (REGNO (operands[1]))))
1915 rtx target = operand_subword (operands[0], 0, 1, SFmode);
1917 result = expand_binop (SImode, xor_optab,
1918 operand_subword_force (operands[1], 0, SFmode),
1919 gen_rtx (CONST_INT, VOIDmode, 0x80000000),
1920 target, 0, OPTAB_WIDEN);
1924 if (result != target)
1925 emit_move_insn (result, target);
1927 /* Make a place for REG_EQUAL. */
1928 emit_move_insn (operands[0], operands[0]);
1933 (define_expand "negdf2"
1934 [(set (match_operand:DF 0 "register_operand" "")
1935 (neg:DF (match_operand:DF 1 "register_operand" "")))]
1939 if (! (GET_CODE (operands[0]) == REG
1940 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
1941 && FP_REGNO_P (REGNO (operands[0])))
1942 && ! (GET_CODE (operands[1]) == REG
1943 && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
1944 && FP_REGNO_P (REGNO (operands[1]))))
1947 rtx target = operand_subword (operands[0], 0, 1, DFmode);
1951 result = expand_binop (SImode, xor_optab,
1952 operand_subword_force (operands[1], 0, DFmode),
1953 gen_rtx (CONST_INT, VOIDmode, 0x80000000),
1954 target, 0, OPTAB_WIDEN);
1958 if (result != target)
1959 emit_move_insn (result, target);
1961 emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
1962 operand_subword_force (operands[1], 1, DFmode));
1964 insns = get_insns ();
1967 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1972 (define_expand "abssf2"
1973 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1974 (abs:SF (match_operand:SF 1 "general_operand" "")))
1975 (clobber (reg:SI 0))
1976 (clobber (reg:SI 15))])]
1980 (define_expand "absdf2"
1981 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1982 (abs:DF (match_operand:DF 1 "general_operand" "")))
1983 (clobber (reg:SI 0))
1984 (clobber (reg:SI 15))])]
1988 ;; Any floating-point operation can be either SFmode or DFmode, and each
1989 ;; operand (including the output) can be either a normal operand or a
1990 ;; conversion from a normal operand.
1992 ;; We use MATCH_OPERATOR to match a floating-point binary or unary operator
1993 ;; and input and output conversions. So we need 2^N patterns for each type
1994 ;; of operation, where N is the number of operands, including the output.
1995 ;; There are thus a total of 14 patterns, 8 for binary operations, 4 for
1996 ;; unary operations and two for conversion/move operations (only one
1997 ;; operand can have a conversion for move operations). In addition, we have
1998 ;; to be careful that a floating-point reload register doesn't get allocated
1999 ;; for an integer. We take care of this for inputs with PREFERRED_RELOAD_CLASS
2000 ;; but need to have two different constraints for outputs. This means that
2001 ;; we have to duplicate each pattern where the output could be an integer.
2002 ;; This adds another 7 patterns, for a total of 21.
2004 ;; Start with conversion operations (moves are done above).
2007 [(set (match_operand:SI 0 "general_operand" "=g")
2008 (match_operator 1 "float_conversion"
2009 [(match_operand 2 "general_operand" "frg")]))
2010 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2011 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2014 { return output_fpop (SET, operands[0], operands[2], 0, insn);
2016 [(set_attr "type" "fp")])
2019 [(set (match_operand 0 "general_operand" "=frg")
2020 (match_operator 1 "float_conversion"
2021 [(match_operand 2 "general_operand" "frg")]))
2022 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2023 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2026 { return output_fpop (SET, operands[0], operands[2], 0, insn);
2028 [(set_attr "type" "fp")])
2030 ;; Next, binary floating-point operations.
2033 [(set (match_operand 0 "general_operand" "=frg")
2034 (match_operator 1 "float_binary"
2035 [(match_operand 2 "general_operand" "frg")
2036 (match_operand 3 "general_operand" "frg")]))
2037 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2038 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2039 "check_precision (GET_MODE (operands[1]), operands[2], operands[3])"
2041 { return output_fpop (GET_CODE (operands[1]), operands[0],
2042 operands[2], operands[3], insn);
2044 [(set_attr "type" "fp")])
2047 [(set (match_operand 0 "general_operand" "=frg")
2048 (match_operator 1 "float_binary"
2049 [(match_operand 2 "general_operand" "frg")
2050 (match_operator 3 "float_conversion"
2051 [(match_operand 4 "general_operand" "frg")])]))
2052 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2053 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2054 "check_precision (GET_MODE (operands[1]), operands[2], operands[4])"
2056 { return output_fpop (GET_CODE (operands[1]), operands[0],
2057 operands[2], operands[4], insn);
2059 [(set_attr "type" "fp")])
2062 [(set (match_operand 0 "general_operand" "=frg")
2063 (match_operator 1 "float_binary"
2064 [(match_operator 2 "float_conversion"
2065 [(match_operand 3 "general_operand" "frg")])
2066 (match_operand 4 "general_operand" "frg")]))
2067 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2068 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2069 "check_precision (GET_MODE (operands[1]), operands[3], operands[4])"
2071 { return output_fpop (GET_CODE (operands[1]), operands[0],
2072 operands[3], operands[4], insn);
2074 [(set_attr "type" "fp")])
2077 [(set (match_operand 0 "general_operand" "=frg")
2078 (match_operator 1 "float_binary"
2079 [(match_operator 2 "float_conversion"
2080 [(match_operand 3 "general_operand" "frg")])
2081 (match_operator 4 "float_conversion"
2082 [(match_operand 5 "general_operand" "frg")])]))
2083 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2084 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2085 "check_precision (GET_MODE (operands[1]), operands[3], operands[5])"
2087 { return output_fpop (GET_CODE (operands[1]), operands[0],
2088 operands[3], operands[5], insn);
2090 [(set_attr "type" "fp")])
2093 [(set (match_operand:SI 0 "general_operand" "=g")
2094 (match_operator 1 "float_conversion"
2095 [(match_operator 2 "float_binary"
2096 [(match_operand 3 "general_operand" "frg")
2097 (match_operand 4 "general_operand" "frg")])]))
2098 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2099 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2100 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2102 { return output_fpop (GET_CODE (operands[2]), operands[0],
2103 operands[3], operands[4], insn);
2105 [(set_attr "type" "fp")])
2108 [(set (match_operand 0 "general_operand" "=frg")
2109 (match_operator 1 "float_conversion"
2110 [(match_operator 2 "float_binary"
2111 [(match_operand 3 "general_operand" "frg")
2112 (match_operand 4 "general_operand" "frg")])]))
2113 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2114 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2115 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2117 { return output_fpop (GET_CODE (operands[2]), operands[0],
2118 operands[3], operands[4], insn);
2120 [(set_attr "type" "fp")])
2123 [(set (match_operand:SI 0 "general_operand" "=g")
2124 (match_operator 1 "float_conversion"
2125 [(match_operator 2 "float_binary"
2126 [(match_operand 3 "general_operand" "frg")
2127 (match_operator 4 "float_conversion"
2128 [(match_operand 5 "general_operand" "frg")])])]))
2129 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2130 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2131 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2133 { return output_fpop (GET_CODE (operands[2]), operands[0],
2134 operands[3], operands[5], insn);
2136 [(set_attr "type" "fp")])
2139 [(set (match_operand 0 "general_operand" "=frg")
2140 (match_operator 1 "float_conversion"
2141 [(match_operator 2 "float_binary"
2142 [(match_operand 3 "general_operand" "frg")
2143 (match_operator 4 "float_conversion"
2144 [(match_operand 5 "general_operand" "frg")])])]))
2145 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2146 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2147 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2149 { return output_fpop (GET_CODE (operands[2]), operands[0],
2150 operands[3], operands[5], insn);
2152 [(set_attr "type" "fp")])
2155 [(set (match_operand:SI 0 "general_operand" "=g")
2156 (match_operator 1 "float_conversion"
2157 [(match_operator 2 "float_binary"
2158 [(match_operator 3 "float_conversion"
2159 [(match_operand 4 "general_operand" "frg")])
2160 (match_operand 5 "general_operand" "frg")])]))
2161 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2162 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2163 "check_precision (GET_MODE (operands[2]), operands[4], operands[5])"
2165 { return output_fpop (GET_CODE (operands[2]), operands[0],
2166 operands[4], operands[5], insn);
2168 [(set_attr "type" "fp")])
2171 [(set (match_operand 0 "general_operand" "=frg")
2172 (match_operator 1 "float_conversion"
2173 [(match_operator 2 "float_binary"
2174 [(match_operator 3 "float_conversion"
2175 [(match_operand 4 "general_operand" "frg")])
2176 (match_operand 5 "general_operand" "frg")])]))
2177 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2178 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2179 "check_precision (GET_MODE (operands[2]), operands[4], operands[5])"
2181 { return output_fpop (GET_CODE (operands[2]), operands[0],
2182 operands[4], operands[5], insn);
2184 [(set_attr "type" "fp")])
2187 [(set (match_operand:SI 0 "general_operand" "=g")
2188 (match_operator 1 "float_conversion"
2189 [(match_operator 2 "float_binary"
2190 [(match_operator 3 "float_conversion"
2191 [(match_operand 4 "general_operand" "frg")])
2192 (match_operator 5 "float_conversion"
2193 [(match_operand 6 "general_operand" "frg")])])]))
2194 (clobber (match_operand:SI 7 "reg_0_operand" "=&z"))
2195 (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))]
2196 "check_precision (GET_MODE (operands[2]), operands[4], operands[6])"
2198 { return output_fpop (GET_CODE (operands[2]), operands[0],
2199 operands[4], operands[6], insn);
2201 [(set_attr "type" "fp")])
2204 [(set (match_operand 0 "general_operand" "=frg")
2205 (match_operator 1 "float_conversion"
2206 [(match_operator 2 "float_binary"
2207 [(match_operator 3 "float_conversion"
2208 [(match_operand 4 "general_operand" "frg")])
2209 (match_operator 5 "float_conversion"
2210 [(match_operand 6 "general_operand" "frg")])])]))
2211 (clobber (match_operand:SI 7 "reg_0_operand" "=&z"))
2212 (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))]
2213 "check_precision (GET_MODE (operands[2]), operands[4], operands[6])"
2215 { return output_fpop (GET_CODE (operands[2]), operands[0],
2216 operands[4], operands[6], insn);
2218 [(set_attr "type" "fp")])
2220 ;; Unary floating-point operations.
2223 [(set (match_operand 0 "general_operand" "=frg")
2224 (match_operator 1 "float_unary"
2225 [(match_operand 2 "general_operand" "frg")]))
2226 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2227 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2228 "check_precision (GET_MODE (operands[1]), operands[2], 0)"
2230 { return output_fpop (GET_CODE (operands[1]), operands[0], operands[2],
2233 [(set_attr "type" "fp")])
2236 [(set (match_operand 0 "general_operand" "=frg")
2237 (match_operator 1 "float_unary"
2238 [(match_operator 2 "float_conversion"
2239 [(match_operand 3 "general_operand" "frg")])]))
2240 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2241 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2242 "check_precision (GET_MODE (operands[1]), operands[3], 0)"
2244 { return output_fpop (GET_CODE (operands[1]), operands[0], operands[3],
2247 [(set_attr "type" "fp")])
2250 [(set (match_operand:SI 0 "general_operand" "=g")
2251 (match_operator 1 "float_conversion"
2252 [(match_operator 2 "float_unary"
2253 [(match_operand 3 "general_operand" "frg")])]))
2254 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2255 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2256 "check_precision (GET_MODE (operands[2]), operands[3], 0)"
2258 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3],
2261 [(set_attr "type" "fp")])
2264 [(set (match_operand 0 "general_operand" "=frg")
2265 (match_operator 1 "float_conversion"
2266 [(match_operator 2 "float_unary"
2267 [(match_operand 3 "general_operand" "frg")])]))
2268 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2269 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2270 "check_precision (GET_MODE (operands[2]), operands[3], 0)"
2272 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3],
2275 [(set_attr "type" "fp")])
2278 [(set (match_operand:SI 0 "general_operand" "=g")
2279 (match_operator 1 "float_conversion"
2280 [(match_operator 2 "float_unary"
2281 [(match_operator 3 "float_conversion"
2282 [(match_operand 4 "general_operand" "frg")])])]))
2283 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2284 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2285 "check_precision (GET_MODE (operands[2]), operands[4], 0)"
2287 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4],
2290 [(set_attr "type" "fp")])
2293 [(set (match_operand 0 "general_operand" "=frg")
2294 (match_operator 1 "float_conversion"
2295 [(match_operator 2 "float_unary"
2296 [(match_operator 3 "float_conversion"
2297 [(match_operand 4 "general_operand" "frg")])])]))
2298 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2299 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2300 "check_precision (GET_MODE (operands[2]), operands[4], 0)"
2302 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4],
2305 [(set_attr "type" "fp")])
2307 ;; Compare insns are next. Note that the ROMP has two types of compares,
2308 ;; signed & unsigned, and one type of branch. Use the routine
2309 ;; `next_insn_tests_no_unsigned' to see which type to use.
2310 (define_expand "tstsi"
2312 (match_operand:SI 0 "register_operand" "r"))]
2316 (define_expand "cmpsi"
2318 (compare (match_operand:SI 0 "register_operand" "")
2319 (match_operand:SI 1 "reg_or_cint_operand" "")))]
2323 ;; Signed compare, `test' first.
2327 (match_operand:SI 0 "register_operand" "r"))]
2328 "next_insn_tests_no_unsigned (insn)"
2330 [(set_attr "length" "2")
2331 (set_attr "type" "compare")])
2334 [(set (cc0) (match_operand:SI 0 "register_operand" "r,r,r"))
2335 (set (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "=0,r,Q")
2337 "next_insn_tests_no_unsigned (insn)"
2341 st%M1 %0,%1\;cis %0,0"
2342 [(set_attr "type" "compare,compare,store")
2343 (set_attr "length" "2,4,6")
2344 (set_attr "cc" "compare")])
2348 (compare (match_operand:SI 0 "register_operand" "r,r,r")
2349 (match_operand:SI 1 "reg_or_cint_operand" "I,K,r")))]
2350 "next_insn_tests_no_unsigned (insn)"
2355 [(set_attr "length" "2,4,2")
2356 (set_attr "type" "compare")])
2358 ;; Unsigned comparisons, `test' first, again.
2361 (match_operand:SI 0 "register_operand" "r"))]
2362 "! next_insn_tests_no_unsigned (insn)"
2364 [(set_attr "type" "compare")])
2368 (compare (match_operand:SI 0 "register_operand" "r,r")
2369 (match_operand:SI 1 "reg_or_cint_operand" "K,r")))]
2370 "! next_insn_tests_no_unsigned (insn)"
2374 [(set_attr "length" "4,2")
2375 (set_attr "type" "compare")])
2377 ;; Bit test insn. Many cases are converted into this by combine. This
2378 ;; uses the ROMP test bit.
2382 (zero_extract (match_operand:SI 0 "register_operand" "r,r")
2384 (match_operand:SI 1 "reg_or_any_cint_operand" "r,n")))]
2385 "next_insn_tests_no_inequality (insn)"
2389 [(set_attr "length" "2")
2390 (set_attr "type" "compare")
2391 (set_attr "cc" "tbit")])
2393 ;; Floating-point comparisons. There are two, equality and order.
2394 ;; The difference will be that a trap for NaN will be given on the orderr
2395 ;; comparisons only.
2397 (define_expand "cmpsf"
2398 [(parallel [(set (cc0) (compare (match_operand:SF 0 "general_operand" "")
2399 (match_operand:SF 1 "general_operand" "")))
2400 (clobber (reg:SI 0))
2401 (clobber (reg:SI 15))])]
2405 (define_expand "cmpdf"
2406 [(parallel [(set (cc0) (compare (match_operand:DF 0 "general_operand" "")
2407 (match_operand:DF 1 "general_operand" "")))
2408 (clobber (reg:SI 0))
2409 (clobber (reg:SI 15))])]
2413 (define_expand "tstsf"
2414 [(parallel [(set (cc0) (match_operand:SF 0 "general_operand" ""))
2415 (clobber (reg:SI 0))
2416 (clobber (reg:SI 15))])]
2420 (define_expand "tstdf"
2421 [(parallel [(set (cc0) (match_operand:DF 0 "general_operand" ""))
2422 (clobber (reg:SI 0))
2423 (clobber (reg:SI 15))])]
2427 ;; There are four cases for compare and two for test. These correspond
2428 ;; to each input having a floating-point conversion or not.
2431 [(set (cc0) (compare (match_operand 0 "general_operand" "frg")
2432 (match_operand 1 "general_operand" "frg")))
2433 (clobber (match_operand:SI 2 "reg_0_operand" "=&z"))
2434 (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))]
2435 "GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode"
2437 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2438 operands[0], operands[1], 0, insn);
2440 [(set_attr "type" "fp")
2441 (set_attr "cc" "compare")])
2444 [(set (cc0) (compare (match_operand 0 "general_operand" "frg")
2445 (match_operator 1 "float_conversion"
2446 [(match_operand 2 "general_operand" "frg")])))
2447 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2448 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2451 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2452 operands[0], operands[2], 0, insn);
2454 [(set_attr "type" "fp")
2455 (set_attr "cc" "compare")])
2458 [(set (cc0) (compare (match_operator 0 "float_conversion"
2459 [(match_operand 1 "general_operand" "frg")])
2460 (match_operand 2 "general_operand" "frg")))
2461 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2462 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2465 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2466 operands[1], operands[2], 0, insn);
2468 [(set_attr "type" "fp")
2469 (set_attr "cc" "compare")])
2472 [(set (cc0) (compare (match_operator 0 "float_conversion"
2473 [(match_operand 1 "general_operand" "frg")])
2474 (match_operator 2 "float_conversion"
2475 [(match_operand 3 "general_operand" "frg")])))
2476 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2477 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2480 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2481 operands[1], operands[3], 0, insn);
2483 [(set_attr "type" "fp")
2484 (set_attr "cc" "compare")])
2487 [(set (cc0) (match_operand 0 "general_operand" "frg"))
2488 (clobber (match_operand:SI 1 "reg_0_operand" "=&z"))
2489 (clobber (match_operand:SI 2 "reg_15_operand" "=&t"))]
2490 "GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode"
2492 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2493 operands[0], immed_real_const_1 (0, 0,
2494 GET_MODE (operands[0])),
2497 [(set_attr "type" "fp")
2498 (set_attr "cc" "compare")])
2501 [(set (cc0) (match_operator 0 "float_conversion"
2502 [(match_operand 1 "general_operand" "frg")]))
2503 (clobber (match_operand:SI 2 "reg_0_operand" "=&z"))
2504 (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))]
2507 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2508 operands[1], immed_real_const_1 (0, 0,
2509 GET_MODE (operands[1])),
2512 [(set_attr "type" "fp")
2513 (set_attr "cc" "compare")])
2515 ;; Branch insns. Unsigned vs. signed have already
2516 ;; been taken care of. The only insns that need to be concerned about the
2517 ;; test bit are beq and bne because the rest are either always true,
2518 ;; always false, or converted to EQ or NE.
2520 ;; For conditional branches, we use `define_expand' and just have two patterns
2521 ;; that match them. Operand printing does most of the work.
2523 (define_expand "beq"
2525 (if_then_else (eq (cc0)
2527 (label_ref (match_operand 0 "" ""))
2532 (define_expand "bne"
2534 (if_then_else (ne (cc0)
2536 (label_ref (match_operand 0 "" ""))
2541 (define_expand "bgt"
2543 (if_then_else (gt (cc0)
2545 (label_ref (match_operand 0 "" ""))
2550 (define_expand "bgtu"
2552 (if_then_else (gtu (cc0)
2554 (label_ref (match_operand 0 "" ""))
2559 (define_expand "blt"
2561 (if_then_else (lt (cc0)
2563 (label_ref (match_operand 0 "" ""))
2568 (define_expand "bltu"
2570 (if_then_else (ltu (cc0)
2572 (label_ref (match_operand 0 "" ""))
2577 (define_expand "bge"
2579 (if_then_else (ge (cc0)
2581 (label_ref (match_operand 0 "" ""))
2586 (define_expand "bgeu"
2588 (if_then_else (geu (cc0)
2590 (label_ref (match_operand 0 "" ""))
2595 (define_expand "ble"
2597 (if_then_else (le (cc0)
2599 (label_ref (match_operand 0 "" ""))
2604 (define_expand "bleu"
2606 (if_then_else (leu (cc0)
2608 (label_ref (match_operand 0 "" ""))
2613 ;; Define both directions of branch and return.
2617 (if_then_else (match_operator 1 "comparison_operator"
2618 [(cc0) (const_int 0)])
2619 (label_ref (match_operand 0 "" ""))
2624 if (restore_compare_p (operands[1]))
2626 else if (get_attr_length (insn) == 2)
2627 return \"j%j1 %l0\";
2629 return \"b%j1%# %l0\";
2631 [(set_attr "type" "branch")])
2635 (if_then_else (match_operator 0 "comparison_operator"
2636 [(cc0) (const_int 0)])
2642 if (restore_compare_p (operands[0]))
2645 return \"b%j0r%# r15\";
2647 [(set_attr "type" "return")])
2651 (if_then_else (match_operator 1 "comparison_operator"
2652 [(cc0) (const_int 0)])
2654 (label_ref (match_operand 0 "" ""))))]
2658 if (restore_compare_p (operands[1]))
2660 else if (get_attr_length (insn) == 2)
2661 return \"j%J1 %l0\";
2663 return \"b%J1%# %l0\";
2665 [(set_attr "type" "branch")])
2669 (if_then_else (match_operator 0 "comparison_operator"
2670 [(cc0) (const_int 0)])
2676 if (restore_compare_p (operands[0]))
2679 return \"b%J0r%# r15\";
2681 [(set_attr "type" "return")])
2683 ;; Unconditional branch and return.
2687 (label_ref (match_operand 0 "" "")))]
2691 if (get_attr_length (insn) == 2)
2696 [(set_attr "type" "branch")])
2698 (define_insn "return"
2702 [(set_attr "type" "return")])
2704 (define_insn "indirect_jump"
2705 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2708 [(set_attr "type" "branch")
2709 (set_attr "length" "2")])
2711 ;; Table jump for switch statements:
2712 (define_insn "tablejump"
2714 (match_operand:SI 0 "register_operand" "r"))
2715 (use (label_ref (match_operand 1 "" "")))]
2718 [(set_attr "type" "branch")
2719 (set_attr "length" "2")])
2721 ;;- Local variables:
2723 ;;- comment-start: ";;- "
2724 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2725 ;;- eval: (modify-syntax-entry ?[ "(]")
2726 ;;- eval: (modify-syntax-entry ?] ")[")
2727 ;;- eval: (modify-syntax-entry ?{ "(}")
2728 ;;- eval: (modify-syntax-entry ?} "){")