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