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