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