]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/pa/pa.c
(DO_GLOBAL_CTORS_BODY): Run constructors from right to
[thirdparty/gcc.git] / gcc / config / pa / pa.c
CommitLineData
87ad11b0 1/* Subroutines for insn-output.c for HPPA.
6c640a06 2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
87ad11b0 3 Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#include <stdio.h>
22#include "config.h"
23#include "rtl.h"
24#include "regs.h"
25#include "hard-reg-set.h"
26#include "real.h"
27#include "insn-config.h"
28#include "conditions.h"
29#include "insn-flags.h"
30#include "output.h"
31#include "insn-attr.h"
32#include "flags.h"
33#include "tree.h"
34#include "c-tree.h"
35#include "expr.h"
d6f01525 36#include "obstack.h"
87ad11b0 37
38/* Save the operands last given to a compare for use when we
39 generate a scc or bcc insn. */
40
41rtx hppa_compare_op0, hppa_compare_op1;
42enum cmp_type hppa_branch_type;
43
eff812f1 44rtx hppa_save_pic_table_rtx;
45
87ad11b0 46/* Set by the FUNCTION_PROFILER macro. */
47int hp_profile_labelno;
48
a9960cdc 49/* Counts for the number of callee-saved general and floating point
50 registers which were saved by the current function's prologue. */
51static int gr_saved, fr_saved;
52
87ad11b0 53static rtx find_addr_reg ();
54
06ddb6f8 55/* Keep track of the number of bytes we have output in the CODE subspaces
56 during this compilation so we'll know when to emit inline long-calls. */
57
58unsigned int total_code_bytes;
59
87ad11b0 60/* Return non-zero only if OP is a register of mode MODE,
891b55b4 61 or CONST0_RTX. */
87ad11b0 62int
63reg_or_0_operand (op, mode)
64 rtx op;
65 enum machine_mode mode;
66{
891b55b4 67 return (op == CONST0_RTX (mode) || register_operand (op, mode));
87ad11b0 68}
69
575e0eb4 70/* Return non-zero if OP is suitable for use in a call to a named
71 function.
72
6d36483b 73 (???) For 2.5 try to eliminate either call_operand_address or
575e0eb4 74 function_label_operand, they perform very similar functions. */
87ad11b0 75int
76call_operand_address (op, mode)
77 rtx op;
78 enum machine_mode mode;
79{
06ddb6f8 80 return (CONSTANT_P (op) && ! TARGET_PORTABLE_RUNTIME);
87ad11b0 81}
82
6d36483b 83/* Return 1 if X contains a symbolic expression. We know these
84 expressions will have one of a few well defined forms, so
347b5848 85 we need only check those forms. */
86int
87symbolic_expression_p (x)
88 register rtx x;
89{
90
6d36483b 91 /* Strip off any HIGH. */
347b5848 92 if (GET_CODE (x) == HIGH)
93 x = XEXP (x, 0);
94
95 return (symbolic_operand (x, VOIDmode));
96}
97
87ad11b0 98int
99symbolic_operand (op, mode)
100 register rtx op;
101 enum machine_mode mode;
102{
103 switch (GET_CODE (op))
104 {
105 case SYMBOL_REF:
106 case LABEL_REF:
107 return 1;
108 case CONST:
109 op = XEXP (op, 0);
110 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
111 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
112 && GET_CODE (XEXP (op, 1)) == CONST_INT);
113 default:
114 return 0;
115 }
116}
117
118/* Return truth value of statement that OP is a symbolic memory
119 operand of mode MODE. */
120
121int
122symbolic_memory_operand (op, mode)
123 rtx op;
124 enum machine_mode mode;
125{
126 if (GET_CODE (op) == SUBREG)
127 op = SUBREG_REG (op);
128 if (GET_CODE (op) != MEM)
129 return 0;
130 op = XEXP (op, 0);
131 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
132 || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
133}
134
135/* Return 1 if the operand is either a register or a memory operand that is
136 not symbolic. */
137
138int
139reg_or_nonsymb_mem_operand (op, mode)
140 register rtx op;
141 enum machine_mode mode;
142{
143 if (register_operand (op, mode))
144 return 1;
145
146 if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
147 return 1;
148
149 return 0;
150}
151
6d36483b 152/* Return 1 if the operand is either a register, zero, or a memory operand
891b55b4 153 that is not symbolic. */
154
155int
156reg_or_0_or_nonsymb_mem_operand (op, mode)
157 register rtx op;
158 enum machine_mode mode;
159{
160 if (register_operand (op, mode))
161 return 1;
162
163 if (op == CONST0_RTX (mode))
164 return 1;
165
166 if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
167 return 1;
168
169 return 0;
170}
171
6d36483b 172/* Accept any constant that can be moved in one instructions into a
d9d7c968 173 general register. */
6d36483b 174int
d9d7c968 175cint_ok_for_move (intval)
6d36483b 176 HOST_WIDE_INT intval;
d9d7c968 177{
178 /* OK if ldo, ldil, or zdepi, can be used. */
179 return (VAL_14_BITS_P (intval) || (intval & 0x7ff) == 0
180 || zdepi_cint_p (intval));
181}
182
6ecdbaa1 183/* Accept anything that can be moved in one instruction into a general
184 register. */
87ad11b0 185int
186move_operand (op, mode)
187 rtx op;
188 enum machine_mode mode;
189{
190 if (register_operand (op, mode))
191 return 1;
192
42faba01 193 if (GET_CODE (op) == CONST_INT)
d9d7c968 194 return cint_ok_for_move (INTVAL (op));
87ad11b0 195
196 if (GET_MODE (op) != mode)
197 return 0;
198 if (GET_CODE (op) == SUBREG)
199 op = SUBREG_REG (op);
200 if (GET_CODE (op) != MEM)
201 return 0;
202
203 op = XEXP (op, 0);
204 if (GET_CODE (op) == LO_SUM)
205 return (register_operand (XEXP (op, 0), Pmode)
206 && CONSTANT_P (XEXP (op, 1)));
207 return memory_address_p (mode, op);
208}
209
6ecdbaa1 210/* Accept REG and any CONST_INT that can be moved in one instruction into a
211 general register. */
212int
213reg_or_cint_move_operand (op, mode)
214 rtx op;
215 enum machine_mode mode;
216{
217 if (register_operand (op, mode))
218 return 1;
219
220 if (GET_CODE (op) == CONST_INT)
686b848d 221 return cint_ok_for_move (INTVAL (op));
222
6ecdbaa1 223 return 0;
224}
225
87ad11b0 226int
b4a7bf10 227pic_label_operand (op, mode)
87ad11b0 228 rtx op;
229 enum machine_mode mode;
230{
b4a7bf10 231 if (!flag_pic)
232 return 0;
233
234 switch (GET_CODE (op))
235 {
236 case LABEL_REF:
237 return 1;
b4a7bf10 238 case CONST:
239 op = XEXP (op, 0);
3c69dc97 240 return (GET_CODE (XEXP (op, 0)) == LABEL_REF
b4a7bf10 241 && GET_CODE (XEXP (op, 1)) == CONST_INT);
242 default:
243 return 0;
244 }
87ad11b0 245}
246
87ad11b0 247int
248fp_reg_operand (op, mode)
249 rtx op;
250 enum machine_mode mode;
251{
252 return reg_renumber && FP_REG_P (op);
253}
d6f01525 254
87ad11b0 255\f
87ad11b0 256
87ad11b0 257/* Return truth value of whether OP can be used as an operand in a
258 three operand arithmetic insn that accepts registers of mode MODE
259 or 14-bit signed integers. */
260int
261arith_operand (op, mode)
262 rtx op;
263 enum machine_mode mode;
264{
265 return (register_operand (op, mode)
266 || (GET_CODE (op) == CONST_INT && INT_14_BITS (op)));
267}
268
269/* Return truth value of whether OP can be used as an operand in a
270 three operand arithmetic insn that accepts registers of mode MODE
271 or 11-bit signed integers. */
272int
273arith11_operand (op, mode)
274 rtx op;
275 enum machine_mode mode;
276{
277 return (register_operand (op, mode)
278 || (GET_CODE (op) == CONST_INT && INT_11_BITS (op)));
279}
280
6d36483b 281/* A constant integer suitable for use in a PRE_MODIFY memory
757d4970 282 reference. */
42faba01 283int
284pre_cint_operand (op, mode)
285 rtx op;
286 enum machine_mode mode;
287{
288 return (GET_CODE (op) == CONST_INT
289 && INTVAL (op) >= -0x2000 && INTVAL (op) < 0x10);
290}
291
6d36483b 292/* A constant integer suitable for use in a POST_MODIFY memory
757d4970 293 reference. */
294int
295post_cint_operand (op, mode)
296 rtx op;
297 enum machine_mode mode;
298{
299 return (GET_CODE (op) == CONST_INT
300 && INTVAL (op) < 0x2000 && INTVAL (op) >= -0x10);
301}
302
87ad11b0 303int
304arith_double_operand (op, mode)
305 rtx op;
306 enum machine_mode mode;
307{
308 return (register_operand (op, mode)
309 || (GET_CODE (op) == CONST_DOUBLE
310 && GET_MODE (op) == mode
311 && VAL_14_BITS_P (CONST_DOUBLE_LOW (op))
312 && (CONST_DOUBLE_HIGH (op) >= 0
313 == ((CONST_DOUBLE_LOW (op) & 0x1000) == 0))));
314}
315
316/* Return truth value of whether OP is a integer which fits the
317 range constraining immediate operands in three-address insns. */
318
319int
320int5_operand (op, mode)
321 rtx op;
322 enum machine_mode mode;
323{
324 return (GET_CODE (op) == CONST_INT && INT_5_BITS (op));
325}
326
327int
328uint5_operand (op, mode)
329 rtx op;
330 enum machine_mode mode;
331{
332 return (GET_CODE (op) == CONST_INT && INT_U5_BITS (op));
333}
334
87ad11b0 335int
336int11_operand (op, mode)
337 rtx op;
338 enum machine_mode mode;
339{
6d36483b 340 return (GET_CODE (op) == CONST_INT && INT_11_BITS (op));
341}
342
343int
344uint32_operand (op, mode)
345 rtx op;
346 enum machine_mode mode;
347{
348#if HOST_BITS_PER_WIDE_INT > 32
349 /* All allowed constants will fit a CONST_INT. */
350 return (GET_CODE (op) == CONST_INT
351 && (INTVAL (op) >= 0 && INTVAL (op) < 0x100000000L));
352#else
353 return (GET_CODE (op) == CONST_INT
354 || (GET_CODE (op) == CONST_DOUBLE
355 && CONST_DOUBLE_HIGH (op) == 0));
356#endif
87ad11b0 357}
358
359int
360arith5_operand (op, mode)
361 rtx op;
362 enum machine_mode mode;
363{
364 return register_operand (op, mode) || int5_operand (op, mode);
365}
366
fad0b60f 367/* True iff zdepi can be used to generate this CONST_INT. */
e057641f 368int
42faba01 369zdepi_cint_p (x)
6d36483b 370 unsigned HOST_WIDE_INT x;
fad0b60f 371{
42faba01 372 unsigned lsb_mask, t;
fad0b60f 373
374 /* This might not be obvious, but it's at least fast.
375 This function is critcal; we don't have the time loops would take. */
42faba01 376 lsb_mask = x & -x;
377 t = ((x >> 4) + lsb_mask) & ~(lsb_mask - 1);
378 /* Return true iff t is a power of two. */
fad0b60f 379 return ((t & (t - 1)) == 0);
380}
381
6d36483b 382/* True iff depi or extru can be used to compute (reg & mask).
383 Accept bit pattern like these:
384 0....01....1
385 1....10....0
386 1..10..01..1 */
e057641f 387int
42faba01 388and_mask_p (mask)
6d36483b 389 unsigned HOST_WIDE_INT mask;
e057641f 390{
391 mask = ~mask;
392 mask += mask & -mask;
393 return (mask & (mask - 1)) == 0;
394}
395
396/* True iff depi or extru can be used to compute (reg & OP). */
397int
398and_operand (op, mode)
399 rtx op;
400 enum machine_mode mode;
401{
402 return (register_operand (op, mode)
42faba01 403 || (GET_CODE (op) == CONST_INT && and_mask_p (INTVAL (op))));
e057641f 404}
405
406/* True iff depi can be used to compute (reg | MASK). */
407int
408ior_mask_p (mask)
6d36483b 409 unsigned HOST_WIDE_INT mask;
e057641f 410{
411 mask += mask & -mask;
412 return (mask & (mask - 1)) == 0;
413}
414
415/* True iff depi can be used to compute (reg | OP). */
416int
417ior_operand (op, mode)
418 rtx op;
419 enum machine_mode mode;
420{
b744c8cb 421 return (GET_CODE (op) == CONST_INT && ior_mask_p (INTVAL (op)));
e057641f 422}
423
e5965947 424int
425lhs_lshift_operand (op, mode)
426 rtx op;
427 enum machine_mode mode;
428{
429 return register_operand (op, mode) || lhs_lshift_cint_operand (op, mode);
430}
431
432/* True iff OP is a CONST_INT of the forms 0...0xxxx or 0...01...1xxxx.
433 Such values can be the left hand side x in (x << r), using the zvdepi
434 instruction. */
435int
436lhs_lshift_cint_operand (op, mode)
437 rtx op;
438 enum machine_mode mode;
439{
440 unsigned x;
441 if (GET_CODE (op) != CONST_INT)
442 return 0;
443 x = INTVAL (op) >> 4;
444 return (x & (x + 1)) == 0;
445}
446
9c6d4825 447int
448arith32_operand (op, mode)
449 rtx op;
450 enum machine_mode mode;
451{
452 return register_operand (op, mode) || GET_CODE (op) == CONST_INT;
453}
ead9285f 454
455int
456pc_or_label_operand (op, mode)
457 rtx op;
458 enum machine_mode mode;
459{
460 return (GET_CODE (op) == PC || GET_CODE (op) == LABEL_REF);
461}
87ad11b0 462\f
463/* Legitimize PIC addresses. If the address is already
464 position-independent, we return ORIG. Newly generated
465 position-independent addresses go to REG. If we need more
466 than one register, we lose. */
467
468rtx
469legitimize_pic_address (orig, mode, reg)
470 rtx orig, reg;
471 enum machine_mode mode;
472{
473 rtx pic_ref = orig;
474
3c69dc97 475 /* Lables need special handling. */
b4a7bf10 476 if (pic_label_operand (orig))
477 {
478 emit_insn (gen_pic_load_label (reg, orig));
479 current_function_uses_pic_offset_table = 1;
480 return reg;
481 }
87ad11b0 482 if (GET_CODE (orig) == SYMBOL_REF)
483 {
484 if (reg == 0)
485 abort ();
486
487 if (flag_pic == 2)
488 {
e8df7698 489 emit_insn (gen_pic2_highpart (reg, pic_offset_table_rtx, orig));
490 pic_ref = gen_rtx (MEM, Pmode,
491 gen_rtx (LO_SUM, Pmode, reg,
492 gen_rtx (UNSPEC, SImode, gen_rtvec (1, orig), 0)));
87ad11b0 493 }
b4a7bf10 494 else
495 pic_ref = gen_rtx (MEM, Pmode,
496 gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig));
87ad11b0 497 current_function_uses_pic_offset_table = 1;
498 RTX_UNCHANGING_P (pic_ref) = 1;
499 emit_move_insn (reg, pic_ref);
500 return reg;
501 }
502 else if (GET_CODE (orig) == CONST)
503 {
57ed30e5 504 rtx base;
87ad11b0 505
506 if (GET_CODE (XEXP (orig, 0)) == PLUS
507 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
508 return orig;
509
510 if (reg == 0)
511 abort ();
512
513 if (GET_CODE (XEXP (orig, 0)) == PLUS)
514 {
515 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
516 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
517 base == reg ? 0 : reg);
518 }
519 else abort ();
520 if (GET_CODE (orig) == CONST_INT)
521 {
42faba01 522 if (INT_14_BITS (orig))
87ad11b0 523 return plus_constant_for_output (base, INTVAL (orig));
524 orig = force_reg (Pmode, orig);
525 }
526 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
527 /* Likewise, should we set special REG_NOTEs here? */
528 }
529 return pic_ref;
530}
531
347b5848 532/* Try machine-dependent ways of modifying an illegitimate address
533 to be legitimate. If we find one, return the new, valid address.
534 This macro is used in only one place: `memory_address' in explow.c.
535
536 OLDX is the address as it was before break_out_memory_refs was called.
537 In some cases it is useful to look at this to decide what needs to be done.
538
539 MODE and WIN are passed so that this macro can use
540 GO_IF_LEGITIMATE_ADDRESS.
541
542 It is always safe for this macro to do nothing. It exists to recognize
6d36483b 543 opportunities to optimize the output.
347b5848 544
545 For the PA, transform:
546
547 memory(X + <large int>)
548
549 into:
550
551 if (<large int> & mask) >= 16
552 Y = (<large int> & ~mask) + mask + 1 Round up.
553 else
554 Y = (<large int> & ~mask) Round down.
555 Z = X + Y
556 memory (Z + (<large int> - Y));
557
6d36483b 558 This is for CSE to find several similar references, and only use one Z.
347b5848 559
560 X can either be a SYMBOL_REF or REG, but because combine can not
561 perform a 4->2 combination we do nothing for SYMBOL_REF + D where
562 D will not fit in 14 bits.
563
564 MODE_FLOAT references allow displacements which fit in 5 bits, so use
6d36483b 565 0x1f as the mask.
347b5848 566
567 MODE_INT references allow displacements which fit in 14 bits, so use
6d36483b 568 0x3fff as the mask.
347b5848 569
570 This relies on the fact that most mode MODE_FLOAT references will use FP
571 registers and most mode MODE_INT references will use integer registers.
572 (In the rare case of an FP register used in an integer MODE, we depend
573 on secondary reloads to clean things up.)
574
575
576 It is also beneficial to handle (plus (mult (X) (Y)) (Z)) in a special
577 manner if Y is 2, 4, or 8. (allows more shadd insns and shifted indexed
578 adressing modes to be used).
579
580 Put X and Z into registers. Then put the entire expression into
581 a register. */
582
583rtx
584hppa_legitimize_address (x, oldx, mode)
585 rtx x, oldx;
586 enum machine_mode mode;
587{
347b5848 588 rtx orig = x;
589
b4a7bf10 590 if (flag_pic)
591 return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
592
347b5848 593 /* Strip off CONST. */
594 if (GET_CODE (x) == CONST)
595 x = XEXP (x, 0);
596
166bf021 597 /* Note we must reject symbols which represent function addresses
598 since the assembler/linker can't handle arithmetic on plabels. */
347b5848 599 if (GET_CODE (x) == PLUS
600 && GET_CODE (XEXP (x, 1)) == CONST_INT
166bf021 601 && ((GET_CODE (XEXP (x, 0)) == SYMBOL_REF
602 && !FUNCTION_NAME_P (XSTR (XEXP (x, 0), 0)))
347b5848 603 || GET_CODE (XEXP (x, 0)) == REG))
604 {
605 rtx int_part, ptr_reg;
606 int newoffset;
607 int offset = INTVAL (XEXP (x, 1));
608 int mask = GET_MODE_CLASS (mode) == MODE_FLOAT ? 0x1f : 0x3fff;
609
6d36483b 610 /* Choose which way to round the offset. Round up if we
347b5848 611 are >= halfway to the next boundary. */
612 if ((offset & mask) >= ((mask + 1) / 2))
613 newoffset = (offset & ~ mask) + mask + 1;
614 else
615 newoffset = (offset & ~ mask);
616
617 /* If the newoffset will not fit in 14 bits (ldo), then
618 handling this would take 4 or 5 instructions (2 to load
619 the SYMBOL_REF + 1 or 2 to load the newoffset + 1 to
620 add the new offset and the SYMBOL_REF.) Combine can
621 not handle 4->2 or 5->2 combinations, so do not create
622 them. */
623 if (! VAL_14_BITS_P (newoffset)
624 && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
625 {
626 rtx const_part = gen_rtx (CONST, VOIDmode,
339613b4 627 gen_rtx (PLUS, Pmode,
347b5848 628 XEXP (x, 0),
629 GEN_INT (newoffset)));
630 rtx tmp_reg
339613b4 631 = force_reg (Pmode,
632 gen_rtx (HIGH, Pmode, const_part));
347b5848 633 ptr_reg
339613b4 634 = force_reg (Pmode,
635 gen_rtx (LO_SUM, Pmode,
347b5848 636 tmp_reg, const_part));
637 }
638 else
639 {
640 if (! VAL_14_BITS_P (newoffset))
339613b4 641 int_part = force_reg (Pmode, GEN_INT (newoffset));
347b5848 642 else
643 int_part = GEN_INT (newoffset);
644
339613b4 645 ptr_reg = force_reg (Pmode,
646 gen_rtx (PLUS, Pmode,
647 force_reg (Pmode, XEXP (x, 0)),
347b5848 648 int_part));
649 }
650 return plus_constant (ptr_reg, offset - newoffset);
651 }
45f1285a 652
653 /* Try to arrange things so that indexing modes can be used, but
6d36483b 654 only do so if indexing is safe.
45f1285a 655
656 Indexing is safe when the second operand for the outer PLUS
6d36483b 657 is a REG, SUBREG, SYMBOL_REF or the like.
45f1285a 658
6d36483b 659 For 2.5, indexing is also safe for (plus (symbol_ref) (const_int))
45f1285a 660 if the integer is > 0. */
347b5848 661 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
662 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
45f1285a 663 && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))
664 && (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == 'o'
665 || GET_CODE (XEXP (x, 1)) == SUBREG)
666 && GET_CODE (XEXP (x, 1)) != CONST)
347b5848 667 {
668 int val = INTVAL (XEXP (XEXP (x, 0), 1));
669 rtx reg1, reg2;
339613b4 670 reg1 = force_reg (Pmode, force_operand (XEXP (x, 1), 0));
671 reg2 = force_reg (Pmode,
347b5848 672 force_operand (XEXP (XEXP (x, 0), 0), 0));
339613b4 673 return force_reg (Pmode,
674 gen_rtx (PLUS, Pmode,
675 gen_rtx (MULT, Pmode, reg2,
347b5848 676 GEN_INT (val)),
677 reg1));
678 }
45f1285a 679
6d36483b 680 /* Uh-oh. We might have an address for x[n-100000]. This needs
45f1285a 681 special handling. */
682
683 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
684 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
685 && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
686 {
687 /* Ugly. We modify things here so that the address offset specified
688 by the index expression is computed first, then added to x to form
689 the entire address.
690
691 For 2.5, it might be profitable to set things up so that we
692 compute the raw (unscaled) index first, then use scaled indexing
693 to access memory, or better yet have the MI parts of the compiler
694 handle this. */
695
696 rtx regx1, regy1, regy2, y;
697
698 /* Strip off any CONST. */
699 y = XEXP (x, 1);
700 if (GET_CODE (y) == CONST)
701 y = XEXP (y, 0);
702
7ee96d6e 703 if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)
704 {
705 regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
706 regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
707 regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
708 regx1 = force_reg (Pmode, gen_rtx (GET_CODE (y), Pmode, regx1, regy2));
709 return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1));
710 }
45f1285a 711 }
712
347b5848 713 return orig;
714}
715
87ad11b0 716/* For the HPPA, REG and REG+CONST is cost 0
717 and addresses involving symbolic constants are cost 2.
718
719 PIC addresses are very expensive.
720
721 It is no coincidence that this has the same structure
722 as GO_IF_LEGITIMATE_ADDRESS. */
723int
724hppa_address_cost (X)
725 rtx X;
726{
727 if (GET_CODE (X) == PLUS)
728 return 1;
729 else if (GET_CODE (X) == LO_SUM)
730 return 1;
731 else if (GET_CODE (X) == HIGH)
732 return 2;
733 return 4;
734}
735
736/* Emit insns to move operands[1] into operands[0].
737
738 Return 1 if we have written out everything that needs to be done to
739 do the move. Otherwise, return 0 and the caller will emit the move
740 normally. */
741
742int
d6f01525 743emit_move_sequence (operands, mode, scratch_reg)
87ad11b0 744 rtx *operands;
745 enum machine_mode mode;
d6f01525 746 rtx scratch_reg;
87ad11b0 747{
748 register rtx operand0 = operands[0];
749 register rtx operand1 = operands[1];
750
e8fdbafa 751 /* Handle secondary reloads for loads/stores of FP registers from
6b1c36c2 752 REG+D addresses where D does not fit in 5 bits, including
753 (subreg (mem (addr)) cases. */
d6f01525 754 if (fp_reg_operand (operand0, mode)
6b1c36c2 755 && ((GET_CODE (operand1) == MEM
756 && ! memory_address_p (DFmode, XEXP (operand1, 0)))
757 || ((GET_CODE (operand1) == SUBREG
758 && GET_CODE (XEXP (operand1, 0)) == MEM
759 && !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0)))))
d6f01525 760 && scratch_reg)
761 {
6b1c36c2 762 if (GET_CODE (operand1) == SUBREG)
763 operand1 = XEXP (operand1, 0);
764
765 scratch_reg = gen_rtx (REG, SImode, REGNO (scratch_reg));
6d36483b 766 emit_move_insn (scratch_reg, XEXP (operand1, 0));
d6f01525 767 emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MEM, mode,
768 scratch_reg)));
769 return 1;
770 }
771 else if (fp_reg_operand (operand1, mode)
6b1c36c2 772 && ((GET_CODE (operand0) == MEM
773 && ! memory_address_p (DFmode, XEXP (operand0, 0)))
774 || ((GET_CODE (operand0) == SUBREG)
775 && GET_CODE (XEXP (operand0, 0)) == MEM
776 && !memory_address_p (DFmode, XEXP (XEXP (operand0, 0), 0))))
d6f01525 777 && scratch_reg)
778 {
6b1c36c2 779 if (GET_CODE (operand0) == SUBREG)
780 operand0 = XEXP (operand0, 0);
781
782 scratch_reg = gen_rtx (REG, SImode, REGNO (scratch_reg));
6d36483b 783 emit_move_insn (scratch_reg, XEXP (operand0, 0));
784 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, mode, scratch_reg),
d6f01525 785 operand1));
786 return 1;
787 }
753bd06a 788 /* Handle secondary reloads for loads of FP registers from constant
789 expressions by forcing the constant into memory.
790
6d36483b 791 use scratch_reg to hold the address of the memory location.
753bd06a 792
6d36483b 793 ??? The proper fix is to change PREFERRED_RELOAD_CLASS to return
794 NO_REGS when presented with a const_int and an register class
753bd06a 795 containing only FP registers. Doing so unfortunately creates
796 more problems than it solves. Fix this for 2.5. */
797 else if (fp_reg_operand (operand0, mode)
798 && CONSTANT_P (operand1)
799 && scratch_reg)
800 {
801 rtx xoperands[2];
802
803 /* Force the constant into memory and put the address of the
804 memory location into scratch_reg. */
805 xoperands[0] = scratch_reg;
806 xoperands[1] = XEXP (force_const_mem (mode, operand1), 0);
8f258b49 807 emit_move_sequence (xoperands, Pmode, 0);
753bd06a 808
809 /* Now load the destination register. */
810 emit_insn (gen_rtx (SET, mode, operand0,
811 gen_rtx (MEM, mode, scratch_reg)));
812 return 1;
813 }
e8fdbafa 814 /* Handle secondary reloads for SAR. These occur when trying to load
7d43e0f7 815 the SAR from memory a FP register, or with a constant. */
e8fdbafa 816 else if (GET_CODE (operand0) == REG
817 && REGNO_REG_CLASS (REGNO (operand0)) == SHIFT_REGS
818 && (GET_CODE (operand1) == MEM
7d43e0f7 819 || GET_CODE (operand1) == CONST_INT
e8fdbafa 820 || (GET_CODE (operand1) == REG
821 && FP_REG_CLASS_P (REGNO_REG_CLASS (REGNO (operand1)))))
822 && scratch_reg)
823 {
824 emit_move_insn (scratch_reg, operand1);
825 emit_move_insn (operand0, scratch_reg);
826 return 1;
827 }
d6f01525 828 /* Handle most common case: storing into a register. */
829 else if (register_operand (operand0, mode))
87ad11b0 830 {
831 if (register_operand (operand1, mode)
42faba01 832 || (GET_CODE (operand1) == CONST_INT && INT_14_BITS (operand1))
891b55b4 833 || (operand1 == CONST0_RTX (mode))
87ad11b0 834 || (GET_CODE (operand1) == HIGH
df0651dc 835 && !symbolic_operand (XEXP (operand1, 0), VOIDmode))
87ad11b0 836 /* Only `general_operands' can come here, so MEM is ok. */
837 || GET_CODE (operand1) == MEM)
838 {
839 /* Run this case quickly. */
840 emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
841 return 1;
842 }
843 }
844 else if (GET_CODE (operand0) == MEM)
845 {
891b55b4 846 if (register_operand (operand1, mode) || operand1 == CONST0_RTX (mode))
87ad11b0 847 {
848 /* Run this case quickly. */
849 emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
850 return 1;
851 }
2ff4bf8d 852 if (! (reload_in_progress || reload_completed))
87ad11b0 853 {
854 operands[0] = validize_mem (operand0);
855 operands[1] = operand1 = force_reg (mode, operand1);
856 }
857 }
858
859 /* Simplify the source if we need to. */
57ed30e5 860 if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
2ee034bc 861 || (GET_CODE (operand1) == HIGH
63882853 862 && symbolic_operand (XEXP (operand1, 0), mode)))
87ad11b0 863 {
2ee034bc 864 int ishighonly = 0;
865
866 if (GET_CODE (operand1) == HIGH)
867 {
868 ishighonly = 1;
869 operand1 = XEXP (operand1, 0);
870 }
87ad11b0 871 if (symbolic_operand (operand1, mode))
872 {
873 if (flag_pic)
874 {
2ff4bf8d 875 rtx temp;
876
877 if (reload_in_progress || reload_completed)
b4a7bf10 878 temp = scratch_reg ? scratch_reg : operand0;
2ff4bf8d 879 else
880 temp = gen_reg_rtx (Pmode);
6d36483b 881
87ad11b0 882 operands[1] = legitimize_pic_address (operand1, mode, temp);
b4a7bf10 883 emit_insn (gen_rtx (SET, VOIDmode, operand0, operands[1]));
87ad11b0 884 }
b4a7bf10 885 /* On the HPPA, references to data space are supposed to use dp,
886 register 27, but showing it in the RTL inhibits various cse
887 and loop optimizations. */
6d36483b 888 else
87ad11b0 889 {
166bf021 890 rtx temp, set, const_part = NULL;
2ee034bc 891
6d36483b 892 if (reload_in_progress || reload_completed)
2ee034bc 893 temp = scratch_reg ? scratch_reg : operand0;
894 else
895 temp = gen_reg_rtx (mode);
896
166bf021 897 /* Argh. The assembler and linker can't handle arithmetic
898 involving plabels. We'll have to split up operand1 here
899 if it's a function label involved in an arithmetic
900 expression. Luckily, this only happens with addition
901 of constants to plabels, which simplifies the test. */
902 if (GET_CODE (operand1) == CONST
903 && GET_CODE (XEXP (operand1, 0)) == PLUS
904 && function_label_operand (XEXP (XEXP (operand1, 0), 0),
905 Pmode))
906 {
907 /* Save away the constant part of the expression. */
908 const_part = XEXP (XEXP (operand1, 0), 1);
909 if (GET_CODE (const_part) != CONST_INT)
910 abort ();
911
912 /* Set operand1 to just the SYMBOL_REF. */
913 operand1 = XEXP (XEXP (operand1, 0), 0);
914 }
915
2ee034bc 916 if (ishighonly)
917 set = gen_rtx (SET, mode, operand0, temp);
918 else
919 set = gen_rtx (SET, VOIDmode,
920 operand0,
921 gen_rtx (LO_SUM, mode, temp, operand1));
6d36483b 922
87ad11b0 923 emit_insn (gen_rtx (SET, VOIDmode,
2ee034bc 924 temp,
d6f01525 925 gen_rtx (HIGH, mode, operand1)));
d2498717 926 emit_insn (set);
166bf021 927
928 /* Add back in the constant part if needed. */
929 if (const_part != NULL)
930 emit_insn (gen_rtx (SET, mode, operand0,
931 plus_constant (operand0,
932 XEXP (const_part, 0))));
87ad11b0 933 return 1;
934 }
2ee034bc 935 return 1;
87ad11b0 936 }
42faba01 937 else if (GET_CODE (operand1) != CONST_INT
8c8ec4de 938 || ! cint_ok_for_move (INTVAL (operand1)))
87ad11b0 939 {
2ff4bf8d 940 rtx temp;
941
942 if (reload_in_progress || reload_completed)
943 temp = operand0;
944 else
945 temp = gen_reg_rtx (mode);
946
87ad11b0 947 emit_insn (gen_rtx (SET, VOIDmode, temp,
948 gen_rtx (HIGH, mode, operand1)));
949 operands[1] = gen_rtx (LO_SUM, mode, temp, operand1);
950 }
951 }
952 /* Now have insn-emit do whatever it normally does. */
953 return 0;
954}
955
956/* Does operand (which is a symbolic_operand) live in text space? If
201f01e9 957 so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true. */
87ad11b0 958
959int
960read_only_operand (operand)
961 rtx operand;
962{
963 if (GET_CODE (operand) == CONST)
964 operand = XEXP (XEXP (operand, 0), 0);
b4a7bf10 965 if (flag_pic)
966 {
967 if (GET_CODE (operand) == SYMBOL_REF)
968 return SYMBOL_REF_FLAG (operand) && !CONSTANT_POOL_ADDRESS_P (operand);
969 }
970 else
971 {
972 if (GET_CODE (operand) == SYMBOL_REF)
973 return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand);
974 }
87ad11b0 975 return 1;
976}
6d36483b 977
87ad11b0 978\f
979/* Return the best assembler insn template
f54b1341 980 for moving operands[1] into operands[0] as a fullword. */
5c683f13 981char *
87ad11b0 982singlemove_string (operands)
983 rtx *operands;
984{
985 if (GET_CODE (operands[0]) == MEM)
986 return "stw %r1,%0";
9d5108ea 987 else if (GET_CODE (operands[1]) == MEM)
87ad11b0 988 return "ldw %1,%0";
9d5108ea 989 else if (GET_CODE (operands[1]) == CONST_DOUBLE
990 && GET_MODE (operands[1]) == SFmode)
991 {
992 int i;
993 union real_extract u;
994 union float_extract { float f; int i; } v;
995
996 bcopy (&CONST_DOUBLE_LOW (operands[1]), &u, sizeof u);
997 v.f = REAL_VALUE_TRUNCATE (SFmode, u.d);
998 i = v.i;
999
1000 operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
1001
f54b1341 1002 /* See if we can handle this constant in a single instruction. */
1003 if (cint_ok_for_move (INTVAL (operands[1])))
1004 {
6d36483b 1005 HOST_WIDE_INT intval = INTVAL (operands[1]);
f54b1341 1006
1007 if (intval == 0)
1008 return "copy 0,%0";
1009 else if (VAL_14_BITS_P (intval))
1010 return "ldi %1,%0";
1011 else if ((intval & 0x7ff) == 0)
1012 return "ldil L'%1,%0";
1013 else if (zdepi_cint_p (intval))
1014 return "zdepi %Z1,%0";
1015 }
9d5108ea 1016 else
1017 return "ldil L'%1,%0\n\tldo R'%1(%0),%0";
1018 }
1019
1020 else if (GET_CODE (operands[1]) == CONST_INT)
1021 {
f54b1341 1022 /* See if we can handle this in a single instruction. */
1023 if (cint_ok_for_move (INTVAL (operands[1])))
1024 {
1025 int intval = INTVAL (operands[1]);
1026
1027 if (intval == 0)
1028 return "copy 0,%0";
1029 else if (VAL_14_BITS_P (intval))
1030 return "ldi %1,%0";
1031 else if ((intval & 0x7ff) == 0)
1032 return "ldil L'%1,%0";
1033 else if (zdepi_cint_p (intval))
1034 return "zdepi %Z1,%0";
1035 }
9d5108ea 1036 else
1037 return "ldil L'%1,%0\n\tldo R'%1(%0),%0";
1038 }
87ad11b0 1039 return "copy %1,%0";
1040}
1041\f
1042
201f01e9 1043/* Compute position (in OP[1]) and width (in OP[2])
1044 useful for copying IMM to a register using the zdepi
1045 instructions. Store the immediate value to insert in OP[0]. */
e057641f 1046void
42faba01 1047compute_zdepi_operands (imm, op)
6d36483b 1048 unsigned HOST_WIDE_INT imm;
42faba01 1049 unsigned *op;
7e10ba53 1050{
e057641f 1051 int lsb, len;
7e10ba53 1052
e057641f 1053 /* Find the least significant set bit in IMM. */
1054 for (lsb = 0; lsb < 32; lsb++)
7e10ba53 1055 {
e057641f 1056 if ((imm & 1) != 0)
7e10ba53 1057 break;
e057641f 1058 imm >>= 1;
7e10ba53 1059 }
1060
e057641f 1061 /* Choose variants based on *sign* of the 5-bit field. */
1062 if ((imm & 0x10) == 0)
1063 len = (lsb <= 28) ? 4 : 32 - lsb;
7e10ba53 1064 else
1065 {
e057641f 1066 /* Find the width of the bitstring in IMM. */
1067 for (len = 5; len < 32; len++)
7e10ba53 1068 {
e057641f 1069 if ((imm & (1 << len)) == 0)
7e10ba53 1070 break;
7e10ba53 1071 }
1072
e057641f 1073 /* Sign extend IMM as a 5-bit value. */
1074 imm = (imm & 0xf) - 0x10;
7e10ba53 1075 }
1076
42faba01 1077 op[0] = imm;
1078 op[1] = 31 - lsb;
1079 op[2] = len;
7e10ba53 1080}
1081
87ad11b0 1082/* Output assembler code to perform a doubleword move insn
1083 with operands OPERANDS. */
1084
1085char *
1086output_move_double (operands)
1087 rtx *operands;
1088{
1089 enum { REGOP, OFFSOP, MEMOP, CNSTOP, RNDOP } optype0, optype1;
1090 rtx latehalf[2];
1091 rtx addreg0 = 0, addreg1 = 0;
1092
1093 /* First classify both operands. */
1094
1095 if (REG_P (operands[0]))
1096 optype0 = REGOP;
1097 else if (offsettable_memref_p (operands[0]))
1098 optype0 = OFFSOP;
1099 else if (GET_CODE (operands[0]) == MEM)
1100 optype0 = MEMOP;
1101 else
1102 optype0 = RNDOP;
1103
1104 if (REG_P (operands[1]))
1105 optype1 = REGOP;
1106 else if (CONSTANT_P (operands[1]))
1107 optype1 = CNSTOP;
1108 else if (offsettable_memref_p (operands[1]))
1109 optype1 = OFFSOP;
1110 else if (GET_CODE (operands[1]) == MEM)
1111 optype1 = MEMOP;
1112 else
1113 optype1 = RNDOP;
1114
1115 /* Check for the cases that the operand constraints are not
1116 supposed to allow to happen. Abort if we get one,
1117 because generating code for these cases is painful. */
1118
1119 if (optype0 != REGOP && optype1 != REGOP)
1120 abort ();
1121
1122 /* Handle auto decrementing and incrementing loads and stores
1123 specifically, since the structure of the function doesn't work
1124 for them without major modification. Do it better when we learn
1125 this port about the general inc/dec addressing of PA.
1126 (This was written by tege. Chide him if it doesn't work.) */
1127
1128 if (optype0 == MEMOP)
1129 {
1df0058a 1130 /* We have to output the address syntax ourselves, since print_operand
1131 doesn't deal with the addresses we want to use. Fix this later. */
1132
87ad11b0 1133 rtx addr = XEXP (operands[0], 0);
1df0058a 1134 if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
87ad11b0 1135 {
1df0058a 1136 rtx high_reg = gen_rtx (SUBREG, SImode, operands[1], 0);
1137
1138 operands[0] = XEXP (addr, 0);
1139 if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
1140 abort ();
1141
1142 if (!reg_overlap_mentioned_p (high_reg, addr))
1143 {
1144 /* No overlap between high target register and address
1145 register. (We do this in a non-obvious way to
1146 save a register file writeback) */
1147 if (GET_CODE (addr) == POST_INC)
1148 return "stws,ma %1,8(0,%0)\n\tstw %R1,-4(0,%0)";
1149 return "stws,ma %1,-8(0,%0)\n\tstw %R1,12(0,%0)";
1150 }
1151 else
1152 abort();
a3217f65 1153 }
1df0058a 1154 else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
a3217f65 1155 {
1df0058a 1156 rtx high_reg = gen_rtx (SUBREG, SImode, operands[1], 0);
1157
1158 operands[0] = XEXP (addr, 0);
1159 if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
1160 abort ();
1161
1162 if (!reg_overlap_mentioned_p (high_reg, addr))
1163 {
1164 /* No overlap between high target register and address
1165 register. (We do this in a non-obvious way to
1166 save a register file writeback) */
1167 if (GET_CODE (addr) == PRE_INC)
1168 return "stws,mb %1,8(0,%0)\n\tstw %R1,4(0,%0)";
1169 return "stws,mb %1,-8(0,%0)\n\tstw %R1,4(0,%0)";
1170 }
1171 else
1172 abort();
87ad11b0 1173 }
1174 }
1175 if (optype1 == MEMOP)
1176 {
1177 /* We have to output the address syntax ourselves, since print_operand
1178 doesn't deal with the addresses we want to use. Fix this later. */
1179
1180 rtx addr = XEXP (operands[1], 0);
1181 if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
1182 {
1183 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], 0);
1184
1185 operands[1] = XEXP (addr, 0);
1186 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
1187 abort ();
1188
1189 if (!reg_overlap_mentioned_p (high_reg, addr))
1190 {
1191 /* No overlap between high target register and address
3857fa62 1192 register. (We do this in a non-obvious way to
87ad11b0 1193 save a register file writeback) */
1194 if (GET_CODE (addr) == POST_INC)
1195 return "ldws,ma 8(0,%1),%0\n\tldw -4(0,%1),%R0";
1196 return "ldws,ma -8(0,%1),%0\n\tldw 12(0,%1),%R0";
1197 }
1198 else
1199 {
1200 /* This is an undefined situation. We should load into the
1201 address register *and* update that register. Probably
1202 we don't need to handle this at all. */
1203 if (GET_CODE (addr) == POST_INC)
1204 return "ldw 4(0,%1),%R0\n\tldws,ma 8(0,%1),%0";
1205 return "ldw 4(0,%1),%R0\n\tldws,ma -8(0,%1),%0";
1206 }
1207 }
1208 else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
1209 {
1210 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], 0);
1211
1212 operands[1] = XEXP (addr, 0);
1213 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
1214 abort ();
1215
1216 if (!reg_overlap_mentioned_p (high_reg, addr))
1217 {
1218 /* No overlap between high target register and address
3857fa62 1219 register. (We do this in a non-obvious way to
87ad11b0 1220 save a register file writeback) */
1221 if (GET_CODE (addr) == PRE_INC)
1222 return "ldws,mb 8(0,%1),%0\n\tldw 4(0,%1),%R0";
1223 return "ldws,mb -8(0,%1),%0\n\tldw 4(0,%1),%R0";
1224 }
1225 else
1226 {
1227 /* This is an undefined situation. We should load into the
1228 address register *and* update that register. Probably
1229 we don't need to handle this at all. */
1230 if (GET_CODE (addr) == PRE_INC)
1231 return "ldw 12(0,%1),%R0\n\tldws,mb 8(0,%1),%0";
1232 return "ldw -4(0,%1),%R0\n\tldws,mb -8(0,%1),%0";
1233 }
1234 }
1235 }
1236
1237 /* If an operand is an unoffsettable memory ref, find a register
1238 we can increment temporarily to make it refer to the second word. */
1239
1240 if (optype0 == MEMOP)
1241 addreg0 = find_addr_reg (XEXP (operands[0], 0));
1242
1243 if (optype1 == MEMOP)
1244 addreg1 = find_addr_reg (XEXP (operands[1], 0));
1245
1246 /* Ok, we can do one word at a time.
1247 Normally we do the low-numbered word first.
1248
1249 In either case, set up in LATEHALF the operands to use
1250 for the high-numbered word and in some cases alter the
1251 operands in OPERANDS to be suitable for the low-numbered word. */
1252
1253 if (optype0 == REGOP)
1254 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1255 else if (optype0 == OFFSOP)
1256 latehalf[0] = adj_offsettable_operand (operands[0], 4);
1257 else
1258 latehalf[0] = operands[0];
1259
1260 if (optype1 == REGOP)
1261 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1262 else if (optype1 == OFFSOP)
1263 latehalf[1] = adj_offsettable_operand (operands[1], 4);
1264 else if (optype1 == CNSTOP)
1265 split_double (operands[1], &operands[1], &latehalf[1]);
1266 else
1267 latehalf[1] = operands[1];
1268
1269 /* If the first move would clobber the source of the second one,
1270 do them in the other order.
1271
1272 RMS says "This happens only for registers;
1273 such overlap can't happen in memory unless the user explicitly
1274 sets it up, and that is an undefined circumstance."
1275
1276 but it happens on the HP-PA when loading parameter registers,
1277 so I am going to define that circumstance, and make it work
1278 as expected. */
1279
1280 if (optype0 == REGOP && (optype1 == MEMOP || optype1 == OFFSOP)
1281 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
1282 {
1283 /* XXX THIS PROBABLY DOESN'T WORK. */
1284 /* Do the late half first. */
1285 if (addreg1)
6a5d085a 1286 output_asm_insn ("ldo 4(%0),%0", &addreg1);
87ad11b0 1287 output_asm_insn (singlemove_string (latehalf), latehalf);
1288 if (addreg1)
6a5d085a 1289 output_asm_insn ("ldo -4(%0),%0", &addreg1);
87ad11b0 1290 /* Then clobber. */
1291 return singlemove_string (operands);
1292 }
1293
c4fa5937 1294 if (optype0 == REGOP && optype1 == REGOP
1295 && REGNO (operands[0]) == REGNO (operands[1]) + 1)
1296 {
1297 output_asm_insn (singlemove_string (latehalf), latehalf);
1298 return singlemove_string (operands);
1299 }
1300
87ad11b0 1301 /* Normal case: do the two words, low-numbered first. */
1302
1303 output_asm_insn (singlemove_string (operands), operands);
1304
1305 /* Make any unoffsettable addresses point at high-numbered word. */
1306 if (addreg0)
6a5d085a 1307 output_asm_insn ("ldo 4(%0),%0", &addreg0);
87ad11b0 1308 if (addreg1)
6a5d085a 1309 output_asm_insn ("ldo 4(%0),%0", &addreg1);
87ad11b0 1310
1311 /* Do that word. */
1312 output_asm_insn (singlemove_string (latehalf), latehalf);
1313
1314 /* Undo the adds we just did. */
1315 if (addreg0)
6a5d085a 1316 output_asm_insn ("ldo -4(%0),%0", &addreg0);
87ad11b0 1317 if (addreg1)
6a5d085a 1318 output_asm_insn ("ldo -4(%0),%0", &addreg1);
87ad11b0 1319
1320 return "";
1321}
1322\f
1323char *
1324output_fp_move_double (operands)
1325 rtx *operands;
1326{
1327 if (FP_REG_P (operands[0]))
1328 {
6d36483b 1329 if (FP_REG_P (operands[1])
891b55b4 1330 || operands[1] == CONST0_RTX (GET_MODE (operands[0])))
1331 output_asm_insn ("fcpy,dbl %r1,%0", operands);
6d36483b 1332 else
87ad11b0 1333 output_asm_insn ("fldds%F1 %1,%0", operands);
1334 }
1335 else if (FP_REG_P (operands[1]))
1336 {
23b9e2b3 1337 output_asm_insn ("fstds%F0 %1,%0", operands);
87ad11b0 1338 }
891b55b4 1339 else if (operands[1] == CONST0_RTX (GET_MODE (operands[0])))
1340 {
1341 if (GET_CODE (operands[0]) == REG)
1342 {
1343 rtx xoperands[2];
1344 xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1345 xoperands[0] = operands[0];
1346 output_asm_insn ("copy %%r0,%0\n\tcopy %%r0,%1", xoperands);
1347 }
6d36483b 1348 /* This is a pain. You have to be prepared to deal with an
891b55b4 1349 arbritary address here including pre/post increment/decrement.
1350
1351 so avoid this in the MD. */
1352 else
1353 abort ();
1354 }
87ad11b0 1355 else abort ();
1356 return "";
1357}
1358\f
1359/* Return a REG that occurs in ADDR with coefficient 1.
1360 ADDR can be effectively incremented by incrementing REG. */
1361
1362static rtx
1363find_addr_reg (addr)
1364 rtx addr;
1365{
1366 while (GET_CODE (addr) == PLUS)
1367 {
1368 if (GET_CODE (XEXP (addr, 0)) == REG)
1369 addr = XEXP (addr, 0);
1370 else if (GET_CODE (XEXP (addr, 1)) == REG)
1371 addr = XEXP (addr, 1);
1372 else if (CONSTANT_P (XEXP (addr, 0)))
1373 addr = XEXP (addr, 1);
1374 else if (CONSTANT_P (XEXP (addr, 1)))
1375 addr = XEXP (addr, 0);
1376 else
1377 abort ();
1378 }
1379 if (GET_CODE (addr) == REG)
1380 return addr;
1381 abort ();
1382}
1383
87ad11b0 1384/* Emit code to perform a block move.
1385
1386 Restriction: If the length argument is non-constant, alignment
1387 must be 4.
1388
1389 OPERANDS[0] is the destination pointer as a REG, clobbered.
1390 OPERANDS[1] is the source pointer as a REG, clobbered.
1391 if SIZE_IS_CONSTANT
1392 OPERANDS[2] is a register for temporary storage.
1393 OPERANDS[4] is the size as a CONST_INT
1394 else
1395 OPERANDS[2] is a REG which will contain the size, clobbered.
1396 OPERANDS[3] is a register for temporary storage.
1397 OPERANDS[5] is the alignment safe to use, as a CONST_INT. */
1398
1399char *
1400output_block_move (operands, size_is_constant)
1401 rtx *operands;
1402 int size_is_constant;
1403{
1404 int align = INTVAL (operands[5]);
1405 unsigned long n_bytes;
1406
1407 /* We can't move more than four bytes at a time because the PA
1408 has no longer integer move insns. (Could use fp mem ops?) */
1409 if (align > 4)
1410 align = 4;
1411
1412 if (size_is_constant)
1413 {
87ad11b0 1414 unsigned long offset;
1415 rtx temp;
1416
1417 n_bytes = INTVAL (operands[4]);
1418 if (n_bytes == 0)
1419 return "";
1420
1421 if (align >= 4)
1422 {
1423 /* Don't unroll too large blocks. */
6d36483b 1424 if (n_bytes > 32)
87ad11b0 1425 goto copy_with_loop;
1426
1427 /* Read and store using two registers, and hide latency
4bbea254 1428 by deferring the stores until three instructions after
87ad11b0 1429 the corresponding load. The last load insn will read
1430 the entire word were the last bytes are, possibly past
1431 the end of the source block, but since loads are aligned,
1432 this is harmless. */
1433
1434 output_asm_insn ("ldws,ma 4(0,%1),%2", operands);
1435
1436 for (offset = 4; offset < n_bytes; offset += 4)
1437 {
1438 output_asm_insn ("ldws,ma 4(0,%1),%3", operands);
1439 output_asm_insn ("stws,ma %2,4(0,%0)", operands);
1440
1441 temp = operands[2];
1442 operands[2] = operands[3];
1443 operands[3] = temp;
1444 }
1445 if (n_bytes % 4 == 0)
1446 /* Store the last word. */
1447 output_asm_insn ("stw %2,0(0,%0)", operands);
1448 else
1449 {
1450 /* Store the last, partial word. */
1451 operands[4] = gen_rtx (CONST_INT, VOIDmode, n_bytes % 4);
1452 output_asm_insn ("stbys,e %2,%4(0,%0)", operands);
1453 }
1454 return "";
1455 }
1456
1457 if (align >= 2 && n_bytes >= 2)
1458 {
1459 output_asm_insn ("ldhs,ma 2(0,%1),%2", operands);
1460
1461 for (offset = 2; offset + 2 <= n_bytes; offset += 2)
1462 {
1463 output_asm_insn ("ldhs,ma 2(0,%1),%3", operands);
1464 output_asm_insn ("sths,ma %2,2(0,%0)", operands);
1465
1466 temp = operands[2];
1467 operands[2] = operands[3];
1468 operands[3] = temp;
1469 }
1470 if (n_bytes % 2 != 0)
1471 output_asm_insn ("ldb 0(0,%1),%3", operands);
1472
1473 output_asm_insn ("sths,ma %2,2(0,%0)", operands);
1474
1475 if (n_bytes % 2 != 0)
1476 output_asm_insn ("stb %3,0(0,%0)", operands);
1477
1478 return "";
1479 }
1480
1481 output_asm_insn ("ldbs,ma 1(0,%1),%2", operands);
1482
1483 for (offset = 1; offset + 1 <= n_bytes; offset += 1)
1484 {
1485 output_asm_insn ("ldbs,ma 1(0,%1),%3", operands);
1486 output_asm_insn ("stbs,ma %2,1(0,%0)", operands);
1487
1488 temp = operands[2];
1489 operands[2] = operands[3];
1490 operands[3] = temp;
1491 }
1492 output_asm_insn ("stb %2,0(0,%0)", operands);
1493
1494 return "";
1495 }
1496
1497 if (align != 4)
1498 abort();
6d36483b 1499
87ad11b0 1500 copy_with_loop:
1501
1502 if (size_is_constant)
1503 {
a3217f65 1504 /* Size is compile-time determined, and also not
87ad11b0 1505 very small (such small cases are handled above). */
1506 operands[4] = gen_rtx (CONST_INT, VOIDmode, n_bytes - 4);
1507 output_asm_insn ("ldo %4(0),%2", operands);
1508 }
1509 else
1510 {
1511 /* Decrement counter by 4, and if it becomes negative, jump past the
1512 word copying loop. */
1513 output_asm_insn ("addib,<,n -4,%2,.+16", operands);
1514 }
1515
4bbea254 1516 /* Copying loop. Note that the first load is in the annulled delay slot
87ad11b0 1517 of addib. Is it OK on PA to have a load in a delay slot, i.e. is a
1518 possible page fault stopped in time? */
1519 output_asm_insn ("ldws,ma 4(0,%1),%3", operands);
1520 output_asm_insn ("addib,>= -4,%2,.-4", operands);
1521 output_asm_insn ("stws,ma %3,4(0,%0)", operands);
1522
1523 /* The counter is negative, >= -4. The remaining number of bytes are
1524 determined by the two least significant bits. */
1525
1526 if (size_is_constant)
1527 {
1528 if (n_bytes % 4 != 0)
1529 {
1530 /* Read the entire word of the source block tail. */
1531 output_asm_insn ("ldw 0(0,%1),%3", operands);
1532 operands[4] = gen_rtx (CONST_INT, VOIDmode, n_bytes % 4);
1533 output_asm_insn ("stbys,e %3,%4(0,%0)", operands);
1534 }
1535 }
1536 else
1537 {
1538 /* Add 4 to counter. If it becomes zero, we're done. */
1539 output_asm_insn ("addib,=,n 4,%2,.+16", operands);
1540
1541 /* Read the entire word of the source block tail. (Also this
4bbea254 1542 load is in an annulled delay slot.) */
87ad11b0 1543 output_asm_insn ("ldw 0(0,%1),%3", operands);
1544
1545 /* Make %0 point at the first byte after the destination block. */
df0651dc 1546 output_asm_insn ("addl %2,%0,%0", operands);
87ad11b0 1547 /* Store the leftmost bytes, up to, but not including, the address
1548 in %0. */
1549 output_asm_insn ("stbys,e %3,0(0,%0)", operands);
1550 }
1551 return "";
1552}
58e17b0b 1553
1554/* Count the number of insns necessary to handle this block move.
1555
1556 Basic structure is the same as emit_block_move, except that we
1557 count insns rather than emit them. */
1558
1559int
1560compute_movstrsi_length (insn)
1561 rtx insn;
1562{
1563 rtx pat = PATTERN (insn);
1564 int size_is_constant;
1565 int align = INTVAL (XEXP (XVECEXP (pat, 0, 6), 0));
1566 unsigned long n_bytes;
1567 int insn_count = 0;
1568
1569 if (GET_CODE (XEXP (XVECEXP (pat, 0, 5), 0)) == CONST_INT)
1570 {
1571 size_is_constant = 1;
1572 n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 5), 0));
1573 }
1574 else
1575 {
1576 size_is_constant = 0;
1577 n_bytes = 0;
1578 }
1579
1580 /* We can't move more than four bytes at a time because the PA
1581 has no longer integer move insns. (Could use fp mem ops?) */
1582 if (align > 4)
1583 align = 4;
1584
1585 if (size_is_constant)
1586 {
58e17b0b 1587 unsigned long offset;
58e17b0b 1588
1589 if (n_bytes == 0)
1590 return 0;
1591
1592 if (align >= 4)
1593 {
1594 /* Don't unroll too large blocks. */
6d36483b 1595 if (n_bytes > 32)
58e17b0b 1596 goto copy_with_loop;
1597
1598 /* first load */
1599 insn_count = 1;
1600
1601 /* Count the unrolled insns. */
1602 for (offset = 4; offset < n_bytes; offset += 4)
1603 insn_count += 2;
1604
1605 /* Count last store or partial store. */
1606 insn_count += 1;
5a1231ef 1607 return insn_count * 4;
58e17b0b 1608 }
1609
1610 if (align >= 2 && n_bytes >= 2)
1611 {
1612 /* initial load. */
1613 insn_count = 1;
1614
1615 /* Unrolled loop. */
1616 for (offset = 2; offset + 2 <= n_bytes; offset += 2)
1617 insn_count += 2;
1618
1619 /* ??? odd load/store */
1620 if (n_bytes % 2 != 0)
1621 insn_count += 2;
1622
1623 /* ??? final store from loop. */
1624 insn_count += 1;
1625
5a1231ef 1626 return insn_count * 4;
58e17b0b 1627 }
1628
1629 /* First load. */
1630 insn_count = 1;
1631
1632 /* The unrolled loop. */
1633 for (offset = 1; offset + 1 <= n_bytes; offset += 1)
1634 insn_count += 2;
1635
1636 /* Final store. */
1637 insn_count += 1;
1638
5a1231ef 1639 return insn_count * 4;
58e17b0b 1640 }
1641
1642 if (align != 4)
1643 abort();
6d36483b 1644
58e17b0b 1645 copy_with_loop:
1646
1647 /* setup for constant and non-constant case. */
1648 insn_count = 1;
1649
1650 /* The copying loop. */
1651 insn_count += 3;
1652
1653 /* The counter is negative, >= -4. The remaining number of bytes are
1654 determined by the two least significant bits. */
1655
1656 if (size_is_constant)
1657 {
1658 if (n_bytes % 4 != 0)
1659 insn_count += 2;
1660 }
1661 else
1662 insn_count += 4;
5a1231ef 1663 return insn_count * 4;
58e17b0b 1664}
87ad11b0 1665\f
1666
e057641f 1667char *
1668output_and (operands)
1669 rtx *operands;
1670{
d6f01525 1671 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
e057641f 1672 {
1673 unsigned mask = INTVAL (operands[2]);
1674 int ls0, ls1, ms0, p, len;
1675
1676 for (ls0 = 0; ls0 < 32; ls0++)
1677 if ((mask & (1 << ls0)) == 0)
1678 break;
1679
1680 for (ls1 = ls0; ls1 < 32; ls1++)
1681 if ((mask & (1 << ls1)) != 0)
1682 break;
1683
1684 for (ms0 = ls1; ms0 < 32; ms0++)
1685 if ((mask & (1 << ms0)) == 0)
1686 break;
1687
1688 if (ms0 != 32)
1689 abort();
1690
1691 if (ls1 == 32)
1692 {
1693 len = ls0;
1694
1695 if (len == 0)
1696 abort ();
1697
1698 operands[2] = gen_rtx (CONST_INT, VOIDmode, len);
1699 return "extru %1,31,%2,%0";
1700 }
1701 else
1702 {
1703 /* We could use this `depi' for the case above as well, but `depi'
1704 requires one more register file access than an `extru'. */
1705
1706 p = 31 - ls0;
1707 len = ls1 - ls0;
1708
1709 operands[2] = gen_rtx (CONST_INT, VOIDmode, p);
1710 operands[3] = gen_rtx (CONST_INT, VOIDmode, len);
1711 return "depi 0,%2,%3,%0";
1712 }
1713 }
1714 else
1715 return "and %1,%2,%0";
1716}
1717
1718char *
1719output_ior (operands)
1720 rtx *operands;
1721{
c9da5f4d 1722 unsigned mask = INTVAL (operands[2]);
57ed30e5 1723 int bs0, bs1, p, len;
6d36483b 1724
c9da5f4d 1725 if (INTVAL (operands[2]) == 0)
1726 return "copy %1,%0";
e057641f 1727
c9da5f4d 1728 for (bs0 = 0; bs0 < 32; bs0++)
1729 if ((mask & (1 << bs0)) != 0)
1730 break;
e057641f 1731
c9da5f4d 1732 for (bs1 = bs0; bs1 < 32; bs1++)
1733 if ((mask & (1 << bs1)) == 0)
1734 break;
e057641f 1735
c9da5f4d 1736 if (bs1 != 32 && ((unsigned) 1 << bs1) <= mask)
1737 abort();
e057641f 1738
c9da5f4d 1739 p = 31 - bs0;
1740 len = bs1 - bs0;
e057641f 1741
c9da5f4d 1742 operands[2] = gen_rtx (CONST_INT, VOIDmode, p);
1743 operands[3] = gen_rtx (CONST_INT, VOIDmode, len);
1744 return "depi -1,%2,%3,%0";
e057641f 1745}
1746\f
87ad11b0 1747/* Output an ascii string. */
57ed30e5 1748void
87ad11b0 1749output_ascii (file, p, size)
1750 FILE *file;
1751 unsigned char *p;
1752 int size;
1753{
1754 int i;
1755 int chars_output;
1756 unsigned char partial_output[16]; /* Max space 4 chars can occupy. */
1757
1758 /* The HP assembler can only take strings of 256 characters at one
1759 time. This is a limitation on input line length, *not* the
1760 length of the string. Sigh. Even worse, it seems that the
1761 restriction is in number of input characters (see \xnn &
1762 \whatever). So we have to do this very carefully. */
1763
1764 fprintf (file, "\t.STRING \"");
1765
1766 chars_output = 0;
1767 for (i = 0; i < size; i += 4)
1768 {
1769 int co = 0;
1770 int io = 0;
1771 for (io = 0, co = 0; io < MIN (4, size - i); io++)
1772 {
1773 register unsigned int c = p[i + io];
1774
1775 if (c == '\"' || c == '\\')
1776 partial_output[co++] = '\\';
1777 if (c >= ' ' && c < 0177)
1778 partial_output[co++] = c;
1779 else
1780 {
1781 unsigned int hexd;
1782 partial_output[co++] = '\\';
1783 partial_output[co++] = 'x';
1784 hexd = c / 16 - 0 + '0';
1785 if (hexd > '9')
1786 hexd -= '9' - 'a' + 1;
1787 partial_output[co++] = hexd;
1788 hexd = c % 16 - 0 + '0';
1789 if (hexd > '9')
1790 hexd -= '9' - 'a' + 1;
1791 partial_output[co++] = hexd;
1792 }
1793 }
1794 if (chars_output + co > 243)
1795 {
1796 fprintf (file, "\"\n\t.STRING \"");
1797 chars_output = 0;
1798 }
1799 fwrite (partial_output, 1, co, file);
1800 chars_output += co;
1801 co = 0;
1802 }
1803 fprintf (file, "\"\n");
1804}
1805\f
201f01e9 1806/* You may have trouble believing this, but this is the HP-PA stack
87ad11b0 1807 layout. Wow.
1808
1809 Offset Contents
1810
1811 Variable arguments (optional; any number may be allocated)
1812
1813 SP-(4*(N+9)) arg word N
1814 : :
1815 SP-56 arg word 5
1816 SP-52 arg word 4
1817
1818 Fixed arguments (must be allocated; may remain unused)
1819
1820 SP-48 arg word 3
1821 SP-44 arg word 2
1822 SP-40 arg word 1
1823 SP-36 arg word 0
1824
1825 Frame Marker
1826
1827 SP-32 External Data Pointer (DP)
1828 SP-28 External sr4
1829 SP-24 External/stub RP (RP')
1830 SP-20 Current RP
1831 SP-16 Static Link
1832 SP-12 Clean up
1833 SP-8 Calling Stub RP (RP'')
1834 SP-4 Previous SP
1835
1836 Top of Frame
1837
1838 SP-0 Stack Pointer (points to next available address)
1839
1840*/
1841
1842/* This function saves registers as follows. Registers marked with ' are
1843 this function's registers (as opposed to the previous function's).
1844 If a frame_pointer isn't needed, r4 is saved as a general register;
1845 the space for the frame pointer is still allocated, though, to keep
1846 things simple.
1847
1848
1849 Top of Frame
1850
1851 SP (FP') Previous FP
1852 SP + 4 Alignment filler (sigh)
1853 SP + 8 Space for locals reserved here.
1854 .
1855 .
1856 .
1857 SP + n All call saved register used.
1858 .
1859 .
1860 .
1861 SP + o All call saved fp registers used.
1862 .
1863 .
1864 .
1865 SP + p (SP') points to next available address.
6d36483b 1866
87ad11b0 1867*/
1868
daee63dd 1869/* Emit RTL to store REG at the memory location specified by BASE+DISP.
1870 Handle case where DISP > 8k by using the add_high_const pattern.
1871
1872 Note in DISP > 8k case, we will leave the high part of the address
1873 in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
1874static void
1875store_reg (reg, disp, base)
1876 int reg, disp, base;
87ad11b0 1877{
1878 if (VAL_14_BITS_P (disp))
daee63dd 1879 {
6d36483b 1880 emit_move_insn (gen_rtx (MEM, SImode,
1881 gen_rtx (PLUS, SImode,
daee63dd 1882 gen_rtx (REG, SImode, base),
1883 GEN_INT (disp))),
1884 gen_rtx (REG, SImode, reg));
1885 }
87ad11b0 1886 else
daee63dd 1887 {
6d36483b 1888 emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
1889 gen_rtx (REG, SImode, base),
daee63dd 1890 GEN_INT (disp)));
1891 emit_move_insn (gen_rtx (MEM, SImode,
6d36483b 1892 gen_rtx (LO_SUM, SImode,
daee63dd 1893 gen_rtx (REG, SImode, 1),
1894 GEN_INT (disp))),
1895 gen_rtx (REG, SImode, reg));
1896 }
87ad11b0 1897}
1898
daee63dd 1899/* Emit RTL to load REG from the memory location specified by BASE+DISP.
1900 Handle case where DISP > 8k by using the add_high_const pattern.
1901
1902 Note in DISP > 8k case, we will leave the high part of the address
1903 in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
1904static void
1905load_reg (reg, disp, base)
1906 int reg, disp, base;
1907{
1908 if (VAL_14_BITS_P (disp))
1909 {
1910 emit_move_insn (gen_rtx (REG, SImode, reg),
6d36483b 1911 gen_rtx (MEM, SImode,
1912 gen_rtx (PLUS, SImode,
daee63dd 1913 gen_rtx (REG, SImode, base),
1914 GEN_INT (disp))));
daee63dd 1915 }
1916 else
1917 {
6d36483b 1918 emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
daee63dd 1919 gen_rtx (REG, SImode, base),
1920 GEN_INT (disp)));
1921 emit_move_insn (gen_rtx (REG, SImode, reg),
1922 gen_rtx (MEM, SImode,
6d36483b 1923 gen_rtx (LO_SUM, SImode,
1924 gen_rtx (REG, SImode, 1),
daee63dd 1925 GEN_INT (disp))));
1926 }
1927}
1928
1929/* Emit RTL to set REG to the value specified by BASE+DISP.
1930 Handle case where DISP > 8k by using the add_high_const pattern.
1931
1932 Note in DISP > 8k case, we will leave the high part of the address
1933 in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
1934static void
1935set_reg_plus_d(reg, base, disp)
1936 int reg, base, disp;
87ad11b0 1937{
1938 if (VAL_14_BITS_P (disp))
daee63dd 1939 {
1940 emit_move_insn (gen_rtx (REG, SImode, reg),
6d36483b 1941 gen_rtx (PLUS, SImode,
daee63dd 1942 gen_rtx (REG, SImode, base),
1943 GEN_INT (disp)));
daee63dd 1944 }
87ad11b0 1945 else
daee63dd 1946 {
6d36483b 1947 emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
daee63dd 1948 gen_rtx (REG, SImode, base),
1949 GEN_INT (disp)));
1950 emit_move_insn (gen_rtx (REG, SImode, reg),
6d36483b 1951 gen_rtx (LO_SUM, SImode,
daee63dd 1952 gen_rtx (REG, SImode, 1),
1953 GEN_INT (disp)));
1954 }
87ad11b0 1955}
1956
3ddcbb9d 1957/* Global variables set by FUNCTION_PROLOGUE. */
1958/* Size of frame. Need to know this to emit return insns from
1959 leaf procedures. */
a1ab4fa3 1960static int actual_fsize;
1961static int local_fsize, save_fregs;
3ddcbb9d 1962
87ad11b0 1963int
a1ab4fa3 1964compute_frame_size (size, fregs_live)
87ad11b0 1965 int size;
3ddcbb9d 1966 int *fregs_live;
87ad11b0 1967{
1968 extern int current_function_outgoing_args_size;
a1ab4fa3 1969 int i, fsize;
87ad11b0 1970
6d36483b 1971 /* 8 is space for frame pointer + filler. If any frame is allocated
a1ab4fa3 1972 we need to add this in because of STARTING_FRAME_OFFSET. */
1973 fsize = size + (size || frame_pointer_needed ? 8 : 0);
87ad11b0 1974
df0651dc 1975 for (i = 18; i >= 4; i--)
daee63dd 1976 {
df0651dc 1977 if (regs_ever_live[i])
daee63dd 1978 fsize += 4;
1979 }
df0651dc 1980 /* If we don't have a frame pointer, the register normally used for that
1981 purpose is saved just like other registers, not in the "frame marker". */
1982 if (! frame_pointer_needed)
87ad11b0 1983 {
df0651dc 1984 if (regs_ever_live[FRAME_POINTER_REGNUM])
1985 fsize += 4;
87ad11b0 1986 }
df0651dc 1987 fsize = (fsize + 7) & ~7;
1988
1989 for (i = 66; i >= 48; i -= 2)
1990 if (regs_ever_live[i] || regs_ever_live[i + 1])
1991 {
1992 fsize += 8;
1993 if (fregs_live)
1994 *fregs_live = 1;
1995 }
1996
a1ab4fa3 1997 fsize += current_function_outgoing_args_size;
1998 if (! leaf_function_p () || fsize)
1999 fsize += 32;
57ed30e5 2000 return (fsize + 63) & ~63;
87ad11b0 2001}
6d36483b 2002
daee63dd 2003rtx hp_profile_label_rtx;
2004static char hp_profile_label_name[8];
87ad11b0 2005void
a1ab4fa3 2006output_function_prologue (file, size)
87ad11b0 2007 FILE *file;
2008 int size;
87ad11b0 2009{
d151162a 2010 /* The function's label and associated .PROC must never be
2011 separated and must be output *after* any profiling declarations
2012 to avoid changing spaces/subspaces within a procedure. */
2013 ASM_OUTPUT_LABEL (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
2014 fputs ("\t.PROC\n", file);
2015
daee63dd 2016 /* hppa_expand_prologue does the dirty work now. We just need
2017 to output the assembler directives which denote the start
2018 of a function. */
2acd4f33 2019 fprintf (file, "\t.CALLINFO FRAME=%d", actual_fsize);
daee63dd 2020 if (regs_ever_live[2] || profile_flag)
f3ba7709 2021 fprintf (file, ",CALLS,SAVE_RP");
daee63dd 2022 else
f3ba7709 2023 fprintf (file, ",NO_CALLS");
2024
2025 if (frame_pointer_needed)
2026 fprintf (file, ",SAVE_SP");
2027
a9960cdc 2028 /* Pass on information about the number of callee register saves
9b0c95be 2029 performed in the prologue.
2030
2031 The compiler is supposed to pass the highest register number
6d36483b 2032 saved, the assembler then has to adjust that number before
9b0c95be 2033 entering it into the unwind descriptor (to account for any
6d36483b 2034 caller saved registers with lower register numbers than the
9b0c95be 2035 first callee saved register). */
2036 if (gr_saved)
2037 fprintf (file, ",ENTRY_GR=%d", gr_saved + 2);
2038
2039 if (fr_saved)
2040 fprintf (file, ",ENTRY_FR=%d", fr_saved + 11);
a9960cdc 2041
f3ba7709 2042 fprintf (file, "\n\t.ENTRY\n");
daee63dd 2043
2044 /* Horrid hack. emit_function_prologue will modify this RTL in
2045 place to get the expected results. */
2046 if (profile_flag)
07b209fc 2047 ASM_GENERATE_INTERNAL_LABEL (hp_profile_label_name, "LP",
2048 hp_profile_labelno);
06ddb6f8 2049
2050 if (insn_addresses)
2051 {
2052 unsigned int old_total = total_code_bytes;
2053
2054 total_code_bytes += insn_addresses[INSN_UID (get_last_insn())];
2055 total_code_bytes += FUNCTION_BOUNDARY /BITS_PER_UNIT;
2056
2057 /* Be prepared to handle overflows. */
2058 total_code_bytes = old_total > total_code_bytes ? -1 : total_code_bytes;
2059 }
2060 else
2061 total_code_bytes = -1;
daee63dd 2062}
2063
57ed30e5 2064void
daee63dd 2065hppa_expand_prologue()
2066{
87ad11b0 2067 extern char call_used_regs[];
daee63dd 2068 int size = get_frame_size ();
afd7b680 2069 int merge_sp_adjust_with_store = 0;
daee63dd 2070 int i, offset;
2071 rtx tmpreg, size_rtx;
2072
a9960cdc 2073 gr_saved = 0;
2074 fr_saved = 0;
3ddcbb9d 2075 save_fregs = 0;
a1ab4fa3 2076 local_fsize = size + (size || frame_pointer_needed ? 8 : 0);
2077 actual_fsize = compute_frame_size (size, &save_fregs);
87ad11b0 2078
daee63dd 2079 /* Compute a few things we will use often. */
2080 tmpreg = gen_rtx (REG, SImode, 1);
2081 size_rtx = GEN_INT (actual_fsize);
87ad11b0 2082
6d36483b 2083 /* Save RP first. The calling conventions manual states RP will
daee63dd 2084 always be stored into the caller's frame at sp-20. */
372ef038 2085 if (regs_ever_live[2] || profile_flag)
6d36483b 2086 store_reg (2, -20, STACK_POINTER_REGNUM);
2087
daee63dd 2088 /* Allocate the local frame and set up the frame pointer if needed. */
a1ab4fa3 2089 if (actual_fsize)
2090 if (frame_pointer_needed)
2091 {
daee63dd 2092 /* Copy the old frame pointer temporarily into %r1. Set up the
2093 new stack pointer, then store away the saved old frame pointer
2094 into the stack at sp+actual_fsize and at the same time update
2095 the stack pointer by actual_fsize bytes. Two versions, first
2096 handles small (<8k) frames. The second handles large (>8k)
2097 frames. */
2098 emit_move_insn (tmpreg, frame_pointer_rtx);
2099 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
a1ab4fa3 2100 if (VAL_14_BITS_P (actual_fsize))
daee63dd 2101 emit_insn (gen_post_stwm (stack_pointer_rtx,
2102 stack_pointer_rtx,
2103 size_rtx, tmpreg));
a1ab4fa3 2104 else
2105 {
b75ad75e 2106 /* It is incorrect to store the saved frame pointer at *sp,
2107 then increment sp (writes beyond the current stack boundary).
2108
2109 So instead use stwm to store at *sp and post-increment the
2110 stack pointer as an atomic operation. Then increment sp to
2111 finish allocating the new frame. */
2112 emit_insn (gen_post_stwm (stack_pointer_rtx,
2113 stack_pointer_rtx,
2114 GEN_INT (64), tmpreg));
daee63dd 2115 set_reg_plus_d (STACK_POINTER_REGNUM,
2116 STACK_POINTER_REGNUM,
b75ad75e 2117 actual_fsize - 64);
a1ab4fa3 2118 }
2119 }
daee63dd 2120 /* no frame pointer needed. */
a1ab4fa3 2121 else
a1ab4fa3 2122 {
daee63dd 2123 /* In some cases we can perform the first callee register save
2124 and allocating the stack frame at the same time. If so, just
2125 make a note of it and defer allocating the frame until saving
2126 the callee registers. */
6d36483b 2127 if (VAL_14_BITS_P (-actual_fsize)
2128 && local_fsize == 0
daee63dd 2129 && ! profile_flag
2130 && ! flag_pic)
afd7b680 2131 merge_sp_adjust_with_store = 1;
daee63dd 2132 /* Can not optimize. Adjust the stack frame by actual_fsize bytes. */
2133 else if (actual_fsize != 0)
2134 set_reg_plus_d (STACK_POINTER_REGNUM,
2135 STACK_POINTER_REGNUM,
2136 actual_fsize);
a1ab4fa3 2137 }
201f01e9 2138 /* The hppa calling conventions say that that %r19, the pic offset
daee63dd 2139 register, is saved at sp - 32 (in this function's frame) when
2140 generating PIC code. */
d6f01525 2141 if (flag_pic)
6d36483b 2142 store_reg (PIC_OFFSET_TABLE_REGNUM, -32, STACK_POINTER_REGNUM);
daee63dd 2143
2144 /* Profiling code.
372ef038 2145
daee63dd 2146 Instead of taking one argument, the counter label, as most normal
2147 mcounts do, _mcount appears to behave differently on the HPPA. It
6d36483b 2148 takes the return address of the caller, the address of this routine,
2149 and the address of the label. Also, it isn't magic, so
daee63dd 2150 argument registre hsave to be preserved. */
372ef038 2151 if (profile_flag)
2152 {
daee63dd 2153 int pc_offset, i, arg_offset, basereg, offsetadj;
2154
2155 pc_offset = 4 + (frame_pointer_needed
2156 ? (VAL_14_BITS_P (actual_fsize) ? 12 : 20)
2157 : (VAL_14_BITS_P (actual_fsize) ? 4 : 8));
2158
2159 /* When the function has a frame pointer, use it as the base
2160 register for saving/restore registers. Else use the stack
2161 pointer. Adjust the offset according to the frame size if
2162 this function does not have a frame pointer. */
d2daf090 2163
2164 basereg = frame_pointer_needed ? FRAME_POINTER_REGNUM
2165 : STACK_POINTER_REGNUM;
2166 offsetadj = frame_pointer_needed ? 0 : actual_fsize;
2167
daee63dd 2168 /* Horrid hack. emit_function_prologue will modify this RTL in
2169 place to get the expected results. sprintf here is just to
2170 put something in the name. */
2171 sprintf(hp_profile_label_name, "LP$%04d", -1);
2172 hp_profile_label_rtx = gen_rtx (SYMBOL_REF, SImode,
2173 hp_profile_label_name);
d6f01525 2174 if (current_function_returns_struct)
daee63dd 2175 store_reg (STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg);
2176
d2daf090 2177 for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
daee63dd 2178 if (regs_ever_live [i])
372ef038 2179 {
daee63dd 2180 store_reg (i, arg_offset, basereg);
2181 /* Deal with arg_offset not fitting in 14 bits. */
d2daf090 2182 pc_offset += VAL_14_BITS_P (arg_offset) ? 4 : 8;
372ef038 2183 }
daee63dd 2184
2185 emit_move_insn (gen_rtx (REG, SImode, 26), gen_rtx (REG, SImode, 2));
2186 emit_move_insn (tmpreg, gen_rtx (HIGH, SImode, hp_profile_label_rtx));
2187 emit_move_insn (gen_rtx (REG, SImode, 24),
2188 gen_rtx (LO_SUM, SImode, tmpreg, hp_profile_label_rtx));
2189 /* %r25 is set from within the output pattern. */
2190 emit_insn (gen_call_profiler (GEN_INT (- pc_offset - 20)));
2191
2192 /* Restore argument registers. */
d2daf090 2193 for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
daee63dd 2194 if (regs_ever_live [i])
2195 load_reg (i, arg_offset, basereg);
2196
d6f01525 2197 if (current_function_returns_struct)
daee63dd 2198 load_reg (STRUCT_VALUE_REGNUM, -12 - offsetadj, basereg);
2199
372ef038 2200 }
2201
6d36483b 2202 /* Normal register save.
daee63dd 2203
2204 Do not save the frame pointer in the frame_pointer_needed case. It
2205 was done earlier. */
87ad11b0 2206 if (frame_pointer_needed)
2207 {
df0651dc 2208 for (i = 18, offset = local_fsize; i >= 4; i--)
2209 if (regs_ever_live[i] && ! call_used_regs[i])
87ad11b0 2210 {
6d36483b 2211 store_reg (i, offset, FRAME_POINTER_REGNUM);
daee63dd 2212 offset += 4;
a9960cdc 2213 gr_saved++;
87ad11b0 2214 }
9b0c95be 2215 /* Account for %r4 which is saved in a special place. */
2216 gr_saved++;
87ad11b0 2217 }
daee63dd 2218 /* No frame pointer needed. */
87ad11b0 2219 else
2220 {
daee63dd 2221 for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
87ad11b0 2222 if (regs_ever_live[i] && ! call_used_regs[i])
2223 {
6d36483b 2224 /* If merge_sp_adjust_with_store is nonzero, then we can
afd7b680 2225 optimize the first GR save. */
201f01e9 2226 if (merge_sp_adjust_with_store)
afd7b680 2227 {
2228 merge_sp_adjust_with_store = 0;
daee63dd 2229 emit_insn (gen_post_stwm (stack_pointer_rtx,
2230 stack_pointer_rtx,
2231 GEN_INT (-offset),
2232 gen_rtx (REG, SImode, i)));
afd7b680 2233 }
2234 else
daee63dd 2235 store_reg (i, offset, STACK_POINTER_REGNUM);
2236 offset += 4;
a9960cdc 2237 gr_saved++;
87ad11b0 2238 }
daee63dd 2239
afd7b680 2240 /* If we wanted to merge the SP adjustment with a GR save, but we never
daee63dd 2241 did any GR saves, then just emit the adjustment here. */
201f01e9 2242 if (merge_sp_adjust_with_store)
daee63dd 2243 set_reg_plus_d (STACK_POINTER_REGNUM,
2244 STACK_POINTER_REGNUM,
2245 actual_fsize);
87ad11b0 2246 }
6d36483b 2247
87ad11b0 2248 /* Align pointer properly (doubleword boundary). */
2249 offset = (offset + 7) & ~7;
2250
2251 /* Floating point register store. */
2252 if (save_fregs)
87ad11b0 2253 {
daee63dd 2254
2255 /* First get the frame or stack pointer to the start of the FP register
2256 save area. */
a1ab4fa3 2257 if (frame_pointer_needed)
daee63dd 2258 set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
a1ab4fa3 2259 else
daee63dd 2260 set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
2261
2262 /* Now actually save the FP registers. */
df0651dc 2263 for (i = 66; i >= 48; i -= 2)
2264 if (regs_ever_live[i] || regs_ever_live[i + 1])
2265 {
2266 emit_move_insn (gen_rtx (MEM, DFmode,
2267 gen_rtx (POST_INC, DFmode, tmpreg)),
2268 gen_rtx (REG, DFmode, i));
2269 fr_saved++;
2270 }
87ad11b0 2271 }
2272}
2273
daee63dd 2274
87ad11b0 2275void
a1ab4fa3 2276output_function_epilogue (file, size)
87ad11b0 2277 FILE *file;
2278 int size;
87ad11b0 2279{
3695c664 2280
2281 rtx insn = get_last_insn ();
2282
daee63dd 2283 /* hppa_expand_epilogue does the dirty work now. We just need
2284 to output the assembler directives which denote the end
3695c664 2285 of a function.
2286
2287 To make debuggers happy, emit a nop if the epilogue was completely
2288 eliminated due to a volatile call as the last insn in the
6d36483b 2289 current function. That way the return address (in %r2) will
3695c664 2290 always point to a valid instruction in the current function. */
2291
2292 /* Get the last real insn. */
2293 if (GET_CODE (insn) == NOTE)
2294 insn = prev_real_insn (insn);
2295
2296 /* If it is a sequence, then look inside. */
2297 if (insn && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
2298 insn = XVECEXP (PATTERN (insn), 0, 0);
2299
6d36483b 2300 /* If insn is a CALL_INSN, then it must be a call to a volatile
3695c664 2301 function (otherwise there would be epilogue insns). */
2302 if (insn && GET_CODE (insn) == CALL_INSN)
2303 fprintf (file, "\tnop\n");
6d36483b 2304
daee63dd 2305 fprintf (file, "\t.EXIT\n\t.PROCEND\n");
2306}
afd7b680 2307
daee63dd 2308void
3695c664 2309hppa_expand_epilogue ()
daee63dd 2310{
6d36483b 2311 rtx tmpreg;
daee63dd 2312 int offset,i;
2313 int merge_sp_adjust_with_load = 0;
2314
2315 /* We will use this often. */
2316 tmpreg = gen_rtx (REG, SImode, 1);
2317
2318 /* Try to restore RP early to avoid load/use interlocks when
2319 RP gets used in the return (bv) instruction. This appears to still
2320 be necessary even when we schedule the prologue and epilogue. */
afd7b680 2321 if (frame_pointer_needed
2322 && (regs_ever_live [2] || profile_flag))
daee63dd 2323 load_reg (2, -20, FRAME_POINTER_REGNUM);
87ad11b0 2324
daee63dd 2325 /* No frame pointer, and stack is smaller than 8k. */
2326 else if (! frame_pointer_needed
2327 && VAL_14_BITS_P (actual_fsize + 20)
2328 && (regs_ever_live[2] || profile_flag))
2329 load_reg (2, - (actual_fsize + 20), STACK_POINTER_REGNUM);
2330
2331 /* General register restores. */
87ad11b0 2332 if (frame_pointer_needed)
2333 {
df0651dc 2334 for (i = 18, offset = local_fsize; i >= 4; i--)
2335 if (regs_ever_live[i] && ! call_used_regs[i])
87ad11b0 2336 {
daee63dd 2337 load_reg (i, offset, FRAME_POINTER_REGNUM);
2338 offset += 4;
87ad11b0 2339 }
87ad11b0 2340 }
2341 else
2342 {
daee63dd 2343 for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
2344 if (regs_ever_live[i] && ! call_used_regs[i])
87ad11b0 2345 {
daee63dd 2346 /* Only for the first load.
2347 merge_sp_adjust_with_load holds the register load
2348 with which we will merge the sp adjustment. */
afd7b680 2349 if (VAL_14_BITS_P (actual_fsize + 20)
2350 && local_fsize == 0
afd7b680 2351 && ! merge_sp_adjust_with_load)
2352 merge_sp_adjust_with_load = i;
daee63dd 2353 else
2354 load_reg (i, offset, STACK_POINTER_REGNUM);
2355 offset += 4;
87ad11b0 2356 }
87ad11b0 2357 }
daee63dd 2358
87ad11b0 2359 /* Align pointer properly (doubleword boundary). */
2360 offset = (offset + 7) & ~7;
2361
daee63dd 2362 /* FP register restores. */
87ad11b0 2363 if (save_fregs)
87ad11b0 2364 {
daee63dd 2365 /* Adjust the register to index off of. */
a1ab4fa3 2366 if (frame_pointer_needed)
daee63dd 2367 set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
a1ab4fa3 2368 else
daee63dd 2369 set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
2370
2371 /* Actually do the restores now. */
df0651dc 2372 for (i = 66; i >= 48; i -= 2)
2373 if (regs_ever_live[i] || regs_ever_live[i + 1])
2374 emit_move_insn (gen_rtx (REG, DFmode, i),
2375 gen_rtx (MEM, DFmode,
2376 gen_rtx (POST_INC, DFmode, tmpreg)));
87ad11b0 2377 }
daee63dd 2378
2379 /* No frame pointer, but we have a stack greater than 8k. We restore
1921d762 2380 %r2 very late in this case. (All other cases are restored as early
2381 as possible.) */
daee63dd 2382 if (! frame_pointer_needed
2383 && ! VAL_14_BITS_P (actual_fsize + 20)
2384 && (regs_ever_live[2] || profile_flag))
87ad11b0 2385 {
daee63dd 2386 set_reg_plus_d (STACK_POINTER_REGNUM,
2387 STACK_POINTER_REGNUM,
2388 - actual_fsize);
2389 /* Uses value left over in %r1 by set_reg_plus_d. */
2390 load_reg (2, - (actual_fsize + 20 + ((- actual_fsize) & ~0x7ff)), 1);
87ad11b0 2391 }
daee63dd 2392
2393 /* Reset stack pointer (and possibly frame pointer). The stack */
2394 /* pointer is initially set to fp + 64 to avoid a race condition.
2395 ??? What race condition?!? */
2396 else if (frame_pointer_needed)
87ad11b0 2397 {
e03010ce 2398 /* Emit a blockage insn here to keep these insns from being moved
2399 to the beginning of the prologue or into the main instruction
2400 stream, doing so avoids some very obscure problems. */
2401 emit_insn (gen_blockage ());
daee63dd 2402 set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
2403 emit_insn (gen_pre_ldwm (stack_pointer_rtx, stack_pointer_rtx,
2404 GEN_INT (-64), frame_pointer_rtx));
87ad11b0 2405 }
daee63dd 2406 /* If we were deferring a callee register restore, do it now. */
2407 else if (! frame_pointer_needed && merge_sp_adjust_with_load)
2408 emit_insn (gen_pre_ldwm (stack_pointer_rtx,
2409 stack_pointer_rtx,
2410 GEN_INT (- actual_fsize),
6d36483b 2411 gen_rtx (REG, SImode,
daee63dd 2412 merge_sp_adjust_with_load)));
2413 else if (actual_fsize != 0)
2414 set_reg_plus_d (STACK_POINTER_REGNUM,
2415 STACK_POINTER_REGNUM,
2416 - actual_fsize);
87ad11b0 2417}
2418
757d4970 2419/* This is only valid once reload has completed because it depends on
2420 knowing exactly how much (if any) frame there is and...
2421
2422 It's only valid if there is no frame marker to de-allocate and...
2423
2424 It's only valid if %r2 hasn't been saved into the caller's frame
2425 (we're not profiling and %r2 isn't live anywhere). */
2426int
2427hppa_can_use_return_insn_p ()
2428{
2429 return (reload_completed
2430 && (compute_frame_size (get_frame_size (), 0) ? 0 : 1)
2431 && ! profile_flag
2432 && ! regs_ever_live[2]
2433 && ! frame_pointer_needed);
2434}
2435
87ad11b0 2436void
2437emit_bcond_fp (code, operand0)
2438 enum rtx_code code;
2439 rtx operand0;
2440{
2441 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2442 gen_rtx (IF_THEN_ELSE, VOIDmode,
6d36483b 2443 gen_rtx (code, VOIDmode,
87ad11b0 2444 gen_rtx (REG, CCFPmode, 0),
2445 const0_rtx),
2446 gen_rtx (LABEL_REF, VOIDmode, operand0),
2447 pc_rtx)));
2448
2449}
2450
2451rtx
2452gen_cmp_fp (code, operand0, operand1)
2453 enum rtx_code code;
2454 rtx operand0, operand1;
2455{
2456 return gen_rtx (SET, VOIDmode, gen_rtx (REG, CCFPmode, 0),
2457 gen_rtx (code, CCFPmode, operand0, operand1));
2458}
2459
8b49b3c7 2460/* Adjust the cost of a scheduling dependency. Return the new cost of
2461 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2462
2463int
2464pa_adjust_cost (insn, link, dep_insn, cost)
2465 rtx insn;
2466 rtx link;
2467 rtx dep_insn;
2468 int cost;
2469{
d402da4b 2470 if (! recog_memoized (insn))
2471 return 0;
8b49b3c7 2472
2473 if (REG_NOTE_KIND (link) == 0)
2474 {
2475 /* Data dependency; DEP_INSN writes a register that INSN reads some
2476 cycles later. */
2477
2478 if (get_attr_type (insn) == TYPE_FPSTORE)
2479 {
d402da4b 2480 rtx pat = PATTERN (insn);
2481 rtx dep_pat = PATTERN (dep_insn);
2482 if (GET_CODE (pat) == PARALLEL)
2483 {
2484 /* This happens for the fstXs,mb patterns. */
2485 pat = XVECEXP (pat, 0, 0);
2486 }
2487 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
8b49b3c7 2488 /* If this happens, we have to extend this to schedule
d402da4b 2489 optimally. Return 0 for now. */
2490 return 0;
8b49b3c7 2491
d402da4b 2492 if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
8b49b3c7 2493 {
d402da4b 2494 if (! recog_memoized (dep_insn))
2495 return 0;
2496 /* DEP_INSN is writing its result to the register
2497 being stored in the fpstore INSN. */
8b49b3c7 2498 switch (get_attr_type (dep_insn))
2499 {
2500 case TYPE_FPLOAD:
2501 /* This cost 3 cycles, not 2 as the md says. */
2502 return cost + 1;
2503
2504 case TYPE_FPALU:
2505 case TYPE_FPMUL:
2506 case TYPE_FPDIVSGL:
2507 case TYPE_FPDIVDBL:
2508 case TYPE_FPSQRTSGL:
2509 case TYPE_FPSQRTDBL:
2510 /* In these important cases, we save one cycle compared to
2511 when flop instruction feed each other. */
2512 return cost - 1;
2513
2514 default:
2515 return cost;
2516 }
2517 }
2518 }
2519
2520 /* For other data dependencies, the default cost specified in the
2521 md is correct. */
2522 return cost;
2523 }
2524 else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
2525 {
2526 /* Anti dependency; DEP_INSN reads a register that INSN writes some
2527 cycles later. */
2528
2529 if (get_attr_type (insn) == TYPE_FPLOAD)
2530 {
d402da4b 2531 rtx pat = PATTERN (insn);
2532 rtx dep_pat = PATTERN (dep_insn);
2533 if (GET_CODE (pat) == PARALLEL)
2534 {
2535 /* This happens for the fldXs,mb patterns. */
2536 pat = XVECEXP (pat, 0, 0);
2537 }
2538 if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
8b49b3c7 2539 /* If this happens, we have to extend this to schedule
d402da4b 2540 optimally. Return 0 for now. */
2541 return 0;
8b49b3c7 2542
d402da4b 2543 if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
8b49b3c7 2544 {
d402da4b 2545 if (! recog_memoized (dep_insn))
2546 return 0;
8b49b3c7 2547 switch (get_attr_type (dep_insn))
2548 {
2549 case TYPE_FPALU:
2550 case TYPE_FPMUL:
2551 case TYPE_FPDIVSGL:
2552 case TYPE_FPDIVDBL:
2553 case TYPE_FPSQRTSGL:
2554 case TYPE_FPSQRTDBL:
d402da4b 2555 /* A fpload can't be issued until one cycle before a
2556 preceeding arithmetic operation has finished, if
2557 the target of the fpload is any of the sources
2558 (or destination) of the arithmetic operation. */
8b49b3c7 2559 return cost - 1;
2560
2561 default:
2562 return 0;
2563 }
2564 }
2565 }
2566
2567 /* For other anti dependencies, the cost is 0. */
2568 return 0;
2569 }
2570
d402da4b 2571 /* For output dependencies, the cost is often one too high. */
2572 return cost - 1;
8b49b3c7 2573}
87ad11b0 2574
58e17b0b 2575/* Return any length adjustment needed by INSN which already has its length
6d36483b 2576 computed as LENGTH. Return zero if no adjustment is necessary.
58e17b0b 2577
5fbd5940 2578 For the PA: function calls, millicode calls, and backwards short
6d36483b 2579 conditional branches with unfilled delay slots need an adjustment by +1
5fbd5940 2580 (to account for the NOP which will be inserted into the instruction stream).
58e17b0b 2581
2582 Also compute the length of an inline block move here as it is too
5fbd5940 2583 complicated to express as a length attribute in pa.md. */
58e17b0b 2584int
2585pa_adjust_insn_length (insn, length)
2586 rtx insn;
2587 int length;
2588{
2589 rtx pat = PATTERN (insn);
2590
5fbd5940 2591 /* Call insns which are *not* indirect and have unfilled delay slots. */
58e17b0b 2592 if (GET_CODE (insn) == CALL_INSN)
5fbd5940 2593 {
2594
2595 if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL
2596 && GET_CODE (XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)) == SYMBOL_REF)
5a1231ef 2597 return 4;
5fbd5940 2598 else if (GET_CODE (XVECEXP (pat, 0, 0)) == SET
2599 && GET_CODE (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0))
2600 == SYMBOL_REF)
5a1231ef 2601 return 4;
5fbd5940 2602 else
2603 return 0;
2604 }
58e17b0b 2605 /* Millicode insn with an unfilled delay slot. */
2606 else if (GET_CODE (insn) == INSN
2607 && GET_CODE (pat) != SEQUENCE
2608 && GET_CODE (pat) != USE
2609 && GET_CODE (pat) != CLOBBER
2610 && get_attr_type (insn) == TYPE_MILLI)
5a1231ef 2611 return 4;
58e17b0b 2612 /* Block move pattern. */
2613 else if (GET_CODE (insn) == INSN
2614 && GET_CODE (pat) == PARALLEL
2615 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM
2616 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 1)) == MEM
2617 && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode
2618 && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode)
5a1231ef 2619 return compute_movstrsi_length (insn) - 4;
58e17b0b 2620 /* Conditional branch with an unfilled delay slot. */
5fbd5940 2621 else if (GET_CODE (insn) == JUMP_INSN && ! simplejump_p (insn))
2622 {
2623 /* Adjust a short backwards conditional with an unfilled delay slot. */
2624 if (GET_CODE (pat) == SET
5a1231ef 2625 && length == 4
5fbd5940 2626 && ! forward_branch_p (insn))
5a1231ef 2627 return 4;
5fbd5940 2628 /* Adjust dbra insn with short backwards conditional branch with
6d36483b 2629 unfilled delay slot -- only for case where counter is in a
29a4502c 2630 general register register. */
5fbd5940 2631 else if (GET_CODE (pat) == PARALLEL
2632 && GET_CODE (XVECEXP (pat, 0, 1)) == SET
2633 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == REG
6d36483b 2634 && ! FP_REG_P (XEXP (XVECEXP (pat, 0, 1), 0))
5a1231ef 2635 && length == 4
5fbd5940 2636 && ! forward_branch_p (insn))
5a1231ef 2637 return 4;
5fbd5940 2638 else
2639 return 0;
2640 }
58e17b0b 2641 else
2642 return 0;
2643}
2644
87ad11b0 2645/* Print operand X (an rtx) in assembler syntax to file FILE.
2646 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
2647 For `%' followed by punctuation, CODE is the punctuation and X is null. */
2648
2649void
2650print_operand (file, x, code)
2651 FILE *file;
2652 rtx x;
2653 int code;
2654{
2655 switch (code)
2656 {
2657 case '#':
2658 /* Output a 'nop' if there's nothing for the delay slot. */
2659 if (dbr_sequence_length () == 0)
2660 fputs ("\n\tnop", file);
2661 return;
2662 case '*':
2663 /* Output an nullification completer if there's nothing for the */
6d36483b 2664 /* delay slot or nullification is requested. */
87ad11b0 2665 if (dbr_sequence_length () == 0 ||
2666 (final_sequence &&
2667 INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))))
2668 fputs (",n", file);
2669 return;
2670 case 'R':
2671 /* Print out the second register name of a register pair.
2672 I.e., R (6) => 7. */
2673 fputs (reg_names[REGNO (x)+1], file);
2674 return;
2675 case 'r':
2676 /* A register or zero. */
891b55b4 2677 if (x == const0_rtx
2678 || (x == CONST0_RTX (DFmode))
2679 || (x == CONST0_RTX (SFmode)))
87ad11b0 2680 {
2681 fputs ("0", file);
2682 return;
2683 }
2684 else
2685 break;
c8975385 2686 case 'C': /* Plain (C)ondition */
87ad11b0 2687 case 'X':
2688 switch (GET_CODE (x))
6d36483b 2689 {
87ad11b0 2690 case EQ:
2691 fprintf (file, "="); break;
2692 case NE:
9d887bf4 2693 fprintf (file, "<>"); break;
87ad11b0 2694 case GT:
2695 fprintf (file, ">"); break;
2696 case GE:
2697 fprintf (file, ">="); break;
2698 case GEU:
2699 fprintf (file, ">>="); break;
2700 case GTU:
2701 fprintf (file, ">>"); break;
2702 case LT:
2703 fprintf (file, "<"); break;
2704 case LE:
2705 fprintf (file, "<="); break;
2706 case LEU:
2707 fprintf (file, "<<="); break;
2708 case LTU:
2709 fprintf (file, "<<"); break;
2710 default:
87ad11b0 2711 abort ();
2712 }
2713 return;
c8975385 2714 case 'N': /* Condition, (N)egated */
87ad11b0 2715 switch (GET_CODE (x))
2716 {
2717 case EQ:
9d887bf4 2718 fprintf (file, "<>"); break;
87ad11b0 2719 case NE:
2720 fprintf (file, "="); break;
2721 case GT:
2722 fprintf (file, "<="); break;
2723 case GE:
2724 fprintf (file, "<"); break;
2725 case GEU:
2726 fprintf (file, "<<"); break;
2727 case GTU:
2728 fprintf (file, "<<="); break;
2729 case LT:
2730 fprintf (file, ">="); break;
2731 case LE:
2732 fprintf (file, ">"); break;
2733 case LEU:
2734 fprintf (file, ">>"); break;
2735 case LTU:
2736 fprintf (file, ">>="); break;
2737 default:
87ad11b0 2738 abort ();
2739 }
2740 return;
61230bc9 2741 /* For floating point comparisons. Need special conditions to deal
2742 with NaNs properly. */
2743 case 'Y':
2744 switch (GET_CODE (x))
2745 {
2746 case EQ:
2747 fprintf (file, "!="); break;
2748 case NE:
2749 fprintf (file, "="); break;
2750 case GT:
2751 fprintf (file, "!>"); break;
2752 case GE:
2753 fprintf (file, "!>="); break;
2754 case LT:
2755 fprintf (file, "!<"); break;
2756 case LE:
2757 fprintf (file, "!<="); break;
2758 default:
61230bc9 2759 abort ();
2760 }
2761 return;
c8975385 2762 case 'S': /* Condition, operands are (S)wapped. */
2763 switch (GET_CODE (x))
2764 {
2765 case EQ:
2766 fprintf (file, "="); break;
2767 case NE:
2768 fprintf (file, "<>"); break;
2769 case GT:
2770 fprintf (file, "<"); break;
2771 case GE:
2772 fprintf (file, "<="); break;
2773 case GEU:
2774 fprintf (file, "<<="); break;
2775 case GTU:
2776 fprintf (file, "<<"); break;
2777 case LT:
2778 fprintf (file, ">"); break;
2779 case LE:
2780 fprintf (file, ">="); break;
2781 case LEU:
2782 fprintf (file, ">>="); break;
2783 case LTU:
2784 fprintf (file, ">>"); break;
2785 default:
c8975385 2786 abort ();
6d36483b 2787 }
c8975385 2788 return;
2789 case 'B': /* Condition, (B)oth swapped and negate. */
2790 switch (GET_CODE (x))
2791 {
2792 case EQ:
2793 fprintf (file, "<>"); break;
2794 case NE:
2795 fprintf (file, "="); break;
2796 case GT:
2797 fprintf (file, ">="); break;
2798 case GE:
2799 fprintf (file, ">"); break;
2800 case GEU:
2801 fprintf (file, ">>"); break;
2802 case GTU:
2803 fprintf (file, ">>="); break;
2804 case LT:
2805 fprintf (file, "<="); break;
2806 case LE:
2807 fprintf (file, "<"); break;
2808 case LEU:
2809 fprintf (file, "<<"); break;
2810 case LTU:
2811 fprintf (file, "<<="); break;
2812 default:
c8975385 2813 abort ();
6d36483b 2814 }
c8975385 2815 return;
2816 case 'k':
2817 if (GET_CODE (x) == CONST_INT)
2818 {
2819 fprintf (file, "%d", ~INTVAL (x));
2820 return;
2821 }
2822 abort();
e5965947 2823 case 'L':
2824 if (GET_CODE (x) == CONST_INT)
2825 {
2826 fprintf (file, "%d", 32 - (INTVAL (x) & 31));
2827 return;
2828 }
2829 abort();
3a16146d 2830 case 'O':
2831 if (GET_CODE (x) == CONST_INT && exact_log2 (INTVAL (x)) >= 0)
2832 {
2833 fprintf (file, "%d", exact_log2 (INTVAL (x)));
2834 return;
2835 }
2836 abort();
e5965947 2837 case 'P':
2838 if (GET_CODE (x) == CONST_INT)
2839 {
2840 fprintf (file, "%d", 31 - (INTVAL (x) & 31));
2841 return;
2842 }
2843 abort();
c8975385 2844 case 'I':
2845 if (GET_CODE (x) == CONST_INT)
2846 fputs ("i", file);
2847 return;
87ad11b0 2848 case 'M':
2849 switch (GET_CODE (XEXP (x, 0)))
2850 {
2851 case PRE_DEC:
2852 case PRE_INC:
2853 fprintf (file, "s,mb");
2854 break;
2855 case POST_DEC:
2856 case POST_INC:
2857 fprintf (file, "s,ma");
2858 break;
2859 default:
2860 break;
2861 }
2862 return;
2863 case 'F':
2864 switch (GET_CODE (XEXP (x, 0)))
2865 {
2866 case PRE_DEC:
2867 case PRE_INC:
2868 fprintf (file, ",mb");
2869 break;
2870 case POST_DEC:
2871 case POST_INC:
2872 fprintf (file, ",ma");
2873 break;
2874 default:
2875 break;
2876 }
2877 return;
2878 case 'G':
2879 output_global_address (file, x);
2880 return;
2881 case 0: /* Don't do anything special */
2882 break;
42faba01 2883 case 'Z':
2884 {
2885 unsigned op[3];
2886 compute_zdepi_operands (INTVAL (x), op);
2887 fprintf (file, "%d,%d,%d", op[0], op[1], op[2]);
2888 return;
2889 }
87ad11b0 2890 default:
2891 abort ();
2892 }
2893 if (GET_CODE (x) == REG)
df0651dc 2894 {
2895 if (FP_REG_P (x) && GET_MODE_SIZE (GET_MODE (x)) <= 4 && (REGNO (x) & 1) == 0)
2896 fprintf (file, "%sL", reg_names [REGNO (x)]);
2897 else
2898 fprintf (file, "%s", reg_names [REGNO (x)]);
2899 }
87ad11b0 2900 else if (GET_CODE (x) == MEM)
2901 {
2902 int size = GET_MODE_SIZE (GET_MODE (x));
2903 rtx base = XEXP (XEXP (x, 0), 0);
2904 switch (GET_CODE (XEXP (x, 0)))
2905 {
2906 case PRE_DEC:
2907 case POST_DEC:
2908 fprintf (file, "-%d(0,%s)", size, reg_names [REGNO (base)]);
2909 break;
2910 case PRE_INC:
2911 case POST_INC:
2912 fprintf (file, "%d(0,%s)", size, reg_names [REGNO (base)]);
2913 break;
2914 default:
2915 output_address (XEXP (x, 0));
2916 break;
2917 }
2918 }
2919 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
2920 {
2921 union { double d; int i[2]; } u;
2922 union { float f; int i; } u1;
2923 u.i[0] = XINT (x, 0); u.i[1] = XINT (x, 1);
2924 u1.f = u.d;
2925 if (code == 'f')
2926 fprintf (file, "0r%.9g", u1.f);
2927 else
2928 fprintf (file, "0x%x", u1.i);
2929 }
6c640a06 2930 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
87ad11b0 2931 {
2932 union { double d; int i[2]; } u;
2933 u.i[0] = XINT (x, 0); u.i[1] = XINT (x, 1);
2934 fprintf (file, "0r%.20g", u.d);
2935 }
2936 else
2937 output_addr_const (file, x);
2938}
2939
2940/* output a SYMBOL_REF or a CONST expression involving a SYMBOL_REF. */
2941
2942void
2943output_global_address (file, x)
2944 FILE *file;
2945 rtx x;
2946{
2ee034bc 2947
2948 /* Imagine (high (const (plus ...))). */
2949 if (GET_CODE (x) == HIGH)
2950 x = XEXP (x, 0);
2951
87ad11b0 2952 if (GET_CODE (x) == SYMBOL_REF && read_only_operand (x))
2953 assemble_name (file, XSTR (x, 0));
b4a7bf10 2954 else if (GET_CODE (x) == SYMBOL_REF && !flag_pic)
87ad11b0 2955 {
2956 assemble_name (file, XSTR (x, 0));
2957 fprintf (file, "-$global$");
2958 }
2959 else if (GET_CODE (x) == CONST)
2960 {
2961 char *sep = "";
2962 int offset = 0; /* assembler wants -$global$ at end */
2963 rtx base;
6d36483b 2964
87ad11b0 2965 if (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
2966 {
2967 base = XEXP (XEXP (x, 0), 0);
2968 output_addr_const (file, base);
2969 }
2970 else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == CONST_INT)
2971 offset = INTVAL (XEXP (XEXP (x, 0), 0));
2972 else abort ();
2973
2974 if (GET_CODE (XEXP (XEXP (x, 0), 1)) == SYMBOL_REF)
2975 {
2976 base = XEXP (XEXP (x, 0), 1);
2977 output_addr_const (file, base);
2978 }
2979 else if (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2980 offset = INTVAL (XEXP (XEXP (x, 0),1));
2981 else abort ();
2982
2983 if (GET_CODE (XEXP (x, 0)) == PLUS)
2984 {
2985 if (offset < 0)
2986 {
2987 offset = -offset;
2988 sep = "-";
2989 }
2990 else
2991 sep = "+";
2992 }
2993 else if (GET_CODE (XEXP (x, 0)) == MINUS
2994 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF))
2995 sep = "-";
2996 else abort ();
2997
b4a7bf10 2998 if (!read_only_operand (base) && !flag_pic)
87ad11b0 2999 fprintf (file, "-$global$");
3000 fprintf (file, "%s", sep);
3001 if (offset) fprintf (file,"%d", offset);
3002 }
3003 else
3004 output_addr_const (file, x);
3005}
3006
87ad11b0 3007/* HP's millicode routines mean something special to the assembler.
3008 Keep track of which ones we have used. */
3009
3010enum millicodes { remI, remU, divI, divU, mulI, mulU, end1000 };
3011static char imported[(int)end1000];
3012static char *milli_names[] = {"remI", "remU", "divI", "divU", "mulI", "mulU"};
3013static char import_string[] = ".IMPORT $$....,MILLICODE";
3014#define MILLI_START 10
3015
57ed30e5 3016static void
87ad11b0 3017import_milli (code)
3018 enum millicodes code;
3019{
3020 char str[sizeof (import_string)];
6d36483b 3021
87ad11b0 3022 if (!imported[(int)code])
3023 {
3024 imported[(int)code] = 1;
3025 strcpy (str, import_string);
3026 strncpy (str + MILLI_START, milli_names[(int)code], 4);
3027 output_asm_insn (str, 0);
3028 }
3029}
3030
6d36483b 3031/* The register constraints have put the operands and return value in
87ad11b0 3032 the proper registers. */
3033
3034char *
d6686e21 3035output_mul_insn (unsignedp, insn)
87ad11b0 3036 int unsignedp;
d6686e21 3037 rtx insn;
87ad11b0 3038{
d6686e21 3039
87ad11b0 3040 if (unsignedp)
3041 {
3042 import_milli (mulU);
d6686e21 3043 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$mulU"),
3044 gen_rtx (REG, SImode, 31));
87ad11b0 3045 }
3046 else
3047 {
3048 import_milli (mulI);
d6686e21 3049 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$mulI"),
3050 gen_rtx (REG, SImode, 31));
87ad11b0 3051 }
3052}
3053
3054/* If operands isn't NULL, then it's a CONST_INT with which we can do
3055 something */
3056
3057
3058/* Emit the rtl for doing a division by a constant. */
3059
3060 /* Do magic division millicodes exist for this value? */
3061
3062static int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
3063 1, 1};
3064
6d36483b 3065/* We'll use an array to keep track of the magic millicodes and
87ad11b0 3066 whether or not we've used them already. [n][0] is signed, [n][1] is
3067 unsigned. */
3068
87ad11b0 3069static int div_milli[16][2];
3070
3071int
3072div_operand (op, mode)
3073 rtx op;
3074 enum machine_mode mode;
3075{
3076 return (mode == SImode
3077 && ((GET_CODE (op) == REG && REGNO (op) == 25)
3078 || (GET_CODE (op) == CONST_INT && INTVAL (op) > 0
3079 && INTVAL (op) < 16 && magic_milli[INTVAL (op)])));
3080}
3081
3082int
3083emit_hpdiv_const (operands, unsignedp)
3084 rtx *operands;
3085 int unsignedp;
3086{
3087 if (GET_CODE (operands[2]) == CONST_INT
3088 && INTVAL (operands[2]) > 0
3089 && INTVAL (operands[2]) < 16
3090 && magic_milli[INTVAL (operands[2])])
3091 {
3092 emit_move_insn ( gen_rtx (REG, SImode, 26), operands[1]);
3093 emit
3094 (gen_rtx
3095 (PARALLEL, VOIDmode,
3096 gen_rtvec (5, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29),
3097 gen_rtx (unsignedp ? UDIV : DIV, SImode,
3098 gen_rtx (REG, SImode, 26),
3099 operands[2])),
33bd7237 3100 gen_rtx (CLOBBER, VOIDmode, operands[3]),
87ad11b0 3101 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)),
3102 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)),
3103 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31)))));
3104 emit_move_insn (operands[0], gen_rtx (REG, SImode, 29));
3105 return 1;
3106 }
3107 return 0;
3108}
3109
3110char *
d6686e21 3111output_div_insn (operands, unsignedp, insn)
87ad11b0 3112 rtx *operands;
3113 int unsignedp;
d6686e21 3114 rtx insn;
87ad11b0 3115{
3116 int divisor;
6d36483b 3117
3118 /* If the divisor is a constant, try to use one of the special
87ad11b0 3119 opcodes .*/
3120 if (GET_CODE (operands[0]) == CONST_INT)
3121 {
d6686e21 3122 static char buf[100];
87ad11b0 3123 divisor = INTVAL (operands[0]);
3124 if (!div_milli[divisor][unsignedp])
3125 {
d6686e21 3126 div_milli[divisor][unsignedp] = 1;
87ad11b0 3127 if (unsignedp)
3128 output_asm_insn (".IMPORT $$divU_%0,MILLICODE", operands);
3129 else
3130 output_asm_insn (".IMPORT $$divI_%0,MILLICODE", operands);
87ad11b0 3131 }
3132 if (unsignedp)
d6686e21 3133 {
3134 sprintf (buf, "$$divU_%d", INTVAL (operands[0]));
3135 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, buf),
3136 gen_rtx (REG, SImode, 31));
3137 }
3138 else
3139 {
3140 sprintf (buf, "$$divI_%d", INTVAL (operands[0]));
3141 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, buf),
3142 gen_rtx (REG, SImode, 31));
3143 }
87ad11b0 3144 }
3145 /* Divisor isn't a special constant. */
3146 else
3147 {
3148 if (unsignedp)
3149 {
3150 import_milli (divU);
d6686e21 3151 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$divU"),
3152 gen_rtx (REG, SImode, 31));
87ad11b0 3153 }
3154 else
3155 {
3156 import_milli (divI);
d6686e21 3157 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$divI"),
3158 gen_rtx (REG, SImode, 31));
87ad11b0 3159 }
3160 }
3161}
3162
3163/* Output a $$rem millicode to do mod. */
3164
3165char *
d6686e21 3166output_mod_insn (unsignedp, insn)
87ad11b0 3167 int unsignedp;
d6686e21 3168 rtx insn;
87ad11b0 3169{
3170 if (unsignedp)
3171 {
3172 import_milli (remU);
d6686e21 3173 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$remU"),
3174 gen_rtx (REG, SImode, 31));
87ad11b0 3175 }
3176 else
3177 {
3178 import_milli (remI);
d6686e21 3179 return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$remI"),
3180 gen_rtx (REG, SImode, 31));
87ad11b0 3181 }
3182}
3183
3184void
df0651dc 3185output_arg_descriptor (call_insn)
3186 rtx call_insn;
87ad11b0 3187{
3188 char *arg_regs[4];
3189 enum machine_mode arg_mode;
df0651dc 3190 rtx link;
87ad11b0 3191 int i, output_flag = 0;
3192 int regno;
6d36483b 3193
87ad11b0 3194 for (i = 0; i < 4; i++)
3195 arg_regs[i] = 0;
3196
738176ab 3197 /* Specify explicitly that no argument relocations should take place
3198 if using the portable runtime calling conventions. */
3199 if (TARGET_PORTABLE_RUNTIME)
3200 {
3201 fprintf (asm_out_file,
3202 "\t.CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO,RETVAL=NO\n");
3203 return;
3204 }
3205
df0651dc 3206 if (GET_CODE (call_insn) != CALL_INSN)
3207 abort ();
3208 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); link; link = XEXP (link, 1))
87ad11b0 3209 {
df0651dc 3210 rtx use = XEXP (link, 0);
c12afafd 3211
df0651dc 3212 if (! (GET_CODE (use) == USE
3213 && GET_CODE (XEXP (use, 0)) == REG
3214 && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
c12afafd 3215 continue;
3216
df0651dc 3217 arg_mode = GET_MODE (XEXP (use, 0));
3218 regno = REGNO (XEXP (use, 0));
87ad11b0 3219 if (regno >= 23 && regno <= 26)
372ef038 3220 {
3221 arg_regs[26 - regno] = "GR";
3222 if (arg_mode == DImode)
3223 arg_regs[25 - regno] = "GR";
3224 }
df0651dc 3225 else if (regno >= 32 && regno <= 39)
87ad11b0 3226 {
3227 if (arg_mode == SFmode)
df0651dc 3228 arg_regs[(regno - 32) / 2] = "FR";
e6ba640e 3229 else
87ad11b0 3230 {
eeec72c0 3231#ifndef HP_FP_ARG_DESCRIPTOR_REVERSED
df0651dc 3232 arg_regs[(regno - 34) / 2] = "FR";
3233 arg_regs[(regno - 34) / 2 + 1] = "FU";
87ad11b0 3234#else
df0651dc 3235 arg_regs[(regno - 34) / 2] = "FU";
3236 arg_regs[(regno - 34) / 2 + 1] = "FR";
87ad11b0 3237#endif
3238 }
87ad11b0 3239 }
3240 }
3241 fputs ("\t.CALL ", asm_out_file);
3242 for (i = 0; i < 4; i++)
3243 {
3244 if (arg_regs[i])
3245 {
3246 if (output_flag++)
3247 fputc (',', asm_out_file);
3248 fprintf (asm_out_file, "ARGW%d=%s", i, arg_regs[i]);
3249 }
3250 }
3251 fputc ('\n', asm_out_file);
3252}
3253\f
d2c1d63d 3254/* Memory loads/stores to/from the shift need to go through
3255 the general registers. */
87ad11b0 3256
3257enum reg_class
3258secondary_reload_class (class, mode, in)
3259 enum reg_class class;
3260 enum machine_mode mode;
3261 rtx in;
3262{
3263 int regno = true_regnum (in);
3264
b4a7bf10 3265 /* Trying to load a constant into a FP register during PIC code
3266 generation will require %r1 as a scratch register. */
3267 if (flag_pic == 2
3268 && GET_MODE_CLASS (mode) == MODE_INT
3269 && FP_REG_CLASS_P (class)
3270 && (GET_CODE (in) == CONST_INT || GET_CODE (in) == CONST_DOUBLE))
3271 return R1_REGS;
3272
d2498717 3273 if (((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
6d36483b 3274 && GET_MODE_CLASS (mode) == MODE_INT
3275 && FP_REG_CLASS_P (class))
d6f01525 3276 || (class == SHIFT_REGS && (regno <= 0 || regno >= 32)))
9c6d4825 3277 return GENERAL_REGS;
d2c1d63d 3278
2ee034bc 3279 if (GET_CODE (in) == HIGH)
3280 in = XEXP (in, 0);
3281
b4a7bf10 3282 if (!flag_pic
3283 && symbolic_operand (in, VOIDmode)
3284 && read_only_operand (in))
3285 return NO_REGS;
3286
63882853 3287 if (class != R1_REGS && symbolic_operand (in, VOIDmode))
2ee034bc 3288 return R1_REGS;
3289
6b1c36c2 3290 if (GET_CODE (in) == SUBREG)
3291 in = SUBREG_REG (in);
3292
3293 if (FP_REG_CLASS_P (class)
3294 && GET_CODE (in) == MEM
3295 && !memory_address_p (DFmode, XEXP (in, 0))
3296 && memory_address_p (SImode, XEXP (in, 0)))
3297 return GENERAL_REGS;
3298
d2c1d63d 3299 return NO_REGS;
87ad11b0 3300}
3301
3302enum direction
3303function_arg_padding (mode, type)
3304 enum machine_mode mode;
3305 tree type;
3306{
3307 int size;
3308
3309 if (mode == BLKmode)
3310 {
3311 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
3312 size = int_size_in_bytes (type) * BITS_PER_UNIT;
3313 else
3314 return upward; /* Don't know if this is right, but */
3315 /* same as old definition. */
3316 }
3317 else
3318 size = GET_MODE_BITSIZE (mode);
3319 if (size < PARM_BOUNDARY)
3320 return downward;
3321 else if (size % PARM_BOUNDARY)
3322 return upward;
3323 else
3324 return none;
3325}
3326
87ad11b0 3327\f
3328/* Do what is necessary for `va_start'. The argument is ignored;
3329 We look at the current function to determine if stdargs or varargs
3330 is used and fill in an initial va_list. A pointer to this constructor
3331 is returned. */
3332
3333struct rtx_def *
3334hppa_builtin_saveregs (arglist)
3335 tree arglist;
3336{
57ed30e5 3337 rtx offset;
87ad11b0 3338 tree fntype = TREE_TYPE (current_function_decl);
3339 int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0
3340 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3341 != void_type_node)))
3342 ? UNITS_PER_WORD : 0);
3343
3344 if (argadj)
3345 offset = plus_constant (current_function_arg_offset_rtx, argadj);
3346 else
3347 offset = current_function_arg_offset_rtx;
9c6d4825 3348
87ad11b0 3349 /* Store general registers on the stack. */
3350 move_block_from_reg (23,
3351 gen_rtx (MEM, BLKmode,
3352 plus_constant
3353 (current_function_internal_arg_pointer, -16)),
6d36483b 3354 4, 4 * UNITS_PER_WORD);
9c6d4825 3355 return copy_to_reg (expand_binop (Pmode, add_optab,
3356 current_function_internal_arg_pointer,
3357 offset, 0, 0, OPTAB_LIB_WIDEN));
87ad11b0 3358}
d6f01525 3359
6d36483b 3360/* This routine handles all the normal conditional branch sequences we
3361 might need to generate. It handles compare immediate vs compare
3362 register, nullification of delay slots, varying length branches,
0d986529 3363 negated branches, and all combinations of the above. It returns the
6d36483b 3364 output appropriate to emit the branch corresponding to all given
0d986529 3365 parameters. */
3366
3367char *
3368output_cbranch (operands, nullify, length, negated, insn)
3369 rtx *operands;
3370 int nullify, length, negated;
3371 rtx insn;
29a4502c 3372{
0d986529 3373 static char buf[100];
3374 int useskip = 0;
3375
29a4502c 3376 /* A conditional branch to the following instruction (eg the delay slot) is
3377 asking for a disaster. This can happen when not optimizing.
3378
3379 In such cases it is safe to emit nothing. */
3380
3381 if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
3382 return "";
6d36483b 3383
5fbd5940 3384 /* If this is a long branch with its delay slot unfilled, set `nullify'
3385 as it can nullify the delay slot and save a nop. */
5a1231ef 3386 if (length == 8 && dbr_sequence_length () == 0)
5fbd5940 3387 nullify = 1;
3388
3389 /* If this is a short forward conditional branch which did not get
3390 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 3391 if (! nullify && length == 4 && dbr_sequence_length () == 0)
5fbd5940 3392 nullify = forward_branch_p (insn);
3393
6d36483b 3394 /* A forward branch over a single nullified insn can be done with a
0d986529 3395 comclr instruction. This avoids a single cycle penalty due to
3396 mis-predicted branch if we fall through (branch not taken). */
5a1231ef 3397 if (length == 4
5fbd5940 3398 && next_real_insn (insn) != 0
5a1231ef 3399 && get_attr_length (next_real_insn (insn)) == 4
5fbd5940 3400 && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
0d986529 3401 && nullify)
3402 useskip = 1;
3403
3404 switch (length)
3405 {
5fbd5940 3406 /* All short conditional branches except backwards with an unfilled
3407 delay slot. */
5a1231ef 3408 case 4:
0d986529 3409 if (useskip)
3410 strcpy (buf, "com%I2clr,");
3411 else
3412 strcpy (buf, "com%I2b,");
3413 if (negated)
3414 strcat (buf, "%B3");
3415 else
3416 strcat (buf, "%S3");
3417 if (useskip)
3418 strcat (buf, " %2,%1,0");
3419 else if (nullify)
3420 strcat (buf, ",n %2,%1,%0");
6d36483b 3421 else
5fbd5940 3422 strcat (buf, " %2,%1,%0");
0d986529 3423 break;
3424
6d36483b 3425 /* All long conditionals. Note an short backward branch with an
5fbd5940 3426 unfilled delay slot is treated just like a long backward branch
3427 with an unfilled delay slot. */
5a1231ef 3428 case 8:
5fbd5940 3429 /* Handle weird backwards branch with a filled delay slot
3430 with is nullified. */
3431 if (dbr_sequence_length () != 0
3432 && ! forward_branch_p (insn)
3433 && nullify)
3434 {
3435 strcpy (buf, "com%I2b,");
3436 if (negated)
3437 strcat (buf, "%S3");
3438 else
3439 strcat (buf, "%B3");
3440 strcat (buf, ",n %2,%1,.+12\n\tbl %0,0");
3441 }
43f0c1f2 3442 /* Handle short backwards branch with an unfilled delay slot.
3443 Using a comb;nop rather than comiclr;bl saves 1 cycle for both
3444 taken and untaken branches. */
3445 else if (dbr_sequence_length () == 0
3446 && ! forward_branch_p (insn)
3447 && insn_addresses
3448 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
3449 - insn_addresses[INSN_UID (insn)]))
3450 {
3451 strcpy (buf, "com%I2b,");
3452 if (negated)
3453 strcat (buf, "%B3 %2,%1,%0%#");
3454 else
3455 strcat (buf, "%S3 %2,%1,%0%#");
3456 }
0d986529 3457 else
5fbd5940 3458 {
3459 strcpy (buf, "com%I2clr,");
3460 if (negated)
3461 strcat (buf, "%S3");
3462 else
3463 strcat (buf, "%B3");
3464 if (nullify)
3465 strcat (buf, " %2,%1,0\n\tbl,n %0,0");
3466 else
3467 strcat (buf, " %2,%1,0\n\tbl %0,0");
3468 }
0d986529 3469 break;
3470
3471 default:
3472 abort();
5fbd5940 3473 }
0d986529 3474 return buf;
3475}
3476
6d36483b 3477/* This routine handles all the branch-on-bit conditional branch sequences we
0d986529 3478 might need to generate. It handles nullification of delay slots,
3479 varying length branches, negated branches and all combinations of the
3480 above. it returns the appropriate output template to emit the branch. */
3481
3482char *
3483output_bb (operands, nullify, length, negated, insn, which)
3484 rtx *operands;
3485 int nullify, length, negated;
3486 rtx insn;
3487 int which;
29a4502c 3488{
0d986529 3489 static char buf[100];
3490 int useskip = 0;
3491
29a4502c 3492 /* A conditional branch to the following instruction (eg the delay slot) is
3493 asking for a disaster. I do not think this can happen as this pattern
6d36483b 3494 is only used when optimizing; jump optimization should eliminate the
29a4502c 3495 jump. But be prepared just in case. */
6d36483b 3496
29a4502c 3497 if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
3498 return "";
6d36483b 3499
5fbd5940 3500 /* If this is a long branch with its delay slot unfilled, set `nullify'
3501 as it can nullify the delay slot and save a nop. */
5a1231ef 3502 if (length == 8 && dbr_sequence_length () == 0)
5fbd5940 3503 nullify = 1;
3504
3505 /* If this is a short forward conditional branch which did not get
3506 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 3507 if (! nullify && length == 4 && dbr_sequence_length () == 0)
5fbd5940 3508 nullify = forward_branch_p (insn);
3509
6d36483b 3510 /* A forward branch over a single nullified insn can be done with a
0d986529 3511 extrs instruction. This avoids a single cycle penalty due to
3512 mis-predicted branch if we fall through (branch not taken). */
3513
5a1231ef 3514 if (length == 4
5fbd5940 3515 && next_real_insn (insn) != 0
5a1231ef 3516 && get_attr_length (next_real_insn (insn)) == 4
5fbd5940 3517 && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
0d986529 3518 && nullify)
3519 useskip = 1;
3520
3521 switch (length)
3522 {
3523
5fbd5940 3524 /* All short conditional branches except backwards with an unfilled
3525 delay slot. */
5a1231ef 3526 case 4:
0d986529 3527 if (useskip)
3528 strcpy (buf, "extrs,");
6d36483b 3529 else
0d986529 3530 strcpy (buf, "bb,");
3531 if ((which == 0 && negated)
3532 || (which == 1 && ! negated))
3533 strcat (buf, ">=");
3534 else
3535 strcat (buf, "<");
3536 if (useskip)
3537 strcat (buf, " %0,%1,1,0");
3538 else if (nullify && negated)
3539 strcat (buf, ",n %0,%1,%3");
3540 else if (nullify && ! negated)
3541 strcat (buf, ",n %0,%1,%2");
3542 else if (! nullify && negated)
5fbd5940 3543 strcat (buf, "%0,%1,%3");
0d986529 3544 else if (! nullify && ! negated)
5fbd5940 3545 strcat (buf, " %0,%1,%2");
0d986529 3546 break;
3547
6d36483b 3548 /* All long conditionals. Note an short backward branch with an
5fbd5940 3549 unfilled delay slot is treated just like a long backward branch
3550 with an unfilled delay slot. */
5a1231ef 3551 case 8:
5fbd5940 3552 /* Handle weird backwards branch with a filled delay slot
3553 with is nullified. */
3554 if (dbr_sequence_length () != 0
3555 && ! forward_branch_p (insn)
3556 && nullify)
3557 {
3558 strcpy (buf, "bb,");
3559 if ((which == 0 && negated)
3560 || (which == 1 && ! negated))
3561 strcat (buf, "<");
3562 else
3563 strcat (buf, ">=");
3564 if (negated)
3565 strcat (buf, " %0,%1,.+12\n\tbl %3,0");
3566 else
3567 strcat (buf, " %0,%1,.+12\n\tbl %2,0");
3568 }
43f0c1f2 3569 /* Handle short backwards branch with an unfilled delay slot.
3570 Using a bb;nop rather than extrs;bl saves 1 cycle for both
3571 taken and untaken branches. */
3572 else if (dbr_sequence_length () == 0
3573 && ! forward_branch_p (insn)
3574 && insn_addresses
3575 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
3576 - insn_addresses[INSN_UID (insn)]))
3577 {
3578 strcpy (buf, "bb,");
3579 if ((which == 0 && negated)
3580 || (which == 1 && ! negated))
3581 strcat (buf, ">=");
3582 else
3583 strcat (buf, "<");
3584 if (negated)
3585 strcat (buf, " %0,%1,%3%#");
3586 else
3587 strcat (buf, " %0,%1,%2%#");
3588 }
0d986529 3589 else
5fbd5940 3590 {
3591 strcpy (buf, "extrs,");
3592 if ((which == 0 && negated)
3593 || (which == 1 && ! negated))
3594 strcat (buf, "<");
3595 else
3596 strcat (buf, ">=");
3597 if (nullify && negated)
3598 strcat (buf, " %0,%1,1,0\n\tbl,n %3,0");
3599 else if (nullify && ! negated)
3600 strcat (buf, " %0,%1,1,0\n\tbl,n %2,0");
3601 else if (negated)
3602 strcat (buf, " %0,%1,1,0\n\tbl %3,0");
6d36483b 3603 else
5fbd5940 3604 strcat (buf, " %0,%1,1,0\n\tbl %2,0");
3605 }
0d986529 3606 break;
3607
3608 default:
3609 abort();
5fbd5940 3610 }
0d986529 3611 return buf;
3612}
3613
29a4502c 3614/* Return the output template for emitting a dbra type insn.
3615
3616 Note it may perform some output operations on its own before
3617 returning the final output string. */
3618char *
3619output_dbra (operands, insn, which_alternative)
3620 rtx *operands;
3621 rtx insn;
3622 int which_alternative;
3623{
3624
3625 /* A conditional branch to the following instruction (eg the delay slot) is
3626 asking for a disaster. Be prepared! */
3627
3628 if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
3629 {
3630 if (which_alternative == 0)
3631 return "ldo %1(%0),%0";
3632 else if (which_alternative == 1)
3633 {
3634 output_asm_insn ("fstws %0,-16(0,%%r30)",operands);
3635 output_asm_insn ("ldw -16(0,%%r30),%4",operands);
3636 output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands);
3637 return "fldws -16(0,%%r30),%0";
3638 }
3639 else
3640 {
3641 output_asm_insn ("ldw %0,%4", operands);
3642 return "ldo %1(%4),%4\n\tstw %4,%0";
3643 }
3644 }
3645
3646 if (which_alternative == 0)
3647 {
3648 int nullify = INSN_ANNULLED_BRANCH_P (insn);
3649 int length = get_attr_length (insn);
3650
3651 /* If this is a long branch with its delay slot unfilled, set `nullify'
3652 as it can nullify the delay slot and save a nop. */
5a1231ef 3653 if (length == 8 && dbr_sequence_length () == 0)
29a4502c 3654 nullify = 1;
3655
3656 /* If this is a short forward conditional branch which did not get
3657 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 3658 if (! nullify && length == 4 && dbr_sequence_length () == 0)
29a4502c 3659 nullify = forward_branch_p (insn);
3660
3661 /* Handle short versions first. */
5a1231ef 3662 if (length == 4 && nullify)
29a4502c 3663 return "addib,%C2,n %1,%0,%3";
5a1231ef 3664 else if (length == 4 && ! nullify)
29a4502c 3665 return "addib,%C2 %1,%0,%3";
5a1231ef 3666 else if (length == 8)
29a4502c 3667 {
6d36483b 3668 /* Handle weird backwards branch with a fulled delay slot
29a4502c 3669 which is nullified. */
3670 if (dbr_sequence_length () != 0
3671 && ! forward_branch_p (insn)
3672 && nullify)
3673 return "addib,%N2,n %1,%0,.+12\n\tbl %3,0";
43f0c1f2 3674 /* Handle short backwards branch with an unfilled delay slot.
3675 Using a addb;nop rather than addi;bl saves 1 cycle for both
3676 taken and untaken branches. */
3677 else if (dbr_sequence_length () == 0
3678 && ! forward_branch_p (insn)
3679 && insn_addresses
3680 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
3681 - insn_addresses[INSN_UID (insn)]))
3682 return "addib,%C2 %1,%0,%3%#";
6d36483b 3683
3684 /* Handle normal cases. */
29a4502c 3685 if (nullify)
3686 return "addi,%N2 %1,%0,%0\n\tbl,n %3,0";
3687 else
3688 return "addi,%N2 %1,%0,%0\n\tbl %3,0";
3689 }
3690 else
3691 abort();
3692 }
3693 /* Deal with gross reload from FP register case. */
3694 else if (which_alternative == 1)
3695 {
3696 /* Move loop counter from FP register to MEM then into a GR,
3697 increment the GR, store the GR into MEM, and finally reload
6d36483b 3698 the FP register from MEM from within the branch's delay slot. */
29a4502c 3699 output_asm_insn ("fstws %0,-16(0,%%r30)\n\tldw -16(0,%%r30),%4",operands);
3700 output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands);
5a1231ef 3701 if (get_attr_length (insn) == 24)
29a4502c 3702 return "comb,%S2 0,%4,%3\n\tfldws -16(0,%%r30),%0";
3703 else
3704 return "comclr,%B2 0,%4,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0";
3705 }
3706 /* Deal with gross reload from memory case. */
3707 else
3708 {
3709 /* Reload loop counter from memory, the store back to memory
3710 happens in the branch's delay slot. */
3711 output_asm_insn ("ldw %0,%4", operands);
5a1231ef 3712 if (get_attr_length (insn) == 12)
29a4502c 3713 return "addib,%C2 %1,%4,%3\n\tstw %4,%0";
3714 else
b42d4c50 3715 return "addi,%N2 %1,%4,%4\n\tbl %3,0\n\tstw %4,%0";
29a4502c 3716 }
3717}
3718
3719/* Return the output template for emitting a dbra type insn.
3720
3721 Note it may perform some output operations on its own before
3722 returning the final output string. */
3723char *
3724output_movb (operands, insn, which_alternative, reverse_comparison)
3725 rtx *operands;
3726 rtx insn;
3727 int which_alternative;
3728 int reverse_comparison;
3729{
3730
3731 /* A conditional branch to the following instruction (eg the delay slot) is
3732 asking for a disaster. Be prepared! */
3733
3734 if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
3735 {
3736 if (which_alternative == 0)
3737 return "copy %1,%0";
3738 else if (which_alternative == 1)
3739 {
b4437664 3740 output_asm_insn ("stw %1,-16(0,%%r30)",operands);
29a4502c 3741 return "fldws -16(0,%%r30),%0";
3742 }
3743 else
3744 return "stw %1,%0";
3745 }
3746
3747 /* Support the second variant. */
3748 if (reverse_comparison)
3749 PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
3750
3751 if (which_alternative == 0)
3752 {
3753 int nullify = INSN_ANNULLED_BRANCH_P (insn);
3754 int length = get_attr_length (insn);
3755
3756 /* If this is a long branch with its delay slot unfilled, set `nullify'
3757 as it can nullify the delay slot and save a nop. */
5a1231ef 3758 if (length == 8 && dbr_sequence_length () == 0)
29a4502c 3759 nullify = 1;
3760
3761 /* If this is a short forward conditional branch which did not get
3762 its delay slot filled, the delay slot can still be nullified. */
5a1231ef 3763 if (! nullify && length == 4 && dbr_sequence_length () == 0)
29a4502c 3764 nullify = forward_branch_p (insn);
3765
3766 /* Handle short versions first. */
5a1231ef 3767 if (length == 4 && nullify)
29a4502c 3768 return "movb,%C2,n %1,%0,%3";
5a1231ef 3769 else if (length == 4 && ! nullify)
29a4502c 3770 return "movb,%C2 %1,%0,%3";
5a1231ef 3771 else if (length == 8)
29a4502c 3772 {
6d36483b 3773 /* Handle weird backwards branch with a filled delay slot
29a4502c 3774 which is nullified. */
3775 if (dbr_sequence_length () != 0
3776 && ! forward_branch_p (insn)
3777 && nullify)
eb4a3ec3 3778 return "movb,%N2,n %1,%0,.+12\n\tbl %3,0";
6d36483b 3779
43f0c1f2 3780 /* Handle short backwards branch with an unfilled delay slot.
3781 Using a movb;nop rather than or;bl saves 1 cycle for both
3782 taken and untaken branches. */
3783 else if (dbr_sequence_length () == 0
3784 && ! forward_branch_p (insn)
3785 && insn_addresses
3786 && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
3787 - insn_addresses[INSN_UID (insn)]))
3788 return "movb,%C2 %1,%0,%3%#";
6d36483b 3789 /* Handle normal cases. */
29a4502c 3790 if (nullify)
3791 return "or,%N2 %1,%%r0,%0\n\tbl,n %3,0";
3792 else
3793 return "or,%N2 %1,%%r0,%0\n\tbl %3,0";
3794 }
3795 else
3796 abort();
3797 }
3798 /* Deal with gross reload from FP register case. */
3799 else if (which_alternative == 1)
3800 {
3801 /* Move loop counter from FP register to MEM then into a GR,
3802 increment the GR, store the GR into MEM, and finally reload
6d36483b 3803 the FP register from MEM from within the branch's delay slot. */
b4437664 3804 output_asm_insn ("stw %1,-16(0,%%r30)",operands);
5a1231ef 3805 if (get_attr_length (insn) == 12)
29a4502c 3806 return "comb,%S2 0,%1,%3\n\tfldws -16(0,%%r30),%0";
3807 else
3808 return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0";
3809 }
3810 /* Deal with gross reload from memory case. */
3811 else
3812 {
3813 /* Reload loop counter from memory, the store back to memory
3814 happens in the branch's delay slot. */
5a1231ef 3815 if (get_attr_length (insn) == 8)
29a4502c 3816 return "comb,%S2 0,%1,%3\n\tstw %1,%0";
3817 else
3818 return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tstw %1,%0";
3819 }
3820}
3821
3822
d6686e21 3823/* INSN is either a function call or a millicode call. It may have an
6d36483b 3824 unconditional jump in its delay slot.
d6686e21 3825
3826 CALL_DEST is the routine we are calling.
3827
3828 RETURN_POINTER is the register which will hold the return address.
3683f840 3829 %r2 for most calls, %r31 for millicode calls.
3830
06ddb6f8 3831 When TARGET_MILLICODE_LONG_CALLS is true, then we have to assume
3832 that two instruction sequences must be used to reach the millicode
3833 routines (including dyncall!). */
3683f840 3834
d6686e21 3835char *
3836output_call (insn, call_dest, return_pointer)
3837 rtx insn;
3838 rtx call_dest;
3839 rtx return_pointer;
3840
3841{
3842 int distance;
3843 rtx xoperands[4];
3844 rtx seq_insn;
3845
06ddb6f8 3846 /* Handle long millicode calls for mod, div, and mul. */
3847 if (TARGET_PORTABLE_RUNTIME
3848 || (TARGET_MILLICODE_LONG_CALLS && REGNO (return_pointer) == 31))
3849 {
3850 xoperands[0] = call_dest;
3851 xoperands[1] = return_pointer;
3852 output_asm_insn ("ldil L%%%0,%%r29", xoperands);
3853 output_asm_insn ("ldo R%%%0(%%r29),%%r29", xoperands);
3854 output_asm_insn ("blr 0,%r1\n\tbv,n 0(%%r29)\n\tnop", xoperands);
3855 return "";
3856 }
3857
3858 /* Handle common case -- empty delay slot or no jump in the delay slot,
3859 and we're sure that the branch will reach the beginning of the $CODE$
3860 subspace. */
3861 if ((dbr_sequence_length () == 0
3862 && get_attr_length (insn) == 8)
6d36483b 3863 || (dbr_sequence_length () != 0
06ddb6f8 3864 && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN
3865 && get_attr_length (insn) == 4))
d6686e21 3866 {
3867 xoperands[0] = call_dest;
3868 xoperands[1] = return_pointer;
06ddb6f8 3869 output_asm_insn ("bl %0,%r1%#", xoperands);
3870 return "";
3871 }
3872
3873 /* This call may not reach the beginning of the $CODE$ subspace. */
3874 if (get_attr_length (insn) > 8)
3875 {
3876 int delay_insn_deleted = 0;
3877 rtx xoperands[2];
3878 rtx link;
3879
3880 /* We need to emit an inline long-call branch. Furthermore,
3881 because we're changing a named function call into an indirect
3882 function call well after the parameters have been set up, we
3883 need to make sure any FP args appear in both the integer
3884 and FP registers. Also, we need move any delay slot insn
3885 out of the delay slot -- Yuk! */
3886 if (dbr_sequence_length () != 0
3887 && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN)
3683f840 3888 {
06ddb6f8 3889 /* A non-jump insn in the delay slot. By definition we can
3890 emit this insn before the call (and in fact before argument
3891 relocating. */
3892 final_scan_insn (NEXT_INSN (insn), asm_out_file, optimize, 0, 0);
3893
3894 /* Now delete the delay insn. */
3895 PUT_CODE (NEXT_INSN (insn), NOTE);
3896 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
3897 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
3898 delay_insn_deleted = 1;
3899 }
3900
3901 /* Now copy any FP arguments into integer registers. */
3902 for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
3903 {
3904 int arg_mode, regno;
3905 rtx use = XEXP (link, 0);
3906 if (! (GET_CODE (use) == USE
3907 && GET_CODE (XEXP (use, 0)) == REG
3908 && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
3909 continue;
3910
3911 arg_mode = GET_MODE (XEXP (use, 0));
3912 regno = REGNO (XEXP (use, 0));
3913 /* Is it a floating point register? */
3914 if (regno >= 32 && regno <= 39)
3915 {
3916 /* Copy from the FP register into an integer register
3917 (via memory). */
3918 if (arg_mode == SFmode)
3919 {
3920 xoperands[0] = XEXP (use, 0);
3921 xoperands[1] = gen_rtx (REG, SImode, 26 - (regno - 32) / 2);
3922 output_asm_insn ("fstws %0,-16(%%sr0,%%r30)", xoperands);
3923 output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
3924 }
3925 else
3926 {
3927 xoperands[0] = XEXP (use, 0);
3928 xoperands[1] = gen_rtx (REG, DImode, 25 - (regno - 34) / 2);
3929 output_asm_insn ("fstds %0,-16(%%sr0,%%r30)", xoperands);
3930 output_asm_insn ("ldw -12(%%sr0,%%r30),%R1", xoperands);
3931 output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
3932 }
3933
3934 }
3935 }
3936
3937 /* Now emit the inline long-call. */
3938 xoperands[0] = call_dest;
7b42e7f8 3939 output_asm_insn ("ldil LP%%%0,%%r22\n\tldo RP%%%0(%%r22),%%r22",
3940 xoperands);
06ddb6f8 3941
3942 /* If TARGET_MILLICODE_LONG_CALLS, then we must use a long-call sequence
3943 to call dyncall! */
3944 if (TARGET_MILLICODE_LONG_CALLS)
3945 {
3946 output_asm_insn ("ldil L%%$$dyncall,%%r31", xoperands);
3947 output_asm_insn ("ldo R%%$$dyncall(%%r31),%%r31", xoperands);
3948 output_asm_insn ("blr 0,%%r2\n\tbv,n 0(%%r31)\n\tnop", xoperands);
3683f840 3949 }
3950 else
06ddb6f8 3951 output_asm_insn ("bl $$dyncall,%%r31\n\tcopy %%r31,%%r2", xoperands);
3952
3953 /* If we had a jump in the call's delay slot, output it now. */
3954 if (dbr_sequence_length () != 0
3955 && !delay_insn_deleted)
3956 {
3957 xoperands[0] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
3958 output_asm_insn ("b,n %0", xoperands);
3959
3960 /* Now delete the delay insn. */
3961 PUT_CODE (NEXT_INSN (insn), NOTE);
3962 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
3963 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
3964 }
d6686e21 3965 return "";
3966 }
6d36483b 3967
d6686e21 3968 /* This call has an unconditional jump in its delay slot. */
3969
3970 /* Use the containing sequence insn's address. */
3971 seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
3972
6d36483b 3973 distance = insn_addresses[INSN_UID (JUMP_LABEL (NEXT_INSN (insn)))]
d6686e21 3974 - insn_addresses[INSN_UID (seq_insn)] - 8;
3975
3976 /* If the branch was too far away, emit a normal call followed
3977 by a nop, followed by the unconditional branch.
3978
6d36483b 3979 If the branch is close, then adjust %r2 from within the
d6686e21 3980 call's delay slot. */
3981
3982 xoperands[0] = call_dest;
3983 xoperands[1] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
3984 xoperands[2] = return_pointer;
3985 if (! VAL_14_BITS_P (distance))
3986 output_asm_insn ("bl %0,%r2\n\tnop\n\tbl,n %1,%%r0", xoperands);
3987 else
3988 {
3989 xoperands[3] = gen_label_rtx ();
2a033928 3990 output_asm_insn ("\n\tbl %0,%r2\n\tldo %1-%3(%r2),%r2", xoperands);
6d36483b 3991 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
0410a74e 3992 CODE_LABEL_NUMBER (xoperands[3]));
d6686e21 3993 }
3994
3995 /* Delete the jump. */
3996 PUT_CODE (NEXT_INSN (insn), NOTE);
3997 NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
3998 NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
3999 return "";
4000}
4001
d6f01525 4002extern struct obstack *saveable_obstack;
4003
4004/* In HPUX 8.0's shared library scheme, special relocations are needed
6d36483b 4005 for function labels if they might be passed to a function
d6f01525 4006 in a shared library (because shared libraries don't live in code
4007 space), and special magic is needed to construct their address. */
4008
4009void
4010hppa_encode_label (sym)
4011 rtx sym;
4012{
4013 char *str = XSTR (sym, 0);
4014 int len = strlen (str);
4015 char *newstr = obstack_alloc (saveable_obstack, len + 2) ;
4016
c1b3411e 4017 if (str[0] == '*')
4018 *newstr++ = *str++;
d6f01525 4019 strcpy (newstr + 1, str);
c1b3411e 4020 *newstr = '@';
d6f01525 4021 XSTR (sym,0) = newstr;
4022}
6d36483b 4023
d6f01525 4024int
166bf021 4025function_label_operand (op, mode)
d6f01525 4026 rtx op;
4027 enum machine_mode mode;
4028{
c1b3411e 4029 return GET_CODE (op) == SYMBOL_REF && FUNCTION_NAME_P (XSTR (op, 0));
d6f01525 4030}
f33e3942 4031
166bf021 4032/* Returns 1 if OP is a function label involved in a simple addition
4033 with a constant. Used to keep certain patterns from matching
4034 during instruction combination. */
4035int
4036is_function_label_plus_const (op)
4037 rtx op;
4038{
4039 /* Strip off any CONST. */
4040 if (GET_CODE (op) == CONST)
4041 op = XEXP (op, 0);
4042
4043 return (GET_CODE (op) == PLUS
4044 && function_label_operand (XEXP (op, 0), Pmode)
4045 && GET_CODE (XEXP (op, 1)) == CONST_INT);
4046}
4047
37580c80 4048/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
4049 use in fmpyadd instructions. */
4ed6ee50 4050int
df0651dc 4051fmpyaddoperands (operands)
4ed6ee50 4052 rtx *operands;
4053{
201f01e9 4054 enum machine_mode mode = GET_MODE (operands[0]);
4ed6ee50 4055
4056 /* All modes must be the same. */
201f01e9 4057 if (! (mode == GET_MODE (operands[1])
4058 && mode == GET_MODE (operands[2])
4059 && mode == GET_MODE (operands[3])
4060 && mode == GET_MODE (operands[4])
4061 && mode == GET_MODE (operands[5])))
4ed6ee50 4062 return 0;
4063
4064 /* Both DFmode and SFmode should work. But using SFmode makes the
4065 assembler complain. Just turn it off for now. */
201f01e9 4066 if (mode != DFmode)
4ed6ee50 4067 return 0;
4068
37580c80 4069 /* Only 2 real operands to the addition. One of the input operands must
4070 be the same as the output operand. */
4ed6ee50 4071 if (! rtx_equal_p (operands[3], operands[4])
4072 && ! rtx_equal_p (operands[3], operands[5]))
4073 return 0;
4074
4075 /* Inout operand of add can not conflict with any operands from multiply. */
4076 if (rtx_equal_p (operands[3], operands[0])
4077 || rtx_equal_p (operands[3], operands[1])
4078 || rtx_equal_p (operands[3], operands[2]))
4079 return 0;
4080
4081 /* multiply can not feed into addition operands. */
4082 if (rtx_equal_p (operands[4], operands[0])
4083 || rtx_equal_p (operands[5], operands[0]))
4084 return 0;
4085
4ed6ee50 4086 /* Passed. Operands are suitable for fmpyadd. */
4087 return 1;
4088}
4089
37580c80 4090/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
4091 use in fmpysub instructions. */
4ed6ee50 4092int
df0651dc 4093fmpysuboperands (operands)
4ed6ee50 4094 rtx *operands;
4095{
201f01e9 4096 enum machine_mode mode = GET_MODE (operands[0]);
4ed6ee50 4097
4098 /* All modes must be the same. */
201f01e9 4099 if (! (mode == GET_MODE (operands[1])
4100 && mode == GET_MODE (operands[2])
4101 && mode == GET_MODE (operands[3])
4102 && mode == GET_MODE (operands[4])
4103 && mode == GET_MODE (operands[5])))
4ed6ee50 4104 return 0;
4105
4106 /* Both DFmode and SFmode should work. But using SFmode makes the
4107 assembler complain. Just turn it off for now. */
201f01e9 4108 if (mode != DFmode)
4ed6ee50 4109 return 0;
4110
37580c80 4111 /* Only 2 real operands to the subtraction. Subtraction is not a commutative
4112 operation, so operands[4] must be the same as operand[3]. */
4ed6ee50 4113 if (! rtx_equal_p (operands[3], operands[4]))
4114 return 0;
4115
4116 /* multiply can not feed into subtraction. */
37580c80 4117 if (rtx_equal_p (operands[5], operands[0]))
4ed6ee50 4118 return 0;
4119
37580c80 4120 /* Inout operand of sub can not conflict with any operands from multiply. */
4ed6ee50 4121 if (rtx_equal_p (operands[3], operands[0])
4122 || rtx_equal_p (operands[3], operands[1])
4123 || rtx_equal_p (operands[3], operands[2]))
4124 return 0;
4125
4126 /* Passed. Operands are suitable for fmpysub. */
4127 return 1;
4128}
4129
89f29d73 4130int
4131plus_xor_ior_operator (op, mode)
4132 rtx op;
4133 enum machine_mode mode;
4134{
4135 return (GET_CODE (op) == PLUS || GET_CODE (op) == XOR
4136 || GET_CODE (op) == IOR);
4137}
6720f95e 4138
4139/* Return 1 if the given constant is 2, 4, or 8. These are the valid
4140 constants for shadd instructions. */
4141int
4142shadd_constant_p (val)
4143 int val;
4144{
4145 if (val == 2 || val == 4 || val == 8)
4146 return 1;
4147 else
4148 return 0;
4149}
3a16146d 4150
4151/* Return 1 if OP is a CONST_INT with the value 2, 4, or 8. These are
4152 the valid constant for shadd instructions. */
4153int
4154shadd_operand (op, mode)
4155 rtx op;
4156 enum machine_mode mode;
4157{
4158 return (GET_CODE (op) == CONST_INT && shadd_constant_p (INTVAL (op)));
4159}
5fbd5940 4160
51987f90 4161/* Return 1 if this operand is anything other than a hard register. */
4162
4163int
4164non_hard_reg_operand (op, mode)
4165 rtx op;
4166 enum machine_mode mode;
4167{
4168 return ! (GET_CODE (op) == REG && REGNO (op) < FIRST_PSEUDO_REGISTER);
4169}
4170
5fbd5940 4171/* Return 1 if INSN branches forward. Should be using insn_addresses
4172 to avoid walking through all the insns... */
4173int
4174forward_branch_p (insn)
4175 rtx insn;
4176{
4177 rtx label = JUMP_LABEL (insn);
4178
4179 while (insn)
4180 {
4181 if (insn == label)
4182 break;
4183 else
4184 insn = NEXT_INSN (insn);
4185 }
4186
4187 return (insn == label);
4188}
4189
29a4502c 4190/* Return 1 if OP is an equality comparison, else return 0. */
4191int
4192eq_neq_comparison_operator (op, mode)
4193 rtx op;
4194 enum machine_mode mode;
4195{
4196 return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
4197}
4198
4199/* Return 1 if OP is an operator suitable for use in a movb instruction. */
4200int
4201movb_comparison_operator (op, mode)
4202 rtx op;
4203 enum machine_mode mode;
4204{
4205 return (GET_CODE (op) == EQ || GET_CODE (op) == NE
4206 || GET_CODE (op) == LT || GET_CODE (op) == GE);
4207}
4208
d6686e21 4209/* Return 1 if INSN is in the delay slot of a call instruction. */
4210int
4211jump_in_call_delay (insn)
4212 rtx insn;
4213{
4214
4215 if (GET_CODE (insn) != JUMP_INSN)
4216 return 0;
4217
4218 if (PREV_INSN (insn)
4219 && PREV_INSN (PREV_INSN (insn))
4220 && GET_CODE (next_active_insn (PREV_INSN (PREV_INSN (insn)))) == INSN)
4221 {
4222 rtx test_insn = next_active_insn (PREV_INSN (PREV_INSN (insn)));
4223
4224 return (GET_CODE (PATTERN (test_insn)) == SEQUENCE
4225 && XVECEXP (PATTERN (test_insn), 0, 1) == insn);
4226
4227 }
4228 else
4229 return 0;
4230}