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