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