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