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