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