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