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