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