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