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