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