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