home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / config / pa / pa.c < prev    next >
C/C++ Source or Header  |  1996-06-12  |  139KB  |  4,932 lines

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