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