]> gcc.gnu.org Git - gcc.git/blob - gcc/config/romp/romp.md
(EXTRA_CONSTRAINT, case 'Q'): Check for MEM instead of calling memory_operand.
[gcc.git] / gcc / config / romp / romp.md
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)
4
5 ;; This file is part of GNU CC.
6
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)
10 ;; any later version.
11
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.
16
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.
20
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 \f
24 ;; Define the attributes for the ROMP.
25
26 ;; Insn type. Used to default other attribute values.
27
28 (define_attr "type"
29 "branch,ibranch,return,fp,load,loadz,store,call,address,arith,compare,multi,misc"
30 (const_string "arith"))
31
32 ;; Length in bytes.
33
34 (define_attr "length" ""
35 (cond [(eq_attr "type" "branch")
36 (if_then_else (and (ge (minus (pc) (match_dup 0))
37 (const_int -256))
38 (le (minus (pc) (match_dup 0))
39 (const_int 254)))
40 (const_int 2)
41 (const_int 4))
42 (eq_attr "type" "return,ibranch") (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)]
48 (const_int 4))
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)]
52 (const_string "4"))
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)]
56 (const_int 4))]
57 (const_int 4)))
58
59 ;; Whether insn can be placed in a delay slot.
60
61 (define_attr "in_delay_slot" "yes,no"
62 (cond [(eq_attr "length" "8,10,38") (const_string "no")
63 (eq_attr "type" "branch,ibranch,return,call,multi")
64 (const_string "no")]
65 (const_string "yes")))
66
67 ;; Whether insn needs a delay slot. We have to say that two-byte
68 ;; branches do not need a delay slot. Otherwise, branch shortening will
69 ;; try to do something with delay slot insns (we want it to on the PA).
70 ;; This is a kludge, which should be cleaned up at some point.
71
72 (define_attr "needs_delay_slot" "yes,no"
73 (if_then_else (ior (and (eq_attr "type" "branch")
74 (eq_attr "length" "4"))
75 (eq_attr "type" "ibranch,return,call"))
76 (const_string "yes") (const_string "no")))
77
78 ;; What insn does to the condition code.
79
80 (define_attr "cc"
81 "clobber,none,sets,change0,copy1to0,compare,tbit"
82 (cond [(eq_attr "type" "load,loadz") (const_string "change0")
83 (eq_attr "type" "store") (const_string "none")
84 (eq_attr "type" "fp,call") (const_string "clobber")
85 (eq_attr "type" "branch,ibranch,return") (const_string "none")
86 (eq_attr "type" "address") (const_string "change0")
87 (eq_attr "type" "compare") (const_string "compare")
88 (eq_attr "type" "arith") (const_string "sets")]
89 (const_string "clobber")))
90 \f
91 ;; Define attributes for `asm' insns.
92
93 (define_asm_attributes [(set_attr "type" "misc")
94 (set_attr "length" "8")
95 (set_attr "in_delay_slot" "no")
96 (set_attr "cc" "clobber")])
97
98 ;; Define the delay slot requirements for branches and calls. We don't have
99 ;; any annulled insns.
100 ;;
101 (define_delay (eq_attr "needs_delay_slot" "yes")
102 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
103
104 ;; We cannot give a floating-point comparison a delay slot, even though it
105 ;; could make use of it. This is because it would confuse next_cc0_user
106 ;; to do so. Other fp insns can't get a delay slow because they set their
107 ;; result and use their input after the delay slot insn is executed. This
108 ;; isn't what reorg.c expects.
109
110 ;; Define load & store delays. These were obtained by measurements done by
111 ;; jfc@athena.mit.edu.
112 ;;
113 ;; In general, the memory unit can support at most two simultaneous operations.
114 ;;
115 ;; Loads take 5 cycles to return the data and can be pipelined up to the
116 ;; limit of two simultaneous operations.
117 (define_function_unit "memory" 1 2 (eq_attr "type" "load,loadz") 5 0)
118
119 ;; Stores do not return data, but tie up the memory unit for 2 cycles if the
120 ;; next insn is also a store.
121 (define_function_unit "memory" 1 2 (eq_attr "type" "store") 1 2
122 [(eq_attr "type" "store")])
123 \f
124 ;; Move word instructions.
125 ;;
126 ;; If destination is memory but source is not register, force source to
127 ;; register.
128 ;;
129 ;; If source is a constant that is too large to load in a single insn, build
130 ;; it in two pieces.
131 ;;
132 ;; If destination is memory and source is a register, a temporary register
133 ;; will be needed. In that case, make a PARALLEL of the SET and a
134 ;; CLOBBER of a SCRATCH to allocate the required temporary.
135 ;;
136 ;; This temporary is ACTUALLY only needed when the destination is a
137 ;; relocatable expression. For generating RTL, however, we always
138 ;; place the CLOBBER. In insns where it is not needed, the SCRATCH will
139 ;; not be allocated to a register.
140 ;;
141 ;; Also, avoid creating pseudo-registers or SCRATCH rtx's during reload as
142 ;; they will not be correctly handled. We never need pseudos for that
143 ;; case anyway.
144 ;;
145 ;; We do not use DEFINE_SPLIT for loading constants because the number
146 ;; of cases in the resulting unsplit insn would be too high to deal
147 ;; with practically.
148 (define_expand "movsi"
149 [(set (match_operand:SI 0 "general_operand" "")
150 (match_operand:SI 1 "general_operand" ""))]
151 ""
152 "
153 { rtx op0 = operands[0];
154 rtx op1 = operands[1];
155
156 if (GET_CODE (op1) == REG && REGNO (op1) == 16)
157 DONE;
158
159 if (GET_CODE (op0) == REG && REGNO (op0) == 16)
160 DONE;
161
162 if (GET_CODE (op0) == MEM && ! reload_in_progress)
163 {
164 emit_insn (gen_storesi (operands[0], force_reg (SImode, operands[1])));
165 DONE;
166 }
167 else if (GET_CODE (op1) == CONST_INT)
168 {
169 int const_val = INTVAL (op1);
170
171 /* Try a number of cases to see how to best load the constant. */
172 if ((const_val & 0xffff) == 0
173 || (const_val & 0xffff0000) == 0
174 || (unsigned) (const_val + 0x8000) < 0x10000)
175 /* Can do this in one insn, so generate it. */
176 ;
177 else if (((- const_val) & 0xffff) == 0
178 || ((- const_val) & 0xffff0000) == 0
179 || (unsigned) ((- const_val) + 0x8000) < 0x10000)
180 {
181 /* Can do this by loading the negative constant and then negating. */
182 emit_move_insn (operands[0],
183 gen_rtx (CONST_INT, VOIDmode, - const_val));
184 emit_insn (gen_negsi2 (operands[0], operands[0]));
185 DONE;
186 }
187 else
188 /* Do this the long way. */
189 {
190 unsigned int high_part = const_val & 0xffff0000;
191 unsigned int low_part = const_val & 0xffff;
192 int i;
193
194 if (low_part >= 0x10 && exact_log2 (low_part) >= 0)
195 i = high_part, high_part = low_part, low_part = i;
196
197 emit_move_insn (operands[0],
198 gen_rtx (CONST_INT, VOIDmode, low_part));
199 emit_insn (gen_iorsi3 (operands[0], operands[0],
200 gen_rtx (CONST_INT, VOIDmode, high_part)));
201 DONE;
202 }
203 }
204 }")
205
206 ;; Move from a symbolic memory location to a register is special. In this
207 ;; case, we know in advance that the register cannot be r0, so we can improve
208 ;; register allocation by treating it separately.
209
210 (define_insn ""
211 [(set (match_operand:SI 0 "register_operand" "=b")
212 (match_operand:SI 1 "symbolic_memory_operand" "m"))]
213 ""
214 "load %0,%1"
215 [(set_attr "type" "load")])
216
217 ;; Generic single-word move insn. We avoid the case where the destination is
218 ;; a symbolic address, as that needs a temporary register.
219
220 (define_insn ""
221 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,r,r,r,b,Q")
222 (match_operand:SI 1 "romp_operand" "rR,I,K,L,M,S,s,Q,m,r"))]
223 "register_operand (operands[0], SImode)
224 || register_operand (operands[1], SImode)"
225 "@
226 cas %0,%1,r0
227 lis %0,%1
228 cal %0,%1(r0)
229 cal16 %0,%1(r0)
230 cau %0,%H1(r0)
231 ail %0,r14,%C1
232 get %0,$%1
233 l%M1 %0,%1
234 load %0,%1
235 st%M0 %1,%0"
236 [(set_attr "type" "address,address,address,address,address,arith,misc,load,load,store")
237 (set_attr "length" "2,2,4,4,4,4,8,*,*,*")])
238
239 (define_insn "storesi"
240 [(set (match_operand:SI 0 "memory_operand" "=Q,m")
241 (match_operand:SI 1 "register_operand" "r,r"))
242 (clobber (match_scratch:SI 2 "=X,&b"))]
243 ""
244 "@
245 st%M0 %1,%0
246 store %1,%0,%2"
247 [(set_attr "type" "store")])
248
249 ;; This pattern is used by reload when we store into a symbolic address. It
250 ;; provides the temporary register required. This pattern is only used
251 ;; when SECONDARY_OUTPUT_RELOAD_CLASS returns something other than
252 ;; NO_REGS, so we need not have any predicates here.
253
254 (define_expand "reload_outsi"
255 [(parallel [(set (match_operand:SI 0 "symbolic_memory_operand" "=m")
256 (match_operand:SI 1 "" "r"))
257 (clobber (match_operand:SI 2 "" "=&b"))])]
258 ""
259 "")
260 \f
261 ;; Now do the same for the QI move instructions.
262 (define_expand "movqi"
263 [(set (match_operand:QI 0 "general_operand" "")
264 (match_operand:QI 1 "general_operand" ""))]
265 ""
266 "
267 { rtx op0 = operands[0];
268
269 if (GET_CODE (op0) == MEM && ! reload_in_progress)
270 {
271 emit_insn (gen_storeqi (operands[0], force_reg (QImode, operands[1])));
272 DONE;
273 }
274 }")
275
276 (define_insn ""
277 [(set (match_operand:QI 0 "register_operand" "=b")
278 (match_operand:QI 1 "symbolic_memory_operand" "m"))]
279 ""
280 "loadc %0,%1"
281 [(set_attr "type" "load")])
282
283 (define_insn ""
284 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,b,Q")
285 (match_operand:QI 1 "romp_operand" "r,I,n,s,Q,m,r"))]
286 "register_operand (operands[0], QImode)
287 || register_operand (operands[1], QImode)"
288 "@
289 cas %0,%1,r0
290 lis %0,%1
291 cal %0,%L1(r0)
292 get %0,$%1
293 lc%M1 %0,%1
294 loadc %0,%1
295 stc%M0 %1,%0"
296 [(set_attr "type" "address,address,address,misc,load,load,store")
297 (set_attr "length" "2,2,4,8,*,*,*")])
298
299 (define_insn "storeqi"
300 [(set (match_operand:QI 0 "memory_operand" "=Q,m")
301 (match_operand:QI 1 "register_operand" "r,r"))
302 (clobber (match_scratch:SI 2 "=X,&b"))]
303 ""
304 "@
305 stc%M0 %1,%0
306 storec %1,%0,%2"
307 [(set_attr "type" "store")])
308
309 (define_expand "reload_outqi"
310 [(set (match_operand:QI 0 "symbolic_memory_operand" "=m")
311 (match_operand:QI 1 "" "r"))
312 (match_operand:SI 2 "" "=&b")]
313 ""
314 "")
315 \f
316 ;; Finally, the HI instructions.
317 (define_expand "movhi"
318 [(set (match_operand:HI 0 "general_operand" "")
319 (match_operand:HI 1 "general_operand" ""))]
320 ""
321 "
322 { rtx op0 = operands[0];
323
324 if (GET_CODE (op0) == MEM && ! reload_in_progress)
325 {
326 emit_insn (gen_storehi (operands[0], force_reg (HImode, operands[1])));
327 DONE;
328 }
329 }")
330
331 (define_insn ""
332 [(set (match_operand:HI 0 "register_operand" "=b")
333 (match_operand:HI 1 "symbolic_memory_operand" "m"))]
334 ""
335 "loadha %0,%1"
336 [(set_attr "type" "load")])
337
338 (define_insn ""
339 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,b,Q")
340 (match_operand:HI 1 "romp_operand" "r,I,n,s,Q,m,r"))]
341 "register_operand (operands[0], HImode)
342 || register_operand (operands[1], HImode)"
343 "@
344 cas %0,%1,r0
345 lis %0,%1
346 cal %0,%L1(r0)
347 get %0,$%1
348 lh%N1 %0,%1
349 loadh %0,%1
350 sth%M0 %1,%0"
351 [(set_attr "type" "address,address,address,misc,loadz,loadz,store")
352 (set_attr "length" "2,2,4,8,*,*,*")])
353
354 (define_insn "storehi"
355 [(set (match_operand:HI 0 "memory_operand" "=Q,m")
356 (match_operand:HI 1 "register_operand" "r,r"))
357 (clobber (match_scratch:SI 2 "=X,&b"))]
358 ""
359 "@
360 sth%M0 %1,%0
361 storeh %1,%0,%2"
362 [(set_attr "type" "store")])
363
364 (define_expand "reload_outhi"
365 [(set (match_operand:HI 0 "symbolic_memory_operand" "=m")
366 (match_operand:HI 1 "" "r"))
367 (match_operand:SI 2 "" "=&b")]
368 ""
369 "")
370 \f
371 ;; For DI move, if we have a constant, break the operation apart into
372 ;; two SImode moves because the optimizer may be able to do a better job
373 ;; with the resulting code.
374 ;;
375 ;; For memory stores, make the required pseudo for a temporary in case we
376 ;; are storing into an absolute address.
377 ;;
378 ;; We need to be careful about the cases where the output is a register that is
379 ;; the second register of the input.
380
381 (define_expand "movdi"
382 [(set (match_operand:DI 0 "general_operand" "")
383 (match_operand:DI 1 "general_operand" ""))]
384 ""
385 "
386 { rtx op0 = operands[0];
387 rtx op1 = operands[1];
388
389 if (CONSTANT_P (op1))
390 {
391 rtx insns;
392
393 start_sequence ();
394 emit_move_insn (operand_subword (op0, 0, 1, DImode),
395 operand_subword (op1, 0, 1, DImode));
396 emit_move_insn (operand_subword (op0, 1, 1, DImode),
397 operand_subword (op1, 1, 1, DImode));
398 insns = get_insns ();
399 end_sequence ();
400
401 emit_no_conflict_block (insns, op0, op1, 0, op1);
402 DONE;
403 }
404
405 if (GET_CODE (op0) == MEM && ! reload_in_progress)
406 {
407 emit_insn (gen_storedi (operands[0], force_reg (DImode, operands[1])));
408 DONE;
409 }
410 }")
411
412 (define_insn ""
413 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
414 (match_operand:DI 1 "reg_or_mem_operand" "r,Q,m,r"))]
415 "register_operand (operands[0], DImode)
416 || register_operand (operands[1], DImode)"
417 "*
418 {
419 switch (which_alternative)
420 {
421 case 0:
422 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
423 return \"cas %O0,%O1,r0\;cas %0,%1,r0\";
424 else
425 return \"cas %0,%1,r0\;cas %O0,%O1,r0\";
426 case 1:
427 /* Here we must see which word to load first. We default to the
428 low-order word unless it occurs in the address. */
429 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
430 operands[1], 0))
431 return \"l%M1 %O0,%O1\;l%M1 %0,%1\";
432 else
433 return \"l%M1 %0,%1\;l%M1 %O0,%O1\";
434 case 2:
435 return \"get %O0,$%1\;ls %0,0(%O0)\;ls %O0,4(%O0)\";
436 case 3:
437 return \"st%M0 %1,%0\;st%M0 %O1,%O0\";
438 }
439 }"
440 [(set_attr "type" "multi")
441 (set_attr "cc" "change0,change0,change0,none")
442 (set_attr "length" "4,12,8,8")])
443
444 (define_insn "storedi"
445 [(set (match_operand:DI 0 "memory_operand" "=Q,m")
446 (match_operand:DI 1 "register_operand" "r,r"))
447 (clobber (match_scratch:SI 2 "=X,&b"))]
448 ""
449 "@
450 st%M0 %1,%0\;st%M0 %O1,%O0
451 get %2,$%0\;sts %1,0(%2)\;sts %O1,4(%2)"
452 [(set_attr "type" "multi,multi")
453 (set_attr "cc" "none,none")
454 (set_attr "length" "8,12")])
455
456 (define_expand "reload_outdi"
457 [(set (match_operand:DI 0 "symbolic_memory_operand" "=m")
458 (match_operand:DI 1 "" "r"))
459 (match_operand:SI 2 "" "=&b")]
460 ""
461 "")
462
463 ;; Split symbolic memory operands differently. We first load the address
464 ;; into a register and then do the two loads or stores. We can only do
465 ;; this if operand_subword won't produce a SUBREG, which is only when
466 ;; operands[0] is a hard register. Thus, these won't be used during the
467 ;; first insn scheduling pass.
468 (define_split
469 [(set (match_operand:DI 0 "register_operand" "")
470 (match_operand:DI 1 "symbolic_memory_operand" ""))]
471 "GET_CODE (operands[0]) == REG
472 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER"
473 [(set (match_dup 2) (match_dup 3))
474 (set (match_dup 4) (match_dup 5))
475 (set (match_dup 6) (match_dup 7))]
476 "
477 { operands[2] = operand_subword (operands[0], 1, 0, DImode);
478 operands[3] = XEXP (operands[1], 0);
479 operands[4] = operand_subword (operands[0], 0, 0, DImode);
480 operands[5] = gen_rtx (MEM, SImode, operands[2]);
481 operands[6] = operands[2];
482 operands[7] = gen_rtx (MEM, SImode,
483 gen_rtx (PLUS, SImode, operands[2],
484 gen_rtx (CONST_INT, VOIDmode, 4)));
485
486 if (operands[2] == 0 || operands[4] == 0)
487 FAIL;
488 }")
489
490 (define_split
491 [(set (match_operand:DI 0 "symbolic_memory_operand" "")
492 (match_operand:DI 1 "register_operand" ""))
493 (clobber (match_operand:SI 2 "register_operand" ""))]
494 "GET_CODE (operands[0]) == REG
495 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER"
496 [(set (match_dup 2) (match_dup 3))
497 (set (match_dup 4) (match_dup 5))
498 (set (match_dup 6) (match_dup 7))]
499 "
500 { operands[3] = XEXP (operands[0], 0);
501 operands[4] = gen_rtx (MEM, SImode, operands[2]);
502 operands[5] = operand_subword (operands[1], 0, 0, DImode);
503 operands[6] = gen_rtx (MEM, SImode,
504 gen_rtx (PLUS, SImode, operands[2],
505 gen_rtx (CONST_INT, VOIDmode, 4)));
506 operands[7] = operand_subword (operands[1], 1, 0, DImode);
507
508 if (operands[5] == 0 || operands[7] == 0)
509 FAIL;
510 }")
511
512 ;; If the output is a register and the input is memory, we have to be careful
513 ;; and see which word needs to be loaded first.
514 ;;
515 ;; Note that this case doesn't have a CLOBBER. Therefore, we must either
516 ;; be after reload or operand[0] must not be a MEM. So we don't need a
517 ;; CLOBBER on the new insns either.
518 ;;
519 ;; Due to a bug in sched.c, we do not want to split this insn if both
520 ;; operands are registers and they overlap unless reload has completed.
521 (define_split
522 [(set (match_operand:DI 0 "general_operand" "")
523 (match_operand:DI 1 "general_operand" ""))]
524 "! symbolic_memory_operand (operands[0], DImode)
525 && ! symbolic_memory_operand (operands[1], DImode)
526 && ! (GET_CODE (operands[0]) == REG
527 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
528 && ! (GET_CODE (operands[1]) == REG
529 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
530 && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
531 && ! reload_completed
532 && reg_overlap_mentioned_p (operands[0], operands[1]))"
533 [(set (match_dup 2) (match_dup 3))
534 (set (match_dup 4) (match_dup 5))]
535 "
536 { if (GET_CODE (operands[0]) != REG
537 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
538 operands[1], 0))
539 {
540 operands[2] = operand_subword (operands[0], 0, 0, DImode);
541 operands[3] = operand_subword (operands[1], 0, 0, DImode);
542 operands[4] = operand_subword (operands[0], 1, 0, DImode);
543 operands[5] = operand_subword (operands[1], 1, 0, DImode);
544 }
545 else
546 {
547 operands[2] = operand_subword (operands[0], 1, 0, DImode);
548 operands[3] = operand_subword (operands[1], 1, 0, DImode);
549 operands[4] = operand_subword (operands[0], 0, 0, DImode);
550 operands[5] = operand_subword (operands[1], 0, 0, DImode);
551 }
552
553 if (operands[2] == 0 || operands[3] == 0
554 || operands[4] == 0 || operands[5] == 0)
555 FAIL;
556 }")
557
558 (define_split
559 [(set (match_operand:DI 0 "general_operand" "")
560 (match_operand:DI 1 "general_operand" ""))
561 (clobber (match_operand:SI 6 "register_operand" ""))]
562 "! symbolic_memory_operand (operands[0], DImode)
563 && ! symbolic_memory_operand (operands[1], DImode)
564 && ! (GET_CODE (operands[0]) == REG
565 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
566 && ! (GET_CODE (operands[1]) == REG
567 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
568 && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
569 && ! reload_completed
570 && reg_overlap_mentioned_p (operands[0], operands[1]))"
571 [(parallel [(set (match_dup 2) (match_dup 3))
572 (clobber (match_dup 7))])
573 (parallel [(set (match_dup 4) (match_dup 5))
574 (clobber (match_dup 8))])]
575 "
576 { if (GET_CODE (operands[0]) != REG
577 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
578 operands[1], 0))
579 {
580 operands[2] = operand_subword (operands[0], 0, 0, DImode);
581 operands[3] = operand_subword (operands[1], 0, 0, DImode);
582 operands[4] = operand_subword (operands[0], 1, 0, DImode);
583 operands[5] = operand_subword (operands[1], 1, 0, DImode);
584 }
585 else
586 {
587 operands[2] = operand_subword (operands[0], 1, 0, DImode);
588 operands[3] = operand_subword (operands[1], 1, 0, DImode);
589 operands[4] = operand_subword (operands[0], 0, 0, DImode);
590 operands[5] = operand_subword (operands[1], 0, 0, DImode);
591 }
592
593 if (operands[2] == 0 || operands[3] == 0
594 || operands[4] == 0 || operands[5] == 0)
595 FAIL;
596
597 /* We must be sure to make two different SCRATCH operands, since they
598 are not allowed to be shared. After reload, however, we only have
599 a SCRATCH if we won't use the operand, so it is allowed to share it
600 then. */
601 if (reload_completed || GET_CODE (operands[6]) != SCRATCH)
602 operands[7] = operands[8] = operands[6];
603 else
604 {
605 operands[7] = gen_rtx (SCRATCH, SImode);
606 operands[8] = gen_rtx (SCRATCH, SImode);
607 }
608 }")
609
610 ;; Define move insns for SF, and DF.
611 ;;
612 ;; For register-register copies or a copy of something to itself, emit a
613 ;; single SET insn since it will likely be optimized away.
614 ;;
615 ;; Otherwise, emit a floating-point move operation unless both input and
616 ;; output are either constant, memory, or a non-floating-point hard register.
617 (define_expand "movdf"
618 [(parallel [(set (match_operand:DF 0 "general_operand" "")
619 (match_operand:DF 1 "general_operand" ""))
620 (clobber (reg:SI 0))
621 (clobber (reg:SI 15))])]
622 ""
623 "
624 { rtx op0 = operands[0];
625 rtx op1 = operands[1];
626
627 if (op0 == op1)
628 {
629 emit_insn (gen_rtx (SET, VOIDmode, op0, op1));
630 DONE;
631 }
632
633 if ((GET_CODE (op0) == MEM
634 || (GET_CODE (op0) == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER
635 && ! FP_REGNO_P (REGNO (op0))))
636 && (GET_CODE (op1) == MEM
637 || GET_CODE (op1) == CONST_DOUBLE
638 || (GET_CODE (op1) == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER
639 && ! FP_REGNO_P (REGNO (op1)) && ! rtx_equal_p (op0, op1))))
640 {
641 rtx insns;
642
643 if (GET_CODE (op1) == CONST_DOUBLE)
644 op1 = force_const_mem (DFmode, op1);
645
646 start_sequence ();
647 if (GET_CODE (operands[0]) != REG
648 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
649 operands[1]), 0)
650 {
651 emit_move_insn (operand_subword (op0, 0, 1, DFmode),
652 operand_subword_force (op1, 0, DFmode));
653 emit_move_insn (operand_subword (op0, 1, 1, DFmode),
654 operand_subword_force (op1, 1, DFmode));
655 }
656 else
657 {
658 emit_move_insn (operand_subword (op0, 1, 1, DFmode),
659 operand_subword_force (op1, 1, DFmode));
660 emit_move_insn (operand_subword (op0, 0, 1, DFmode),
661 operand_subword_force (op1, 0, DFmode));
662 }
663
664 insns = get_insns ();
665 end_sequence ();
666
667 emit_no_conflict_block (insns, op0, op1, 0, op1);
668 DONE;
669 }
670 }")
671
672 (define_expand "movsf"
673 [(parallel [(set (match_operand:SF 0 "general_operand" "")
674 (match_operand:SF 1 "general_operand" ""))
675 (clobber (reg:SI 0))
676 (clobber (reg:SI 15))])]
677 ""
678 "
679 { rtx op0 = operands[0];
680 rtx op1 = operands[1];
681
682 if (op0 == op1)
683 {
684 emit_insn (gen_rtx (SET, VOIDmode, op0, op1));
685 DONE;
686 }
687
688 if ((GET_CODE (op0) == MEM
689 || (GET_CODE (op0) == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER
690 && ! FP_REGNO_P (REGNO (op0))))
691 && (GET_CODE (op1) == MEM
692 || GET_CODE (op1) == CONST_DOUBLE
693 || (GET_CODE (op1) == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER
694 && ! FP_REGNO_P (REGNO (op1)))))
695 {
696 rtx last;
697
698 if (GET_CODE (op1) == CONST_DOUBLE)
699 op1 = force_const_mem (SFmode, op1);
700
701 last = emit_move_insn (operand_subword (op0, 0, 1, SFmode),
702 operand_subword_force (op1, 0, SFmode));
703
704 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, op1, REG_NOTES (last));
705 DONE;
706 }
707 }")
708
709 ;; Define the move insns for SF and DF. Check for all general regs
710 ;; in the FP insns and make them non-FP if so. Do the same if the input and
711 ;; output are the same (the insn will be deleted in this case and we don't
712 ;; want to think there are FP insns when there might not be).
713 (define_insn ""
714 [(set (match_operand:SF 0 "general_operand" "=*frg")
715 (match_dup 0))]
716 ""
717 "nopr r0"
718 [(set_attr "type" "address")
719 (set_attr "length" "2")])
720
721 (define_insn ""
722 [(set (match_operand:SF 0 "general_operand" "=r,*fr,r,r,Q,m,frg")
723 (match_operand:SF 1 "general_operand" "r,0,Q,m,r,r,frg"))
724 (clobber (match_operand:SI 2 "reg_0_operand" "=&z,z,z,z,z,z,z"))
725 (clobber (match_operand:SI 3 "reg_15_operand" "=&t,t,t,t,t,t,t"))]
726 ""
727 "*
728 { switch (which_alternative)
729 {
730 case 0:
731 return \"cas %0,%1,r0\";
732 case 1:
733 return \"nopr r0\";
734 case 2:
735 return \"l%M1 %0,%1\";
736 case 3:
737 return \"load %0,%1\";
738 case 4:
739 return \"st%M0 %1,%0\";
740 case 5:
741 return \"store %1,%0,%3\";
742 default:
743 return output_fpop (SET, operands[0], operands[1], 0, insn);
744 }
745 }"
746 [(set_attr "type" "address,address,load,load,store,store,fp")
747 (set_attr "length" "2,2,*,*,*,*,*")])
748
749 (define_insn ""
750 [(set (match_operand:DF 0 "general_operand" "=*frg")
751 (match_dup 0))]
752 ""
753 "nopr r0"
754 [(set_attr "type" "address")
755 (set_attr "length" "2")])
756
757 (define_insn ""
758 [(set (match_operand:DF 0 "general_operand" "=r,*fr,r,r,Q,m,frg")
759 (match_operand:DF 1 "general_operand" "r,0,Q,m,r,r,*frg"))
760 (clobber (match_operand:SI 2 "reg_0_operand" "=&z,z,z,z,z,z,z"))
761 (clobber (match_operand:SI 3 "reg_15_operand" "=&t,t,t,t,t,t,t"))]
762 ""
763 "*
764 { switch (which_alternative)
765 {
766 case 0:
767 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
768 return \"cas %O0,%O1,r0\;cas %0,%1,r0\";
769 else
770 return \"cas %0,%1,r0\;cas %O0,%O1,r0\";
771 case 1:
772 return \"nopr r0\";
773 case 2:
774 /* Here we must see which word to load first. We default to the
775 low-order word unless it occurs in the address. */
776 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
777 operands[1], 0))
778 return \"l%M1 %O0,%O1\;l%M1 %0,%1\";
779 else
780 return \"l%M1 %0,%1\;l%M1 %O0,%O1\";
781 case 3:
782 return \"get %3,$%1\;ls %0,0(%3)\;ls %O0,4(%3)\";
783 case 4:
784 return \"st%M0 %1,%0\;st%M0 %O1,%O0\";
785 case 5:
786 return \"get %3,$%0\;sts %1,0(%3)\;sts %O1,4(%3)\";
787 default:
788 return output_fpop (SET, operands[0], operands[1], 0, insn);
789 }
790 }"
791 [(set_attr "type" "address,multi,multi,multi,multi,multi,fp")
792 (set_attr "length" "2,4,*,*,*,*,*")])
793
794 ;; Split all the above cases that involve multiple insns and no floating-point
795 ;; data block. If before reload, we can make a SCRATCH. Otherwise, use
796 ;; register 15.
797
798 (define_split
799 [(set (match_operand:DF 0 "register_operand" "")
800 (match_operand:DF 1 "symbolic_memory_operand" ""))
801 (clobber (reg:SI 0))
802 (clobber (reg:SI 15))]
803 "GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 16"
804 [(set (reg:SI 15) (match_dup 2))
805 (set (match_dup 3) (match_dup 4))
806 (set (match_dup 5) (match_dup 6))]
807 "
808 { operands[2] = XEXP (operands[1], 0);
809 operands[3] = operand_subword (operands[0], 0, 0, DFmode);
810 operands[4] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 15));
811 operands[5] = operand_subword (operands[0], 1, 0, DFmode);
812 operands[6] = gen_rtx (MEM, SImode,
813 gen_rtx (PLUS, SImode, gen_rtx (REG, SImode, 15),
814 gen_rtx (CONST_INT, VOIDmode, 4)));
815
816 if (operands[3] == 0 || operands[5] == 0)
817 FAIL;
818 }")
819
820 (define_split
821 [(set (match_operand:DF 0 "symbolic_memory_operand" "")
822 (match_operand:DF 1 "register_operand" ""))
823 (clobber (reg:SI 0))
824 (clobber (reg:SI 15))]
825 "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 16"
826 [(set (reg:SI 15) (match_dup 2))
827 (set (match_dup 3) (match_dup 4))
828 (set (match_dup 5) (match_dup 6))]
829 "
830 { operands[2] = XEXP (operands[0], 0);
831 operands[3] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 15));
832 operands[4] = operand_subword (operands[1], 0, 0, DFmode);
833 operands[5] = gen_rtx (MEM, SImode,
834 gen_rtx (PLUS, SImode, gen_rtx (REG, SImode, 15),
835 gen_rtx (CONST_INT, VOIDmode, 4)));
836 operands[6] = operand_subword (operands[1], 1, 0, DFmode);
837
838 if (operands[4] == 0 || operands[6] == 0)
839 FAIL;
840 }")
841
842 ;; If the output is a register and the input is memory, we have to be careful
843 ;; and see which word needs to be loaded first. We also cannot to the
844 ;; split if the input is a constant because it would result in invalid
845 ;; insns. When the output is a MEM, we must put a CLOBBER on each of the
846 ;; resulting insn, when it is not a MEM, we must not.
847 (define_split
848 [(set (match_operand:DF 0 "memory_operand" "")
849 (match_operand:DF 1 "register_operand" ""))
850 (clobber (reg:SI 0))
851 (clobber (reg:SI 15))]
852 "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 15"
853 [(parallel [(set (match_dup 2) (match_dup 3))
854 (clobber (match_dup 6))])
855 (parallel [(set (match_dup 4) (match_dup 5))
856 (clobber (match_dup 7))])]
857 "
858 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
859 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
860 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
861 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
862
863 if (operands[2] == 0 || operands[3] == 0
864 || operands[4] == 0 || operands[5] == 0)
865 FAIL;
866
867 if (reload_completed)
868 operands[6] = operands[7] = gen_rtx (REG, SImode, 15);
869 else
870 {
871 operands[6] = gen_rtx (SCRATCH, SImode);
872 operands[7] = gen_rtx (SCRATCH, SImode);
873 }
874 }")
875
876 (define_split
877 [(set (match_operand:DF 0 "nonmemory_operand" "")
878 (match_operand:DF 1 "general_operand" ""))
879 (clobber (reg:SI 0))
880 (clobber (reg:SI 15))]
881 "! symbolic_memory_operand (operands[1], DFmode)
882 && GET_CODE (operands[1]) != CONST_DOUBLE
883 && (GET_CODE (operands[0]) != REG || REGNO (operands[0]) < 15)
884 && (GET_CODE (operands[1]) != REG || REGNO (operands[1]) < 15)
885 && (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
886 && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
887 && ! reload_completed
888 && reg_overlap_mentioned_p (operands[0], operands[1]))"
889 [(set (match_dup 2) (match_dup 3))
890 (set (match_dup 4) (match_dup 5))]
891 "
892 { if (GET_CODE (operands[0]) != REG
893 || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
894 operands[1], 0))
895 {
896 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
897 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
898 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
899 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
900 }
901 else
902 {
903 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
904 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
905 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
906 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
907 }
908
909 if (operands[2] == 0 || operands[3] == 0
910 || operands[4] == 0 || operands[5] == 0)
911 FAIL;
912 }")
913 \f
914 ;; Conversions from one integer mode to another.
915 ;; It is possible sometimes to sign- or zero-extend while fetching from memory.
916 ;;
917 ;; First, sign-extensions:
918 (define_expand "extendhisi2"
919 [(set (match_operand:SI 0 "register_operand" "")
920 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
921 ""
922 "")
923
924 (define_insn ""
925 [(set (match_operand:SI 0 "register_operand" "=b")
926 (sign_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))]
927 ""
928 "loadha %0,%1"
929 [(set_attr "type" "load")])
930
931 (define_insn ""
932 [(set (match_operand:SI 0 "register_operand" "=r,r,b")
933 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))]
934 ""
935 "@
936 exts %0,%1
937 lha%M1 %0,%1
938 loadha %0,%1"
939 [(set_attr "type" "arith,load,load")
940 (set_attr "length" "2,*,*")])
941
942 (define_expand "extendqisi2"
943 [(set (match_dup 2)
944 (ashift:SI (match_operand:QI 1 "register_operand" "")
945 (const_int 24)))
946 (set (match_operand:SI 0 "register_operand" "")
947 (ashiftrt:SI (match_dup 2)
948 (const_int 24)))]
949 ""
950 "
951 { operands[1] = gen_lowpart (SImode, operands[1]);
952 operands[2] = gen_reg_rtx (SImode); }")
953
954 (define_expand "extendqihi2"
955 [(set (match_dup 2)
956 (ashift:SI (match_operand:QI 1 "register_operand" "")
957 (const_int 24)))
958 (set (match_operand:HI 0 "register_operand" "")
959 (ashiftrt:SI (match_dup 2)
960 (const_int 24)))]
961 ""
962 "
963 { operands[0] = gen_lowpart (SImode, operands[0]);
964 operands[1] = gen_lowpart (SImode, operands[1]);
965 operands[2] = gen_reg_rtx (SImode); }")
966
967 ;; Define peepholes to eliminate an instruction when we are doing a sign
968 ;; extension but cannot clobber the input.
969 ;;
970 ;; In this case we will shift left 24 bits, but need a copy first. The shift
971 ;; can be replaced by a "mc03" instruction, but this can only be done if
972 ;; followed by the right shift of 24 or more bits.
973 (define_peephole
974 [(set (match_operand:SI 0 "register_operand" "")
975 (subreg:SI (match_operand:QI 1 "register_operand" "") 0))
976 (set (match_dup 0)
977 (ashift:SI (match_dup 0)
978 (const_int 24)))
979 (set (match_dup 0)
980 (ashiftrt:SI (match_dup 0)
981 (match_operand:SI 2 "const_int_operand" "")))]
982 "INTVAL (operands[2]) >= 24"
983 "mc03 %0,%1\;sari16 %0,%S2"
984 [(set_attr "type" "multi")
985 (set_attr "length" "4")
986 (set_attr "cc" "sets")])
987
988 ;; Now zero extensions:
989 (define_expand "zero_extendhisi2"
990 [(set (match_operand:SI 0 "register_operand" "")
991 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
992 ""
993 "")
994
995 (define_insn ""
996 [(set (match_operand:SI 0 "register_operand" "=b")
997 (zero_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))]
998 ""
999 "loadh %0,%1"
1000 [(set_attr "type" "load")])
1001
1002 (define_insn ""
1003 [(set (match_operand:SI 0 "register_operand" "=r,r,b")
1004 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))]
1005 ""
1006 "@
1007 nilz %0,%1,65535
1008 lh%N1 %0,%1
1009 loadh %0,%1"
1010 [(set_attr "type" "arith,loadz,load")])
1011
1012 (define_expand "zero_extendqisi2"
1013 [(set (match_operand:SI 0 "register_operand" "")
1014 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1015 ""
1016 "")
1017
1018 (define_insn ""
1019 [(set (match_operand:SI 0 "register_operand" "=b")
1020 (zero_extend:SI (match_operand:QI 1 "symbolic_memory_operand" "m")))]
1021 ""
1022 "loadc %0,%1"
1023 [(set_attr "type" "load")])
1024
1025 (define_insn ""
1026 [(set (match_operand:SI 0 "register_operand" "=r,r,b")
1027 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))]
1028 ""
1029 "@
1030 nilz %0,%1,255
1031 lc%M1 %0,%1
1032 loadc %0,%1"
1033 [(set_attr "type" "arith,load,load")])
1034
1035 (define_expand "zero_extendqihi2"
1036 [(set (match_operand:HI 0 "register_operand" "")
1037 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1038 ""
1039 "")
1040
1041 (define_insn ""
1042 [(set (match_operand:HI 0 "register_operand" "=b")
1043 (zero_extend:HI (match_operand:QI 1 "symbolic_memory_operand" "m")))]
1044 ""
1045 "loadc %0,%1"
1046 [(set_attr "type" "load")])
1047
1048 (define_insn ""
1049 [(set (match_operand:HI 0 "register_operand" "=r,r,b")
1050 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))]
1051 ""
1052 "@
1053 nilz %0,%1,255
1054 lc%M1 %0,%1
1055 loadc %0,%1"
1056 [(set_attr "type" "arith,load,load")])
1057 \f
1058 ;; Various extract and insertion operations.
1059 (define_expand "extzv"
1060 [(set (match_operand:SI 0 "register_operand" "")
1061 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
1062 (match_operand:SI 2 "const_int_operand" "")
1063 (match_operand:SI 3 "const_int_operand" "")))]
1064 ""
1065 "
1066 {
1067 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
1068 FAIL;
1069
1070 if (GET_CODE (operands[3]) != CONST_INT)
1071 FAIL;
1072
1073 if (INTVAL (operands[3]) != 0 && INTVAL (operands[3]) != 8
1074 && INTVAL (operands[3]) != 16 && INTVAL (operands[3]) != 24)
1075 FAIL;
1076 }")
1077
1078 (define_insn ""
1079 [(set (match_operand:SI 0 "register_operand" "=&r")
1080 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1081 (const_int 8)
1082 (match_operand:SI 2 "const_int_operand" "n")))]
1083 "(INTVAL (operands[2]) & 7) == 0"
1084 "lis %0,0\;mc3%B2 %0,%1"
1085 [(set_attr "type" "multi")
1086 (set_attr "cc" "change0")])
1087
1088 (define_split
1089 [(set (match_operand:SI 0 "register_operand" "=&r")
1090 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1091 (const_int 8)
1092 (match_operand:SI 2 "const_int_operand" "n")))]
1093 "(INTVAL (operands[2]) & 7) == 0"
1094 [(set (match_dup 0) (const_int 0))
1095 (set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 24))
1096 (zero_extract:SI (match_dup 1) (const_int 8) (match_dup 2)))]
1097 "")
1098
1099 (define_insn ""
1100 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1101 (const_int 8)
1102 (const_int 24))
1103 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1104 (const_int 8)
1105 (match_operand:SI 2 "const_int_operand" "n")))]
1106 "(INTVAL (operands[2]) & 7) == 0"
1107 "mc3%B2 %0,%1"
1108 [(set_attr "type" "address")
1109 (set_attr "length" "2")])
1110
1111 (define_expand "insv"
1112 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
1113 (match_operand:SI 1 "const_int_operand" "")
1114 (match_operand:SI 2 "const_int_operand" ""))
1115 (match_operand:SI 3 "register_operand" ""))]
1116 ""
1117 "
1118 {
1119 if (GET_CODE (operands[2]) != CONST_INT)
1120 FAIL;
1121
1122 if (GET_CODE (operands[1]) != CONST_INT)
1123 FAIL;
1124
1125 if (INTVAL (operands[1]) == 1)
1126 {
1127 emit_insn (gen_bit_insv (operands[0], operands[1], operands[2],
1128 operands[3]));
1129 DONE;
1130 }
1131 else if (INTVAL (operands[1]) == 8
1132 && (INTVAL (operands[2]) % 8 == 0))
1133 ; /* Accept aligned byte-wide field. */
1134 else
1135 FAIL;
1136 }")
1137
1138 ;; For a single-bit insert, it is better to explicitly generate references
1139 ;; to the T bit. We will call the T bit "CC0" because it can be clobbered
1140 ;; by some CC0 sets (single-bit tests).
1141
1142 (define_expand "bit_insv"
1143 [(set (cc0)
1144 (zero_extract:SI (match_operand:SI 3 "register_operand" "")
1145 (const_int 1)
1146 (const_int 31)))
1147 (parallel [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
1148 (match_operand:SI 1 "const_int_operand" "")
1149 (match_operand:SI 2 "const_int_operand" ""))
1150 (ne (cc0) (const_int 0)))
1151 (clobber (match_scratch:SI 4 ""))])]
1152 ""
1153 "")
1154
1155 (define_insn ""
1156 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1157 (const_int 8)
1158 (match_operand:SI 1 "const_int_operand" "n"))
1159 (match_operand:SI 2 "register_operand" "r"))]
1160 "(INTVAL (operands[1]) & 7) == 0"
1161 "mc%B1%.3 %0,%2"
1162 [(set_attr "type" "address")
1163 (set_attr "length" "2")])
1164
1165 ;; This pattern cannot have any input reloads since if references CC0.
1166 ;; So we have to add code to support memory, which is the only other
1167 ;; thing that a "register_operand" can become. There is still a problem
1168 ;; if the address isn't valid and *it* needs a reload, but there is no
1169 ;; way to solve that problem, so let's hope it never happens.
1170
1171 (define_insn ""
1172 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,m")
1173 (const_int 1)
1174 (match_operand:SI 1 "const_int_operand" "n,m"))
1175 (ne (cc0) (const_int 0)))
1176 (clobber (match_scratch:SI 2 "=X,b"))]
1177 ""
1178 "@
1179 mftbi%t1 %0,%S1
1180 l%M0 %2,%0\;mftb%t1 %2,%S1\;st%M0 %2,%0"
1181 [(set_attr "type" "*,multi")
1182 (set_attr "cc" "none,none")
1183 (set_attr "length" "2,10")])
1184 \f
1185 ;; Arithmetic instructions. First, add and subtract.
1186 ;;
1187 ;; It may be that the second input is either large or small enough that
1188 ;; the operation cannot be done in a single insn. In that case, emit two.
1189 (define_expand "addsi3"
1190 [(set (match_operand:SI 0 "register_operand" "")
1191 (plus:SI (match_operand:SI 1 "register_operand" "")
1192 (match_operand:SI 2 "nonmemory_operand" "")))]
1193 ""
1194 "
1195 {
1196 if (GET_CODE (operands[2]) == CONST_INT
1197 && (unsigned) (INTVAL (operands[2]) + 0x8000) >= 0x10000
1198 && (INTVAL (operands[2]) & 0xffff) != 0)
1199 {
1200 int low = INTVAL (operands[2]) & 0xffff;
1201 int high = (unsigned) INTVAL (operands[2]) >> 16;
1202
1203 if (low & 0x8000)
1204 high++, low |= 0xffff0000;
1205
1206 emit_insn (gen_addsi3 (operands[0], operands[1],
1207 gen_rtx (CONST_INT, VOIDmode, high << 16)));
1208 operands[1] = operands[0];
1209 operands[2] = gen_rtx (CONST_INT, VOIDmode, low);
1210 }
1211 }")
1212
1213 ;; Put the insn to add a symbolic constant to a register separately to
1214 ;; improve register allocation since it has different register requirements.
1215 (define_insn ""
1216 [(set (match_operand:SI 0 "register_operand" "=b")
1217 (plus:SI (match_operand:SI 1 "register_operand" "%b")
1218 (match_operand:SI 2 "romp_symbolic_operand" "s")))]
1219 ""
1220 "get %0,$%2(%1)"
1221 [(set_attr "type" "address")
1222 (set_attr "length" "8")])
1223
1224 (define_insn ""
1225 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,b")
1226 (plus:SI (match_operand:SI 1 "reg_or_add_operand" "%0,0,r,b,0,r,b")
1227 (match_operand:SI 2 "reg_or_add_operand" "I,J,K,M,r,b,s")))]
1228 "register_operand (operands[1], SImode)
1229 || register_operand (operands[2], SImode)"
1230 "@
1231 ais %0,%2
1232 sis %0,%n2
1233 ail %0,%1,%2
1234 cau %0,%H2(%1)
1235 a %0,%2
1236 cas %0,%1,%2
1237 get %0,$%2(%1)"
1238 [(set_attr "type" "arith,arith,arith,address,arith,address,misc")
1239 (set_attr "length" "2,2,4,4,2,2,8")])
1240
1241 ;; Now subtract.
1242 ;;
1243 ;; 1. If third operand is constant integer, convert it to add of the negative
1244 ;; of that integer.
1245 ;; 2. If the second operand is not a valid constant integer, force it into a
1246 ;; register.
1247 (define_expand "subsi3"
1248 [(set (match_operand:SI 0 "register_operand" "")
1249 (minus:SI (match_operand:SI 1 "reg_or_any_cint_operand" "")
1250 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1251 ""
1252 "
1253 {
1254 if (GET_CODE (operands [2]) == CONST_INT)
1255 {
1256 emit_insn (gen_addsi3 (operands[0], operands[1],
1257 gen_rtx (CONST_INT,
1258 VOIDmode, - INTVAL (operands[2]))));
1259 DONE;
1260 }
1261 else
1262 operands[2] = force_reg (SImode, operands[2]);
1263
1264 if (GET_CODE (operands[1]) != CONST_INT
1265 || (unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000)
1266 operands[1] = force_reg (SImode, operands[1]);
1267 }")
1268
1269 (define_insn ""
1270 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1271 (minus:SI (match_operand:SI 1 "reg_or_D_operand" "K,0,r")
1272 (match_operand:SI 2 "register_operand" "r,r,0")))]
1273 ""
1274 "@
1275 sfi %0,%2,%1
1276 s %0,%2
1277 sf %0,%1"
1278 [(set_attr "length" "4,2,2")])
1279 \f
1280 ;; Multiply either calls a special RT routine or is done in-line, depending
1281 ;; on the value of a -m flag.
1282 ;;
1283 ;; First define the way we call the subroutine.
1284 (define_expand "mulsi3_subr"
1285 [(set (reg:SI 2) (match_operand:SI 1 "register_operand" ""))
1286 (set (reg:SI 3) (match_operand:SI 2 "register_operand" ""))
1287 (parallel [(set (reg:SI 2) (mult:SI (reg:SI 2) (reg:SI 3)))
1288 (clobber (reg:SI 0))
1289 (clobber (reg:SI 15))])
1290 (set (match_operand:SI 0 "register_operand" "")
1291 (reg:SI 2))]
1292 ""
1293 "")
1294
1295 (define_expand "mulsi3"
1296 [(set (match_operand:SI 0 "register_operand" "")
1297 (mult:SI (match_operand:SI 1 "register_operand" "")
1298 (match_operand:SI 2 "register_operand" "")))]
1299 ""
1300 "
1301 {
1302 if (! TARGET_IN_LINE_MUL)
1303 {
1304 emit_insn (gen_mulsi3_subr (operands[0], operands[1], operands[2]));
1305 DONE;
1306 }
1307 }")
1308
1309 ;; Define the patterns to match.
1310 ;; We would like to provide a delay slot for the insns that call internal
1311 ;; routines, but doing so is risky since reorg will think that the use of
1312 ;; r2 and r3 is completed in the insn needing the delay slot. Also, it
1313 ;; won't know that the cc will be clobbered. So take the safe approach
1314 ;; and don't give them delay slots.
1315 (define_insn ""
1316 [(set (reg:SI 2)
1317 (mult:SI (reg:SI 2) (reg:SI 3)))
1318 (clobber (reg:SI 0))
1319 (clobber (reg:SI 15))]
1320 "! TARGET_IN_LINE_MUL"
1321 "bali%# r15,lmul$$"
1322 [(set_attr "type" "misc")
1323 (set_attr "in_delay_slot" "no")])
1324
1325 (define_insn ""
1326 [(set (match_operand:SI 0 "register_operand" "=&r")
1327 (mult:SI (match_operand:SI 1 "register_operand" "%r")
1328 (match_operand:SI 2 "register_operand" "r")))]
1329 "TARGET_IN_LINE_MUL"
1330 "*
1331 { return output_in_line_mul (); }"
1332 [(set_attr "length" "38")
1333 (set_attr "type" "multi")])
1334 \f
1335 ;; Handle divide and modulus. The same function returns both values,
1336 ;; so use divmodsi4. This divides arg 1 by arg 2 with quotient to go
1337 ;; into arg 0 and remainder in arg 3.
1338 ;;
1339 ;; We want to put REG_EQUAL notes for the two outputs. So we need a
1340 ;; function to do everything else.
1341 (define_expand "divmodsi4_doit"
1342 [(set (reg:SI 2)
1343 (match_operand:SI 0 "register_operand" ""))
1344 (set (reg:SI 3)
1345 (match_operand:SI 1 "register_operand" ""))
1346 (parallel [(set (reg:SI 2) (div:SI (reg:SI 2) (reg:SI 3)))
1347 (set (reg:SI 3) (mod:SI (reg:SI 2) (reg:SI 3)))
1348 (clobber (reg:SI 0))
1349 (clobber (reg:SI 15))])]
1350 ""
1351 "")
1352
1353 (define_expand "divmodsi4"
1354 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1355 (div:SI (match_operand:SI 1 "register_operand" "")
1356 (match_operand:SI 2 "register_operand" "")))
1357 (set (match_operand:SI 3 "register_operand" "")
1358 (mod:SI (match_dup 1) (match_dup 2)))])]
1359 ""
1360 "
1361 {
1362 rtx insn;
1363
1364 emit_insn (gen_divmodsi4_doit (operands[1], operands[2]));
1365 insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2));
1366 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1367 gen_rtx (DIV, SImode, operands[1],
1368 operands[2]),
1369 REG_NOTES (insn));
1370 insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3));
1371 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1372 gen_rtx (MOD, SImode, operands[1],
1373 operands[2]),
1374 REG_NOTES (insn));
1375 DONE;
1376 }")
1377
1378 (define_insn ""
1379 [(set (reg:SI 2)
1380 (div:SI (reg:SI 2) (reg:SI 3)))
1381 (set (reg:SI 3)
1382 (mod:SI (reg:SI 2) (reg:SI 3)))
1383 (clobber (reg:SI 0))
1384 (clobber (reg:SI 15))]
1385 ""
1386 "bali%# r15,ldiv$$"
1387 [(set_attr "type" "misc")
1388 (set_attr "in_delay_slot" "no")])
1389
1390 ;; Similarly for unsigned divide.
1391 (define_expand "udivmodsi4_doit"
1392 [(set (reg:SI 2)
1393 (match_operand:SI 0 "register_operand" ""))
1394 (set (reg:SI 3)
1395 (match_operand:SI 1 "register_operand" ""))
1396 (parallel [(set (reg:SI 2) (udiv:SI (reg:SI 2) (reg:SI 3)))
1397 (set (reg:SI 3) (umod:SI (reg:SI 2) (reg:SI 3)))
1398 (clobber (reg:SI 0))
1399 (clobber (reg:SI 15))])]
1400 ""
1401 "")
1402
1403 (define_expand "udivmodsi4"
1404 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1405 (udiv:SI (match_operand:SI 1 "register_operand" "")
1406 (match_operand:SI 2 "register_operand" "")))
1407 (set (match_operand:SI 3 "register_operand" "")
1408 (umod:SI (match_dup 1) (match_dup 2)))])]
1409 ""
1410 "
1411 {
1412 rtx insn;
1413
1414 emit_insn (gen_udivmodsi4_doit (operands[1], operands[2]));
1415 insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2));
1416 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1417 gen_rtx (UDIV, SImode, operands[1],
1418 operands[2]),
1419 REG_NOTES (insn));
1420 insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3));
1421 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
1422 gen_rtx (UMOD, SImode, operands[1],
1423 operands[2]),
1424 REG_NOTES (insn));
1425 DONE;
1426 }")
1427
1428 (define_insn ""
1429 [(set (reg:SI 2)
1430 (udiv:SI (reg:SI 2) (reg:SI 3)))
1431 (set (reg:SI 3)
1432 (umod:SI (reg:SI 2) (reg:SI 3)))
1433 (clobber (reg:SI 0))
1434 (clobber (reg:SI 15))]
1435 ""
1436 "bali%# r15,uldiv$$"
1437 [(set_attr "type" "misc")
1438 (set_attr "in_delay_slot" "no")])
1439 \f
1440 ;; Define DImode arithmetic operations.
1441 ;;
1442 ;; It is possible to do certain adds and subtracts with constants in a single
1443 ;; insn, but it doesn't seem worth the trouble.
1444 ;;
1445 ;; Don't use DEFINE_SPLIT on these because the dependency on CC can't be
1446 ;; easily tracked in that case!
1447 (define_insn "adddi3"
1448 [(set (match_operand:DI 0 "register_operand" "=r")
1449 (plus:DI (match_operand:DI 1 "register_operand" "%0")
1450 (match_operand:DI 2 "register_operand" "r")))]
1451 ""
1452 "a %O0,%O2\;ae %0,%2"
1453 [(set_attr "type" "multi")])
1454
1455 (define_insn "subdi3"
1456 [(set (match_operand:DI 0 "register_operand" "=r")
1457 (minus:DI (match_operand:DI 1 "register_operand" "0")
1458 (match_operand:DI 2 "register_operand" "r")))]
1459 ""
1460 "s %O0,%O2\;se %0,%2"
1461 [(set_attr "type" "multi")])
1462
1463 (define_insn "negdi2"
1464 [(set (match_operand:DI 0 "register_operand" "=r,&r")
1465 (neg:DI (match_operand:DI 1 "register_operand" "0,r")))]
1466 ""
1467 "twoc %O0,%O1\;onec %0,%1\;aei %0,%0,0"
1468 [(set_attr "type" "multi")
1469 (set_attr "length" "8")])
1470 \f
1471 ;; Unary arithmetic operations.
1472 (define_insn "abssi2"
1473 [(set (match_operand:SI 0 "register_operand" "=r")
1474 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1475 ""
1476 "abs %0,%1"
1477 [(set_attr "length" "2")])
1478
1479 (define_insn "negsi2"
1480 [(set (match_operand:SI 0 "register_operand" "=r")
1481 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1482 ""
1483 "twoc %0,%1"
1484 [(set_attr "length" "2")])
1485
1486 (define_insn "one_cmplsi2"
1487 [(set (match_operand:SI 0 "register_operand" "=r")
1488 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1489 ""
1490 "onec %0,%1"
1491 [(set_attr "length" "2")])
1492
1493 \f
1494 ;; Logical insns: AND, IOR, and XOR
1495 ;;
1496 ;; If the operation is being performed on a 32-bit constant such that
1497 ;; it cannot be done in one insn, do it in two. We may lose a bit on
1498 ;; CSE in pathological cases, but it seems better doing it this way.
1499 (define_expand "andsi3"
1500 [(set (match_operand:SI 0 "register_operand" "")
1501 (and:SI (match_operand:SI 1 "register_operand" "")
1502 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1503 ""
1504 "
1505 {
1506 if (GET_CODE (operands[2]) == CONST_INT)
1507 {
1508 int top = (unsigned) INTVAL (operands[2]) >> 16;
1509 int bottom = INTVAL (operands[2]) & 0xffff;
1510
1511 if (top != 0 && top != 0xffff && bottom != 0 && bottom != 0xffff)
1512 {
1513 emit_insn (gen_andsi3 (operands[0], operands[1],
1514 gen_rtx (CONST_INT, VOIDmode,
1515 (top << 16) | 0xffff)));
1516 operands[1] = operands[0];
1517 operands[2] = gen_rtx (CONST_INT, VOIDmode, 0xffff0000 | bottom);
1518 }
1519 }
1520 }");
1521
1522 (define_insn ""
1523 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1524 (and:SI (match_operand:SI 1 "reg_or_and_operand" "%0,r,0")
1525 (match_operand:SI 2 "reg_or_and_operand" "P,LMO,r")))]
1526 "register_operand (operands[1], SImode)
1527 || register_operand (operands[2], SImode)"
1528 "@
1529 clrb%k2 %0,%b2
1530 ni%z2 %0,%1,%Z2
1531 n %0,%2"
1532 [(set_attr "length" "2,4,2")])
1533
1534 ;; logical OR (IOR)
1535 (define_expand "iorsi3"
1536 [(set (match_operand:SI 0 "register_operand" "")
1537 (ior:SI (match_operand:SI 1 "register_operand" "")
1538 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1539 ""
1540 "
1541 {
1542 if (GET_CODE (operands[2]) == CONST_INT)
1543 {
1544 int top = (unsigned) INTVAL (operands[2]) >> 16;
1545 int bottom = INTVAL (operands[2]) & 0xffff;
1546
1547 if (top != 0 && bottom != 0)
1548 {
1549 emit_insn (gen_iorsi3 (operands[0], operands[1],
1550 gen_rtx (CONST_INT, VOIDmode, (top << 16))));
1551 operands[1] = operands[0];
1552 operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom);
1553 }
1554 }
1555 }");
1556
1557 (define_insn ""
1558 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1559 (ior:SI (match_operand:SI 1 "reg_or_cint_operand" "%0,r,0")
1560 (match_operand:SI 2 "reg_or_cint_operand" "N,LM,r")))]
1561 "register_operand (operands[1], SImode)
1562 || register_operand (operands[2], SImode)"
1563 "@
1564 setb%h2 %0,%b2
1565 oi%h2 %0,%1,%H2
1566 o %0,%2"
1567 [(set_attr "length" "2,4,2")])
1568
1569 ;; exclusive-or (XOR)
1570 (define_expand "xorsi3"
1571 [(set (match_operand:SI 0 "register_operand" "")
1572 (xor:SI (match_operand:SI 1 "register_operand" "")
1573 (match_operand:SI 2 "reg_or_any_cint_operand" "")))]
1574 ""
1575 "
1576 {
1577 if (GET_CODE (operands[2]) == CONST_INT)
1578 {
1579 int top = (unsigned) INTVAL (operands[2]) >> 16;
1580 int bottom = INTVAL (operands[2]) & 0xffff;
1581
1582 if (top == 0xffff && bottom == 0xffff)
1583 {
1584 emit_insn (gen_one_cmplsi2 (operands[0], operands[1]));
1585 DONE;
1586 }
1587 else if (top != 0 && bottom != 0)
1588 {
1589 emit_insn (gen_xorsi3 (operands[0], operands[1],
1590 gen_rtx (CONST_INT, VOIDmode, (top << 16))));
1591 operands[1] = operands[0];
1592 operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom);
1593 }
1594 }
1595 }");
1596
1597 (define_insn ""
1598 [(set (match_operand:SI 0 "register_operand" "=r,r")
1599 (xor:SI (match_operand:SI 1 "reg_or_cint_operand" "%r,0")
1600 (match_operand:SI 2 "reg_or_cint_operand" "LM,r")))]
1601 "register_operand (operands[1], SImode)
1602 || register_operand (operands[2], SImode)"
1603 "@
1604 xi%h2 %0,%1,%H2
1605 x %0,%2"
1606 [(set_attr "length" "4,2")])
1607 \f
1608 ;; Various shift insns
1609 (define_insn "ashrsi3"
1610 [(set (match_operand:SI 0 "register_operand" "=r,r")
1611 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1612 (match_operand:SI 2 "reg_or_cint_operand" "r,n")))]
1613 ""
1614 "@
1615 sar %0,%2
1616 sari%s2 %0,%S2"
1617 [(set_attr "length" "2")])
1618
1619 (define_insn "lshrsi3"
1620 [(set (match_operand:SI 0 "register_operand" "=r,r")
1621 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1622 (match_operand:SI 2 "reg_or_cint_operand" "r,n")))]
1623 ""
1624 "@
1625 sr %0,%2
1626 sri%s2 %0,%S2"
1627 [(set_attr "length" "2")])
1628
1629 (define_insn ""
1630 [(set (match_operand:SI 0 "register_operand" "=r")
1631 (ashift:SI (match_operand:SI 1 "register_operand" "b")
1632 (const_int 1)))]
1633 ""
1634 "cas %0,%1,%1"
1635 [(set_attr "length" "2")
1636 (set_attr "type" "address")])
1637
1638 (define_insn "ashlsi3"
1639 [(set (match_operand:SI 0 "register_operand" "=r,r")
1640 (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1641 (match_operand:SI 2 "reg_or_cint_operand" "r,n")))]
1642 ""
1643 "@
1644 sl %0,%2
1645 sli%s2 %0,%S2"
1646 [(set_attr "length" "2")])
1647 \f
1648 ;; Function call insns:
1649 ;;
1650 ;; On the ROMP, &fcn is actually a pointer to the data area, which is passed
1651 ;; to the function in r0. &.fcn is the actual starting address of the
1652 ;; function. Also, the word at &fcn contains &.fcn.
1653 ;;
1654 ;; For both functions that do and don't return values, there are two cases:
1655 ;; where the function's address is a constant, and where it isn't.
1656 ;;
1657 ;; Operand 1 (2 for `call_value') is the number of arguments and is not used.
1658 (define_expand "call"
1659 [(use (reg:SI 0))
1660 (parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
1661 (match_operand 1 "" ""))
1662 (clobber (reg:SI 15))])]
1663 ""
1664 "
1665 {
1666 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
1667 abort();
1668
1669 operands[0] = XEXP (operands[0], 0);
1670 if (GET_CODE (operands[0]) == SYMBOL_REF)
1671 {
1672 extern rtx get_symref ();
1673 char *real_fcnname =
1674 (char *) alloca (strlen (XSTR (operands[0], 0)) + 2);
1675
1676 /* Copy the data area address to r0. */
1677 emit_move_insn (gen_rtx (REG, SImode, 0),
1678 force_reg (SImode, operands[0]));
1679 strcpy (real_fcnname, \".\");
1680 strcat (real_fcnname, XSTR (operands[0], 0));
1681 operands[0] = get_symref (real_fcnname);
1682 }
1683 else
1684 {
1685 rtx data_access;
1686
1687 emit_move_insn (gen_rtx (REG, SImode, 0),
1688 force_reg (SImode, operands[0]));
1689 data_access = gen_rtx (MEM, SImode, operands[0]);
1690 RTX_UNCHANGING_P (data_access) = 1;
1691 operands[0] = copy_to_reg (data_access);
1692 }
1693 }")
1694
1695 (define_insn ""
1696 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
1697 (match_operand 1 "" "g"))
1698 (clobber (reg:SI 15))]
1699 ""
1700 "balr%# r15,%0"
1701 [(set_attr "type" "call")
1702 (set_attr "length" "2")])
1703
1704 (define_insn ""
1705 [(call (mem:SI (match_operand:SI 0 "romp_symbolic_operand" "i"))
1706 (match_operand 1 "" "g"))
1707 (clobber (reg:SI 15))]
1708 "GET_CODE (operands[0]) == SYMBOL_REF"
1709 "bali%# r15,%0"
1710 [(set_attr "type" "call")])
1711
1712 ;; Call a function and return a value.
1713 (define_expand "call_value"
1714 [(use (reg:SI 0))
1715 (parallel [(set (match_operand 0 "" "=fg")
1716 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
1717 (match_operand 2 "" "")))
1718 (clobber (reg:SI 15))])]
1719 ""
1720 "
1721 {
1722 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
1723 abort();
1724
1725 operands[1] = XEXP (operands[1], 0);
1726 if (GET_CODE (operands[1]) == SYMBOL_REF)
1727 {
1728 extern rtx get_symref ();
1729 char *real_fcnname =
1730 (char *) alloca (strlen (XSTR (operands[1], 0)) + 2);
1731
1732 /* Copy the data area address to r0. */
1733 emit_move_insn (gen_rtx (REG, SImode, 0),
1734 force_reg (SImode, operands[1]));
1735 strcpy (real_fcnname, \".\");
1736 strcat (real_fcnname, XSTR (operands[1], 0));
1737 operands[1] = get_symref (real_fcnname);
1738 }
1739 else
1740 {
1741 rtx data_access;
1742
1743 emit_move_insn (gen_rtx (REG, SImode, 0),
1744 force_reg (SImode, operands[1]));
1745 data_access = gen_rtx (MEM, SImode, operands[1]);
1746 RTX_UNCHANGING_P (data_access) = 1;
1747 operands[1] = copy_to_reg (data_access);
1748 }
1749 }")
1750
1751 (define_insn ""
1752 [(set (match_operand 0 "" "=fg")
1753 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
1754 (match_operand 2 "" "g")))
1755 (clobber (reg:SI 15))]
1756 ""
1757 "balr%# r15,%1"
1758 [(set_attr "length" "2")
1759 (set_attr "type" "call")])
1760
1761 (define_insn ""
1762 [(set (match_operand 0 "" "=fg")
1763 (call (mem:SI (match_operand:SI 1 "romp_symbolic_operand" "i"))
1764 (match_operand 2 "" "g")))
1765 (clobber (reg:SI 15))]
1766 "GET_CODE (operands[1]) == SYMBOL_REF"
1767 "bali%# r15,%1"
1768 [(set_attr "type" "call")])
1769
1770 ;; No operation insn.
1771 (define_insn "nop"
1772 [(const_int 0)]
1773 ""
1774 "nopr r0"
1775 [(set_attr "type" "address")
1776 (set_attr "length" "2")
1777 (set_attr "cc" "none")])
1778 \f
1779 ;; Here are the floating-point operations.
1780 ;;
1781 ;; Start by providing DEFINE_EXPAND for each operation.
1782 ;; The insns will be handled with MATCH_OPERATOR; the methodology will be
1783 ;; discussed below.
1784
1785 ;; First the conversion operations.
1786
1787 (define_expand "truncdfsf2"
1788 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1789 (float_truncate:SF (match_operand:DF 1 "general_operand" "")))
1790 (clobber (reg:SI 0))
1791 (clobber (reg:SI 15))])]
1792 ""
1793 "")
1794
1795 (define_expand "extendsfdf2"
1796 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1797 (float_extend:DF (match_operand:SF 1 "general_operand" "")))
1798 (clobber (reg:SI 0))
1799 (clobber (reg:SI 15))])]
1800 ""
1801 "")
1802
1803 (define_expand "floatsisf2"
1804 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1805 (float:SF (match_operand:SI 1 "general_operand" "")))
1806 (clobber (reg:SI 0))
1807 (clobber (reg:SI 15))])]
1808 ""
1809 "")
1810
1811 (define_expand "floatsidf2"
1812 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1813 (float:DF (match_operand:SI 1 "general_operand" "")))
1814 (clobber (reg:SI 0))
1815 (clobber (reg:SI 15))])]
1816 ""
1817 "")
1818
1819 (define_expand "fix_truncsfsi2"
1820 [(parallel [(set (match_operand:SI 0 "general_operand" "")
1821 (fix:SI (match_operand:SF 1 "general_operand" "")))
1822 (clobber (reg:SI 0))
1823 (clobber (reg:SI 15))])]
1824 ""
1825 "")
1826
1827 (define_expand "fix_truncdfsi2"
1828 [(parallel [(set (match_operand:SI 0 "general_operand" "")
1829 (fix:SI (match_operand:DF 1 "general_operand" "")))
1830 (clobber (reg:SI 0))
1831 (clobber (reg:SI 15))])]
1832 ""
1833 "")
1834 \f
1835 ;; Now the binary operations.
1836
1837 (define_expand "addsf3"
1838 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1839 (plus:SF (match_operand:SF 1 "general_operand" "")
1840 (match_operand:SF 2 "general_operand" "")))
1841 (clobber (reg:SI 0))
1842 (clobber (reg:SI 15))])]
1843 ""
1844 "")
1845
1846 (define_expand "adddf3"
1847 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1848 (plus:DF (match_operand:DF 1 "general_operand" "")
1849 (match_operand:DF 2 "general_operand" "")))
1850 (clobber (reg:SI 0))
1851 (clobber (reg:SI 15))])]
1852 ""
1853 "")
1854
1855 (define_expand "subsf3"
1856 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1857 (minus:SF (match_operand:SF 1 "general_operand" "")
1858 (match_operand:SF 2 "general_operand" "")))
1859 (clobber (reg:SI 0))
1860 (clobber (reg:SI 15))])]
1861 ""
1862 "")
1863
1864 (define_expand "subdf3"
1865 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1866 (minus:DF (match_operand:DF 1 "general_operand" "")
1867 (match_operand:DF 2 "general_operand" "")))
1868 (clobber (reg:SI 0))
1869 (clobber (reg:SI 15))])]
1870 ""
1871 "")
1872
1873 (define_expand "mulsf3"
1874 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1875 (mult:SF (match_operand:SF 1 "general_operand" "")
1876 (match_operand:SF 2 "general_operand" "")))
1877 (clobber (reg:SI 0))
1878 (clobber (reg:SI 15))])]
1879 ""
1880 "")
1881
1882 (define_expand "muldf3"
1883 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1884 (mult:DF (match_operand:DF 1 "general_operand" "")
1885 (match_operand:DF 2 "general_operand" "")))
1886 (clobber (reg:SI 0))
1887 (clobber (reg:SI 15))])]
1888 ""
1889 "")
1890
1891 (define_expand "divsf3"
1892 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1893 (div:SF (match_operand:SF 1 "general_operand" "")
1894 (match_operand:SF 2 "general_operand" "")))
1895 (clobber (reg:SI 0))
1896 (clobber (reg:SI 15))])]
1897 ""
1898 "")
1899
1900 (define_expand "divdf3"
1901 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1902 (div:DF (match_operand:DF 1 "general_operand" "")
1903 (match_operand:DF 2 "general_operand" "")))
1904 (clobber (reg:SI 0))
1905 (clobber (reg:SI 15))])]
1906 ""
1907 "")
1908 \f
1909 ;; Unary floating-point operations.
1910 ;;
1911 ;; Negations can be done without floating-point, since this is IEEE.
1912 ;; But we cannot do this if an operand is a hard FP register, since
1913 ;; the SUBREG we create would not be valid.
1914 (define_expand "negsf2"
1915 [(set (match_operand:SF 0 "register_operand" "")
1916 (neg:SF (match_operand:SF 1 "register_operand" "")))]
1917 ""
1918 "
1919 {
1920 if (! (GET_CODE (operands[0]) == REG
1921 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
1922 && FP_REGNO_P (REGNO (operands[0])))
1923 && ! (GET_CODE (operands[1]) == REG
1924 && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
1925 && FP_REGNO_P (REGNO (operands[1]))))
1926 {
1927 rtx result;
1928 rtx target = operand_subword (operands[0], 0, 1, SFmode);
1929
1930 result = expand_binop (SImode, xor_optab,
1931 operand_subword_force (operands[1], 0, SFmode),
1932 gen_rtx (CONST_INT, VOIDmode, 0x80000000),
1933 target, 0, OPTAB_WIDEN);
1934 if (result == 0)
1935 abort ();
1936
1937 if (result != target)
1938 emit_move_insn (result, target);
1939
1940 /* Make a place for REG_EQUAL. */
1941 emit_move_insn (operands[0], operands[0]);
1942 DONE;
1943 }
1944 }")
1945
1946 (define_expand "negdf2"
1947 [(set (match_operand:DF 0 "register_operand" "")
1948 (neg:DF (match_operand:DF 1 "register_operand" "")))]
1949 ""
1950 "
1951 {
1952 if (! (GET_CODE (operands[0]) == REG
1953 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
1954 && FP_REGNO_P (REGNO (operands[0])))
1955 && ! (GET_CODE (operands[1]) == REG
1956 && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
1957 && FP_REGNO_P (REGNO (operands[1]))))
1958 {
1959 rtx result;
1960 rtx target = operand_subword (operands[0], 0, 1, DFmode);
1961 rtx insns;
1962
1963 start_sequence ();
1964 result = expand_binop (SImode, xor_optab,
1965 operand_subword_force (operands[1], 0, DFmode),
1966 gen_rtx (CONST_INT, VOIDmode, 0x80000000),
1967 target, 0, OPTAB_WIDEN);
1968 if (result == 0)
1969 abort ();
1970
1971 if (result != target)
1972 emit_move_insn (result, target);
1973
1974 emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
1975 operand_subword_force (operands[1], 1, DFmode));
1976
1977 insns = get_insns ();
1978 end_sequence ();
1979
1980 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1981 DONE;
1982 }
1983 }")
1984
1985 (define_expand "abssf2"
1986 [(parallel [(set (match_operand:SF 0 "general_operand" "")
1987 (abs:SF (match_operand:SF 1 "general_operand" "")))
1988 (clobber (reg:SI 0))
1989 (clobber (reg:SI 15))])]
1990 ""
1991 "")
1992
1993 (define_expand "absdf2"
1994 [(parallel [(set (match_operand:DF 0 "general_operand" "")
1995 (abs:DF (match_operand:DF 1 "general_operand" "")))
1996 (clobber (reg:SI 0))
1997 (clobber (reg:SI 15))])]
1998 ""
1999 "")
2000 \f
2001 ;; Any floating-point operation can be either SFmode or DFmode, and each
2002 ;; operand (including the output) can be either a normal operand or a
2003 ;; conversion from a normal operand.
2004 ;;
2005 ;; We use MATCH_OPERATOR to match a floating-point binary or unary operator
2006 ;; and input and output conversions. So we need 2^N patterns for each type
2007 ;; of operation, where N is the number of operands, including the output.
2008 ;; There are thus a total of 14 patterns, 8 for binary operations, 4 for
2009 ;; unary operations and two for conversion/move operations (only one
2010 ;; operand can have a conversion for move operations). In addition, we have
2011 ;; to be careful that a floating-point reload register doesn't get allocated
2012 ;; for an integer. We take care of this for inputs with PREFERRED_RELOAD_CLASS
2013 ;; but need to have two different constraints for outputs. This means that
2014 ;; we have to duplicate each pattern where the output could be an integer.
2015 ;; This adds another 7 patterns, for a total of 21.
2016
2017 ;; Start with conversion operations (moves are done above).
2018
2019 (define_insn ""
2020 [(set (match_operand:SI 0 "general_operand" "=g")
2021 (match_operator 1 "float_conversion"
2022 [(match_operand 2 "general_operand" "frg")]))
2023 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2024 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2025 ""
2026 "*
2027 { return output_fpop (SET, operands[0], operands[2], 0, insn);
2028 }"
2029 [(set_attr "type" "fp")])
2030
2031 (define_insn ""
2032 [(set (match_operand 0 "general_operand" "=frg")
2033 (match_operator 1 "float_conversion"
2034 [(match_operand 2 "general_operand" "frg")]))
2035 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2036 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2037 ""
2038 "*
2039 { return output_fpop (SET, operands[0], operands[2], 0, insn);
2040 }"
2041 [(set_attr "type" "fp")])
2042 \f
2043 ;; Next, binary floating-point operations.
2044
2045 (define_insn ""
2046 [(set (match_operand 0 "general_operand" "=frg")
2047 (match_operator 1 "float_binary"
2048 [(match_operand 2 "general_operand" "frg")
2049 (match_operand 3 "general_operand" "frg")]))
2050 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2051 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2052 "check_precision (GET_MODE (operands[1]), operands[2], operands[3])"
2053 "*
2054 { return output_fpop (GET_CODE (operands[1]), operands[0],
2055 operands[2], operands[3], insn);
2056 }"
2057 [(set_attr "type" "fp")])
2058
2059 (define_insn ""
2060 [(set (match_operand 0 "general_operand" "=frg")
2061 (match_operator 1 "float_binary"
2062 [(match_operand 2 "general_operand" "frg")
2063 (match_operator 3 "float_conversion"
2064 [(match_operand 4 "general_operand" "frg")])]))
2065 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2066 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2067 "check_precision (GET_MODE (operands[1]), operands[2], operands[4])"
2068 "*
2069 { return output_fpop (GET_CODE (operands[1]), operands[0],
2070 operands[2], operands[4], insn);
2071 }"
2072 [(set_attr "type" "fp")])
2073
2074 (define_insn ""
2075 [(set (match_operand 0 "general_operand" "=frg")
2076 (match_operator 1 "float_binary"
2077 [(match_operator 2 "float_conversion"
2078 [(match_operand 3 "general_operand" "frg")])
2079 (match_operand 4 "general_operand" "frg")]))
2080 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2081 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2082 "check_precision (GET_MODE (operands[1]), operands[3], operands[4])"
2083 "*
2084 { return output_fpop (GET_CODE (operands[1]), operands[0],
2085 operands[3], operands[4], insn);
2086 }"
2087 [(set_attr "type" "fp")])
2088
2089 (define_insn ""
2090 [(set (match_operand 0 "general_operand" "=frg")
2091 (match_operator 1 "float_binary"
2092 [(match_operator 2 "float_conversion"
2093 [(match_operand 3 "general_operand" "frg")])
2094 (match_operator 4 "float_conversion"
2095 [(match_operand 5 "general_operand" "frg")])]))
2096 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2097 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2098 "check_precision (GET_MODE (operands[1]), operands[3], operands[5])"
2099 "*
2100 { return output_fpop (GET_CODE (operands[1]), operands[0],
2101 operands[3], operands[5], insn);
2102 }"
2103 [(set_attr "type" "fp")])
2104
2105 (define_insn ""
2106 [(set (match_operand:SI 0 "general_operand" "=g")
2107 (match_operator 1 "float_conversion"
2108 [(match_operator 2 "float_binary"
2109 [(match_operand 3 "general_operand" "frg")
2110 (match_operand 4 "general_operand" "frg")])]))
2111 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2112 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2113 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2114 "*
2115 { return output_fpop (GET_CODE (operands[2]), operands[0],
2116 operands[3], operands[4], insn);
2117 }"
2118 [(set_attr "type" "fp")])
2119
2120 (define_insn ""
2121 [(set (match_operand 0 "general_operand" "=frg")
2122 (match_operator 1 "float_conversion"
2123 [(match_operator 2 "float_binary"
2124 [(match_operand 3 "general_operand" "frg")
2125 (match_operand 4 "general_operand" "frg")])]))
2126 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2127 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2128 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2129 "*
2130 { return output_fpop (GET_CODE (operands[2]), operands[0],
2131 operands[3], operands[4], insn);
2132 }"
2133 [(set_attr "type" "fp")])
2134
2135 (define_insn ""
2136 [(set (match_operand:SI 0 "general_operand" "=g")
2137 (match_operator 1 "float_conversion"
2138 [(match_operator 2 "float_binary"
2139 [(match_operand 3 "general_operand" "frg")
2140 (match_operator 4 "float_conversion"
2141 [(match_operand 5 "general_operand" "frg")])])]))
2142 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2143 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2144 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2145 "*
2146 { return output_fpop (GET_CODE (operands[2]), operands[0],
2147 operands[3], operands[5], insn);
2148 }"
2149 [(set_attr "type" "fp")])
2150
2151 (define_insn ""
2152 [(set (match_operand 0 "general_operand" "=frg")
2153 (match_operator 1 "float_conversion"
2154 [(match_operator 2 "float_binary"
2155 [(match_operand 3 "general_operand" "frg")
2156 (match_operator 4 "float_conversion"
2157 [(match_operand 5 "general_operand" "frg")])])]))
2158 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2159 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2160 "check_precision (GET_MODE (operands[2]), operands[3], operands[4])"
2161 "*
2162 { return output_fpop (GET_CODE (operands[2]), operands[0],
2163 operands[3], operands[5], insn);
2164 }"
2165 [(set_attr "type" "fp")])
2166
2167 (define_insn ""
2168 [(set (match_operand:SI 0 "general_operand" "=g")
2169 (match_operator 1 "float_conversion"
2170 [(match_operator 2 "float_binary"
2171 [(match_operator 3 "float_conversion"
2172 [(match_operand 4 "general_operand" "frg")])
2173 (match_operand 5 "general_operand" "frg")])]))
2174 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2175 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2176 "check_precision (GET_MODE (operands[2]), operands[4], operands[5])"
2177 "*
2178 { return output_fpop (GET_CODE (operands[2]), operands[0],
2179 operands[4], operands[5], insn);
2180 }"
2181 [(set_attr "type" "fp")])
2182
2183 (define_insn ""
2184 [(set (match_operand 0 "general_operand" "=frg")
2185 (match_operator 1 "float_conversion"
2186 [(match_operator 2 "float_binary"
2187 [(match_operator 3 "float_conversion"
2188 [(match_operand 4 "general_operand" "frg")])
2189 (match_operand 5 "general_operand" "frg")])]))
2190 (clobber (match_operand:SI 6 "reg_0_operand" "=&z"))
2191 (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))]
2192 "check_precision (GET_MODE (operands[2]), operands[4], operands[5])"
2193 "*
2194 { return output_fpop (GET_CODE (operands[2]), operands[0],
2195 operands[4], operands[5], insn);
2196 }"
2197 [(set_attr "type" "fp")])
2198
2199 (define_insn ""
2200 [(set (match_operand:SI 0 "general_operand" "=g")
2201 (match_operator 1 "float_conversion"
2202 [(match_operator 2 "float_binary"
2203 [(match_operator 3 "float_conversion"
2204 [(match_operand 4 "general_operand" "frg")])
2205 (match_operator 5 "float_conversion"
2206 [(match_operand 6 "general_operand" "frg")])])]))
2207 (clobber (match_operand:SI 7 "reg_0_operand" "=&z"))
2208 (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))]
2209 "check_precision (GET_MODE (operands[2]), operands[4], operands[6])"
2210 "*
2211 { return output_fpop (GET_CODE (operands[2]), operands[0],
2212 operands[4], operands[6], insn);
2213 }"
2214 [(set_attr "type" "fp")])
2215
2216 (define_insn ""
2217 [(set (match_operand 0 "general_operand" "=frg")
2218 (match_operator 1 "float_conversion"
2219 [(match_operator 2 "float_binary"
2220 [(match_operator 3 "float_conversion"
2221 [(match_operand 4 "general_operand" "frg")])
2222 (match_operator 5 "float_conversion"
2223 [(match_operand 6 "general_operand" "frg")])])]))
2224 (clobber (match_operand:SI 7 "reg_0_operand" "=&z"))
2225 (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))]
2226 "check_precision (GET_MODE (operands[2]), operands[4], operands[6])"
2227 "*
2228 { return output_fpop (GET_CODE (operands[2]), operands[0],
2229 operands[4], operands[6], insn);
2230 }"
2231 [(set_attr "type" "fp")])
2232 \f
2233 ;; Unary floating-point operations.
2234
2235 (define_insn ""
2236 [(set (match_operand 0 "general_operand" "=frg")
2237 (match_operator 1 "float_unary"
2238 [(match_operand 2 "general_operand" "frg")]))
2239 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2240 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2241 "check_precision (GET_MODE (operands[1]), operands[2], 0)"
2242 "*
2243 { return output_fpop (GET_CODE (operands[1]), operands[0], operands[2],
2244 0, insn);
2245 }"
2246 [(set_attr "type" "fp")])
2247
2248 (define_insn ""
2249 [(set (match_operand 0 "general_operand" "=frg")
2250 (match_operator 1 "float_unary"
2251 [(match_operator 2 "float_conversion"
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[1]), operands[3], 0)"
2256 "*
2257 { return output_fpop (GET_CODE (operands[1]), operands[0], operands[3],
2258 0, insn);
2259 }"
2260 [(set_attr "type" "fp")])
2261
2262 (define_insn ""
2263 [(set (match_operand:SI 0 "general_operand" "=g")
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)"
2270 "*
2271 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3],
2272 0, insn);
2273 }"
2274 [(set_attr "type" "fp")])
2275
2276 (define_insn ""
2277 [(set (match_operand 0 "general_operand" "=frg")
2278 (match_operator 1 "float_conversion"
2279 [(match_operator 2 "float_unary"
2280 [(match_operand 3 "general_operand" "frg")])]))
2281 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2282 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2283 "check_precision (GET_MODE (operands[2]), operands[3], 0)"
2284 "*
2285 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3],
2286 0, insn);
2287 }"
2288 [(set_attr "type" "fp")])
2289
2290 (define_insn ""
2291 [(set (match_operand:SI 0 "general_operand" "=g")
2292 (match_operator 1 "float_conversion"
2293 [(match_operator 2 "float_unary"
2294 [(match_operator 3 "float_conversion"
2295 [(match_operand 4 "general_operand" "frg")])])]))
2296 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2297 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2298 "check_precision (GET_MODE (operands[2]), operands[4], 0)"
2299 "*
2300 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4],
2301 0, insn);
2302 }"
2303 [(set_attr "type" "fp")])
2304
2305 (define_insn ""
2306 [(set (match_operand 0 "general_operand" "=frg")
2307 (match_operator 1 "float_conversion"
2308 [(match_operator 2 "float_unary"
2309 [(match_operator 3 "float_conversion"
2310 [(match_operand 4 "general_operand" "frg")])])]))
2311 (clobber (match_operand:SI 5 "reg_0_operand" "=&z"))
2312 (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))]
2313 "check_precision (GET_MODE (operands[2]), operands[4], 0)"
2314 "*
2315 { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4],
2316 0, insn);
2317 }"
2318 [(set_attr "type" "fp")])
2319 \f
2320 ;; Compare insns are next. Note that the ROMP has two types of compares,
2321 ;; signed & unsigned, and one type of branch. Use the routine
2322 ;; `next_insn_tests_no_unsigned' to see which type to use.
2323 (define_expand "tstsi"
2324 [(set (cc0)
2325 (match_operand:SI 0 "register_operand" "r"))]
2326 ""
2327 "")
2328
2329 (define_expand "cmpsi"
2330 [(set (cc0)
2331 (compare (match_operand:SI 0 "register_operand" "")
2332 (match_operand:SI 1 "reg_or_cint_operand" "")))]
2333 ""
2334 "")
2335
2336 ;; Signed compare, `test' first.
2337
2338 (define_insn ""
2339 [(set (cc0)
2340 (match_operand:SI 0 "register_operand" "r"))]
2341 "next_insn_tests_no_unsigned (insn)"
2342 "cis %0,0"
2343 [(set_attr "length" "2")
2344 (set_attr "type" "compare")])
2345
2346 (define_insn ""
2347 [(set (cc0) (match_operand:SI 0 "register_operand" "r,r,r"))
2348 (set (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "=0,r,Q")
2349 (match_dup 0))]
2350 "next_insn_tests_no_unsigned (insn)"
2351 "@
2352 cis %1,0
2353 nilo %1,%0,65535
2354 st%M1 %0,%1\;cis %0,0"
2355 [(set_attr "type" "compare,compare,store")
2356 (set_attr "length" "2,4,6")
2357 (set_attr "cc" "compare")])
2358
2359 (define_insn ""
2360 [(set (cc0)
2361 (compare (match_operand:SI 0 "register_operand" "r,r,r")
2362 (match_operand:SI 1 "reg_or_cint_operand" "I,K,r")))]
2363 "next_insn_tests_no_unsigned (insn)"
2364 "@
2365 cis %0,%1
2366 cil %0,%1
2367 c %0,%1"
2368 [(set_attr "length" "2,4,2")
2369 (set_attr "type" "compare")])
2370
2371 ;; Unsigned comparisons, `test' first, again.
2372 (define_insn ""
2373 [(set (cc0)
2374 (match_operand:SI 0 "register_operand" "r"))]
2375 "! next_insn_tests_no_unsigned (insn)"
2376 "clil %0,0"
2377 [(set_attr "type" "compare")])
2378
2379 (define_insn ""
2380 [(set (cc0)
2381 (compare (match_operand:SI 0 "register_operand" "r,r")
2382 (match_operand:SI 1 "reg_or_cint_operand" "K,r")))]
2383 "! next_insn_tests_no_unsigned (insn)"
2384 "@
2385 clil %0,%1
2386 cl %0,%1"
2387 [(set_attr "length" "4,2")
2388 (set_attr "type" "compare")])
2389
2390 ;; Bit test insn. Many cases are converted into this by combine. This
2391 ;; uses the ROMP test bit.
2392
2393 (define_insn ""
2394 [(set (cc0)
2395 (zero_extract (match_operand:SI 0 "register_operand" "r,r")
2396 (const_int 1)
2397 (match_operand:SI 1 "reg_or_any_cint_operand" "r,n")))]
2398 "next_insn_tests_no_inequality (insn)"
2399 "@
2400 mttb %0,%1
2401 mttbi%t1 %0,%S1"
2402 [(set_attr "length" "2")
2403 (set_attr "type" "compare")
2404 (set_attr "cc" "tbit")])
2405 \f
2406 ;; Floating-point comparisons. There are two, equality and order.
2407 ;; The difference will be that a trap for NaN will be given on the orderr
2408 ;; comparisons only.
2409
2410 (define_expand "cmpsf"
2411 [(parallel [(set (cc0) (compare (match_operand:SF 0 "general_operand" "")
2412 (match_operand:SF 1 "general_operand" "")))
2413 (clobber (reg:SI 0))
2414 (clobber (reg:SI 15))])]
2415 ""
2416 "")
2417
2418 (define_expand "cmpdf"
2419 [(parallel [(set (cc0) (compare (match_operand:DF 0 "general_operand" "")
2420 (match_operand:DF 1 "general_operand" "")))
2421 (clobber (reg:SI 0))
2422 (clobber (reg:SI 15))])]
2423 ""
2424 "")
2425
2426 (define_expand "tstsf"
2427 [(parallel [(set (cc0) (match_operand:SF 0 "general_operand" ""))
2428 (clobber (reg:SI 0))
2429 (clobber (reg:SI 15))])]
2430 ""
2431 "")
2432
2433 (define_expand "tstdf"
2434 [(parallel [(set (cc0) (match_operand:DF 0 "general_operand" ""))
2435 (clobber (reg:SI 0))
2436 (clobber (reg:SI 15))])]
2437 ""
2438 "")
2439 \f
2440 ;; There are four cases for compare and two for test. These correspond
2441 ;; to each input having a floating-point conversion or not.
2442
2443 (define_insn ""
2444 [(set (cc0) (compare (match_operand 0 "general_operand" "frg")
2445 (match_operand 1 "general_operand" "frg")))
2446 (clobber (match_operand:SI 2 "reg_0_operand" "=&z"))
2447 (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))]
2448 "GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode"
2449 "*
2450 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2451 operands[0], operands[1], 0, insn);
2452 }"
2453 [(set_attr "type" "fp")
2454 (set_attr "cc" "compare")])
2455
2456 (define_insn ""
2457 [(set (cc0) (compare (match_operand 0 "general_operand" "frg")
2458 (match_operator 1 "float_conversion"
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"))]
2462 ""
2463 "*
2464 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2465 operands[0], operands[2], 0, insn);
2466 }"
2467 [(set_attr "type" "fp")
2468 (set_attr "cc" "compare")])
2469
2470 (define_insn ""
2471 [(set (cc0) (compare (match_operator 0 "float_conversion"
2472 [(match_operand 1 "general_operand" "frg")])
2473 (match_operand 2 "general_operand" "frg")))
2474 (clobber (match_operand:SI 3 "reg_0_operand" "=&z"))
2475 (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))]
2476 ""
2477 "*
2478 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2479 operands[1], operands[2], 0, insn);
2480 }"
2481 [(set_attr "type" "fp")
2482 (set_attr "cc" "compare")])
2483
2484 (define_insn ""
2485 [(set (cc0) (compare (match_operator 0 "float_conversion"
2486 [(match_operand 1 "general_operand" "frg")])
2487 (match_operator 2 "float_conversion"
2488 [(match_operand 3 "general_operand" "frg")])))
2489 (clobber (match_operand:SI 4 "reg_0_operand" "=&z"))
2490 (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))]
2491 ""
2492 "*
2493 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2494 operands[1], operands[3], 0, insn);
2495 }"
2496 [(set_attr "type" "fp")
2497 (set_attr "cc" "compare")])
2498
2499 (define_insn ""
2500 [(set (cc0) (match_operand 0 "general_operand" "frg"))
2501 (clobber (match_operand:SI 1 "reg_0_operand" "=&z"))
2502 (clobber (match_operand:SI 2 "reg_15_operand" "=&t"))]
2503 "GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode"
2504 "*
2505 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2506 operands[0], immed_real_const_1 (0, 0,
2507 GET_MODE (operands[0])),
2508 0, insn);
2509 }"
2510 [(set_attr "type" "fp")
2511 (set_attr "cc" "compare")])
2512
2513 (define_insn ""
2514 [(set (cc0) (match_operator 0 "float_conversion"
2515 [(match_operand 1 "general_operand" "frg")]))
2516 (clobber (match_operand:SI 2 "reg_0_operand" "=&z"))
2517 (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))]
2518 ""
2519 "*
2520 { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE,
2521 operands[1], immed_real_const_1 (0, 0,
2522 GET_MODE (operands[1])),
2523 0, insn);
2524 }"
2525 [(set_attr "type" "fp")
2526 (set_attr "cc" "compare")])
2527 \f
2528 ;; Branch insns. Unsigned vs. signed have already
2529 ;; been taken care of. The only insns that need to be concerned about the
2530 ;; test bit are beq and bne because the rest are either always true,
2531 ;; always false, or converted to EQ or NE.
2532
2533 ;; For conditional branches, we use `define_expand' and just have two patterns
2534 ;; that match them. Operand printing does most of the work.
2535
2536 (define_expand "beq"
2537 [(set (pc)
2538 (if_then_else (eq (cc0)
2539 (const_int 0))
2540 (label_ref (match_operand 0 "" ""))
2541 (pc)))]
2542 ""
2543 "")
2544
2545 (define_expand "bne"
2546 [(set (pc)
2547 (if_then_else (ne (cc0)
2548 (const_int 0))
2549 (label_ref (match_operand 0 "" ""))
2550 (pc)))]
2551 ""
2552 "")
2553
2554 (define_expand "bgt"
2555 [(set (pc)
2556 (if_then_else (gt (cc0)
2557 (const_int 0))
2558 (label_ref (match_operand 0 "" ""))
2559 (pc)))]
2560 ""
2561 "")
2562
2563 (define_expand "bgtu"
2564 [(set (pc)
2565 (if_then_else (gtu (cc0)
2566 (const_int 0))
2567 (label_ref (match_operand 0 "" ""))
2568 (pc)))]
2569 ""
2570 "")
2571
2572 (define_expand "blt"
2573 [(set (pc)
2574 (if_then_else (lt (cc0)
2575 (const_int 0))
2576 (label_ref (match_operand 0 "" ""))
2577 (pc)))]
2578 ""
2579 "")
2580
2581 (define_expand "bltu"
2582 [(set (pc)
2583 (if_then_else (ltu (cc0)
2584 (const_int 0))
2585 (label_ref (match_operand 0 "" ""))
2586 (pc)))]
2587 ""
2588 "")
2589
2590 (define_expand "bge"
2591 [(set (pc)
2592 (if_then_else (ge (cc0)
2593 (const_int 0))
2594 (label_ref (match_operand 0 "" ""))
2595 (pc)))]
2596 ""
2597 "")
2598
2599 (define_expand "bgeu"
2600 [(set (pc)
2601 (if_then_else (geu (cc0)
2602 (const_int 0))
2603 (label_ref (match_operand 0 "" ""))
2604 (pc)))]
2605 ""
2606 "")
2607
2608 (define_expand "ble"
2609 [(set (pc)
2610 (if_then_else (le (cc0)
2611 (const_int 0))
2612 (label_ref (match_operand 0 "" ""))
2613 (pc)))]
2614 ""
2615 "")
2616
2617 (define_expand "bleu"
2618 [(set (pc)
2619 (if_then_else (leu (cc0)
2620 (const_int 0))
2621 (label_ref (match_operand 0 "" ""))
2622 (pc)))]
2623 ""
2624 "")
2625 \f
2626 ;; Define both directions of branch and return.
2627
2628 (define_insn ""
2629 [(set (pc)
2630 (if_then_else (match_operator 1 "comparison_operator"
2631 [(cc0) (const_int 0)])
2632 (label_ref (match_operand 0 "" ""))
2633 (pc)))]
2634 ""
2635 "*
2636 {
2637 if (restore_compare_p (operands[1]))
2638 return 0;
2639 else if (get_attr_length (insn) == 2)
2640 return \"j%j1 %l0\";
2641 else
2642 return \"b%j1%# %l0\";
2643 }"
2644 [(set_attr "type" "branch")])
2645
2646 (define_insn ""
2647 [(set (pc)
2648 (if_then_else (match_operator 0 "comparison_operator"
2649 [(cc0) (const_int 0)])
2650 (return)
2651 (pc)))]
2652 "null_epilogue ()"
2653 "*
2654 {
2655 if (restore_compare_p (operands[0]))
2656 return 0;
2657 else
2658 return \"b%j0r%# r15\";
2659 }"
2660 [(set_attr "type" "return")])
2661
2662 (define_insn ""
2663 [(set (pc)
2664 (if_then_else (match_operator 1 "comparison_operator"
2665 [(cc0) (const_int 0)])
2666 (pc)
2667 (label_ref (match_operand 0 "" ""))))]
2668 ""
2669 "*
2670 {
2671 if (restore_compare_p (operands[1]))
2672 return 0;
2673 else if (get_attr_length (insn) == 2)
2674 return \"j%J1 %l0\";
2675 else
2676 return \"b%J1%# %l0\";
2677 }"
2678 [(set_attr "type" "branch")])
2679
2680 (define_insn ""
2681 [(set (pc)
2682 (if_then_else (match_operator 0 "comparison_operator"
2683 [(cc0) (const_int 0)])
2684 (pc)
2685 (return)))]
2686 "null_epilogue ()"
2687 "*
2688 {
2689 if (restore_compare_p (operands[0]))
2690 return 0;
2691 else
2692 return \"b%J0r%# r15\";
2693 }"
2694 [(set_attr "type" "return")])
2695
2696 ;; Unconditional branch and return.
2697
2698 (define_insn "jump"
2699 [(set (pc)
2700 (label_ref (match_operand 0 "" "")))]
2701 ""
2702 "*
2703 {
2704 if (get_attr_length (insn) == 2)
2705 return \"j %l0\";
2706 else
2707 return \"b%# %l0\";
2708 }"
2709 [(set_attr "type" "branch")])
2710
2711 (define_insn "return"
2712 [(return)]
2713 "null_epilogue ()"
2714 "br%# r15"
2715 [(set_attr "type" "return")])
2716
2717 (define_insn "indirect_jump"
2718 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2719 ""
2720 "br%# %0"
2721 [(set_attr "type" "ibranch")])
2722
2723 ;; Table jump for switch statements:
2724 (define_insn "tablejump"
2725 [(set (pc)
2726 (match_operand:SI 0 "register_operand" "r"))
2727 (use (label_ref (match_operand 1 "" "")))]
2728 ""
2729 "br%# %0"
2730 [(set_attr "type" "ibranch")])
2731 \f
2732 ;;- Local variables:
2733 ;;- mode:emacs-lisp
2734 ;;- comment-start: ";;- "
2735 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2736 ;;- eval: (modify-syntax-entry ?[ "(]")
2737 ;;- eval: (modify-syntax-entry ?] ")[")
2738 ;;- eval: (modify-syntax-entry ?{ "(}")
2739 ;;- eval: (modify-syntax-entry ?} "){")
2740 ;;- End:
This page took 0.1535 seconds and 5 git commands to generate.