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