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