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