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