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