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