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