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