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