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