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 [(set (match_operand:SI 0 "symbolic_memory_operand" "=m")
249 (match_operand:SI 1 "" "r"))
250 (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 (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)))]
1142 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1144 (match_operand:SI 1 "const_int_operand" "n"))
1145 (match_operand:SI 2 "register_operand" "r"))]
1146 "(INTVAL (operands[1]) & 7) == 0"
1148 [(set_attr "type" "address")
1149 (set_attr "length" "2")])
1151 ;; This pattern cannot have any input reloads since if references CC0.
1152 ;; So we have to add code to support memory, which is the only other
1153 ;; thing that a "register_operand" can become. There is still a problem
1154 ;; if the address isn't valid and *it* needs a reload, but there is no
1155 ;; way to solve that problem, so let's hope it never happens.
1158 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,m")
1160 (match_operand:SI 1 "const_int_operand" "n,m"))
1161 (ne (cc0) (const_int 0)))
1162 (match_scratch 2 "=X,b")]
1166 l%M0 %2,%0\;mftb%t1 %2,%S1\;st%M0 %2,%0"
1167 [(set_attr "type" "*,multi")
1168 (set_attr "cc" "none,none")
1169 (set_attr "length" "2,10")])
1171 ;; Arithmetic instructions. First, add and subtract.
1173 ;; It may be that the second input is either large or small enough that
1174 ;; the operation cannot be done in a single insn. In that case, emit two.
1175 (define_expand "addsi3"
1176 [(set (match_operand:SI 0 "register_operand" "")
1177 (plus:SI (match_operand:SI 1 "register_operand" "")
1178 (match_operand:SI 2 "nonmemory_operand" "")))]
1182 if (GET_CODE (operands[2]) == CONST_INT
1183 && (unsigned) (INTVAL (operands[2]) + 0x8000) >= 0x10000
1184 && (INTVAL (operands[2]) & 0xffff) != 0)
1186 int low = INTVAL (operands[2]) & 0xffff;
1187 int high = (unsigned) INTVAL (operands[2]) >> 16;
1190 high++, low |= 0xffff0000;
1192 emit_insn (gen_addsi3 (operands[0], operands[1],
1193 gen_rtx (CONST_INT, VOIDmode, high << 16)));
1194 operands[1] = operands[0];
1195 operands[2] = gen_rtx (CONST_INT, VOIDmode, low);
1199 ;; Put the insn to add a symbolic constant to a register separately to
1200 ;; improve register allocation since it has different register requirements.
1202 [(set (match_operand:SI 0 "register_operand" "=b")
1203 (plus:SI (match_operand:SI 1 "register_operand" "%b")
1204 (match_operand:SI 2 "romp_symbolic_operand" "s")))]
1207 [(set_attr "type" "address")
1208 (set_attr "length" "8")])
1211 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,b")
1212 (plus:SI (match_operand:SI 1 "reg_or_add_operand" "%0,0,r,b,0,r,b")
1213 (match_operand:SI 2 "reg_or_add_operand" "I,J,K,M,r,b,s")))]
1214 "register_operand (operands[1], SImode)
1215 || register_operand (operands[2], SImode)"
1224 [(set_attr "type" "arith,arith,arith,address,arith,address,misc")
1225 (set_attr "length" "2,2,4,4,2,2,8")])
1229 ;; 1. If third operand is constant integer, convert it to add of the negative
1231 ;; 2. If the second operand is not a valid constant integer, force it into a
1233 (define_expand "subsi3"
1234 [(set (match_operand:SI 0 "register_operand" "")
1235 (minus:SI (match_operand:SI 1 "reg_or_any_cint_operand" "")
1236 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1240 if (GET_CODE (operands [2]) == CONST_INT)
1242 emit_insn (gen_addsi3 (operands[0], operands[1],
1244 VOIDmode, - INTVAL (operands[2]))));
1248 operands[2] = force_reg (SImode, operands[2]);
1250 if (GET_CODE (operands[1]) != CONST_INT
1251 || (unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000)
1252 operands[1] = force_reg (SImode, operands[1]);
1256 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1257 (minus:SI (match_operand:SI 1 "reg_or_D_operand" "K,0,r")
1258 (match_operand:SI 2 "register_operand" "r,r,0")))]
1264 [(set_attr "length" "4,2,2")])
1266 ;; Multiply either calls a special RT routine or is done in-line, depending
1267 ;; on the value of a -m flag.
1269 ;; First define the way we call the subroutine.
1270 (define_expand "mulsi3_subr"
1271 [(set (reg:SI 2) (match_operand:SI 1 "register_operand" ""))
1272 (set (reg:SI 3) (match_operand:SI 2 "register_operand" ""))
1273 (parallel [(set (reg:SI 2) (mult:SI (reg:SI 2) (reg:SI 3)))
1274 (clobber (reg:SI 0))
1275 (clobber (reg:SI 15))])
1276 (set (match_operand:SI 0 "register_operand" "")
1281 (define_expand "mulsi3"
1282 [(set (match_operand:SI 0 "register_operand" "")
1283 (mult:SI (match_operand:SI 1 "register_operand" "")
1284 (match_operand:SI 2 "register_operand" "")))]
1288 if (! TARGET_IN_LINE_MUL)
1290 emit_insn (gen_mulsi3_subr (operands[0], operands[1], operands[2]));
1295 ;; Define the patterns to match.
1296 ;; We would like to provide a delay slot for the insns that call internal
1297 ;; routines, but doing so is risky since reorg will think that the use of
1298 ;; r2 and r3 is completed in the insn needing the delay slot. Also, it
1299 ;; won't know that the cc will be clobbered. So take the safe approach
1300 ;; and don't give them delay slots.
1303 (mult:SI (reg:SI 2) (reg:SI 3)))
1304 (clobber (reg:SI 0))
1305 (clobber (reg:SI 15))]
1306 "! TARGET_IN_LINE_MUL"
1308 [(set_attr "type" "misc")
1309 (set_attr "in_delay_slot" "no")])
1312 [(set (match_operand:SI 0 "register_operand" "=&r")
1313 (mult:SI (match_operand:SI 1 "register_operand" "%r")
1314 (match_operand:SI 2 "register_operand" "r")))]
1315 "TARGET_IN_LINE_MUL"
1317 { return output_in_line_mul (); }"
1318 [(set_attr "length" "38")
1319 (set_attr "type" "multi")])
1321 ;; Handle divide and modulus. The same function returns both values,
1322 ;; so use divmodsi4. This divides arg 1 by arg 2 with quotient to go
1323 ;; into arg 0 and remainder in arg 3.
1325 ;; We want to put REG_EQUAL notes for the two outputs. So we need a
1326 ;; function to do everything else.
1327 (define_expand "divmodsi4_doit"
1329 (match_operand:SI 0 "register_operand" ""))
1331 (match_operand:SI 1 "register_operand" ""))
1332 (parallel [(set (reg:SI 2) (div:SI (reg:SI 2) (reg:SI 3)))
1333 (set (reg:SI 3) (mod:SI (reg:SI 2) (reg:SI 3)))
1334 (clobber (reg:SI 0))
1335 (clobber (reg:SI 15))])]
1339 (define_expand "divmodsi4"
1340 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1341 (div:SI (match_operand:SI 1 "register_operand" "")
1342 (match_operand:SI 2 "register_operand" "")))
1343 (set (match_operand:SI 3 "register_operand" "")
1344 (mod:SI (match_dup 1) (match_dup 2)))])]
1350 emit_insn (gen_divmodsi4_doit (operands[1], operands[2]));
1351 insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2));
1352 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1353 gen_rtx (DIV, SImode, operands[1],
1356 insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3));
1357 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1358 gen_rtx (MOD, SImode, operands[1],
1366 (div:SI (reg:SI 2) (reg:SI 3)))
1368 (mod:SI (reg:SI 2) (reg:SI 3)))
1369 (clobber (reg:SI 0))
1370 (clobber (reg:SI 15))]
1373 [(set_attr "type" "misc")
1374 (set_attr "in_delay_slot" "no")])
1376 ;; Similarly for unsigned divide.
1377 (define_expand "udivmodsi4_doit"
1379 (match_operand:SI 0 "register_operand" ""))
1381 (match_operand:SI 1 "register_operand" ""))
1382 (parallel [(set (reg:SI 2) (udiv:SI (reg:SI 2) (reg:SI 3)))
1383 (set (reg:SI 3) (umod:SI (reg:SI 2) (reg:SI 3)))
1384 (clobber (reg:SI 0))
1385 (clobber (reg:SI 15))])]
1389 (define_expand "udivmodsi4"
1390 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1391 (udiv:SI (match_operand:SI 1 "register_operand" "")
1392 (match_operand:SI 2 "register_operand" "")))
1393 (set (match_operand:SI 3 "register_operand" "")
1394 (umod:SI (match_dup 1) (match_dup 2)))])]
1400 emit_insn (gen_udivmodsi4_doit (operands[1], operands[2]));
1401 insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2));
1402 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1403 gen_rtx (UDIV, SImode, operands[1],
1406 insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3));
1407 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1408 gen_rtx (UMOD, SImode, operands[1],
1416 (udiv:SI (reg:SI 2) (reg:SI 3)))
1418 (umod:SI (reg:SI 2) (reg:SI 3)))
1419 (clobber (reg:SI 0))
1420 (clobber (reg:SI 15))]
1422 "bali%# r15,uldiv$$"
1423 [(set_attr "type" "misc")
1424 (set_attr "in_delay_slot" "no")])
1426 ;; Define DImode arithmetic operations.
1428 ;; It is possible to do certain adds and subtracts with constants in a single
1429 ;; insn, but it doesn't seem worth the trouble.
1431 ;; Don't use DEFINE_SPLIT on these because the dependency on CC can't be
1432 ;; easily tracked in that case!
1433 (define_insn "adddi3"
1434 [(set (match_operand:DI 0 "register_operand" "=r")
1435 (plus:DI (match_operand:DI 1 "register_operand" "%0")
1436 (match_operand:DI 2 "register_operand" "r")))]
1438 "a %O0,%O2\;ae %0,%2"
1439 [(set_attr "type" "multi")])
1441 (define_insn "subdi3"
1442 [(set (match_operand:DI 0 "register_operand" "=r")
1443 (minus:DI (match_operand:DI 1 "register_operand" "0")
1444 (match_operand:DI 2 "register_operand" "r")))]
1446 "s %O0,%O2\;se %0,%2"
1447 [(set_attr "type" "multi")])
1449 (define_insn "negdi2"
1450 [(set (match_operand:DI 0 "register_operand" "=r,&r")
1451 (neg:DI (match_operand:DI 1 "register_operand" "0,r")))]
1453 "twoc %O0,%O1\;onec %0,%1\;aei %0,%0,0"
1454 [(set_attr "type" "multi")
1455 (set_attr "length" "8")])
1457 ;; Unary arithmetic operations.
1458 (define_insn "abssi2"
1459 [(set (match_operand:SI 0 "register_operand" "=r")
1460 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1463 [(set_attr "length" "2")])
1465 (define_insn "negsi2"
1466 [(set (match_operand:SI 0 "register_operand" "=r")
1467 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1470 [(set_attr "length" "2")])
1472 (define_insn "one_cmplsi2"
1473 [(set (match_operand:SI 0 "register_operand" "=r")
1474 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1477 [(set_attr "length" "2")])
1480 ;; Logical insns: AND, IOR, and XOR
1482 ;; If the operation is being performed on a 32-bit constant such that
1483 ;; it cannot be done in one insn, do it in two. We may lose a bit on
1484 ;; CSE in pathological cases, but it seems better doing it this way.
1485 (define_expand "andsi3"
1486 [(set (match_operand:SI 0 "register_operand" "")
1487 (and:SI (match_operand:SI 1 "register_operand" "")
1488 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1492 if (GET_CODE (operands[2]) == CONST_INT)
1494 int top = (unsigned) INTVAL (operands[2]) >> 16;
1495 int bottom = INTVAL (operands[2]) & 0xffff;
1497 if (top != 0 && top != 0xffff && bottom != 0 && bottom != 0xffff)
1499 emit_insn (gen_andsi3 (operands[0], operands[1],
1500 gen_rtx (CONST_INT, VOIDmode,
1501 (top << 16) | 0xffff)));
1502 operands[1] = operands[0];
1503 operands[2] = gen_rtx (CONST_INT, VOIDmode, 0xffff0000 | bottom);
1509 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1510 (and:SI (match_operand:SI 1 "reg_or_and_operand" "%0,r,0")
1511 (match_operand:SI 2 "reg_or_and_operand" "P,LMO,r")))]
1512 "register_operand (operands[1], SImode)
1513 || register_operand (operands[2], SImode)"
1518 [(set_attr "length" "2,4,2")])
1521 (define_expand "iorsi3"
1522 [(set (match_operand:SI 0 "register_operand" "")
1523 (ior:SI (match_operand:SI 1 "register_operand" "")
1524 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1528 if (GET_CODE (operands[2]) == CONST_INT)
1530 int top = (unsigned) INTVAL (operands[2]) >> 16;
1531 int bottom = INTVAL (operands[2]) & 0xffff;
1533 if (top != 0 && bottom != 0)
1535 emit_insn (gen_iorsi3 (operands[0], operands[1],
1536 gen_rtx (CONST_INT, VOIDmode, (top << 16))));
1537 operands[1] = operands[0];
1538 operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom);
1544 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1545 (ior:SI (match_operand:SI 1 "reg_or_cint_operand" "%0,r,0")
1546 (match_operand:SI 2 "reg_or_cint_operand" "N,LM,r")))]
1547 "register_operand (operands[1], SImode)
1548 || register_operand (operands[2], SImode)"
1553 [(set_attr "length" "2,4,2")])
1555 ;; exclusive-or (XOR)
1556 (define_expand "xorsi3"
1557 [(set (match_operand:SI 0 "register_operand" "")
1558 (xor:SI (match_operand:SI 1 "register_operand" "")
1559 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1563 if (GET_CODE (operands[2]) == CONST_INT)
1565 int top = (unsigned) INTVAL (operands[2]) >> 16;
1566 int bottom = INTVAL (operands[2]) & 0xffff;
1568 if (top == 0xffff && bottom == 0xffff)
1570 emit_insn (gen_one_cmplsi2 (operands[0], operands[1]));
1573 else if (top != 0 && bottom != 0)
1575 emit_insn (gen_xorsi3 (operands[0], operands[1],
1576 gen_rtx (CONST_INT, VOIDmode, (top << 16))));
1577 operands[1] = operands[0];
1578 operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom);
1584 [(set (match_operand:SI 0 "register_operand" "=r,r")
1585 (xor:SI (match_operand:SI 1 "reg_or_cint_operand" "%r,0")
1586 (match_operand:SI 2 "reg_or_cint_operand" "LM,r")))]
1587 "register_operand (operands[1], SImode)
1588 || register_operand (operands[2], SImode)"
1592 [(set_attr "length" "4,2")])
1594 ;; Various shift insns
1595 (define_insn "ashrsi3"
1596 [(set (match_operand:SI 0 "register_operand" "=r,r")
1597 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1598 (match_operand:QI 2 "reg_or_cint_operand" "r,n")))]
1603 [(set_attr "length" "2")])
1605 (define_insn "lshrsi3"
1606 [(set (match_operand:SI 0 "register_operand" "=r,r")
1607 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1608 (match_operand:QI 2 "reg_or_cint_operand" "r,n")))]
1613 [(set_attr "length" "2")])
1616 [(set (match_operand:SI 0 "register_operand" "=r")
1617 (ashift:SI (match_operand:SI 1 "register_operand" "b")
1621 [(set_attr "length" "2")
1622 (set_attr "type" "address")])
1624 (define_insn "ashlsi3"
1625 [(set (match_operand:SI 0 "register_operand" "=r,r")
1626 (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1627 (match_operand:QI 2 "reg_or_cint_operand" "r,n")))]
1632 [(set_attr "length" "2")])
1634 ;; Function call insns:
1636 ;; On the ROMP, &fcn is actually a pointer to the data area, which is passed
1637 ;; to the function in r0. &.fcn is the actual starting address of the
1638 ;; function. Also, the word at &fcn contains &.fcn.
1640 ;; For both functions that do and don't return values, there are two cases:
1641 ;; where the function's address is a constant, and where it isn't.
1643 ;; Operand 1 (2 for `call_value') is the number of arguments and is not used.
1644 (define_expand "call"
1646 (parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
1647 (match_operand 1 "" ""))
1648 (clobber (reg:SI 15))])]
1652 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
1655 operands[0] = XEXP (operands[0], 0);
1656 if (GET_CODE (operands[0]) == SYMBOL_REF)
1658 extern rtx get_symref ();
1659 char *real_fcnname =
1660 (char *) alloca (strlen (XSTR (operands[0], 0)) + 2);
1662 /* Copy the data area address to r0. */
1663 emit_move_insn (gen_rtx (REG, SImode, 0),
1664 force_reg (SImode, operands[0]));
1665 strcpy (real_fcnname, \".\");
1666 strcat (real_fcnname, XSTR (operands[0], 0));
1667 operands[0] = get_symref (real_fcnname);
1673 emit_move_insn (gen_rtx (REG, SImode, 0),
1674 force_reg (SImode, operands[0]));
1675 data_access = gen_rtx (MEM, SImode, operands[0]);
1676 RTX_UNCHANGING_P (data_access) = 1;
1677 operands[0] = copy_to_reg (data_access);
1682 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
1683 (match_operand 1 "" "g"))
1684 (clobber (reg:SI 15))]
1687 [(set_attr "type" "call")
1688 (set_attr "length" "2")])
1691 [(call (mem:SI (match_operand:SI 0 "romp_symbolic_operand" "i"))
1692 (match_operand 1 "" "g"))
1693 (clobber (reg:SI 15))]
1694 "GET_CODE (operands[0]) == SYMBOL_REF"
1696 [(set_attr "type" "call")])
1698 ;; Call a function and return a value.
1699 (define_expand "call_value"
1701 (parallel [(set (match_operand 0 "" "=fg")
1702 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
1703 (match_operand 2 "" "")))
1704 (clobber (reg:SI 15))])]
1708 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
1711 operands[1] = XEXP (operands[1], 0);
1712 if (GET_CODE (operands[1]) == SYMBOL_REF)
1714 extern rtx get_symref ();
1715 char *real_fcnname =
1716 (char *) alloca (strlen (XSTR (operands[1], 0)) + 2);
1718 /* Copy the data area address to r0. */
1719 emit_move_insn (gen_rtx (REG, SImode, 0),
1720 force_reg (SImode, operands[1]));
1721 strcpy (real_fcnname, \".\");
1722 strcat (real_fcnname, XSTR (operands[1], 0));
1723 operands[1] = get_symref (real_fcnname);
1729 emit_move_insn (gen_rtx (REG, SImode, 0),
1730 force_reg (SImode, operands[1]));
1731 data_access = gen_rtx (MEM, SImode, operands[1]);
1732 RTX_UNCHANGING_P (data_access) = 1;
1733 operands[1] = copy_to_reg (data_access);
1738 [(set (match_operand 0 "" "=fg")
1739 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
1740 (match_operand 2 "" "g")))
1741 (clobber (reg:SI 15))]
1744 [(set_attr "length" "2")
1745 (set_attr "type" "call")])
1748 [(set (match_operand 0 "" "=fg")
1749 (call (mem:SI (match_operand:SI 1 "romp_symbolic_operand" "i"))
1750 (match_operand 2 "" "g")))
1751 (clobber (reg:SI 15))]
1752 "GET_CODE (operands[1]) == SYMBOL_REF"
1754 [(set_attr "type" "call")])
1756 ;; No operation insn.
1761 [(set_attr "type" "address")
1762 (set_attr "length" "2")
1763 (set_attr "cc" "none")])
1765 ;; Here are the floating-point operations.
1767 ;; Start by providing DEFINE_EXPAND for each operation.
1768 ;; The insns will be handled with MATCH_OPERATOR; the methodology will be
1771 ;; First the conversion operations.
1773 (define_expand "truncdfsf2"
1774 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1775 (float_truncate:SF (match_operand:DF 1 "general_operand" "")))
1776 (clobber (reg:SI 0))
1777 (clobber (reg:SI 15))])]
1781 (define_expand "extendsfdf2"
1782 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1783 (float_extend:DF (match_operand:SF 1 "general_operand" "")))
1784 (clobber (reg:SI 0))
1785 (clobber (reg:SI 15))])]
1789 (define_expand "floatsisf2"
1790 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1791 (float:SF (match_operand:SI 1 "general_operand" "")))
1792 (clobber (reg:SI 0))
1793 (clobber (reg:SI 15))])]
1797 (define_expand "floatsidf2"
1798 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1799 (float:DF (match_operand:SI 1 "general_operand" "")))
1800 (clobber (reg:SI 0))
1801 (clobber (reg:SI 15))])]
1805 (define_expand "fix_truncsfsi2"
1806 [(parallel [(set (match_operand:SI 0 "general_operand" "")
1807 (fix:SI (match_operand:SF 1 "general_operand" "")))
1808 (clobber (reg:SI 0))
1809 (clobber (reg:SI 15))])]
1813 (define_expand "fix_truncdfsi2"
1814 [(parallel [(set (match_operand:SI 0 "general_operand" "")
1815 (fix:SI (match_operand:DF 1 "general_operand" "")))
1816 (clobber (reg:SI 0))
1817 (clobber (reg:SI 15))])]
1821 ;; Now the binary operations.
1823 (define_expand "addsf3"
1824 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1825 (plus:SF (match_operand:SF 1 "general_operand" "")
1826 (match_operand:SF 2 "general_operand" "")))
1827 (clobber (reg:SI 0))
1828 (clobber (reg:SI 15))])]
1832 (define_expand "adddf3"
1833 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1834 (plus:DF (match_operand:DF 1 "general_operand" "")
1835 (match_operand:DF 2 "general_operand" "")))
1836 (clobber (reg:SI 0))
1837 (clobber (reg:SI 15))])]
1841 (define_expand "subsf3"
1842 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1843 (minus:SF (match_operand:SF 1 "general_operand" "")
1844 (match_operand:SF 2 "general_operand" "")))
1845 (clobber (reg:SI 0))
1846 (clobber (reg:SI 15))])]
1850 (define_expand "subdf3"
1851 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1852 (minus:DF (match_operand:DF 1 "general_operand" "")
1853 (match_operand:DF 2 "general_operand" "")))
1854 (clobber (reg:SI 0))
1855 (clobber (reg:SI 15))])]
1859 (define_expand "mulsf3"
1860 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1861 (mult:SF (match_operand:SF 1 "general_operand" "")
1862 (match_operand:SF 2 "general_operand" "")))
1863 (clobber (reg:SI 0))
1864 (clobber (reg:SI 15))])]
1868 (define_expand "muldf3"
1869 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1870 (mult:DF (match_operand:DF 1 "general_operand" "")
1871 (match_operand:DF 2 "general_operand" "")))
1872 (clobber (reg:SI 0))
1873 (clobber (reg:SI 15))])]
1877 (define_expand "divsf3"
1878 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1879 (div:SF (match_operand:SF 1 "general_operand" "")
1880 (match_operand:SF 2 "general_operand" "")))
1881 (clobber (reg:SI 0))
1882 (clobber (reg:SI 15))])]
1886 (define_expand "divdf3"
1887 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1888 (div:DF (match_operand:DF 1 "general_operand" "")
1889 (match_operand:DF 2 "general_operand" "")))
1890 (clobber (reg:SI 0))
1891 (clobber (reg:SI 15))])]
1895 ;; Unary floating-point operations.
1897 ;; Negations can be done without floating-point, since this is IEEE.
1898 ;; But we cannot do this if an operand is a hard FP register, since
1899 ;; the SUBREG we create would not be valid.
1900 (define_expand "negsf2"
1901 [(set (match_operand:SF 0 "register_operand" "")
1902 (neg:SF (match_operand:SF 1 "register_operand" "")))]
1906 if (! (GET_CODE (operands[0]) == REG
1907 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
1908 && FP_REGNO_P (REGNO (operands[0])))
1909 && ! (GET_CODE (operands[1]) == REG
1910 && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
1911 && FP_REGNO_P (REGNO (operands[1]))))
1914 rtx target = operand_subword (operands[0], 0, 1, SFmode);
1916 result = expand_binop (SImode, xor_optab,
1917 operand_subword_force (operands[1], 0, SFmode),
1918 gen_rtx (CONST_INT, VOIDmode, 0x80000000),
1919 target, 0, OPTAB_WIDEN);
1923 if (result != target)
1924 emit_move_insn (result, target);
1926 /* Make a place for REG_EQUAL. */
1927 emit_move_insn (operands[0], operands[0]);
1932 (define_expand "negdf2"
1933 [(set (match_operand:DF 0 "register_operand" "")
1934 (neg:DF (match_operand:DF 1 "register_operand" "")))]
1938 if (! (GET_CODE (operands[0]) == REG
1939 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
1940 && FP_REGNO_P (REGNO (operands[0])))
1941 && ! (GET_CODE (operands[1]) == REG
1942 && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
1943 && FP_REGNO_P (REGNO (operands[1]))))
1946 rtx target = operand_subword (operands[0], 0, 1, DFmode);
1950 result = expand_binop (SImode, xor_optab,
1951 operand_subword_force (operands[1], 0, DFmode),
1952 gen_rtx (CONST_INT, VOIDmode, 0x80000000),
1953 target, 0, OPTAB_WIDEN);
1957 if (result != target)
1958 emit_move_insn (result, target);
1960 emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
1961 operand_subword_force (operands[1], 1, DFmode));
1963 insns = get_insns ();
1966 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1971 (define_expand "abssf2"
1972 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1973 (abs:SF (match_operand:SF 1 "general_operand" "")))
1974 (clobber (reg:SI 0))
1975 (clobber (reg:SI 15))])]
1979 (define_expand "absdf2"
1980 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1981 (abs:DF (match_operand:DF 1 "general_operand" "")))
1982 (clobber (reg:SI 0))
1983 (clobber (reg:SI 15))])]
1987 ;; Any floating-point operation can be either SFmode or DFmode, and each
1988 ;; operand (including the output) can be either a normal operand or a
1989 ;; conversion from a normal operand.
1991 ;; We use MATCH_OPERATOR to match a floating-point binary or unary operator
1992 ;; and input and output conversions. So we need 2^N patterns for each type
1993 ;; of operation, where N is the number of operands, including the output.
1994 ;; There are thus a total of 14 patterns, 8 for binary operations, 4 for
1995 ;; unary operations and two for conversion/move operations (only one
1996 ;; operand can have a conversion for move operations). In addition, we have
1997 ;; to be careful that a floating-point reload register doesn't get allocated
1998 ;; for an integer. We take care of this for inputs with PREFERRED_RELOAD_CLASS
1999 ;; but need to have two different constraints for outputs. This means that
2000 ;; we have to duplicate each pattern where the output could be an integer.
2001 ;; This adds another 7 patterns, for a total of 21.
2003 ;; Start with conversion operations (moves are done above).
2006 [(set (match_operand:SI 0 "general_operand" "=g")
2007 (match_operator 1 "float_conversion"
2008 [(match_operand 2 "general_operand" "frg")]))
2009 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2010 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2013 { return output_fpop (SET, operands[0], operands[2], 0, insn);
2015 [(set_attr "type" "fp")])
2018 [(set (match_operand 0 "general_operand" "=frg")
2019 (match_operator 1 "float_conversion"
2020 [(match_operand 2 "general_operand" "frg")]))
2021 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2022 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2025 { return output_fpop (SET, operands[0], operands[2], 0, insn);
2027 [(set_attr "type" "fp")])
2029 ;; Next, binary floating-point operations.
2032 [(set (match_operand 0 "general_operand" "=frg")
2033 (match_operator 1 "float_binary"
2034 [(match_operand 2 "general_operand" "frg")
2035 (match_operand 3 "general_operand" "frg")]))
2036 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2037 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2038 "check_precision (GET_MODE (operands[1]), operands[2], operands[3])"
2040 { return output_fpop (GET_CODE (operands[1]), operands[0],
2041 operands[2], operands[3], insn);
2043 [(set_attr "type" "fp")])
2046 [(set (match_operand 0 "general_operand" "=frg")
2047 (match_operator 1 "float_binary"
2048 [(match_operand 2 "general_operand" "frg")
2049 (match_operator 3 "float_conversion"
2050 [(match_operand 4 "general_operand" "frg")])]))
2051 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2052 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2053 "check_precision (GET_MODE (operands[1]), operands[2], operands[4])"
2055 { return output_fpop (GET_CODE (operands[1]), operands[0],
2056 operands[2], operands[4], insn);
2058 [(set_attr "type" "fp")])
2061 [(set (match_operand 0 "general_operand" "=frg")
2062 (match_operator 1 "float_binary"
2063 [(match_operator 2 "float_conversion"
2064 [(match_operand 3 "general_operand" "frg")])
2065 (match_operand 4 "general_operand" "frg")]))
2066 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2067 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2068 "check_precision (GET_MODE (operands[1]), operands[3], operands[4])"
2070 { return output_fpop (GET_CODE (operands[1]), operands[0],
2071 operands[3], operands[4], insn);
2073 [(set_attr "type" "fp")])
2076 [(set (match_operand 0 "general_operand" "=frg")
2077 (match_operator 1 "float_binary"
2078 [(match_operator 2 "float_conversion"
2079 [(match_operand 3 "general_operand" "frg")])
2080 (match_operator 4 "float_conversion"
2081 [(match_operand 5 "general_operand" "frg")])]))
2082 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2083 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2084 "check_precision (GET_MODE (operands[1]), operands[3], operands[5])"
2086 { return output_fpop (GET_CODE (operands[1]), operands[0],
2087 operands[3], operands[5], insn);
2089 [(set_attr "type" "fp")])
2092 [(set (match_operand:SI 0 "general_operand" "=g")
2093 (match_operator 1 "float_conversion"
2094 [(match_operator 2 "float_binary"
2095 [(match_operand 3 "general_operand" "frg")
2096 (match_operand 4 "general_operand" "frg")])]))
2097 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2098 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2099 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2101 { return output_fpop (GET_CODE (operands[2]), operands[0],
2102 operands[3], operands[4], insn);
2104 [(set_attr "type" "fp")])
2107 [(set (match_operand 0 "general_operand" "=frg")
2108 (match_operator 1 "float_conversion"
2109 [(match_operator 2 "float_binary"
2110 [(match_operand 3 "general_operand" "frg")
2111 (match_operand 4 "general_operand" "frg")])]))
2112 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2113 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2114 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2116 { return output_fpop (GET_CODE (operands[2]), operands[0],
2117 operands[3], operands[4], insn);
2119 [(set_attr "type" "fp")])
2122 [(set (match_operand:SI 0 "general_operand" "=g")
2123 (match_operator 1 "float_conversion"
2124 [(match_operator 2 "float_binary"
2125 [(match_operand 3 "general_operand" "frg")
2126 (match_operator 4 "float_conversion"
2127 [(match_operand 5 "general_operand" "frg")])])]))
2128 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2129 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2130 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2132 { return output_fpop (GET_CODE (operands[2]), operands[0],
2133 operands[3], operands[5], insn);
2135 [(set_attr "type" "fp")])
2138 [(set (match_operand 0 "general_operand" "=frg")
2139 (match_operator 1 "float_conversion"
2140 [(match_operator 2 "float_binary"
2141 [(match_operand 3 "general_operand" "frg")
2142 (match_operator 4 "float_conversion"
2143 [(match_operand 5 "general_operand" "frg")])])]))
2144 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2145 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2146 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2148 { return output_fpop (GET_CODE (operands[2]), operands[0],
2149 operands[3], operands[5], insn);
2151 [(set_attr "type" "fp")])
2154 [(set (match_operand:SI 0 "general_operand" "=g")
2155 (match_operator 1 "float_conversion"
2156 [(match_operator 2 "float_binary"
2157 [(match_operator 3 "float_conversion"
2158 [(match_operand 4 "general_operand" "frg")])
2159 (match_operand 5 "general_operand" "frg")])]))
2160 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2161 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2162 "check_precision (GET_MODE (operands[2]), operands[4], operands[5])"
2164 { return output_fpop (GET_CODE (operands[2]), operands[0],
2165 operands[4], operands[5], insn);
2167 [(set_attr "type" "fp")])
2170 [(set (match_operand 0 "general_operand" "=frg")
2171 (match_operator 1 "float_conversion"
2172 [(match_operator 2 "float_binary"
2173 [(match_operator 3 "float_conversion"
2174 [(match_operand 4 "general_operand" "frg")])
2175 (match_operand 5 "general_operand" "frg")])]))
2176 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2177 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2178 "check_precision (GET_MODE (operands[2]), operands[4], operands[5])"
2180 { return output_fpop (GET_CODE (operands[2]), operands[0],
2181 operands[4], operands[5], insn);
2183 [(set_attr "type" "fp")])
2186 [(set (match_operand:SI 0 "general_operand" "=g")
2187 (match_operator 1 "float_conversion"
2188 [(match_operator 2 "float_binary"
2189 [(match_operator 3 "float_conversion"
2190 [(match_operand 4 "general_operand" "frg")])
2191 (match_operator 5 "float_conversion"
2192 [(match_operand 6 "general_operand" "frg")])])]))
2193 (clobber (match_operand:SI 7 "reg_0_operand" "=&z"))
2194 (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))]
2195 "check_precision (GET_MODE (operands[2]), operands[4], operands[6])"
2197 { return output_fpop (GET_CODE (operands[2]), operands[0],
2198 operands[4], operands[6], insn);
2200 [(set_attr "type" "fp")])
2203 [(set (match_operand 0 "general_operand" "=frg")
2204 (match_operator 1 "float_conversion"
2205 [(match_operator 2 "float_binary"
2206 [(match_operator 3 "float_conversion"
2207 [(match_operand 4 "general_operand" "frg")])
2208 (match_operator 5 "float_conversion"
2209 [(match_operand 6 "general_operand" "frg")])])]))
2210 (clobber (match_operand:SI 7 "reg_0_operand" "=&z"))
2211 (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))]
2212 "check_precision (GET_MODE (operands[2]), operands[4], operands[6])"
2214 { return output_fpop (GET_CODE (operands[2]), operands[0],
2215 operands[4], operands[6], insn);
2217 [(set_attr "type" "fp")])
2219 ;; Unary floating-point operations.
2222 [(set (match_operand 0 "general_operand" "=frg")
2223 (match_operator 1 "float_unary"
2224 [(match_operand 2 "general_operand" "frg")]))
2225 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2226 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2227 "check_precision (GET_MODE (operands[1]), operands[2], 0)"
2229 { return output_fpop (GET_CODE (operands[1]), operands[0], operands[2],
2232 [(set_attr "type" "fp")])
2235 [(set (match_operand 0 "general_operand" "=frg")
2236 (match_operator 1 "float_unary"
2237 [(match_operator 2 "float_conversion"
2238 [(match_operand 3 "general_operand" "frg")])]))
2239 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2240 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2241 "check_precision (GET_MODE (operands[1]), operands[3], 0)"
2243 { return output_fpop (GET_CODE (operands[1]), operands[0], operands[3],
2246 [(set_attr "type" "fp")])
2249 [(set (match_operand:SI 0 "general_operand" "=g")
2250 (match_operator 1 "float_conversion"
2251 [(match_operator 2 "float_unary"
2252 [(match_operand 3 "general_operand" "frg")])]))
2253 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2254 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2255 "check_precision (GET_MODE (operands[2]), operands[3], 0)"
2257 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3],
2260 [(set_attr "type" "fp")])
2263 [(set (match_operand 0 "general_operand" "=frg")
2264 (match_operator 1 "float_conversion"
2265 [(match_operator 2 "float_unary"
2266 [(match_operand 3 "general_operand" "frg")])]))
2267 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2268 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2269 "check_precision (GET_MODE (operands[2]), operands[3], 0)"
2271 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3],
2274 [(set_attr "type" "fp")])
2277 [(set (match_operand:SI 0 "general_operand" "=g")
2278 (match_operator 1 "float_conversion"
2279 [(match_operator 2 "float_unary"
2280 [(match_operator 3 "float_conversion"
2281 [(match_operand 4 "general_operand" "frg")])])]))
2282 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2283 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2284 "check_precision (GET_MODE (operands[2]), operands[4], 0)"
2286 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4],
2289 [(set_attr "type" "fp")])
2292 [(set (match_operand 0 "general_operand" "=frg")
2293 (match_operator 1 "float_conversion"
2294 [(match_operator 2 "float_unary"
2295 [(match_operator 3 "float_conversion"
2296 [(match_operand 4 "general_operand" "frg")])])]))
2297 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2298 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2299 "check_precision (GET_MODE (operands[2]), operands[4], 0)"
2301 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4],
2304 [(set_attr "type" "fp")])
2306 ;; Compare insns are next. Note that the ROMP has two types of compares,
2307 ;; signed & unsigned, and one type of branch. Use the routine
2308 ;; `next_insn_tests_no_unsigned' to see which type to use.
2309 (define_expand "tstsi"
2311 (match_operand:SI 0 "register_operand" "r"))]
2315 (define_expand "cmpsi"
2317 (compare (match_operand:SI 0 "register_operand" "")
2318 (match_operand:SI 1 "reg_or_cint_operand" "")))]
2322 ;; Signed compare, `test' first.
2326 (match_operand:SI 0 "register_operand" "r"))]
2327 "next_insn_tests_no_unsigned (insn)"
2329 [(set_attr "length" "2")
2330 (set_attr "type" "compare")])
2333 [(set (cc0) (match_operand:SI 0 "register_operand" "r,r,r"))
2334 (set (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "=0,r,Q")
2336 "next_insn_tests_no_unsigned (insn)"
2340 st%M1 %0,%1\;cis %0,0"
2341 [(set_attr "type" "compare,compare,store")
2342 (set_attr "length" "2,4,6")
2343 (set_attr "cc" "compare")])
2347 (compare (match_operand:SI 0 "register_operand" "r,r,r")
2348 (match_operand:SI 1 "reg_or_cint_operand" "I,K,r")))]
2349 "next_insn_tests_no_unsigned (insn)"
2354 [(set_attr "length" "2,4,2")
2355 (set_attr "type" "compare")])
2357 ;; Unsigned comparisons, `test' first, again.
2360 (match_operand:SI 0 "register_operand" "r"))]
2361 "! next_insn_tests_no_unsigned (insn)"
2363 [(set_attr "type" "compare")])
2367 (compare (match_operand:SI 0 "register_operand" "r,r")
2368 (match_operand:SI 1 "reg_or_cint_operand" "K,r")))]
2369 "! next_insn_tests_no_unsigned (insn)"
2373 [(set_attr "length" "4,2")
2374 (set_attr "type" "compare")])
2376 ;; Bit test insn. Many cases are converted into this by combine. This
2377 ;; uses the ROMP test bit.
2381 (zero_extract (match_operand:SI 0 "register_operand" "r,r")
2383 (match_operand:SI 1 "reg_or_any_cint_operand" "r,n")))]
2384 "next_insn_tests_no_inequality (insn)"
2388 [(set_attr "length" "2")
2389 (set_attr "type" "compare")
2390 (set_attr "cc" "tbit")])
2392 ;; Floating-point comparisons. There are two, equality and order.
2393 ;; The difference will be that a trap for NaN will be given on the orderr
2394 ;; comparisons only.
2396 (define_expand "cmpsf"
2397 [(parallel [(set (cc0) (compare (match_operand:SF 0 "general_operand" "")
2398 (match_operand:SF 1 "general_operand" "")))
2399 (clobber (reg:SI 0))
2400 (clobber (reg:SI 15))])]
2404 (define_expand "cmpdf"
2405 [(parallel [(set (cc0) (compare (match_operand:DF 0 "general_operand" "")
2406 (match_operand:DF 1 "general_operand" "")))
2407 (clobber (reg:SI 0))
2408 (clobber (reg:SI 15))])]
2412 (define_expand "tstsf"
2413 [(parallel [(set (cc0) (match_operand:SF 0 "general_operand" ""))
2414 (clobber (reg:SI 0))
2415 (clobber (reg:SI 15))])]
2419 (define_expand "tstdf"
2420 [(parallel [(set (cc0) (match_operand:DF 0 "general_operand" ""))
2421 (clobber (reg:SI 0))
2422 (clobber (reg:SI 15))])]
2426 ;; There are four cases for compare and two for test. These correspond
2427 ;; to each input having a floating-point conversion or not.
2430 [(set (cc0) (compare (match_operand 0 "general_operand" "frg")
2431 (match_operand 1 "general_operand" "frg")))
2432 (clobber (match_operand:SI 2 "reg_0_operand" "=&z"))
2433 (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))]
2434 "GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode"
2436 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2437 operands[0], operands[1], 0, insn);
2439 [(set_attr "type" "fp")
2440 (set_attr "cc" "compare")])
2443 [(set (cc0) (compare (match_operand 0 "general_operand" "frg")
2444 (match_operator 1 "float_conversion"
2445 [(match_operand 2 "general_operand" "frg")])))
2446 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2447 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2450 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2451 operands[0], operands[2], 0, insn);
2453 [(set_attr "type" "fp")
2454 (set_attr "cc" "compare")])
2457 [(set (cc0) (compare (match_operator 0 "float_conversion"
2458 [(match_operand 1 "general_operand" "frg")])
2459 (match_operand 2 "general_operand" "frg")))
2460 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2461 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2464 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2465 operands[1], operands[2], 0, insn);
2467 [(set_attr "type" "fp")
2468 (set_attr "cc" "compare")])
2471 [(set (cc0) (compare (match_operator 0 "float_conversion"
2472 [(match_operand 1 "general_operand" "frg")])
2473 (match_operator 2 "float_conversion"
2474 [(match_operand 3 "general_operand" "frg")])))
2475 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2476 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2479 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2480 operands[1], operands[3], 0, insn);
2482 [(set_attr "type" "fp")
2483 (set_attr "cc" "compare")])
2486 [(set (cc0) (match_operand 0 "general_operand" "frg"))
2487 (clobber (match_operand:SI 1 "reg_0_operand" "=&z"))
2488 (clobber (match_operand:SI 2 "reg_15_operand" "=&t"))]
2489 "GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode"
2491 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2492 operands[0], immed_real_const_1 (0, 0,
2493 GET_MODE (operands[0])),
2496 [(set_attr "type" "fp")
2497 (set_attr "cc" "compare")])
2500 [(set (cc0) (match_operator 0 "float_conversion"
2501 [(match_operand 1 "general_operand" "frg")]))
2502 (clobber (match_operand:SI 2 "reg_0_operand" "=&z"))
2503 (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))]
2506 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2507 operands[1], immed_real_const_1 (0, 0,
2508 GET_MODE (operands[1])),
2511 [(set_attr "type" "fp")
2512 (set_attr "cc" "compare")])
2514 ;; Branch insns. Unsigned vs. signed have already
2515 ;; been taken care of. The only insns that need to be concerned about the
2516 ;; test bit are beq and bne because the rest are either always true,
2517 ;; always false, or converted to EQ or NE.
2519 ;; For conditional branches, we use `define_expand' and just have two patterns
2520 ;; that match them. Operand printing does most of the work.
2522 (define_expand "beq"
2524 (if_then_else (eq (cc0)
2526 (label_ref (match_operand 0 "" ""))
2531 (define_expand "bne"
2533 (if_then_else (ne (cc0)
2535 (label_ref (match_operand 0 "" ""))
2540 (define_expand "bgt"
2542 (if_then_else (gt (cc0)
2544 (label_ref (match_operand 0 "" ""))
2549 (define_expand "bgtu"
2551 (if_then_else (gtu (cc0)
2553 (label_ref (match_operand 0 "" ""))
2558 (define_expand "blt"
2560 (if_then_else (lt (cc0)
2562 (label_ref (match_operand 0 "" ""))
2567 (define_expand "bltu"
2569 (if_then_else (ltu (cc0)
2571 (label_ref (match_operand 0 "" ""))
2576 (define_expand "bge"
2578 (if_then_else (ge (cc0)
2580 (label_ref (match_operand 0 "" ""))
2585 (define_expand "bgeu"
2587 (if_then_else (geu (cc0)
2589 (label_ref (match_operand 0 "" ""))
2594 (define_expand "ble"
2596 (if_then_else (le (cc0)
2598 (label_ref (match_operand 0 "" ""))
2603 (define_expand "bleu"
2605 (if_then_else (leu (cc0)
2607 (label_ref (match_operand 0 "" ""))
2612 ;; Define both directions of branch and return.
2616 (if_then_else (match_operator 1 "comparison_operator"
2617 [(cc0) (const_int 0)])
2618 (label_ref (match_operand 0 "" ""))
2623 if (restore_compare_p (operands[1]))
2625 else if (get_attr_length (insn) == 2)
2626 return \"j%j1 %l0\";
2628 return \"b%j1%# %l0\";
2630 [(set_attr "type" "branch")])
2634 (if_then_else (match_operator 0 "comparison_operator"
2635 [(cc0) (const_int 0)])
2641 if (restore_compare_p (operands[0]))
2644 return \"b%j0r%# r15\";
2646 [(set_attr "type" "return")])
2650 (if_then_else (match_operator 1 "comparison_operator"
2651 [(cc0) (const_int 0)])
2653 (label_ref (match_operand 0 "" ""))))]
2657 if (restore_compare_p (operands[1]))
2659 else if (get_attr_length (insn) == 2)
2660 return \"j%J1 %l0\";
2662 return \"b%J1%# %l0\";
2664 [(set_attr "type" "branch")])
2668 (if_then_else (match_operator 0 "comparison_operator"
2669 [(cc0) (const_int 0)])
2675 if (restore_compare_p (operands[0]))
2678 return \"b%J0r%# r15\";
2680 [(set_attr "type" "return")])
2682 ;; Unconditional branch and return.
2686 (label_ref (match_operand 0 "" "")))]
2690 if (get_attr_length (insn) == 2)
2695 [(set_attr "type" "branch")])
2697 (define_insn "return"
2701 [(set_attr "type" "return")])
2703 (define_insn "indirect_jump"
2704 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2707 [(set_attr "type" "branch")
2708 (set_attr "length" "2")])
2710 ;; Table jump for switch statements:
2711 (define_insn "tablejump"
2713 (match_operand:SI 0 "register_operand" "r"))
2714 (use (label_ref (match_operand 1 "" "")))]
2717 [(set_attr "type" "branch")
2718 (set_attr "length" "2")])
2720 ;;- Local variables:
2722 ;;- comment-start: ";;- "
2723 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2724 ;;- eval: (modify-syntax-entry ?[ "(]")
2725 ;;- eval: (modify-syntax-entry ?] ")[")
2726 ;;- eval: (modify-syntax-entry ?{ "(}")
2727 ;;- eval: (modify-syntax-entry ?} "){")