]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/pa/pa.c
(do_error, do_warning): Fix memory leak.
[thirdparty/gcc.git] / gcc / config / pa / pa.c
CommitLineData
87ad11b0 1/* Subroutines for insn-output.c for HPPA.
7f7c4869 2 Copyright (C) 1992, 1993, 1994, 1995, 1996 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
01e379d0 19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
87ad11b0 21
22#include <stdio.h>
23#include "config.h"
24#include "rtl.h"
25#include "regs.h"
26#include "hard-reg-set.h"
27#include "real.h"
28#include "insn-config.h"
29#include "conditions.h"
30#include "insn-flags.h"
31#include "output.h"
32#include "insn-attr.h"
33#include "flags.h"
34#include "tree.h"
d1e2bb73 35#include "reload.h"
87ad11b0 36#include "c-tree.h"
37#include "expr.h"
d6f01525 38#include "obstack.h"
87ad11b0 39
40/* Save the operands last given to a compare for use when we
41 generate a scc or bcc insn. */
42
43rtx hppa_compare_op0, hppa_compare_op1;
44enum cmp_type hppa_branch_type;
45
134b4858 46/* Which cpu we are scheduling for. */
47enum processor_type pa_cpu;
48
49/* String to hold which cpu we are scheduling for. */
50char *pa_cpu_string;
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
7f7c4869 59/* Whether or not the current function uses an out-of-line prologue
60 and epilogue. */
61static int out_of_line_prologue_epilogue;
62
87ad11b0 63static rtx find_addr_reg ();
64
06ddb6f8 65/* Keep track of the number of bytes we have output in the CODE subspaces
66 during this compilation so we'll know when to emit inline long-calls. */
67
68unsigned int total_code_bytes;
69
e3f53689 70/* Variables to handle plabels that we discover are necessary at assembly
01cc3b75 71 output time. They are output after the current function. */
e3f53689 72
73struct defer_plab
74{
75 rtx internal_label;
76 rtx symbol;
77} *deferred_plabels = 0;
78int n_deferred_plabels = 0;
79
134b4858 80void
81override_options ()
82{
a87e1e15 83 /* Default to 7100 scheduling. If the 7100LC scheduling ever
84 gets reasonably tuned, it should be the default since that
85 what most PAs sold now are. */
134b4858 86 if (pa_cpu_string == NULL
a87e1e15 87 || ! strcmp (pa_cpu_string, "7100"))
134b4858 88 {
89 pa_cpu_string = "7100";
90 pa_cpu = PROCESSOR_7100;
91 }
a87e1e15 92 else if (! strcmp (pa_cpu_string, "700"))
93 {
94 pa_cpu_string = "700";
95 pa_cpu = PROCESSOR_700;
96 }
36f2814b 97 else if (! strcmp (pa_cpu_string, "7100LC"))
134b4858 98 {
99 pa_cpu_string = "7100LC";
100 pa_cpu = PROCESSOR_7100LC;
101 }
102 else
103 {
104 warning ("Unknown -mschedule= option (%s).\nValid options are 700, 7100 and 7100LC\n", pa_cpu_string);
105 }
c7a4e712 106
107 if (flag_pic && TARGET_PORTABLE_RUNTIME)
108 {
109 warning ("PIC code generation is not supported in the portable runtime model\n");
110 }
111
ac5850cf 112 if (flag_pic && (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS))
c7a4e712 113 {
114 warning ("PIC code generation is not compatable with fast indirect calls\n");
115 }
751e64a1 116
117 if (flag_pic && profile_flag)
118 {
119 warning ("PIC code generation is not compatable with profiling\n");
120 }
002fc5f7 121
122 if (TARGET_SPACE && (flag_pic || profile_flag))
123 {
124 warning ("Out of line entry/exit sequences are not compatable\n");
125 warning ("with PIC or profiling\n");
126 }
5bd7b548 127
128 if (! TARGET_GAS && write_symbols != NO_DEBUG)
129 {
130 warning ("-g is only supported when using GAS on this processor,");
131 warning ("-g option disabled.");
132 write_symbols = NO_DEBUG;
133 }
134b4858 134}
135
136
87ad11b0 137/* Return non-zero only if OP is a register of mode MODE,
891b55b4 138 or CONST0_RTX. */
87ad11b0 139int
140reg_or_0_operand (op, mode)
141 rtx op;
142 enum machine_mode mode;
143{
891b55b4 144 return (op == CONST0_RTX (mode) || register_operand (op, mode));
87ad11b0 145}
146
575e0eb4 147/* Return non-zero if OP is suitable for use in a call to a named
148 function.
149
6d36483b 150 (???) For 2.5 try to eliminate either call_operand_address or
575e0eb4 151 function_label_operand, they perform very similar functions. */
87ad11b0 152int
153call_operand_address (op, mode)
154 rtx op;
155 enum machine_mode mode;
156{
06ddb6f8 157 return (CONSTANT_P (op) && ! TARGET_PORTABLE_RUNTIME);
87ad11b0 158}
159
6d36483b 160/* Return 1 if X contains a symbolic expression. We know these
161 expressions will have one of a few well defined forms, so
347b5848 162 we need only check those forms. */
163int
164symbolic_expression_p (x)
165 register rtx x;
166{
167
6d36483b 168 /* Strip off any HIGH. */
347b5848 169 if (GET_CODE (x) == HIGH)
170 x = XEXP (x, 0);
171
172 return (symbolic_operand (x, VOIDmode));
173}
174
87ad11b0 175int
176symbolic_operand (op, mode)
177 register rtx op;
178 enum machine_mode mode;
179{
180 switch (GET_CODE (op))
181 {
182 case SYMBOL_REF:
183 case LABEL_REF:
184 return 1;
185 case CONST:
186 op = XEXP (op, 0);
187 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
188 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
189 && GET_CODE (XEXP (op, 1)) == CONST_INT);
190 default:
191 return 0;
192 }
193}
194
195/* Return truth value of statement that OP is a symbolic memory
196 operand of mode MODE. */
197
198int
199symbolic_memory_operand (op, mode)
200 rtx op;
201 enum machine_mode mode;
202{
203 if (GET_CODE (op) == SUBREG)
204 op = SUBREG_REG (op);
205 if (GET_CODE (op) != MEM)
206 return 0;
207 op = XEXP (op, 0);
208 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
209 || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
210}
211
212/* Return 1 if the operand is either a register or a memory operand that is
213 not symbolic. */
214
215int
216reg_or_nonsymb_mem_operand (op, mode)
217 register rtx op;
218 enum machine_mode mode;
219{
220 if (register_operand (op, mode))
221 return 1;
222
223 if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
224 return 1;
225
226 return 0;
227}
228
6d36483b 229/* Return 1 if the operand is either a register, zero, or a memory operand
891b55b4 230 that is not symbolic. */
231
232int
233reg_or_0_or_nonsymb_mem_operand (op, mode)
234 register rtx op;
235 enum machine_mode mode;
236{
237 if (register_operand (op, mode))
238 return 1;
239
240 if (op == CONST0_RTX (mode))
241 return 1;
242
243 if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
244 return 1;
245
246 return 0;
247}
248
6d36483b 249/* Accept any constant that can be moved in one instructions into a
d9d7c968 250 general register. */
6d36483b 251int
d9d7c968 252cint_ok_for_move (intval)
6d36483b 253 HOST_WIDE_INT intval;
d9d7c968 254{
255 /* OK if ldo, ldil, or zdepi, can be used. */
256 return (VAL_14_BITS_P (intval) || (intval & 0x7ff) == 0
257 || zdepi_cint_p (intval));
258}
259
6ecdbaa1 260/* Accept anything that can be moved in one instruction into a general
261 register. */
87ad11b0 262int
263move_operand (op, mode)
264 rtx op;
265 enum machine_mode mode;
266{
267 if (register_operand (op, mode))
268 return 1;
269
42faba01 270 if (GET_CODE (op) == CONST_INT)
d9d7c968 271 return cint_ok_for_move (INTVAL (op));
87ad11b0 272
87ad11b0 273 if (GET_CODE (op) == SUBREG)
274 op = SUBREG_REG (op);
275 if (GET_CODE (op) != MEM)
276 return 0;
277
278 op = XEXP (op, 0);
279 if (GET_CODE (op) == LO_SUM)
280 return (register_operand (XEXP (op, 0), Pmode)
281 && CONSTANT_P (XEXP (op, 1)));
27ef382d 282
283 /* Since move_operand is only used for source operands, we can always
284 allow scaled indexing! */
285 if (GET_CODE (op) == PLUS
286 && ((GET_CODE (XEXP (op, 0)) == MULT
287 && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
288 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
289 && INTVAL (XEXP (XEXP (op, 0), 1)) == GET_MODE_SIZE (mode)
290 && GET_CODE (XEXP (op, 1)) == REG)
291 || (GET_CODE (XEXP (op, 1)) == MULT
292 &&GET_CODE (XEXP (XEXP (op, 1), 0)) == REG
293 && GET_CODE (XEXP (XEXP (op, 1), 1)) == CONST_INT
294 && INTVAL (XEXP (XEXP (op, 1), 1)) == GET_MODE_SIZE (mode)
295 && GET_CODE (XEXP (op, 0)) == REG)))
296 return 1;
297
87ad11b0 298 return memory_address_p (mode, op);
299}
300
6ecdbaa1 301/* Accept REG and any CONST_INT that can be moved in one instruction into a
302 general register. */
303int
304reg_or_cint_move_operand (op, mode)
305 rtx op;
306 enum machine_mode mode;
307{
308 if (register_operand (op, mode))
309 return 1;
310
311 if (GET_CODE (op) == CONST_INT)
686b848d 312 return cint_ok_for_move (INTVAL (op));
313
6ecdbaa1 314 return 0;
315}
316
87ad11b0 317int
b4a7bf10 318pic_label_operand (op, mode)
87ad11b0 319 rtx op;
320 enum machine_mode mode;
321{
b4a7bf10 322 if (!flag_pic)
323 return 0;
324
325 switch (GET_CODE (op))
326 {
327 case LABEL_REF:
328 return 1;
b4a7bf10 329 case CONST:
330 op = XEXP (op, 0);
3c69dc97 331 return (GET_CODE (XEXP (op, 0)) == LABEL_REF
b4a7bf10 332 && GET_CODE (XEXP (op, 1)) == CONST_INT);
333 default:
334 return 0;
335 }
87ad11b0 336}
337
87ad11b0 338int
339fp_reg_operand (op, mode)
340 rtx op;
341 enum machine_mode mode;
342{
343 return reg_renumber && FP_REG_P (op);
344}
d6f01525 345
87ad11b0 346\f
87ad11b0 347
87ad11b0 348/* Return truth value of whether OP can be used as an operand in a
349 three operand arithmetic insn that accepts registers of mode MODE
350 or 14-bit signed integers. */
351int
352arith_operand (op, mode)
353 rtx op;
354 enum machine_mode mode;
355{
356 return (register_operand (op, mode)
357 || (GET_CODE (op) == CONST_INT && INT_14_BITS (op)));
358}
359
360/* Return truth value of whether OP can be used as an operand in a
361 three operand arithmetic insn that accepts registers of mode MODE
362 or 11-bit signed integers. */
363int
364arith11_operand (op, mode)
365 rtx op;
366 enum machine_mode mode;
367{
368 return (register_operand (op, mode)
369 || (GET_CODE (op) == CONST_INT && INT_11_BITS (op)));
370}
371
6d36483b 372/* A constant integer suitable for use in a PRE_MODIFY memory
757d4970 373 reference. */
42faba01 374int
375pre_cint_operand (op, mode)
376 rtx op;
377 enum machine_mode mode;
378{
379 return (GET_CODE (op) == CONST_INT
380 && INTVAL (op) >= -0x2000 && INTVAL (op) < 0x10);
381}
382
6d36483b 383/* A constant integer suitable for use in a POST_MODIFY memory
757d4970 384 reference. */
385int
386post_cint_operand (op, mode)
387 rtx op;
388 enum machine_mode mode;
389{
390 return (GET_CODE (op) == CONST_INT
391 && INTVAL (op) < 0x2000 && INTVAL (op) >= -0x10);
392}
393
87ad11b0 394int
395arith_double_operand (op, mode)
396 rtx op;
397 enum machine_mode mode;
398{
399 return (register_operand (op, mode)
400 || (GET_CODE (op) == CONST_DOUBLE
401 && GET_MODE (op) == mode
402 && VAL_14_BITS_P (CONST_DOUBLE_LOW (op))
403 && (CONST_DOUBLE_HIGH (op) >= 0
404 == ((CONST_DOUBLE_LOW (op) & 0x1000) == 0))));
405}
406
546a40bd 407/* Return truth value of whether OP is a integer which fits the
408 range constraining immediate operands in three-address insns, or
409 is an integer register. */
410
411int
412ireg_or_int5_operand (op, mode)
413 rtx op;
414 enum machine_mode mode;
415{
416 return ((GET_CODE (op) == CONST_INT && INT_5_BITS (op))
417 || (GET_CODE (op) == REG && REGNO (op) > 0 && REGNO (op) < 32));
418}
419
87ad11b0 420/* Return truth value of whether OP is a integer which fits the
421 range constraining immediate operands in three-address insns. */
422
423int
424int5_operand (op, mode)
425 rtx op;
426 enum machine_mode mode;
427{
428 return (GET_CODE (op) == CONST_INT && INT_5_BITS (op));
429}
430
431int
432uint5_operand (op, mode)
433 rtx op;
434 enum machine_mode mode;
435{
436 return (GET_CODE (op) == CONST_INT && INT_U5_BITS (op));
437}
438
87ad11b0 439int
440int11_operand (op, mode)
441 rtx op;
442 enum machine_mode mode;
443{
6d36483b 444 return (GET_CODE (op) == CONST_INT && INT_11_BITS (op));
445}
446
447int
448uint32_operand (op, mode)
449 rtx op;
450 enum machine_mode mode;
451{
452#if HOST_BITS_PER_WIDE_INT > 32
453 /* All allowed constants will fit a CONST_INT. */
454 return (GET_CODE (op) == CONST_INT
455 && (INTVAL (op) >= 0 && INTVAL (op) < 0x100000000L));
456#else
457 return (GET_CODE (op) == CONST_INT
458 || (GET_CODE (op) == CONST_DOUBLE
459 && CONST_DOUBLE_HIGH (op) == 0));
460#endif
87ad11b0 461}
462
463int
464arith5_operand (op, mode)
465 rtx op;
466 enum machine_mode mode;
467{
468 return register_operand (op, mode) || int5_operand (op, mode);
469}
470
fad0b60f 471/* True iff zdepi can be used to generate this CONST_INT. */
e057641f 472int
42faba01 473zdepi_cint_p (x)
6d36483b 474 unsigned HOST_WIDE_INT x;
fad0b60f 475{
3745c59b 476 unsigned HOST_WIDE_INT lsb_mask, t;
fad0b60f 477
478 /* This might not be obvious, but it's at least fast.
01cc3b75 479 This function is critical; we don't have the time loops would take. */
42faba01 480 lsb_mask = x & -x;
481 t = ((x >> 4) + lsb_mask) & ~(lsb_mask - 1);
482 /* Return true iff t is a power of two. */
fad0b60f 483 return ((t & (t - 1)) == 0);
484}
485
6d36483b 486/* True iff depi or extru can be used to compute (reg & mask).
487 Accept bit pattern like these:
488 0....01....1
489 1....10....0
490 1..10..01..1 */
e057641f 491int
42faba01 492and_mask_p (mask)
6d36483b 493 unsigned HOST_WIDE_INT mask;
e057641f 494{
495 mask = ~mask;
496 mask += mask & -mask;
497 return (mask & (mask - 1)) == 0;
498}
499
500/* True iff depi or extru can be used to compute (reg & OP). */
501int
502and_operand (op, mode)
503 rtx op;
504 enum machine_mode mode;
505{
506 return (register_operand (op, mode)
42faba01 507 || (GET_CODE (op) == CONST_INT && and_mask_p (INTVAL (op))));
e057641f 508}
509
510/* True iff depi can be used to compute (reg | MASK). */
511int
512ior_mask_p (mask)
6d36483b 513 unsigned HOST_WIDE_INT mask;
e057641f 514{
515 mask += mask & -mask;
516 return (mask & (mask - 1)) == 0;
517}
518
519/* True iff depi can be used to compute (reg | OP). */
520int
521ior_operand (op, mode)
522 rtx op;
523 enum machine_mode mode;
524{
b744c8cb 525 return (GET_CODE (op) == CONST_INT && ior_mask_p (INTVAL (op)));
e057641f 526}
527
e5965947 528int
529lhs_lshift_operand (op, mode)
530 rtx op;
531 enum machine_mode mode;
532{
533 return register_operand (op, mode) || lhs_lshift_cint_operand (op, mode);
534}
535
536/* True iff OP is a CONST_INT of the forms 0...0xxxx or 0...01...1xxxx.
537 Such values can be the left hand side x in (x << r), using the zvdepi
538 instruction. */
539int
540lhs_lshift_cint_operand (op, mode)
541 rtx op;
542 enum machine_mode mode;
543{
3745c59b 544 unsigned HOST_WIDE_INT x;
e5965947 545 if (GET_CODE (op) != CONST_INT)
546 return 0;
547 x = INTVAL (op) >> 4;
548 return (x & (x + 1)) == 0;
549}
550
9c6d4825 551int
552arith32_operand (op, mode)
553 rtx op;
554 enum machine_mode mode;
555{
556 return register_operand (op, mode) || GET_CODE (op) == CONST_INT;
557}
ead9285f 558
559int
560pc_or_label_operand (op, mode)
561 rtx op;
562 enum machine_mode mode;
563{
564 return (GET_CODE (op) == PC || GET_CODE (op) == LABEL_REF);
565}
87ad11b0 566\f
567/* Legitimize PIC addresses. If the address is already
568 position-independent, we return ORIG. Newly generated
569 position-independent addresses go to REG. If we need more
570 than one register, we lose. */
571
572rtx
573legitimize_pic_address (orig, mode, reg)
574 rtx orig, reg;
575 enum machine_mode mode;
576{
577 rtx pic_ref = orig;
578
b090827b 579 /* Labels need special handling. */
b4a7bf10 580 if (pic_label_operand (orig))
581 {
582 emit_insn (gen_pic_load_label (reg, orig));
583 current_function_uses_pic_offset_table = 1;
584 return reg;
585 }
87ad11b0 586 if (GET_CODE (orig) == SYMBOL_REF)
587 {
588 if (reg == 0)
589 abort ();
590
591 if (flag_pic == 2)
592 {
e8df7698 593 emit_insn (gen_pic2_highpart (reg, pic_offset_table_rtx, orig));
594 pic_ref = gen_rtx (MEM, Pmode,
595 gen_rtx (LO_SUM, Pmode, reg,
596 gen_rtx (UNSPEC, SImode, gen_rtvec (1, orig), 0)));
87ad11b0 597 }
b4a7bf10 598 else
599 pic_ref = gen_rtx (MEM, Pmode,
600 gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig));
87ad11b0 601 current_function_uses_pic_offset_table = 1;
602 RTX_UNCHANGING_P (pic_ref) = 1;
603 emit_move_insn (reg, pic_ref);
604 return reg;
605 }
606 else if (GET_CODE (orig) == CONST)
607 {
57ed30e5 608 rtx base;
87ad11b0 609
610 if (GET_CODE (XEXP (orig, 0)) == PLUS
611 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
612 return orig;
613
614 if (reg == 0)
615 abort ();
616
617 if (GET_CODE (XEXP (orig, 0)) == PLUS)
618 {
619 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
620 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
621 base == reg ? 0 : reg);
622 }
623 else abort ();
624 if (GET_CODE (orig) == CONST_INT)
625 {
42faba01 626 if (INT_14_BITS (orig))
87ad11b0 627 return plus_constant_for_output (base, INTVAL (orig));
628 orig = force_reg (Pmode, orig);
629 }
630 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
631 /* Likewise, should we set special REG_NOTEs here? */
632 }
633 return pic_ref;
634}
635
347b5848 636/* Try machine-dependent ways of modifying an illegitimate address
637 to be legitimate. If we find one, return the new, valid address.
638 This macro is used in only one place: `memory_address' in explow.c.
639
640 OLDX is the address as it was before break_out_memory_refs was called.
641 In some cases it is useful to look at this to decide what needs to be done.
642
643 MODE and WIN are passed so that this macro can use
644 GO_IF_LEGITIMATE_ADDRESS.
645
646 It is always safe for this macro to do nothing. It exists to recognize
6d36483b 647 opportunities to optimize the output.
347b5848 648
649 For the PA, transform:
650
651 memory(X + <large int>)
652
653 into:
654
655 if (<large int> & mask) >= 16
656 Y = (<large int> & ~mask) + mask + 1 Round up.
657 else
658 Y = (<large int> & ~mask) Round down.
659 Z = X + Y
660 memory (Z + (<large int> - Y));
661
6d36483b 662 This is for CSE to find several similar references, and only use one Z.
347b5848 663
664 X can either be a SYMBOL_REF or REG, but because combine can not
665 perform a 4->2 combination we do nothing for SYMBOL_REF + D where
666 D will not fit in 14 bits.
667
668 MODE_FLOAT references allow displacements which fit in 5 bits, so use
6d36483b 669 0x1f as the mask.
347b5848 670
671 MODE_INT references allow displacements which fit in 14 bits, so use
6d36483b 672 0x3fff as the mask.
347b5848 673
674 This relies on the fact that most mode MODE_FLOAT references will use FP
675 registers and most mode MODE_INT references will use integer registers.
676 (In the rare case of an FP register used in an integer MODE, we depend
677 on secondary reloads to clean things up.)
678
679
680 It is also beneficial to handle (plus (mult (X) (Y)) (Z)) in a special
681 manner if Y is 2, 4, or 8. (allows more shadd insns and shifted indexed
01cc3b75 682 addressing modes to be used).
347b5848 683
684 Put X and Z into registers. Then put the entire expression into
685 a register. */
686
687rtx
688hppa_legitimize_address (x, oldx, mode)
689 rtx x, oldx;
690 enum machine_mode mode;
691{
347b5848 692 rtx orig = x;
693
b4a7bf10 694 if (flag_pic)
695 return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
696
347b5848 697 /* Strip off CONST. */
698 if (GET_CODE (x) == CONST)
699 x = XEXP (x, 0);
700
42819d4e 701 /* Special case. Get the SYMBOL_REF into a register and use indexing.
702 That should always be safe. */
703 if (GET_CODE (x) == PLUS
704 && GET_CODE (XEXP (x, 0)) == REG
705 && GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
706 {
707 rtx reg = force_reg (SImode, XEXP (x, 1));
708 return force_reg (SImode, gen_rtx (PLUS, SImode, reg, XEXP (x, 0)));
709 }
710
166bf021 711 /* Note we must reject symbols which represent function addresses
712 since the assembler/linker can't handle arithmetic on plabels. */
347b5848 713 if (GET_CODE (x) == PLUS
714 && GET_CODE (XEXP (x, 1)) == CONST_INT
166bf021 715 && ((GET_CODE (XEXP (x, 0)) == SYMBOL_REF
716 && !FUNCTION_NAME_P (XSTR (XEXP (x, 0), 0)))
347b5848 717 || GET_CODE (XEXP (x, 0)) == REG))
718 {
719 rtx int_part, ptr_reg;
720 int newoffset;
721 int offset = INTVAL (XEXP (x, 1));
722 int mask = GET_MODE_CLASS (mode) == MODE_FLOAT ? 0x1f : 0x3fff;
723
6d36483b 724 /* Choose which way to round the offset. Round up if we
347b5848 725 are >= halfway to the next boundary. */
726 if ((offset & mask) >= ((mask + 1) / 2))
727 newoffset = (offset & ~ mask) + mask + 1;
728 else
729 newoffset = (offset & ~ mask);
730
731 /* If the newoffset will not fit in 14 bits (ldo), then
732 handling this would take 4 or 5 instructions (2 to load
733 the SYMBOL_REF + 1 or 2 to load the newoffset + 1 to
734 add the new offset and the SYMBOL_REF.) Combine can
735 not handle 4->2 or 5->2 combinations, so do not create
736 them. */
737 if (! VAL_14_BITS_P (newoffset)
738 && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
739 {
740 rtx const_part = gen_rtx (CONST, VOIDmode,
339613b4 741 gen_rtx (PLUS, Pmode,
347b5848 742 XEXP (x, 0),
743 GEN_INT (newoffset)));
744 rtx tmp_reg
339613b4 745 = force_reg (Pmode,
746 gen_rtx (HIGH, Pmode, const_part));
347b5848 747 ptr_reg
339613b4 748 = force_reg (Pmode,
749 gen_rtx (LO_SUM, Pmode,
347b5848 750 tmp_reg, const_part));
751 }
752 else
753 {
754 if (! VAL_14_BITS_P (newoffset))
339613b4 755 int_part = force_reg (Pmode, GEN_INT (newoffset));
347b5848 756 else
757 int_part = GEN_INT (newoffset);
758
339613b4 759 ptr_reg = force_reg (Pmode,
760 gen_rtx (PLUS, Pmode,
761 force_reg (Pmode, XEXP (x, 0)),
347b5848 762 int_part));
763 }
764 return plus_constant (ptr_reg, offset - newoffset);
765 }
45f1285a 766
5115683e 767 /* Handle (plus (mult (a) (shadd_constant)) (b)). */
45f1285a 768
347b5848 769 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
770 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
45f1285a 771 && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))
772 && (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == 'o'
773 || GET_CODE (XEXP (x, 1)) == SUBREG)
774 && GET_CODE (XEXP (x, 1)) != CONST)
347b5848 775 {
776 int val = INTVAL (XEXP (XEXP (x, 0), 1));
777 rtx reg1, reg2;
5115683e 778
779 reg1 = XEXP (x, 1);
780 if (GET_CODE (reg1) != REG)
781 reg1 = force_reg (Pmode, force_operand (reg1, 0));
782
783 reg2 = XEXP (XEXP (x, 0), 0);
784 if (GET_CODE (reg2) != REG)
785 reg2 = force_reg (Pmode, force_operand (reg2, 0));
786
5115683e 787 return force_reg (Pmode, gen_rtx (PLUS, Pmode,
788 gen_rtx (MULT, Pmode,
789 reg2, GEN_INT (val)),
790 reg1));
347b5848 791 }
45f1285a 792
00a87639 793 /* Similarly for (plus (plus (mult (a) (shadd_constant)) (b)) (c)).
794
795 Only do so for floating point modes since this is more speculative
796 and we lose if it's an integer store. */
5115683e 797 if (GET_CODE (x) == PLUS
00a87639 798 && GET_CODE (XEXP (x, 0)) == PLUS
799 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
800 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
5115683e 801 && shadd_constant_p (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)))
802 && (mode == SFmode || mode == DFmode))
00a87639 803 {
5115683e 804
805 /* First, try and figure out what to use as a base register. */
806 rtx reg1, reg2, base, idx, orig_base;
807
808 reg1 = XEXP (XEXP (x, 0), 1);
809 reg2 = XEXP (x, 1);
810 base = NULL_RTX;
811 idx = NULL_RTX;
812
813 /* Make sure they're both regs. If one was a SYMBOL_REF [+ const],
814 then emit_move_sequence will turn on REGNO_POINTER_FLAG so we'll
815 know it's a base register below. */
816 if (GET_CODE (reg1) != REG)
817 reg1 = force_reg (Pmode, force_operand (reg1, 0));
818
819 if (GET_CODE (reg2) != REG)
820 reg2 = force_reg (Pmode, force_operand (reg2, 0));
821
822 /* Figure out what the base and index are. */
823
824 if (GET_CODE (reg1) == REG
825 && REGNO_POINTER_FLAG (REGNO (reg1)))
826 {
827 base = reg1;
828 orig_base = XEXP (XEXP (x, 0), 1);
829 idx = gen_rtx (PLUS, Pmode,
830 gen_rtx (MULT, Pmode,
831 XEXP (XEXP (XEXP (x, 0), 0), 0),
832 XEXP (XEXP (XEXP (x, 0), 0), 1)),
833 XEXP (x, 1));
834 }
835 else if (GET_CODE (reg2) == REG
836 && REGNO_POINTER_FLAG (REGNO (reg2)))
837 {
838 base = reg2;
839 orig_base = XEXP (x, 1);
840 idx = XEXP (x, 0);
841 }
842
843 if (base == 0)
21f3ee9c 844 return orig;
5115683e 845
846 /* If the index adds a large constant, try to scale the
847 constant so that it can be loaded with only one insn. */
848 if (GET_CODE (XEXP (idx, 1)) == CONST_INT
849 && VAL_14_BITS_P (INTVAL (XEXP (idx, 1))
850 / INTVAL (XEXP (XEXP (idx, 0), 1)))
851 && INTVAL (XEXP (idx, 1)) % INTVAL (XEXP (XEXP (idx, 0), 1)) == 0)
852 {
853 /* Divide the CONST_INT by the scale factor, then add it to A. */
854 int val = INTVAL (XEXP (idx, 1));
855
856 val /= INTVAL (XEXP (XEXP (idx, 0), 1));
857 reg1 = XEXP (XEXP (idx, 0), 0);
858 if (GET_CODE (reg1) != REG)
859 reg1 = force_reg (Pmode, force_operand (reg1, 0));
860
861 reg1 = force_reg (Pmode, gen_rtx (PLUS, Pmode, reg1, GEN_INT (val)));
862
863 /* We can now generate a simple scaled indexed address. */
864 return force_reg (Pmode, gen_rtx (PLUS, Pmode,
865 gen_rtx (MULT, Pmode, reg1,
866 XEXP (XEXP (idx, 0), 1)),
867 base));
868 }
869
870 /* If B + C is still a valid base register, then add them. */
871 if (GET_CODE (XEXP (idx, 1)) == CONST_INT
872 && INTVAL (XEXP (idx, 1)) <= 4096
873 && INTVAL (XEXP (idx, 1)) >= -4096)
874 {
875 int val = INTVAL (XEXP (XEXP (idx, 0), 1));
876 rtx reg1, reg2;
877
878 reg1 = force_reg (Pmode, gen_rtx (PLUS, Pmode, base, XEXP (idx, 1)));
879
880 reg2 = XEXP (XEXP (idx, 0), 0);
881 if (GET_CODE (reg2) != CONST_INT)
882 reg2 = force_reg (Pmode, force_operand (reg2, 0));
883
884 return force_reg (Pmode, gen_rtx (PLUS, Pmode,
885 gen_rtx (MULT, Pmode,
886 reg2, GEN_INT (val)),
887 reg1));
888 }
889
890 /* Get the index into a register, then add the base + index and
891 return a register holding the result. */
892
893 /* First get A into a register. */
894 reg1 = XEXP (XEXP (idx, 0), 0);
895 if (GET_CODE (reg1) != REG)
896 reg1 = force_reg (Pmode, force_operand (reg1, 0));
897
898 /* And get B into a register. */
899 reg2 = XEXP (idx, 1);
900 if (GET_CODE (reg2) != REG)
901 reg2 = force_reg (Pmode, force_operand (reg2, 0));
902
903 reg1 = force_reg (Pmode, gen_rtx (PLUS, Pmode,
904 gen_rtx (MULT, Pmode, reg1,
905 XEXP (XEXP (idx, 0), 1)),
906 reg2));
907
908 /* Add the result to our base register and return. */
909 return force_reg (Pmode, gen_rtx (PLUS, Pmode, base, reg1));
00a87639 910
00a87639 911 }
912
6d36483b 913 /* Uh-oh. We might have an address for x[n-100000]. This needs
fb5390c1 914 special handling to avoid creating an indexed memory address
915 with x-100000 as the base.
916
917 If the constant part is small enough, then it's still safe because
918 there is a guard page at the beginning and end of the data segment.
919
920 Scaled references are common enough that we want to try and rearrange the
921 terms so that we can use indexing for these addresses too. Only
00a87639 922 do the optimization for floatint point modes. */
45f1285a 923
fb5390c1 924 if (GET_CODE (x) == PLUS
925 && symbolic_expression_p (XEXP (x, 1)))
45f1285a 926 {
927 /* Ugly. We modify things here so that the address offset specified
928 by the index expression is computed first, then added to x to form
fb5390c1 929 the entire address. */
45f1285a 930
00a87639 931 rtx regx1, regx2, regy1, regy2, y;
45f1285a 932
933 /* Strip off any CONST. */
934 y = XEXP (x, 1);
935 if (GET_CODE (y) == CONST)
936 y = XEXP (y, 0);
937
7ee96d6e 938 if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)
939 {
00a87639 940 /* See if this looks like
941 (plus (mult (reg) (shadd_const))
942 (const (plus (symbol_ref) (const_int))))
943
5115683e 944 Where const_int is small. In that case the const
945 expression is a valid pointer for indexing.
946
947 If const_int is big, but can be divided evenly by shadd_const
948 and added to (reg). This allows more scaled indexed addresses. */
949 if (GET_CODE (XEXP (y, 0)) == SYMBOL_REF
950 && GET_CODE (XEXP (x, 0)) == MULT
00a87639 951 && GET_CODE (XEXP (y, 1)) == CONST_INT
5115683e 952 && INTVAL (XEXP (y, 1)) >= -4096
953 && INTVAL (XEXP (y, 1)) <= 4095
954 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
955 && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
956 {
957 int val = INTVAL (XEXP (XEXP (x, 0), 1));
958 rtx reg1, reg2;
959
960 reg1 = XEXP (x, 1);
961 if (GET_CODE (reg1) != REG)
962 reg1 = force_reg (Pmode, force_operand (reg1, 0));
963
964 reg2 = XEXP (XEXP (x, 0), 0);
965 if (GET_CODE (reg2) != REG)
966 reg2 = force_reg (Pmode, force_operand (reg2, 0));
967
968 return force_reg (Pmode, gen_rtx (PLUS, Pmode,
969 gen_rtx (MULT, Pmode,
970 reg2, GEN_INT (val)),
971 reg1));
972 }
973 else if ((mode == DFmode || mode == SFmode)
974 && GET_CODE (XEXP (y, 0)) == SYMBOL_REF
975 && GET_CODE (XEXP (x, 0)) == MULT
976 && GET_CODE (XEXP (y, 1)) == CONST_INT
977 && INTVAL (XEXP (y, 1)) % INTVAL (XEXP (XEXP (x, 0), 1)) == 0
978 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
979 && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
00a87639 980 {
981 regx1
982 = force_reg (Pmode, GEN_INT (INTVAL (XEXP (y, 1))
983 / INTVAL (XEXP (XEXP (x, 0), 1))));
984 regx2 = XEXP (XEXP (x, 0), 0);
985 if (GET_CODE (regx2) != REG)
986 regx2 = force_reg (Pmode, force_operand (regx2, 0));
987 regx2 = force_reg (Pmode, gen_rtx (GET_CODE (y), Pmode,
988 regx2, regx1));
989 return force_reg (Pmode,
990 gen_rtx (PLUS, Pmode,
991 gen_rtx (MULT, Pmode, regx2,
992 XEXP (XEXP (x, 0), 1)),
993 force_reg (Pmode, XEXP (y, 0))));
994 }
fb5390c1 995 else if (GET_CODE (XEXP (y, 1)) == CONST_INT
996 && INTVAL (XEXP (y, 1)) >= -4096
997 && INTVAL (XEXP (y, 1)) <= 4095)
998 {
999 /* This is safe because of the guard page at the
1000 beginning and end of the data space. Just
1001 return the original address. */
1002 return orig;
1003 }
00a87639 1004 else
1005 {
1006 /* Doesn't look like one we can optimize. */
1007 regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
1008 regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
1009 regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
1010 regx1 = force_reg (Pmode,
1011 gen_rtx (GET_CODE (y), Pmode, regx1, regy2));
1012 return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1));
1013 }
7ee96d6e 1014 }
45f1285a 1015 }
1016
347b5848 1017 return orig;
1018}
1019
87ad11b0 1020/* For the HPPA, REG and REG+CONST is cost 0
1021 and addresses involving symbolic constants are cost 2.
1022
1023 PIC addresses are very expensive.
1024
1025 It is no coincidence that this has the same structure
1026 as GO_IF_LEGITIMATE_ADDRESS. */
1027int
1028hppa_address_cost (X)
1029 rtx X;
1030{
1031 if (GET_CODE (X) == PLUS)
1032 return 1;
1033 else if (GET_CODE (X) == LO_SUM)
1034 return 1;
1035 else if (GET_CODE (X) == HIGH)
1036 return 2;
1037 return 4;
1038}
1039
1040/* Emit insns to move operands[1] into operands[0].
1041
1042 Return 1 if we have written out everything that needs to be done to
1043 do the move. Otherwise, return 0 and the caller will emit the move
1044 normally. */
1045
1046int
d6f01525 1047emit_move_sequence (operands, mode, scratch_reg)
87ad11b0 1048 rtx *operands;
1049 enum machine_mode mode;
d6f01525 1050 rtx scratch_reg;
87ad11b0 1051{
1052 register rtx operand0 = operands[0];
1053 register rtx operand1 = operands[1];
1054
d1e2bb73 1055 if (reload_in_progress && GET_CODE (operand0) == REG
1056 && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
1057 operand0 = reg_equiv_mem[REGNO (operand0)];
1058 else if (reload_in_progress && GET_CODE (operand0) == SUBREG
1059 && GET_CODE (SUBREG_REG (operand0)) == REG
1060 && REGNO (SUBREG_REG (operand0)) >= FIRST_PSEUDO_REGISTER)
a3afad75 1061 {
1062 SUBREG_REG (operand0) = reg_equiv_mem[REGNO (SUBREG_REG (operand0))];
1063 operand0 = alter_subreg (operand0);
1064 }
d1e2bb73 1065
1066 if (reload_in_progress && GET_CODE (operand1) == REG
1067 && REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
1068 operand1 = reg_equiv_mem[REGNO (operand1)];
1069 else if (reload_in_progress && GET_CODE (operand1) == SUBREG
1070 && GET_CODE (SUBREG_REG (operand1)) == REG
1071 && REGNO (SUBREG_REG (operand1)) >= FIRST_PSEUDO_REGISTER)
a3afad75 1072 {
1073 SUBREG_REG (operand1) = reg_equiv_mem[REGNO (SUBREG_REG (operand1))];
1074 operand1 = alter_subreg (operand1);
1075 }
d1e2bb73 1076
e8fdbafa 1077 /* Handle secondary reloads for loads/stores of FP registers from
6b1c36c2 1078 REG+D addresses where D does not fit in 5 bits, including
42819d4e 1079 (subreg (mem (addr))) cases. */
d6f01525 1080 if (fp_reg_operand (operand0, mode)
6b1c36c2 1081 && ((GET_CODE (operand1) == MEM
1082 && ! memory_address_p (DFmode, XEXP (operand1, 0)))
1083 || ((GET_CODE (operand1) == SUBREG
1084 && GET_CODE (XEXP (operand1, 0)) == MEM
1085 && !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0)))))
d6f01525 1086 && scratch_reg)
1087 {
6b1c36c2 1088 if (GET_CODE (operand1) == SUBREG)
1089 operand1 = XEXP (operand1, 0);
1090
1091 scratch_reg = gen_rtx (REG, SImode, REGNO (scratch_reg));
7ee39d73 1092
1093 /* D might not fit in 14 bits either; for such cases load D into
1094 scratch reg. */
1095 if (!memory_address_p (SImode, XEXP (operand1, 0)))
1096 {
1097 emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1));
1098 emit_move_insn (scratch_reg, gen_rtx (GET_CODE (XEXP (operand1, 0)),
1099 SImode,
1100 XEXP (XEXP (operand1, 0), 0),
1101 scratch_reg));
1102 }
1103 else
1104 emit_move_insn (scratch_reg, XEXP (operand1, 0));
d6f01525 1105 emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MEM, mode,
1106 scratch_reg)));
1107 return 1;
1108 }
1109 else if (fp_reg_operand (operand1, mode)
6b1c36c2 1110 && ((GET_CODE (operand0) == MEM
1111 && ! memory_address_p (DFmode, XEXP (operand0, 0)))
1112 || ((GET_CODE (operand0) == SUBREG)
1113 && GET_CODE (XEXP (operand0, 0)) == MEM
1114 && !memory_address_p (DFmode, XEXP (XEXP (operand0, 0), 0))))
d6f01525 1115 && scratch_reg)
1116 {
6b1c36c2 1117 if (GET_CODE (operand0) == SUBREG)
1118 operand0 = XEXP (operand0, 0);
1119
1120 scratch_reg = gen_rtx (REG, SImode, REGNO (scratch_reg));
7ee39d73 1121 /* D might not fit in 14 bits either; for such cases load D into
1122 scratch reg. */
1123 if (!memory_address_p (SImode, XEXP (operand0, 0)))
1124 {
1125 emit_move_insn (scratch_reg, XEXP (XEXP (operand0, 0), 1));
1126 emit_move_insn (scratch_reg, gen_rtx (GET_CODE (XEXP (operand0, 0)),
1127 SImode,
1128 XEXP (XEXP (operand0, 0), 0),
1129 scratch_reg));
1130 }
1131 else
1132 emit_move_insn (scratch_reg, XEXP (operand0, 0));
6d36483b 1133 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, mode, scratch_reg),
d6f01525 1134 operand1));
1135 return 1;
1136 }
753bd06a 1137 /* Handle secondary reloads for loads of FP registers from constant
1138 expressions by forcing the constant into memory.
1139
6d36483b 1140 use scratch_reg to hold the address of the memory location.
753bd06a 1141
6d36483b 1142 ??? The proper fix is to change PREFERRED_RELOAD_CLASS to return
1143 NO_REGS when presented with a const_int and an register class
753bd06a 1144 containing only FP registers. Doing so unfortunately creates
1145 more problems than it solves. Fix this for 2.5. */
1146 else if (fp_reg_operand (operand0, mode)
1147 && CONSTANT_P (operand1)
1148 && scratch_reg)
1149 {
1150 rtx xoperands[2];
1151
1152 /* Force the constant into memory and put the address of the
1153 memory location into scratch_reg. */
1154 xoperands[0] = scratch_reg;
1155 xoperands[1] = XEXP (force_const_mem (mode, operand1), 0);
8f258b49 1156 emit_move_sequence (xoperands, Pmode, 0);
753bd06a 1157
1158 /* Now load the destination register. */
1159 emit_insn (gen_rtx (SET, mode, operand0,
1160 gen_rtx (MEM, mode, scratch_reg)));
1161 return 1;
1162 }
e8fdbafa 1163 /* Handle secondary reloads for SAR. These occur when trying to load
7d43e0f7 1164 the SAR from memory a FP register, or with a constant. */
e8fdbafa 1165 else if (GET_CODE (operand0) == REG
1166 && REGNO_REG_CLASS (REGNO (operand0)) == SHIFT_REGS
1167 && (GET_CODE (operand1) == MEM
7d43e0f7 1168 || GET_CODE (operand1) == CONST_INT
e8fdbafa 1169 || (GET_CODE (operand1) == REG
1170 && FP_REG_CLASS_P (REGNO_REG_CLASS (REGNO (operand1)))))
1171 && scratch_reg)
1172 {
1173 emit_move_insn (scratch_reg, operand1);
1174 emit_move_insn (operand0, scratch_reg);
1175 return 1;
1176 }
d6f01525 1177 /* Handle most common case: storing into a register. */
1178 else if (register_operand (operand0, mode))
87ad11b0 1179 {
1180 if (register_operand (operand1, mode)
42faba01 1181 || (GET_CODE (operand1) == CONST_INT && INT_14_BITS (operand1))
891b55b4 1182 || (operand1 == CONST0_RTX (mode))
87ad11b0 1183 || (GET_CODE (operand1) == HIGH
df0651dc 1184 && !symbolic_operand (XEXP (operand1, 0), VOIDmode))
87ad11b0 1185 /* Only `general_operands' can come here, so MEM is ok. */
1186 || GET_CODE (operand1) == MEM)
1187 {
1188 /* Run this case quickly. */
1189 emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
1190 return 1;
1191 }
1192 }
1193 else if (GET_CODE (operand0) == MEM)
1194 {
85eb4c6e 1195 if (mode == DFmode && operand1 == CONST0_RTX (mode)
1196 && !(reload_in_progress || reload_completed))
1197 {
1198 rtx temp = gen_reg_rtx (DFmode);
1199
1200 emit_insn (gen_rtx (SET, VOIDmode, temp, operand1));
1201 emit_insn (gen_rtx (SET, VOIDmode, operand0, temp));
1202 return 1;
1203 }
891b55b4 1204 if (register_operand (operand1, mode) || operand1 == CONST0_RTX (mode))
87ad11b0 1205 {
1206 /* Run this case quickly. */
1207 emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
1208 return 1;
1209 }
2ff4bf8d 1210 if (! (reload_in_progress || reload_completed))
87ad11b0 1211 {
1212 operands[0] = validize_mem (operand0);
1213 operands[1] = operand1 = force_reg (mode, operand1);
1214 }
1215 }
1216
1217 /* Simplify the source if we need to. */
57ed30e5 1218 if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
2ee034bc 1219 || (GET_CODE (operand1) == HIGH
63882853 1220 && symbolic_operand (XEXP (operand1, 0), mode)))
87ad11b0 1221 {
2ee034bc 1222 int ishighonly = 0;
1223
1224 if (GET_CODE (operand1) == HIGH)
1225 {
1226 ishighonly = 1;
1227 operand1 = XEXP (operand1, 0);
1228 }
87ad11b0 1229 if (symbolic_operand (operand1, mode))
1230 {
005a7dd0 1231 rtx const_part = NULL;
1232
1233 /* Argh. The assembler and linker can't handle arithmetic
1234 involving plabels. We'll have to split up operand1 here
1235 if it's a function label involved in an arithmetic
1236 expression. Luckily, this only happens with addition
1237 of constants to plabels, which simplifies the test.
1238
1239 We add the constant back in just before returning to
1240 our caller. */
1241 if (GET_CODE (operand1) == CONST
1242 && GET_CODE (XEXP (operand1, 0)) == PLUS
1243 && function_label_operand (XEXP (XEXP (operand1, 0), 0), Pmode))
1244 {
1245 /* Save away the constant part of the expression. */
1246 const_part = XEXP (XEXP (operand1, 0), 1);
1247 if (GET_CODE (const_part) != CONST_INT)
1248 abort ();
1249
1250 /* Set operand1 to just the SYMBOL_REF. */
1251 operand1 = XEXP (XEXP (operand1, 0), 0);
1252 }
1253
87ad11b0 1254 if (flag_pic)
1255 {
2ff4bf8d 1256 rtx temp;
1257
1258 if (reload_in_progress || reload_completed)
b4a7bf10 1259 temp = scratch_reg ? scratch_reg : operand0;
2ff4bf8d 1260 else
1261 temp = gen_reg_rtx (Pmode);
6d36483b 1262
005a7dd0 1263 /* If operand1 is a function label, then we've got to
1264 force it to memory, then load op0 from memory. */
1265 if (function_label_operand (operand1, mode))
1266 {
1267 operands[1] = force_const_mem (mode, operand1);
1268 emit_move_sequence (operands, mode, temp);
1269 }
42819d4e 1270 /* Likewise for (const (plus (symbol) (const_int))) when
1271 generating pic code during or after reload and const_int
1272 will not fit in 14 bits. */
96b86ab6 1273 else if (GET_CODE (operand1) == CONST
1274 && GET_CODE (XEXP (operand1, 0)) == PLUS
1275 && GET_CODE (XEXP (XEXP (operand1, 0), 1)) == CONST_INT
1276 && !INT_14_BITS (XEXP (XEXP (operand1, 0), 1))
1277 && (reload_completed || reload_in_progress)
1278 && flag_pic)
1279 {
1280 operands[1] = force_const_mem (mode, operand1);
1281 operands[1] = legitimize_pic_address (XEXP (operands[1], 0),
1282 mode, temp);
1283 emit_move_sequence (operands, mode, temp);
1284 }
005a7dd0 1285 else
1286 {
1287 operands[1] = legitimize_pic_address (operand1, mode, temp);
1288 emit_insn (gen_rtx (SET, VOIDmode, operand0, operands[1]));
1289 }
87ad11b0 1290 }
b4a7bf10 1291 /* On the HPPA, references to data space are supposed to use dp,
1292 register 27, but showing it in the RTL inhibits various cse
1293 and loop optimizations. */
6d36483b 1294 else
87ad11b0 1295 {
005a7dd0 1296 rtx temp, set;
2ee034bc 1297
6d36483b 1298 if (reload_in_progress || reload_completed)
2ee034bc 1299 temp = scratch_reg ? scratch_reg : operand0;
1300 else
1301 temp = gen_reg_rtx (mode);
1302
42819d4e 1303 /* Loading a SYMBOL_REF into a register makes that register
1304 safe to be used as the base in an indexed address.
1305
1306 Don't mark hard registers though. That loses. */
47a61b79 1307 if (GET_CODE (operand0) == REG
1308 && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
42819d4e 1309 REGNO_POINTER_FLAG (REGNO (operand0)) = 1;
1310 if (REGNO (temp) >= FIRST_PSEUDO_REGISTER)
1311 REGNO_POINTER_FLAG (REGNO (temp)) = 1;
2ee034bc 1312 if (ishighonly)
1313 set = gen_rtx (SET, mode, operand0, temp);
1314 else
1315 set = gen_rtx (SET, VOIDmode,
1316 operand0,
1317 gen_rtx (LO_SUM, mode, temp, operand1));
6d36483b 1318
87ad11b0 1319 emit_insn (gen_rtx (SET, VOIDmode,
2ee034bc 1320 temp,
d6f01525 1321 gen_rtx (HIGH, mode, operand1)));
d2498717 1322 emit_insn (set);
166bf021 1323
87ad11b0 1324 }
005a7dd0 1325
1326 /* Add back in the constant part if needed. */
1327 if (const_part != NULL)
1328 expand_inc (operand0, const_part);
2ee034bc 1329 return 1;
87ad11b0 1330 }
42faba01 1331 else if (GET_CODE (operand1) != CONST_INT
8c8ec4de 1332 || ! cint_ok_for_move (INTVAL (operand1)))
87ad11b0 1333 {
2ff4bf8d 1334 rtx temp;
1335
1336 if (reload_in_progress || reload_completed)
1337 temp = operand0;
1338 else
1339 temp = gen_reg_rtx (mode);
1340
87ad11b0 1341 emit_insn (gen_rtx (SET, VOIDmode, temp,
1342 gen_rtx (HIGH, mode, operand1)));
1343 operands[1] = gen_rtx (LO_SUM, mode, temp, operand1);
1344 }
1345 }
1346 /* Now have insn-emit do whatever it normally does. */
1347 return 0;
1348}
1349
1946138e 1350/* Examine EXP and return nonzero if it contains an ADDR_EXPR (meaning
bd49d362 1351 it will need a link/runtime reloc). */
1946138e 1352
1353int
1354reloc_needed (exp)
1355 tree exp;
1356{
1357 int reloc = 0;
1358
1359 switch (TREE_CODE (exp))
1360 {
1361 case ADDR_EXPR:
1362 return 1;
1363
1364 case PLUS_EXPR:
1365 case MINUS_EXPR:
1366 reloc = reloc_needed (TREE_OPERAND (exp, 0));
1367 reloc |= reloc_needed (TREE_OPERAND (exp, 1));
1368 break;
1369
1370 case NOP_EXPR:
1371 case CONVERT_EXPR:
1372 case NON_LVALUE_EXPR:
1373 reloc = reloc_needed (TREE_OPERAND (exp, 0));
1374 break;
1375
1376 case CONSTRUCTOR:
1377 {
1378 register tree link;
1379 for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
1380 if (TREE_VALUE (link) != 0)
1381 reloc |= reloc_needed (TREE_VALUE (link));
1382 }
1383 break;
1384
1385 case ERROR_MARK:
1386 break;
1387 }
1388 return reloc;
1389}
1390
87ad11b0 1391/* Does operand (which is a symbolic_operand) live in text space? If
201f01e9 1392 so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true. */
87ad11b0 1393
1394int
1395read_only_operand (operand)
1396 rtx operand;
1397{
1398 if (GET_CODE (operand) == CONST)
1399 operand = XEXP (XEXP (operand, 0), 0);
b4a7bf10 1400 if (flag_pic)
1401 {
1402 if (GET_CODE (operand) == SYMBOL_REF)
1403 return SYMBOL_REF_FLAG (operand) && !CONSTANT_POOL_ADDRESS_P (operand);
1404 }
1405 else
1406 {
1407 if (GET_CODE (operand) == SYMBOL_REF)
1408 return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand);
1409 }
87ad11b0 1410 return 1;
1411}
6d36483b 1412
87ad11b0 1413\f
1414/* Return the best assembler insn template
f54b1341 1415 for moving operands[1] into operands[0] as a fullword. */
5c683f13 1416char *
87ad11b0 1417singlemove_string (operands)
1418 rtx *operands;
1419{
3745c59b 1420 HOST_WIDE_INT intval;
1421
87ad11b0 1422 if (GET_CODE (operands[0]) == MEM)
1423 return "stw %r1,%0";
3745c59b 1424 if (GET_CODE (operands[1]) == MEM)
87ad11b0 1425 return "ldw %1,%0";
3745c59b 1426 if (GET_CODE (operands[1]) == CONST_DOUBLE)
9d5108ea 1427 {
3745c59b 1428 long i;
1429 REAL_VALUE_TYPE d;
9d5108ea 1430
3745c59b 1431 if (GET_MODE (operands[1]) != SFmode)
1432 abort ();
9d5108ea 1433
3745c59b 1434 /* Translate the CONST_DOUBLE to a CONST_INT with the same target
1435 bit pattern. */
1436 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[1]);
1437 REAL_VALUE_TO_TARGET_SINGLE (d, i);
9d5108ea 1438
3745c59b 1439 operands[1] = GEN_INT (i);
1440 /* Fall through to CONST_INT case. */
1441 }
1442 if (GET_CODE (operands[1]) == CONST_INT)
9d5108ea 1443 {
3745c59b 1444 intval = INTVAL (operands[1]);
1445
1446 if (VAL_14_BITS_P (intval))
1447 return "ldi %1,%0";
1448 else if ((intval & 0x7ff) == 0)
1449 return "ldil L'%1,%0";
1450 else if (zdepi_cint_p (intval))
1451 return "zdepi %Z1,%0";
9d5108ea 1452 else
1453 return "ldil L'%1,%0\n\tldo R'%1(%0),%0";
1454 }
87ad11b0 1455 return "copy %1,%0";
1456}
1457\f
1458
201f01e9 1459/* Compute position (in OP[1]) and width (in OP[2])
1460 useful for copying IMM to a register using the zdepi
1461 instructions. Store the immediate value to insert in OP[0]. */
e057641f 1462void
42faba01 1463compute_zdepi_operands (imm, op)
6d36483b 1464 unsigned HOST_WIDE_INT imm;
42faba01 1465 unsigned *op;
7e10ba53 1466{
e057641f 1467 int lsb, len;
7e10ba53 1468
e057641f 1469 /* Find the least significant set bit in IMM. */
1470 for (lsb = 0; lsb < 32; lsb++)
7e10ba53 1471 {
e057641f 1472 if ((imm & 1) != 0)
7e10ba53 1473 break;
e057641f 1474 imm >>= 1;
7e10ba53 1475 }
1476
e057641f 1477 /* Choose variants based on *sign* of the 5-bit field. */
1478 if ((imm & 0x10) == 0)
1479 len = (lsb <= 28) ? 4 : 32 - lsb;
7e10ba53 1480 else
1481 {
e057641f 1482 /* Find the width of the bitstring in IMM. */
1483 for (len = 5; len < 32; len++)
7e10ba53 1484 {
e057641f 1485 if ((imm & (1 << len)) == 0)
7e10ba53 1486 break;
7e10ba53 1487 }
1488
e057641f 1489 /* Sign extend IMM as a 5-bit value. */
1490 imm = (imm & 0xf) - 0x10;
7e10ba53 1491 }
1492
42faba01 1493 op[0] = imm;
1494 op[1] = 31 - lsb;
1495 op[2] = len;
7e10ba53 1496}
1497
87ad11b0 1498/* Output assembler code to perform a doubleword move insn
1499 with operands OPERANDS. */
1500
1501char *
1502output_move_double (operands)
1503 rtx *operands;
1504{
1505 enum { REGOP, OFFSOP, MEMOP, CNSTOP, RNDOP } optype0, optype1;
1506 rtx latehalf[2];
1507 rtx addreg0 = 0, addreg1 = 0;
1508
1509 /* First classify both operands. */
1510
1511 if (REG_P (operands[0]))
1512 optype0 = REGOP;
1513 else if (offsettable_memref_p (operands[0]))
1514 optype0 = OFFSOP;
1515 else if (GET_CODE (operands[0]) == MEM)
1516 optype0 = MEMOP;
1517 else
1518 optype0 = RNDOP;
1519
1520 if (REG_P (operands[1]))
1521 optype1 = REGOP;
1522 else if (CONSTANT_P (operands[1]))
1523 optype1 = CNSTOP;
1524 else if (offsettable_memref_p (operands[1]))
1525 optype1 = OFFSOP;
1526 else if (GET_CODE (operands[1]) == MEM)
1527 optype1 = MEMOP;
1528 else
1529 optype1 = RNDOP;
1530
1531 /* Check for the cases that the operand constraints are not
1532 supposed to allow to happen. Abort if we get one,
1533 because generating code for these cases is painful. */
1534
1535 if (optype0 != REGOP && optype1 != REGOP)
1536 abort ();
1537
1538 /* Handle auto decrementing and incrementing loads and stores
1539 specifically, since the structure of the function doesn't work
1540 for them without major modification. Do it better when we learn
1541 this port about the general inc/dec addressing of PA.
1542 (This was written by tege. Chide him if it doesn't work.) */
1543
1544 if (optype0 == MEMOP)
1545 {
1df0058a 1546 /* We have to output the address syntax ourselves, since print_operand
1547 doesn't deal with the addresses we want to use. Fix this later. */
1548
87ad11b0 1549 rtx addr = XEXP (operands[0], 0);
1df0058a 1550 if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
87ad11b0 1551 {
1df0058a 1552 rtx high_reg = gen_rtx (SUBREG, SImode, operands[1], 0);
1553
1554 operands[0] = XEXP (addr, 0);
1555 if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
1556 abort ();
1557
1558 if (!reg_overlap_mentioned_p (high_reg, addr))
1559 {
1560 /* No overlap between high target register and address
1561 register. (We do this in a non-obvious way to
1562 save a register file writeback) */
1563 if (GET_CODE (addr) == POST_INC)
1564 return "stws,ma %1,8(0,%0)\n\tstw %R1,-4(0,%0)";
1565 return "stws,ma %1,-8(0,%0)\n\tstw %R1,12(0,%0)";
1566 }
1567 else
1568 abort();
a3217f65 1569 }
1df0058a 1570 else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
a3217f65 1571 {
1df0058a 1572 rtx high_reg = gen_rtx (SUBREG, SImode, operands[1], 0);
1573
1574 operands[0] = XEXP (addr, 0);
1575 if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
1576 abort ();
1577
1578 if (!reg_overlap_mentioned_p (high_reg, addr))
1579 {
1580 /* No overlap between high target register and address
1581 register. (We do this in a non-obvious way to
1582 save a register file writeback) */
1583 if (GET_CODE (addr) == PRE_INC)
1584 return "stws,mb %1,8(0,%0)\n\tstw %R1,4(0,%0)";
1585 return "stws,mb %1,-8(0,%0)\n\tstw %R1,4(0,%0)";
1586 }
1587 else
1588 abort();
87ad11b0 1589 }
1590 }
1591 if (optype1 == MEMOP)
1592 {
1593 /* We have to output the address syntax ourselves, since print_operand
1594 doesn't deal with the addresses we want to use. Fix this later. */
1595
1596 rtx addr = XEXP (operands[1], 0);
1597 if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
1598 {
1599 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], 0);
1600
1601 operands[1] = XEXP (addr, 0);
1602 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
1603 abort ();
1604
1605 if (!reg_overlap_mentioned_p (high_reg, addr))
1606 {
1607 /* No overlap between high target register and address
3857fa62 1608 register. (We do this in a non-obvious way to
87ad11b0 1609 save a register file writeback) */
1610 if (GET_CODE (addr) == POST_INC)
1611 return "ldws,ma 8(0,%1),%0\n\tldw -4(0,%1),%R0";
1612 return "ldws,ma -8(0,%1),%0\n\tldw 12(0,%1),%R0";
1613 }
1614 else
1615 {
1616 /* This is an undefined situation. We should load into the
1617 address register *and* update that register. Probably
1618 we don't need to handle this at all. */
1619 if (GET_CODE (addr) == POST_INC)
1620 return "ldw 4(0,%1),%R0\n\tldws,ma 8(0,%1),%0";
1621 return "ldw 4(0,%1),%R0\n\tldws,ma -8(0,%1),%0";
1622 }
1623 }
1624 else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
1625 {
1626 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], 0);
1627
1628 operands[1] = XEXP (addr, 0);
1629 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
1630 abort ();
1631
1632 if (!reg_overlap_mentioned_p (high_reg, addr))
1633 {
1634 /* No overlap between high target register and address
3857fa62 1635 register. (We do this in a non-obvious way to
87ad11b0 1636 save a register file writeback) */
1637 if (GET_CODE (addr) == PRE_INC)
1638 return "ldws,mb 8(0,%1),%0\n\tldw 4(0,%1),%R0";
1639 return "ldws,mb -8(0,%1),%0\n\tldw 4(0,%1),%R0";
1640 }
1641 else
1642 {
1643 /* This is an undefined situation. We should load into the
1644 address register *and* update that register. Probably
1645 we don't need to handle this at all. */
1646 if (GET_CODE (addr) == PRE_INC)
1647 return "ldw 12(0,%1),%R0\n\tldws,mb 8(0,%1),%0";
1648 return "ldw -4(0,%1),%R0\n\tldws,mb -8(0,%1),%0";
1649 }
1650 }
1651 }
1652
1653 /* If an operand is an unoffsettable memory ref, find a register
1654 we can increment temporarily to make it refer to the second word. */
1655
1656 if (optype0 == MEMOP)
1657 addreg0 = find_addr_reg (XEXP (operands[0], 0));
1658
1659 if (optype1 == MEMOP)
1660 addreg1 = find_addr_reg (XEXP (operands[1], 0));
1661
1662 /* Ok, we can do one word at a time.
1663 Normally we do the low-numbered word first.
1664
1665 In either case, set up in LATEHALF the operands to use
1666 for the high-numbered word and in some cases alter the
1667 operands in OPERANDS to be suitable for the low-numbered word. */
1668
1669 if (optype0 == REGOP)
1670 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1671 else if (optype0 == OFFSOP)
1672 latehalf[0] = adj_offsettable_operand (operands[0], 4);
1673 else
1674 latehalf[0] = operands[0];
1675
1676 if (optype1 == REGOP)
1677 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1678 else if (optype1 == OFFSOP)
1679 latehalf[1] = adj_offsettable_operand (operands[1], 4);
1680 else if (optype1 == CNSTOP)
1681 split_double (operands[1], &operands[1], &latehalf[1]);
1682 else
1683 latehalf[1] = operands[1];
1684
1685 /* If the first move would clobber the source of the second one,
1686 do them in the other order.
1687
cf489d53 1688 This can happen in two cases:
87ad11b0 1689
cf489d53 1690 mem -> register where the first half of the destination register
1691 is the same register used in the memory's address. Reload
1692 can create such insns.
87ad11b0 1693
cf489d53 1694 mem in this case will be either register indirect or register
1695 indirect plus a valid offset.
1696
1697 register -> register move where REGNO(dst) == REGNO(src + 1)
1698 someone (Tim/Tege?) claimed this can happen for parameter loads.
1699
1700 Handle mem -> register case first. */
1701 if (optype0 == REGOP
1702 && (optype1 == MEMOP || optype1 == OFFSOP)
1703 && refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
1704 operands[1], 0))
87ad11b0 1705 {
87ad11b0 1706 /* Do the late half first. */
1707 if (addreg1)
6a5d085a 1708 output_asm_insn ("ldo 4(%0),%0", &addreg1);
87ad11b0 1709 output_asm_insn (singlemove_string (latehalf), latehalf);
cf489d53 1710
1711 /* Then clobber. */
87ad11b0 1712 if (addreg1)
6a5d085a 1713 output_asm_insn ("ldo -4(%0),%0", &addreg1);
87ad11b0 1714 return singlemove_string (operands);
1715 }
1716
cf489d53 1717 /* Now handle register -> register case. */
c4fa5937 1718 if (optype0 == REGOP && optype1 == REGOP
1719 && REGNO (operands[0]) == REGNO (operands[1]) + 1)
1720 {
1721 output_asm_insn (singlemove_string (latehalf), latehalf);
1722 return singlemove_string (operands);
1723 }
1724
87ad11b0 1725 /* Normal case: do the two words, low-numbered first. */
1726
1727 output_asm_insn (singlemove_string (operands), operands);
1728
1729 /* Make any unoffsettable addresses point at high-numbered word. */
1730 if (addreg0)
6a5d085a 1731 output_asm_insn ("ldo 4(%0),%0", &addreg0);
87ad11b0 1732 if (addreg1)
6a5d085a 1733 output_asm_insn ("ldo 4(%0),%0", &addreg1);
87ad11b0 1734
1735 /* Do that word. */
1736 output_asm_insn (singlemove_string (latehalf), latehalf);
1737
1738 /* Undo the adds we just did. */
1739 if (addreg0)
6a5d085a 1740 output_asm_insn ("ldo -4(%0),%0", &addreg0);
87ad11b0 1741 if (addreg1)
6a5d085a 1742 output_asm_insn ("ldo -4(%0),%0", &addreg1);
87ad11b0 1743
1744 return "";
1745}
1746\f
1747char *
1748output_fp_move_double (operands)
1749 rtx *operands;
1750{
1751 if (FP_REG_P (operands[0]))
1752 {
6d36483b 1753 if (FP_REG_P (operands[1])
891b55b4 1754 || operands[1] == CONST0_RTX (GET_MODE (operands[0])))
1755 output_asm_insn ("fcpy,dbl %r1,%0", operands);
6d36483b 1756 else
27ef382d 1757 output_asm_insn ("fldd%F1 %1,%0", operands);
87ad11b0 1758 }
1759 else if (FP_REG_P (operands[1]))
1760 {
27ef382d 1761 output_asm_insn ("fstd%F0 %1,%0", operands);
87ad11b0 1762 }
891b55b4 1763 else if (operands[1] == CONST0_RTX (GET_MODE (operands[0])))
1764 {
1765 if (GET_CODE (operands[0]) == REG)
1766 {
1767 rtx xoperands[2];
1768 xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1769 xoperands[0] = operands[0];
1770 output_asm_insn ("copy %%r0,%0\n\tcopy %%r0,%1", xoperands);
1771 }
6d36483b 1772 /* This is a pain. You have to be prepared to deal with an
01cc3b75 1773 arbitrary address here including pre/post increment/decrement.
891b55b4 1774
1775 so avoid this in the MD. */
1776 else
1777 abort ();
1778 }
87ad11b0 1779 else abort ();
1780 return "";
1781}
1782\f
1783/* Return a REG that occurs in ADDR with coefficient 1.
1784 ADDR can be effectively incremented by incrementing REG. */
1785
1786static rtx
1787find_addr_reg (addr)
1788 rtx addr;
1789{
1790 while (GET_CODE (addr) == PLUS)
1791 {
1792 if (GET_CODE (XEXP (addr, 0)) == REG)
1793 addr = XEXP (addr, 0);
1794 else if (GET_CODE (XEXP (addr, 1)) == REG)
1795 addr = XEXP (addr, 1);
1796 else if (CONSTANT_P (XEXP (addr, 0)))
1797 addr = XEXP (addr, 1);
1798 else if (CONSTANT_P (XEXP (addr, 1)))
1799 addr = XEXP (addr, 0);
1800 else
1801 abort ();
1802 }
1803 if (GET_CODE (addr) == REG)
1804 return addr;
1805 abort ();
1806}
1807
87ad11b0 1808/* Emit code to perform a block move.
1809
87ad11b0 1810 OPERANDS[0] is the destination pointer as a REG, clobbered.
1811 OPERANDS[1] is the source pointer as a REG, clobbered.
42819d4e 1812 OPERANDS[2] is a register for temporary storage.
1813 OPERANDS[4] is the size as a CONST_INT
87ad11b0 1814 OPERANDS[3] is a register for temporary storage.
42819d4e 1815 OPERANDS[5] is the alignment safe to use, as a CONST_INT.
1816 OPERNADS[6] is another temporary register. */
87ad11b0 1817
1818char *
1819output_block_move (operands, size_is_constant)
1820 rtx *operands;
1821 int size_is_constant;
1822{
1823 int align = INTVAL (operands[5]);
42819d4e 1824 unsigned long n_bytes = INTVAL (operands[4]);
87ad11b0 1825
1826 /* We can't move more than four bytes at a time because the PA
1827 has no longer integer move insns. (Could use fp mem ops?) */
1828 if (align > 4)
1829 align = 4;
1830
42819d4e 1831 /* Note that we know each loop below will execute at least twice
1832 (else we would have open-coded the copy). */
1833 switch (align)
87ad11b0 1834 {
42819d4e 1835 case 4:
1836 /* Pre-adjust the loop counter. */
1837 operands[4] = GEN_INT (n_bytes - 8);
1838 output_asm_insn ("ldi %4,%2", operands);
1839
1840 /* Copying loop. */
1841 output_asm_insn ("ldws,ma 4(0,%1),%3", operands);
1842 output_asm_insn ("ldws,ma 4(0,%1),%6", operands);
1843 output_asm_insn ("stws,ma %3,4(0,%0)", operands);
1844 output_asm_insn ("addib,>= -8,%2,.-12", operands);
1845 output_asm_insn ("stws,ma %6,4(0,%0)", operands);
1846
1847 /* Handle the residual. There could be up to 7 bytes of
1848 residual to copy! */
1849 if (n_bytes % 8 != 0)
1850 {
1851 operands[4] = GEN_INT (n_bytes % 4);
1852 if (n_bytes % 8 >= 4)
87ad11b0 1853 output_asm_insn ("ldws,ma 4(0,%1),%3", operands);
42819d4e 1854 if (n_bytes % 4 != 0)
1855 output_asm_insn ("ldw 0(0,%1),%6", operands);
1856 if (n_bytes % 8 >= 4)
1857 output_asm_insn ("stws,ma %3,4(0,%0)", operands);
1858 if (n_bytes % 4 != 0)
1859 output_asm_insn ("stbys,e %6,%4(0,%0)", operands);
1860 }
1861 return "";
87ad11b0 1862
42819d4e 1863 case 2:
1864 /* Pre-adjust the loop counter. */
1865 operands[4] = GEN_INT (n_bytes - 4);
1866 output_asm_insn ("ldi %4,%2", operands);
87ad11b0 1867
42819d4e 1868 /* Copying loop. */
1869 output_asm_insn ("ldhs,ma 2(0,%1),%3", operands);
1870 output_asm_insn ("ldhs,ma 2(0,%1),%6", operands);
1871 output_asm_insn ("sths,ma %3,2(0,%0)", operands);
1872 output_asm_insn ("addib,>= -4,%2,.-12", operands);
1873 output_asm_insn ("sths,ma %6,2(0,%0)", operands);
87ad11b0 1874
42819d4e 1875 /* Handle the residual. */
1876 if (n_bytes % 4 != 0)
1877 {
1878 if (n_bytes % 4 >= 2)
87ad11b0 1879 output_asm_insn ("ldhs,ma 2(0,%1),%3", operands);
42819d4e 1880 if (n_bytes % 2 != 0)
1881 output_asm_insn ("ldb 0(0,%1),%6", operands);
1882 if (n_bytes % 4 >= 2)
1883 output_asm_insn ("sths,ma %3,2(0,%0)", operands);
1884 if (n_bytes % 2 != 0)
1885 output_asm_insn ("stb %6,0(0,%0)", operands);
1886 }
1887 return "";
87ad11b0 1888
42819d4e 1889 case 1:
1890 /* Pre-adjust the loop counter. */
1891 operands[4] = GEN_INT (n_bytes - 2);
1892 output_asm_insn ("ldi %4,%2", operands);
87ad11b0 1893
42819d4e 1894 /* Copying loop. */
1895 output_asm_insn ("ldbs,ma 1(0,%1),%3", operands);
1896 output_asm_insn ("ldbs,ma 1(0,%1),%6", operands);
1897 output_asm_insn ("stbs,ma %3,1(0,%0)", operands);
1898 output_asm_insn ("addib,>= -2,%2,.-12", operands);
1899 output_asm_insn ("stbs,ma %6,1(0,%0)", operands);
87ad11b0 1900
42819d4e 1901 /* Handle the residual. */
1902 if (n_bytes % 2 != 0)
1903 {
1904 output_asm_insn ("ldb 0(0,%1),%3", operands);
87ad11b0 1905 output_asm_insn ("stb %3,0(0,%0)", operands);
42819d4e 1906 }
1907 return "";
87ad11b0 1908
42819d4e 1909 default:
1910 abort ();
87ad11b0 1911 }
87ad11b0 1912}
58e17b0b 1913
1914/* Count the number of insns necessary to handle this block move.
1915
1916 Basic structure is the same as emit_block_move, except that we
1917 count insns rather than emit them. */
1918
1919int
1920compute_movstrsi_length (insn)
1921 rtx insn;
1922{
1923 rtx pat = PATTERN (insn);
58e17b0b 1924 int align = INTVAL (XEXP (XVECEXP (pat, 0, 6), 0));
42819d4e 1925 unsigned long n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 5), 0));
1926 unsigned int n_insns = 0;
58e17b0b 1927
1928 /* We can't move more than four bytes at a time because the PA
1929 has no longer integer move insns. (Could use fp mem ops?) */
1930 if (align > 4)
1931 align = 4;
1932
42819d4e 1933 /* The basic opying loop. */
1934 n_insns = 6;
58e17b0b 1935
42819d4e 1936 /* Residuals. */
1937 if (n_bytes % (2 * align) != 0)
58e17b0b 1938 {
42819d4e 1939 /* Any residual caused by unrolling the copy loop. */
1940 if (n_bytes % (2 * align) > align)
1941 n_insns += 1;
1942
1943 /* Any residual because the number of bytes was not a
1944 multiple of the alignment. */
1945 if (n_bytes % align != 0)
1946 n_insns += 1;
58e17b0b 1947 }
42819d4e 1948
1949 /* Lengths are expressed in bytes now; each insn is 4 bytes. */
1950 return n_insns * 4;
58e17b0b 1951}
87ad11b0 1952\f
1953
e057641f 1954char *
1955output_and (operands)
1956 rtx *operands;
1957{
d6f01525 1958 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
e057641f 1959 {
3745c59b 1960 unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
e057641f 1961 int ls0, ls1, ms0, p, len;
1962
1963 for (ls0 = 0; ls0 < 32; ls0++)
1964 if ((mask & (1 << ls0)) == 0)
1965 break;
1966
1967 for (ls1 = ls0; ls1 < 32; ls1++)
1968 if ((mask & (1 << ls1)) != 0)
1969 break;
1970
1971 for (ms0 = ls1; ms0 < 32; ms0++)
1972 if ((mask & (1 << ms0)) == 0)
1973 break;
1974
1975 if (ms0 != 32)
1976 abort();
1977
1978 if (ls1 == 32)
1979 {
1980 len = ls0;
1981
1982 if (len == 0)
1983 abort ();
1984
ef618fe4 1985 operands[2] = GEN_INT (len);
e057641f 1986 return "extru %1,31,%2,%0";
1987 }
1988 else
1989 {
1990 /* We could use this `depi' for the case above as well, but `depi'
1991 requires one more register file access than an `extru'. */
1992
1993 p = 31 - ls0;
1994 len = ls1 - ls0;
1995
ef618fe4 1996 operands[2] = GEN_INT (p);
1997 operands[3] = GEN_INT (len);
e057641f 1998 return "depi 0,%2,%3,%0";
1999 }
2000 }
2001 else
2002 return "and %1,%2,%0";
2003}
2004
2005char *
2006output_ior (operands)
2007 rtx *operands;
2008{
3745c59b 2009 unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
57ed30e5 2010 int bs0, bs1, p, len;
6d36483b 2011
c9da5f4d 2012 if (INTVAL (operands[2]) == 0)
2013 return "copy %1,%0";
e057641f 2014
c9da5f4d 2015 for (bs0 = 0; bs0 < 32; bs0++)
2016 if ((mask & (1 << bs0)) != 0)
2017 break;
e057641f 2018
c9da5f4d 2019 for (bs1 = bs0; bs1 < 32; bs1++)
2020 if ((mask & (1 << bs1)) == 0)
2021 break;
e057641f 2022
3745c59b 2023 if (bs1 != 32 && ((unsigned HOST_WIDE_INT) 1 << bs1) <= mask)
c9da5f4d 2024 abort();
e057641f 2025
c9da5f4d 2026 p = 31 - bs0;
2027 len = bs1 - bs0;
e057641f 2028
ef618fe4 2029 operands[2] = GEN_INT (p);
2030 operands[3] = GEN_INT (len);
c9da5f4d 2031 return "depi -1,%2,%3,%0";
e057641f 2032}
2033\f
87ad11b0 2034/* Output an ascii string. */
57ed30e5 2035void
87ad11b0 2036output_ascii (file, p, size)
2037 FILE *file;
2038 unsigned char *p;
2039 int size;
2040{
2041 int i;
2042 int chars_output;
2043 unsigned char partial_output[16]; /* Max space 4 chars can occupy. */
2044
2045 /* The HP assembler can only take strings of 256 characters at one
2046 time. This is a limitation on input line length, *not* the
2047 length of the string. Sigh. Even worse, it seems that the
2048 restriction is in number of input characters (see \xnn &
2049 \whatever). So we have to do this very carefully. */
2050
9c0ac0fd 2051 fputs ("\t.STRING \"", file);
87ad11b0 2052
2053 chars_output = 0;
2054 for (i = 0; i < size; i += 4)
2055 {
2056 int co = 0;
2057 int io = 0;
2058 for (io = 0, co = 0; io < MIN (4, size - i); io++)
2059 {
2060 register unsigned int c = p[i + io];
2061
2062 if (c == '\"' || c == '\\')
2063 partial_output[co++] = '\\';
2064 if (c >= ' ' && c < 0177)
2065 partial_output[co++] = c;
2066 else
2067 {
2068 unsigned int hexd;
2069 partial_output[co++] = '\\';
2070 partial_output[co++] = 'x';
2071 hexd = c / 16 - 0 + '0';
2072 if (hexd > '9')
2073 hexd -= '9' - 'a' + 1;
2074 partial_output[co++] = hexd;
2075 hexd = c % 16 - 0 + '0';
2076 if (hexd > '9')
2077 hexd -= '9' - 'a' + 1;
2078 partial_output[co++] = hexd;
2079 }
2080 }
2081 if (chars_output + co > 243)
2082 {
9c0ac0fd 2083 fputs ("\"\n\t.STRING \"", file);
87ad11b0 2084 chars_output = 0;
2085 }
2086 fwrite (partial_output, 1, co, file);
2087 chars_output += co;
2088 co = 0;
2089 }
9c0ac0fd 2090 fputs ("\"\n", file);
87ad11b0 2091}
c533da59 2092
2093/* Try to rewrite floating point comparisons & branches to avoid
2094 useless add,tr insns.
2095
2096 CHECK_NOTES is nonzero if we should examine REG_DEAD notes
2097 to see if FPCC is dead. CHECK_NOTES is nonzero for the
2098 first attempt to remove useless add,tr insns. It is zero
2099 for the second pass as reorg sometimes leaves bogus REG_DEAD
2100 notes lying around.
2101
2102 When CHECK_NOTES is zero we can only eliminate add,tr insns
2103 when there's a 1:1 correspondence between fcmp and ftest/fbranch
2104 instructions. */
2105void
2106remove_useless_addtr_insns (insns, check_notes)
2107 rtx insns;
2108 int check_notes;
2109{
2110 rtx insn;
2111 int all;
2112 static int pass = 0;
2113
2114 /* This is fairly cheap, so always run it when optimizing. */
2115 if (optimize > 0)
2116 {
2117 int fcmp_count = 0;
2118 int fbranch_count = 0;
2119
2120 /* Walk all the insns in this function looking for fcmp & fbranch
2121 instructions. Keep track of how many of each we find. */
2122 insns = get_insns ();
2123 for (insn = insns; insn; insn = next_insn (insn))
2124 {
2125 rtx tmp;
2126
2127 /* Ignore anything that isn't an INSN or a JUMP_INSN. */
2128 if (GET_CODE (insn) != INSN && GET_CODE (insn) != JUMP_INSN)
2129 continue;
2130
2131 tmp = PATTERN (insn);
2132
2133 /* It must be a set. */
2134 if (GET_CODE (tmp) != SET)
2135 continue;
2136
2137 /* If the destination is CCFP, then we've found an fcmp insn. */
2138 tmp = SET_DEST (tmp);
2139 if (GET_CODE (tmp) == REG && REGNO (tmp) == 0)
2140 {
2141 fcmp_count++;
2142 continue;
2143 }
2144
2145 tmp = PATTERN (insn);
2146 /* If this is an fbranch instruction, bump the fbranch counter. */
2147 if (GET_CODE (tmp) == SET
2148 && SET_DEST (tmp) == pc_rtx
2149 && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
2150 && GET_CODE (XEXP (SET_SRC (tmp), 0)) == NE
2151 && GET_CODE (XEXP (XEXP (SET_SRC (tmp), 0), 0)) == REG
2152 && REGNO (XEXP (XEXP (SET_SRC (tmp), 0), 0)) == 0)
2153 {
2154 fbranch_count++;
2155 continue;
2156 }
2157 }
2158
2159
2160 /* Find all floating point compare + branch insns. If possible,
2161 reverse the comparison & the branch to avoid add,tr insns. */
2162 for (insn = insns; insn; insn = next_insn (insn))
2163 {
2164 rtx tmp, next;
2165
2166 /* Ignore anything that isn't an INSN. */
2167 if (GET_CODE (insn) != INSN)
2168 continue;
2169
2170 tmp = PATTERN (insn);
2171
2172 /* It must be a set. */
2173 if (GET_CODE (tmp) != SET)
2174 continue;
2175
2176 /* The destination must be CCFP, which is register zero. */
2177 tmp = SET_DEST (tmp);
2178 if (GET_CODE (tmp) != REG || REGNO (tmp) != 0)
2179 continue;
2180
2181 /* INSN should be a set of CCFP.
2182
2183 See if the result of this insn is used in a reversed FP
2184 conditional branch. If so, reverse our condition and
2185 the branch. Doing so avoids useless add,tr insns. */
2186 next = next_insn (insn);
2187 while (next)
2188 {
2189 /* Jumps, calls and labels stop our search. */
2190 if (GET_CODE (next) == JUMP_INSN
2191 || GET_CODE (next) == CALL_INSN
2192 || GET_CODE (next) == CODE_LABEL)
2193 break;
2194
2195 /* As does another fcmp insn. */
2196 if (GET_CODE (next) == INSN
2197 && GET_CODE (PATTERN (next)) == SET
2198 && GET_CODE (SET_DEST (PATTERN (next))) == REG
2199 && REGNO (SET_DEST (PATTERN (next))) == 0)
2200 break;
2201
2202 next = next_insn (next);
2203 }
2204
2205 /* Is NEXT_INSN a branch? */
2206 if (next
2207 && GET_CODE (next) == JUMP_INSN)
2208 {
2209 rtx pattern = PATTERN (next);
2210
2211 /* If it a reversed fp conditional branch (eg uses add,tr)
2212 and CCFP dies, then reverse our conditional and the branch
2213 to avoid the add,tr. */
2214 if (GET_CODE (pattern) == SET
2215 && SET_DEST (pattern) == pc_rtx
2216 && GET_CODE (SET_SRC (pattern)) == IF_THEN_ELSE
2217 && GET_CODE (XEXP (SET_SRC (pattern), 0)) == NE
2218 && GET_CODE (XEXP (XEXP (SET_SRC (pattern), 0), 0)) == REG
2219 && REGNO (XEXP (XEXP (SET_SRC (pattern), 0), 0)) == 0
2220 && GET_CODE (XEXP (SET_SRC (pattern), 1)) == PC
2221 && (fcmp_count == fbranch_count
2222 || (check_notes
2223 && find_regno_note (next, REG_DEAD, 0))))
2224 {
2225 /* Reverse the branch. */
2226 tmp = XEXP (SET_SRC (pattern), 1);
2227 XEXP (SET_SRC (pattern), 1) = XEXP (SET_SRC (pattern), 2);
2228 XEXP (SET_SRC (pattern), 2) = tmp;
2229 INSN_CODE (next) = -1;
2230
2231 /* Reverse our condition. */
2232 tmp = PATTERN (insn);
2233 PUT_CODE (XEXP (tmp, 1),
2234 reverse_condition (GET_CODE (XEXP (tmp, 1))));
2235 }
2236 }
2237 }
2238 }
2239
2240 pass = !pass;
2241
2242}
87ad11b0 2243\f
201f01e9 2244/* You may have trouble believing this, but this is the HP-PA stack
87ad11b0 2245 layout. Wow.
2246
2247 Offset Contents
2248
2249 Variable arguments (optional; any number may be allocated)
2250
2251 SP-(4*(N+9)) arg word N
2252 : :
2253 SP-56 arg word 5
2254 SP-52 arg word 4
2255
2256 Fixed arguments (must be allocated; may remain unused)
2257
2258 SP-48 arg word 3
2259 SP-44 arg word 2
2260 SP-40 arg word 1
2261 SP-36 arg word 0
2262
2263 Frame Marker
2264
2265 SP-32 External Data Pointer (DP)
2266 SP-28 External sr4
2267 SP-24 External/stub RP (RP')
2268 SP-20 Current RP
2269 SP-16 Static Link
2270 SP-12 Clean up
2271 SP-8 Calling Stub RP (RP'')
2272 SP-4 Previous SP
2273
2274 Top of Frame
2275
2276 SP-0 Stack Pointer (points to next available address)
2277
2278*/
2279
2280/* This function saves registers as follows. Registers marked with ' are
2281 this function's registers (as opposed to the previous function's).
2282 If a frame_pointer isn't needed, r4 is saved as a general register;
2283 the space for the frame pointer is still allocated, though, to keep
2284 things simple.
2285
2286
2287 Top of Frame
2288
2289 SP (FP') Previous FP
2290 SP + 4 Alignment filler (sigh)
2291 SP + 8 Space for locals reserved here.
2292 .
2293 .
2294 .
2295 SP + n All call saved register used.
2296 .
2297 .
2298 .
2299 SP + o All call saved fp registers used.
2300 .
2301 .
2302 .
2303 SP + p (SP') points to next available address.
6d36483b 2304
87ad11b0 2305*/
2306
daee63dd 2307/* Emit RTL to store REG at the memory location specified by BASE+DISP.
2308 Handle case where DISP > 8k by using the add_high_const pattern.
2309
2310 Note in DISP > 8k case, we will leave the high part of the address
2311 in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
2312static void
2313store_reg (reg, disp, base)
2314 int reg, disp, base;
87ad11b0 2315{
2316 if (VAL_14_BITS_P (disp))
daee63dd 2317 {
6d36483b 2318 emit_move_insn (gen_rtx (MEM, SImode,
2319 gen_rtx (PLUS, SImode,
daee63dd 2320 gen_rtx (REG, SImode, base),
2321 GEN_INT (disp))),
2322 gen_rtx (REG, SImode, reg));
2323 }
87ad11b0 2324 else
daee63dd 2325 {
6d36483b 2326 emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
2327 gen_rtx (REG, SImode, base),
daee63dd 2328 GEN_INT (disp)));
2329 emit_move_insn (gen_rtx (MEM, SImode,
6d36483b 2330 gen_rtx (LO_SUM, SImode,
daee63dd 2331 gen_rtx (REG, SImode, 1),
2332 GEN_INT (disp))),
2333 gen_rtx (REG, SImode, reg));
2334 }
87ad11b0 2335}
2336
daee63dd 2337/* Emit RTL to load REG from the memory location specified by BASE+DISP.
2338 Handle case where DISP > 8k by using the add_high_const pattern.
2339
2340 Note in DISP > 8k case, we will leave the high part of the address
2341 in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
2342static void
2343load_reg (reg, disp, base)
2344 int reg, disp, base;
2345{
2346 if (VAL_14_BITS_P (disp))
2347 {
2348 emit_move_insn (gen_rtx (REG, SImode, reg),
6d36483b 2349 gen_rtx (MEM, SImode,
2350 gen_rtx (PLUS, SImode,
daee63dd 2351 gen_rtx (REG, SImode, base),
2352 GEN_INT (disp))));
daee63dd 2353 }
2354 else
2355 {
6d36483b 2356 emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
daee63dd 2357 gen_rtx (REG, SImode, base),
2358 GEN_INT (disp)));
2359 emit_move_insn (gen_rtx (REG, SImode, reg),
2360 gen_rtx (MEM, SImode,
6d36483b 2361 gen_rtx (LO_SUM, SImode,
2362 gen_rtx (REG, SImode, 1),
daee63dd 2363 GEN_INT (disp))));
2364 }
2365}
2366
2367/* Emit RTL to set REG to the value specified by BASE+DISP.
2368 Handle case where DISP > 8k by using the add_high_const pattern.
2369
2370 Note in DISP > 8k case, we will leave the high part of the address
2371 in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
2372static void
2373set_reg_plus_d(reg, base, disp)
2374 int reg, base, disp;
87ad11b0 2375{
2376 if (VAL_14_BITS_P (disp))
daee63dd 2377 {
2378 emit_move_insn (gen_rtx (REG, SImode, reg),
6d36483b 2379 gen_rtx (PLUS, SImode,
daee63dd 2380 gen_rtx (REG, SImode, base),
2381 GEN_INT (disp)));
daee63dd 2382 }
87ad11b0 2383 else
daee63dd 2384 {
6d36483b 2385 emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
daee63dd 2386 gen_rtx (REG, SImode, base),
2387 GEN_INT (disp)));
2388 emit_move_insn (gen_rtx (REG, SImode, reg),
6d36483b 2389 gen_rtx (LO_SUM, SImode,
daee63dd 2390 gen_rtx (REG, SImode, 1),
2391 GEN_INT (disp)));
2392 }
87ad11b0 2393}
2394
3ddcbb9d 2395/* Global variables set by FUNCTION_PROLOGUE. */
2396/* Size of frame. Need to know this to emit return insns from
2397 leaf procedures. */
a1ab4fa3 2398static int actual_fsize;
2399static int local_fsize, save_fregs;
3ddcbb9d 2400
87ad11b0 2401int
a1ab4fa3 2402compute_frame_size (size, fregs_live)
87ad11b0 2403 int size;
3ddcbb9d 2404 int *fregs_live;
87ad11b0 2405{
2406 extern int current_function_outgoing_args_size;
a1ab4fa3 2407 int i, fsize;
87ad11b0 2408
6d36483b 2409 /* 8 is space for frame pointer + filler. If any frame is allocated
a1ab4fa3 2410 we need to add this in because of STARTING_FRAME_OFFSET. */
2411 fsize = size + (size || frame_pointer_needed ? 8 : 0);
87ad11b0 2412
98328a39 2413 /* We must leave enough space for all the callee saved registers
2414 from 3 .. highest used callee save register since we don't
2415 know if we're going to have an inline or out of line prologue
2416 and epilogue. */
7f7c4869 2417 for (i = 18; i >= 3; i--)
2418 if (regs_ever_live[i])
2419 {
2420 fsize += 4 * (i - 2);
2421 break;
2422 }
002fc5f7 2423
7f7c4869 2424 /* Round the stack. */
df0651dc 2425 fsize = (fsize + 7) & ~7;
2426
98328a39 2427 /* We must leave enough space for all the callee saved registers
2428 from 3 .. highest used callee save register since we don't
2429 know if we're going to have an inline or out of line prologue
2430 and epilogue. */
df0651dc 2431 for (i = 66; i >= 48; i -= 2)
2432 if (regs_ever_live[i] || regs_ever_live[i + 1])
2433 {
df0651dc 2434 if (fregs_live)
2435 *fregs_live = 1;
002fc5f7 2436
c839764f 2437 fsize += 4 * (i - 46);
7f7c4869 2438 break;
df0651dc 2439 }
2440
a1ab4fa3 2441 fsize += current_function_outgoing_args_size;
2442 if (! leaf_function_p () || fsize)
2443 fsize += 32;
57ed30e5 2444 return (fsize + 63) & ~63;
87ad11b0 2445}
6d36483b 2446
daee63dd 2447rtx hp_profile_label_rtx;
2448static char hp_profile_label_name[8];
87ad11b0 2449void
a1ab4fa3 2450output_function_prologue (file, size)
87ad11b0 2451 FILE *file;
2452 int size;
87ad11b0 2453{
d151162a 2454 /* The function's label and associated .PROC must never be
2455 separated and must be output *after* any profiling declarations
2456 to avoid changing spaces/subspaces within a procedure. */
2457 ASM_OUTPUT_LABEL (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
2458 fputs ("\t.PROC\n", file);
2459
daee63dd 2460 /* hppa_expand_prologue does the dirty work now. We just need
2461 to output the assembler directives which denote the start
2462 of a function. */
2acd4f33 2463 fprintf (file, "\t.CALLINFO FRAME=%d", actual_fsize);
daee63dd 2464 if (regs_ever_live[2] || profile_flag)
9c0ac0fd 2465 fputs (",CALLS,SAVE_RP", file);
daee63dd 2466 else
9c0ac0fd 2467 fputs (",NO_CALLS", file);
f3ba7709 2468
2469 if (frame_pointer_needed)
9c0ac0fd 2470 fputs (",SAVE_SP", file);
f3ba7709 2471
a9960cdc 2472 /* Pass on information about the number of callee register saves
9b0c95be 2473 performed in the prologue.
2474
2475 The compiler is supposed to pass the highest register number
6d36483b 2476 saved, the assembler then has to adjust that number before
9b0c95be 2477 entering it into the unwind descriptor (to account for any
6d36483b 2478 caller saved registers with lower register numbers than the
9b0c95be 2479 first callee saved register). */
2480 if (gr_saved)
2481 fprintf (file, ",ENTRY_GR=%d", gr_saved + 2);
2482
2483 if (fr_saved)
2484 fprintf (file, ",ENTRY_FR=%d", fr_saved + 11);
a9960cdc 2485
9c0ac0fd 2486 fputs ("\n\t.ENTRY\n", file);
daee63dd 2487
2488 /* Horrid hack. emit_function_prologue will modify this RTL in
2489 place to get the expected results. */
2490 if (profile_flag)
07b209fc 2491 ASM_GENERATE_INTERNAL_LABEL (hp_profile_label_name, "LP",
2492 hp_profile_labelno);
06ddb6f8 2493
f9333726 2494 /* If we're using GAS and not using the portable runtime model, then
2495 we don't need to accumulate the total number of code bytes. */
2496 if (TARGET_GAS && ! TARGET_PORTABLE_RUNTIME)
2497 total_code_bytes = 0;
2498 else if (insn_addresses)
06ddb6f8 2499 {
2500 unsigned int old_total = total_code_bytes;
2501
2502 total_code_bytes += insn_addresses[INSN_UID (get_last_insn())];
f9333726 2503 total_code_bytes += FUNCTION_BOUNDARY / BITS_PER_UNIT;
06ddb6f8 2504
2505 /* Be prepared to handle overflows. */
2506 total_code_bytes = old_total > total_code_bytes ? -1 : total_code_bytes;
2507 }
2508 else
2509 total_code_bytes = -1;
c533da59 2510
2511 remove_useless_addtr_insns (get_insns (), 0);
daee63dd 2512}
2513
57ed30e5 2514void
daee63dd 2515hppa_expand_prologue()
2516{
87ad11b0 2517 extern char call_used_regs[];
daee63dd 2518 int size = get_frame_size ();
afd7b680 2519 int merge_sp_adjust_with_store = 0;
daee63dd 2520 int i, offset;
2521 rtx tmpreg, size_rtx;
2522
a9960cdc 2523 gr_saved = 0;
2524 fr_saved = 0;
3ddcbb9d 2525 save_fregs = 0;
a1ab4fa3 2526 local_fsize = size + (size || frame_pointer_needed ? 8 : 0);
2527 actual_fsize = compute_frame_size (size, &save_fregs);
87ad11b0 2528
daee63dd 2529 /* Compute a few things we will use often. */
2530 tmpreg = gen_rtx (REG, SImode, 1);
2531 size_rtx = GEN_INT (actual_fsize);
87ad11b0 2532
002fc5f7 2533 /* Handle out of line prologues and epilogues. */
2534 if (TARGET_SPACE)
2535 {
2536 rtx operands[2];
2537 int saves = 0;
7f7c4869 2538 int outline_insn_count = 0;
2539 int inline_insn_count = 0;
002fc5f7 2540
7f7c4869 2541 /* Count the number of insns for the inline and out of line
2542 variants so we can choose one appropriately.
002fc5f7 2543
7f7c4869 2544 No need to screw with counting actual_fsize operations -- they're
2545 done for both inline and out of line prologues. */
2546 if (regs_ever_live[2])
2547 inline_insn_count += 1;
2548
2549 if (! cint_ok_for_move (local_fsize))
2550 outline_insn_count += 2;
2551 else
2552 outline_insn_count += 1;
002fc5f7 2553
2554 /* Put the register save info into %r22. */
2555 for (i = 18; i >= 3; i--)
2556 if (regs_ever_live[i] && ! call_used_regs[i])
2557 {
7f7c4869 2558 /* -1 because the stack adjustment is normally done in
2559 the same insn as a register save. */
2560 inline_insn_count += (i - 2) - 1;
002fc5f7 2561 saves = i;
2562 break;
2563 }
7f7c4869 2564
002fc5f7 2565 for (i = 66; i >= 48; i -= 2)
2566 if (regs_ever_live[i] || regs_ever_live[i + 1])
2567 {
7f7c4869 2568 /* +1 needed as we load %r1 with the start of the freg
2569 save area. */
2570 inline_insn_count += (i/2 - 23) + 1;
002fc5f7 2571 saves |= ((i/2 - 12 ) << 16);
2572 break;
2573 }
2574
7f7c4869 2575 if (frame_pointer_needed)
2576 inline_insn_count += 3;
002fc5f7 2577
7f7c4869 2578 if (! cint_ok_for_move (saves))
2579 outline_insn_count += 2;
2580 else
2581 outline_insn_count += 1;
2582
2583 if (TARGET_PORTABLE_RUNTIME)
2584 outline_insn_count += 2;
2585 else
2586 outline_insn_count += 1;
2587
2588 /* If there's a lot of insns in the prologue, then do it as
2589 an out-of-line sequence. */
2590 if (inline_insn_count > outline_insn_count)
2591 {
2592 /* Put the local_fisze into %r19. */
2593 operands[0] = gen_rtx (REG, SImode, 19);
2594 operands[1] = GEN_INT (local_fsize);
2595 emit_move_insn (operands[0], operands[1]);
2596
2597 /* Put the stack size into %r21. */
2598 operands[0] = gen_rtx (REG, SImode, 21);
2599 operands[1] = size_rtx;
2600 emit_move_insn (operands[0], operands[1]);
2601
2602 operands[0] = gen_rtx (REG, SImode, 22);
2603 operands[1] = GEN_INT (saves);
2604 emit_move_insn (operands[0], operands[1]);
2605
2606 /* Now call the out-of-line prologue. */
2607 emit_insn (gen_outline_prologue_call ());
2608 emit_insn (gen_blockage ());
2609
2610 /* Note that we're using an out-of-line prologue. */
2611 out_of_line_prologue_epilogue = 1;
2612 return;
2613 }
002fc5f7 2614 }
2615
7f7c4869 2616 out_of_line_prologue_epilogue = 0;
2617
6d36483b 2618 /* Save RP first. The calling conventions manual states RP will
daee63dd 2619 always be stored into the caller's frame at sp-20. */
372ef038 2620 if (regs_ever_live[2] || profile_flag)
6d36483b 2621 store_reg (2, -20, STACK_POINTER_REGNUM);
2622
daee63dd 2623 /* Allocate the local frame and set up the frame pointer if needed. */
a1ab4fa3 2624 if (actual_fsize)
2625 if (frame_pointer_needed)
2626 {
daee63dd 2627 /* Copy the old frame pointer temporarily into %r1. Set up the
2628 new stack pointer, then store away the saved old frame pointer
2629 into the stack at sp+actual_fsize and at the same time update
2630 the stack pointer by actual_fsize bytes. Two versions, first
2631 handles small (<8k) frames. The second handles large (>8k)
2632 frames. */
2633 emit_move_insn (tmpreg, frame_pointer_rtx);
2634 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
a1ab4fa3 2635 if (VAL_14_BITS_P (actual_fsize))
00a87639 2636 emit_insn (gen_post_stwm (stack_pointer_rtx, tmpreg, size_rtx));
a1ab4fa3 2637 else
2638 {
b75ad75e 2639 /* It is incorrect to store the saved frame pointer at *sp,
2640 then increment sp (writes beyond the current stack boundary).
2641
2642 So instead use stwm to store at *sp and post-increment the
2643 stack pointer as an atomic operation. Then increment sp to
2644 finish allocating the new frame. */
00a87639 2645 emit_insn (gen_post_stwm (stack_pointer_rtx, tmpreg, GEN_INT (64)));
daee63dd 2646 set_reg_plus_d (STACK_POINTER_REGNUM,
2647 STACK_POINTER_REGNUM,
b75ad75e 2648 actual_fsize - 64);
a1ab4fa3 2649 }
2650 }
daee63dd 2651 /* no frame pointer needed. */
a1ab4fa3 2652 else
a1ab4fa3 2653 {
daee63dd 2654 /* In some cases we can perform the first callee register save
2655 and allocating the stack frame at the same time. If so, just
2656 make a note of it and defer allocating the frame until saving
2657 the callee registers. */
6d36483b 2658 if (VAL_14_BITS_P (-actual_fsize)
2659 && local_fsize == 0
daee63dd 2660 && ! profile_flag
2661 && ! flag_pic)
afd7b680 2662 merge_sp_adjust_with_store = 1;
daee63dd 2663 /* Can not optimize. Adjust the stack frame by actual_fsize bytes. */
2664 else if (actual_fsize != 0)
2665 set_reg_plus_d (STACK_POINTER_REGNUM,
2666 STACK_POINTER_REGNUM,
2667 actual_fsize);
a1ab4fa3 2668 }
201f01e9 2669 /* The hppa calling conventions say that that %r19, the pic offset
daee63dd 2670 register, is saved at sp - 32 (in this function's frame) when
9f33c102 2671 generating PIC code. FIXME: What is the correct thing to do
2672 for functions which make no calls and allocate no frame? Do
2673 we need to allocate a frame, or can we just omit the save? For
2674 now we'll just omit the save. */
2675 if (actual_fsize != 0 && flag_pic)
6d36483b 2676 store_reg (PIC_OFFSET_TABLE_REGNUM, -32, STACK_POINTER_REGNUM);
daee63dd 2677
2678 /* Profiling code.
372ef038 2679
daee63dd 2680 Instead of taking one argument, the counter label, as most normal
2681 mcounts do, _mcount appears to behave differently on the HPPA. It
6d36483b 2682 takes the return address of the caller, the address of this routine,
2683 and the address of the label. Also, it isn't magic, so
01cc3b75 2684 argument registers have to be preserved. */
372ef038 2685 if (profile_flag)
2686 {
daee63dd 2687 int pc_offset, i, arg_offset, basereg, offsetadj;
2688
2689 pc_offset = 4 + (frame_pointer_needed
2690 ? (VAL_14_BITS_P (actual_fsize) ? 12 : 20)
2691 : (VAL_14_BITS_P (actual_fsize) ? 4 : 8));
2692
2693 /* When the function has a frame pointer, use it as the base
2694 register for saving/restore registers. Else use the stack
2695 pointer. Adjust the offset according to the frame size if
2696 this function does not have a frame pointer. */
d2daf090 2697
2698 basereg = frame_pointer_needed ? FRAME_POINTER_REGNUM
2699 : STACK_POINTER_REGNUM;
2700 offsetadj = frame_pointer_needed ? 0 : actual_fsize;
2701
daee63dd 2702 /* Horrid hack. emit_function_prologue will modify this RTL in
2703 place to get the expected results. sprintf here is just to
2704 put something in the name. */
2705 sprintf(hp_profile_label_name, "LP$%04d", -1);
2706 hp_profile_label_rtx = gen_rtx (SYMBOL_REF, SImode,
2707 hp_profile_label_name);
d6f01525 2708 if (current_function_returns_struct)
daee63dd 2709 store_reg (STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg);
2710
d2daf090 2711 for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
daee63dd 2712 if (regs_ever_live [i])
372ef038 2713 {
daee63dd 2714 store_reg (i, arg_offset, basereg);
2715 /* Deal with arg_offset not fitting in 14 bits. */
d2daf090 2716 pc_offset += VAL_14_BITS_P (arg_offset) ? 4 : 8;
372ef038 2717 }
daee63dd 2718
2719 emit_move_insn (gen_rtx (REG, SImode, 26), gen_rtx (REG, SImode, 2));
2720 emit_move_insn (tmpreg, gen_rtx (HIGH, SImode, hp_profile_label_rtx));
2721 emit_move_insn (gen_rtx (REG, SImode, 24),
2722 gen_rtx (LO_SUM, SImode, tmpreg, hp_profile_label_rtx));
2723 /* %r25 is set from within the output pattern. */
2724 emit_insn (gen_call_profiler (GEN_INT (- pc_offset - 20)));
2725
2726 /* Restore argument registers. */
d2daf090 2727 for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
daee63dd 2728 if (regs_ever_live [i])
2729 load_reg (i, arg_offset, basereg);
2730
d6f01525 2731 if (current_function_returns_struct)
daee63dd 2732 load_reg (STRUCT_VALUE_REGNUM, -12 - offsetadj, basereg);
2733
372ef038 2734 }
2735
6d36483b 2736 /* Normal register save.
daee63dd 2737
2738 Do not save the frame pointer in the frame_pointer_needed case. It
2739 was done earlier. */
87ad11b0 2740 if (frame_pointer_needed)
2741 {
df0651dc 2742 for (i = 18, offset = local_fsize; i >= 4; i--)
98328a39 2743 if (regs_ever_live[i] && ! call_used_regs[i])
87ad11b0 2744 {
6d36483b 2745 store_reg (i, offset, FRAME_POINTER_REGNUM);
daee63dd 2746 offset += 4;
a9960cdc 2747 gr_saved++;
87ad11b0 2748 }
7f7c4869 2749 /* Account for %r3 which is saved in a special place. */
9b0c95be 2750 gr_saved++;
87ad11b0 2751 }
daee63dd 2752 /* No frame pointer needed. */
87ad11b0 2753 else
2754 {
daee63dd 2755 for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
98328a39 2756 if (regs_ever_live[i] && ! call_used_regs[i])
87ad11b0 2757 {
6d36483b 2758 /* If merge_sp_adjust_with_store is nonzero, then we can
afd7b680 2759 optimize the first GR save. */
201f01e9 2760 if (merge_sp_adjust_with_store)
afd7b680 2761 {
2762 merge_sp_adjust_with_store = 0;
daee63dd 2763 emit_insn (gen_post_stwm (stack_pointer_rtx,
00a87639 2764 gen_rtx (REG, SImode, i),
2765 GEN_INT (-offset)));
afd7b680 2766 }
2767 else
daee63dd 2768 store_reg (i, offset, STACK_POINTER_REGNUM);
2769 offset += 4;
a9960cdc 2770 gr_saved++;
87ad11b0 2771 }
daee63dd 2772
afd7b680 2773 /* If we wanted to merge the SP adjustment with a GR save, but we never
daee63dd 2774 did any GR saves, then just emit the adjustment here. */
201f01e9 2775 if (merge_sp_adjust_with_store)
daee63dd 2776 set_reg_plus_d (STACK_POINTER_REGNUM,
2777 STACK_POINTER_REGNUM,
2778 actual_fsize);
87ad11b0 2779 }
6d36483b 2780
87ad11b0 2781 /* Align pointer properly (doubleword boundary). */
2782 offset = (offset + 7) & ~7;
2783
2784 /* Floating point register store. */
2785 if (save_fregs)
87ad11b0 2786 {
daee63dd 2787 /* First get the frame or stack pointer to the start of the FP register
2788 save area. */
a1ab4fa3 2789 if (frame_pointer_needed)
daee63dd 2790 set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
a1ab4fa3 2791 else
daee63dd 2792 set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
2793
2794 /* Now actually save the FP registers. */
df0651dc 2795 for (i = 66; i >= 48; i -= 2)
7f7c4869 2796 {
98328a39 2797 if (regs_ever_live[i] || regs_ever_live[i + 1])
7f7c4869 2798 {
7f7c4869 2799 emit_move_insn (gen_rtx (MEM, DFmode,
2800 gen_rtx (POST_INC, DFmode, tmpreg)),
2801 gen_rtx (REG, DFmode, i));
2802 fr_saved++;
2803 }
2804 }
87ad11b0 2805 }
6f978154 2806
2807 /* When generating PIC code it is necessary to save/restore the
2808 PIC register around each function call. We used to do this
2809 in the call patterns themselves, but that implementation
2810 made incorrect assumptions about using global variables to hold
2811 per-function rtl code generated in the backend.
2812
2813 So instead, we copy the PIC register into a reserved callee saved
2814 register in the prologue. Then after each call we reload the PIC
2815 register from the callee saved register. We also reload the PIC
2816 register from the callee saved register in the epilogue ensure the
2817 PIC register is valid at function exit.
2818
2819 This may (depending on the exact characteristics of the function)
2820 even be more efficient.
2821
2822 Avoid this if the callee saved register wasn't used (these are
42819d4e 2823 leaf functions). */
6f978154 2824 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM_SAVED])
2825 emit_move_insn (gen_rtx (REG, SImode, PIC_OFFSET_TABLE_REGNUM_SAVED),
2826 gen_rtx (REG, SImode, PIC_OFFSET_TABLE_REGNUM));
87ad11b0 2827}
2828
daee63dd 2829
87ad11b0 2830void
a1ab4fa3 2831output_function_epilogue (file, size)
87ad11b0 2832 FILE *file;
2833 int size;
87ad11b0 2834{
3695c664 2835 rtx insn = get_last_insn ();
e3f53689 2836 int i;
3695c664 2837
daee63dd 2838 /* hppa_expand_epilogue does the dirty work now. We just need
2839 to output the assembler directives which denote the end
3695c664 2840 of a function.
2841
2842 To make debuggers happy, emit a nop if the epilogue was completely
2843 eliminated due to a volatile call as the last insn in the
6d36483b 2844 current function. That way the return address (in %r2) will
3695c664 2845 always point to a valid instruction in the current function. */
2846
2847 /* Get the last real insn. */
2848 if (GET_CODE (insn) == NOTE)
2849 insn = prev_real_insn (insn);
2850
2851 /* If it is a sequence, then look inside. */
2852 if (insn && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
2853 insn = XVECEXP (PATTERN (insn), 0, 0);
2854
6d36483b 2855 /* If insn is a CALL_INSN, then it must be a call to a volatile
3695c664 2856 function (otherwise there would be epilogue insns). */
2857 if (insn && GET_CODE (insn) == CALL_INSN)
9c0ac0fd 2858 fputs ("\tnop\n", file);
6d36483b 2859
9c0ac0fd 2860 fputs ("\t.EXIT\n\t.PROCEND\n", file);
e3f53689 2861
2862 /* If we have deferred plabels, then we need to switch into the data
2863 section and align it to a 4 byte boundary before we output the
2864 deferred plabels. */
2865 if (n_deferred_plabels)
2866 {
2867 data_section ();
2868 ASM_OUTPUT_ALIGN (file, 2);
2869 }
2870
2871 /* Now output the deferred plabels. */
2872 for (i = 0; i < n_deferred_plabels; i++)
2873 {
2874 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (deferred_plabels[i].internal_label));
35661368 2875 assemble_integer (deferred_plabels[i].symbol, 4, 1);
e3f53689 2876 }
2877 n_deferred_plabels = 0;
daee63dd 2878}
afd7b680 2879
daee63dd 2880void
3695c664 2881hppa_expand_epilogue ()
daee63dd 2882{
6d36483b 2883 rtx tmpreg;
daee63dd 2884 int offset,i;
2885 int merge_sp_adjust_with_load = 0;
2886
002fc5f7 2887 /* Handle out of line prologues and epilogues. */
7f7c4869 2888 if (TARGET_SPACE && out_of_line_prologue_epilogue)
002fc5f7 2889 {
2890 int saves = 0;
2891 rtx operands[2];
2892
2893 /* Put the register save info into %r22. */
2894 for (i = 18; i >= 3; i--)
2895 if (regs_ever_live[i] && ! call_used_regs[i])
2896 {
2897 saves = i;
2898 break;
2899 }
2900
2901 for (i = 66; i >= 48; i -= 2)
2902 if (regs_ever_live[i] || regs_ever_live[i + 1])
2903 {
2904 saves |= ((i/2 - 12 ) << 16);
2905 break;
2906 }
2907
2908 emit_insn (gen_blockage ());
2909
2910 /* Put the local_fisze into %r19. */
2911 operands[0] = gen_rtx (REG, SImode, 19);
2912 operands[1] = GEN_INT (local_fsize);
2913 emit_move_insn (operands[0], operands[1]);
2914
7f7c4869 2915 /* Put the stack size into %r21. */
2916 operands[0] = gen_rtx (REG, SImode, 21);
2917 operands[1] = GEN_INT (actual_fsize);
2918 emit_move_insn (operands[0], operands[1]);
2919
002fc5f7 2920 operands[0] = gen_rtx (REG, SImode, 22);
2921 operands[1] = GEN_INT (saves);
2922 emit_move_insn (operands[0], operands[1]);
2923
2924 /* Now call the out-of-line epilogue. */
2925 emit_insn (gen_outline_epilogue_call ());
2926 return;
2927 }
2928
daee63dd 2929 /* We will use this often. */
2930 tmpreg = gen_rtx (REG, SImode, 1);
2931
2932 /* Try to restore RP early to avoid load/use interlocks when
2933 RP gets used in the return (bv) instruction. This appears to still
2934 be necessary even when we schedule the prologue and epilogue. */
afd7b680 2935 if (frame_pointer_needed
2936 && (regs_ever_live [2] || profile_flag))
daee63dd 2937 load_reg (2, -20, FRAME_POINTER_REGNUM);
87ad11b0 2938
daee63dd 2939 /* No frame pointer, and stack is smaller than 8k. */
2940 else if (! frame_pointer_needed
2941 && VAL_14_BITS_P (actual_fsize + 20)
2942 && (regs_ever_live[2] || profile_flag))
2943 load_reg (2, - (actual_fsize + 20), STACK_POINTER_REGNUM);
2944
2945 /* General register restores. */
87ad11b0 2946 if (frame_pointer_needed)
2947 {
df0651dc 2948 for (i = 18, offset = local_fsize; i >= 4; i--)
98328a39 2949 if (regs_ever_live[i] && ! call_used_regs[i])
87ad11b0 2950 {
daee63dd 2951 load_reg (i, offset, FRAME_POINTER_REGNUM);
2952 offset += 4;
87ad11b0 2953 }
87ad11b0 2954 }
2955 else
2956 {
daee63dd 2957 for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
7f7c4869 2958 {
98328a39 2959 if (regs_ever_live[i] && ! call_used_regs[i])
7f7c4869 2960 {
7f7c4869 2961 /* Only for the first load.
2962 merge_sp_adjust_with_load holds the register load
2963 with which we will merge the sp adjustment. */
2964 if (VAL_14_BITS_P (actual_fsize + 20)
2965 && local_fsize == 0
2966 && ! merge_sp_adjust_with_load)
2967 merge_sp_adjust_with_load = i;
2968 else
2969 load_reg (i, offset, STACK_POINTER_REGNUM);
2970 offset += 4;
2971 }
2972 }
87ad11b0 2973 }
daee63dd 2974
87ad11b0 2975 /* Align pointer properly (doubleword boundary). */
2976 offset = (offset + 7) & ~7;
2977
daee63dd 2978 /* FP register restores. */
87ad11b0 2979 if (save_fregs)
87ad11b0 2980 {
daee63dd 2981 /* Adjust the register to index off of. */
a1ab4fa3 2982 if (frame_pointer_needed)
daee63dd 2983 set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
a1ab4fa3 2984 else
daee63dd 2985 set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
2986
2987 /* Actually do the restores now. */
df0651dc 2988 for (i = 66; i >= 48; i -= 2)
7f7c4869 2989 {
7f7c4869 2990 if (regs_ever_live[i] || regs_ever_live[i + 1])
2991 {
7f7c4869 2992 emit_move_insn (gen_rtx (REG, DFmode, i),
2993 gen_rtx (MEM, DFmode,
2994 gen_rtx (POST_INC, DFmode, tmpreg)));
2995 }
2996 }
87ad11b0 2997 }
daee63dd 2998
14660146 2999 /* Emit a blockage insn here to keep these insns from being moved to
3000 an earlier spot in the epilogue, or into the main instruction stream.
3001
3002 This is necessary as we must not cut the stack back before all the
3003 restores are finished. */
3004 emit_insn (gen_blockage ());
daee63dd 3005 /* No frame pointer, but we have a stack greater than 8k. We restore
1921d762 3006 %r2 very late in this case. (All other cases are restored as early
3007 as possible.) */
daee63dd 3008 if (! frame_pointer_needed
3009 && ! VAL_14_BITS_P (actual_fsize + 20)
3010 && (regs_ever_live[2] || profile_flag))
87ad11b0 3011 {
daee63dd 3012 set_reg_plus_d (STACK_POINTER_REGNUM,
3013 STACK_POINTER_REGNUM,
3014 - actual_fsize);
8c824e42 3015
3016 /* This used to try and be clever by not depending on the value in
3017 %r30 and instead use the value held in %r1 (so that the 2nd insn
3018 which sets %r30 could be put in the delay slot of the return insn).
3019
3020 That won't work since if the stack is exactly 8k set_reg_plus_d
3021 doesn't set %r1, just %r30. */
db0a8300 3022 load_reg (2, - 20, STACK_POINTER_REGNUM);
87ad11b0 3023 }
daee63dd 3024
42819d4e 3025 /* Reset stack pointer (and possibly frame pointer). The stack
3026 pointer is initially set to fp + 64 to avoid a race condition. */
daee63dd 3027 else if (frame_pointer_needed)
87ad11b0 3028 {
daee63dd 3029 set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
00a87639 3030 emit_insn (gen_pre_ldwm (frame_pointer_rtx,
3031 stack_pointer_rtx,
3032 GEN_INT (-64)));
87ad11b0 3033 }
daee63dd 3034 /* If we were deferring a callee register restore, do it now. */
3035 else if (! frame_pointer_needed && merge_sp_adjust_with_load)
00a87639 3036 emit_insn (gen_pre_ldwm (gen_rtx (REG, SImode,
3037 merge_sp_adjust_with_load),
daee63dd 3038 stack_pointer_rtx,
00a87639 3039 GEN_INT (- actual_fsize)));
daee63dd 3040 else if (actual_fsize != 0)
3041 set_reg_plus_d (STACK_POINTER_REGNUM,
3042 STACK_POINTER_REGNUM,
3043 - actual_fsize);
87ad11b0 3044}
3045
e07ff380 3046/* Fetch the return address for the frame COUNT steps up from
3047 the current frame, after the prologue. FRAMEADDR is the
3048 frame pointer of the COUNT frame.
3049
a6c6fd6c 3050 We want to ignore any export stub remnants here.
3051
3052 The value returned is used in two different ways:
3053
3054 1. To find a function's caller.
3055
3056 2. To change the return address for a function.
3057
3058 This function handles most instances of case 1; however, it will
3059 fail if there are two levels of stubs to execute on the return
3060 path. The only way I believe that can happen is if the return value
3061 needs a parameter relocation, which never happens for C code.
3062
3063 This function handles most instances of case 2; however, it will
3064 fail if we did not originally have stub code on the return path
3065 but will need code on the new return path. This can happen if
3066 the caller & callee are both in the main program, but the new
3067 return location is in a shared library.
3068
3069 To handle this correctly we need to set the return pointer at
3070 frame-20 to point to a return stub frame-24 to point to the
3071 location we wish to return to. */
e07ff380 3072
3073rtx
3074return_addr_rtx (count, frameaddr)
3075 int count;
3076 rtx frameaddr;
3077{
3078 rtx label;
3079 rtx saved_rp;
3080 rtx ins;
3081
3082 saved_rp = gen_reg_rtx (Pmode);
3083
3084 /* First, we start off with the normal return address pointer from
3085 -20[frameaddr]. */
3086
3087 emit_move_insn (saved_rp, plus_constant (frameaddr, -5 * UNITS_PER_WORD));
3088
3089 /* Get pointer to the instruction stream. We have to mask out the
3090 privilege level from the two low order bits of the return address
3091 pointer here so that ins will point to the start of the first
3092 instruction that would have been executed if we returned. */
3093 ins = copy_to_reg (gen_rtx (AND, Pmode,
3094 copy_to_reg (gen_rtx (MEM, Pmode, saved_rp)),
3095 MASK_RETURN_ADDR));
3096 label = gen_label_rtx ();
3097
3098 /* Check the instruction stream at the normal return address for the
3099 export stub:
3100
3101 0x4bc23fd1 | stub+8: ldw -18(sr0,sp),rp
3102 0x004010a1 | stub+12: ldsid (sr0,rp),r1
3103 0x00011820 | stub+16: mtsp r1,sr0
3104 0xe0400002 | stub+20: be,n 0(sr0,rp)
3105
3106 If it is an export stub, than our return address is really in
3107 -24[frameaddr]. */
3108
3109 emit_cmp_insn (gen_rtx (MEM, SImode, ins),
3110 GEN_INT (0x4bc23fd1),
3111 NE, NULL_RTX, SImode, 1, 0);
3112 emit_jump_insn (gen_bne (label));
3113
3114 emit_cmp_insn (gen_rtx (MEM, SImode, plus_constant (ins, 4)),
3115 GEN_INT (0x004010a1),
3116 NE, NULL_RTX, SImode, 1, 0);
3117 emit_jump_insn (gen_bne (label));
3118
3119 emit_cmp_insn (gen_rtx (MEM, SImode, plus_constant (ins, 8)),
3120 GEN_INT (0x00011820),
3121 NE, NULL_RTX, SImode, 1, 0);
3122 emit_jump_insn (gen_bne (label));
3123
3124 emit_cmp_insn (gen_rtx (MEM, SImode, plus_constant (ins, 12)),
3125 GEN_INT (0xe0400002),
3126 NE, NULL_RTX, SImode, 1, 0);
3127
3128 /* If there is no export stub then just use our initial guess of
3129 -20[frameaddr]. */
3130
3131 emit_jump_insn (gen_bne (label));
3132
3133 /* Here we know that our return address pointer points to an export
3134 stub. We don't want to return the address of the export stub,
3135 but rather the return address that leads back into user code.
3136 That return address is stored at -24[frameaddr]. */
3137
3138 emit_move_insn (saved_rp, plus_constant (frameaddr, -6 * UNITS_PER_WORD));
3139
3140 emit_label (label);
3141 return gen_rtx (MEM, Pmode, memory_address (Pmode, saved_rp));
3142}
3143
757d4970 3144/* This is only valid once reload has completed because it depends on
3145 knowing exactly how much (if any) frame there is and...
3146
3147 It's only valid if there is no frame marker to de-allocate and...
3148
3149 It's only valid if %r2 hasn't been saved into the caller's frame
3150 (we're not profiling and %r2 isn't live anywhere). */
3151int
3152hppa_can_use_return_insn_p ()
3153{
3154 return (reload_completed
3155 && (compute_frame_size (get_frame_size (), 0) ? 0 : 1)
3156 && ! profile_flag
3157 && ! regs_ever_live[2]
3158 && ! frame_pointer_needed);
3159}
3160
87ad11b0 3161void
3162emit_bcond_fp (code, operand0)
3163 enum rtx_code code;
3164 rtx operand0;
3165{
3166 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
3167 gen_rtx (IF_THEN_ELSE, VOIDmode,
6d36483b 3168 gen_rtx (code, VOIDmode,
87ad11b0 3169 gen_rtx (REG, CCFPmode, 0),
3170 const0_rtx),
3171 gen_rtx (LABEL_REF, VOIDmode, operand0),
3172 pc_rtx)));
3173
3174}
3175
3176rtx
3177gen_cmp_fp (code, operand0, operand1)
3178 enum rtx_code code;
3179 rtx operand0, operand1;
3180{
3181 return gen_rtx (SET, VOIDmode, gen_rtx (REG, CCFPmode, 0),
3182 gen_rtx (code, CCFPmode, operand0, operand1));
3183}
3184
8b49b3c7 3185/* Adjust the cost of a scheduling dependency. Return the new cost of
3186 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
3187
3188int
3189pa_adjust_cost (insn, link, dep_insn, cost)
3190 rtx insn;
3191 rtx link;
3192 rtx dep_insn;
3193 int cost;
3194{
d402da4b 3195 if (! recog_memoized (insn))
3196 return 0;
8b49b3c7 3197
3198 if (REG_NOTE_KIND (link) == 0)
3199 {
3200 /* Data dependency; DEP_INSN writes a register that INSN reads some
3201 cycles later. */
3202
3203 if (get_attr_type (insn) == TYPE_FPSTORE)
3204 {
d402da4b 3205 rtx pat = PATTERN (insn);
3206 rtx dep_pat = PATTERN (dep_insn);
3207 if (GET_CODE (pat) == PARALLEL)
3208 {
3209 /* This happens for the fstXs,mb patterns. */
3210 pat = XVECEXP (pat, 0, 0);
3211 }
3212 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
8b49b3c7 3213 /* If this happens, we have to extend this to schedule
d402da4b 3214 optimally. Return 0 for now. */
3215 return 0;
8b49b3c7 3216
d402da4b 3217 if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
8b49b3c7 3218 {
d402da4b 3219 if (! recog_memoized (dep_insn))
3220 return 0;
3221 /* DEP_INSN is writing its result to the register
3222 being stored in the fpstore INSN. */
8b49b3c7 3223 switch (get_attr_type (dep_insn))
3224 {
3225 case TYPE_FPLOAD:
134b4858 3226 /* This cost 3 cycles, not 2 as the md says for the
3227 700 and 7100. Note scaling of cost for 7100. */
e811e65b 3228 return cost + (pa_cpu == PROCESSOR_700) ? 1 : 2;
8b49b3c7 3229
3230 case TYPE_FPALU:
134b4858 3231 case TYPE_FPMULSGL:
3232 case TYPE_FPMULDBL:
8b49b3c7 3233 case TYPE_FPDIVSGL:
3234 case TYPE_FPDIVDBL:
3235 case TYPE_FPSQRTSGL:
3236 case TYPE_FPSQRTDBL:
3237 /* In these important cases, we save one cycle compared to
3238 when flop instruction feed each other. */
e811e65b 3239 return cost - (pa_cpu == PROCESSOR_700) ? 1 : 2;
8b49b3c7 3240
3241 default:
3242 return cost;
3243 }
3244 }
3245 }
3246
3247 /* For other data dependencies, the default cost specified in the
3248 md is correct. */
3249 return cost;
3250 }
3251 else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
3252 {
3253 /* Anti dependency; DEP_INSN reads a register that INSN writes some
3254 cycles later. */
3255
3256 if (get_attr_type (insn) == TYPE_FPLOAD)
3257 {
d402da4b 3258 rtx pat = PATTERN (insn);
3259 rtx dep_pat = PATTERN (dep_insn);
3260 if (GET_CODE (pat) == PARALLEL)
3261 {
3262 /* This happens for the fldXs,mb patterns. */
3263 pat = XVECEXP (pat, 0, 0);
3264 }
3265 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
8b49b3c7 3266 /* If this happens, we have to extend this to schedule
d402da4b 3267 optimally. Return 0 for now. */
3268 return 0;
8b49b3c7 3269
d402da4b 3270 if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
8b49b3c7 3271 {
d402da4b 3272 if (! recog_memoized (dep_insn))
3273 return 0;
8b49b3c7 3274 switch (get_attr_type (dep_insn))
3275 {
3276 case TYPE_FPALU:
134b4858 3277 case TYPE_FPMULSGL:
3278 case TYPE_FPMULDBL:
8b49b3c7 3279 case TYPE_FPDIVSGL:
3280 case TYPE_FPDIVDBL:
3281 case TYPE_FPSQRTSGL:
3282 case TYPE_FPSQRTDBL:
d402da4b 3283 /* A fpload can't be issued until one cycle before a
01cc3b75 3284 preceding arithmetic operation has finished if
d402da4b 3285 the target of the fpload is any of the sources
3286 (or destination) of the arithmetic operation. */
e811e65b 3287 return cost - (pa_cpu == PROCESSOR_700) ? 1 : 2;
134b4858 3288
3289 default:
3290 return 0;
3291 }
3292 }
3293 }
3294 else if (get_attr_type (insn) == TYPE_FPALU)
3295 {
3296 rtx pat = PATTERN (insn);
3297 rtx dep_pat = PATTERN (dep_insn);
3298 if (GET_CODE (pat) == PARALLEL)
3299 {
3300 /* This happens for the fldXs,mb patterns. */
3301 pat = XVECEXP (pat, 0, 0);
3302 }
3303 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
3304 /* If this happens, we have to extend this to schedule
3305 optimally. Return 0 for now. */
3306 return 0;
3307
3308 if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
3309 {
3310 if (! recog_memoized (dep_insn))
3311 return 0;
3312 switch (get_attr_type (dep_insn))
3313 {
3314 case TYPE_FPDIVSGL:
3315 case TYPE_FPDIVDBL:
3316 case TYPE_FPSQRTSGL:
3317 case TYPE_FPSQRTDBL:
3318 /* An ALU flop can't be issued until two cycles before a
01cc3b75 3319 preceding divide or sqrt operation has finished if
134b4858 3320 the target of the ALU flop is any of the sources
3321 (or destination) of the divide or sqrt operation. */
e811e65b 3322 return cost - (pa_cpu == PROCESSOR_700) ? 2 : 4;
8b49b3c7 3323
3324 default:
3325 return 0;
3326 }
3327 }
3328 }
3329
3330 /* For other anti dependencies, the cost is 0. */
3331 return 0;
3332 }
134b4858 3333 else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
3334 {
3335 /* Output dependency; DEP_INSN writes a register that INSN writes some
3336 cycles later. */
3337 if (get_attr_type (insn) == TYPE_FPLOAD)
3338 {
3339 rtx pat = PATTERN (insn);
3340 rtx dep_pat = PATTERN (dep_insn);
3341 if (GET_CODE (pat) == PARALLEL)
3342 {
3343 /* This happens for the fldXs,mb patterns. */
3344 pat = XVECEXP (pat, 0, 0);
3345 }
3346 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
3347 /* If this happens, we have to extend this to schedule
3348 optimally. Return 0 for now. */
3349 return 0;
3350
3351 if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
3352 {
3353 if (! recog_memoized (dep_insn))
3354 return 0;
3355 switch (get_attr_type (dep_insn))
3356 {
3357 case TYPE_FPALU:
3358 case TYPE_FPMULSGL:
3359 case TYPE_FPMULDBL:
3360 case TYPE_FPDIVSGL:
3361 case TYPE_FPDIVDBL:
3362 case TYPE_FPSQRTSGL:
3363 case TYPE_FPSQRTDBL:
3364 /* A fpload can't be issued until one cycle before a
01cc3b75 3365 preceding arithmetic operation has finished if
134b4858 3366 the target of the fpload is the destination of the
3367 arithmetic operation. */
e811e65b 3368 return cost - (pa_cpu == PROCESSOR_700) ? 1 : 2;
8b49b3c7 3369
134b4858 3370 default:
3371 return 0;
3372 }
3373 }
3374 }
3375 else if (get_attr_type (insn) == TYPE_FPALU)
3376 {
3377 rtx pat = PATTERN (insn);
3378 rtx dep_pat = PATTERN (dep_insn);
3379 if (GET_CODE (pat) == PARALLEL)
3380 {
3381 /* This happens for the fldXs,mb patterns. */
3382 pat = XVECEXP (pat, 0, 0);
3383 }
3384 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
3385 /* If this happens, we have to extend this to schedule
3386 optimally. Return 0 for now. */
3387 return 0;
3388
3389 if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
3390 {
3391 if (! recog_memoized (dep_insn))
3392 return 0;
3393 switch (get_attr_type (dep_insn))
3394 {
3395 case TYPE_FPDIVSGL:
3396 case TYPE_FPDIVDBL:
3397 case TYPE_FPSQRTSGL:
3398 case TYPE_FPSQRTDBL:
3399 /* An ALU flop can't be issued until two cycles before a
01cc3b75 3400 preceding divide or sqrt operation has finished if
134b4858 3401 the target of the ALU flop is also the target of
3402 of the divide or sqrt operation. */
e811e65b 3403 return cost - (pa_cpu == PROCESSOR_700) ? 2 : 4;
134b4858 3404
3405 default:
3406 return 0;
3407 }
3408 }
3409 }
3410
3411 /* For other output dependencies, the cost is 0. */
3412 return 0;
3413 }
3414 else
3415 abort ();
8b49b3c7 3416}
87ad11b0 3417
58e17b0b 3418/* Return any length adjustment needed by INSN which already has its length
6d36483b 3419 computed as LENGTH. Return zero if no adjustment is necessary.
58e17b0b 3420
5fbd5940 3421 For the PA: function calls, millicode calls, and backwards short
6d36483b 3422 conditional branches with unfilled delay slots need an adjustment by +1
5fbd5940 3423 (to account for the NOP which will be inserted into the instruction stream).
58e17b0b 3424
3425 Also compute the length of an inline block move here as it is too
5fbd5940 3426 complicated to express as a length attribute in pa.md. */
58e17b0b 3427int
3428pa_adjust_insn_length (insn, length)
3429 rtx insn;
3430 int length;
3431{
3432 rtx pat = PATTERN (insn);
3433
5fbd5940 3434 /* Call insns which are *not* indirect and have unfilled delay slots. */
58e17b0b 3435 if (GET_CODE (insn) == CALL_INSN)
5fbd5940 3436 {
3437
3438 if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL
3439 && GET_CODE (XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)) == SYMBOL_REF)
5a1231ef 3440 return 4;
5fbd5940 3441 else if (GET_CODE (XVECEXP (pat, 0, 0)) == SET
3442 && GET_CODE (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0))
3443 == SYMBOL_REF)
5a1231ef 3444 return 4;
5fbd5940 3445 else
3446 return 0;
3447 }
3b1e673e 3448 /* Jumps inside switch tables which have unfilled delay slots
3449 also need adjustment. */
3450 else if (GET_CODE (insn) == JUMP_INSN
3451 && simplejump_p (insn)
3452 && GET_MODE (PATTERN (insn)) == DImode)
3453 return 4;
58e17b0b 3454 /* Millicode insn with an unfilled delay slot. */
3455 else if (GET_CODE (insn) == INSN
3456 && GET_CODE (pat) != SEQUENCE
3457 && GET_CODE (pat) != USE
3458 && GET_CODE (pat) != CLOBBER
3459 && get_attr_type (insn) == TYPE_MILLI)
5a1231ef 3460 return 4;
58e17b0b 3461 /* Block move pattern. */
3462 else if (GET_CODE (insn) == INSN
3463 && GET_CODE (pat) == PARALLEL
3464 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM
3465 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 1)) == MEM
3466 && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode
3467 && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode)
5a1231ef 3468 return compute_movstrsi_length (insn) - 4;
58e17b0b 3469 /* Conditional branch with an unfilled delay slot. */
5fbd5940 3470 else if (GET_CODE (insn) == JUMP_INSN && ! simplejump_p (insn))
3471 {
3472 /* Adjust a short backwards conditional with an unfilled delay slot. */
3473 if (GET_CODE (pat) == SET
5a1231ef 3474 && length == 4
5fbd5940 3475 && ! forward_branch_p (insn))
5a1231ef 3476 return 4;
546a40bd 3477 else if (GET_CODE (pat) == PARALLEL
3478 && get_attr_type (insn) == TYPE_PARALLEL_BRANCH
3479 && length == 4)
3480 return 4;
5fbd5940 3481 /* Adjust dbra insn with short backwards conditional branch with
6d36483b 3482 unfilled delay slot -- only for case where counter is in a
29a4502c 3483 general register register. */
5fbd5940 3484 else if (GET_CODE (pat) == PARALLEL
3485 && GET_CODE (XVECEXP (pat, 0, 1)) == SET
3486 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == REG
6d36483b 3487 && ! FP_REG_P (XEXP (XVECEXP (pat, 0, 1), 0))
5a1231ef 3488 && length == 4
5fbd5940 3489 && ! forward_branch_p (insn))
5a1231ef 3490 return 4;
5fbd5940 3491 else
3492 return 0;
3493 }
546a40bd 3494 return 0;
58e17b0b 3495}
3496
87ad11b0 3497/* Print operand X (an rtx) in assembler syntax to file FILE.
3498 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3499 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3500
3501void
3502print_operand (file, x, code)
3503 FILE *file;
3504 rtx x;
3505 int code;
3506{
3507 switch (code)
3508 {
3509 case '#':
3510 /* Output a 'nop' if there's nothing for the delay slot. */
3511 if (dbr_sequence_length () == 0)
3512 fputs ("\n\tnop", file);
3513 return;
3514 case '*':
3515 /* Output an nullification completer if there's nothing for the */
6d36483b 3516 /* delay slot or nullification is requested. */
87ad11b0 3517 if (dbr_sequence_length () == 0 ||
3518 (final_sequence &&
3519 INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))))
3520 fputs (",n", file);
3521 return;
3522 case 'R':
3523 /* Print out the second register name of a register pair.
3524 I.e., R (6) => 7. */
3525 fputs (reg_names[REGNO (x)+1], file);
3526 return;
3527 case 'r':
3528 /* A register or zero. */
891b55b4 3529 if (x == const0_rtx
3530 || (x == CONST0_RTX (DFmode))
3531 || (x == CONST0_RTX (SFmode)))
87ad11b0 3532 {
3533 fputs ("0", file);
3534 return;
3535 }
3536 else
3537 break;
c8975385 3538 case 'C': /* Plain (C)ondition */
87ad11b0 3539 case 'X':
3540 switch (GET_CODE (x))
6d36483b 3541 {
87ad11b0 3542 case EQ:
9c0ac0fd 3543 fputs ("=", file); break;
87ad11b0 3544 case NE:
9c0ac0fd 3545 fputs ("<>", file); break;
87ad11b0 3546 case GT:
9c0ac0fd 3547 fputs (">", file); break;
87ad11b0 3548 case GE:
9c0ac0fd 3549 fputs (">=", file); break;
87ad11b0 3550 case GEU:
9c0ac0fd 3551 fputs (">>=", file); break;
87ad11b0 3552 case GTU:
9c0ac0fd 3553 fputs (">>", file); break;
87ad11b0 3554 case LT:
9c0ac0fd 3555 fputs ("<", file); break;
87ad11b0 3556 case LE:
9c0ac0fd 3557 fputs ("<=", file); break;
87ad11b0 3558 case LEU:
9c0ac0fd 3559 fputs ("<<=", file); break;
87ad11b0 3560 case LTU:
9c0ac0fd 3561 fputs ("<<", file); break;
87ad11b0 3562 default:
87ad11b0 3563 abort ();
3564 }
3565 return;
c8975385 3566 case 'N': /* Condition, (N)egated */
87ad11b0 3567 switch (GET_CODE (x))
3568 {
3569 case EQ:
9c0ac0fd 3570 fputs ("<>", file); break;
87ad11b0 3571 case NE:
9c0ac0fd 3572 fputs ("=", file); break;
87ad11b0 3573 case GT:
9c0ac0fd 3574 fputs ("<=", file); break;
87ad11b0 3575 case GE:
9c0ac0fd 3576 fputs ("<", file); break;
87ad11b0 3577 case GEU:
9c0ac0fd 3578 fputs ("<<", file); break;
87ad11b0 3579 case GTU:
9c0ac0fd 3580 fputs ("<<=", file); break;
87ad11b0 3581 case LT:
9c0ac0fd 3582 fputs (">=", file); break;
87ad11b0 3583 case LE:
9c0ac0fd 3584 fputs (">", file); break;
87ad11b0 3585 case LEU:
9c0ac0fd 3586 fputs (">>", file); break;
87ad11b0 3587 case LTU:
9c0ac0fd 3588 fputs (">>=", file); break;
87ad11b0 3589 default:
87ad11b0 3590 abort ();
3591 }
3592 return;
61230bc9 3593 /* For floating point comparisons. Need special conditions to deal
3594 with NaNs properly. */
3595 case 'Y':
3596 switch (GET_CODE (x))
3597 {
3598 case EQ:
9c0ac0fd 3599 fputs ("!=", file); break;
61230bc9 3600 case NE:
9c0ac0fd 3601 fputs ("=", file); break;
61230bc9 3602 case GT:
85837adc 3603 fputs ("<=", file); break;
61230bc9 3604 case GE:
85837adc 3605 fputs ("<", file); break;
61230bc9 3606 case LT:
85837adc 3607 fputs (">=", file); break;
61230bc9 3608 case LE:
85837adc 3609 fputs (">", file); break;
61230bc9 3610 default:
61230bc9 3611 abort ();
3612 }
3613 return;
c8975385 3614 case 'S': /* Condition, operands are (S)wapped. */
3615 switch (GET_CODE (x))
3616 {
3617 case EQ:
9c0ac0fd 3618 fputs ("=", file); break;
c8975385 3619 case NE:
9c0ac0fd 3620 fputs ("<>", file); break;
c8975385 3621 case GT:
9c0ac0fd 3622 fputs ("<", file); break;
c8975385 3623 case GE:
9c0ac0fd 3624 fputs ("<=", file); break;
c8975385 3625 case GEU:
9c0ac0fd 3626 fputs ("<<=", file); break;
c8975385 3627 case GTU:
9c0ac0fd 3628 fputs ("<<", file); break;
c8975385 3629 case LT:
9c0ac0fd 3630 fputs (">", file); break;
c8975385 3631 case LE:
9c0ac0fd 3632 fputs (">=", file); break;
c8975385 3633 case LEU:
9c0ac0fd 3634 fputs (">>=", file); break;
c8975385 3635 case LTU:
9c0ac0fd 3636 fputs (">>", file); break;
c8975385 3637 default:
c8975385 3638 abort ();
6d36483b 3639 }
c8975385 3640 return;
3641 case 'B': /* Condition, (B)oth swapped and negate. */
3642 switch (GET_CODE (x))
3643 {
3644 case EQ:
9c0ac0fd 3645 fputs ("<>", file); break;
c8975385 3646 case NE:
9c0ac0fd 3647 fputs ("=", file); break;
c8975385 3648 case GT:
9c0ac0fd 3649 fputs (">=", file); break;
c8975385 3650 case GE:
9c0ac0fd 3651 fputs (">", file); break;
c8975385 3652 case GEU:
9c0ac0fd 3653 fputs (">>", file); break;
c8975385 3654 case GTU:
9c0ac0fd 3655 fputs (">>=", file); break;
c8975385 3656 case LT:
9c0ac0fd 3657 fputs ("<=", file); break;
c8975385 3658 case LE:
9c0ac0fd 3659 fputs ("<", file); break;
c8975385 3660 case LEU:
9c0ac0fd 3661 fputs ("<<", file); break;
c8975385 3662 case LTU:
9c0ac0fd 3663 fputs ("<<=", file); break;
c8975385 3664 default:
c8975385 3665 abort ();
6d36483b 3666 }
c8975385 3667 return;
3668 case 'k':
3669 if (GET_CODE (x) == CONST_INT)
3670 {
3671 fprintf (file, "%d", ~INTVAL (x));
3672 return;
3673 }
3674 abort();
e5965947 3675 case 'L':
3676 if (GET_CODE (x) == CONST_INT)
3677 {
3678 fprintf (file, "%d", 32 - (INTVAL (x) & 31));
3679 return;
3680 }
3681 abort();
3a16146d 3682 case 'O':
3683 if (GET_CODE (x) == CONST_INT && exact_log2 (INTVAL (x)) >= 0)
3684 {
3685 fprintf (file, "%d", exact_log2 (INTVAL (x)));
3686 return;
3687 }
3688 abort();
e5965947 3689 case 'P':
3690 if (GET_CODE (x) == CONST_INT)
3691 {
3692 fprintf (file, "%d", 31 - (INTVAL (x) & 31));
3693 return;
3694 }
3695 abort();
c8975385 3696 case 'I':
3697 if (GET_CODE (x) == CONST_INT)
3698 fputs ("i", file);
3699 return;
87ad11b0 3700 case 'M':
27ef382d 3701 case 'F':
87ad11b0 3702 switch (GET_CODE (XEXP (x, 0)))
3703 {
3704 case PRE_DEC:
3705 case PRE_INC:
9c0ac0fd 3706 fputs ("s,mb", file);
87ad11b0 3707 break;
3708 case POST_DEC:
3709 case POST_INC:
9c0ac0fd 3710 fputs ("s,ma", file);
87ad11b0 3711 break;
27ef382d 3712 case PLUS:
3713 if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
3714 || GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
3715 fputs ("x,s", file);
3716 else if (code == 'F')
3717 fputs ("s", file);
87ad11b0 3718 break;
3719 default:
27ef382d 3720 if (code == 'F')
3721 fputs ("s", file);
87ad11b0 3722 break;
3723 }
3724 return;
3725 case 'G':
f9333726 3726 output_global_address (file, x, 0);
3727 return;
3728 case 'H':
3729 output_global_address (file, x, 1);
87ad11b0 3730 return;
3731 case 0: /* Don't do anything special */
3732 break;
42faba01 3733 case 'Z':
3734 {
3735 unsigned op[3];
3736 compute_zdepi_operands (INTVAL (x), op);
3737 fprintf (file, "%d,%d,%d", op[0], op[1], op[2]);
3738 return;
3739 }
87ad11b0 3740 default:
3741 abort ();
3742 }
3743 if (GET_CODE (x) == REG)
df0651dc 3744 {
35661368 3745 fputs (reg_names [REGNO (x)], file);
df0651dc 3746 if (FP_REG_P (x) && GET_MODE_SIZE (GET_MODE (x)) <= 4 && (REGNO (x) & 1) == 0)
35661368 3747 fputs ("L", file);
df0651dc 3748 }
87ad11b0 3749 else if (GET_CODE (x) == MEM)
3750 {
3751 int size = GET_MODE_SIZE (GET_MODE (x));
3752 rtx base = XEXP (XEXP (x, 0), 0);
3753 switch (GET_CODE (XEXP (x, 0)))
3754 {
3755 case PRE_DEC:
3756 case POST_DEC:
3757 fprintf (file, "-%d(0,%s)", size, reg_names [REGNO (base)]);
3758 break;
3759 case PRE_INC:
3760 case POST_INC:
3761 fprintf (file, "%d(0,%s)", size, reg_names [REGNO (base)]);
3762 break;
3763 default:
27ef382d 3764 if (GET_CODE (XEXP (x, 0)) == PLUS
3765 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
3766 fprintf (file, "%s(0,%s)",
3767 reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0))],
3768 reg_names [REGNO (XEXP (XEXP (x, 0), 1))]);
3769 else if (GET_CODE (XEXP (x, 0)) == PLUS
3770 && GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
3771 fprintf (file, "%s(0,%s)",
3772 reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 1), 0))],
3773 reg_names [REGNO (XEXP (XEXP (x, 0), 0))]);
3774 else
3775 output_address (XEXP (x, 0));
87ad11b0 3776 break;
3777 }
3778 }
87ad11b0 3779 else
3780 output_addr_const (file, x);
3781}
3782
3783/* output a SYMBOL_REF or a CONST expression involving a SYMBOL_REF. */
3784
3785void
f9333726 3786output_global_address (file, x, round_constant)
87ad11b0 3787 FILE *file;
3788 rtx x;
f9333726 3789 int round_constant;
87ad11b0 3790{
2ee034bc 3791
3792 /* Imagine (high (const (plus ...))). */
3793 if (GET_CODE (x) == HIGH)
3794 x = XEXP (x, 0);
3795
87ad11b0 3796 if (GET_CODE (x) == SYMBOL_REF && read_only_operand (x))
3797 assemble_name (file, XSTR (x, 0));
b4a7bf10 3798 else if (GET_CODE (x) == SYMBOL_REF && !flag_pic)
87ad11b0 3799 {
3800 assemble_name (file, XSTR (x, 0));
9c0ac0fd 3801 fputs ("-$global$", file);
87ad11b0 3802 }
3803 else if (GET_CODE (x) == CONST)
3804 {
3805 char *sep = "";
3806 int offset = 0; /* assembler wants -$global$ at end */
3807 rtx base;
6d36483b 3808
87ad11b0 3809 if (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
3810 {
3811 base = XEXP (XEXP (x, 0), 0);
3812 output_addr_const (file, base);
3813 }
3814 else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == CONST_INT)
3815 offset = INTVAL (XEXP (XEXP (x, 0), 0));
3816 else abort ();
3817
3818 if (GET_CODE (XEXP (XEXP (x, 0), 1)) == SYMBOL_REF)
3819 {
3820 base = XEXP (XEXP (x, 0), 1);
3821 output_addr_const (file, base);
3822 }
3823 else if (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
3824 offset = INTVAL (XEXP (XEXP (x, 0),1));
3825 else abort ();
3826
f9333726 3827 /* How bogus. The compiler is apparently responsible for
3828 rounding the constant if it uses an LR field selector.
3829
3830 The linker and/or assembler seem a better place since
3831 they have to do this kind of thing already.
3832
3833 If we fail to do this, HP's optimizing linker may eliminate
3834 an addil, but not update the ldw/stw/ldo instruction that
3835 uses the result of the addil. */
3836 if (round_constant)
3837 offset = ((offset + 0x1000) & ~0x1fff);
3838
87ad11b0 3839 if (GET_CODE (XEXP (x, 0)) == PLUS)
3840 {
3841 if (offset < 0)
3842 {
3843 offset = -offset;
3844 sep = "-";
3845 }
3846 else
3847 sep = "+";
3848 }
3849 else if (GET_CODE (XEXP (x, 0)) == MINUS
3850 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF))
3851 sep = "-";
3852 else abort ();
3853
b4a7bf10 3854 if (!read_only_operand (base) && !flag_pic)
9c0ac0fd 3855 fputs ("-$global$", file);
f9333726 3856 if (offset)
3857 fprintf (file,"%s%d", sep, offset);
87ad11b0 3858 }
3859 else
3860 output_addr_const (file, x);
3861}
3862
87ad11b0 3863/* HP's millicode routines mean something special to the assembler.
3864 Keep track of which ones we have used. */
3865
3866enum millicodes { remI, remU, divI, divU, mulI, mulU, end1000 };
3867static char imported[(int)end1000];
3868static char *milli_names[] = {"remI", "remU", "divI", "divU", "mulI", "mulU"};
3869static char import_string[] = ".IMPORT $$....,MILLICODE";
3870#define MILLI_START 10
3871
57ed30e5 3872static void
87ad11b0 3873import_milli (code)
3874 enum millicodes code;
3875{
3876 char str[sizeof (import_string)];
6d36483b 3877
87ad11b0 3878 if (!imported[(int)code])
3879 {
3880 imported[(int)code] = 1;
3881 strcpy (str, import_string);
3882 strncpy (str + MILLI_START, milli_names[(int)code], 4);
3883 output_asm_insn (str, 0);
3884 }
3885}
3886
6d36483b 3887/* The register constraints have put the operands and return value in
87ad11b0 3888 the proper registers. */
3889
3890char *
d6686e21 3891output_mul_insn (unsignedp, insn)
87ad11b0 3892 int unsignedp;
d6686e21 3893 rtx insn;
87ad11b0 3894{
d178f670 3895 import_milli (mulI);
c7a4e712 3896 return output_millicode_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$mulI"));
87ad11b0 3897}
3898
87ad11b0 3899/* Emit the rtl for doing a division by a constant. */
3900
d178f670 3901/* Do magic division millicodes exist for this value? */
87ad11b0 3902static int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
3903 1, 1};
3904
6d36483b 3905/* We'll use an array to keep track of the magic millicodes and
87ad11b0 3906 whether or not we've used them already. [n][0] is signed, [n][1] is
3907 unsigned. */
3908
87ad11b0 3909static int div_milli[16][2];
3910
3911int
3912div_operand (op, mode)
3913 rtx op;
3914 enum machine_mode mode;
3915{
3916 return (mode == SImode
3917 && ((GET_CODE (op) == REG && REGNO (op) == 25)
3918 || (GET_CODE (op) == CONST_INT && INTVAL (op) > 0
3919 && INTVAL (op) < 16 && magic_milli[INTVAL (op)])));
3920}
3921
3922int
3923emit_hpdiv_const (operands, unsignedp)
3924 rtx *operands;
3925 int unsignedp;
3926{
3927 if (GET_CODE (operands[2]) == CONST_INT
3928 && INTVAL (operands[2]) > 0
3929 && INTVAL (operands[2]) < 16
3930 && magic_milli[INTVAL (operands[2])])
3931 {
3932 emit_move_insn ( gen_rtx (REG, SImode, 26), operands[1]);
3933 emit
3934 (gen_rtx
3935 (PARALLEL, VOIDmode,
3936 gen_rtvec (5, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29),
3937 gen_rtx (unsignedp ? UDIV : DIV, SImode,
3938 gen_rtx (REG, SImode, 26),
3939 operands[2])),
33bd7237 3940 gen_rtx (CLOBBER, VOIDmode, operands[3]),
87ad11b0 3941 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)),
3942 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)),
3943 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31)))));
3944 emit_move_insn (operands[0], gen_rtx (REG, SImode, 29));
3945 return 1;
3946 }
3947 return 0;
3948}
3949
3950char *
d6686e21 3951output_div_insn (operands, unsignedp, insn)
87ad11b0 3952 rtx *operands;
3953 int unsignedp;
d6686e21 3954 rtx insn;
87ad11b0 3955{
3956 int divisor;
6d36483b 3957
3958 /* If the divisor is a constant, try to use one of the special
87ad11b0 3959 opcodes .*/
3960 if (GET_CODE (operands[0]) == CONST_INT)
3961 {
d6686e21 3962 static char buf[100];
87ad11b0 3963 divisor = INTVAL (operands[0]);
3964 if (!div_milli[divisor][unsignedp])
3965 {
d6686e21 3966 div_milli[divisor][unsignedp] = 1;
87ad11b0 3967 if (unsignedp)
3968 output_asm_insn (".IMPORT $$divU_%0,MILLICODE", operands);
3969 else
3970 output_asm_insn (".IMPORT $$divI_%0,MILLICODE", operands);
87ad11b0 3971 }
3972 if (unsignedp)
d6686e21 3973 {
3974 sprintf (buf, "$$divU_%d", INTVAL (operands[0]));
c7a4e712 3975 return output_millicode_call (insn,
3976 gen_rtx (SYMBOL_REF, SImode, buf));
d6686e21 3977 }
3978 else
3979 {
3980 sprintf (buf, "$$divI_%d", INTVAL (operands[0]));
c7a4e712 3981 return output_millicode_call (insn,
3982 gen_rtx (SYMBOL_REF, SImode, buf));
d6686e21 3983 }
87ad11b0 3984 }
3985 /* Divisor isn't a special constant. */
3986 else
3987 {
3988 if (unsignedp)
3989 {
3990 import_milli (divU);
c7a4e712 3991 return output_millicode_call (insn,
3992 gen_rtx (SYMBOL_REF, SImode, "$$divU"));
87ad11b0 3993 }
3994 else
3995 {
3996 import_milli (divI);
c7a4e712 3997 return output_millicode_call (insn,
3998 gen_rtx (SYMBOL_REF, SImode, "$$divI"));
87ad11b0 3999 }
4000 }
4001}
4002
4003/* Output a $$rem millicode to do mod. */
4004
4005char *
d6686e21 4006output_mod_insn (unsignedp, insn)
87ad11b0 4007 int unsignedp;
d6686e21 4008 rtx insn;
87ad11b0 4009{
4010 if (unsignedp)
4011 {
4012 import_milli (remU);
c7a4e712 4013 return output_millicode_call (insn,
4014 gen_rtx (SYMBOL_REF, SImode, "$$remU"));
87ad11b0 4015 }
4016 else
4017 {
4018 import_milli (remI);
c7a4e712 4019 return output_millicode_call (insn,
4020 gen_rtx (SYMBOL_REF, SImode, "$$remI"));
87ad11b0 4021 }
4022}
4023
4024void
df0651dc 4025output_arg_descriptor (call_insn)
4026 rtx call_insn;
87ad11b0 4027{
4028 char *arg_regs[4];
4029 enum machine_mode arg_mode;
df0651dc 4030 rtx link;
87ad11b0 4031 int i, output_flag = 0;
4032 int regno;
6d36483b 4033
87ad11b0 4034 for (i = 0; i < 4; i++)
4035 arg_regs[i] = 0;
4036
738176ab 4037 /* Specify explicitly that no argument relocations should take place
4038 if using the portable runtime calling conventions. */
4039 if (TARGET_PORTABLE_RUNTIME)
4040 {
9c0ac0fd 4041 fputs ("\t.CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO,RETVAL=NO\n",
4042 asm_out_file);
738176ab 4043 return;
4044 }
4045
df0651dc 4046 if (GET_CODE (call_insn) != CALL_INSN)
4047 abort ();
4048 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); link; link = XEXP (link, 1))
87ad11b0 4049 {
df0651dc 4050 rtx use = XEXP (link, 0);
c12afafd 4051
df0651dc 4052 if (! (GET_CODE (use) == USE
4053 && GET_CODE (XEXP (use, 0)) == REG
4054 && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
c12afafd 4055 continue;
4056
df0651dc 4057 arg_mode = GET_MODE (XEXP (use, 0));
4058 regno = REGNO (XEXP (use, 0));
87ad11b0 4059 if (regno >= 23 && regno <= 26)
372ef038 4060 {
4061 arg_regs[26 - regno] = "GR";
4062 if (arg_mode == DImode)
4063 arg_regs[25 - regno] = "GR";
4064 }
df0651dc 4065 else if (regno >= 32 && regno <= 39)
87ad11b0 4066 {
4067 if (arg_mode == SFmode)
df0651dc 4068 arg_regs[(regno - 32) / 2] = "FR";
e6ba640e 4069 else
87ad11b0 4070 {
eeec72c0 4071#ifndef HP_FP_ARG_DESCRIPTOR_REVERSED
df0651dc 4072 arg_regs[(regno - 34) / 2] = "FR";
4073 arg_regs[(regno - 34) / 2 + 1] = "FU";
87ad11b0 4074#else
df0651dc 4075 arg_regs[(regno - 34) / 2] = "FU";
4076 arg_regs[(regno - 34) / 2 + 1] = "FR";
87ad11b0 4077#endif
4078 }
87ad11b0 4079 }
4080 }
4081 fputs ("\t.CALL ", asm_out_file);
4082 for (i = 0; i < 4; i++)
4083 {
4084 if (arg_regs[i])
4085 {
4086 if (output_flag++)
4087 fputc (',', asm_out_file);
4088 fprintf (asm_out_file, "ARGW%d=%s", i, arg_regs[i]);
4089 }
4090 }
4091 fputc ('\n', asm_out_file);
4092}
4093\f
9c0ac0fd 4094/* Return the class of any secondary reload register that is needed to
4095 move IN into a register in class CLASS using mode MODE.
4096
4097 Profiling has showed this routine and its descendants account for
4098 a significant amount of compile time (~7%). So it has been
4099 optimized to reduce redundant computations and eliminate useless
4100 function calls.
4101
4102 It might be worthwhile to try and make this a leaf function too. */
87ad11b0 4103
4104enum reg_class
4105secondary_reload_class (class, mode, in)
4106 enum reg_class class;
4107 enum machine_mode mode;
4108 rtx in;
4109{
9c0ac0fd 4110 int regno, is_symbolic;
87ad11b0 4111
b4a7bf10 4112 /* Trying to load a constant into a FP register during PIC code
4113 generation will require %r1 as a scratch register. */
4114 if (flag_pic == 2
4115 && GET_MODE_CLASS (mode) == MODE_INT
4116 && FP_REG_CLASS_P (class)
4117 && (GET_CODE (in) == CONST_INT || GET_CODE (in) == CONST_DOUBLE))
4118 return R1_REGS;
4119
9c0ac0fd 4120 /* Profiling showed the PA port spends about 1.3% of its compilation
4121 time in true_regnum from calls inside secondary_reload_class. */
4122
4123 if (GET_CODE (in) == REG)
4124 {
4125 regno = REGNO (in);
4126 if (regno >= FIRST_PSEUDO_REGISTER)
4127 regno = true_regnum (in);
4128 }
4129 else if (GET_CODE (in) == SUBREG)
4130 regno = true_regnum (in);
9c0ac0fd 4131 else
4132 regno = -1;
4133
d2498717 4134 if (((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
6d36483b 4135 && GET_MODE_CLASS (mode) == MODE_INT
4136 && FP_REG_CLASS_P (class))
d6f01525 4137 || (class == SHIFT_REGS && (regno <= 0 || regno >= 32)))
9c6d4825 4138 return GENERAL_REGS;
d2c1d63d 4139
2ee034bc 4140 if (GET_CODE (in) == HIGH)
4141 in = XEXP (in, 0);
4142
9c0ac0fd 4143 /* Profiling has showed GCC spends about 2.6% of its compilation
4144 time in symbolic_operand from calls inside secondary_reload_class.
4145
4146 We use an inline copy and only compute its return value once to avoid
4147 useless work. */
4148 switch (GET_CODE (in))
4149 {
4150 rtx tmp;
4151
4152 case SYMBOL_REF:
4153 case LABEL_REF:
4154 is_symbolic = 1;
4155 break;
4156 case CONST:
4157 tmp = XEXP (in, 0);
4158 is_symbolic = ((GET_CODE (XEXP (tmp, 0)) == SYMBOL_REF
4159 || GET_CODE (XEXP (tmp, 0)) == LABEL_REF)
4160 && GET_CODE (XEXP (tmp, 1)) == CONST_INT);
4161 break;
4162 default:
4163 is_symbolic = 0;
4164 break;
4165 }
4166
b4a7bf10 4167 if (!flag_pic
9c0ac0fd 4168 && is_symbolic
b4a7bf10 4169 && read_only_operand (in))
4170 return NO_REGS;
4171
9c0ac0fd 4172 if (class != R1_REGS && is_symbolic)
2ee034bc 4173 return R1_REGS;
4174
d2c1d63d 4175 return NO_REGS;
87ad11b0 4176}
4177
4178enum direction
4179function_arg_padding (mode, type)
4180 enum machine_mode mode;
4181 tree type;
4182{
4183 int size;
4184
4185 if (mode == BLKmode)
4186 {
4187 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
4188 size = int_size_in_bytes (type) * BITS_PER_UNIT;
4189 else
4190 return upward; /* Don't know if this is right, but */
4191 /* same as old definition. */
4192 }
4193 else
4194 size = GET_MODE_BITSIZE (mode);
4195 if (size < PARM_BOUNDARY)
4196 return downward;
4197 else if (size % PARM_BOUNDARY)
4198 return upward;
4199 else
4200 return none;
4201}
4202
87ad11b0 4203\f
4204/* Do what is necessary for `va_start'. The argument is ignored;
4205 We look at the current function to determine if stdargs or varargs
4206 is used and fill in an initial va_list. A pointer to this constructor
4207 is returned. */
4208
4209struct rtx_def *
4210hppa_builtin_saveregs (arglist)
4211 tree arglist;
4212{
57ed30e5 4213 rtx offset;
87ad11b0 4214 tree fntype = TREE_TYPE (current_function_decl);
4215 int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0
4216 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4217 != void_type_node)))
4218 ? UNITS_PER_WORD : 0);
4219
4220 if (argadj)
4221 offset = plus_constant (current_function_arg_offset_rtx, argadj);
4222 else
4223 offset = current_function_arg_offset_rtx;
9c6d4825 4224
87ad11b0 4225 /* Store general registers on the stack. */
4226 move_block_from_reg (23,
4227 gen_rtx (MEM, BLKmode,
4228 plus_constant
4229 (current_function_internal_arg_pointer, -16)),
6d36483b 4230 4, 4 * UNITS_PER_WORD);
9c6d4825 4231 return copy_to_reg (expand_binop (Pmode, add_optab,
4232 current_function_internal_arg_pointer,
4233 offset, 0, 0, OPTAB_LIB_WIDEN));
87ad11b0 4234}
d6f01525 4235
6d36483b 4236/* This routine handles all the normal conditional branch sequences we
4237 might need to generate. It handles compare immediate vs compare
4238 register, nullification of delay slots, varying length branches,
0d986529 4239 negated branches, and all combinations of the above. It returns the
6d36483b 4240 output appropriate to emit the branch corresponding to all given
0d986529 4241 parameters. */
4242
4243char *
4244output_cbranch (operands, nullify, length, negated, insn)
4245 rtx *operands;
4246 int nullify, length, negated;
4247 rtx insn;
29a4502c 4248{
0d986529 4249 static char buf[100];
4250 int useskip = 0;
4251
29a4502c 4252 /* A conditional branch to the following instruction (eg the delay slot) is
4253 asking for a disaster. This can happen when not optimizing.
4254
4255 In such cases it is safe to emit nothing. */
4256
db3da815 4257 if (next_active_insn (JUMP_LABEL (insn)) == next_active_insn (insn))
29a4502c 4258 return "";
6d36483b 4259
5fbd5940 4260 /* If this is a long branch with its delay slot unfilled, set `nullify'
4261 as it can nullify the delay slot and save a nop. */
5a1231ef 4262 if (length == 8 && dbr_sequence_length () == 0)
5fbd5940 4263 nullify = 1;
4264
4265 /* If this is a short forward conditional branch which did not get
4266 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 4267 if (! nullify && length == 4 && dbr_sequence_length () == 0)
5fbd5940 4268 nullify = forward_branch_p (insn);
4269
6d36483b 4270 /* A forward branch over a single nullified insn can be done with a
0d986529 4271 comclr instruction. This avoids a single cycle penalty due to
4272 mis-predicted branch if we fall through (branch not taken). */
5a1231ef 4273 if (length == 4
5fbd5940 4274 && next_real_insn (insn) != 0
5a1231ef 4275 && get_attr_length (next_real_insn (insn)) == 4
5fbd5940 4276 && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
0d986529 4277 && nullify)
4278 useskip = 1;
4279
4280 switch (length)
4281 {
5fbd5940 4282 /* All short conditional branches except backwards with an unfilled
4283 delay slot. */
5a1231ef 4284 case 4:
0d986529 4285 if (useskip)
4286 strcpy (buf, "com%I2clr,");
4287 else
4288 strcpy (buf, "com%I2b,");
4289 if (negated)
4290 strcat (buf, "%B3");
4291 else
4292 strcat (buf, "%S3");
4293 if (useskip)
4294 strcat (buf, " %2,%1,0");
4295 else if (nullify)
4296 strcat (buf, ",n %2,%1,%0");
6d36483b 4297 else
5fbd5940 4298 strcat (buf, " %2,%1,%0");
0d986529 4299 break;
4300
6d36483b 4301 /* All long conditionals. Note an short backward branch with an
5fbd5940 4302 unfilled delay slot is treated just like a long backward branch
4303 with an unfilled delay slot. */
5a1231ef 4304 case 8:
5fbd5940 4305 /* Handle weird backwards branch with a filled delay slot
4306 with is nullified. */
4307 if (dbr_sequence_length () != 0
4308 && ! forward_branch_p (insn)
4309 && nullify)
4310 {
4311 strcpy (buf, "com%I2b,");
4312 if (negated)
4313 strcat (buf, "%S3");
4314 else
4315 strcat (buf, "%B3");
4316 strcat (buf, ",n %2,%1,.+12\n\tbl %0,0");
4317 }
43f0c1f2 4318 /* Handle short backwards branch with an unfilled delay slot.
4319 Using a comb;nop rather than comiclr;bl saves 1 cycle for both
4320 taken and untaken branches. */
4321 else if (dbr_sequence_length () == 0
4322 && ! forward_branch_p (insn)
4323 && insn_addresses
4324 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
c7a4e712 4325 - insn_addresses[INSN_UID (insn)] - 8))
43f0c1f2 4326 {
4327 strcpy (buf, "com%I2b,");
4328 if (negated)
4329 strcat (buf, "%B3 %2,%1,%0%#");
4330 else
4331 strcat (buf, "%S3 %2,%1,%0%#");
4332 }
0d986529 4333 else
5fbd5940 4334 {
4335 strcpy (buf, "com%I2clr,");
4336 if (negated)
4337 strcat (buf, "%S3");
4338 else
4339 strcat (buf, "%B3");
4340 if (nullify)
4341 strcat (buf, " %2,%1,0\n\tbl,n %0,0");
4342 else
4343 strcat (buf, " %2,%1,0\n\tbl %0,0");
4344 }
0d986529 4345 break;
4346
4347 default:
4348 abort();
5fbd5940 4349 }
0d986529 4350 return buf;
4351}
4352
6d36483b 4353/* This routine handles all the branch-on-bit conditional branch sequences we
0d986529 4354 might need to generate. It handles nullification of delay slots,
4355 varying length branches, negated branches and all combinations of the
4356 above. it returns the appropriate output template to emit the branch. */
4357
4358char *
4359output_bb (operands, nullify, length, negated, insn, which)
4360 rtx *operands;
4361 int nullify, length, negated;
4362 rtx insn;
4363 int which;
29a4502c 4364{
0d986529 4365 static char buf[100];
4366 int useskip = 0;
4367
29a4502c 4368 /* A conditional branch to the following instruction (eg the delay slot) is
4369 asking for a disaster. I do not think this can happen as this pattern
6d36483b 4370 is only used when optimizing; jump optimization should eliminate the
29a4502c 4371 jump. But be prepared just in case. */
6d36483b 4372
db3da815 4373 if (next_active_insn (JUMP_LABEL (insn)) == next_active_insn (insn))
29a4502c 4374 return "";
6d36483b 4375
5fbd5940 4376 /* If this is a long branch with its delay slot unfilled, set `nullify'
4377 as it can nullify the delay slot and save a nop. */
5a1231ef 4378 if (length == 8 && dbr_sequence_length () == 0)
5fbd5940 4379 nullify = 1;
4380
4381 /* If this is a short forward conditional branch which did not get
4382 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 4383 if (! nullify && length == 4 && dbr_sequence_length () == 0)
5fbd5940 4384 nullify = forward_branch_p (insn);
4385
6d36483b 4386 /* A forward branch over a single nullified insn can be done with a
0d986529 4387 extrs instruction. This avoids a single cycle penalty due to
4388 mis-predicted branch if we fall through (branch not taken). */
4389
5a1231ef 4390 if (length == 4
5fbd5940 4391 && next_real_insn (insn) != 0
5a1231ef 4392 && get_attr_length (next_real_insn (insn)) == 4
5fbd5940 4393 && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
0d986529 4394 && nullify)
4395 useskip = 1;
4396
4397 switch (length)
4398 {
4399
5fbd5940 4400 /* All short conditional branches except backwards with an unfilled
4401 delay slot. */
5a1231ef 4402 case 4:
0d986529 4403 if (useskip)
4404 strcpy (buf, "extrs,");
6d36483b 4405 else
0d986529 4406 strcpy (buf, "bb,");
4407 if ((which == 0 && negated)
4408 || (which == 1 && ! negated))
4409 strcat (buf, ">=");
4410 else
4411 strcat (buf, "<");
4412 if (useskip)
4413 strcat (buf, " %0,%1,1,0");
4414 else if (nullify && negated)
4415 strcat (buf, ",n %0,%1,%3");
4416 else if (nullify && ! negated)
4417 strcat (buf, ",n %0,%1,%2");
4418 else if (! nullify && negated)
5fbd5940 4419 strcat (buf, "%0,%1,%3");
0d986529 4420 else if (! nullify && ! negated)
5fbd5940 4421 strcat (buf, " %0,%1,%2");
0d986529 4422 break;
4423
6d36483b 4424 /* All long conditionals. Note an short backward branch with an
5fbd5940 4425 unfilled delay slot is treated just like a long backward branch
4426 with an unfilled delay slot. */
5a1231ef 4427 case 8:
5fbd5940 4428 /* Handle weird backwards branch with a filled delay slot
4429 with is nullified. */
4430 if (dbr_sequence_length () != 0
4431 && ! forward_branch_p (insn)
4432 && nullify)
4433 {
4434 strcpy (buf, "bb,");
4435 if ((which == 0 && negated)
4436 || (which == 1 && ! negated))
4437 strcat (buf, "<");
4438 else
4439 strcat (buf, ">=");
4440 if (negated)
2b5f8dc2 4441 strcat (buf, ",n %0,%1,.+12\n\tbl %3,0");
5fbd5940 4442 else
2b5f8dc2 4443 strcat (buf, ",n %0,%1,.+12\n\tbl %2,0");
5fbd5940 4444 }
43f0c1f2 4445 /* Handle short backwards branch with an unfilled delay slot.
4446 Using a bb;nop rather than extrs;bl saves 1 cycle for both
4447 taken and untaken branches. */
4448 else if (dbr_sequence_length () == 0
4449 && ! forward_branch_p (insn)
4450 && insn_addresses
4451 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
c7a4e712 4452 - insn_addresses[INSN_UID (insn)] - 8))
43f0c1f2 4453 {
4454 strcpy (buf, "bb,");
4455 if ((which == 0 && negated)
4456 || (which == 1 && ! negated))
4457 strcat (buf, ">=");
4458 else
4459 strcat (buf, "<");
4460 if (negated)
4461 strcat (buf, " %0,%1,%3%#");
4462 else
4463 strcat (buf, " %0,%1,%2%#");
4464 }
0d986529 4465 else
5fbd5940 4466 {
4467 strcpy (buf, "extrs,");
4468 if ((which == 0 && negated)
4469 || (which == 1 && ! negated))
4470 strcat (buf, "<");
4471 else
4472 strcat (buf, ">=");
4473 if (nullify && negated)
4474 strcat (buf, " %0,%1,1,0\n\tbl,n %3,0");
4475 else if (nullify && ! negated)
4476 strcat (buf, " %0,%1,1,0\n\tbl,n %2,0");
4477 else if (negated)
4478 strcat (buf, " %0,%1,1,0\n\tbl %3,0");
6d36483b 4479 else
5fbd5940 4480 strcat (buf, " %0,%1,1,0\n\tbl %2,0");
4481 }
0d986529 4482 break;
4483
4484 default:
4485 abort();
5fbd5940 4486 }
0d986529 4487 return buf;
4488}
4489
c7a4e712 4490/* This routine handles all the branch-on-variable-bit conditional branch
4491 sequences we might need to generate. It handles nullification of delay
4492 slots, varying length branches, negated branches and all combinations
4493 of the above. it returns the appropriate output template to emit the
4494 branch. */
4495
4496char *
4497output_bvb (operands, nullify, length, negated, insn, which)
4498 rtx *operands;
4499 int nullify, length, negated;
4500 rtx insn;
4501 int which;
4502{
4503 static char buf[100];
4504 int useskip = 0;
4505
4506 /* A conditional branch to the following instruction (eg the delay slot) is
4507 asking for a disaster. I do not think this can happen as this pattern
4508 is only used when optimizing; jump optimization should eliminate the
4509 jump. But be prepared just in case. */
4510
4511 if (next_active_insn (JUMP_LABEL (insn)) == next_active_insn (insn))
4512 return "";
4513
4514 /* If this is a long branch with its delay slot unfilled, set `nullify'
4515 as it can nullify the delay slot and save a nop. */
4516 if (length == 8 && dbr_sequence_length () == 0)
4517 nullify = 1;
4518
4519 /* If this is a short forward conditional branch which did not get
4520 its delay slot filled, the delay slot can still be nullified. */
4521 if (! nullify && length == 4 && dbr_sequence_length () == 0)
4522 nullify = forward_branch_p (insn);
4523
4524 /* A forward branch over a single nullified insn can be done with a
4525 extrs instruction. This avoids a single cycle penalty due to
4526 mis-predicted branch if we fall through (branch not taken). */
4527
4528 if (length == 4
4529 && next_real_insn (insn) != 0
4530 && get_attr_length (next_real_insn (insn)) == 4
4531 && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
4532 && nullify)
4533 useskip = 1;
4534
4535 switch (length)
4536 {
4537
4538 /* All short conditional branches except backwards with an unfilled
4539 delay slot. */
4540 case 4:
4541 if (useskip)
4542 strcpy (buf, "vextrs,");
4543 else
4544 strcpy (buf, "bvb,");
4545 if ((which == 0 && negated)
4546 || (which == 1 && ! negated))
4547 strcat (buf, ">=");
4548 else
4549 strcat (buf, "<");
4550 if (useskip)
4551 strcat (buf, " %0,1,0");
4552 else if (nullify && negated)
4553 strcat (buf, ",n %0,%3");
4554 else if (nullify && ! negated)
4555 strcat (buf, ",n %0,%2");
4556 else if (! nullify && negated)
4557 strcat (buf, "%0,%3");
4558 else if (! nullify && ! negated)
4559 strcat (buf, " %0,%2");
4560 break;
4561
4562 /* All long conditionals. Note an short backward branch with an
4563 unfilled delay slot is treated just like a long backward branch
4564 with an unfilled delay slot. */
4565 case 8:
4566 /* Handle weird backwards branch with a filled delay slot
4567 with is nullified. */
4568 if (dbr_sequence_length () != 0
4569 && ! forward_branch_p (insn)
4570 && nullify)
4571 {
4572 strcpy (buf, "bvb,");
4573 if ((which == 0 && negated)
4574 || (which == 1 && ! negated))
4575 strcat (buf, "<");
4576 else
4577 strcat (buf, ">=");
4578 if (negated)
4579 strcat (buf, ",n %0,.+12\n\tbl %3,0");
4580 else
4581 strcat (buf, ",n %0,.+12\n\tbl %2,0");
4582 }
4583 /* Handle short backwards branch with an unfilled delay slot.
4584 Using a bb;nop rather than extrs;bl saves 1 cycle for both
4585 taken and untaken branches. */
4586 else if (dbr_sequence_length () == 0
4587 && ! forward_branch_p (insn)
4588 && insn_addresses
4589 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
4590 - insn_addresses[INSN_UID (insn)] - 8))
4591 {
4592 strcpy (buf, "bvb,");
4593 if ((which == 0 && negated)
4594 || (which == 1 && ! negated))
4595 strcat (buf, ">=");
4596 else
4597 strcat (buf, "<");
4598 if (negated)
4599 strcat (buf, " %0,%3%#");
4600 else
4601 strcat (buf, " %0,%2%#");
4602 }
4603 else
4604 {
4605 strcpy (buf, "vextrs,");
4606 if ((which == 0 && negated)
4607 || (which == 1 && ! negated))
4608 strcat (buf, "<");
4609 else
4610 strcat (buf, ">=");
4611 if (nullify && negated)
4612 strcat (buf, " %0,1,0\n\tbl,n %3,0");
4613 else if (nullify && ! negated)
4614 strcat (buf, " %0,1,0\n\tbl,n %2,0");
4615 else if (negated)
4616 strcat (buf, " %0,1,0\n\tbl %3,0");
4617 else
4618 strcat (buf, " %0,1,0\n\tbl %2,0");
4619 }
4620 break;
4621
4622 default:
4623 abort();
4624 }
4625 return buf;
4626}
4627
29a4502c 4628/* Return the output template for emitting a dbra type insn.
4629
4630 Note it may perform some output operations on its own before
4631 returning the final output string. */
4632char *
4633output_dbra (operands, insn, which_alternative)
4634 rtx *operands;
4635 rtx insn;
4636 int which_alternative;
4637{
4638
4639 /* A conditional branch to the following instruction (eg the delay slot) is
4640 asking for a disaster. Be prepared! */
4641
db3da815 4642 if (next_active_insn (JUMP_LABEL (insn)) == next_active_insn (insn))
29a4502c 4643 {
4644 if (which_alternative == 0)
4645 return "ldo %1(%0),%0";
4646 else if (which_alternative == 1)
4647 {
4648 output_asm_insn ("fstws %0,-16(0,%%r30)",operands);
4649 output_asm_insn ("ldw -16(0,%%r30),%4",operands);
4650 output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands);
4651 return "fldws -16(0,%%r30),%0";
4652 }
4653 else
4654 {
4655 output_asm_insn ("ldw %0,%4", operands);
4656 return "ldo %1(%4),%4\n\tstw %4,%0";
4657 }
4658 }
4659
4660 if (which_alternative == 0)
4661 {
4662 int nullify = INSN_ANNULLED_BRANCH_P (insn);
4663 int length = get_attr_length (insn);
4664
4665 /* If this is a long branch with its delay slot unfilled, set `nullify'
4666 as it can nullify the delay slot and save a nop. */
5a1231ef 4667 if (length == 8 && dbr_sequence_length () == 0)
29a4502c 4668 nullify = 1;
4669
4670 /* If this is a short forward conditional branch which did not get
4671 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 4672 if (! nullify && length == 4 && dbr_sequence_length () == 0)
29a4502c 4673 nullify = forward_branch_p (insn);
4674
4675 /* Handle short versions first. */
5a1231ef 4676 if (length == 4 && nullify)
29a4502c 4677 return "addib,%C2,n %1,%0,%3";
5a1231ef 4678 else if (length == 4 && ! nullify)
29a4502c 4679 return "addib,%C2 %1,%0,%3";
5a1231ef 4680 else if (length == 8)
29a4502c 4681 {
6d36483b 4682 /* Handle weird backwards branch with a fulled delay slot
29a4502c 4683 which is nullified. */
4684 if (dbr_sequence_length () != 0
4685 && ! forward_branch_p (insn)
4686 && nullify)
4687 return "addib,%N2,n %1,%0,.+12\n\tbl %3,0";
43f0c1f2 4688 /* Handle short backwards branch with an unfilled delay slot.
4689 Using a addb;nop rather than addi;bl saves 1 cycle for both
4690 taken and untaken branches. */
4691 else if (dbr_sequence_length () == 0
4692 && ! forward_branch_p (insn)
4693 && insn_addresses
4694 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
c7a4e712 4695 - insn_addresses[INSN_UID (insn)] - 8))
43f0c1f2 4696 return "addib,%C2 %1,%0,%3%#";
6d36483b 4697
4698 /* Handle normal cases. */
29a4502c 4699 if (nullify)
4700 return "addi,%N2 %1,%0,%0\n\tbl,n %3,0";
4701 else
4702 return "addi,%N2 %1,%0,%0\n\tbl %3,0";
4703 }
4704 else
4705 abort();
4706 }
4707 /* Deal with gross reload from FP register case. */
4708 else if (which_alternative == 1)
4709 {
4710 /* Move loop counter from FP register to MEM then into a GR,
4711 increment the GR, store the GR into MEM, and finally reload
6d36483b 4712 the FP register from MEM from within the branch's delay slot. */
29a4502c 4713 output_asm_insn ("fstws %0,-16(0,%%r30)\n\tldw -16(0,%%r30),%4",operands);
4714 output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands);
5a1231ef 4715 if (get_attr_length (insn) == 24)
29a4502c 4716 return "comb,%S2 0,%4,%3\n\tfldws -16(0,%%r30),%0";
4717 else
4718 return "comclr,%B2 0,%4,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0";
4719 }
4720 /* Deal with gross reload from memory case. */
4721 else
4722 {
4723 /* Reload loop counter from memory, the store back to memory
4724 happens in the branch's delay slot. */
4725 output_asm_insn ("ldw %0,%4", operands);
5a1231ef 4726 if (get_attr_length (insn) == 12)
29a4502c 4727 return "addib,%C2 %1,%4,%3\n\tstw %4,%0";
4728 else
b42d4c50 4729 return "addi,%N2 %1,%4,%4\n\tbl %3,0\n\tstw %4,%0";
29a4502c 4730 }
4731}
4732
4733/* Return the output template for emitting a dbra type insn.
4734
4735 Note it may perform some output operations on its own before
4736 returning the final output string. */
4737char *
4738output_movb (operands, insn, which_alternative, reverse_comparison)
4739 rtx *operands;
4740 rtx insn;
4741 int which_alternative;
4742 int reverse_comparison;
4743{
4744
4745 /* A conditional branch to the following instruction (eg the delay slot) is
4746 asking for a disaster. Be prepared! */
4747
db3da815 4748 if (next_active_insn (JUMP_LABEL (insn)) == next_active_insn (insn))
29a4502c 4749 {
4750 if (which_alternative == 0)
4751 return "copy %1,%0";
4752 else if (which_alternative == 1)
4753 {
b4437664 4754 output_asm_insn ("stw %1,-16(0,%%r30)",operands);
29a4502c 4755 return "fldws -16(0,%%r30),%0";
4756 }
546a40bd 4757 else if (which_alternative == 2)
29a4502c 4758 return "stw %1,%0";
546a40bd 4759 else
4760 return "mtsar %r1";
29a4502c 4761 }
4762
4763 /* Support the second variant. */
4764 if (reverse_comparison)
4765 PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
4766
4767 if (which_alternative == 0)
4768 {
4769 int nullify = INSN_ANNULLED_BRANCH_P (insn);
4770 int length = get_attr_length (insn);
4771
4772 /* If this is a long branch with its delay slot unfilled, set `nullify'
4773 as it can nullify the delay slot and save a nop. */
5a1231ef 4774 if (length == 8 && dbr_sequence_length () == 0)
29a4502c 4775 nullify = 1;
4776
4777 /* If this is a short forward conditional branch which did not get
4778 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 4779 if (! nullify && length == 4 && dbr_sequence_length () == 0)
29a4502c 4780 nullify = forward_branch_p (insn);
4781
4782 /* Handle short versions first. */
5a1231ef 4783 if (length == 4 && nullify)
29a4502c 4784 return "movb,%C2,n %1,%0,%3";
5a1231ef 4785 else if (length == 4 && ! nullify)
29a4502c 4786 return "movb,%C2 %1,%0,%3";
5a1231ef 4787 else if (length == 8)
29a4502c 4788 {
6d36483b 4789 /* Handle weird backwards branch with a filled delay slot
29a4502c 4790 which is nullified. */
4791 if (dbr_sequence_length () != 0
4792 && ! forward_branch_p (insn)
4793 && nullify)
eb4a3ec3 4794 return "movb,%N2,n %1,%0,.+12\n\tbl %3,0";
6d36483b 4795
43f0c1f2 4796 /* Handle short backwards branch with an unfilled delay slot.
4797 Using a movb;nop rather than or;bl saves 1 cycle for both
4798 taken and untaken branches. */
4799 else if (dbr_sequence_length () == 0
4800 && ! forward_branch_p (insn)
4801 && insn_addresses
4802 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
c7a4e712 4803 - insn_addresses[INSN_UID (insn)] - 8))
43f0c1f2 4804 return "movb,%C2 %1,%0,%3%#";
6d36483b 4805 /* Handle normal cases. */
29a4502c 4806 if (nullify)
4807 return "or,%N2 %1,%%r0,%0\n\tbl,n %3,0";
4808 else
4809 return "or,%N2 %1,%%r0,%0\n\tbl %3,0";
4810 }
4811 else
4812 abort();
4813 }
4814 /* Deal with gross reload from FP register case. */
4815 else if (which_alternative == 1)
4816 {
4817 /* Move loop counter from FP register to MEM then into a GR,
4818 increment the GR, store the GR into MEM, and finally reload
6d36483b 4819 the FP register from MEM from within the branch's delay slot. */
b4437664 4820 output_asm_insn ("stw %1,-16(0,%%r30)",operands);
5a1231ef 4821 if (get_attr_length (insn) == 12)
29a4502c 4822 return "comb,%S2 0,%1,%3\n\tfldws -16(0,%%r30),%0";
4823 else
4824 return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0";
4825 }
4826 /* Deal with gross reload from memory case. */
546a40bd 4827 else if (which_alternative == 2)
29a4502c 4828 {
4829 /* Reload loop counter from memory, the store back to memory
4830 happens in the branch's delay slot. */
5a1231ef 4831 if (get_attr_length (insn) == 8)
29a4502c 4832 return "comb,%S2 0,%1,%3\n\tstw %1,%0";
4833 else
4834 return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tstw %1,%0";
4835 }
546a40bd 4836 /* Handle SAR as a destination. */
4837 else
4838 {
4839 if (get_attr_length (insn) == 8)
4840 return "comb,%S2 0,%1,%3\n\tmtsar %r1";
4841 else
4842 return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tmtsar %r1";
4843 }
29a4502c 4844}
4845
4846
c7a4e712 4847/* INSN is a millicode call. It may have an unconditional jump in its delay
4848 slot.
3683f840 4849
c7a4e712 4850 CALL_DEST is the routine we are calling. */
3683f840 4851
d6686e21 4852char *
c7a4e712 4853output_millicode_call (insn, call_dest)
d6686e21 4854 rtx insn;
4855 rtx call_dest;
d6686e21 4856{
4857 int distance;
4858 rtx xoperands[4];
4859 rtx seq_insn;
4860
c7a4e712 4861 /* Handle common case -- empty delay slot or no jump in the delay slot,
4862 and we're sure that the branch will reach the beginning of the $CODE$
4863 subspace. */
4864 if ((dbr_sequence_length () == 0
c7a4e712 4865 && (get_attr_length (insn) == 8 || get_attr_length (insn) == 28))
c7a4e712 4866 || (dbr_sequence_length () != 0
4867 && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN
4868 && get_attr_length (insn) == 4))
06ddb6f8 4869 {
4870 xoperands[0] = call_dest;
c7a4e712 4871 output_asm_insn ("bl %0,%%r31%#", xoperands);
06ddb6f8 4872 return "";
4873 }
4874
c7a4e712 4875 /* This call may not reach the beginning of the $CODE$ subspace. */
4876 if (get_attr_length (insn) > 4)
4877 {
4878 int delay_insn_deleted = 0;
4879 rtx xoperands[2];
4880 rtx link;
4881
4882 /* We need to emit an inline long-call branch. */
4883 if (dbr_sequence_length () != 0
4884 && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN)
4885 {
4886 /* A non-jump insn in the delay slot. By definition we can
4887 emit this insn before the call. */
4888 final_scan_insn (NEXT_INSN (insn), asm_out_file, optimize, 0, 0);
4889
4890 /* Now delete the delay insn. */
4891 PUT_CODE (NEXT_INSN (insn), NOTE);
4892 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
4893 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
4894 delay_insn_deleted = 1;
4895 }
4896
4897 /* If we're allowed to use be/ble instructions, then this is the
4898 best sequence to use for a long millicode call. */
ac5850cf 4899 if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS
c7a4e712 4900 || ! (flag_pic || TARGET_PORTABLE_RUNTIME))
4901 {
4902 xoperands[0] = call_dest;
4903 output_asm_insn ("ldil L%%%0,%%r31", xoperands);
4904 output_asm_insn ("ble R%%%0(%%sr4,%%r31)", xoperands);
4905 output_asm_insn ("nop", xoperands);
4906 }
4907 /* Pure portable runtime doesn't allow be/ble; we also don't have
4908 PIC support int he assembler/linker, so this sequence is needed. */
4909 else if (TARGET_PORTABLE_RUNTIME)
4910 {
4911 xoperands[0] = call_dest;
4912 /* Get the address of our target into %r29. */
4913 output_asm_insn ("ldil L%%%0,%%r29", xoperands);
4914 output_asm_insn ("ldo R%%%0(%%r29),%%r29", xoperands);
4915
4916 /* Get our return address into %r31. */
4917 output_asm_insn ("blr 0,%%r31", xoperands);
4918
4919 /* Jump to our target address in %r29. */
4920 output_asm_insn ("bv,n 0(%%r29)", xoperands);
4921
4922 /* Empty delay slot. Note this insn gets fetched twice and
4923 executed once. To be safe we use a nop. */
4924 output_asm_insn ("nop", xoperands);
4925 return "";
4926 }
4927 /* PIC long millicode call sequence. */
4928 else
4929 {
4930 xoperands[0] = call_dest;
4931 xoperands[1] = gen_label_rtx ();
4932 /* Get our address + 8 into %r1. */
4933 output_asm_insn ("bl .+8,%%r1", xoperands);
4934
4935 /* Add %r1 to the offset of our target from the next insn. */
4936 output_asm_insn ("addil L%%%0-%1,%%r1", xoperands);
4937 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
4938 CODE_LABEL_NUMBER (xoperands[1]));
4939 output_asm_insn ("ldo R%%%0-%1(%%r1),%%r1", xoperands);
4940
4941 /* Get the return address into %r31. */
4942 output_asm_insn ("blr 0,%%r31", xoperands);
4943
4944 /* Branch to our target which is in %r1. */
4945 output_asm_insn ("bv,n 0(%%r1)", xoperands);
4946
4947 /* Empty delay slot. Note this insn gets fetched twice and
4948 executed once. To be safe we use a nop. */
4949 output_asm_insn ("nop", xoperands);
4950 }
4951
4952 /* If we had a jump in the call's delay slot, output it now. */
4953 if (dbr_sequence_length () != 0
4954 && !delay_insn_deleted)
4955 {
4956 xoperands[0] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
4957 output_asm_insn ("b,n %0", xoperands);
4958
4959 /* Now delete the delay insn. */
4960 PUT_CODE (NEXT_INSN (insn), NOTE);
4961 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
4962 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
4963 }
4964 return "";
4965 }
4966
4967 /* This call has an unconditional jump in its delay slot and the
4968 call is known to reach its target or the beginning of the current
4969 subspace. */
4970
4971 /* Use the containing sequence insn's address. */
4972 seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
4973
4974 distance = insn_addresses[INSN_UID (JUMP_LABEL (NEXT_INSN (insn)))]
4975 - insn_addresses[INSN_UID (seq_insn)] - 8;
4976
4977 /* If the branch was too far away, emit a normal call followed
4978 by a nop, followed by the unconditional branch.
4979
4980 If the branch is close, then adjust %r2 from within the
4981 call's delay slot. */
4982
4983 xoperands[0] = call_dest;
4984 xoperands[1] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
4985 if (! VAL_14_BITS_P (distance))
4986 output_asm_insn ("bl %0,%%r31\n\tnop\n\tbl,n %1,%%r0", xoperands);
4987 else
4988 {
4989 xoperands[3] = gen_label_rtx ();
4990 output_asm_insn ("\n\tbl %0,%%r31\n\tldo %1-%3(%%r31),%%r31", xoperands);
4991 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
4992 CODE_LABEL_NUMBER (xoperands[3]));
4993 }
4994
4995 /* Delete the jump. */
4996 PUT_CODE (NEXT_INSN (insn), NOTE);
4997 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
4998 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
4999 return "";
5000}
5001
5002/* INSN is either a function call. It may have an unconditional jump
5003 in its delay slot.
5004
5005 CALL_DEST is the routine we are calling. */
5006
5007char *
5008output_call (insn, call_dest)
5009 rtx insn;
5010 rtx call_dest;
5011{
5012 int distance;
5013 rtx xoperands[4];
5014 rtx seq_insn;
5015
06ddb6f8 5016 /* Handle common case -- empty delay slot or no jump in the delay slot,
5017 and we're sure that the branch will reach the beginning of the $CODE$
5018 subspace. */
5019 if ((dbr_sequence_length () == 0
5020 && get_attr_length (insn) == 8)
6d36483b 5021 || (dbr_sequence_length () != 0
06ddb6f8 5022 && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN
5023 && get_attr_length (insn) == 4))
d6686e21 5024 {
5025 xoperands[0] = call_dest;
c7a4e712 5026 output_asm_insn ("bl %0,%%r2%#", xoperands);
06ddb6f8 5027 return "";
5028 }
5029
5030 /* This call may not reach the beginning of the $CODE$ subspace. */
5031 if (get_attr_length (insn) > 8)
5032 {
5033 int delay_insn_deleted = 0;
5034 rtx xoperands[2];
5035 rtx link;
5036
5037 /* We need to emit an inline long-call branch. Furthermore,
5038 because we're changing a named function call into an indirect
5039 function call well after the parameters have been set up, we
5040 need to make sure any FP args appear in both the integer
5041 and FP registers. Also, we need move any delay slot insn
c7a4e712 5042 out of the delay slot. And finally, we can't rely on the linker
5043 being able to fix the call to $$dyncall! -- Yuk!. */
06ddb6f8 5044 if (dbr_sequence_length () != 0
5045 && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN)
3683f840 5046 {
06ddb6f8 5047 /* A non-jump insn in the delay slot. By definition we can
c7a4e712 5048 emit this insn before the call (and in fact before argument
5049 relocating. */
06ddb6f8 5050 final_scan_insn (NEXT_INSN (insn), asm_out_file, optimize, 0, 0);
5051
5052 /* Now delete the delay insn. */
5053 PUT_CODE (NEXT_INSN (insn), NOTE);
5054 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
5055 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
5056 delay_insn_deleted = 1;
5057 }
5058
5059 /* Now copy any FP arguments into integer registers. */
5060 for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
5061 {
5062 int arg_mode, regno;
5063 rtx use = XEXP (link, 0);
5064 if (! (GET_CODE (use) == USE
5065 && GET_CODE (XEXP (use, 0)) == REG
5066 && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
5067 continue;
5068
5069 arg_mode = GET_MODE (XEXP (use, 0));
5070 regno = REGNO (XEXP (use, 0));
5071 /* Is it a floating point register? */
5072 if (regno >= 32 && regno <= 39)
5073 {
5074 /* Copy from the FP register into an integer register
5075 (via memory). */
5076 if (arg_mode == SFmode)
5077 {
5078 xoperands[0] = XEXP (use, 0);
5079 xoperands[1] = gen_rtx (REG, SImode, 26 - (regno - 32) / 2);
5080 output_asm_insn ("fstws %0,-16(%%sr0,%%r30)", xoperands);
5081 output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
5082 }
5083 else
5084 {
5085 xoperands[0] = XEXP (use, 0);
5086 xoperands[1] = gen_rtx (REG, DImode, 25 - (regno - 34) / 2);
5087 output_asm_insn ("fstds %0,-16(%%sr0,%%r30)", xoperands);
5088 output_asm_insn ("ldw -12(%%sr0,%%r30),%R1", xoperands);
5089 output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
5090 }
5091
5092 }
5093 }
5094
c7a4e712 5095 /* Don't have to worry about TARGET_PORTABLE_RUNTIME here since
5096 we don't have any direct calls in that case. */
e3f53689 5097 if (flag_pic)
5098 {
5099 /* We have to load the address of the function using a procedure
5100 label (plabel). The LP and RP relocs don't work reliably for PIC,
5101 so we make a plain 32 bit plabel in the data segment instead. We
5102 have to defer outputting it of course... Not pretty. */
5103
5104 xoperands[0] = gen_label_rtx ();
c7a4e712 5105 xoperands[1] = gen_label_rtx ();
5106 output_asm_insn ("addil LT%%%0,%%r19", xoperands);
5107 output_asm_insn ("ldw RT%%%0(%%r1),%%r22", xoperands);
e3f53689 5108 output_asm_insn ("ldw 0(0,%%r22),%%r22", xoperands);
5109
5110 if (deferred_plabels == 0)
5111 deferred_plabels = (struct defer_plab *)
5112 xmalloc (1 * sizeof (struct defer_plab));
5113 else
5114 deferred_plabels = (struct defer_plab *)
5115 xrealloc (deferred_plabels,
5116 (n_deferred_plabels + 1) * sizeof (struct defer_plab));
5117 deferred_plabels[n_deferred_plabels].internal_label = xoperands[0];
5118 deferred_plabels[n_deferred_plabels].symbol = call_dest;
5119 n_deferred_plabels++;
c7a4e712 5120
5121 /* Get our address + 8 into %r1. */
5122 output_asm_insn ("bl .+8,%%r1", xoperands);
5123
5124 /* Add %r1 to the offset of dyncall from the next insn. */
5125 output_asm_insn ("addil L%%$$dyncall-%1,%%r1", xoperands);
5126 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5127 CODE_LABEL_NUMBER (xoperands[1]));
5128 output_asm_insn ("ldo R%%$$dyncall-%1(%%r1),%%r1", xoperands);
5129
5130 /* Get the return address into %r31. */
5131 output_asm_insn ("blr 0,%%r31", xoperands);
5132
5133 /* Branch to our target which is in %r1. */
5134 output_asm_insn ("bv 0(%%r1)", xoperands);
5135
5136 /* Copy the return address into %r2 also. */
5137 output_asm_insn ("copy %%r31,%%r2", xoperands);
e3f53689 5138 }
5139 else
5140 {
c7a4e712 5141 /* No PIC stuff to worry about. We can use ldil;ble. */
e3f53689 5142 xoperands[0] = call_dest;
06ddb6f8 5143
c7a4e712 5144 /* Get the address of our target into %r22. */
5145 output_asm_insn ("ldil LP%%%0,%%r22", xoperands);
5146 output_asm_insn ("ldo RP%%%0(%%r22),%%r22", xoperands);
5147
5148 /* Get the high part of the address of $dyncall into %r2, then
5149 add in the low part in the branch instruction. */
5150 output_asm_insn ("ldil L%%$$dyncall,%%r2", xoperands);
5151 output_asm_insn ("ble R%%$$dyncall(%%sr4,%%r2)", xoperands);
5152
5153 /* Copy the return pointer into both %r31 and %r2. */
5154 output_asm_insn ("copy %%r31,%%r2", xoperands);
3683f840 5155 }
06ddb6f8 5156
5157 /* If we had a jump in the call's delay slot, output it now. */
5158 if (dbr_sequence_length () != 0
5159 && !delay_insn_deleted)
5160 {
5161 xoperands[0] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
5162 output_asm_insn ("b,n %0", xoperands);
5163
5164 /* Now delete the delay insn. */
5165 PUT_CODE (NEXT_INSN (insn), NOTE);
5166 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
5167 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
5168 }
d6686e21 5169 return "";
5170 }
6d36483b 5171
c7a4e712 5172 /* This call has an unconditional jump in its delay slot and the
5173 call is known to reach its target or the beginning of the current
5174 subspace. */
d6686e21 5175
5176 /* Use the containing sequence insn's address. */
5177 seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
5178
6d36483b 5179 distance = insn_addresses[INSN_UID (JUMP_LABEL (NEXT_INSN (insn)))]
d6686e21 5180 - insn_addresses[INSN_UID (seq_insn)] - 8;
5181
5182 /* If the branch was too far away, emit a normal call followed
5183 by a nop, followed by the unconditional branch.
5184
6d36483b 5185 If the branch is close, then adjust %r2 from within the
d6686e21 5186 call's delay slot. */
5187
5188 xoperands[0] = call_dest;
5189 xoperands[1] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
d6686e21 5190 if (! VAL_14_BITS_P (distance))
c7a4e712 5191 output_asm_insn ("bl %0,%%r2\n\tnop\n\tbl,n %1,%%r0", xoperands);
d6686e21 5192 else
5193 {
5194 xoperands[3] = gen_label_rtx ();
c7a4e712 5195 output_asm_insn ("\n\tbl %0,%%r2\n\tldo %1-%3(%%r2),%%r2", xoperands);
6d36483b 5196 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
0410a74e 5197 CODE_LABEL_NUMBER (xoperands[3]));
d6686e21 5198 }
5199
5200 /* Delete the jump. */
5201 PUT_CODE (NEXT_INSN (insn), NOTE);
5202 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
5203 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
5204 return "";
5205}
5206
33f67bdd 5207extern struct obstack permanent_obstack;
d6f01525 5208extern struct obstack *saveable_obstack;
5209
5210/* In HPUX 8.0's shared library scheme, special relocations are needed
6d36483b 5211 for function labels if they might be passed to a function
d6f01525 5212 in a shared library (because shared libraries don't live in code
34fc0dd7 5213 space), and special magic is needed to construct their address.
5214
5215 For reasons too disgusting to describe storage for the new name
5216 is allocated either on the saveable_obstack (released at function
33f67bdd 5217 exit) or on the permanent_obstack for things that can never change
5218 (libcall names for example). */
d6f01525 5219
5220void
34fc0dd7 5221hppa_encode_label (sym, permanent)
d6f01525 5222 rtx sym;
34fc0dd7 5223 int permanent;
d6f01525 5224{
5225 char *str = XSTR (sym, 0);
5226 int len = strlen (str);
34fc0dd7 5227 char *newstr;
5228
33f67bdd 5229 newstr = obstack_alloc ((permanent ? &permanent_obstack : saveable_obstack),
5230 len + 2);
d6f01525 5231
c1b3411e 5232 if (str[0] == '*')
5233 *newstr++ = *str++;
d6f01525 5234 strcpy (newstr + 1, str);
c1b3411e 5235 *newstr = '@';
d6f01525 5236 XSTR (sym,0) = newstr;
5237}
6d36483b 5238
d6f01525 5239int
166bf021 5240function_label_operand (op, mode)
d6f01525 5241 rtx op;
5242 enum machine_mode mode;
5243{
c1b3411e 5244 return GET_CODE (op) == SYMBOL_REF && FUNCTION_NAME_P (XSTR (op, 0));
d6f01525 5245}
f33e3942 5246
166bf021 5247/* Returns 1 if OP is a function label involved in a simple addition
5248 with a constant. Used to keep certain patterns from matching
5249 during instruction combination. */
5250int
5251is_function_label_plus_const (op)
5252 rtx op;
5253{
5254 /* Strip off any CONST. */
5255 if (GET_CODE (op) == CONST)
5256 op = XEXP (op, 0);
5257
5258 return (GET_CODE (op) == PLUS
5259 && function_label_operand (XEXP (op, 0), Pmode)
5260 && GET_CODE (XEXP (op, 1)) == CONST_INT);
5261}
5262
37580c80 5263/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
5264 use in fmpyadd instructions. */
4ed6ee50 5265int
df0651dc 5266fmpyaddoperands (operands)
4ed6ee50 5267 rtx *operands;
5268{
201f01e9 5269 enum machine_mode mode = GET_MODE (operands[0]);
4ed6ee50 5270
ab449421 5271 /* Must be a floating point mode. */
5272 if (mode != SFmode && mode != DFmode)
5273 return 0;
5274
4ed6ee50 5275 /* All modes must be the same. */
201f01e9 5276 if (! (mode == GET_MODE (operands[1])
5277 && mode == GET_MODE (operands[2])
5278 && mode == GET_MODE (operands[3])
5279 && mode == GET_MODE (operands[4])
5280 && mode == GET_MODE (operands[5])))
4ed6ee50 5281 return 0;
5282
ab449421 5283 /* All operands must be registers. */
5284 if (! (GET_CODE (operands[1]) == REG
5285 && GET_CODE (operands[2]) == REG
5286 && GET_CODE (operands[3]) == REG
5287 && GET_CODE (operands[4]) == REG
5288 && GET_CODE (operands[5]) == REG))
4ed6ee50 5289 return 0;
5290
37580c80 5291 /* Only 2 real operands to the addition. One of the input operands must
5292 be the same as the output operand. */
4ed6ee50 5293 if (! rtx_equal_p (operands[3], operands[4])
5294 && ! rtx_equal_p (operands[3], operands[5]))
5295 return 0;
5296
5297 /* Inout operand of add can not conflict with any operands from multiply. */
5298 if (rtx_equal_p (operands[3], operands[0])
5299 || rtx_equal_p (operands[3], operands[1])
5300 || rtx_equal_p (operands[3], operands[2]))
5301 return 0;
5302
5303 /* multiply can not feed into addition operands. */
5304 if (rtx_equal_p (operands[4], operands[0])
5305 || rtx_equal_p (operands[5], operands[0]))
5306 return 0;
5307
ab449421 5308 /* SFmode limits the registers to the upper 32 of the 32bit FP regs. */
5309 if (mode == SFmode
5310 && (REGNO (operands[0]) < 57
5311 || REGNO (operands[1]) < 57
5312 || REGNO (operands[2]) < 57
5313 || REGNO (operands[3]) < 57
5314 || REGNO (operands[4]) < 57
5315 || REGNO (operands[5]) < 57))
5316 return 0;
5317
4ed6ee50 5318 /* Passed. Operands are suitable for fmpyadd. */
5319 return 1;
5320}
5321
37580c80 5322/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
5323 use in fmpysub instructions. */
4ed6ee50 5324int
df0651dc 5325fmpysuboperands (operands)
4ed6ee50 5326 rtx *operands;
5327{
201f01e9 5328 enum machine_mode mode = GET_MODE (operands[0]);
4ed6ee50 5329
ab449421 5330 /* Must be a floating point mode. */
5331 if (mode != SFmode && mode != DFmode)
5332 return 0;
5333
4ed6ee50 5334 /* All modes must be the same. */
201f01e9 5335 if (! (mode == GET_MODE (operands[1])
5336 && mode == GET_MODE (operands[2])
5337 && mode == GET_MODE (operands[3])
5338 && mode == GET_MODE (operands[4])
5339 && mode == GET_MODE (operands[5])))
4ed6ee50 5340 return 0;
5341
ab449421 5342 /* All operands must be registers. */
5343 if (! (GET_CODE (operands[1]) == REG
5344 && GET_CODE (operands[2]) == REG
5345 && GET_CODE (operands[3]) == REG
5346 && GET_CODE (operands[4]) == REG
5347 && GET_CODE (operands[5]) == REG))
4ed6ee50 5348 return 0;
5349
37580c80 5350 /* Only 2 real operands to the subtraction. Subtraction is not a commutative
5351 operation, so operands[4] must be the same as operand[3]. */
4ed6ee50 5352 if (! rtx_equal_p (operands[3], operands[4]))
5353 return 0;
5354
5355 /* multiply can not feed into subtraction. */
37580c80 5356 if (rtx_equal_p (operands[5], operands[0]))
4ed6ee50 5357 return 0;
5358
37580c80 5359 /* Inout operand of sub can not conflict with any operands from multiply. */
4ed6ee50 5360 if (rtx_equal_p (operands[3], operands[0])
5361 || rtx_equal_p (operands[3], operands[1])
5362 || rtx_equal_p (operands[3], operands[2]))
5363 return 0;
5364
ab449421 5365 /* SFmode limits the registers to the upper 32 of the 32bit FP regs. */
5366 if (mode == SFmode
5367 && (REGNO (operands[0]) < 57
5368 || REGNO (operands[1]) < 57
5369 || REGNO (operands[2]) < 57
5370 || REGNO (operands[3]) < 57
5371 || REGNO (operands[4]) < 57
5372 || REGNO (operands[5]) < 57))
5373 return 0;
5374
4ed6ee50 5375 /* Passed. Operands are suitable for fmpysub. */
5376 return 1;
5377}
5378
89f29d73 5379int
5380plus_xor_ior_operator (op, mode)
5381 rtx op;
5382 enum machine_mode mode;
5383{
5384 return (GET_CODE (op) == PLUS || GET_CODE (op) == XOR
5385 || GET_CODE (op) == IOR);
5386}
6720f95e 5387
5388/* Return 1 if the given constant is 2, 4, or 8. These are the valid
5389 constants for shadd instructions. */
5390int
5391shadd_constant_p (val)
5392 int val;
5393{
5394 if (val == 2 || val == 4 || val == 8)
5395 return 1;
5396 else
5397 return 0;
5398}
3a16146d 5399
5400/* Return 1 if OP is a CONST_INT with the value 2, 4, or 8. These are
5401 the valid constant for shadd instructions. */
5402int
5403shadd_operand (op, mode)
5404 rtx op;
5405 enum machine_mode mode;
5406{
5407 return (GET_CODE (op) == CONST_INT && shadd_constant_p (INTVAL (op)));
5408}
5fbd5940 5409
42819d4e 5410/* Return 1 if OP is valid as a base register in a reg + reg address. */
5411
5412int
5413basereg_operand (op, mode)
5414 rtx op;
5415 enum machine_mode mode;
5416{
21f3ee9c 5417 /* cse will create some unscaled indexed addresses, however; it
5418 generally isn't a win on the PA, so avoid creating unscaled
5419 indexed addresses until after cse is finished. */
5420 if (!cse_not_expected)
5421 return 0;
5422
42819d4e 5423 /* Once reload has started everything is considered valid. Reload should
5424 only create indexed addresses using the stack/frame pointer, and any
5425 others were checked for validity when created by the combine pass.
5426
5427 Also allow any register when TARGET_NO_SPACE_REGS is in effect since
5428 we don't have to worry about the braindamaged implicit space register
5429 selection using the basereg only (rather than effective address)
5430 screwing us over. */
5431 if (TARGET_NO_SPACE_REGS || reload_in_progress || reload_completed)
23a667d0 5432 return (GET_CODE (op) == REG);
42819d4e 5433
21f3ee9c 5434 /* Stack is always OK for indexing. */
5435 if (op == stack_pointer_rtx)
5436 return 1;
5437
5438 /* While it's always safe to index off the frame pointer, it's not
5439 always profitable, particularly when the frame pointer is being
5440 eliminated. */
5441 if (! flag_omit_frame_pointer && op == frame_pointer_rtx)
42819d4e 5442 return 1;
5443
5444 /* The only other valid OPs are pseudo registers with
5445 REGNO_POINTER_FLAG set. */
5446 if (GET_CODE (op) != REG
5447 || REGNO (op) < FIRST_PSEUDO_REGISTER
5448 || ! register_operand (op, mode))
5449 return 0;
5450
5451 return REGNO_POINTER_FLAG (REGNO (op));
5452}
5453
51987f90 5454/* Return 1 if this operand is anything other than a hard register. */
5455
5456int
5457non_hard_reg_operand (op, mode)
5458 rtx op;
5459 enum machine_mode mode;
5460{
5461 return ! (GET_CODE (op) == REG && REGNO (op) < FIRST_PSEUDO_REGISTER);
5462}
5463
5fbd5940 5464/* Return 1 if INSN branches forward. Should be using insn_addresses
5465 to avoid walking through all the insns... */
5466int
5467forward_branch_p (insn)
5468 rtx insn;
5469{
5470 rtx label = JUMP_LABEL (insn);
5471
5472 while (insn)
5473 {
5474 if (insn == label)
5475 break;
5476 else
5477 insn = NEXT_INSN (insn);
5478 }
5479
5480 return (insn == label);
5481}
5482
29a4502c 5483/* Return 1 if OP is an equality comparison, else return 0. */
5484int
5485eq_neq_comparison_operator (op, mode)
5486 rtx op;
5487 enum machine_mode mode;
5488{
5489 return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
5490}
5491
5492/* Return 1 if OP is an operator suitable for use in a movb instruction. */
5493int
5494movb_comparison_operator (op, mode)
5495 rtx op;
5496 enum machine_mode mode;
5497{
5498 return (GET_CODE (op) == EQ || GET_CODE (op) == NE
5499 || GET_CODE (op) == LT || GET_CODE (op) == GE);
5500}
5501
d6686e21 5502/* Return 1 if INSN is in the delay slot of a call instruction. */
5503int
5504jump_in_call_delay (insn)
5505 rtx insn;
5506{
5507
5508 if (GET_CODE (insn) != JUMP_INSN)
5509 return 0;
5510
5511 if (PREV_INSN (insn)
5512 && PREV_INSN (PREV_INSN (insn))
5513 && GET_CODE (next_active_insn (PREV_INSN (PREV_INSN (insn)))) == INSN)
5514 {
5515 rtx test_insn = next_active_insn (PREV_INSN (PREV_INSN (insn)));
5516
5517 return (GET_CODE (PATTERN (test_insn)) == SEQUENCE
5518 && XVECEXP (PATTERN (test_insn), 0, 1) == insn);
5519
5520 }
5521 else
5522 return 0;
5523}
3b1e673e 5524
546a40bd 5525/* Output an unconditional move and branch insn. */
5526
5527char *
5528output_parallel_movb (operands, length)
5529 rtx *operands;
5530 int length;
5531{
5532 /* These are the cases in which we win. */
5533 if (length == 4)
5534 return "mov%I1b,tr %1,%0,%2";
5535
5536 /* None of these cases wins, but they don't lose either. */
5537 if (dbr_sequence_length () == 0)
5538 {
5539 /* Nothing in the delay slot, fake it by putting the combined
5540 insn (the copy or add) in the delay slot of a bl. */
5541 if (GET_CODE (operands[1]) == CONST_INT)
5542 return "bl %2,0\n\tldi %1,%0";
5543 else
5544 return "bl %2,0\n\tcopy %1,%0";
5545 }
5546 else
5547 {
5548 /* Something in the delay slot, but we've got a long branch. */
5549 if (GET_CODE (operands[1]) == CONST_INT)
5550 return "ldi %1,%0\n\tbl %2,0";
5551 else
5552 return "copy %1,%0\n\tbl %2,0";
5553 }
5554}
5555
5556/* Output an unconditional add and branch insn. */
5557
5558char *
5559output_parallel_addb (operands, length)
5560 rtx *operands;
5561 int length;
5562{
5563 /* To make life easy we want operand0 to be the shared input/output
5564 operand and operand1 to be the readonly operand. */
5565 if (operands[0] == operands[1])
5566 operands[1] = operands[2];
5567
5568 /* These are the cases in which we win. */
5569 if (length == 4)
5570 return "add%I1b,tr %1,%0,%3";
5571
5572 /* None of these cases win, but they don't lose either. */
5573 if (dbr_sequence_length () == 0)
5574 {
5575 /* Nothing in the delay slot, fake it by putting the combined
5576 insn (the copy or add) in the delay slot of a bl. */
5577 return "bl %3,0\n\tadd%I1 %1,%0,%0";
5578 }
5579 else
5580 {
5581 /* Something in the delay slot, but we've got a long branch. */
5582 return "add%I1 %1,%0,%0\n\tbl %3,0";
5583 }
5584}
5585
546a40bd 5586/* Return nonzero if INSN (a jump insn) immediately follows a call. This
5587 is used to discourage creating parallel movb/addb insns since a jump
5588 which immediately follows a call can execute in the delay slot of the
5589 call. */
5590
5591following_call (insn)
5592 rtx insn;
5593{
5594 /* Find the previous real insn, skipping NOTEs. */
5595 insn = PREV_INSN (insn);
5596 while (insn && GET_CODE (insn) == NOTE)
5597 insn = PREV_INSN (insn);
5598
5599 /* Check for CALL_INSNs and millicode calls. */
5600 if (insn
5601 && (GET_CODE (insn) == CALL_INSN
5602 || (GET_CODE (insn) == INSN
5603 && GET_CODE (PATTERN (insn)) != SEQUENCE
5604 && GET_CODE (PATTERN (insn)) != USE
5605 && GET_CODE (PATTERN (insn)) != CLOBBER
5606 && get_attr_type (insn) == TYPE_MILLI)))
5607 return 1;
5608
5609 return 0;
5610}
5611
3b1e673e 5612/* We use this hook to perform a PA specific optimization which is difficult
5613 to do in earlier passes.
5614
5615 We want the delay slots of branches within jump tables to be filled.
5616 None of the compiler passes at the moment even has the notion that a
5617 PA jump table doesn't contain addresses, but instead contains actual
5618 instructions!
5619
5620 Because we actually jump into the table, the addresses of each entry
01cc3b75 5621 must stay constant in relation to the beginning of the table (which
3b1e673e 5622 itself must stay constant relative to the instruction to jump into
5623 it). I don't believe we can guarantee earlier passes of the compiler
5624 will adhere to those rules.
5625
5626 So, late in the compilation process we find all the jump tables, and
5627 expand them into real code -- eg each entry in the jump table vector
5628 will get an appropriate label followed by a jump to the final target.
5629
5630 Reorg and the final jump pass can then optimize these branches and
5631 fill their delay slots. We end up with smaller, more efficient code.
5632
5633 The jump instructions within the table are special; we must be able
5634 to identify them during assembly output (if the jumps don't get filled
5635 we need to emit a nop rather than nullifying the delay slot)). We
5636 identify jumps in switch tables by marking the SET with DImode. */
5637
5638pa_reorg (insns)
5639 rtx insns;
5640{
5641 rtx insn;
5642
c533da59 5643 remove_useless_addtr_insns (insns, 1);
3d457930 5644
bd49d362 5645 pa_combine_instructions (get_insns ());
5646
3d457930 5647 /* This is fairly cheap, so always run it if optimizing. */
3b1e673e 5648 if (optimize > 0)
5649 {
5650 /* Find and explode all ADDR_VEC insns. */
5651 insns = get_insns ();
5652 for (insn = insns; insn; insn = NEXT_INSN (insn))
5653 {
5654 rtx pattern, tmp, location;
5655 unsigned int length, i;
5656
5657 /* Find an ADDR_VEC insn to explode. */
5658 if (GET_CODE (insn) != JUMP_INSN
5659 || GET_CODE (PATTERN (insn)) != ADDR_VEC)
5660 continue;
5661
f9333726 5662 /* If needed, emit marker for the beginning of the branch table. */
5663 if (TARGET_GAS)
5664 emit_insn_before (gen_begin_brtab (), insn);
5665
3b1e673e 5666 pattern = PATTERN (insn);
5667 location = PREV_INSN (insn);
5668 length = XVECLEN (pattern, 0);
f9333726 5669
3b1e673e 5670 for (i = 0; i < length; i++)
5671 {
5672 /* Emit the jump itself. */
5673 tmp = gen_switch_jump (XEXP (XVECEXP (pattern, 0, i), 0));
5674 tmp = emit_jump_insn_after (tmp, location);
5675 JUMP_LABEL (tmp) = XEXP (XVECEXP (pattern, 0, i), 0);
331808ce 5676 LABEL_NUSES (JUMP_LABEL (tmp))++;
3b1e673e 5677
5678 /* Emit a BARRIER after the jump. */
5679 location = NEXT_INSN (location);
5680 emit_barrier_after (location);
5681
5682 /* Put a CODE_LABEL before each so jump.c does not optimize
5683 the jumps away. */
5684 location = NEXT_INSN (location);
5685 tmp = gen_label_rtx ();
5686 LABEL_NUSES (tmp) = 1;
5687 emit_label_after (tmp, location);
5688 location = NEXT_INSN (location);
5689 }
f9333726 5690
5691 /* If needed, emit marker for the end of the branch table. */
5692 if (TARGET_GAS)
5693 emit_insn_before (gen_end_brtab (), location);
3b1e673e 5694 /* Delete the ADDR_VEC. */
5695 delete_insn (insn);
5696 }
5697 }
f9333726 5698 else if (TARGET_GAS)
5699 {
5700 /* Sill need an end_brtab insn. */
5701 insns = get_insns ();
5702 for (insn = insns; insn; insn = NEXT_INSN (insn))
5703 {
5704 /* Find an ADDR_VEC insn. */
5705 if (GET_CODE (insn) != JUMP_INSN
5706 || GET_CODE (PATTERN (insn)) != ADDR_VEC)
5707 continue;
5708
5709 /* Now generate markers for the beginning and end of the
5710 branc table. */
5711 emit_insn_before (gen_begin_brtab (), insn);
5712 emit_insn_after (gen_end_brtab (), insn);
5713 }
5714 }
d3287673 5715}
bd49d362 5716
5717/* The PA has a number of odd instructions which can perform multiple
5718 tasks at once. On first generation PA machines (PA1.0 and PA1.1)
5719 it may be profitable to combine two instructions into one instruction
5720 with two outputs. It's not profitable PA2.0 machines because the
5721 two outputs would take two slots in the reorder buffers.
5722
5723 This routine finds instructions which can be combined and combines
5724 them. We only support some of the potential combinations, and we
5725 only try common ways to find suitable instructions.
5726
5727 * addb can add two registers or a register and a small integer
5728 and jump to a nearby (+-8k) location. Normally the jump to the
5729 nearby location is conditional on the result of the add, but by
5730 using the "true" condition we can make the jump unconditional.
5731 Thus addb can perform two independent operations in one insn.
5732
5733 * movb is similar to addb in that it can perform a reg->reg
5734 or small immediate->reg copy and jump to a nearby (+-8k location).
5735
5736 * fmpyadd and fmpysub can perform a FP multiply and either an
5737 FP add or FP sub if the operands of the multiply and add/sub are
5738 independent (there are other minor restrictions). Note both
5739 the fmpy and fadd/fsub can in theory move to better spots according
5740 to data dependencies, but for now we require the fmpy stay at a
5741 fixed location.
5742
5743 * Many of the memory operations can perform pre & post updates
5744 of index registers. GCC's pre/post increment/decrement addressing
5745 is far too simple to take advantage of all the possibilities. This
5746 pass may not be suitable since those insns may not be independent.
5747
5748 * comclr can compare two ints or an int and a register, nullify
5749 the following instruction and zero some other register. This
5750 is more difficult to use as it's harder to find an insn which
5751 will generate a comclr than finding something like an unconditional
5752 branch. (conditional moves & long branches create comclr insns).
5753
5754 * Most arithmetic operations can conditionally skip the next
5755 instruction. They can be viewed as "perform this operation
5756 and conditionally jump to this nearby location" (where nearby
5757 is an insns away). These are difficult to use due to the
5758 branch length restrictions. */
5759
5760pa_combine_instructions (insns)
5761 rtx insns;
5762{
5763 rtx anchor, new;
5764
5765 /* This can get expensive since the basic algorithm is on the
5766 order of O(n^2) (or worse). Only do it for -O2 or higher
5767 levels of optimizaton. */
5768 if (optimize < 2)
5769 return;
5770
5771 /* Walk down the list of insns looking for "anchor" insns which
5772 may be combined with "floating" insns. As the name implies,
5773 "anchor" instructions don't move, while "floating" insns may
5774 move around. */
5775 new = gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, NULL_RTX, NULL_RTX));
5776 new = make_insn_raw (new);
5777
5778 for (anchor = get_insns (); anchor; anchor = NEXT_INSN (anchor))
5779 {
5780 enum attr_pa_combine_type anchor_attr;
5781 enum attr_pa_combine_type floater_attr;
5782
5783 /* We only care about INSNs, JUMP_INSNs, and CALL_INSNs.
5784 Also ignore any special USE insns. */
5785 if (GET_CODE (anchor) != INSN
5786 && GET_CODE (anchor) != JUMP_INSN
5787 && GET_CODE (anchor) != CALL_INSN
5788 || GET_CODE (PATTERN (anchor)) == USE
5789 || GET_CODE (PATTERN (anchor)) == CLOBBER
5790 || GET_CODE (PATTERN (anchor)) == ADDR_VEC
5791 || GET_CODE (PATTERN (anchor)) == ADDR_DIFF_VEC)
5792 continue;
5793
5794 anchor_attr = get_attr_pa_combine_type (anchor);
5795 /* See if anchor is an insn suitable for combination. */
5796 if (anchor_attr == PA_COMBINE_TYPE_FMPY
5797 || anchor_attr == PA_COMBINE_TYPE_FADDSUB
5798 || (anchor_attr == PA_COMBINE_TYPE_UNCOND_BRANCH
5799 && ! forward_branch_p (anchor)))
5800 {
5801 rtx floater;
5802
5803 for (floater = PREV_INSN (anchor);
5804 floater;
5805 floater = PREV_INSN (floater))
5806 {
5807 if (GET_CODE (floater) == NOTE
5808 || (GET_CODE (floater) == INSN
5809 && (GET_CODE (PATTERN (floater)) == USE
5810 || GET_CODE (PATTERN (floater)) == CLOBBER)))
5811 continue;
5812
5813 /* Anything except a regular INSN will stop our search. */
5814 if (GET_CODE (floater) != INSN
5815 || GET_CODE (PATTERN (floater)) == ADDR_VEC
5816 || GET_CODE (PATTERN (floater)) == ADDR_DIFF_VEC)
5817 {
5818 floater = NULL_RTX;
5819 break;
5820 }
5821
5822 /* See if FLOATER is suitable for combination with the
5823 anchor. */
5824 floater_attr = get_attr_pa_combine_type (floater);
5825 if ((anchor_attr == PA_COMBINE_TYPE_FMPY
5826 && floater_attr == PA_COMBINE_TYPE_FADDSUB)
5827 || (anchor_attr == PA_COMBINE_TYPE_FADDSUB
5828 && floater_attr == PA_COMBINE_TYPE_FMPY))
5829 {
5830 /* If ANCHOR and FLOATER can be combined, then we're
5831 done with this pass. */
5832 if (pa_can_combine_p (new, anchor, floater, 0,
5833 SET_DEST (PATTERN (floater)),
5834 XEXP (SET_SRC (PATTERN (floater)), 0),
5835 XEXP (SET_SRC (PATTERN (floater)), 1)))
5836 break;
5837 }
5838
5839 else if (anchor_attr == PA_COMBINE_TYPE_UNCOND_BRANCH
5840 && floater_attr == PA_COMBINE_TYPE_ADDMOVE)
5841 {
5842 if (GET_CODE (SET_SRC (PATTERN (floater))) == PLUS)
5843 {
5844 if (pa_can_combine_p (new, anchor, floater, 0,
5845 SET_DEST (PATTERN (floater)),
5846 XEXP (SET_SRC (PATTERN (floater)), 0),
5847 XEXP (SET_SRC (PATTERN (floater)), 1)))
5848 break;
5849 }
5850 else
5851 {
5852 if (pa_can_combine_p (new, anchor, floater, 0,
5853 SET_DEST (PATTERN (floater)),
5854 SET_SRC (PATTERN (floater)),
5855 SET_SRC (PATTERN (floater))))
5856 break;
5857 }
5858 }
5859 }
5860
5861 /* If we didn't find anything on the backwards scan try forwards. */
5862 if (!floater
5863 && (anchor_attr == PA_COMBINE_TYPE_FMPY
5864 || anchor_attr == PA_COMBINE_TYPE_FADDSUB))
5865 {
5866 for (floater = anchor; floater; floater = NEXT_INSN (floater))
5867 {
5868 if (GET_CODE (floater) == NOTE
5869 || (GET_CODE (floater) == INSN
5870 && (GET_CODE (PATTERN (floater)) == USE
5871 || GET_CODE (PATTERN (floater)) == CLOBBER)))
5872
5873 continue;
5874
5875 /* Anything except a regular INSN will stop our search. */
5876 if (GET_CODE (floater) != INSN
5877 || GET_CODE (PATTERN (floater)) == ADDR_VEC
5878 || GET_CODE (PATTERN (floater)) == ADDR_DIFF_VEC)
5879 {
5880 floater = NULL_RTX;
5881 break;
5882 }
5883
5884 /* See if FLOATER is suitable for combination with the
5885 anchor. */
5886 floater_attr = get_attr_pa_combine_type (floater);
5887 if ((anchor_attr == PA_COMBINE_TYPE_FMPY
5888 && floater_attr == PA_COMBINE_TYPE_FADDSUB)
5889 || (anchor_attr == PA_COMBINE_TYPE_FADDSUB
5890 && floater_attr == PA_COMBINE_TYPE_FMPY))
5891 {
5892 /* If ANCHOR and FLOATER can be combined, then we're
5893 done with this pass. */
5894 if (pa_can_combine_p (new, anchor, floater, 1,
5895 SET_DEST (PATTERN (floater)),
5896 XEXP (SET_SRC (PATTERN(floater)),0),
5897 XEXP(SET_SRC(PATTERN(floater)),1)))
5898 break;
5899 }
5900 }
5901 }
5902
5903 /* FLOATER will be nonzero if we found a suitable floating
5904 insn for combination with ANCHOR. */
5905 if (floater
5906 && (anchor_attr == PA_COMBINE_TYPE_FADDSUB
5907 || anchor_attr == PA_COMBINE_TYPE_FMPY))
5908 {
5909 /* Emit the new instruction and delete the old anchor. */
5910 emit_insn_before (gen_rtx (PARALLEL, VOIDmode,
5911 gen_rtvec (2, PATTERN (anchor),
5912 PATTERN (floater))),
5913 anchor);
5914 PUT_CODE (anchor, NOTE);
5915 NOTE_LINE_NUMBER (anchor) = NOTE_INSN_DELETED;
5916 NOTE_SOURCE_FILE (anchor) = 0;
5917
5918 /* Emit a special USE insn for FLOATER, then delete
5919 the floating insn. */
5920 emit_insn_before (gen_rtx (USE, VOIDmode, floater), floater);
5921 delete_insn (floater);
5922
5923 continue;
5924 }
5925 else if (floater
5926 && anchor_attr == PA_COMBINE_TYPE_UNCOND_BRANCH)
5927 {
5928 rtx temp;
5929 /* Emit the new_jump instruction and delete the old anchor. */
5930 temp = emit_jump_insn_before (gen_rtx (PARALLEL, VOIDmode,
5931 gen_rtvec (2, PATTERN (anchor),
5932 PATTERN (floater))),
5933 anchor);
5934 JUMP_LABEL (temp) = JUMP_LABEL (anchor);
5935 PUT_CODE (anchor, NOTE);
5936 NOTE_LINE_NUMBER (anchor) = NOTE_INSN_DELETED;
5937 NOTE_SOURCE_FILE (anchor) = 0;
5938
5939 /* Emit a special USE insn for FLOATER, then delete
5940 the floating insn. */
5941 emit_insn_before (gen_rtx (USE, VOIDmode, floater), floater);
5942 delete_insn (floater);
5943 continue;
5944 }
5945 }
5946 }
5947}
5948
5949int
5950pa_can_combine_p (new, anchor, floater, reversed, dest, src1, src2)
5951 rtx new, anchor, floater;
5952 int reversed;
5953 rtx dest, src1, src2;
5954{
5955 int insn_code_number;
5956 rtx start, end;
5957
5958 /* Create a PARALLEL with the patterns of ANCHOR and
5959 FLOATER, try to recognize it, then test constraints
5960 for the resulting pattern.
5961
5962 If the pattern doesn't match or the constraints
5963 aren't met keep searching for a suitable floater
5964 insn. */
5965 XVECEXP (PATTERN (new), 0, 0) = PATTERN (anchor);
5966 XVECEXP (PATTERN (new), 0, 1) = PATTERN (floater);
5967 INSN_CODE (new) = -1;
5968 insn_code_number = recog_memoized (new);
5969 if (insn_code_number < 0
5970 || !constrain_operands (insn_code_number, 1))
5971 return 0;
5972
5973 if (reversed)
5974 {
5975 start = anchor;
5976 end = floater;
5977 }
5978 else
5979 {
5980 start = floater;
5981 end = anchor;
5982 }
5983
5984 /* There's up to three operands to consider. One
5985 output and two inputs.
5986
5987 The output must not be used between FLOATER & ANCHOR
5988 exclusive. The inputs must not be set between
5989 FLOATER and ANCHOR exclusive. */
5990
5991 if (reg_used_between_p (dest, start, end))
5992 return 0;
5993
5994 if (reg_set_between_p (src1, start, end))
5995 return 0;
5996
5997 if (reg_set_between_p (src2, start, end))
5998 return 0;
5999
6000 /* If we get here, then everything is good. */
6001 return 1;
6002}