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