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