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