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