OSDN Git Service

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