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