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