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