home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / gcc-2.4.5 / config / pa / pa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-03  |  91.2 KB  |  3,511 lines

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