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