]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/pa/pa.c
(build_binary_op): Don't call common_type for uncommon pointer types.
[thirdparty/gcc.git] / gcc / config / pa / pa.c
CommitLineData
87ad11b0 1/* Subroutines for insn-output.c for HPPA.
3ef80983 2 Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
87ad11b0 3 Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#include <stdio.h>
22#include "config.h"
23#include "rtl.h"
24#include "regs.h"
25#include "hard-reg-set.h"
26#include "real.h"
27#include "insn-config.h"
28#include "conditions.h"
29#include "insn-flags.h"
30#include "output.h"
31#include "insn-attr.h"
32#include "flags.h"
33#include "tree.h"
34#include "c-tree.h"
35#include "expr.h"
d6f01525 36#include "obstack.h"
87ad11b0 37
38/* Save the operands last given to a compare for use when we
39 generate a scc or bcc insn. */
40
41rtx hppa_compare_op0, hppa_compare_op1;
42enum cmp_type hppa_branch_type;
43
134b4858 44/* Which cpu we are scheduling for. */
45enum processor_type pa_cpu;
46
47/* String to hold which cpu we are scheduling for. */
48char *pa_cpu_string;
49
eff812f1 50rtx hppa_save_pic_table_rtx;
51
87ad11b0 52/* Set by the FUNCTION_PROFILER macro. */
53int hp_profile_labelno;
54
a9960cdc 55/* Counts for the number of callee-saved general and floating point
56 registers which were saved by the current function's prologue. */
57static int gr_saved, fr_saved;
58
87ad11b0 59static rtx find_addr_reg ();
60
06ddb6f8 61/* Keep track of the number of bytes we have output in the CODE subspaces
62 during this compilation so we'll know when to emit inline long-calls. */
63
64unsigned int total_code_bytes;
65
134b4858 66void
67override_options ()
68{
69 /* Default to 700 scheduling which is reasonable for older 800 processors
70 correct for the 700s, and not too bad for the 7100s and 7100LCs. */
71 if (pa_cpu_string == NULL
72 || ! strcmp (pa_cpu_string, "700"))
73 {
74 pa_cpu_string = "700";
75 pa_cpu = PROCESSOR_700;
76 }
77 else if (! strcmp (pa_cpu_string, "7100"))
78 {
79 pa_cpu_string = "7100";
80 pa_cpu = PROCESSOR_7100;
81 }
82 else if (! strncmp (pa_cpu_string, "7100LC"))
83 {
84 pa_cpu_string = "7100LC";
85 pa_cpu = PROCESSOR_7100LC;
86 }
87 else
88 {
89 warning ("Unknown -mschedule= option (%s).\nValid options are 700, 7100 and 7100LC\n", pa_cpu_string);
90 }
91}
92
93
87ad11b0 94/* Return non-zero only if OP is a register of mode MODE,
891b55b4 95 or CONST0_RTX. */
87ad11b0 96int
97reg_or_0_operand (op, mode)
98 rtx op;
99 enum machine_mode mode;
100{
891b55b4 101 return (op == CONST0_RTX (mode) || register_operand (op, mode));
87ad11b0 102}
103
575e0eb4 104/* Return non-zero if OP is suitable for use in a call to a named
105 function.
106
6d36483b 107 (???) For 2.5 try to eliminate either call_operand_address or
575e0eb4 108 function_label_operand, they perform very similar functions. */
87ad11b0 109int
110call_operand_address (op, mode)
111 rtx op;
112 enum machine_mode mode;
113{
06ddb6f8 114 return (CONSTANT_P (op) && ! TARGET_PORTABLE_RUNTIME);
87ad11b0 115}
116
6d36483b 117/* Return 1 if X contains a symbolic expression. We know these
118 expressions will have one of a few well defined forms, so
347b5848 119 we need only check those forms. */
120int
121symbolic_expression_p (x)
122 register rtx x;
123{
124
6d36483b 125 /* Strip off any HIGH. */
347b5848 126 if (GET_CODE (x) == HIGH)
127 x = XEXP (x, 0);
128
129 return (symbolic_operand (x, VOIDmode));
130}
131
87ad11b0 132int
133symbolic_operand (op, mode)
134 register rtx op;
135 enum machine_mode mode;
136{
137 switch (GET_CODE (op))
138 {
139 case SYMBOL_REF:
140 case LABEL_REF:
141 return 1;
142 case CONST:
143 op = XEXP (op, 0);
144 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
145 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
146 && GET_CODE (XEXP (op, 1)) == CONST_INT);
147 default:
148 return 0;
149 }
150}
151
152/* Return truth value of statement that OP is a symbolic memory
153 operand of mode MODE. */
154
155int
156symbolic_memory_operand (op, mode)
157 rtx op;
158 enum machine_mode mode;
159{
160 if (GET_CODE (op) == SUBREG)
161 op = SUBREG_REG (op);
162 if (GET_CODE (op) != MEM)
163 return 0;
164 op = XEXP (op, 0);
165 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
166 || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
167}
168
169/* Return 1 if the operand is either a register or a memory operand that is
170 not symbolic. */
171
172int
173reg_or_nonsymb_mem_operand (op, mode)
174 register rtx op;
175 enum machine_mode mode;
176{
177 if (register_operand (op, mode))
178 return 1;
179
180 if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
181 return 1;
182
183 return 0;
184}
185
6d36483b 186/* Return 1 if the operand is either a register, zero, or a memory operand
891b55b4 187 that is not symbolic. */
188
189int
190reg_or_0_or_nonsymb_mem_operand (op, mode)
191 register rtx op;
192 enum machine_mode mode;
193{
194 if (register_operand (op, mode))
195 return 1;
196
197 if (op == CONST0_RTX (mode))
198 return 1;
199
200 if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
201 return 1;
202
203 return 0;
204}
205
6d36483b 206/* Accept any constant that can be moved in one instructions into a
d9d7c968 207 general register. */
6d36483b 208int
d9d7c968 209cint_ok_for_move (intval)
6d36483b 210 HOST_WIDE_INT intval;
d9d7c968 211{
212 /* OK if ldo, ldil, or zdepi, can be used. */
213 return (VAL_14_BITS_P (intval) || (intval & 0x7ff) == 0
214 || zdepi_cint_p (intval));
215}
216
6ecdbaa1 217/* Accept anything that can be moved in one instruction into a general
218 register. */
87ad11b0 219int
220move_operand (op, mode)
221 rtx op;
222 enum machine_mode mode;
223{
224 if (register_operand (op, mode))
225 return 1;
226
42faba01 227 if (GET_CODE (op) == CONST_INT)
d9d7c968 228 return cint_ok_for_move (INTVAL (op));
87ad11b0 229
230 if (GET_MODE (op) != mode)
231 return 0;
232 if (GET_CODE (op) == SUBREG)
233 op = SUBREG_REG (op);
234 if (GET_CODE (op) != MEM)
235 return 0;
236
237 op = XEXP (op, 0);
238 if (GET_CODE (op) == LO_SUM)
239 return (register_operand (XEXP (op, 0), Pmode)
240 && CONSTANT_P (XEXP (op, 1)));
241 return memory_address_p (mode, op);
242}
243
6ecdbaa1 244/* Accept REG and any CONST_INT that can be moved in one instruction into a
245 general register. */
246int
247reg_or_cint_move_operand (op, mode)
248 rtx op;
249 enum machine_mode mode;
250{
251 if (register_operand (op, mode))
252 return 1;
253
254 if (GET_CODE (op) == CONST_INT)
686b848d 255 return cint_ok_for_move (INTVAL (op));
256
6ecdbaa1 257 return 0;
258}
259
87ad11b0 260int
b4a7bf10 261pic_label_operand (op, mode)
87ad11b0 262 rtx op;
263 enum machine_mode mode;
264{
b4a7bf10 265 if (!flag_pic)
266 return 0;
267
268 switch (GET_CODE (op))
269 {
270 case LABEL_REF:
271 return 1;
b4a7bf10 272 case CONST:
273 op = XEXP (op, 0);
3c69dc97 274 return (GET_CODE (XEXP (op, 0)) == LABEL_REF
b4a7bf10 275 && GET_CODE (XEXP (op, 1)) == CONST_INT);
276 default:
277 return 0;
278 }
87ad11b0 279}
280
87ad11b0 281int
282fp_reg_operand (op, mode)
283 rtx op;
284 enum machine_mode mode;
285{
286 return reg_renumber && FP_REG_P (op);
287}
d6f01525 288
87ad11b0 289\f
87ad11b0 290
87ad11b0 291/* Return truth value of whether OP can be used as an operand in a
292 three operand arithmetic insn that accepts registers of mode MODE
293 or 14-bit signed integers. */
294int
295arith_operand (op, mode)
296 rtx op;
297 enum machine_mode mode;
298{
299 return (register_operand (op, mode)
300 || (GET_CODE (op) == CONST_INT && INT_14_BITS (op)));
301}
302
303/* Return truth value of whether OP can be used as an operand in a
304 three operand arithmetic insn that accepts registers of mode MODE
305 or 11-bit signed integers. */
306int
307arith11_operand (op, mode)
308 rtx op;
309 enum machine_mode mode;
310{
311 return (register_operand (op, mode)
312 || (GET_CODE (op) == CONST_INT && INT_11_BITS (op)));
313}
314
6d36483b 315/* A constant integer suitable for use in a PRE_MODIFY memory
757d4970 316 reference. */
42faba01 317int
318pre_cint_operand (op, mode)
319 rtx op;
320 enum machine_mode mode;
321{
322 return (GET_CODE (op) == CONST_INT
323 && INTVAL (op) >= -0x2000 && INTVAL (op) < 0x10);
324}
325
6d36483b 326/* A constant integer suitable for use in a POST_MODIFY memory
757d4970 327 reference. */
328int
329post_cint_operand (op, mode)
330 rtx op;
331 enum machine_mode mode;
332{
333 return (GET_CODE (op) == CONST_INT
334 && INTVAL (op) < 0x2000 && INTVAL (op) >= -0x10);
335}
336
87ad11b0 337int
338arith_double_operand (op, mode)
339 rtx op;
340 enum machine_mode mode;
341{
342 return (register_operand (op, mode)
343 || (GET_CODE (op) == CONST_DOUBLE
344 && GET_MODE (op) == mode
345 && VAL_14_BITS_P (CONST_DOUBLE_LOW (op))
346 && (CONST_DOUBLE_HIGH (op) >= 0
347 == ((CONST_DOUBLE_LOW (op) & 0x1000) == 0))));
348}
349
350/* Return truth value of whether OP is a integer which fits the
351 range constraining immediate operands in three-address insns. */
352
353int
354int5_operand (op, mode)
355 rtx op;
356 enum machine_mode mode;
357{
358 return (GET_CODE (op) == CONST_INT && INT_5_BITS (op));
359}
360
361int
362uint5_operand (op, mode)
363 rtx op;
364 enum machine_mode mode;
365{
366 return (GET_CODE (op) == CONST_INT && INT_U5_BITS (op));
367}
368
87ad11b0 369int
370int11_operand (op, mode)
371 rtx op;
372 enum machine_mode mode;
373{
6d36483b 374 return (GET_CODE (op) == CONST_INT && INT_11_BITS (op));
375}
376
377int
378uint32_operand (op, mode)
379 rtx op;
380 enum machine_mode mode;
381{
382#if HOST_BITS_PER_WIDE_INT > 32
383 /* All allowed constants will fit a CONST_INT. */
384 return (GET_CODE (op) == CONST_INT
385 && (INTVAL (op) >= 0 && INTVAL (op) < 0x100000000L));
386#else
387 return (GET_CODE (op) == CONST_INT
388 || (GET_CODE (op) == CONST_DOUBLE
389 && CONST_DOUBLE_HIGH (op) == 0));
390#endif
87ad11b0 391}
392
393int
394arith5_operand (op, mode)
395 rtx op;
396 enum machine_mode mode;
397{
398 return register_operand (op, mode) || int5_operand (op, mode);
399}
400
fad0b60f 401/* True iff zdepi can be used to generate this CONST_INT. */
e057641f 402int
42faba01 403zdepi_cint_p (x)
6d36483b 404 unsigned HOST_WIDE_INT x;
fad0b60f 405{
3745c59b 406 unsigned HOST_WIDE_INT lsb_mask, t;
fad0b60f 407
408 /* This might not be obvious, but it's at least fast.
409 This function is critcal; we don't have the time loops would take. */
42faba01 410 lsb_mask = x & -x;
411 t = ((x >> 4) + lsb_mask) & ~(lsb_mask - 1);
412 /* Return true iff t is a power of two. */
fad0b60f 413 return ((t & (t - 1)) == 0);
414}
415
6d36483b 416/* True iff depi or extru can be used to compute (reg & mask).
417 Accept bit pattern like these:
418 0....01....1
419 1....10....0
420 1..10..01..1 */
e057641f 421int
42faba01 422and_mask_p (mask)
6d36483b 423 unsigned HOST_WIDE_INT mask;
e057641f 424{
425 mask = ~mask;
426 mask += mask & -mask;
427 return (mask & (mask - 1)) == 0;
428}
429
430/* True iff depi or extru can be used to compute (reg & OP). */
431int
432and_operand (op, mode)
433 rtx op;
434 enum machine_mode mode;
435{
436 return (register_operand (op, mode)
42faba01 437 || (GET_CODE (op) == CONST_INT && and_mask_p (INTVAL (op))));
e057641f 438}
439
440/* True iff depi can be used to compute (reg | MASK). */
441int
442ior_mask_p (mask)
6d36483b 443 unsigned HOST_WIDE_INT mask;
e057641f 444{
445 mask += mask & -mask;
446 return (mask & (mask - 1)) == 0;
447}
448
449/* True iff depi can be used to compute (reg | OP). */
450int
451ior_operand (op, mode)
452 rtx op;
453 enum machine_mode mode;
454{
b744c8cb 455 return (GET_CODE (op) == CONST_INT && ior_mask_p (INTVAL (op)));
e057641f 456}
457
e5965947 458int
459lhs_lshift_operand (op, mode)
460 rtx op;
461 enum machine_mode mode;
462{
463 return register_operand (op, mode) || lhs_lshift_cint_operand (op, mode);
464}
465
466/* True iff OP is a CONST_INT of the forms 0...0xxxx or 0...01...1xxxx.
467 Such values can be the left hand side x in (x << r), using the zvdepi
468 instruction. */
469int
470lhs_lshift_cint_operand (op, mode)
471 rtx op;
472 enum machine_mode mode;
473{
3745c59b 474 unsigned HOST_WIDE_INT x;
e5965947 475 if (GET_CODE (op) != CONST_INT)
476 return 0;
477 x = INTVAL (op) >> 4;
478 return (x & (x + 1)) == 0;
479}
480
9c6d4825 481int
482arith32_operand (op, mode)
483 rtx op;
484 enum machine_mode mode;
485{
486 return register_operand (op, mode) || GET_CODE (op) == CONST_INT;
487}
ead9285f 488
489int
490pc_or_label_operand (op, mode)
491 rtx op;
492 enum machine_mode mode;
493{
494 return (GET_CODE (op) == PC || GET_CODE (op) == LABEL_REF);
495}
87ad11b0 496\f
497/* Legitimize PIC addresses. If the address is already
498 position-independent, we return ORIG. Newly generated
499 position-independent addresses go to REG. If we need more
500 than one register, we lose. */
501
502rtx
503legitimize_pic_address (orig, mode, reg)
504 rtx orig, reg;
505 enum machine_mode mode;
506{
507 rtx pic_ref = orig;
508
3c69dc97 509 /* Lables need special handling. */
b4a7bf10 510 if (pic_label_operand (orig))
511 {
512 emit_insn (gen_pic_load_label (reg, orig));
513 current_function_uses_pic_offset_table = 1;
514 return reg;
515 }
87ad11b0 516 if (GET_CODE (orig) == SYMBOL_REF)
517 {
518 if (reg == 0)
519 abort ();
520
521 if (flag_pic == 2)
522 {
e8df7698 523 emit_insn (gen_pic2_highpart (reg, pic_offset_table_rtx, orig));
524 pic_ref = gen_rtx (MEM, Pmode,
525 gen_rtx (LO_SUM, Pmode, reg,
526 gen_rtx (UNSPEC, SImode, gen_rtvec (1, orig), 0)));
87ad11b0 527 }
b4a7bf10 528 else
529 pic_ref = gen_rtx (MEM, Pmode,
530 gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig));
87ad11b0 531 current_function_uses_pic_offset_table = 1;
532 RTX_UNCHANGING_P (pic_ref) = 1;
533 emit_move_insn (reg, pic_ref);
534 return reg;
535 }
536 else if (GET_CODE (orig) == CONST)
537 {
57ed30e5 538 rtx base;
87ad11b0 539
540 if (GET_CODE (XEXP (orig, 0)) == PLUS
541 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
542 return orig;
543
544 if (reg == 0)
545 abort ();
546
547 if (GET_CODE (XEXP (orig, 0)) == PLUS)
548 {
549 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
550 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
551 base == reg ? 0 : reg);
552 }
553 else abort ();
554 if (GET_CODE (orig) == CONST_INT)
555 {
42faba01 556 if (INT_14_BITS (orig))
87ad11b0 557 return plus_constant_for_output (base, INTVAL (orig));
558 orig = force_reg (Pmode, orig);
559 }
560 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
561 /* Likewise, should we set special REG_NOTEs here? */
562 }
563 return pic_ref;
564}
565
347b5848 566/* Try machine-dependent ways of modifying an illegitimate address
567 to be legitimate. If we find one, return the new, valid address.
568 This macro is used in only one place: `memory_address' in explow.c.
569
570 OLDX is the address as it was before break_out_memory_refs was called.
571 In some cases it is useful to look at this to decide what needs to be done.
572
573 MODE and WIN are passed so that this macro can use
574 GO_IF_LEGITIMATE_ADDRESS.
575
576 It is always safe for this macro to do nothing. It exists to recognize
6d36483b 577 opportunities to optimize the output.
347b5848 578
579 For the PA, transform:
580
581 memory(X + <large int>)
582
583 into:
584
585 if (<large int> & mask) >= 16
586 Y = (<large int> & ~mask) + mask + 1 Round up.
587 else
588 Y = (<large int> & ~mask) Round down.
589 Z = X + Y
590 memory (Z + (<large int> - Y));
591
6d36483b 592 This is for CSE to find several similar references, and only use one Z.
347b5848 593
594 X can either be a SYMBOL_REF or REG, but because combine can not
595 perform a 4->2 combination we do nothing for SYMBOL_REF + D where
596 D will not fit in 14 bits.
597
598 MODE_FLOAT references allow displacements which fit in 5 bits, so use
6d36483b 599 0x1f as the mask.
347b5848 600
601 MODE_INT references allow displacements which fit in 14 bits, so use
6d36483b 602 0x3fff as the mask.
347b5848 603
604 This relies on the fact that most mode MODE_FLOAT references will use FP
605 registers and most mode MODE_INT references will use integer registers.
606 (In the rare case of an FP register used in an integer MODE, we depend
607 on secondary reloads to clean things up.)
608
609
610 It is also beneficial to handle (plus (mult (X) (Y)) (Z)) in a special
611 manner if Y is 2, 4, or 8. (allows more shadd insns and shifted indexed
612 adressing modes to be used).
613
614 Put X and Z into registers. Then put the entire expression into
615 a register. */
616
617rtx
618hppa_legitimize_address (x, oldx, mode)
619 rtx x, oldx;
620 enum machine_mode mode;
621{
347b5848 622 rtx orig = x;
623
b4a7bf10 624 if (flag_pic)
625 return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
626
347b5848 627 /* Strip off CONST. */
628 if (GET_CODE (x) == CONST)
629 x = XEXP (x, 0);
630
166bf021 631 /* Note we must reject symbols which represent function addresses
632 since the assembler/linker can't handle arithmetic on plabels. */
347b5848 633 if (GET_CODE (x) == PLUS
634 && GET_CODE (XEXP (x, 1)) == CONST_INT
166bf021 635 && ((GET_CODE (XEXP (x, 0)) == SYMBOL_REF
636 && !FUNCTION_NAME_P (XSTR (XEXP (x, 0), 0)))
347b5848 637 || GET_CODE (XEXP (x, 0)) == REG))
638 {
639 rtx int_part, ptr_reg;
640 int newoffset;
641 int offset = INTVAL (XEXP (x, 1));
642 int mask = GET_MODE_CLASS (mode) == MODE_FLOAT ? 0x1f : 0x3fff;
643
6d36483b 644 /* Choose which way to round the offset. Round up if we
347b5848 645 are >= halfway to the next boundary. */
646 if ((offset & mask) >= ((mask + 1) / 2))
647 newoffset = (offset & ~ mask) + mask + 1;
648 else
649 newoffset = (offset & ~ mask);
650
651 /* If the newoffset will not fit in 14 bits (ldo), then
652 handling this would take 4 or 5 instructions (2 to load
653 the SYMBOL_REF + 1 or 2 to load the newoffset + 1 to
654 add the new offset and the SYMBOL_REF.) Combine can
655 not handle 4->2 or 5->2 combinations, so do not create
656 them. */
657 if (! VAL_14_BITS_P (newoffset)
658 && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
659 {
660 rtx const_part = gen_rtx (CONST, VOIDmode,
339613b4 661 gen_rtx (PLUS, Pmode,
347b5848 662 XEXP (x, 0),
663 GEN_INT (newoffset)));
664 rtx tmp_reg
339613b4 665 = force_reg (Pmode,
666 gen_rtx (HIGH, Pmode, const_part));
347b5848 667 ptr_reg
339613b4 668 = force_reg (Pmode,
669 gen_rtx (LO_SUM, Pmode,
347b5848 670 tmp_reg, const_part));
671 }
672 else
673 {
674 if (! VAL_14_BITS_P (newoffset))
339613b4 675 int_part = force_reg (Pmode, GEN_INT (newoffset));
347b5848 676 else
677 int_part = GEN_INT (newoffset);
678
339613b4 679 ptr_reg = force_reg (Pmode,
680 gen_rtx (PLUS, Pmode,
681 force_reg (Pmode, XEXP (x, 0)),
347b5848 682 int_part));
683 }
684 return plus_constant (ptr_reg, offset - newoffset);
685 }
45f1285a 686
687 /* Try to arrange things so that indexing modes can be used, but
6d36483b 688 only do so if indexing is safe.
45f1285a 689
690 Indexing is safe when the second operand for the outer PLUS
6d36483b 691 is a REG, SUBREG, SYMBOL_REF or the like.
45f1285a 692
6d36483b 693 For 2.5, indexing is also safe for (plus (symbol_ref) (const_int))
45f1285a 694 if the integer is > 0. */
347b5848 695 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
696 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
45f1285a 697 && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))
698 && (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == 'o'
699 || GET_CODE (XEXP (x, 1)) == SUBREG)
700 && GET_CODE (XEXP (x, 1)) != CONST)
347b5848 701 {
702 int val = INTVAL (XEXP (XEXP (x, 0), 1));
703 rtx reg1, reg2;
339613b4 704 reg1 = force_reg (Pmode, force_operand (XEXP (x, 1), 0));
705 reg2 = force_reg (Pmode,
347b5848 706 force_operand (XEXP (XEXP (x, 0), 0), 0));
339613b4 707 return force_reg (Pmode,
708 gen_rtx (PLUS, Pmode,
709 gen_rtx (MULT, Pmode, reg2,
347b5848 710 GEN_INT (val)),
711 reg1));
712 }
45f1285a 713
6d36483b 714 /* Uh-oh. We might have an address for x[n-100000]. This needs
45f1285a 715 special handling. */
716
717 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
718 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
719 && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
720 {
721 /* Ugly. We modify things here so that the address offset specified
722 by the index expression is computed first, then added to x to form
723 the entire address.
724
725 For 2.5, it might be profitable to set things up so that we
726 compute the raw (unscaled) index first, then use scaled indexing
727 to access memory, or better yet have the MI parts of the compiler
728 handle this. */
729
730 rtx regx1, regy1, regy2, y;
731
732 /* Strip off any CONST. */
733 y = XEXP (x, 1);
734 if (GET_CODE (y) == CONST)
735 y = XEXP (y, 0);
736
7ee96d6e 737 if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)
738 {
739 regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
740 regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
741 regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
742 regx1 = force_reg (Pmode, gen_rtx (GET_CODE (y), Pmode, regx1, regy2));
743 return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1));
744 }
45f1285a 745 }
746
347b5848 747 return orig;
748}
749
87ad11b0 750/* For the HPPA, REG and REG+CONST is cost 0
751 and addresses involving symbolic constants are cost 2.
752
753 PIC addresses are very expensive.
754
755 It is no coincidence that this has the same structure
756 as GO_IF_LEGITIMATE_ADDRESS. */
757int
758hppa_address_cost (X)
759 rtx X;
760{
761 if (GET_CODE (X) == PLUS)
762 return 1;
763 else if (GET_CODE (X) == LO_SUM)
764 return 1;
765 else if (GET_CODE (X) == HIGH)
766 return 2;
767 return 4;
768}
769
770/* Emit insns to move operands[1] into operands[0].
771
772 Return 1 if we have written out everything that needs to be done to
773 do the move. Otherwise, return 0 and the caller will emit the move
774 normally. */
775
776int
d6f01525 777emit_move_sequence (operands, mode, scratch_reg)
87ad11b0 778 rtx *operands;
779 enum machine_mode mode;
d6f01525 780 rtx scratch_reg;
87ad11b0 781{
782 register rtx operand0 = operands[0];
783 register rtx operand1 = operands[1];
784
e8fdbafa 785 /* Handle secondary reloads for loads/stores of FP registers from
6b1c36c2 786 REG+D addresses where D does not fit in 5 bits, including
787 (subreg (mem (addr)) cases. */
d6f01525 788 if (fp_reg_operand (operand0, mode)
6b1c36c2 789 && ((GET_CODE (operand1) == MEM
790 && ! memory_address_p (DFmode, XEXP (operand1, 0)))
791 || ((GET_CODE (operand1) == SUBREG
792 && GET_CODE (XEXP (operand1, 0)) == MEM
793 && !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0)))))
d6f01525 794 && scratch_reg)
795 {
6b1c36c2 796 if (GET_CODE (operand1) == SUBREG)
797 operand1 = XEXP (operand1, 0);
798
799 scratch_reg = gen_rtx (REG, SImode, REGNO (scratch_reg));
7ee39d73 800
801 /* D might not fit in 14 bits either; for such cases load D into
802 scratch reg. */
803 if (!memory_address_p (SImode, XEXP (operand1, 0)))
804 {
805 emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1));
806 emit_move_insn (scratch_reg, gen_rtx (GET_CODE (XEXP (operand1, 0)),
807 SImode,
808 XEXP (XEXP (operand1, 0), 0),
809 scratch_reg));
810 }
811 else
812 emit_move_insn (scratch_reg, XEXP (operand1, 0));
d6f01525 813 emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MEM, mode,
814 scratch_reg)));
815 return 1;
816 }
817 else if (fp_reg_operand (operand1, mode)
6b1c36c2 818 && ((GET_CODE (operand0) == MEM
819 && ! memory_address_p (DFmode, XEXP (operand0, 0)))
820 || ((GET_CODE (operand0) == SUBREG)
821 && GET_CODE (XEXP (operand0, 0)) == MEM
822 && !memory_address_p (DFmode, XEXP (XEXP (operand0, 0), 0))))
d6f01525 823 && scratch_reg)
824 {
6b1c36c2 825 if (GET_CODE (operand0) == SUBREG)
826 operand0 = XEXP (operand0, 0);
827
828 scratch_reg = gen_rtx (REG, SImode, REGNO (scratch_reg));
7ee39d73 829 /* D might not fit in 14 bits either; for such cases load D into
830 scratch reg. */
831 if (!memory_address_p (SImode, XEXP (operand0, 0)))
832 {
833 emit_move_insn (scratch_reg, XEXP (XEXP (operand0, 0), 1));
834 emit_move_insn (scratch_reg, gen_rtx (GET_CODE (XEXP (operand0, 0)),
835 SImode,
836 XEXP (XEXP (operand0, 0), 0),
837 scratch_reg));
838 }
839 else
840 emit_move_insn (scratch_reg, XEXP (operand0, 0));
6d36483b 841 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, mode, scratch_reg),
d6f01525 842 operand1));
843 return 1;
844 }
753bd06a 845 /* Handle secondary reloads for loads of FP registers from constant
846 expressions by forcing the constant into memory.
847
6d36483b 848 use scratch_reg to hold the address of the memory location.
753bd06a 849
6d36483b 850 ??? The proper fix is to change PREFERRED_RELOAD_CLASS to return
851 NO_REGS when presented with a const_int and an register class
753bd06a 852 containing only FP registers. Doing so unfortunately creates
853 more problems than it solves. Fix this for 2.5. */
854 else if (fp_reg_operand (operand0, mode)
855 && CONSTANT_P (operand1)
856 && scratch_reg)
857 {
858 rtx xoperands[2];
859
860 /* Force the constant into memory and put the address of the
861 memory location into scratch_reg. */
862 xoperands[0] = scratch_reg;
863 xoperands[1] = XEXP (force_const_mem (mode, operand1), 0);
8f258b49 864 emit_move_sequence (xoperands, Pmode, 0);
753bd06a 865
866 /* Now load the destination register. */
867 emit_insn (gen_rtx (SET, mode, operand0,
868 gen_rtx (MEM, mode, scratch_reg)));
869 return 1;
870 }
e8fdbafa 871 /* Handle secondary reloads for SAR. These occur when trying to load
7d43e0f7 872 the SAR from memory a FP register, or with a constant. */
e8fdbafa 873 else if (GET_CODE (operand0) == REG
874 && REGNO_REG_CLASS (REGNO (operand0)) == SHIFT_REGS
875 && (GET_CODE (operand1) == MEM
7d43e0f7 876 || GET_CODE (operand1) == CONST_INT
e8fdbafa 877 || (GET_CODE (operand1) == REG
878 && FP_REG_CLASS_P (REGNO_REG_CLASS (REGNO (operand1)))))
879 && scratch_reg)
880 {
881 emit_move_insn (scratch_reg, operand1);
882 emit_move_insn (operand0, scratch_reg);
883 return 1;
884 }
d6f01525 885 /* Handle most common case: storing into a register. */
886 else if (register_operand (operand0, mode))
87ad11b0 887 {
888 if (register_operand (operand1, mode)
42faba01 889 || (GET_CODE (operand1) == CONST_INT && INT_14_BITS (operand1))
891b55b4 890 || (operand1 == CONST0_RTX (mode))
87ad11b0 891 || (GET_CODE (operand1) == HIGH
df0651dc 892 && !symbolic_operand (XEXP (operand1, 0), VOIDmode))
87ad11b0 893 /* Only `general_operands' can come here, so MEM is ok. */
894 || GET_CODE (operand1) == MEM)
895 {
896 /* Run this case quickly. */
897 emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
898 return 1;
899 }
900 }
901 else if (GET_CODE (operand0) == MEM)
902 {
891b55b4 903 if (register_operand (operand1, mode) || operand1 == CONST0_RTX (mode))
87ad11b0 904 {
905 /* Run this case quickly. */
906 emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
907 return 1;
908 }
2ff4bf8d 909 if (! (reload_in_progress || reload_completed))
87ad11b0 910 {
911 operands[0] = validize_mem (operand0);
912 operands[1] = operand1 = force_reg (mode, operand1);
913 }
914 }
915
916 /* Simplify the source if we need to. */
57ed30e5 917 if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
2ee034bc 918 || (GET_CODE (operand1) == HIGH
63882853 919 && symbolic_operand (XEXP (operand1, 0), mode)))
87ad11b0 920 {
2ee034bc 921 int ishighonly = 0;
922
923 if (GET_CODE (operand1) == HIGH)
924 {
925 ishighonly = 1;
926 operand1 = XEXP (operand1, 0);
927 }
87ad11b0 928 if (symbolic_operand (operand1, mode))
929 {
930 if (flag_pic)
931 {
2ff4bf8d 932 rtx temp;
933
934 if (reload_in_progress || reload_completed)
b4a7bf10 935 temp = scratch_reg ? scratch_reg : operand0;
2ff4bf8d 936 else
937 temp = gen_reg_rtx (Pmode);
6d36483b 938
87ad11b0 939 operands[1] = legitimize_pic_address (operand1, mode, temp);
b4a7bf10 940 emit_insn (gen_rtx (SET, VOIDmode, operand0, operands[1]));
87ad11b0 941 }
b4a7bf10 942 /* On the HPPA, references to data space are supposed to use dp,
943 register 27, but showing it in the RTL inhibits various cse
944 and loop optimizations. */
6d36483b 945 else
87ad11b0 946 {
166bf021 947 rtx temp, set, const_part = NULL;
2ee034bc 948
6d36483b 949 if (reload_in_progress || reload_completed)
2ee034bc 950 temp = scratch_reg ? scratch_reg : operand0;
951 else
952 temp = gen_reg_rtx (mode);
953
166bf021 954 /* Argh. The assembler and linker can't handle arithmetic
955 involving plabels. We'll have to split up operand1 here
956 if it's a function label involved in an arithmetic
957 expression. Luckily, this only happens with addition
958 of constants to plabels, which simplifies the test. */
959 if (GET_CODE (operand1) == CONST
960 && GET_CODE (XEXP (operand1, 0)) == PLUS
961 && function_label_operand (XEXP (XEXP (operand1, 0), 0),
962 Pmode))
963 {
964 /* Save away the constant part of the expression. */
965 const_part = XEXP (XEXP (operand1, 0), 1);
966 if (GET_CODE (const_part) != CONST_INT)
967 abort ();
968
969 /* Set operand1 to just the SYMBOL_REF. */
970 operand1 = XEXP (XEXP (operand1, 0), 0);
971 }
972
2ee034bc 973 if (ishighonly)
974 set = gen_rtx (SET, mode, operand0, temp);
975 else
976 set = gen_rtx (SET, VOIDmode,
977 operand0,
978 gen_rtx (LO_SUM, mode, temp, operand1));
6d36483b 979
87ad11b0 980 emit_insn (gen_rtx (SET, VOIDmode,
2ee034bc 981 temp,
d6f01525 982 gen_rtx (HIGH, mode, operand1)));
d2498717 983 emit_insn (set);
166bf021 984
985 /* Add back in the constant part if needed. */
986 if (const_part != NULL)
ef618fe4 987 expand_inc (operand0, const_part);
87ad11b0 988 return 1;
989 }
2ee034bc 990 return 1;
87ad11b0 991 }
42faba01 992 else if (GET_CODE (operand1) != CONST_INT
8c8ec4de 993 || ! cint_ok_for_move (INTVAL (operand1)))
87ad11b0 994 {
2ff4bf8d 995 rtx temp;
996
997 if (reload_in_progress || reload_completed)
998 temp = operand0;
999 else
1000 temp = gen_reg_rtx (mode);
1001
87ad11b0 1002 emit_insn (gen_rtx (SET, VOIDmode, temp,
1003 gen_rtx (HIGH, mode, operand1)));
1004 operands[1] = gen_rtx (LO_SUM, mode, temp, operand1);
1005 }
1006 }
1007 /* Now have insn-emit do whatever it normally does. */
1008 return 0;
1009}
1010
1011/* Does operand (which is a symbolic_operand) live in text space? If
201f01e9 1012 so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true. */
87ad11b0 1013
1014int
1015read_only_operand (operand)
1016 rtx operand;
1017{
1018 if (GET_CODE (operand) == CONST)
1019 operand = XEXP (XEXP (operand, 0), 0);
b4a7bf10 1020 if (flag_pic)
1021 {
1022 if (GET_CODE (operand) == SYMBOL_REF)
1023 return SYMBOL_REF_FLAG (operand) && !CONSTANT_POOL_ADDRESS_P (operand);
1024 }
1025 else
1026 {
1027 if (GET_CODE (operand) == SYMBOL_REF)
1028 return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand);
1029 }
87ad11b0 1030 return 1;
1031}
6d36483b 1032
87ad11b0 1033\f
1034/* Return the best assembler insn template
f54b1341 1035 for moving operands[1] into operands[0] as a fullword. */
5c683f13 1036char *
87ad11b0 1037singlemove_string (operands)
1038 rtx *operands;
1039{
3745c59b 1040 HOST_WIDE_INT intval;
1041
87ad11b0 1042 if (GET_CODE (operands[0]) == MEM)
1043 return "stw %r1,%0";
3745c59b 1044 if (GET_CODE (operands[1]) == MEM)
87ad11b0 1045 return "ldw %1,%0";
3745c59b 1046 if (GET_CODE (operands[1]) == CONST_DOUBLE)
9d5108ea 1047 {
3745c59b 1048 long i;
1049 REAL_VALUE_TYPE d;
9d5108ea 1050
3745c59b 1051 if (GET_MODE (operands[1]) != SFmode)
1052 abort ();
9d5108ea 1053
3745c59b 1054 /* Translate the CONST_DOUBLE to a CONST_INT with the same target
1055 bit pattern. */
1056 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[1]);
1057 REAL_VALUE_TO_TARGET_SINGLE (d, i);
9d5108ea 1058
3745c59b 1059 operands[1] = GEN_INT (i);
1060 /* Fall through to CONST_INT case. */
1061 }
1062 if (GET_CODE (operands[1]) == CONST_INT)
9d5108ea 1063 {
3745c59b 1064 intval = INTVAL (operands[1]);
1065
1066 if (VAL_14_BITS_P (intval))
1067 return "ldi %1,%0";
1068 else if ((intval & 0x7ff) == 0)
1069 return "ldil L'%1,%0";
1070 else if (zdepi_cint_p (intval))
1071 return "zdepi %Z1,%0";
9d5108ea 1072 else
1073 return "ldil L'%1,%0\n\tldo R'%1(%0),%0";
1074 }
87ad11b0 1075 return "copy %1,%0";
1076}
1077\f
1078
201f01e9 1079/* Compute position (in OP[1]) and width (in OP[2])
1080 useful for copying IMM to a register using the zdepi
1081 instructions. Store the immediate value to insert in OP[0]. */
e057641f 1082void
42faba01 1083compute_zdepi_operands (imm, op)
6d36483b 1084 unsigned HOST_WIDE_INT imm;
42faba01 1085 unsigned *op;
7e10ba53 1086{
e057641f 1087 int lsb, len;
7e10ba53 1088
e057641f 1089 /* Find the least significant set bit in IMM. */
1090 for (lsb = 0; lsb < 32; lsb++)
7e10ba53 1091 {
e057641f 1092 if ((imm & 1) != 0)
7e10ba53 1093 break;
e057641f 1094 imm >>= 1;
7e10ba53 1095 }
1096
e057641f 1097 /* Choose variants based on *sign* of the 5-bit field. */
1098 if ((imm & 0x10) == 0)
1099 len = (lsb <= 28) ? 4 : 32 - lsb;
7e10ba53 1100 else
1101 {
e057641f 1102 /* Find the width of the bitstring in IMM. */
1103 for (len = 5; len < 32; len++)
7e10ba53 1104 {
e057641f 1105 if ((imm & (1 << len)) == 0)
7e10ba53 1106 break;
7e10ba53 1107 }
1108
e057641f 1109 /* Sign extend IMM as a 5-bit value. */
1110 imm = (imm & 0xf) - 0x10;
7e10ba53 1111 }
1112
42faba01 1113 op[0] = imm;
1114 op[1] = 31 - lsb;
1115 op[2] = len;
7e10ba53 1116}
1117
87ad11b0 1118/* Output assembler code to perform a doubleword move insn
1119 with operands OPERANDS. */
1120
1121char *
1122output_move_double (operands)
1123 rtx *operands;
1124{
1125 enum { REGOP, OFFSOP, MEMOP, CNSTOP, RNDOP } optype0, optype1;
1126 rtx latehalf[2];
1127 rtx addreg0 = 0, addreg1 = 0;
1128
1129 /* First classify both operands. */
1130
1131 if (REG_P (operands[0]))
1132 optype0 = REGOP;
1133 else if (offsettable_memref_p (operands[0]))
1134 optype0 = OFFSOP;
1135 else if (GET_CODE (operands[0]) == MEM)
1136 optype0 = MEMOP;
1137 else
1138 optype0 = RNDOP;
1139
1140 if (REG_P (operands[1]))
1141 optype1 = REGOP;
1142 else if (CONSTANT_P (operands[1]))
1143 optype1 = CNSTOP;
1144 else if (offsettable_memref_p (operands[1]))
1145 optype1 = OFFSOP;
1146 else if (GET_CODE (operands[1]) == MEM)
1147 optype1 = MEMOP;
1148 else
1149 optype1 = RNDOP;
1150
1151 /* Check for the cases that the operand constraints are not
1152 supposed to allow to happen. Abort if we get one,
1153 because generating code for these cases is painful. */
1154
1155 if (optype0 != REGOP && optype1 != REGOP)
1156 abort ();
1157
1158 /* Handle auto decrementing and incrementing loads and stores
1159 specifically, since the structure of the function doesn't work
1160 for them without major modification. Do it better when we learn
1161 this port about the general inc/dec addressing of PA.
1162 (This was written by tege. Chide him if it doesn't work.) */
1163
1164 if (optype0 == MEMOP)
1165 {
1df0058a 1166 /* We have to output the address syntax ourselves, since print_operand
1167 doesn't deal with the addresses we want to use. Fix this later. */
1168
87ad11b0 1169 rtx addr = XEXP (operands[0], 0);
1df0058a 1170 if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
87ad11b0 1171 {
1df0058a 1172 rtx high_reg = gen_rtx (SUBREG, SImode, operands[1], 0);
1173
1174 operands[0] = XEXP (addr, 0);
1175 if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
1176 abort ();
1177
1178 if (!reg_overlap_mentioned_p (high_reg, addr))
1179 {
1180 /* No overlap between high target register and address
1181 register. (We do this in a non-obvious way to
1182 save a register file writeback) */
1183 if (GET_CODE (addr) == POST_INC)
1184 return "stws,ma %1,8(0,%0)\n\tstw %R1,-4(0,%0)";
1185 return "stws,ma %1,-8(0,%0)\n\tstw %R1,12(0,%0)";
1186 }
1187 else
1188 abort();
a3217f65 1189 }
1df0058a 1190 else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
a3217f65 1191 {
1df0058a 1192 rtx high_reg = gen_rtx (SUBREG, SImode, operands[1], 0);
1193
1194 operands[0] = XEXP (addr, 0);
1195 if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
1196 abort ();
1197
1198 if (!reg_overlap_mentioned_p (high_reg, addr))
1199 {
1200 /* No overlap between high target register and address
1201 register. (We do this in a non-obvious way to
1202 save a register file writeback) */
1203 if (GET_CODE (addr) == PRE_INC)
1204 return "stws,mb %1,8(0,%0)\n\tstw %R1,4(0,%0)";
1205 return "stws,mb %1,-8(0,%0)\n\tstw %R1,4(0,%0)";
1206 }
1207 else
1208 abort();
87ad11b0 1209 }
1210 }
1211 if (optype1 == MEMOP)
1212 {
1213 /* We have to output the address syntax ourselves, since print_operand
1214 doesn't deal with the addresses we want to use. Fix this later. */
1215
1216 rtx addr = XEXP (operands[1], 0);
1217 if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
1218 {
1219 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], 0);
1220
1221 operands[1] = XEXP (addr, 0);
1222 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
1223 abort ();
1224
1225 if (!reg_overlap_mentioned_p (high_reg, addr))
1226 {
1227 /* No overlap between high target register and address
3857fa62 1228 register. (We do this in a non-obvious way to
87ad11b0 1229 save a register file writeback) */
1230 if (GET_CODE (addr) == POST_INC)
1231 return "ldws,ma 8(0,%1),%0\n\tldw -4(0,%1),%R0";
1232 return "ldws,ma -8(0,%1),%0\n\tldw 12(0,%1),%R0";
1233 }
1234 else
1235 {
1236 /* This is an undefined situation. We should load into the
1237 address register *and* update that register. Probably
1238 we don't need to handle this at all. */
1239 if (GET_CODE (addr) == POST_INC)
1240 return "ldw 4(0,%1),%R0\n\tldws,ma 8(0,%1),%0";
1241 return "ldw 4(0,%1),%R0\n\tldws,ma -8(0,%1),%0";
1242 }
1243 }
1244 else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
1245 {
1246 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], 0);
1247
1248 operands[1] = XEXP (addr, 0);
1249 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
1250 abort ();
1251
1252 if (!reg_overlap_mentioned_p (high_reg, addr))
1253 {
1254 /* No overlap between high target register and address
3857fa62 1255 register. (We do this in a non-obvious way to
87ad11b0 1256 save a register file writeback) */
1257 if (GET_CODE (addr) == PRE_INC)
1258 return "ldws,mb 8(0,%1),%0\n\tldw 4(0,%1),%R0";
1259 return "ldws,mb -8(0,%1),%0\n\tldw 4(0,%1),%R0";
1260 }
1261 else
1262 {
1263 /* This is an undefined situation. We should load into the
1264 address register *and* update that register. Probably
1265 we don't need to handle this at all. */
1266 if (GET_CODE (addr) == PRE_INC)
1267 return "ldw 12(0,%1),%R0\n\tldws,mb 8(0,%1),%0";
1268 return "ldw -4(0,%1),%R0\n\tldws,mb -8(0,%1),%0";
1269 }
1270 }
1271 }
1272
1273 /* If an operand is an unoffsettable memory ref, find a register
1274 we can increment temporarily to make it refer to the second word. */
1275
1276 if (optype0 == MEMOP)
1277 addreg0 = find_addr_reg (XEXP (operands[0], 0));
1278
1279 if (optype1 == MEMOP)
1280 addreg1 = find_addr_reg (XEXP (operands[1], 0));
1281
1282 /* Ok, we can do one word at a time.
1283 Normally we do the low-numbered word first.
1284
1285 In either case, set up in LATEHALF the operands to use
1286 for the high-numbered word and in some cases alter the
1287 operands in OPERANDS to be suitable for the low-numbered word. */
1288
1289 if (optype0 == REGOP)
1290 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1291 else if (optype0 == OFFSOP)
1292 latehalf[0] = adj_offsettable_operand (operands[0], 4);
1293 else
1294 latehalf[0] = operands[0];
1295
1296 if (optype1 == REGOP)
1297 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1298 else if (optype1 == OFFSOP)
1299 latehalf[1] = adj_offsettable_operand (operands[1], 4);
1300 else if (optype1 == CNSTOP)
1301 split_double (operands[1], &operands[1], &latehalf[1]);
1302 else
1303 latehalf[1] = operands[1];
1304
1305 /* If the first move would clobber the source of the second one,
1306 do them in the other order.
1307
1308 RMS says "This happens only for registers;
1309 such overlap can't happen in memory unless the user explicitly
1310 sets it up, and that is an undefined circumstance."
1311
1312 but it happens on the HP-PA when loading parameter registers,
1313 so I am going to define that circumstance, and make it work
1314 as expected. */
1315
1316 if (optype0 == REGOP && (optype1 == MEMOP || optype1 == OFFSOP)
1317 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
1318 {
1319 /* XXX THIS PROBABLY DOESN'T WORK. */
1320 /* Do the late half first. */
1321 if (addreg1)
6a5d085a 1322 output_asm_insn ("ldo 4(%0),%0", &addreg1);
87ad11b0 1323 output_asm_insn (singlemove_string (latehalf), latehalf);
1324 if (addreg1)
6a5d085a 1325 output_asm_insn ("ldo -4(%0),%0", &addreg1);
87ad11b0 1326 /* Then clobber. */
1327 return singlemove_string (operands);
1328 }
1329
c4fa5937 1330 if (optype0 == REGOP && optype1 == REGOP
1331 && REGNO (operands[0]) == REGNO (operands[1]) + 1)
1332 {
1333 output_asm_insn (singlemove_string (latehalf), latehalf);
1334 return singlemove_string (operands);
1335 }
1336
87ad11b0 1337 /* Normal case: do the two words, low-numbered first. */
1338
1339 output_asm_insn (singlemove_string (operands), operands);
1340
1341 /* Make any unoffsettable addresses point at high-numbered word. */
1342 if (addreg0)
6a5d085a 1343 output_asm_insn ("ldo 4(%0),%0", &addreg0);
87ad11b0 1344 if (addreg1)
6a5d085a 1345 output_asm_insn ("ldo 4(%0),%0", &addreg1);
87ad11b0 1346
1347 /* Do that word. */
1348 output_asm_insn (singlemove_string (latehalf), latehalf);
1349
1350 /* Undo the adds we just did. */
1351 if (addreg0)
6a5d085a 1352 output_asm_insn ("ldo -4(%0),%0", &addreg0);
87ad11b0 1353 if (addreg1)
6a5d085a 1354 output_asm_insn ("ldo -4(%0),%0", &addreg1);
87ad11b0 1355
1356 return "";
1357}
1358\f
1359char *
1360output_fp_move_double (operands)
1361 rtx *operands;
1362{
1363 if (FP_REG_P (operands[0]))
1364 {
6d36483b 1365 if (FP_REG_P (operands[1])
891b55b4 1366 || operands[1] == CONST0_RTX (GET_MODE (operands[0])))
1367 output_asm_insn ("fcpy,dbl %r1,%0", operands);
6d36483b 1368 else
87ad11b0 1369 output_asm_insn ("fldds%F1 %1,%0", operands);
1370 }
1371 else if (FP_REG_P (operands[1]))
1372 {
23b9e2b3 1373 output_asm_insn ("fstds%F0 %1,%0", operands);
87ad11b0 1374 }
891b55b4 1375 else if (operands[1] == CONST0_RTX (GET_MODE (operands[0])))
1376 {
1377 if (GET_CODE (operands[0]) == REG)
1378 {
1379 rtx xoperands[2];
1380 xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1381 xoperands[0] = operands[0];
1382 output_asm_insn ("copy %%r0,%0\n\tcopy %%r0,%1", xoperands);
1383 }
6d36483b 1384 /* This is a pain. You have to be prepared to deal with an
891b55b4 1385 arbritary address here including pre/post increment/decrement.
1386
1387 so avoid this in the MD. */
1388 else
1389 abort ();
1390 }
87ad11b0 1391 else abort ();
1392 return "";
1393}
1394\f
1395/* Return a REG that occurs in ADDR with coefficient 1.
1396 ADDR can be effectively incremented by incrementing REG. */
1397
1398static rtx
1399find_addr_reg (addr)
1400 rtx addr;
1401{
1402 while (GET_CODE (addr) == PLUS)
1403 {
1404 if (GET_CODE (XEXP (addr, 0)) == REG)
1405 addr = XEXP (addr, 0);
1406 else if (GET_CODE (XEXP (addr, 1)) == REG)
1407 addr = XEXP (addr, 1);
1408 else if (CONSTANT_P (XEXP (addr, 0)))
1409 addr = XEXP (addr, 1);
1410 else if (CONSTANT_P (XEXP (addr, 1)))
1411 addr = XEXP (addr, 0);
1412 else
1413 abort ();
1414 }
1415 if (GET_CODE (addr) == REG)
1416 return addr;
1417 abort ();
1418}
1419
87ad11b0 1420/* Emit code to perform a block move.
1421
1422 Restriction: If the length argument is non-constant, alignment
1423 must be 4.
1424
1425 OPERANDS[0] is the destination pointer as a REG, clobbered.
1426 OPERANDS[1] is the source pointer as a REG, clobbered.
1427 if SIZE_IS_CONSTANT
1428 OPERANDS[2] is a register for temporary storage.
1429 OPERANDS[4] is the size as a CONST_INT
1430 else
1431 OPERANDS[2] is a REG which will contain the size, clobbered.
1432 OPERANDS[3] is a register for temporary storage.
1433 OPERANDS[5] is the alignment safe to use, as a CONST_INT. */
1434
1435char *
1436output_block_move (operands, size_is_constant)
1437 rtx *operands;
1438 int size_is_constant;
1439{
1440 int align = INTVAL (operands[5]);
1441 unsigned long n_bytes;
1442
1443 /* We can't move more than four bytes at a time because the PA
1444 has no longer integer move insns. (Could use fp mem ops?) */
1445 if (align > 4)
1446 align = 4;
1447
1448 if (size_is_constant)
1449 {
87ad11b0 1450 unsigned long offset;
1451 rtx temp;
1452
1453 n_bytes = INTVAL (operands[4]);
1454 if (n_bytes == 0)
1455 return "";
1456
1457 if (align >= 4)
1458 {
1459 /* Don't unroll too large blocks. */
6d36483b 1460 if (n_bytes > 32)
87ad11b0 1461 goto copy_with_loop;
1462
1463 /* Read and store using two registers, and hide latency
4bbea254 1464 by deferring the stores until three instructions after
87ad11b0 1465 the corresponding load. The last load insn will read
1466 the entire word were the last bytes are, possibly past
1467 the end of the source block, but since loads are aligned,
1468 this is harmless. */
1469
1470 output_asm_insn ("ldws,ma 4(0,%1),%2", operands);
1471
1472 for (offset = 4; offset < n_bytes; offset += 4)
1473 {
1474 output_asm_insn ("ldws,ma 4(0,%1),%3", operands);
1475 output_asm_insn ("stws,ma %2,4(0,%0)", operands);
1476
1477 temp = operands[2];
1478 operands[2] = operands[3];
1479 operands[3] = temp;
1480 }
1481 if (n_bytes % 4 == 0)
1482 /* Store the last word. */
1483 output_asm_insn ("stw %2,0(0,%0)", operands);
1484 else
1485 {
1486 /* Store the last, partial word. */
ef618fe4 1487 operands[4] = GEN_INT (n_bytes % 4);
87ad11b0 1488 output_asm_insn ("stbys,e %2,%4(0,%0)", operands);
1489 }
1490 return "";
1491 }
1492
1493 if (align >= 2 && n_bytes >= 2)
1494 {
1495 output_asm_insn ("ldhs,ma 2(0,%1),%2", operands);
1496
1497 for (offset = 2; offset + 2 <= n_bytes; offset += 2)
1498 {
1499 output_asm_insn ("ldhs,ma 2(0,%1),%3", operands);
1500 output_asm_insn ("sths,ma %2,2(0,%0)", operands);
1501
1502 temp = operands[2];
1503 operands[2] = operands[3];
1504 operands[3] = temp;
1505 }
1506 if (n_bytes % 2 != 0)
1507 output_asm_insn ("ldb 0(0,%1),%3", operands);
1508
1509 output_asm_insn ("sths,ma %2,2(0,%0)", operands);
1510
1511 if (n_bytes % 2 != 0)
1512 output_asm_insn ("stb %3,0(0,%0)", operands);
1513
1514 return "";
1515 }
1516
1517 output_asm_insn ("ldbs,ma 1(0,%1),%2", operands);
1518
1519 for (offset = 1; offset + 1 <= n_bytes; offset += 1)
1520 {
1521 output_asm_insn ("ldbs,ma 1(0,%1),%3", operands);
1522 output_asm_insn ("stbs,ma %2,1(0,%0)", operands);
1523
1524 temp = operands[2];
1525 operands[2] = operands[3];
1526 operands[3] = temp;
1527 }
1528 output_asm_insn ("stb %2,0(0,%0)", operands);
1529
1530 return "";
1531 }
1532
1533 if (align != 4)
1534 abort();
6d36483b 1535
87ad11b0 1536 copy_with_loop:
1537
1538 if (size_is_constant)
1539 {
a3217f65 1540 /* Size is compile-time determined, and also not
87ad11b0 1541 very small (such small cases are handled above). */
ef618fe4 1542 operands[4] = GEN_INT (n_bytes - 4);
87ad11b0 1543 output_asm_insn ("ldo %4(0),%2", operands);
1544 }
1545 else
1546 {
1547 /* Decrement counter by 4, and if it becomes negative, jump past the
1548 word copying loop. */
1549 output_asm_insn ("addib,<,n -4,%2,.+16", operands);
1550 }
1551
4bbea254 1552 /* Copying loop. Note that the first load is in the annulled delay slot
87ad11b0 1553 of addib. Is it OK on PA to have a load in a delay slot, i.e. is a
1554 possible page fault stopped in time? */
1555 output_asm_insn ("ldws,ma 4(0,%1),%3", operands);
1556 output_asm_insn ("addib,>= -4,%2,.-4", operands);
1557 output_asm_insn ("stws,ma %3,4(0,%0)", operands);
1558
1559 /* The counter is negative, >= -4. The remaining number of bytes are
1560 determined by the two least significant bits. */
1561
1562 if (size_is_constant)
1563 {
1564 if (n_bytes % 4 != 0)
1565 {
1566 /* Read the entire word of the source block tail. */
1567 output_asm_insn ("ldw 0(0,%1),%3", operands);
ef618fe4 1568 operands[4] = GEN_INT (n_bytes % 4);
87ad11b0 1569 output_asm_insn ("stbys,e %3,%4(0,%0)", operands);
1570 }
1571 }
1572 else
1573 {
1574 /* Add 4 to counter. If it becomes zero, we're done. */
1575 output_asm_insn ("addib,=,n 4,%2,.+16", operands);
1576
1577 /* Read the entire word of the source block tail. (Also this
4bbea254 1578 load is in an annulled delay slot.) */
87ad11b0 1579 output_asm_insn ("ldw 0(0,%1),%3", operands);
1580
1581 /* Make %0 point at the first byte after the destination block. */
df0651dc 1582 output_asm_insn ("addl %2,%0,%0", operands);
87ad11b0 1583 /* Store the leftmost bytes, up to, but not including, the address
1584 in %0. */
1585 output_asm_insn ("stbys,e %3,0(0,%0)", operands);
1586 }
1587 return "";
1588}
58e17b0b 1589
1590/* Count the number of insns necessary to handle this block move.
1591
1592 Basic structure is the same as emit_block_move, except that we
1593 count insns rather than emit them. */
1594
1595int
1596compute_movstrsi_length (insn)
1597 rtx insn;
1598{
1599 rtx pat = PATTERN (insn);
1600 int size_is_constant;
1601 int align = INTVAL (XEXP (XVECEXP (pat, 0, 6), 0));
1602 unsigned long n_bytes;
1603 int insn_count = 0;
1604
1605 if (GET_CODE (XEXP (XVECEXP (pat, 0, 5), 0)) == CONST_INT)
1606 {
1607 size_is_constant = 1;
1608 n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 5), 0));
1609 }
1610 else
1611 {
1612 size_is_constant = 0;
1613 n_bytes = 0;
1614 }
1615
1616 /* We can't move more than four bytes at a time because the PA
1617 has no longer integer move insns. (Could use fp mem ops?) */
1618 if (align > 4)
1619 align = 4;
1620
1621 if (size_is_constant)
1622 {
58e17b0b 1623 unsigned long offset;
58e17b0b 1624
1625 if (n_bytes == 0)
1626 return 0;
1627
1628 if (align >= 4)
1629 {
1630 /* Don't unroll too large blocks. */
6d36483b 1631 if (n_bytes > 32)
58e17b0b 1632 goto copy_with_loop;
1633
1634 /* first load */
1635 insn_count = 1;
1636
1637 /* Count the unrolled insns. */
1638 for (offset = 4; offset < n_bytes; offset += 4)
1639 insn_count += 2;
1640
1641 /* Count last store or partial store. */
1642 insn_count += 1;
5a1231ef 1643 return insn_count * 4;
58e17b0b 1644 }
1645
1646 if (align >= 2 && n_bytes >= 2)
1647 {
1648 /* initial load. */
1649 insn_count = 1;
1650
1651 /* Unrolled loop. */
1652 for (offset = 2; offset + 2 <= n_bytes; offset += 2)
1653 insn_count += 2;
1654
1655 /* ??? odd load/store */
1656 if (n_bytes % 2 != 0)
1657 insn_count += 2;
1658
1659 /* ??? final store from loop. */
1660 insn_count += 1;
1661
5a1231ef 1662 return insn_count * 4;
58e17b0b 1663 }
1664
1665 /* First load. */
1666 insn_count = 1;
1667
1668 /* The unrolled loop. */
1669 for (offset = 1; offset + 1 <= n_bytes; offset += 1)
1670 insn_count += 2;
1671
1672 /* Final store. */
1673 insn_count += 1;
1674
5a1231ef 1675 return insn_count * 4;
58e17b0b 1676 }
1677
1678 if (align != 4)
1679 abort();
6d36483b 1680
58e17b0b 1681 copy_with_loop:
1682
1683 /* setup for constant and non-constant case. */
1684 insn_count = 1;
1685
1686 /* The copying loop. */
1687 insn_count += 3;
1688
1689 /* The counter is negative, >= -4. The remaining number of bytes are
1690 determined by the two least significant bits. */
1691
1692 if (size_is_constant)
1693 {
1694 if (n_bytes % 4 != 0)
1695 insn_count += 2;
1696 }
1697 else
1698 insn_count += 4;
5a1231ef 1699 return insn_count * 4;
58e17b0b 1700}
87ad11b0 1701\f
1702
e057641f 1703char *
1704output_and (operands)
1705 rtx *operands;
1706{
d6f01525 1707 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
e057641f 1708 {
3745c59b 1709 unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
e057641f 1710 int ls0, ls1, ms0, p, len;
1711
1712 for (ls0 = 0; ls0 < 32; ls0++)
1713 if ((mask & (1 << ls0)) == 0)
1714 break;
1715
1716 for (ls1 = ls0; ls1 < 32; ls1++)
1717 if ((mask & (1 << ls1)) != 0)
1718 break;
1719
1720 for (ms0 = ls1; ms0 < 32; ms0++)
1721 if ((mask & (1 << ms0)) == 0)
1722 break;
1723
1724 if (ms0 != 32)
1725 abort();
1726
1727 if (ls1 == 32)
1728 {
1729 len = ls0;
1730
1731 if (len == 0)
1732 abort ();
1733
ef618fe4 1734 operands[2] = GEN_INT (len);
e057641f 1735 return "extru %1,31,%2,%0";
1736 }
1737 else
1738 {
1739 /* We could use this `depi' for the case above as well, but `depi'
1740 requires one more register file access than an `extru'. */
1741
1742 p = 31 - ls0;
1743 len = ls1 - ls0;
1744
ef618fe4 1745 operands[2] = GEN_INT (p);
1746 operands[3] = GEN_INT (len);
e057641f 1747 return "depi 0,%2,%3,%0";
1748 }
1749 }
1750 else
1751 return "and %1,%2,%0";
1752}
1753
1754char *
1755output_ior (operands)
1756 rtx *operands;
1757{
3745c59b 1758 unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
57ed30e5 1759 int bs0, bs1, p, len;
6d36483b 1760
c9da5f4d 1761 if (INTVAL (operands[2]) == 0)
1762 return "copy %1,%0";
e057641f 1763
c9da5f4d 1764 for (bs0 = 0; bs0 < 32; bs0++)
1765 if ((mask & (1 << bs0)) != 0)
1766 break;
e057641f 1767
c9da5f4d 1768 for (bs1 = bs0; bs1 < 32; bs1++)
1769 if ((mask & (1 << bs1)) == 0)
1770 break;
e057641f 1771
3745c59b 1772 if (bs1 != 32 && ((unsigned HOST_WIDE_INT) 1 << bs1) <= mask)
c9da5f4d 1773 abort();
e057641f 1774
c9da5f4d 1775 p = 31 - bs0;
1776 len = bs1 - bs0;
e057641f 1777
ef618fe4 1778 operands[2] = GEN_INT (p);
1779 operands[3] = GEN_INT (len);
c9da5f4d 1780 return "depi -1,%2,%3,%0";
e057641f 1781}
1782\f
87ad11b0 1783/* Output an ascii string. */
57ed30e5 1784void
87ad11b0 1785output_ascii (file, p, size)
1786 FILE *file;
1787 unsigned char *p;
1788 int size;
1789{
1790 int i;
1791 int chars_output;
1792 unsigned char partial_output[16]; /* Max space 4 chars can occupy. */
1793
1794 /* The HP assembler can only take strings of 256 characters at one
1795 time. This is a limitation on input line length, *not* the
1796 length of the string. Sigh. Even worse, it seems that the
1797 restriction is in number of input characters (see \xnn &
1798 \whatever). So we have to do this very carefully. */
1799
1800 fprintf (file, "\t.STRING \"");
1801
1802 chars_output = 0;
1803 for (i = 0; i < size; i += 4)
1804 {
1805 int co = 0;
1806 int io = 0;
1807 for (io = 0, co = 0; io < MIN (4, size - i); io++)
1808 {
1809 register unsigned int c = p[i + io];
1810
1811 if (c == '\"' || c == '\\')
1812 partial_output[co++] = '\\';
1813 if (c >= ' ' && c < 0177)
1814 partial_output[co++] = c;
1815 else
1816 {
1817 unsigned int hexd;
1818 partial_output[co++] = '\\';
1819 partial_output[co++] = 'x';
1820 hexd = c / 16 - 0 + '0';
1821 if (hexd > '9')
1822 hexd -= '9' - 'a' + 1;
1823 partial_output[co++] = hexd;
1824 hexd = c % 16 - 0 + '0';
1825 if (hexd > '9')
1826 hexd -= '9' - 'a' + 1;
1827 partial_output[co++] = hexd;
1828 }
1829 }
1830 if (chars_output + co > 243)
1831 {
1832 fprintf (file, "\"\n\t.STRING \"");
1833 chars_output = 0;
1834 }
1835 fwrite (partial_output, 1, co, file);
1836 chars_output += co;
1837 co = 0;
1838 }
1839 fprintf (file, "\"\n");
1840}
1841\f
201f01e9 1842/* You may have trouble believing this, but this is the HP-PA stack
87ad11b0 1843 layout. Wow.
1844
1845 Offset Contents
1846
1847 Variable arguments (optional; any number may be allocated)
1848
1849 SP-(4*(N+9)) arg word N
1850 : :
1851 SP-56 arg word 5
1852 SP-52 arg word 4
1853
1854 Fixed arguments (must be allocated; may remain unused)
1855
1856 SP-48 arg word 3
1857 SP-44 arg word 2
1858 SP-40 arg word 1
1859 SP-36 arg word 0
1860
1861 Frame Marker
1862
1863 SP-32 External Data Pointer (DP)
1864 SP-28 External sr4
1865 SP-24 External/stub RP (RP')
1866 SP-20 Current RP
1867 SP-16 Static Link
1868 SP-12 Clean up
1869 SP-8 Calling Stub RP (RP'')
1870 SP-4 Previous SP
1871
1872 Top of Frame
1873
1874 SP-0 Stack Pointer (points to next available address)
1875
1876*/
1877
1878/* This function saves registers as follows. Registers marked with ' are
1879 this function's registers (as opposed to the previous function's).
1880 If a frame_pointer isn't needed, r4 is saved as a general register;
1881 the space for the frame pointer is still allocated, though, to keep
1882 things simple.
1883
1884
1885 Top of Frame
1886
1887 SP (FP') Previous FP
1888 SP + 4 Alignment filler (sigh)
1889 SP + 8 Space for locals reserved here.
1890 .
1891 .
1892 .
1893 SP + n All call saved register used.
1894 .
1895 .
1896 .
1897 SP + o All call saved fp registers used.
1898 .
1899 .
1900 .
1901 SP + p (SP') points to next available address.
6d36483b 1902
87ad11b0 1903*/
1904
daee63dd 1905/* Emit RTL to store REG at the memory location specified by BASE+DISP.
1906 Handle case where DISP > 8k by using the add_high_const pattern.
1907
1908 Note in DISP > 8k case, we will leave the high part of the address
1909 in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
1910static void
1911store_reg (reg, disp, base)
1912 int reg, disp, base;
87ad11b0 1913{
1914 if (VAL_14_BITS_P (disp))
daee63dd 1915 {
6d36483b 1916 emit_move_insn (gen_rtx (MEM, SImode,
1917 gen_rtx (PLUS, SImode,
daee63dd 1918 gen_rtx (REG, SImode, base),
1919 GEN_INT (disp))),
1920 gen_rtx (REG, SImode, reg));
1921 }
87ad11b0 1922 else
daee63dd 1923 {
6d36483b 1924 emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
1925 gen_rtx (REG, SImode, base),
daee63dd 1926 GEN_INT (disp)));
1927 emit_move_insn (gen_rtx (MEM, SImode,
6d36483b 1928 gen_rtx (LO_SUM, SImode,
daee63dd 1929 gen_rtx (REG, SImode, 1),
1930 GEN_INT (disp))),
1931 gen_rtx (REG, SImode, reg));
1932 }
87ad11b0 1933}
1934
daee63dd 1935/* Emit RTL to load REG from the memory location specified by BASE+DISP.
1936 Handle case where DISP > 8k by using the add_high_const pattern.
1937
1938 Note in DISP > 8k case, we will leave the high part of the address
1939 in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
1940static void
1941load_reg (reg, disp, base)
1942 int reg, disp, base;
1943{
1944 if (VAL_14_BITS_P (disp))
1945 {
1946 emit_move_insn (gen_rtx (REG, SImode, reg),
6d36483b 1947 gen_rtx (MEM, SImode,
1948 gen_rtx (PLUS, SImode,
daee63dd 1949 gen_rtx (REG, SImode, base),
1950 GEN_INT (disp))));
daee63dd 1951 }
1952 else
1953 {
6d36483b 1954 emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
daee63dd 1955 gen_rtx (REG, SImode, base),
1956 GEN_INT (disp)));
1957 emit_move_insn (gen_rtx (REG, SImode, reg),
1958 gen_rtx (MEM, SImode,
6d36483b 1959 gen_rtx (LO_SUM, SImode,
1960 gen_rtx (REG, SImode, 1),
daee63dd 1961 GEN_INT (disp))));
1962 }
1963}
1964
1965/* Emit RTL to set REG to the value specified by BASE+DISP.
1966 Handle case where DISP > 8k by using the add_high_const pattern.
1967
1968 Note in DISP > 8k case, we will leave the high part of the address
1969 in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
1970static void
1971set_reg_plus_d(reg, base, disp)
1972 int reg, base, disp;
87ad11b0 1973{
1974 if (VAL_14_BITS_P (disp))
daee63dd 1975 {
1976 emit_move_insn (gen_rtx (REG, SImode, reg),
6d36483b 1977 gen_rtx (PLUS, SImode,
daee63dd 1978 gen_rtx (REG, SImode, base),
1979 GEN_INT (disp)));
daee63dd 1980 }
87ad11b0 1981 else
daee63dd 1982 {
6d36483b 1983 emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
daee63dd 1984 gen_rtx (REG, SImode, base),
1985 GEN_INT (disp)));
1986 emit_move_insn (gen_rtx (REG, SImode, reg),
6d36483b 1987 gen_rtx (LO_SUM, SImode,
daee63dd 1988 gen_rtx (REG, SImode, 1),
1989 GEN_INT (disp)));
1990 }
87ad11b0 1991}
1992
3ddcbb9d 1993/* Global variables set by FUNCTION_PROLOGUE. */
1994/* Size of frame. Need to know this to emit return insns from
1995 leaf procedures. */
a1ab4fa3 1996static int actual_fsize;
1997static int local_fsize, save_fregs;
3ddcbb9d 1998
87ad11b0 1999int
a1ab4fa3 2000compute_frame_size (size, fregs_live)
87ad11b0 2001 int size;
3ddcbb9d 2002 int *fregs_live;
87ad11b0 2003{
2004 extern int current_function_outgoing_args_size;
a1ab4fa3 2005 int i, fsize;
87ad11b0 2006
6d36483b 2007 /* 8 is space for frame pointer + filler. If any frame is allocated
a1ab4fa3 2008 we need to add this in because of STARTING_FRAME_OFFSET. */
2009 fsize = size + (size || frame_pointer_needed ? 8 : 0);
87ad11b0 2010
df0651dc 2011 for (i = 18; i >= 4; i--)
daee63dd 2012 {
df0651dc 2013 if (regs_ever_live[i])
daee63dd 2014 fsize += 4;
2015 }
df0651dc 2016 /* If we don't have a frame pointer, the register normally used for that
2017 purpose is saved just like other registers, not in the "frame marker". */
2018 if (! frame_pointer_needed)
87ad11b0 2019 {
df0651dc 2020 if (regs_ever_live[FRAME_POINTER_REGNUM])
2021 fsize += 4;
87ad11b0 2022 }
df0651dc 2023 fsize = (fsize + 7) & ~7;
2024
2025 for (i = 66; i >= 48; i -= 2)
2026 if (regs_ever_live[i] || regs_ever_live[i + 1])
2027 {
2028 fsize += 8;
2029 if (fregs_live)
2030 *fregs_live = 1;
2031 }
2032
a1ab4fa3 2033 fsize += current_function_outgoing_args_size;
2034 if (! leaf_function_p () || fsize)
2035 fsize += 32;
57ed30e5 2036 return (fsize + 63) & ~63;
87ad11b0 2037}
6d36483b 2038
daee63dd 2039rtx hp_profile_label_rtx;
2040static char hp_profile_label_name[8];
87ad11b0 2041void
a1ab4fa3 2042output_function_prologue (file, size)
87ad11b0 2043 FILE *file;
2044 int size;
87ad11b0 2045{
d151162a 2046 /* The function's label and associated .PROC must never be
2047 separated and must be output *after* any profiling declarations
2048 to avoid changing spaces/subspaces within a procedure. */
2049 ASM_OUTPUT_LABEL (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
2050 fputs ("\t.PROC\n", file);
2051
daee63dd 2052 /* hppa_expand_prologue does the dirty work now. We just need
2053 to output the assembler directives which denote the start
2054 of a function. */
2acd4f33 2055 fprintf (file, "\t.CALLINFO FRAME=%d", actual_fsize);
daee63dd 2056 if (regs_ever_live[2] || profile_flag)
f3ba7709 2057 fprintf (file, ",CALLS,SAVE_RP");
daee63dd 2058 else
f3ba7709 2059 fprintf (file, ",NO_CALLS");
2060
2061 if (frame_pointer_needed)
2062 fprintf (file, ",SAVE_SP");
2063
a9960cdc 2064 /* Pass on information about the number of callee register saves
9b0c95be 2065 performed in the prologue.
2066
2067 The compiler is supposed to pass the highest register number
6d36483b 2068 saved, the assembler then has to adjust that number before
9b0c95be 2069 entering it into the unwind descriptor (to account for any
6d36483b 2070 caller saved registers with lower register numbers than the
9b0c95be 2071 first callee saved register). */
2072 if (gr_saved)
2073 fprintf (file, ",ENTRY_GR=%d", gr_saved + 2);
2074
2075 if (fr_saved)
2076 fprintf (file, ",ENTRY_FR=%d", fr_saved + 11);
a9960cdc 2077
f3ba7709 2078 fprintf (file, "\n\t.ENTRY\n");
daee63dd 2079
2080 /* Horrid hack. emit_function_prologue will modify this RTL in
2081 place to get the expected results. */
2082 if (profile_flag)
07b209fc 2083 ASM_GENERATE_INTERNAL_LABEL (hp_profile_label_name, "LP",
2084 hp_profile_labelno);
06ddb6f8 2085
2086 if (insn_addresses)
2087 {
2088 unsigned int old_total = total_code_bytes;
2089
2090 total_code_bytes += insn_addresses[INSN_UID (get_last_insn())];
2091 total_code_bytes += FUNCTION_BOUNDARY /BITS_PER_UNIT;
2092
2093 /* Be prepared to handle overflows. */
2094 total_code_bytes = old_total > total_code_bytes ? -1 : total_code_bytes;
2095 }
2096 else
2097 total_code_bytes = -1;
daee63dd 2098}
2099
57ed30e5 2100void
daee63dd 2101hppa_expand_prologue()
2102{
87ad11b0 2103 extern char call_used_regs[];
daee63dd 2104 int size = get_frame_size ();
afd7b680 2105 int merge_sp_adjust_with_store = 0;
daee63dd 2106 int i, offset;
2107 rtx tmpreg, size_rtx;
2108
a9960cdc 2109 gr_saved = 0;
2110 fr_saved = 0;
3ddcbb9d 2111 save_fregs = 0;
a1ab4fa3 2112 local_fsize = size + (size || frame_pointer_needed ? 8 : 0);
2113 actual_fsize = compute_frame_size (size, &save_fregs);
87ad11b0 2114
daee63dd 2115 /* Compute a few things we will use often. */
2116 tmpreg = gen_rtx (REG, SImode, 1);
2117 size_rtx = GEN_INT (actual_fsize);
87ad11b0 2118
6d36483b 2119 /* Save RP first. The calling conventions manual states RP will
daee63dd 2120 always be stored into the caller's frame at sp-20. */
372ef038 2121 if (regs_ever_live[2] || profile_flag)
6d36483b 2122 store_reg (2, -20, STACK_POINTER_REGNUM);
2123
daee63dd 2124 /* Allocate the local frame and set up the frame pointer if needed. */
a1ab4fa3 2125 if (actual_fsize)
2126 if (frame_pointer_needed)
2127 {
daee63dd 2128 /* Copy the old frame pointer temporarily into %r1. Set up the
2129 new stack pointer, then store away the saved old frame pointer
2130 into the stack at sp+actual_fsize and at the same time update
2131 the stack pointer by actual_fsize bytes. Two versions, first
2132 handles small (<8k) frames. The second handles large (>8k)
2133 frames. */
2134 emit_move_insn (tmpreg, frame_pointer_rtx);
2135 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
a1ab4fa3 2136 if (VAL_14_BITS_P (actual_fsize))
daee63dd 2137 emit_insn (gen_post_stwm (stack_pointer_rtx,
2138 stack_pointer_rtx,
2139 size_rtx, tmpreg));
a1ab4fa3 2140 else
2141 {
b75ad75e 2142 /* It is incorrect to store the saved frame pointer at *sp,
2143 then increment sp (writes beyond the current stack boundary).
2144
2145 So instead use stwm to store at *sp and post-increment the
2146 stack pointer as an atomic operation. Then increment sp to
2147 finish allocating the new frame. */
2148 emit_insn (gen_post_stwm (stack_pointer_rtx,
2149 stack_pointer_rtx,
2150 GEN_INT (64), tmpreg));
daee63dd 2151 set_reg_plus_d (STACK_POINTER_REGNUM,
2152 STACK_POINTER_REGNUM,
b75ad75e 2153 actual_fsize - 64);
a1ab4fa3 2154 }
2155 }
daee63dd 2156 /* no frame pointer needed. */
a1ab4fa3 2157 else
a1ab4fa3 2158 {
daee63dd 2159 /* In some cases we can perform the first callee register save
2160 and allocating the stack frame at the same time. If so, just
2161 make a note of it and defer allocating the frame until saving
2162 the callee registers. */
6d36483b 2163 if (VAL_14_BITS_P (-actual_fsize)
2164 && local_fsize == 0
daee63dd 2165 && ! profile_flag
2166 && ! flag_pic)
afd7b680 2167 merge_sp_adjust_with_store = 1;
daee63dd 2168 /* Can not optimize. Adjust the stack frame by actual_fsize bytes. */
2169 else if (actual_fsize != 0)
2170 set_reg_plus_d (STACK_POINTER_REGNUM,
2171 STACK_POINTER_REGNUM,
2172 actual_fsize);
a1ab4fa3 2173 }
201f01e9 2174 /* The hppa calling conventions say that that %r19, the pic offset
daee63dd 2175 register, is saved at sp - 32 (in this function's frame) when
9f33c102 2176 generating PIC code. FIXME: What is the correct thing to do
2177 for functions which make no calls and allocate no frame? Do
2178 we need to allocate a frame, or can we just omit the save? For
2179 now we'll just omit the save. */
2180 if (actual_fsize != 0 && flag_pic)
6d36483b 2181 store_reg (PIC_OFFSET_TABLE_REGNUM, -32, STACK_POINTER_REGNUM);
daee63dd 2182
2183 /* Profiling code.
372ef038 2184
daee63dd 2185 Instead of taking one argument, the counter label, as most normal
2186 mcounts do, _mcount appears to behave differently on the HPPA. It
6d36483b 2187 takes the return address of the caller, the address of this routine,
2188 and the address of the label. Also, it isn't magic, so
daee63dd 2189 argument registre hsave to be preserved. */
372ef038 2190 if (profile_flag)
2191 {
daee63dd 2192 int pc_offset, i, arg_offset, basereg, offsetadj;
2193
2194 pc_offset = 4 + (frame_pointer_needed
2195 ? (VAL_14_BITS_P (actual_fsize) ? 12 : 20)
2196 : (VAL_14_BITS_P (actual_fsize) ? 4 : 8));
2197
2198 /* When the function has a frame pointer, use it as the base
2199 register for saving/restore registers. Else use the stack
2200 pointer. Adjust the offset according to the frame size if
2201 this function does not have a frame pointer. */
d2daf090 2202
2203 basereg = frame_pointer_needed ? FRAME_POINTER_REGNUM
2204 : STACK_POINTER_REGNUM;
2205 offsetadj = frame_pointer_needed ? 0 : actual_fsize;
2206
daee63dd 2207 /* Horrid hack. emit_function_prologue will modify this RTL in
2208 place to get the expected results. sprintf here is just to
2209 put something in the name. */
2210 sprintf(hp_profile_label_name, "LP$%04d", -1);
2211 hp_profile_label_rtx = gen_rtx (SYMBOL_REF, SImode,
2212 hp_profile_label_name);
d6f01525 2213 if (current_function_returns_struct)
daee63dd 2214 store_reg (STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg);
2215
d2daf090 2216 for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
daee63dd 2217 if (regs_ever_live [i])
372ef038 2218 {
daee63dd 2219 store_reg (i, arg_offset, basereg);
2220 /* Deal with arg_offset not fitting in 14 bits. */
d2daf090 2221 pc_offset += VAL_14_BITS_P (arg_offset) ? 4 : 8;
372ef038 2222 }
daee63dd 2223
2224 emit_move_insn (gen_rtx (REG, SImode, 26), gen_rtx (REG, SImode, 2));
2225 emit_move_insn (tmpreg, gen_rtx (HIGH, SImode, hp_profile_label_rtx));
2226 emit_move_insn (gen_rtx (REG, SImode, 24),
2227 gen_rtx (LO_SUM, SImode, tmpreg, hp_profile_label_rtx));
2228 /* %r25 is set from within the output pattern. */
2229 emit_insn (gen_call_profiler (GEN_INT (- pc_offset - 20)));
2230
2231 /* Restore argument registers. */
d2daf090 2232 for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
daee63dd 2233 if (regs_ever_live [i])
2234 load_reg (i, arg_offset, basereg);
2235
d6f01525 2236 if (current_function_returns_struct)
daee63dd 2237 load_reg (STRUCT_VALUE_REGNUM, -12 - offsetadj, basereg);
2238
372ef038 2239 }
2240
6d36483b 2241 /* Normal register save.
daee63dd 2242
2243 Do not save the frame pointer in the frame_pointer_needed case. It
2244 was done earlier. */
87ad11b0 2245 if (frame_pointer_needed)
2246 {
df0651dc 2247 for (i = 18, offset = local_fsize; i >= 4; i--)
2248 if (regs_ever_live[i] && ! call_used_regs[i])
87ad11b0 2249 {
6d36483b 2250 store_reg (i, offset, FRAME_POINTER_REGNUM);
daee63dd 2251 offset += 4;
a9960cdc 2252 gr_saved++;
87ad11b0 2253 }
9b0c95be 2254 /* Account for %r4 which is saved in a special place. */
2255 gr_saved++;
87ad11b0 2256 }
daee63dd 2257 /* No frame pointer needed. */
87ad11b0 2258 else
2259 {
daee63dd 2260 for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
87ad11b0 2261 if (regs_ever_live[i] && ! call_used_regs[i])
2262 {
6d36483b 2263 /* If merge_sp_adjust_with_store is nonzero, then we can
afd7b680 2264 optimize the first GR save. */
201f01e9 2265 if (merge_sp_adjust_with_store)
afd7b680 2266 {
2267 merge_sp_adjust_with_store = 0;
daee63dd 2268 emit_insn (gen_post_stwm (stack_pointer_rtx,
2269 stack_pointer_rtx,
2270 GEN_INT (-offset),
2271 gen_rtx (REG, SImode, i)));
afd7b680 2272 }
2273 else
daee63dd 2274 store_reg (i, offset, STACK_POINTER_REGNUM);
2275 offset += 4;
a9960cdc 2276 gr_saved++;
87ad11b0 2277 }
daee63dd 2278
afd7b680 2279 /* If we wanted to merge the SP adjustment with a GR save, but we never
daee63dd 2280 did any GR saves, then just emit the adjustment here. */
201f01e9 2281 if (merge_sp_adjust_with_store)
daee63dd 2282 set_reg_plus_d (STACK_POINTER_REGNUM,
2283 STACK_POINTER_REGNUM,
2284 actual_fsize);
87ad11b0 2285 }
6d36483b 2286
87ad11b0 2287 /* Align pointer properly (doubleword boundary). */
2288 offset = (offset + 7) & ~7;
2289
2290 /* Floating point register store. */
2291 if (save_fregs)
87ad11b0 2292 {
daee63dd 2293
2294 /* First get the frame or stack pointer to the start of the FP register
2295 save area. */
a1ab4fa3 2296 if (frame_pointer_needed)
daee63dd 2297 set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
a1ab4fa3 2298 else
daee63dd 2299 set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
2300
2301 /* Now actually save the FP registers. */
df0651dc 2302 for (i = 66; i >= 48; i -= 2)
2303 if (regs_ever_live[i] || regs_ever_live[i + 1])
2304 {
2305 emit_move_insn (gen_rtx (MEM, DFmode,
2306 gen_rtx (POST_INC, DFmode, tmpreg)),
2307 gen_rtx (REG, DFmode, i));
2308 fr_saved++;
2309 }
87ad11b0 2310 }
2311}
2312
daee63dd 2313
87ad11b0 2314void
a1ab4fa3 2315output_function_epilogue (file, size)
87ad11b0 2316 FILE *file;
2317 int size;
87ad11b0 2318{
3695c664 2319
2320 rtx insn = get_last_insn ();
2321
daee63dd 2322 /* hppa_expand_epilogue does the dirty work now. We just need
2323 to output the assembler directives which denote the end
3695c664 2324 of a function.
2325
2326 To make debuggers happy, emit a nop if the epilogue was completely
2327 eliminated due to a volatile call as the last insn in the
6d36483b 2328 current function. That way the return address (in %r2) will
3695c664 2329 always point to a valid instruction in the current function. */
2330
2331 /* Get the last real insn. */
2332 if (GET_CODE (insn) == NOTE)
2333 insn = prev_real_insn (insn);
2334
2335 /* If it is a sequence, then look inside. */
2336 if (insn && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
2337 insn = XVECEXP (PATTERN (insn), 0, 0);
2338
6d36483b 2339 /* If insn is a CALL_INSN, then it must be a call to a volatile
3695c664 2340 function (otherwise there would be epilogue insns). */
2341 if (insn && GET_CODE (insn) == CALL_INSN)
2342 fprintf (file, "\tnop\n");
6d36483b 2343
daee63dd 2344 fprintf (file, "\t.EXIT\n\t.PROCEND\n");
2345}
afd7b680 2346
daee63dd 2347void
3695c664 2348hppa_expand_epilogue ()
daee63dd 2349{
6d36483b 2350 rtx tmpreg;
daee63dd 2351 int offset,i;
2352 int merge_sp_adjust_with_load = 0;
2353
2354 /* We will use this often. */
2355 tmpreg = gen_rtx (REG, SImode, 1);
2356
2357 /* Try to restore RP early to avoid load/use interlocks when
2358 RP gets used in the return (bv) instruction. This appears to still
2359 be necessary even when we schedule the prologue and epilogue. */
afd7b680 2360 if (frame_pointer_needed
2361 && (regs_ever_live [2] || profile_flag))
daee63dd 2362 load_reg (2, -20, FRAME_POINTER_REGNUM);
87ad11b0 2363
daee63dd 2364 /* No frame pointer, and stack is smaller than 8k. */
2365 else if (! frame_pointer_needed
2366 && VAL_14_BITS_P (actual_fsize + 20)
2367 && (regs_ever_live[2] || profile_flag))
2368 load_reg (2, - (actual_fsize + 20), STACK_POINTER_REGNUM);
2369
2370 /* General register restores. */
87ad11b0 2371 if (frame_pointer_needed)
2372 {
df0651dc 2373 for (i = 18, offset = local_fsize; i >= 4; i--)
2374 if (regs_ever_live[i] && ! call_used_regs[i])
87ad11b0 2375 {
daee63dd 2376 load_reg (i, offset, FRAME_POINTER_REGNUM);
2377 offset += 4;
87ad11b0 2378 }
87ad11b0 2379 }
2380 else
2381 {
daee63dd 2382 for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
2383 if (regs_ever_live[i] && ! call_used_regs[i])
87ad11b0 2384 {
daee63dd 2385 /* Only for the first load.
2386 merge_sp_adjust_with_load holds the register load
2387 with which we will merge the sp adjustment. */
afd7b680 2388 if (VAL_14_BITS_P (actual_fsize + 20)
2389 && local_fsize == 0
afd7b680 2390 && ! merge_sp_adjust_with_load)
2391 merge_sp_adjust_with_load = i;
daee63dd 2392 else
2393 load_reg (i, offset, STACK_POINTER_REGNUM);
2394 offset += 4;
87ad11b0 2395 }
87ad11b0 2396 }
daee63dd 2397
87ad11b0 2398 /* Align pointer properly (doubleword boundary). */
2399 offset = (offset + 7) & ~7;
2400
daee63dd 2401 /* FP register restores. */
87ad11b0 2402 if (save_fregs)
87ad11b0 2403 {
daee63dd 2404 /* Adjust the register to index off of. */
a1ab4fa3 2405 if (frame_pointer_needed)
daee63dd 2406 set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
a1ab4fa3 2407 else
daee63dd 2408 set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
2409
2410 /* Actually do the restores now. */
df0651dc 2411 for (i = 66; i >= 48; i -= 2)
2412 if (regs_ever_live[i] || regs_ever_live[i + 1])
2413 emit_move_insn (gen_rtx (REG, DFmode, i),
2414 gen_rtx (MEM, DFmode,
2415 gen_rtx (POST_INC, DFmode, tmpreg)));
87ad11b0 2416 }
daee63dd 2417
2418 /* No frame pointer, but we have a stack greater than 8k. We restore
1921d762 2419 %r2 very late in this case. (All other cases are restored as early
2420 as possible.) */
daee63dd 2421 if (! frame_pointer_needed
2422 && ! VAL_14_BITS_P (actual_fsize + 20)
2423 && (regs_ever_live[2] || profile_flag))
87ad11b0 2424 {
daee63dd 2425 set_reg_plus_d (STACK_POINTER_REGNUM,
2426 STACK_POINTER_REGNUM,
2427 - actual_fsize);
2428 /* Uses value left over in %r1 by set_reg_plus_d. */
2429 load_reg (2, - (actual_fsize + 20 + ((- actual_fsize) & ~0x7ff)), 1);
87ad11b0 2430 }
daee63dd 2431
2432 /* Reset stack pointer (and possibly frame pointer). The stack */
2433 /* pointer is initially set to fp + 64 to avoid a race condition.
2434 ??? What race condition?!? */
2435 else if (frame_pointer_needed)
87ad11b0 2436 {
e03010ce 2437 /* Emit a blockage insn here to keep these insns from being moved
2438 to the beginning of the prologue or into the main instruction
2439 stream, doing so avoids some very obscure problems. */
2440 emit_insn (gen_blockage ());
daee63dd 2441 set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
2442 emit_insn (gen_pre_ldwm (stack_pointer_rtx, stack_pointer_rtx,
2443 GEN_INT (-64), frame_pointer_rtx));
87ad11b0 2444 }
daee63dd 2445 /* If we were deferring a callee register restore, do it now. */
2446 else if (! frame_pointer_needed && merge_sp_adjust_with_load)
2447 emit_insn (gen_pre_ldwm (stack_pointer_rtx,
2448 stack_pointer_rtx,
2449 GEN_INT (- actual_fsize),
6d36483b 2450 gen_rtx (REG, SImode,
daee63dd 2451 merge_sp_adjust_with_load)));
2452 else if (actual_fsize != 0)
2453 set_reg_plus_d (STACK_POINTER_REGNUM,
2454 STACK_POINTER_REGNUM,
2455 - actual_fsize);
87ad11b0 2456}
2457
757d4970 2458/* This is only valid once reload has completed because it depends on
2459 knowing exactly how much (if any) frame there is and...
2460
2461 It's only valid if there is no frame marker to de-allocate and...
2462
2463 It's only valid if %r2 hasn't been saved into the caller's frame
2464 (we're not profiling and %r2 isn't live anywhere). */
2465int
2466hppa_can_use_return_insn_p ()
2467{
2468 return (reload_completed
2469 && (compute_frame_size (get_frame_size (), 0) ? 0 : 1)
2470 && ! profile_flag
2471 && ! regs_ever_live[2]
2472 && ! frame_pointer_needed);
2473}
2474
87ad11b0 2475void
2476emit_bcond_fp (code, operand0)
2477 enum rtx_code code;
2478 rtx operand0;
2479{
2480 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2481 gen_rtx (IF_THEN_ELSE, VOIDmode,
6d36483b 2482 gen_rtx (code, VOIDmode,
87ad11b0 2483 gen_rtx (REG, CCFPmode, 0),
2484 const0_rtx),
2485 gen_rtx (LABEL_REF, VOIDmode, operand0),
2486 pc_rtx)));
2487
2488}
2489
2490rtx
2491gen_cmp_fp (code, operand0, operand1)
2492 enum rtx_code code;
2493 rtx operand0, operand1;
2494{
2495 return gen_rtx (SET, VOIDmode, gen_rtx (REG, CCFPmode, 0),
2496 gen_rtx (code, CCFPmode, operand0, operand1));
2497}
2498
8b49b3c7 2499/* Adjust the cost of a scheduling dependency. Return the new cost of
2500 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2501
2502int
2503pa_adjust_cost (insn, link, dep_insn, cost)
2504 rtx insn;
2505 rtx link;
2506 rtx dep_insn;
2507 int cost;
2508{
d402da4b 2509 if (! recog_memoized (insn))
2510 return 0;
8b49b3c7 2511
2512 if (REG_NOTE_KIND (link) == 0)
2513 {
2514 /* Data dependency; DEP_INSN writes a register that INSN reads some
2515 cycles later. */
2516
2517 if (get_attr_type (insn) == TYPE_FPSTORE)
2518 {
d402da4b 2519 rtx pat = PATTERN (insn);
2520 rtx dep_pat = PATTERN (dep_insn);
2521 if (GET_CODE (pat) == PARALLEL)
2522 {
2523 /* This happens for the fstXs,mb patterns. */
2524 pat = XVECEXP (pat, 0, 0);
2525 }
2526 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
8b49b3c7 2527 /* If this happens, we have to extend this to schedule
d402da4b 2528 optimally. Return 0 for now. */
2529 return 0;
8b49b3c7 2530
d402da4b 2531 if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
8b49b3c7 2532 {
d402da4b 2533 if (! recog_memoized (dep_insn))
2534 return 0;
2535 /* DEP_INSN is writing its result to the register
2536 being stored in the fpstore INSN. */
8b49b3c7 2537 switch (get_attr_type (dep_insn))
2538 {
2539 case TYPE_FPLOAD:
134b4858 2540 /* This cost 3 cycles, not 2 as the md says for the
2541 700 and 7100. Note scaling of cost for 7100. */
2542 return cost + (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
8b49b3c7 2543
2544 case TYPE_FPALU:
134b4858 2545 case TYPE_FPMULSGL:
2546 case TYPE_FPMULDBL:
8b49b3c7 2547 case TYPE_FPDIVSGL:
2548 case TYPE_FPDIVDBL:
2549 case TYPE_FPSQRTSGL:
2550 case TYPE_FPSQRTDBL:
2551 /* In these important cases, we save one cycle compared to
2552 when flop instruction feed each other. */
134b4858 2553 return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
8b49b3c7 2554
2555 default:
2556 return cost;
2557 }
2558 }
2559 }
2560
2561 /* For other data dependencies, the default cost specified in the
2562 md is correct. */
2563 return cost;
2564 }
2565 else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
2566 {
2567 /* Anti dependency; DEP_INSN reads a register that INSN writes some
2568 cycles later. */
2569
2570 if (get_attr_type (insn) == TYPE_FPLOAD)
2571 {
d402da4b 2572 rtx pat = PATTERN (insn);
2573 rtx dep_pat = PATTERN (dep_insn);
2574 if (GET_CODE (pat) == PARALLEL)
2575 {
2576 /* This happens for the fldXs,mb patterns. */
2577 pat = XVECEXP (pat, 0, 0);
2578 }
2579 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
8b49b3c7 2580 /* If this happens, we have to extend this to schedule
d402da4b 2581 optimally. Return 0 for now. */
2582 return 0;
8b49b3c7 2583
d402da4b 2584 if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
8b49b3c7 2585 {
d402da4b 2586 if (! recog_memoized (dep_insn))
2587 return 0;
8b49b3c7 2588 switch (get_attr_type (dep_insn))
2589 {
2590 case TYPE_FPALU:
134b4858 2591 case TYPE_FPMULSGL:
2592 case TYPE_FPMULDBL:
8b49b3c7 2593 case TYPE_FPDIVSGL:
2594 case TYPE_FPDIVDBL:
2595 case TYPE_FPSQRTSGL:
2596 case TYPE_FPSQRTDBL:
d402da4b 2597 /* A fpload can't be issued until one cycle before a
134b4858 2598 preceeding arithmetic operation has finished if
d402da4b 2599 the target of the fpload is any of the sources
2600 (or destination) of the arithmetic operation. */
134b4858 2601 return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
2602
2603 default:
2604 return 0;
2605 }
2606 }
2607 }
2608 else if (get_attr_type (insn) == TYPE_FPALU)
2609 {
2610 rtx pat = PATTERN (insn);
2611 rtx dep_pat = PATTERN (dep_insn);
2612 if (GET_CODE (pat) == PARALLEL)
2613 {
2614 /* This happens for the fldXs,mb patterns. */
2615 pat = XVECEXP (pat, 0, 0);
2616 }
2617 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
2618 /* If this happens, we have to extend this to schedule
2619 optimally. Return 0 for now. */
2620 return 0;
2621
2622 if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
2623 {
2624 if (! recog_memoized (dep_insn))
2625 return 0;
2626 switch (get_attr_type (dep_insn))
2627 {
2628 case TYPE_FPDIVSGL:
2629 case TYPE_FPDIVDBL:
2630 case TYPE_FPSQRTSGL:
2631 case TYPE_FPSQRTDBL:
2632 /* An ALU flop can't be issued until two cycles before a
2633 preceeding divide or sqrt operation has finished if
2634 the target of the ALU flop is any of the sources
2635 (or destination) of the divide or sqrt operation. */
2636 return cost - (pa_cpu_attr == PROCESSOR_700) ? 2 : 4;
8b49b3c7 2637
2638 default:
2639 return 0;
2640 }
2641 }
2642 }
2643
2644 /* For other anti dependencies, the cost is 0. */
2645 return 0;
2646 }
134b4858 2647 else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
2648 {
2649 /* Output dependency; DEP_INSN writes a register that INSN writes some
2650 cycles later. */
2651 if (get_attr_type (insn) == TYPE_FPLOAD)
2652 {
2653 rtx pat = PATTERN (insn);
2654 rtx dep_pat = PATTERN (dep_insn);
2655 if (GET_CODE (pat) == PARALLEL)
2656 {
2657 /* This happens for the fldXs,mb patterns. */
2658 pat = XVECEXP (pat, 0, 0);
2659 }
2660 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
2661 /* If this happens, we have to extend this to schedule
2662 optimally. Return 0 for now. */
2663 return 0;
2664
2665 if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
2666 {
2667 if (! recog_memoized (dep_insn))
2668 return 0;
2669 switch (get_attr_type (dep_insn))
2670 {
2671 case TYPE_FPALU:
2672 case TYPE_FPMULSGL:
2673 case TYPE_FPMULDBL:
2674 case TYPE_FPDIVSGL:
2675 case TYPE_FPDIVDBL:
2676 case TYPE_FPSQRTSGL:
2677 case TYPE_FPSQRTDBL:
2678 /* A fpload can't be issued until one cycle before a
2679 preceeding arithmetic operation has finished if
2680 the target of the fpload is the destination of the
2681 arithmetic operation. */
2682 return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
8b49b3c7 2683
134b4858 2684 default:
2685 return 0;
2686 }
2687 }
2688 }
2689 else if (get_attr_type (insn) == TYPE_FPALU)
2690 {
2691 rtx pat = PATTERN (insn);
2692 rtx dep_pat = PATTERN (dep_insn);
2693 if (GET_CODE (pat) == PARALLEL)
2694 {
2695 /* This happens for the fldXs,mb patterns. */
2696 pat = XVECEXP (pat, 0, 0);
2697 }
2698 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
2699 /* If this happens, we have to extend this to schedule
2700 optimally. Return 0 for now. */
2701 return 0;
2702
2703 if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
2704 {
2705 if (! recog_memoized (dep_insn))
2706 return 0;
2707 switch (get_attr_type (dep_insn))
2708 {
2709 case TYPE_FPDIVSGL:
2710 case TYPE_FPDIVDBL:
2711 case TYPE_FPSQRTSGL:
2712 case TYPE_FPSQRTDBL:
2713 /* An ALU flop can't be issued until two cycles before a
2714 preceeding divide or sqrt operation has finished if
2715 the target of the ALU flop is also the target of
2716 of the divide or sqrt operation. */
2717 return cost - (pa_cpu_attr == PROCESSOR_700) ? 2 : 4;
2718
2719 default:
2720 return 0;
2721 }
2722 }
2723 }
2724
2725 /* For other output dependencies, the cost is 0. */
2726 return 0;
2727 }
2728 else
2729 abort ();
8b49b3c7 2730}
87ad11b0 2731
58e17b0b 2732/* Return any length adjustment needed by INSN which already has its length
6d36483b 2733 computed as LENGTH. Return zero if no adjustment is necessary.
58e17b0b 2734
5fbd5940 2735 For the PA: function calls, millicode calls, and backwards short
6d36483b 2736 conditional branches with unfilled delay slots need an adjustment by +1
5fbd5940 2737 (to account for the NOP which will be inserted into the instruction stream).
58e17b0b 2738
2739 Also compute the length of an inline block move here as it is too
5fbd5940 2740 complicated to express as a length attribute in pa.md. */
58e17b0b 2741int
2742pa_adjust_insn_length (insn, length)
2743 rtx insn;
2744 int length;
2745{
2746 rtx pat = PATTERN (insn);
2747
5fbd5940 2748 /* Call insns which are *not* indirect and have unfilled delay slots. */
58e17b0b 2749 if (GET_CODE (insn) == CALL_INSN)
5fbd5940 2750 {
2751
2752 if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL
2753 && GET_CODE (XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)) == SYMBOL_REF)
5a1231ef 2754 return 4;
5fbd5940 2755 else if (GET_CODE (XVECEXP (pat, 0, 0)) == SET
2756 && GET_CODE (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0))
2757 == SYMBOL_REF)
5a1231ef 2758 return 4;
5fbd5940 2759 else
2760 return 0;
2761 }
58e17b0b 2762 /* Millicode insn with an unfilled delay slot. */
2763 else if (GET_CODE (insn) == INSN
2764 && GET_CODE (pat) != SEQUENCE
2765 && GET_CODE (pat) != USE
2766 && GET_CODE (pat) != CLOBBER
2767 && get_attr_type (insn) == TYPE_MILLI)
5a1231ef 2768 return 4;
58e17b0b 2769 /* Block move pattern. */
2770 else if (GET_CODE (insn) == INSN
2771 && GET_CODE (pat) == PARALLEL
2772 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM
2773 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 1)) == MEM
2774 && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode
2775 && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode)
5a1231ef 2776 return compute_movstrsi_length (insn) - 4;
58e17b0b 2777 /* Conditional branch with an unfilled delay slot. */
5fbd5940 2778 else if (GET_CODE (insn) == JUMP_INSN && ! simplejump_p (insn))
2779 {
2780 /* Adjust a short backwards conditional with an unfilled delay slot. */
2781 if (GET_CODE (pat) == SET
5a1231ef 2782 && length == 4
5fbd5940 2783 && ! forward_branch_p (insn))
5a1231ef 2784 return 4;
5fbd5940 2785 /* Adjust dbra insn with short backwards conditional branch with
6d36483b 2786 unfilled delay slot -- only for case where counter is in a
29a4502c 2787 general register register. */
5fbd5940 2788 else if (GET_CODE (pat) == PARALLEL
2789 && GET_CODE (XVECEXP (pat, 0, 1)) == SET
2790 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == REG
6d36483b 2791 && ! FP_REG_P (XEXP (XVECEXP (pat, 0, 1), 0))
5a1231ef 2792 && length == 4
5fbd5940 2793 && ! forward_branch_p (insn))
5a1231ef 2794 return 4;
5fbd5940 2795 else
2796 return 0;
2797 }
58e17b0b 2798 else
2799 return 0;
2800}
2801
87ad11b0 2802/* Print operand X (an rtx) in assembler syntax to file FILE.
2803 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
2804 For `%' followed by punctuation, CODE is the punctuation and X is null. */
2805
2806void
2807print_operand (file, x, code)
2808 FILE *file;
2809 rtx x;
2810 int code;
2811{
2812 switch (code)
2813 {
2814 case '#':
2815 /* Output a 'nop' if there's nothing for the delay slot. */
2816 if (dbr_sequence_length () == 0)
2817 fputs ("\n\tnop", file);
2818 return;
2819 case '*':
2820 /* Output an nullification completer if there's nothing for the */
6d36483b 2821 /* delay slot or nullification is requested. */
87ad11b0 2822 if (dbr_sequence_length () == 0 ||
2823 (final_sequence &&
2824 INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))))
2825 fputs (",n", file);
2826 return;
2827 case 'R':
2828 /* Print out the second register name of a register pair.
2829 I.e., R (6) => 7. */
2830 fputs (reg_names[REGNO (x)+1], file);
2831 return;
2832 case 'r':
2833 /* A register or zero. */
891b55b4 2834 if (x == const0_rtx
2835 || (x == CONST0_RTX (DFmode))
2836 || (x == CONST0_RTX (SFmode)))
87ad11b0 2837 {
2838 fputs ("0", file);
2839 return;
2840 }
2841 else
2842 break;
c8975385 2843 case 'C': /* Plain (C)ondition */
87ad11b0 2844 case 'X':
2845 switch (GET_CODE (x))
6d36483b 2846 {
87ad11b0 2847 case EQ:
2848 fprintf (file, "="); break;
2849 case NE:
9d887bf4 2850 fprintf (file, "<>"); break;
87ad11b0 2851 case GT:
2852 fprintf (file, ">"); break;
2853 case GE:
2854 fprintf (file, ">="); break;
2855 case GEU:
2856 fprintf (file, ">>="); break;
2857 case GTU:
2858 fprintf (file, ">>"); break;
2859 case LT:
2860 fprintf (file, "<"); break;
2861 case LE:
2862 fprintf (file, "<="); break;
2863 case LEU:
2864 fprintf (file, "<<="); break;
2865 case LTU:
2866 fprintf (file, "<<"); break;
2867 default:
87ad11b0 2868 abort ();
2869 }
2870 return;
c8975385 2871 case 'N': /* Condition, (N)egated */
87ad11b0 2872 switch (GET_CODE (x))
2873 {
2874 case EQ:
9d887bf4 2875 fprintf (file, "<>"); break;
87ad11b0 2876 case NE:
2877 fprintf (file, "="); break;
2878 case GT:
2879 fprintf (file, "<="); break;
2880 case GE:
2881 fprintf (file, "<"); break;
2882 case GEU:
2883 fprintf (file, "<<"); break;
2884 case GTU:
2885 fprintf (file, "<<="); break;
2886 case LT:
2887 fprintf (file, ">="); break;
2888 case LE:
2889 fprintf (file, ">"); break;
2890 case LEU:
2891 fprintf (file, ">>"); break;
2892 case LTU:
2893 fprintf (file, ">>="); break;
2894 default:
87ad11b0 2895 abort ();
2896 }
2897 return;
61230bc9 2898 /* For floating point comparisons. Need special conditions to deal
2899 with NaNs properly. */
2900 case 'Y':
2901 switch (GET_CODE (x))
2902 {
2903 case EQ:
2904 fprintf (file, "!="); break;
2905 case NE:
2906 fprintf (file, "="); break;
2907 case GT:
2908 fprintf (file, "!>"); break;
2909 case GE:
2910 fprintf (file, "!>="); break;
2911 case LT:
2912 fprintf (file, "!<"); break;
2913 case LE:
2914 fprintf (file, "!<="); break;
2915 default:
61230bc9 2916 abort ();
2917 }
2918 return;
c8975385 2919 case 'S': /* Condition, operands are (S)wapped. */
2920 switch (GET_CODE (x))
2921 {
2922 case EQ:
2923 fprintf (file, "="); break;
2924 case NE:
2925 fprintf (file, "<>"); break;
2926 case GT:
2927 fprintf (file, "<"); break;
2928 case GE:
2929 fprintf (file, "<="); break;
2930 case GEU:
2931 fprintf (file, "<<="); break;
2932 case GTU:
2933 fprintf (file, "<<"); break;
2934 case LT:
2935 fprintf (file, ">"); break;
2936 case LE:
2937 fprintf (file, ">="); break;
2938 case LEU:
2939 fprintf (file, ">>="); break;
2940 case LTU:
2941 fprintf (file, ">>"); break;
2942 default:
c8975385 2943 abort ();
6d36483b 2944 }
c8975385 2945 return;
2946 case 'B': /* Condition, (B)oth swapped and negate. */
2947 switch (GET_CODE (x))
2948 {
2949 case EQ:
2950 fprintf (file, "<>"); break;
2951 case NE:
2952 fprintf (file, "="); break;
2953 case GT:
2954 fprintf (file, ">="); break;
2955 case GE:
2956 fprintf (file, ">"); break;
2957 case GEU:
2958 fprintf (file, ">>"); break;
2959 case GTU:
2960 fprintf (file, ">>="); break;
2961 case LT:
2962 fprintf (file, "<="); break;
2963 case LE:
2964 fprintf (file, "<"); break;
2965 case LEU:
2966 fprintf (file, "<<"); break;
2967 case LTU:
2968 fprintf (file, "<<="); break;
2969 default:
c8975385 2970 abort ();
6d36483b 2971 }
c8975385 2972 return;
2973 case 'k':
2974 if (GET_CODE (x) == CONST_INT)
2975 {
2976 fprintf (file, "%d", ~INTVAL (x));
2977 return;
2978 }
2979 abort();
e5965947 2980 case 'L':
2981 if (GET_CODE (x) == CONST_INT)
2982 {
2983 fprintf (file, "%d", 32 - (INTVAL (x) & 31));
2984 return;
2985 }
2986 abort();
3a16146d 2987 case 'O':
2988 if (GET_CODE (x) == CONST_INT && exact_log2 (INTVAL (x)) >= 0)
2989 {
2990 fprintf (file, "%d", exact_log2 (INTVAL (x)));
2991 return;
2992 }
2993 abort();
e5965947 2994 case 'P':
2995 if (GET_CODE (x) == CONST_INT)
2996 {
2997 fprintf (file, "%d", 31 - (INTVAL (x) & 31));
2998 return;
2999 }
3000 abort();
c8975385 3001 case 'I':
3002 if (GET_CODE (x) == CONST_INT)
3003 fputs ("i", file);
3004 return;
87ad11b0 3005 case 'M':
3006 switch (GET_CODE (XEXP (x, 0)))
3007 {
3008 case PRE_DEC:
3009 case PRE_INC:
3010 fprintf (file, "s,mb");
3011 break;
3012 case POST_DEC:
3013 case POST_INC:
3014 fprintf (file, "s,ma");
3015 break;
3016 default:
3017 break;
3018 }
3019 return;
3020 case 'F':
3021 switch (GET_CODE (XEXP (x, 0)))
3022 {
3023 case PRE_DEC:
3024 case PRE_INC:
3025 fprintf (file, ",mb");
3026 break;
3027 case POST_DEC:
3028 case POST_INC:
3029 fprintf (file, ",ma");
3030 break;
3031 default:
3032 break;
3033 }
3034 return;
3035 case 'G':
3036 output_global_address (file, x);
3037 return;
3038 case 0: /* Don't do anything special */
3039 break;
42faba01 3040 case 'Z':
3041 {
3042 unsigned op[3];
3043 compute_zdepi_operands (INTVAL (x), op);
3044 fprintf (file, "%d,%d,%d", op[0], op[1], op[2]);
3045 return;
3046 }
87ad11b0 3047 default:
3048 abort ();
3049 }
3050 if (GET_CODE (x) == REG)
df0651dc 3051 {
3052 if (FP_REG_P (x) && GET_MODE_SIZE (GET_MODE (x)) <= 4 && (REGNO (x) & 1) == 0)
3053 fprintf (file, "%sL", reg_names [REGNO (x)]);
3054 else
3055 fprintf (file, "%s", reg_names [REGNO (x)]);
3056 }
87ad11b0 3057 else if (GET_CODE (x) == MEM)
3058 {
3059 int size = GET_MODE_SIZE (GET_MODE (x));
3060 rtx base = XEXP (XEXP (x, 0), 0);
3061 switch (GET_CODE (XEXP (x, 0)))
3062 {
3063 case PRE_DEC:
3064 case POST_DEC:
3065 fprintf (file, "-%d(0,%s)", size, reg_names [REGNO (base)]);
3066 break;
3067 case PRE_INC:
3068 case POST_INC:
3069 fprintf (file, "%d(0,%s)", size, reg_names [REGNO (base)]);
3070 break;
3071 default:
3072 output_address (XEXP (x, 0));
3073 break;
3074 }
3075 }
94c4f260 3076#if 0
3077 /* The code here is completely wrong. It attempts to extract parts of
3078 a CONST_DOUBLE which is wrong since REAL_ARITHMETIC is defined, and it
3079 extracts the wrong indices (0 instead of 2 and 1 instead of 3) using
3080 the wrong macro (XINT instead of XWINT).
3081 Just disable it for now, since the code will never be used anyway! */
87ad11b0 3082 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
3083 {
3084 union { double d; int i[2]; } u;
3085 union { float f; int i; } u1;
3086 u.i[0] = XINT (x, 0); u.i[1] = XINT (x, 1);
3087 u1.f = u.d;
3088 if (code == 'f')
3089 fprintf (file, "0r%.9g", u1.f);
3090 else
3091 fprintf (file, "0x%x", u1.i);
3092 }
6c640a06 3093 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
87ad11b0 3094 {
3095 union { double d; int i[2]; } u;
3096 u.i[0] = XINT (x, 0); u.i[1] = XINT (x, 1);
3097 fprintf (file, "0r%.20g", u.d);
3098 }
94c4f260 3099#endif
87ad11b0 3100 else
3101 output_addr_const (file, x);
3102}
3103
3104/* output a SYMBOL_REF or a CONST expression involving a SYMBOL_REF. */
3105
3106void
3107output_global_address (file, x)
3108 FILE *file;
3109 rtx x;
3110{
2ee034bc 3111
3112 /* Imagine (high (const (plus ...))). */
3113 if (GET_CODE (x) == HIGH)
3114 x = XEXP (x, 0);
3115
87ad11b0 3116 if (GET_CODE (x) == SYMBOL_REF && read_only_operand (x))
3117 assemble_name (file, XSTR (x, 0));
b4a7bf10 3118 else if (GET_CODE (x) == SYMBOL_REF && !flag_pic)
87ad11b0 3119 {
3120 assemble_name (file, XSTR (x, 0));
3121 fprintf (file, "-$global$");
3122 }
3123 else if (GET_CODE (x) == CONST)
3124 {
3125 char *sep = "";
3126 int offset = 0; /* assembler wants -$global$ at end */
3127 rtx base;
6d36483b 3128
87ad11b0 3129 if (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
3130 {
3131 base = XEXP (XEXP (x, 0), 0);
3132 output_addr_const (file, base);
3133 }
3134 else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == CONST_INT)
3135 offset = INTVAL (XEXP (XEXP (x, 0), 0));
3136 else abort ();
3137
3138 if (GET_CODE (XEXP (XEXP (x, 0), 1)) == SYMBOL_REF)
3139 {
3140 base = XEXP (XEXP (x, 0), 1);
3141 output_addr_const (file, base);
3142 }
3143 else if (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
3144 offset = INTVAL (XEXP (XEXP (x, 0),1));
3145 else abort ();
3146
3147 if (GET_CODE (XEXP (x, 0)) == PLUS)
3148 {
3149 if (offset < 0)
3150 {
3151 offset = -offset;
3152 sep = "-";
3153 }
3154 else
3155 sep = "+";
3156 }
3157 else if (GET_CODE (XEXP (x, 0)) == MINUS
3158 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF))
3159 sep = "-";
3160 else abort ();
3161
b4a7bf10 3162 if (!read_only_operand (base) && !flag_pic)
87ad11b0 3163 fprintf (file, "-$global$");
3164 fprintf (file, "%s", sep);
3165 if (offset) fprintf (file,"%d", offset);
3166 }
3167 else
3168 output_addr_const (file, x);
3169}
3170
87ad11b0 3171/* HP's millicode routines mean something special to the assembler.
3172 Keep track of which ones we have used. */
3173
3174enum millicodes { remI, remU, divI, divU, mulI, mulU, end1000 };
3175static char imported[(int)end1000];
3176static char *milli_names[] = {"remI", "remU", "divI", "divU", "mulI", "mulU"};
3177static char import_string[] = ".IMPORT $$....,MILLICODE";
3178#define MILLI_START 10
3179
57ed30e5 3180static void
87ad11b0 3181import_milli (code)
3182 enum millicodes code;
3183{
3184 char str[sizeof (import_string)];
6d36483b 3185
87ad11b0 3186 if (!imported[(int)code])
3187 {
3188 imported[(int)code] = 1;
3189 strcpy (str, import_string);
3190 strncpy (str + MILLI_START, milli_names[(int)code], 4);
3191 output_asm_insn (str, 0);
3192 }
3193}
3194
6d36483b 3195/* The register constraints have put the operands and return value in
87ad11b0 3196 the proper registers. */
3197
3198char *
d6686e21 3199output_mul_insn (unsignedp, insn)
87ad11b0 3200 int unsignedp;
d6686e21 3201 rtx insn;
87ad11b0 3202{
d6686e21 3203
87ad11b0 3204 if (unsignedp)
3205 {
3206 import_milli (mulU);
d6686e21 3207 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$mulU"),
3208 gen_rtx (REG, SImode, 31));
87ad11b0 3209 }
3210 else
3211 {
3212 import_milli (mulI);
d6686e21 3213 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$mulI"),
3214 gen_rtx (REG, SImode, 31));
87ad11b0 3215 }
3216}
3217
3218/* If operands isn't NULL, then it's a CONST_INT with which we can do
3219 something */
3220
3221
3222/* Emit the rtl for doing a division by a constant. */
3223
3224 /* Do magic division millicodes exist for this value? */
3225
3226static int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
3227 1, 1};
3228
6d36483b 3229/* We'll use an array to keep track of the magic millicodes and
87ad11b0 3230 whether or not we've used them already. [n][0] is signed, [n][1] is
3231 unsigned. */
3232
87ad11b0 3233static int div_milli[16][2];
3234
3235int
3236div_operand (op, mode)
3237 rtx op;
3238 enum machine_mode mode;
3239{
3240 return (mode == SImode
3241 && ((GET_CODE (op) == REG && REGNO (op) == 25)
3242 || (GET_CODE (op) == CONST_INT && INTVAL (op) > 0
3243 && INTVAL (op) < 16 && magic_milli[INTVAL (op)])));
3244}
3245
3246int
3247emit_hpdiv_const (operands, unsignedp)
3248 rtx *operands;
3249 int unsignedp;
3250{
3251 if (GET_CODE (operands[2]) == CONST_INT
3252 && INTVAL (operands[2]) > 0
3253 && INTVAL (operands[2]) < 16
3254 && magic_milli[INTVAL (operands[2])])
3255 {
3256 emit_move_insn ( gen_rtx (REG, SImode, 26), operands[1]);
3257 emit
3258 (gen_rtx
3259 (PARALLEL, VOIDmode,
3260 gen_rtvec (5, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29),
3261 gen_rtx (unsignedp ? UDIV : DIV, SImode,
3262 gen_rtx (REG, SImode, 26),
3263 operands[2])),
33bd7237 3264 gen_rtx (CLOBBER, VOIDmode, operands[3]),
87ad11b0 3265 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)),
3266 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)),
3267 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31)))));
3268 emit_move_insn (operands[0], gen_rtx (REG, SImode, 29));
3269 return 1;
3270 }
3271 return 0;
3272}
3273
3274char *
d6686e21 3275output_div_insn (operands, unsignedp, insn)
87ad11b0 3276 rtx *operands;
3277 int unsignedp;
d6686e21 3278 rtx insn;
87ad11b0 3279{
3280 int divisor;
6d36483b 3281
3282 /* If the divisor is a constant, try to use one of the special
87ad11b0 3283 opcodes .*/
3284 if (GET_CODE (operands[0]) == CONST_INT)
3285 {
d6686e21 3286 static char buf[100];
87ad11b0 3287 divisor = INTVAL (operands[0]);
3288 if (!div_milli[divisor][unsignedp])
3289 {
d6686e21 3290 div_milli[divisor][unsignedp] = 1;
87ad11b0 3291 if (unsignedp)
3292 output_asm_insn (".IMPORT $$divU_%0,MILLICODE", operands);
3293 else
3294 output_asm_insn (".IMPORT $$divI_%0,MILLICODE", operands);
87ad11b0 3295 }
3296 if (unsignedp)
d6686e21 3297 {
3298 sprintf (buf, "$$divU_%d", INTVAL (operands[0]));
3299 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, buf),
3300 gen_rtx (REG, SImode, 31));
3301 }
3302 else
3303 {
3304 sprintf (buf, "$$divI_%d", INTVAL (operands[0]));
3305 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, buf),
3306 gen_rtx (REG, SImode, 31));
3307 }
87ad11b0 3308 }
3309 /* Divisor isn't a special constant. */
3310 else
3311 {
3312 if (unsignedp)
3313 {
3314 import_milli (divU);
d6686e21 3315 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$divU"),
3316 gen_rtx (REG, SImode, 31));
87ad11b0 3317 }
3318 else
3319 {
3320 import_milli (divI);
d6686e21 3321 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$divI"),
3322 gen_rtx (REG, SImode, 31));
87ad11b0 3323 }
3324 }
3325}
3326
3327/* Output a $$rem millicode to do mod. */
3328
3329char *
d6686e21 3330output_mod_insn (unsignedp, insn)
87ad11b0 3331 int unsignedp;
d6686e21 3332 rtx insn;
87ad11b0 3333{
3334 if (unsignedp)
3335 {
3336 import_milli (remU);
d6686e21 3337 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$remU"),
3338 gen_rtx (REG, SImode, 31));
87ad11b0 3339 }
3340 else
3341 {
3342 import_milli (remI);
d6686e21 3343 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$remI"),
3344 gen_rtx (REG, SImode, 31));
87ad11b0 3345 }
3346}
3347
3348void
df0651dc 3349output_arg_descriptor (call_insn)
3350 rtx call_insn;
87ad11b0 3351{
3352 char *arg_regs[4];
3353 enum machine_mode arg_mode;
df0651dc 3354 rtx link;
87ad11b0 3355 int i, output_flag = 0;
3356 int regno;
6d36483b 3357
87ad11b0 3358 for (i = 0; i < 4; i++)
3359 arg_regs[i] = 0;
3360
738176ab 3361 /* Specify explicitly that no argument relocations should take place
3362 if using the portable runtime calling conventions. */
3363 if (TARGET_PORTABLE_RUNTIME)
3364 {
3365 fprintf (asm_out_file,
3366 "\t.CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO,RETVAL=NO\n");
3367 return;
3368 }
3369
df0651dc 3370 if (GET_CODE (call_insn) != CALL_INSN)
3371 abort ();
3372 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); link; link = XEXP (link, 1))
87ad11b0 3373 {
df0651dc 3374 rtx use = XEXP (link, 0);
c12afafd 3375
df0651dc 3376 if (! (GET_CODE (use) == USE
3377 && GET_CODE (XEXP (use, 0)) == REG
3378 && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
c12afafd 3379 continue;
3380
df0651dc 3381 arg_mode = GET_MODE (XEXP (use, 0));
3382 regno = REGNO (XEXP (use, 0));
87ad11b0 3383 if (regno >= 23 && regno <= 26)
372ef038 3384 {
3385 arg_regs[26 - regno] = "GR";
3386 if (arg_mode == DImode)
3387 arg_regs[25 - regno] = "GR";
3388 }
df0651dc 3389 else if (regno >= 32 && regno <= 39)
87ad11b0 3390 {
3391 if (arg_mode == SFmode)
df0651dc 3392 arg_regs[(regno - 32) / 2] = "FR";
e6ba640e 3393 else
87ad11b0 3394 {
eeec72c0 3395#ifndef HP_FP_ARG_DESCRIPTOR_REVERSED
df0651dc 3396 arg_regs[(regno - 34) / 2] = "FR";
3397 arg_regs[(regno - 34) / 2 + 1] = "FU";
87ad11b0 3398#else
df0651dc 3399 arg_regs[(regno - 34) / 2] = "FU";
3400 arg_regs[(regno - 34) / 2 + 1] = "FR";
87ad11b0 3401#endif
3402 }
87ad11b0 3403 }
3404 }
3405 fputs ("\t.CALL ", asm_out_file);
3406 for (i = 0; i < 4; i++)
3407 {
3408 if (arg_regs[i])
3409 {
3410 if (output_flag++)
3411 fputc (',', asm_out_file);
3412 fprintf (asm_out_file, "ARGW%d=%s", i, arg_regs[i]);
3413 }
3414 }
3415 fputc ('\n', asm_out_file);
3416}
3417\f
d2c1d63d 3418/* Memory loads/stores to/from the shift need to go through
3419 the general registers. */
87ad11b0 3420
3421enum reg_class
3422secondary_reload_class (class, mode, in)
3423 enum reg_class class;
3424 enum machine_mode mode;
3425 rtx in;
3426{
3427 int regno = true_regnum (in);
3428
b4a7bf10 3429 /* Trying to load a constant into a FP register during PIC code
3430 generation will require %r1 as a scratch register. */
3431 if (flag_pic == 2
3432 && GET_MODE_CLASS (mode) == MODE_INT
3433 && FP_REG_CLASS_P (class)
3434 && (GET_CODE (in) == CONST_INT || GET_CODE (in) == CONST_DOUBLE))
3435 return R1_REGS;
3436
d2498717 3437 if (((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
6d36483b 3438 && GET_MODE_CLASS (mode) == MODE_INT
3439 && FP_REG_CLASS_P (class))
d6f01525 3440 || (class == SHIFT_REGS && (regno <= 0 || regno >= 32)))
9c6d4825 3441 return GENERAL_REGS;
d2c1d63d 3442
2ee034bc 3443 if (GET_CODE (in) == HIGH)
3444 in = XEXP (in, 0);
3445
b4a7bf10 3446 if (!flag_pic
3447 && symbolic_operand (in, VOIDmode)
3448 && read_only_operand (in))
3449 return NO_REGS;
3450
63882853 3451 if (class != R1_REGS && symbolic_operand (in, VOIDmode))
2ee034bc 3452 return R1_REGS;
3453
6b1c36c2 3454 if (GET_CODE (in) == SUBREG)
3455 in = SUBREG_REG (in);
3456
3457 if (FP_REG_CLASS_P (class)
3458 && GET_CODE (in) == MEM
3459 && !memory_address_p (DFmode, XEXP (in, 0))
3460 && memory_address_p (SImode, XEXP (in, 0)))
3461 return GENERAL_REGS;
3462
d2c1d63d 3463 return NO_REGS;
87ad11b0 3464}
3465
3466enum direction
3467function_arg_padding (mode, type)
3468 enum machine_mode mode;
3469 tree type;
3470{
3471 int size;
3472
3473 if (mode == BLKmode)
3474 {
3475 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
3476 size = int_size_in_bytes (type) * BITS_PER_UNIT;
3477 else
3478 return upward; /* Don't know if this is right, but */
3479 /* same as old definition. */
3480 }
3481 else
3482 size = GET_MODE_BITSIZE (mode);
3483 if (size < PARM_BOUNDARY)
3484 return downward;
3485 else if (size % PARM_BOUNDARY)
3486 return upward;
3487 else
3488 return none;
3489}
3490
87ad11b0 3491\f
3492/* Do what is necessary for `va_start'. The argument is ignored;
3493 We look at the current function to determine if stdargs or varargs
3494 is used and fill in an initial va_list. A pointer to this constructor
3495 is returned. */
3496
3497struct rtx_def *
3498hppa_builtin_saveregs (arglist)
3499 tree arglist;
3500{
57ed30e5 3501 rtx offset;
87ad11b0 3502 tree fntype = TREE_TYPE (current_function_decl);
3503 int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0
3504 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3505 != void_type_node)))
3506 ? UNITS_PER_WORD : 0);
3507
3508 if (argadj)
3509 offset = plus_constant (current_function_arg_offset_rtx, argadj);
3510 else
3511 offset = current_function_arg_offset_rtx;
9c6d4825 3512
87ad11b0 3513 /* Store general registers on the stack. */
3514 move_block_from_reg (23,
3515 gen_rtx (MEM, BLKmode,
3516 plus_constant
3517 (current_function_internal_arg_pointer, -16)),
6d36483b 3518 4, 4 * UNITS_PER_WORD);
9c6d4825 3519 return copy_to_reg (expand_binop (Pmode, add_optab,
3520 current_function_internal_arg_pointer,
3521 offset, 0, 0, OPTAB_LIB_WIDEN));
87ad11b0 3522}
d6f01525 3523
6d36483b 3524/* This routine handles all the normal conditional branch sequences we
3525 might need to generate. It handles compare immediate vs compare
3526 register, nullification of delay slots, varying length branches,
0d986529 3527 negated branches, and all combinations of the above. It returns the
6d36483b 3528 output appropriate to emit the branch corresponding to all given
0d986529 3529 parameters. */
3530
3531char *
3532output_cbranch (operands, nullify, length, negated, insn)
3533 rtx *operands;
3534 int nullify, length, negated;
3535 rtx insn;
29a4502c 3536{
0d986529 3537 static char buf[100];
3538 int useskip = 0;
3539
29a4502c 3540 /* A conditional branch to the following instruction (eg the delay slot) is
3541 asking for a disaster. This can happen when not optimizing.
3542
3543 In such cases it is safe to emit nothing. */
3544
3545 if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
3546 return "";
6d36483b 3547
5fbd5940 3548 /* If this is a long branch with its delay slot unfilled, set `nullify'
3549 as it can nullify the delay slot and save a nop. */
5a1231ef 3550 if (length == 8 && dbr_sequence_length () == 0)
5fbd5940 3551 nullify = 1;
3552
3553 /* If this is a short forward conditional branch which did not get
3554 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 3555 if (! nullify && length == 4 && dbr_sequence_length () == 0)
5fbd5940 3556 nullify = forward_branch_p (insn);
3557
6d36483b 3558 /* A forward branch over a single nullified insn can be done with a
0d986529 3559 comclr instruction. This avoids a single cycle penalty due to
3560 mis-predicted branch if we fall through (branch not taken). */
5a1231ef 3561 if (length == 4
5fbd5940 3562 && next_real_insn (insn) != 0
5a1231ef 3563 && get_attr_length (next_real_insn (insn)) == 4
5fbd5940 3564 && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
0d986529 3565 && nullify)
3566 useskip = 1;
3567
3568 switch (length)
3569 {
5fbd5940 3570 /* All short conditional branches except backwards with an unfilled
3571 delay slot. */
5a1231ef 3572 case 4:
0d986529 3573 if (useskip)
3574 strcpy (buf, "com%I2clr,");
3575 else
3576 strcpy (buf, "com%I2b,");
3577 if (negated)
3578 strcat (buf, "%B3");
3579 else
3580 strcat (buf, "%S3");
3581 if (useskip)
3582 strcat (buf, " %2,%1,0");
3583 else if (nullify)
3584 strcat (buf, ",n %2,%1,%0");
6d36483b 3585 else
5fbd5940 3586 strcat (buf, " %2,%1,%0");
0d986529 3587 break;
3588
6d36483b 3589 /* All long conditionals. Note an short backward branch with an
5fbd5940 3590 unfilled delay slot is treated just like a long backward branch
3591 with an unfilled delay slot. */
5a1231ef 3592 case 8:
5fbd5940 3593 /* Handle weird backwards branch with a filled delay slot
3594 with is nullified. */
3595 if (dbr_sequence_length () != 0
3596 && ! forward_branch_p (insn)
3597 && nullify)
3598 {
3599 strcpy (buf, "com%I2b,");
3600 if (negated)
3601 strcat (buf, "%S3");
3602 else
3603 strcat (buf, "%B3");
3604 strcat (buf, ",n %2,%1,.+12\n\tbl %0,0");
3605 }
43f0c1f2 3606 /* Handle short backwards branch with an unfilled delay slot.
3607 Using a comb;nop rather than comiclr;bl saves 1 cycle for both
3608 taken and untaken branches. */
3609 else if (dbr_sequence_length () == 0
3610 && ! forward_branch_p (insn)
3611 && insn_addresses
3612 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
3613 - insn_addresses[INSN_UID (insn)]))
3614 {
3615 strcpy (buf, "com%I2b,");
3616 if (negated)
3617 strcat (buf, "%B3 %2,%1,%0%#");
3618 else
3619 strcat (buf, "%S3 %2,%1,%0%#");
3620 }
0d986529 3621 else
5fbd5940 3622 {
3623 strcpy (buf, "com%I2clr,");
3624 if (negated)
3625 strcat (buf, "%S3");
3626 else
3627 strcat (buf, "%B3");
3628 if (nullify)
3629 strcat (buf, " %2,%1,0\n\tbl,n %0,0");
3630 else
3631 strcat (buf, " %2,%1,0\n\tbl %0,0");
3632 }
0d986529 3633 break;
3634
3635 default:
3636 abort();
5fbd5940 3637 }
0d986529 3638 return buf;
3639}
3640
6d36483b 3641/* This routine handles all the branch-on-bit conditional branch sequences we
0d986529 3642 might need to generate. It handles nullification of delay slots,
3643 varying length branches, negated branches and all combinations of the
3644 above. it returns the appropriate output template to emit the branch. */
3645
3646char *
3647output_bb (operands, nullify, length, negated, insn, which)
3648 rtx *operands;
3649 int nullify, length, negated;
3650 rtx insn;
3651 int which;
29a4502c 3652{
0d986529 3653 static char buf[100];
3654 int useskip = 0;
3655
29a4502c 3656 /* A conditional branch to the following instruction (eg the delay slot) is
3657 asking for a disaster. I do not think this can happen as this pattern
6d36483b 3658 is only used when optimizing; jump optimization should eliminate the
29a4502c 3659 jump. But be prepared just in case. */
6d36483b 3660
29a4502c 3661 if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
3662 return "";
6d36483b 3663
5fbd5940 3664 /* If this is a long branch with its delay slot unfilled, set `nullify'
3665 as it can nullify the delay slot and save a nop. */
5a1231ef 3666 if (length == 8 && dbr_sequence_length () == 0)
5fbd5940 3667 nullify = 1;
3668
3669 /* If this is a short forward conditional branch which did not get
3670 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 3671 if (! nullify && length == 4 && dbr_sequence_length () == 0)
5fbd5940 3672 nullify = forward_branch_p (insn);
3673
6d36483b 3674 /* A forward branch over a single nullified insn can be done with a
0d986529 3675 extrs instruction. This avoids a single cycle penalty due to
3676 mis-predicted branch if we fall through (branch not taken). */
3677
5a1231ef 3678 if (length == 4
5fbd5940 3679 && next_real_insn (insn) != 0
5a1231ef 3680 && get_attr_length (next_real_insn (insn)) == 4
5fbd5940 3681 && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
0d986529 3682 && nullify)
3683 useskip = 1;
3684
3685 switch (length)
3686 {
3687
5fbd5940 3688 /* All short conditional branches except backwards with an unfilled
3689 delay slot. */
5a1231ef 3690 case 4:
0d986529 3691 if (useskip)
3692 strcpy (buf, "extrs,");
6d36483b 3693 else
0d986529 3694 strcpy (buf, "bb,");
3695 if ((which == 0 && negated)
3696 || (which == 1 && ! negated))
3697 strcat (buf, ">=");
3698 else
3699 strcat (buf, "<");
3700 if (useskip)
3701 strcat (buf, " %0,%1,1,0");
3702 else if (nullify && negated)
3703 strcat (buf, ",n %0,%1,%3");
3704 else if (nullify && ! negated)
3705 strcat (buf, ",n %0,%1,%2");
3706 else if (! nullify && negated)
5fbd5940 3707 strcat (buf, "%0,%1,%3");
0d986529 3708 else if (! nullify && ! negated)
5fbd5940 3709 strcat (buf, " %0,%1,%2");
0d986529 3710 break;
3711
6d36483b 3712 /* All long conditionals. Note an short backward branch with an
5fbd5940 3713 unfilled delay slot is treated just like a long backward branch
3714 with an unfilled delay slot. */
5a1231ef 3715 case 8:
5fbd5940 3716 /* Handle weird backwards branch with a filled delay slot
3717 with is nullified. */
3718 if (dbr_sequence_length () != 0
3719 && ! forward_branch_p (insn)
3720 && nullify)
3721 {
3722 strcpy (buf, "bb,");
3723 if ((which == 0 && negated)
3724 || (which == 1 && ! negated))
3725 strcat (buf, "<");
3726 else
3727 strcat (buf, ">=");
3728 if (negated)
3729 strcat (buf, " %0,%1,.+12\n\tbl %3,0");
3730 else
3731 strcat (buf, " %0,%1,.+12\n\tbl %2,0");
3732 }
43f0c1f2 3733 /* Handle short backwards branch with an unfilled delay slot.
3734 Using a bb;nop rather than extrs;bl saves 1 cycle for both
3735 taken and untaken branches. */
3736 else if (dbr_sequence_length () == 0
3737 && ! forward_branch_p (insn)
3738 && insn_addresses
3739 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
3740 - insn_addresses[INSN_UID (insn)]))
3741 {
3742 strcpy (buf, "bb,");
3743 if ((which == 0 && negated)
3744 || (which == 1 && ! negated))
3745 strcat (buf, ">=");
3746 else
3747 strcat (buf, "<");
3748 if (negated)
3749 strcat (buf, " %0,%1,%3%#");
3750 else
3751 strcat (buf, " %0,%1,%2%#");
3752 }
0d986529 3753 else
5fbd5940 3754 {
3755 strcpy (buf, "extrs,");
3756 if ((which == 0 && negated)
3757 || (which == 1 && ! negated))
3758 strcat (buf, "<");
3759 else
3760 strcat (buf, ">=");
3761 if (nullify && negated)
3762 strcat (buf, " %0,%1,1,0\n\tbl,n %3,0");
3763 else if (nullify && ! negated)
3764 strcat (buf, " %0,%1,1,0\n\tbl,n %2,0");
3765 else if (negated)
3766 strcat (buf, " %0,%1,1,0\n\tbl %3,0");
6d36483b 3767 else
5fbd5940 3768 strcat (buf, " %0,%1,1,0\n\tbl %2,0");
3769 }
0d986529 3770 break;
3771
3772 default:
3773 abort();
5fbd5940 3774 }
0d986529 3775 return buf;
3776}
3777
29a4502c 3778/* Return the output template for emitting a dbra type insn.
3779
3780 Note it may perform some output operations on its own before
3781 returning the final output string. */
3782char *
3783output_dbra (operands, insn, which_alternative)
3784 rtx *operands;
3785 rtx insn;
3786 int which_alternative;
3787{
3788
3789 /* A conditional branch to the following instruction (eg the delay slot) is
3790 asking for a disaster. Be prepared! */
3791
3792 if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
3793 {
3794 if (which_alternative == 0)
3795 return "ldo %1(%0),%0";
3796 else if (which_alternative == 1)
3797 {
3798 output_asm_insn ("fstws %0,-16(0,%%r30)",operands);
3799 output_asm_insn ("ldw -16(0,%%r30),%4",operands);
3800 output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands);
3801 return "fldws -16(0,%%r30),%0";
3802 }
3803 else
3804 {
3805 output_asm_insn ("ldw %0,%4", operands);
3806 return "ldo %1(%4),%4\n\tstw %4,%0";
3807 }
3808 }
3809
3810 if (which_alternative == 0)
3811 {
3812 int nullify = INSN_ANNULLED_BRANCH_P (insn);
3813 int length = get_attr_length (insn);
3814
3815 /* If this is a long branch with its delay slot unfilled, set `nullify'
3816 as it can nullify the delay slot and save a nop. */
5a1231ef 3817 if (length == 8 && dbr_sequence_length () == 0)
29a4502c 3818 nullify = 1;
3819
3820 /* If this is a short forward conditional branch which did not get
3821 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 3822 if (! nullify && length == 4 && dbr_sequence_length () == 0)
29a4502c 3823 nullify = forward_branch_p (insn);
3824
3825 /* Handle short versions first. */
5a1231ef 3826 if (length == 4 && nullify)
29a4502c 3827 return "addib,%C2,n %1,%0,%3";
5a1231ef 3828 else if (length == 4 && ! nullify)
29a4502c 3829 return "addib,%C2 %1,%0,%3";
5a1231ef 3830 else if (length == 8)
29a4502c 3831 {
6d36483b 3832 /* Handle weird backwards branch with a fulled delay slot
29a4502c 3833 which is nullified. */
3834 if (dbr_sequence_length () != 0
3835 && ! forward_branch_p (insn)
3836 && nullify)
3837 return "addib,%N2,n %1,%0,.+12\n\tbl %3,0";
43f0c1f2 3838 /* Handle short backwards branch with an unfilled delay slot.
3839 Using a addb;nop rather than addi;bl saves 1 cycle for both
3840 taken and untaken branches. */
3841 else if (dbr_sequence_length () == 0
3842 && ! forward_branch_p (insn)
3843 && insn_addresses
3844 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
3845 - insn_addresses[INSN_UID (insn)]))
3846 return "addib,%C2 %1,%0,%3%#";
6d36483b 3847
3848 /* Handle normal cases. */
29a4502c 3849 if (nullify)
3850 return "addi,%N2 %1,%0,%0\n\tbl,n %3,0";
3851 else
3852 return "addi,%N2 %1,%0,%0\n\tbl %3,0";
3853 }
3854 else
3855 abort();
3856 }
3857 /* Deal with gross reload from FP register case. */
3858 else if (which_alternative == 1)
3859 {
3860 /* Move loop counter from FP register to MEM then into a GR,
3861 increment the GR, store the GR into MEM, and finally reload
6d36483b 3862 the FP register from MEM from within the branch's delay slot. */
29a4502c 3863 output_asm_insn ("fstws %0,-16(0,%%r30)\n\tldw -16(0,%%r30),%4",operands);
3864 output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands);
5a1231ef 3865 if (get_attr_length (insn) == 24)
29a4502c 3866 return "comb,%S2 0,%4,%3\n\tfldws -16(0,%%r30),%0";
3867 else
3868 return "comclr,%B2 0,%4,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0";
3869 }
3870 /* Deal with gross reload from memory case. */
3871 else
3872 {
3873 /* Reload loop counter from memory, the store back to memory
3874 happens in the branch's delay slot. */
3875 output_asm_insn ("ldw %0,%4", operands);
5a1231ef 3876 if (get_attr_length (insn) == 12)
29a4502c 3877 return "addib,%C2 %1,%4,%3\n\tstw %4,%0";
3878 else
b42d4c50 3879 return "addi,%N2 %1,%4,%4\n\tbl %3,0\n\tstw %4,%0";
29a4502c 3880 }
3881}
3882
3883/* Return the output template for emitting a dbra type insn.
3884
3885 Note it may perform some output operations on its own before
3886 returning the final output string. */
3887char *
3888output_movb (operands, insn, which_alternative, reverse_comparison)
3889 rtx *operands;
3890 rtx insn;
3891 int which_alternative;
3892 int reverse_comparison;
3893{
3894
3895 /* A conditional branch to the following instruction (eg the delay slot) is
3896 asking for a disaster. Be prepared! */
3897
3898 if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
3899 {
3900 if (which_alternative == 0)
3901 return "copy %1,%0";
3902 else if (which_alternative == 1)
3903 {
b4437664 3904 output_asm_insn ("stw %1,-16(0,%%r30)",operands);
29a4502c 3905 return "fldws -16(0,%%r30),%0";
3906 }
3907 else
3908 return "stw %1,%0";
3909 }
3910
3911 /* Support the second variant. */
3912 if (reverse_comparison)
3913 PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
3914
3915 if (which_alternative == 0)
3916 {
3917 int nullify = INSN_ANNULLED_BRANCH_P (insn);
3918 int length = get_attr_length (insn);
3919
3920 /* If this is a long branch with its delay slot unfilled, set `nullify'
3921 as it can nullify the delay slot and save a nop. */
5a1231ef 3922 if (length == 8 && dbr_sequence_length () == 0)
29a4502c 3923 nullify = 1;
3924
3925 /* If this is a short forward conditional branch which did not get
3926 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 3927 if (! nullify && length == 4 && dbr_sequence_length () == 0)
29a4502c 3928 nullify = forward_branch_p (insn);
3929
3930 /* Handle short versions first. */
5a1231ef 3931 if (length == 4 && nullify)
29a4502c 3932 return "movb,%C2,n %1,%0,%3";
5a1231ef 3933 else if (length == 4 && ! nullify)
29a4502c 3934 return "movb,%C2 %1,%0,%3";
5a1231ef 3935 else if (length == 8)
29a4502c 3936 {
6d36483b 3937 /* Handle weird backwards branch with a filled delay slot
29a4502c 3938 which is nullified. */
3939 if (dbr_sequence_length () != 0
3940 && ! forward_branch_p (insn)
3941 && nullify)
eb4a3ec3 3942 return "movb,%N2,n %1,%0,.+12\n\tbl %3,0";
6d36483b 3943
43f0c1f2 3944 /* Handle short backwards branch with an unfilled delay slot.
3945 Using a movb;nop rather than or;bl saves 1 cycle for both
3946 taken and untaken branches. */
3947 else if (dbr_sequence_length () == 0
3948 && ! forward_branch_p (insn)
3949 && insn_addresses
3950 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
3951 - insn_addresses[INSN_UID (insn)]))
3952 return "movb,%C2 %1,%0,%3%#";
6d36483b 3953 /* Handle normal cases. */
29a4502c 3954 if (nullify)
3955 return "or,%N2 %1,%%r0,%0\n\tbl,n %3,0";
3956 else
3957 return "or,%N2 %1,%%r0,%0\n\tbl %3,0";
3958 }
3959 else
3960 abort();
3961 }
3962 /* Deal with gross reload from FP register case. */
3963 else if (which_alternative == 1)
3964 {
3965 /* Move loop counter from FP register to MEM then into a GR,
3966 increment the GR, store the GR into MEM, and finally reload
6d36483b 3967 the FP register from MEM from within the branch's delay slot. */
b4437664 3968 output_asm_insn ("stw %1,-16(0,%%r30)",operands);
5a1231ef 3969 if (get_attr_length (insn) == 12)
29a4502c 3970 return "comb,%S2 0,%1,%3\n\tfldws -16(0,%%r30),%0";
3971 else
3972 return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0";
3973 }
3974 /* Deal with gross reload from memory case. */
3975 else
3976 {
3977 /* Reload loop counter from memory, the store back to memory
3978 happens in the branch's delay slot. */
5a1231ef 3979 if (get_attr_length (insn) == 8)
29a4502c 3980 return "comb,%S2 0,%1,%3\n\tstw %1,%0";
3981 else
3982 return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tstw %1,%0";
3983 }
3984}
3985
3986
d6686e21 3987/* INSN is either a function call or a millicode call. It may have an
6d36483b 3988 unconditional jump in its delay slot.
d6686e21 3989
3990 CALL_DEST is the routine we are calling.
3991
3992 RETURN_POINTER is the register which will hold the return address.
3683f840 3993 %r2 for most calls, %r31 for millicode calls.
3994
06ddb6f8 3995 When TARGET_MILLICODE_LONG_CALLS is true, then we have to assume
3996 that two instruction sequences must be used to reach the millicode
3997 routines (including dyncall!). */
3683f840 3998
d6686e21 3999char *
4000output_call (insn, call_dest, return_pointer)
4001 rtx insn;
4002 rtx call_dest;
4003 rtx return_pointer;
4004
4005{
4006 int distance;
4007 rtx xoperands[4];
4008 rtx seq_insn;
4009
06ddb6f8 4010 /* Handle long millicode calls for mod, div, and mul. */
4011 if (TARGET_PORTABLE_RUNTIME
4012 || (TARGET_MILLICODE_LONG_CALLS && REGNO (return_pointer) == 31))
4013 {
4014 xoperands[0] = call_dest;
4015 xoperands[1] = return_pointer;
4016 output_asm_insn ("ldil L%%%0,%%r29", xoperands);
4017 output_asm_insn ("ldo R%%%0(%%r29),%%r29", xoperands);
4018 output_asm_insn ("blr 0,%r1\n\tbv,n 0(%%r29)\n\tnop", xoperands);
4019 return "";
4020 }
4021
4022 /* Handle common case -- empty delay slot or no jump in the delay slot,
4023 and we're sure that the branch will reach the beginning of the $CODE$
4024 subspace. */
4025 if ((dbr_sequence_length () == 0
4026 && get_attr_length (insn) == 8)
6d36483b 4027 || (dbr_sequence_length () != 0
06ddb6f8 4028 && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN
4029 && get_attr_length (insn) == 4))
d6686e21 4030 {
4031 xoperands[0] = call_dest;
4032 xoperands[1] = return_pointer;
06ddb6f8 4033 output_asm_insn ("bl %0,%r1%#", xoperands);
4034 return "";
4035 }
4036
4037 /* This call may not reach the beginning of the $CODE$ subspace. */
4038 if (get_attr_length (insn) > 8)
4039 {
4040 int delay_insn_deleted = 0;
4041 rtx xoperands[2];
4042 rtx link;
4043
4044 /* We need to emit an inline long-call branch. Furthermore,
4045 because we're changing a named function call into an indirect
4046 function call well after the parameters have been set up, we
4047 need to make sure any FP args appear in both the integer
4048 and FP registers. Also, we need move any delay slot insn
4049 out of the delay slot -- Yuk! */
4050 if (dbr_sequence_length () != 0
4051 && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN)
3683f840 4052 {
06ddb6f8 4053 /* A non-jump insn in the delay slot. By definition we can
4054 emit this insn before the call (and in fact before argument
4055 relocating. */
4056 final_scan_insn (NEXT_INSN (insn), asm_out_file, optimize, 0, 0);
4057
4058 /* Now delete the delay insn. */
4059 PUT_CODE (NEXT_INSN (insn), NOTE);
4060 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
4061 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
4062 delay_insn_deleted = 1;
4063 }
4064
4065 /* Now copy any FP arguments into integer registers. */
4066 for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
4067 {
4068 int arg_mode, regno;
4069 rtx use = XEXP (link, 0);
4070 if (! (GET_CODE (use) == USE
4071 && GET_CODE (XEXP (use, 0)) == REG
4072 && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
4073 continue;
4074
4075 arg_mode = GET_MODE (XEXP (use, 0));
4076 regno = REGNO (XEXP (use, 0));
4077 /* Is it a floating point register? */
4078 if (regno >= 32 && regno <= 39)
4079 {
4080 /* Copy from the FP register into an integer register
4081 (via memory). */
4082 if (arg_mode == SFmode)
4083 {
4084 xoperands[0] = XEXP (use, 0);
4085 xoperands[1] = gen_rtx (REG, SImode, 26 - (regno - 32) / 2);
4086 output_asm_insn ("fstws %0,-16(%%sr0,%%r30)", xoperands);
4087 output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
4088 }
4089 else
4090 {
4091 xoperands[0] = XEXP (use, 0);
4092 xoperands[1] = gen_rtx (REG, DImode, 25 - (regno - 34) / 2);
4093 output_asm_insn ("fstds %0,-16(%%sr0,%%r30)", xoperands);
4094 output_asm_insn ("ldw -12(%%sr0,%%r30),%R1", xoperands);
4095 output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
4096 }
4097
4098 }
4099 }
4100
4101 /* Now emit the inline long-call. */
4102 xoperands[0] = call_dest;
7b42e7f8 4103 output_asm_insn ("ldil LP%%%0,%%r22\n\tldo RP%%%0(%%r22),%%r22",
4104 xoperands);
06ddb6f8 4105
4106 /* If TARGET_MILLICODE_LONG_CALLS, then we must use a long-call sequence
4107 to call dyncall! */
4108 if (TARGET_MILLICODE_LONG_CALLS)
4109 {
4110 output_asm_insn ("ldil L%%$$dyncall,%%r31", xoperands);
4111 output_asm_insn ("ldo R%%$$dyncall(%%r31),%%r31", xoperands);
4112 output_asm_insn ("blr 0,%%r2\n\tbv,n 0(%%r31)\n\tnop", xoperands);
3683f840 4113 }
4114 else
06ddb6f8 4115 output_asm_insn ("bl $$dyncall,%%r31\n\tcopy %%r31,%%r2", xoperands);
4116
4117 /* If we had a jump in the call's delay slot, output it now. */
4118 if (dbr_sequence_length () != 0
4119 && !delay_insn_deleted)
4120 {
4121 xoperands[0] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
4122 output_asm_insn ("b,n %0", xoperands);
4123
4124 /* Now delete the delay insn. */
4125 PUT_CODE (NEXT_INSN (insn), NOTE);
4126 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
4127 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
4128 }
d6686e21 4129 return "";
4130 }
6d36483b 4131
d6686e21 4132 /* This call has an unconditional jump in its delay slot. */
4133
4134 /* Use the containing sequence insn's address. */
4135 seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
4136
6d36483b 4137 distance = insn_addresses[INSN_UID (JUMP_LABEL (NEXT_INSN (insn)))]
d6686e21 4138 - insn_addresses[INSN_UID (seq_insn)] - 8;
4139
4140 /* If the branch was too far away, emit a normal call followed
4141 by a nop, followed by the unconditional branch.
4142
6d36483b 4143 If the branch is close, then adjust %r2 from within the
d6686e21 4144 call's delay slot. */
4145
4146 xoperands[0] = call_dest;
4147 xoperands[1] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
4148 xoperands[2] = return_pointer;
4149 if (! VAL_14_BITS_P (distance))
4150 output_asm_insn ("bl %0,%r2\n\tnop\n\tbl,n %1,%%r0", xoperands);
4151 else
4152 {
4153 xoperands[3] = gen_label_rtx ();
2a033928 4154 output_asm_insn ("\n\tbl %0,%r2\n\tldo %1-%3(%r2),%r2", xoperands);
6d36483b 4155 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
0410a74e 4156 CODE_LABEL_NUMBER (xoperands[3]));
d6686e21 4157 }
4158
4159 /* Delete the jump. */
4160 PUT_CODE (NEXT_INSN (insn), NOTE);
4161 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
4162 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
4163 return "";
4164}
4165
d6f01525 4166extern struct obstack *saveable_obstack;
4167
4168/* In HPUX 8.0's shared library scheme, special relocations are needed
6d36483b 4169 for function labels if they might be passed to a function
d6f01525 4170 in a shared library (because shared libraries don't live in code
4171 space), and special magic is needed to construct their address. */
4172
4173void
4174hppa_encode_label (sym)
4175 rtx sym;
4176{
4177 char *str = XSTR (sym, 0);
4178 int len = strlen (str);
4179 char *newstr = obstack_alloc (saveable_obstack, len + 2) ;
4180
c1b3411e 4181 if (str[0] == '*')
4182 *newstr++ = *str++;
d6f01525 4183 strcpy (newstr + 1, str);
c1b3411e 4184 *newstr = '@';
d6f01525 4185 XSTR (sym,0) = newstr;
4186}
6d36483b 4187
d6f01525 4188int
166bf021 4189function_label_operand (op, mode)
d6f01525 4190 rtx op;
4191 enum machine_mode mode;
4192{
c1b3411e 4193 return GET_CODE (op) == SYMBOL_REF && FUNCTION_NAME_P (XSTR (op, 0));
d6f01525 4194}
f33e3942 4195
166bf021 4196/* Returns 1 if OP is a function label involved in a simple addition
4197 with a constant. Used to keep certain patterns from matching
4198 during instruction combination. */
4199int
4200is_function_label_plus_const (op)
4201 rtx op;
4202{
4203 /* Strip off any CONST. */
4204 if (GET_CODE (op) == CONST)
4205 op = XEXP (op, 0);
4206
4207 return (GET_CODE (op) == PLUS
4208 && function_label_operand (XEXP (op, 0), Pmode)
4209 && GET_CODE (XEXP (op, 1)) == CONST_INT);
4210}
4211
37580c80 4212/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
4213 use in fmpyadd instructions. */
4ed6ee50 4214int
df0651dc 4215fmpyaddoperands (operands)
4ed6ee50 4216 rtx *operands;
4217{
201f01e9 4218 enum machine_mode mode = GET_MODE (operands[0]);
4ed6ee50 4219
4220 /* All modes must be the same. */
201f01e9 4221 if (! (mode == GET_MODE (operands[1])
4222 && mode == GET_MODE (operands[2])
4223 && mode == GET_MODE (operands[3])
4224 && mode == GET_MODE (operands[4])
4225 && mode == GET_MODE (operands[5])))
4ed6ee50 4226 return 0;
4227
4228 /* Both DFmode and SFmode should work. But using SFmode makes the
4229 assembler complain. Just turn it off for now. */
201f01e9 4230 if (mode != DFmode)
4ed6ee50 4231 return 0;
4232
37580c80 4233 /* Only 2 real operands to the addition. One of the input operands must
4234 be the same as the output operand. */
4ed6ee50 4235 if (! rtx_equal_p (operands[3], operands[4])
4236 && ! rtx_equal_p (operands[3], operands[5]))
4237 return 0;
4238
4239 /* Inout operand of add can not conflict with any operands from multiply. */
4240 if (rtx_equal_p (operands[3], operands[0])
4241 || rtx_equal_p (operands[3], operands[1])
4242 || rtx_equal_p (operands[3], operands[2]))
4243 return 0;
4244
4245 /* multiply can not feed into addition operands. */
4246 if (rtx_equal_p (operands[4], operands[0])
4247 || rtx_equal_p (operands[5], operands[0]))
4248 return 0;
4249
4ed6ee50 4250 /* Passed. Operands are suitable for fmpyadd. */
4251 return 1;
4252}
4253
37580c80 4254/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
4255 use in fmpysub instructions. */
4ed6ee50 4256int
df0651dc 4257fmpysuboperands (operands)
4ed6ee50 4258 rtx *operands;
4259{
201f01e9 4260 enum machine_mode mode = GET_MODE (operands[0]);
4ed6ee50 4261
4262 /* All modes must be the same. */
201f01e9 4263 if (! (mode == GET_MODE (operands[1])
4264 && mode == GET_MODE (operands[2])
4265 && mode == GET_MODE (operands[3])
4266 && mode == GET_MODE (operands[4])
4267 && mode == GET_MODE (operands[5])))
4ed6ee50 4268 return 0;
4269
4270 /* Both DFmode and SFmode should work. But using SFmode makes the
4271 assembler complain. Just turn it off for now. */
201f01e9 4272 if (mode != DFmode)
4ed6ee50 4273 return 0;
4274
37580c80 4275 /* Only 2 real operands to the subtraction. Subtraction is not a commutative
4276 operation, so operands[4] must be the same as operand[3]. */
4ed6ee50 4277 if (! rtx_equal_p (operands[3], operands[4]))
4278 return 0;
4279
4280 /* multiply can not feed into subtraction. */
37580c80 4281 if (rtx_equal_p (operands[5], operands[0]))
4ed6ee50 4282 return 0;
4283
37580c80 4284 /* Inout operand of sub can not conflict with any operands from multiply. */
4ed6ee50 4285 if (rtx_equal_p (operands[3], operands[0])
4286 || rtx_equal_p (operands[3], operands[1])
4287 || rtx_equal_p (operands[3], operands[2]))
4288 return 0;
4289
4290 /* Passed. Operands are suitable for fmpysub. */
4291 return 1;
4292}
4293
89f29d73 4294int
4295plus_xor_ior_operator (op, mode)
4296 rtx op;
4297 enum machine_mode mode;
4298{
4299 return (GET_CODE (op) == PLUS || GET_CODE (op) == XOR
4300 || GET_CODE (op) == IOR);
4301}
6720f95e 4302
4303/* Return 1 if the given constant is 2, 4, or 8. These are the valid
4304 constants for shadd instructions. */
4305int
4306shadd_constant_p (val)
4307 int val;
4308{
4309 if (val == 2 || val == 4 || val == 8)
4310 return 1;
4311 else
4312 return 0;
4313}
3a16146d 4314
4315/* Return 1 if OP is a CONST_INT with the value 2, 4, or 8. These are
4316 the valid constant for shadd instructions. */
4317int
4318shadd_operand (op, mode)
4319 rtx op;
4320 enum machine_mode mode;
4321{
4322 return (GET_CODE (op) == CONST_INT && shadd_constant_p (INTVAL (op)));
4323}
5fbd5940 4324
51987f90 4325/* Return 1 if this operand is anything other than a hard register. */
4326
4327int
4328non_hard_reg_operand (op, mode)
4329 rtx op;
4330 enum machine_mode mode;
4331{
4332 return ! (GET_CODE (op) == REG && REGNO (op) < FIRST_PSEUDO_REGISTER);
4333}
4334
5fbd5940 4335/* Return 1 if INSN branches forward. Should be using insn_addresses
4336 to avoid walking through all the insns... */
4337int
4338forward_branch_p (insn)
4339 rtx insn;
4340{
4341 rtx label = JUMP_LABEL (insn);
4342
4343 while (insn)
4344 {
4345 if (insn == label)
4346 break;
4347 else
4348 insn = NEXT_INSN (insn);
4349 }
4350
4351 return (insn == label);
4352}
4353
29a4502c 4354/* Return 1 if OP is an equality comparison, else return 0. */
4355int
4356eq_neq_comparison_operator (op, mode)
4357 rtx op;
4358 enum machine_mode mode;
4359{
4360 return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
4361}
4362
4363/* Return 1 if OP is an operator suitable for use in a movb instruction. */
4364int
4365movb_comparison_operator (op, mode)
4366 rtx op;
4367 enum machine_mode mode;
4368{
4369 return (GET_CODE (op) == EQ || GET_CODE (op) == NE
4370 || GET_CODE (op) == LT || GET_CODE (op) == GE);
4371}
4372
d6686e21 4373/* Return 1 if INSN is in the delay slot of a call instruction. */
4374int
4375jump_in_call_delay (insn)
4376 rtx insn;
4377{
4378
4379 if (GET_CODE (insn) != JUMP_INSN)
4380 return 0;
4381
4382 if (PREV_INSN (insn)
4383 && PREV_INSN (PREV_INSN (insn))
4384 && GET_CODE (next_active_insn (PREV_INSN (PREV_INSN (insn)))) == INSN)
4385 {
4386 rtx test_insn = next_active_insn (PREV_INSN (PREV_INSN (insn)));
4387
4388 return (GET_CODE (PATTERN (test_insn)) == SEQUENCE
4389 && XVECEXP (PATTERN (test_insn), 0, 1) == insn);
4390
4391 }
4392 else
4393 return 0;
4394}