home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gcc-2.7.2.1-base.tgz / gcc-2.7.2.1-base.tar / fsf / gcc / config / i860 / i860.c < prev    next >
C/C++ Source or Header  |  1995-06-15  |  63KB  |  2,098 lines

  1. /* Subroutines for insn-output.c for Intel 860
  2.    Copyright (C) 1989, 1991 Free Software Foundation, Inc.
  3.    Derived from sparc.c.
  4.  
  5.    Written by Richard Stallman (rms@ai.mit.edu).
  6.  
  7.    Hacked substantially by Ron Guilmette (rfg@netcom.com) to cater
  8.    to the whims of the System V Release 4 assembler.
  9.  
  10. This file is part of GNU CC.
  11.  
  12. GNU CC is free software; you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation; either version 2, or (at your option)
  15. any later version.
  16.  
  17. GNU CC is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. GNU General Public License for more details.
  21.  
  22. You should have received a copy of the GNU General Public License
  23. along with GNU CC; see the file COPYING.  If not, write to
  24. the Free Software Foundation, 59 Temple Place - Suite 330,
  25. Boston, MA 02111-1307, USA.  */
  26.  
  27.  
  28. #include "config.h"
  29. #include "flags.h"
  30. #include "rtl.h"
  31. #include "regs.h"
  32. #include "hard-reg-set.h"
  33. #include "real.h"
  34. #include "insn-config.h"
  35. #include "conditions.h"
  36. #include "insn-flags.h"
  37. #include "output.h"
  38. #include "recog.h"
  39. #include "insn-attr.h"
  40.  
  41. #include <stdio.h>
  42.  
  43. static rtx find_addr_reg ();
  44.  
  45. #ifndef I860_REG_PREFIX
  46. #define I860_REG_PREFIX ""
  47. #endif
  48.  
  49. char *i860_reg_prefix = I860_REG_PREFIX;
  50.  
  51. /* Save information from a "cmpxx" operation until the branch is emitted.  */
  52.  
  53. rtx i860_compare_op0, i860_compare_op1;
  54.  
  55. /* Return non-zero if this pattern, can be evaluated safely, even if it
  56.    was not asked for.  */
  57. int
  58. safe_insn_src_p (op, mode)
  59.      rtx op;
  60.      enum machine_mode mode;
  61. {
  62.   /* Just experimenting.  */
  63.  
  64.   /* No floating point src is safe if it contains an arithmetic
  65.      operation, since that operation may trap.  */
  66.   switch (GET_CODE (op))
  67.     {
  68.     case CONST_INT:
  69.     case LABEL_REF:
  70.     case SYMBOL_REF:
  71.     case CONST:
  72.       return 1;
  73.  
  74.     case REG:
  75.       return 1;
  76.  
  77.     case MEM:
  78.       return CONSTANT_ADDRESS_P (XEXP (op, 0));
  79.  
  80.       /* We never need to negate or complement constants.  */
  81.     case NEG:
  82.       return (mode != SFmode && mode != DFmode);
  83.     case NOT:
  84.     case ZERO_EXTEND:
  85.       return 1;
  86.  
  87.     case EQ:
  88.     case NE:
  89.     case LT:
  90.     case GT:
  91.     case LE:
  92.     case GE:
  93.     case LTU:
  94.     case GTU:
  95.     case LEU:
  96.     case GEU:
  97.     case MINUS:
  98.     case PLUS:
  99.       return (mode != SFmode && mode != DFmode);
  100.     case AND:
  101.     case IOR:
  102.     case XOR:
  103.     case ASHIFT:
  104.     case ASHIFTRT:
  105.     case LSHIFTRT:
  106.       if ((GET_CODE (XEXP (op, 0)) == CONST_INT && ! SMALL_INT (XEXP (op, 0)))
  107.       || (GET_CODE (XEXP (op, 1)) == CONST_INT && ! SMALL_INT (XEXP (op, 1))))
  108.     return 0;
  109.       return 1;
  110.  
  111.     default:
  112.       return 0;
  113.     }
  114. }
  115.  
  116. /* Return 1 if REG is clobbered in IN.
  117.    Return 2 if REG is used in IN. 
  118.    Return 3 if REG is both used and clobbered in IN.
  119.    Return 0 if neither.  */
  120.  
  121. static int
  122. reg_clobbered_p (reg, in)
  123.      rtx reg;
  124.      rtx in;
  125. {
  126.   register enum rtx_code code;
  127.  
  128.   if (in == 0)
  129.     return 0;
  130.  
  131.   code = GET_CODE (in);
  132.  
  133.   if (code == SET || code == CLOBBER)
  134.     {
  135.       rtx dest = SET_DEST (in);
  136.       int set = 0;
  137.       int used = 0;
  138.  
  139.       while (GET_CODE (dest) == STRICT_LOW_PART
  140.          || GET_CODE (dest) == SUBREG
  141.          || GET_CODE (dest) == SIGN_EXTRACT
  142.          || GET_CODE (dest) == ZERO_EXTRACT)
  143.     dest = XEXP (dest, 0);
  144.  
  145.       if (dest == reg)
  146.     set = 1;
  147.       else if (GET_CODE (dest) == REG
  148.            && refers_to_regno_p (REGNO (reg),
  149.                      REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
  150.                      SET_DEST (in), 0))
  151.     {
  152.       set = 1;
  153.       /* Anything that sets just part of the register
  154.          is considered using as well as setting it.
  155.          But note that a straight SUBREG of a single-word value
  156.          clobbers the entire value.   */
  157.       if (dest != SET_DEST (in)
  158.           && ! (GET_CODE (SET_DEST (in)) == SUBREG
  159.             || UNITS_PER_WORD >= GET_MODE_SIZE (GET_MODE (dest))))
  160.         used = 1;
  161.     }
  162.  
  163.       if (code == SET)
  164.     {
  165.       if (set)
  166.         used = refers_to_regno_p (REGNO (reg),
  167.                       REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
  168.                       SET_SRC (in), 0);
  169.       else
  170.         used = refers_to_regno_p (REGNO (reg),
  171.                       REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
  172.                       in, 0);
  173.     }
  174.  
  175.       return set + used * 2;
  176.     }
  177.  
  178.   if (refers_to_regno_p (REGNO (reg),
  179.              REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
  180.              in, 0))
  181.     return 2;
  182.   return 0;
  183. }
  184.  
  185. /* Return non-zero if OP can be written to without screwing up
  186.    GCC's model of what's going on.  It is assumed that this operand
  187.    appears in the dest position of a SET insn in a conditional
  188.    branch's delay slot.  AFTER is the label to start looking from.  */
  189. int
  190. operand_clobbered_before_used_after (op, after)
  191.      rtx op;
  192.      rtx after;
  193. {
  194.   /* Just experimenting.  */
  195.   if (GET_CODE (op) == CC0)
  196.     return 1;
  197.   if (GET_CODE (op) == REG)
  198.     {
  199.       rtx insn;
  200.  
  201.       if (op == stack_pointer_rtx)
  202.     return 0;
  203.  
  204.       /* Scan forward from the label, to see if the value of OP
  205.      is clobbered before the first use.  */
  206.  
  207.       for (insn = NEXT_INSN (after); insn; insn = NEXT_INSN (insn))
  208.     {
  209.       if (GET_CODE (insn) == NOTE)
  210.         continue;
  211.       if (GET_CODE (insn) == INSN
  212.           || GET_CODE (insn) == JUMP_INSN
  213.           || GET_CODE (insn) == CALL_INSN)
  214.         {
  215.           switch (reg_clobbered_p (op, PATTERN (insn)))
  216.         {
  217.         default:
  218.           return 0;
  219.         case 1:
  220.           return 1;
  221.         case 0:
  222.           break;
  223.         }
  224.         }
  225.       /* If we reach another label without clobbering OP,
  226.          then we cannot safely write it here.  */
  227.       else if (GET_CODE (insn) == CODE_LABEL)
  228.         return 0;
  229.       if (GET_CODE (insn) == JUMP_INSN)
  230.         {
  231.           if (condjump_p (insn))
  232.         return 0;
  233.           /* This is a jump insn which has already
  234.          been mangled.  We can't tell what it does.  */
  235.           if (GET_CODE (PATTERN (insn)) == PARALLEL)
  236.         return 0;
  237.           if (! JUMP_LABEL (insn))
  238.         return 0;
  239.           /* Keep following jumps.  */
  240.           insn = JUMP_LABEL (insn);
  241.         }
  242.     }
  243.       return 1;
  244.     }
  245.  
  246.   /* In both of these cases, the first insn executed
  247.      for this op will be a orh whatever%h,%?r0,%?r31,
  248.      which is tolerable.  */
  249.   if (GET_CODE (op) == MEM)
  250.     return (CONSTANT_ADDRESS_P (XEXP (op, 0)));
  251.  
  252.   return 0;
  253. }
  254.  
  255. /* Return non-zero if this pattern, as a source to a "SET",
  256.    is known to yield an instruction of unit size.  */
  257. int
  258. single_insn_src_p (op, mode)
  259.      rtx op;
  260.      enum machine_mode mode;
  261. {
  262.   switch (GET_CODE (op))
  263.     {
  264.     case CONST_INT:
  265.       /* This is not always a single insn src, technically,
  266.      but output_delayed_branch knows how to deal with it.  */
  267.       return 1;
  268.  
  269.     case SYMBOL_REF:
  270.     case CONST:
  271.       /* This is not a single insn src, technically,
  272.      but output_delayed_branch knows how to deal with it.  */
  273.       return 1;
  274.  
  275.     case REG:
  276.       return 1;
  277.  
  278.     case MEM:
  279.       return 1;
  280.  
  281.       /* We never need to negate or complement constants.  */
  282.     case NEG:
  283.       return (mode != DFmode);
  284.     case NOT:
  285.     case ZERO_EXTEND:
  286.       return 1;
  287.  
  288.     case PLUS:
  289.     case MINUS:
  290.       /* Detect cases that require multiple instructions.  */
  291.       if (CONSTANT_P (XEXP (op, 1))
  292.       && !(GET_CODE (XEXP (op, 1)) == CONST_INT
  293.            && SMALL_INT (XEXP (op, 1))))
  294.     return 0;
  295.     case EQ:
  296.     case NE:
  297.     case LT:
  298.     case GT:
  299.     case LE:
  300.     case GE:
  301.     case LTU:
  302.     case GTU:
  303.     case LEU:
  304.     case GEU:
  305.       /* Not doing floating point, since they probably
  306.      take longer than the branch slot they might fill.  */
  307.       return (mode != SFmode && mode != DFmode);
  308.  
  309.     case AND:
  310.       if (GET_CODE (XEXP (op, 1)) == NOT)
  311.     {
  312.       rtx arg = XEXP (XEXP (op, 1), 0);
  313.       if (CONSTANT_P (arg)
  314.           && !(GET_CODE (arg) == CONST_INT
  315.            && (SMALL_INT (arg)
  316.                || INTVAL (arg) & 0xffff == 0)))
  317.         return 0;
  318.     }
  319.     case IOR:
  320.     case XOR:
  321.       /* Both small and round numbers take one instruction;
  322.      others take two.  */
  323.       if (CONSTANT_P (XEXP (op, 1))
  324.       && !(GET_CODE (XEXP (op, 1)) == CONST_INT
  325.            && (SMALL_INT (XEXP (op, 1))
  326.            || INTVAL (XEXP (op, 1)) & 0xffff == 0)))
  327.     return 0;
  328.  
  329.     case ASHIFT:
  330.     case ASHIFTRT:
  331.     case LSHIFTRT:
  332.       return 1;
  333.  
  334.     case SUBREG:
  335.       if (SUBREG_WORD (op) != 0)
  336.     return 0;
  337.       return single_insn_src_p (SUBREG_REG (op), mode);
  338.  
  339.       /* Not doing floating point, since they probably
  340.      take longer than the branch slot they might fill.  */
  341.     case FLOAT_EXTEND:
  342.     case FLOAT_TRUNCATE:
  343.     case FLOAT:
  344.     case FIX:
  345.     case UNSIGNED_FLOAT:
  346.     case UNSIGNED_FIX:
  347.       return 0;
  348.  
  349.     default:
  350.       return 0;
  351.     }
  352. }
  353.  
  354. /* Return non-zero only if OP is a register of mode MODE,
  355.    or const0_rtx.  */
  356. int
  357. reg_or_0_operand (op, mode)
  358.      rtx op;
  359.      enum machine_mode mode;
  360. {
  361.   return (op == const0_rtx || register_operand (op, mode)
  362.       || op == CONST0_RTX (mode));
  363. }
  364.  
  365. /* Return truth value of whether OP can be used as an operands in a three
  366.    address add/subtract insn (such as add %o1,7,%l2) of mode MODE.  */
  367.  
  368. int
  369. arith_operand (op, mode)
  370.      rtx op;
  371.      enum machine_mode mode;
  372. {
  373.   return (register_operand (op, mode)
  374.       || (GET_CODE (op) == CONST_INT && SMALL_INT (op)));
  375. }
  376.  
  377. /* Return 1 if OP is a valid first operand for a logical insn of mode MODE.  */
  378.  
  379. int
  380. logic_operand (op, mode)
  381.      rtx op;
  382.      enum machine_mode mode;
  383. {
  384.   return (register_operand (op, mode)
  385.       || (GET_CODE (op) == CONST_INT && LOGIC_INT (op)));
  386. }
  387.  
  388. /* Return 1 if OP is a valid first operand for a shift insn of mode MODE.  */
  389.  
  390. int
  391. shift_operand (op, mode)
  392.      rtx op;
  393.      enum machine_mode mode;
  394. {
  395.   return (register_operand (op, mode)
  396.           || (GET_CODE (op) == CONST_INT));
  397. }
  398.  
  399. /* Return 1 if OP is a valid first operand for either a logical insn
  400.    or an add insn of mode MODE.  */
  401.  
  402. int
  403. compare_operand (op, mode)
  404.      rtx op;
  405.      enum machine_mode mode;
  406. {
  407.   return (register_operand (op, mode)
  408.       || (GET_CODE (op) == CONST_INT && SMALL_INT (op) && LOGIC_INT (op)));
  409. }
  410.  
  411. /* Return truth value of whether OP can be used as the 5-bit immediate
  412.    operand of a bte or btne insn.  */
  413.  
  414. int
  415. bte_operand (op, mode)
  416.      rtx op;
  417.      enum machine_mode mode;
  418. {
  419.   return (register_operand (op, mode)
  420.       || (GET_CODE (op) == CONST_INT
  421.           && (unsigned) INTVAL (op) < 0x20));
  422. }
  423.  
  424. /* Return 1 if OP is an indexed memory reference of mode MODE.  */
  425.  
  426. int
  427. indexed_operand (op, mode)
  428.      rtx op;
  429.      enum machine_mode mode;
  430. {
  431.   return (GET_CODE (op) == MEM && GET_MODE (op) == mode
  432.       && GET_CODE (XEXP (op, 0)) == PLUS
  433.       && GET_MODE (XEXP (op, 0)) == SImode
  434.       && register_operand (XEXP (XEXP (op, 0), 0), SImode)
  435.       && register_operand (XEXP (XEXP (op, 0), 1), SImode));
  436. }
  437.  
  438. /* Return 1 if OP is a suitable source operand for a load insn
  439.    with mode MODE.  */
  440.  
  441. int
  442. load_operand (op, mode)
  443.      rtx op;
  444.      enum machine_mode mode;
  445. {
  446.   return (memory_operand (op, mode) || indexed_operand (op, mode));
  447. }
  448.  
  449. /* Return truth value of whether OP is a integer which fits the
  450.    range constraining immediate operands in add/subtract insns.  */
  451.  
  452. int
  453. small_int (op, mode)
  454.      rtx op;
  455.      enum machine_mode mode;
  456. {
  457.   return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
  458. }
  459.  
  460. /* Return truth value of whether OP is a integer which fits the
  461.    range constraining immediate operands in logic insns.  */
  462.  
  463. int
  464. logic_int (op, mode)
  465.      rtx op;
  466.      enum machine_mode mode;
  467. {
  468.   return (GET_CODE (op) == CONST_INT && LOGIC_INT (op));
  469. }
  470.  
  471. /* Test for a valid operand for a call instruction.
  472.    Don't allow the arg pointer register or virtual regs
  473.    since they may change into reg + const, which the patterns
  474.    can't handle yet.  */
  475.  
  476. int
  477. call_insn_operand (op, mode)
  478.      rtx op;
  479.      enum machine_mode mode;
  480. {
  481.   if (GET_CODE (op) == MEM
  482.       && (CONSTANT_ADDRESS_P (XEXP (op, 0))
  483.       || (GET_CODE (XEXP (op, 0)) == REG
  484.           && XEXP (op, 0) != arg_pointer_rtx
  485.           && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
  486.            && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
  487.     return 1;
  488.   return 0;
  489. }
  490.  
  491. /* Return the best assembler insn template
  492.    for moving operands[1] into operands[0] as a fullword.  */
  493.  
  494. static char *
  495. singlemove_string (operands)
  496.      rtx *operands;
  497. {
  498.   if (GET_CODE (operands[0]) == MEM)
  499.     {
  500.       if (GET_CODE (operands[1]) != MEM)
  501.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  502.       {
  503.         if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
  504.            && (cc_prev_status.flags & CC_HI_R31_ADJ)
  505.            && cc_prev_status.mdep == XEXP (operands[0], 0)))
  506.           {
  507.         CC_STATUS_INIT;
  508.             output_asm_insn ("orh %h0,%?r0,%?r31", operands);
  509.           }
  510.         cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
  511.         cc_status.mdep = XEXP (operands[0], 0);
  512.         return "st.l %r1,%L0(%?r31)";
  513.       }
  514.     else
  515.       return "st.l %r1,%0";
  516.       else
  517.     abort ();
  518. #if 0
  519.     {
  520.       rtx xoperands[2];
  521.  
  522.       cc_status.flags &= ~CC_F0_IS_0;
  523.       xoperands[0] = gen_rtx (REG, SFmode, 32);
  524.       xoperands[1] = operands[1];
  525.       output_asm_insn (singlemove_string (xoperands), xoperands);
  526.       xoperands[1] = xoperands[0];
  527.       xoperands[0] = operands[0];
  528.       output_asm_insn (singlemove_string (xoperands), xoperands);
  529.       return "";
  530.     }
  531. #endif
  532.     }
  533.   if (GET_CODE (operands[1]) == MEM)
  534.     {
  535.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  536.     {
  537.       if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
  538.          && (cc_prev_status.flags & CC_HI_R31_ADJ)
  539.          && cc_prev_status.mdep == XEXP (operands[1], 0)))
  540.         {
  541.           CC_STATUS_INIT;
  542.           output_asm_insn ("orh %h1,%?r0,%?r31", operands);
  543.         }
  544.       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
  545.       cc_status.mdep = XEXP (operands[1], 0);
  546.       return "ld.l %L1(%?r31),%0";
  547.     }
  548.       return "ld.l %m1,%0";
  549.     }
  550.  if (GET_CODE (operands[1]) == CONST_INT)
  551.    {
  552.      if (operands[1] == const0_rtx)
  553.       return "mov %?r0,%0";
  554.      if((INTVAL (operands[1]) & 0xffff0000) == 0)
  555.       return "or %L1,%?r0,%0";
  556.      if((INTVAL (operands[1]) & 0xffff8000) == 0xffff8000)
  557.       return "adds %1,%?r0,%0";
  558.      if((INTVAL (operands[1]) & 0x0000ffff) == 0)
  559.       return "orh %H1,%?r0,%0";
  560.    }
  561.   return "mov %1,%0";
  562. }
  563.  
  564. /* Output assembler code to perform a doubleword move insn
  565.    with operands OPERANDS.  */
  566.  
  567. char *
  568. output_move_double (operands)
  569.      rtx *operands;
  570. {
  571.   enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
  572.   rtx latehalf[2];
  573.   rtx addreg0 = 0, addreg1 = 0;
  574.   int highest_first = 0;
  575.   int no_addreg1_decrement = 0;
  576.  
  577.   /* First classify both operands.  */
  578.  
  579.   if (REG_P (operands[0]))
  580.     optype0 = REGOP;
  581.   else if (offsettable_memref_p (operands[0]))
  582.     optype0 = OFFSOP;
  583.   else if (GET_CODE (operands[0]) == MEM)
  584.     optype0 = MEMOP;
  585.   else
  586.     optype0 = RNDOP;
  587.  
  588.   if (REG_P (operands[1]))
  589.     optype1 = REGOP;
  590.   else if (CONSTANT_P (operands[1]))
  591.     optype1 = CNSTOP;
  592.   else if (offsettable_memref_p (operands[1]))
  593.     optype1 = OFFSOP;
  594.   else if (GET_CODE (operands[1]) == MEM)
  595.     optype1 = MEMOP;
  596.   else
  597.     optype1 = RNDOP;
  598.  
  599.   /* Check for the cases that the operand constraints are not
  600.      supposed to allow to happen.  Abort if we get one,
  601.      because generating code for these cases is painful.  */
  602.  
  603.   if (optype0 == RNDOP || optype1 == RNDOP)
  604.     abort ();
  605.  
  606.   /* If an operand is an unoffsettable memory ref, find a register
  607.      we can increment temporarily to make it refer to the second word.  */
  608.  
  609.   if (optype0 == MEMOP)
  610.     addreg0 = find_addr_reg (XEXP (operands[0], 0));
  611.  
  612.   if (optype1 == MEMOP)
  613.     addreg1 = find_addr_reg (XEXP (operands[1], 0));
  614.  
  615. /* ??? Perhaps in some cases move double words
  616.    if there is a spare pair of floating regs.  */
  617.  
  618.   /* Ok, we can do one word at a time.
  619.      Normally we do the low-numbered word first,
  620.      but if either operand is autodecrementing then we
  621.      do the high-numbered word first.
  622.  
  623.      In either case, set up in LATEHALF the operands to use
  624.      for the high-numbered word and in some cases alter the
  625.      operands in OPERANDS to be suitable for the low-numbered word.  */
  626.  
  627.   if (optype0 == REGOP)
  628.     latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  629.   else if (optype0 == OFFSOP)
  630.     latehalf[0] = adj_offsettable_operand (operands[0], 4);
  631.   else
  632.     latehalf[0] = operands[0];
  633.  
  634.   if (optype1 == REGOP)
  635.     latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
  636.   else if (optype1 == OFFSOP)
  637.     latehalf[1] = adj_offsettable_operand (operands[1], 4);
  638.   else if (optype1 == CNSTOP)
  639.     {
  640.       if (GET_CODE (operands[1]) == CONST_DOUBLE)
  641.     split_double (operands[1], &operands[1], &latehalf[1]);
  642.       else if (CONSTANT_P (operands[1]))
  643.     latehalf[1] = const0_rtx;
  644.     }
  645.   else
  646.     latehalf[1] = operands[1];
  647.  
  648.   /* If the first move would clobber the source of the second one,
  649.      do them in the other order.
  650.  
  651.      RMS says "This happens only for registers;
  652.      such overlap can't happen in memory unless the user explicitly
  653.      sets it up, and that is an undefined circumstance."
  654.  
  655.      but it happens on the sparc when loading parameter registers,
  656.      so I am going to define that circumstance, and make it work
  657.      as expected.  */
  658.  
  659.   if (optype0 == REGOP && optype1 == REGOP
  660.       && REGNO (operands[0]) == REGNO (latehalf[1]))
  661.     {
  662.       CC_STATUS_PARTIAL_INIT;
  663.       /* Make any unoffsettable addresses point at high-numbered word.  */
  664.       if (addreg0)
  665.     output_asm_insn ("adds 0x4,%0,%0", &addreg0);
  666.       if (addreg1)
  667.     output_asm_insn ("adds 0x4,%0,%0", &addreg1);
  668.  
  669.       /* Do that word.  */
  670.       output_asm_insn (singlemove_string (latehalf), latehalf);
  671.  
  672.       /* Undo the adds we just did.  */
  673.       if (addreg0)
  674.     output_asm_insn ("adds -0x4,%0,%0", &addreg0);
  675.       if (addreg1)
  676.     output_asm_insn ("adds -0x4,%0,%0", &addreg1);
  677.  
  678.       /* Do low-numbered word.  */
  679.       return singlemove_string (operands);
  680.     }
  681.   else if (optype0 == REGOP && optype1 != REGOP
  682.        && reg_overlap_mentioned_p (operands[0], operands[1]))
  683.     {
  684.       /* If both halves of dest are used in the src memory address,
  685.      add the two regs and put them in the low reg (operands[0]).
  686.      Then it works to load latehalf first.  */
  687.       if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
  688.       && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
  689.     {
  690.       rtx xops[2];
  691.       xops[0] = latehalf[0];
  692.       xops[1] = operands[0];
  693.       output_asm_insn ("adds %1,%0,%1", xops);
  694.       operands[1] = gen_rtx (MEM, DImode, operands[0]);
  695.       latehalf[1] = adj_offsettable_operand (operands[1], 4);
  696.       addreg1 = 0;
  697.       highest_first = 1;
  698.     }
  699.       /* Only one register in the dest is used in the src memory address,
  700.      and this is the first register of the dest, so we want to do
  701.      the late half first here also.  */
  702.       else if (! reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
  703.     highest_first = 1;
  704.       /* Only one register in the dest is used in the src memory address,
  705.      and this is the second register of the dest, so we want to do
  706.      the late half last.  If addreg1 is set, and addreg1 is the same
  707.      register as latehalf, then we must suppress the trailing decrement,
  708.      because it would clobber the value just loaded.  */
  709.       else if (addreg1 && reg_mentioned_p (addreg1, latehalf[0]))
  710.     no_addreg1_decrement = 1;
  711.     }
  712.  
  713.   /* Normal case: do the two words, low-numbered first.
  714.      Overlap case (highest_first set): do high-numbered word first.  */
  715.  
  716.   if (! highest_first)
  717.     output_asm_insn (singlemove_string (operands), operands);
  718.  
  719.   CC_STATUS_PARTIAL_INIT;
  720.   /* Make any unoffsettable addresses point at high-numbered word.  */
  721.   if (addreg0)
  722.     output_asm_insn ("adds 0x4,%0,%0", &addreg0);
  723.   if (addreg1)
  724.     output_asm_insn ("adds 0x4,%0,%0", &addreg1);
  725.  
  726.   /* Do that word.  */
  727.   output_asm_insn (singlemove_string (latehalf), latehalf);
  728.  
  729.   /* Undo the adds we just did.  */
  730.   if (addreg0)
  731.     output_asm_insn ("adds -0x4,%0,%0", &addreg0);
  732.   if (addreg1 && !no_addreg1_decrement)
  733.     output_asm_insn ("adds -0x4,%0,%0", &addreg1);
  734.  
  735.   if (highest_first)
  736.     output_asm_insn (singlemove_string (operands), operands);
  737.  
  738.   return "";
  739. }
  740.  
  741. char *
  742. output_fp_move_double (operands)
  743.      rtx *operands;
  744. {
  745.   /* If the source operand is any sort of zero, use f0 instead.  */
  746.  
  747.   if (operands[1] == CONST0_RTX (GET_MODE (operands[1])))
  748.     operands[1] = gen_rtx (REG, DFmode, F0_REGNUM);
  749.  
  750.   if (FP_REG_P (operands[0]))
  751.     {
  752.       if (FP_REG_P (operands[1]))
  753.     return "fmov.dd %1,%0";
  754.       if (GET_CODE (operands[1]) == REG)
  755.     {
  756.       output_asm_insn ("ixfr %1,%0", operands);
  757.       operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
  758.       operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
  759.       return "ixfr %1,%0";
  760.     }
  761.       if (operands[1] == CONST0_RTX (DFmode))
  762.     return "fmov.dd f0,%0";
  763.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  764.     {
  765.       if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
  766.          && (cc_prev_status.flags & CC_HI_R31_ADJ)
  767.          && cc_prev_status.mdep == XEXP (operands[1], 0)))
  768.         {
  769.           CC_STATUS_INIT;
  770.           output_asm_insn ("orh %h1,%?r0,%?r31", operands);
  771.         }
  772.       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
  773.       cc_status.mdep = XEXP (operands[1], 0);
  774.       return "fld.d %L1(%?r31),%0";
  775.     }
  776.       return "fld.d %1,%0";
  777.     }
  778.   else if (FP_REG_P (operands[1]))
  779.     {
  780.       if (GET_CODE (operands[0]) == REG)
  781.     {
  782.       output_asm_insn ("fxfr %1,%0", operands);
  783.       operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
  784.       operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
  785.       return "fxfr %1,%0";
  786.     }
  787.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  788.     {
  789.       if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
  790.          && (cc_prev_status.flags & CC_HI_R31_ADJ)
  791.          && cc_prev_status.mdep == XEXP (operands[0], 0)))
  792.         {
  793.           CC_STATUS_INIT;
  794.           output_asm_insn ("orh %h0,%?r0,%?r31", operands);
  795.         }
  796.       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
  797.       cc_status.mdep = XEXP (operands[0], 0);
  798.       return "fst.d %1,%L0(%?r31)";
  799.     }
  800.       return "fst.d %1,%0";
  801.     }
  802.   else
  803.     abort ();
  804.   /* NOTREACHED */
  805.   return NULL;
  806. }
  807.  
  808. /* Return a REG that occurs in ADDR with coefficient 1.
  809.    ADDR can be effectively incremented by incrementing REG.  */
  810.  
  811. static rtx
  812. find_addr_reg (addr)
  813.      rtx addr;
  814. {
  815.   while (GET_CODE (addr) == PLUS)
  816.     {
  817.       if (GET_CODE (XEXP (addr, 0)) == REG)
  818.     addr = XEXP (addr, 0);
  819.       else if (GET_CODE (XEXP (addr, 1)) == REG)
  820.     addr = XEXP (addr, 1);
  821.       else if (CONSTANT_P (XEXP (addr, 0)))
  822.     addr = XEXP (addr, 1);
  823.       else if (CONSTANT_P (XEXP (addr, 1)))
  824.     addr = XEXP (addr, 0);
  825.       else
  826.     abort ();
  827.     }
  828.   if (GET_CODE (addr) == REG)
  829.     return addr;
  830.   abort ();
  831.   /* NOTREACHED */
  832.   return NULL;
  833. }
  834.  
  835. /* Return a template for a load instruction with mode MODE and
  836.    arguments from the string ARGS.
  837.  
  838.    This string is in static storage.   */
  839.  
  840. static char *
  841. load_opcode (mode, args, reg)
  842.      enum machine_mode mode;
  843.      char *args;
  844.      rtx reg;
  845. {
  846.   static char buf[30];
  847.   char *opcode;
  848.  
  849.   switch (mode)
  850.     {
  851.     case QImode:
  852.       opcode = "ld.b";
  853.       break;
  854.  
  855.     case HImode:
  856.       opcode = "ld.s";
  857.       break;
  858.  
  859.     case SImode:
  860.     case SFmode:
  861.       if (FP_REG_P (reg))
  862.     opcode = "fld.l";
  863.       else
  864.     opcode = "ld.l";
  865.       break;
  866.  
  867.     case DImode:
  868.       if (!FP_REG_P (reg))
  869.     abort ();
  870.     case DFmode:
  871.       opcode = "fld.d";
  872.       break;
  873.  
  874.     default:
  875.       abort ();
  876.     }
  877.  
  878.   sprintf (buf, "%s %s", opcode, args);
  879.   return buf;
  880. }
  881.  
  882. /* Return a template for a store instruction with mode MODE and
  883.    arguments from the string ARGS.
  884.  
  885.    This string is in static storage.   */
  886.  
  887. static char *
  888. store_opcode (mode, args, reg)
  889.      enum machine_mode mode;
  890.      char *args;
  891.      rtx reg;
  892. {
  893.   static char buf[30];
  894.   char *opcode;
  895.  
  896.   switch (mode)
  897.     {
  898.     case QImode:
  899.       opcode = "st.b";
  900.       break;
  901.  
  902.     case HImode:
  903.       opcode = "st.s";
  904.       break;
  905.  
  906.     case SImode:
  907.     case SFmode:
  908.       if (FP_REG_P (reg))
  909.     opcode = "fst.l";
  910.       else
  911.     opcode = "st.l";
  912.       break;
  913.  
  914.     case DImode:
  915.       if (!FP_REG_P (reg))
  916.     abort ();
  917.     case DFmode:
  918.       opcode = "fst.d";
  919.       break;
  920.  
  921.     default:
  922.       abort ();
  923.     }
  924.  
  925.   sprintf (buf, "%s %s", opcode, args);
  926.   return buf;
  927. }
  928.  
  929. /* Output a store-in-memory whose operands are OPERANDS[0,1].
  930.    OPERANDS[0] is a MEM, and OPERANDS[1] is a reg or zero.
  931.  
  932.    This function returns a template for an insn.
  933.    This is in static storage.
  934.  
  935.    It may also output some insns directly.
  936.    It may alter the values of operands[0] and operands[1].  */
  937.  
  938. char *
  939. output_store (operands)
  940.      rtx *operands;
  941. {
  942.   enum machine_mode mode = GET_MODE (operands[0]);
  943.   rtx address = XEXP (operands[0], 0);
  944.   char *string;
  945.  
  946.   cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
  947.   cc_status.mdep = address;
  948.  
  949.   if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
  950.      && (cc_prev_status.flags & CC_HI_R31_ADJ)
  951.      && address == cc_prev_status.mdep))
  952.     {
  953.       CC_STATUS_INIT;
  954.       output_asm_insn ("orh %h0,%?r0,%?r31", operands);
  955.       cc_prev_status.mdep = address;
  956.     }
  957.  
  958.   /* Store zero in two parts when appropriate.  */
  959.   if (mode == DFmode && operands[1] == CONST0_RTX (DFmode))
  960.     return store_opcode (DFmode, "%r1,%L0(%?r31)", operands[1]);
  961.  
  962.   /* Code below isn't smart enough to move a doubleword in two parts,
  963.      so use output_move_double to do that in the cases that require it.  */
  964.   if ((mode == DImode || mode == DFmode)
  965.       && ! FP_REG_P (operands[1]))
  966.     return output_move_double (operands);
  967.  
  968.   return store_opcode (mode, "%r1,%L0(%?r31)", operands[1]);
  969. }
  970.  
  971. /* Output a load-from-memory whose operands are OPERANDS[0,1].
  972.    OPERANDS[0] is a reg, and OPERANDS[1] is a mem.
  973.  
  974.    This function returns a template for an insn.
  975.    This is in static storage.
  976.  
  977.    It may also output some insns directly.
  978.    It may alter the values of operands[0] and operands[1].  */
  979.  
  980. char *
  981. output_load (operands)
  982.      rtx *operands;
  983. {
  984.   enum machine_mode mode = GET_MODE (operands[0]);
  985.   rtx address = XEXP (operands[1], 0);
  986.  
  987.   /* We don't bother trying to see if we know %hi(address).
  988.      This is because we are doing a load, and if we know the
  989.      %hi value, we probably also know that value in memory.  */
  990.   cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
  991.   cc_status.mdep = address;
  992.  
  993.   if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
  994.      && (cc_prev_status.flags & CC_HI_R31_ADJ)
  995.      && address == cc_prev_status.mdep
  996.      && cc_prev_status.mdep == cc_status.mdep))
  997.     {
  998.       CC_STATUS_INIT;
  999.       output_asm_insn ("orh %h1,%?r0,%?r31", operands);
  1000.       cc_prev_status.mdep = address;
  1001.     }
  1002.  
  1003.   /* Code below isn't smart enough to move a doubleword in two parts,
  1004.      so use output_move_double to do that in the cases that require it.  */
  1005.   if ((mode == DImode || mode == DFmode)
  1006.       && ! FP_REG_P (operands[0]))
  1007.     return output_move_double (operands);
  1008.  
  1009.   return load_opcode (mode, "%L1(%?r31),%0", operands[0]);
  1010. }
  1011.  
  1012. #if 0
  1013. /* Load the address specified by OPERANDS[3] into the register
  1014.    specified by OPERANDS[0].
  1015.  
  1016.    OPERANDS[3] may be the result of a sum, hence it could either be:
  1017.  
  1018.    (1) CONST
  1019.    (2) REG
  1020.    (2) REG + CONST_INT
  1021.    (3) REG + REG + CONST_INT
  1022.    (4) REG + REG  (special case of 3).
  1023.  
  1024.    Note that (3) is not a legitimate address.
  1025.    All cases are handled here.  */
  1026.  
  1027. void
  1028. output_load_address (operands)
  1029.      rtx *operands;
  1030. {
  1031.   rtx base, offset;
  1032.  
  1033.   if (CONSTANT_P (operands[3]))
  1034.     {
  1035.       output_asm_insn ("mov %3,%0", operands);
  1036.       return;
  1037.     }
  1038.  
  1039.   if (REG_P (operands[3]))
  1040.     {
  1041.       if (REGNO (operands[0]) != REGNO (operands[3]))
  1042.     output_asm_insn ("shl %?r0,%3,%0", operands);
  1043.       return;
  1044.     }
  1045.  
  1046.   if (GET_CODE (operands[3]) != PLUS)
  1047.     abort ();
  1048.  
  1049.   base = XEXP (operands[3], 0);
  1050.   offset = XEXP (operands[3], 1);
  1051.  
  1052.   if (GET_CODE (base) == CONST_INT)
  1053.     {
  1054.       rtx tmp = base;
  1055.       base = offset;
  1056.       offset = tmp;
  1057.     }
  1058.  
  1059.   if (GET_CODE (offset) != CONST_INT)
  1060.     {
  1061.       /* Operand is (PLUS (REG) (REG)).  */
  1062.       base = operands[3];
  1063.       offset = const0_rtx;
  1064.     }
  1065.  
  1066.   if (REG_P (base))
  1067.     {
  1068.       operands[6] = base;
  1069.       operands[7] = offset;
  1070.       CC_STATUS_PARTIAL_INIT;
  1071.       if (SMALL_INT (offset))
  1072.     output_asm_insn ("adds %7,%6,%0", operands);
  1073.       else
  1074.     output_asm_insn ("mov %7,%0\n\tadds %0,%6,%0", operands);
  1075.     }
  1076.   else if (GET_CODE (base) == PLUS)
  1077.     {
  1078.       operands[6] = XEXP (base, 0);
  1079.       operands[7] = XEXP (base, 1);
  1080.       operands[8] = offset;
  1081.  
  1082.       CC_STATUS_PARTIAL_INIT;
  1083.       if (SMALL_INT (offset))
  1084.     output_asm_insn ("adds %6,%7,%0\n\tadds %8,%0,%0", operands);
  1085.       else
  1086.     output_asm_insn ("mov %8,%0\n\tadds %0,%6,%0\n\tadds %0,%7,%0", operands);
  1087.     }
  1088.   else
  1089.     abort ();
  1090. }
  1091. #endif
  1092.  
  1093. /* Output code to place a size count SIZE in register REG.
  1094.    Because block moves are pipelined, we don't include the
  1095.    first element in the transfer of SIZE to REG.
  1096.    For this, we subtract ALIGN.  (Actually, I think it is not
  1097.    right to subtract on this machine, so right now we don't.)  */
  1098.  
  1099. static void
  1100. output_size_for_block_move (size, reg, align)
  1101.      rtx size, reg, align;
  1102. {
  1103.   rtx xoperands[3];
  1104.  
  1105.   xoperands[0] = reg;
  1106.   xoperands[1] = size;
  1107.   xoperands[2] = align;
  1108.  
  1109. #if 1
  1110.   cc_status.flags &= ~ CC_KNOW_HI_R31;
  1111.   output_asm_insn (singlemove_string (xoperands), xoperands);
  1112. #else
  1113.   if (GET_CODE (size) == REG)
  1114.     output_asm_insn ("sub %2,%1,%0", xoperands);
  1115.   else
  1116.     {
  1117.       xoperands[1]
  1118.     = gen_rtx (CONST_INT, VOIDmode, INTVAL (size) - INTVAL (align));
  1119.       cc_status.flags &= ~ CC_KNOW_HI_R31;
  1120.       output_asm_insn ("mov %1,%0", xoperands);
  1121.     }
  1122. #endif
  1123. }
  1124.  
  1125. /* Emit code to perform a block move.
  1126.  
  1127.    OPERANDS[0] is the destination.
  1128.    OPERANDS[1] is the source.
  1129.    OPERANDS[2] is the size.
  1130.    OPERANDS[3] is the known safe alignment.
  1131.    OPERANDS[4..6] are pseudos we can safely clobber as temps.  */
  1132.  
  1133. char *
  1134. output_block_move (operands)
  1135.      rtx *operands;
  1136. {
  1137.   /* A vector for our computed operands.  Note that load_output_address
  1138.      makes use of (and can clobber) up to the 8th element of this vector.  */
  1139.   rtx xoperands[10];
  1140.   rtx zoperands[10];
  1141.   static int movstrsi_label = 0;
  1142.   int i, j;
  1143.   rtx temp1 = operands[4];
  1144.   rtx alignrtx = operands[3];
  1145.   int align = INTVAL (alignrtx);
  1146.   int chunk_size;
  1147.  
  1148.   xoperands[0] = operands[0];
  1149.   xoperands[1] = operands[1];
  1150.   xoperands[2] = temp1;
  1151.  
  1152.   /* We can't move more than four bytes at a time
  1153.      because we have only one register to move them through.  */
  1154.   if (align > 4)
  1155.     {
  1156.       align = 4;
  1157.       alignrtx = gen_rtx (CONST_INT, VOIDmode, 4);
  1158.     }
  1159.  
  1160.   /* Recognize special cases of block moves.  These occur
  1161.      when GNU C++ is forced to treat something as BLKmode
  1162.      to keep it in memory, when its mode could be represented
  1163.      with something smaller.
  1164.  
  1165.      We cannot do this for global variables, since we don't know
  1166.      what pages they don't cross.  Sigh.  */
  1167.   if (GET_CODE (operands[2]) == CONST_INT
  1168.       && ! CONSTANT_ADDRESS_P (operands[0])
  1169.       && ! CONSTANT_ADDRESS_P (operands[1]))
  1170.     {
  1171.       int size = INTVAL (operands[2]);
  1172.       rtx op0 = xoperands[0];
  1173.       rtx op1 = xoperands[1];
  1174.  
  1175.       if ((align & 3) == 0 && (size & 3) == 0 && (size >> 2) <= 16)
  1176.     {
  1177.       if (memory_address_p (SImode, plus_constant (op0, size))
  1178.           && memory_address_p (SImode, plus_constant (op1, size)))
  1179.         {
  1180.           cc_status.flags &= ~CC_KNOW_HI_R31;
  1181.           for (i = (size>>2)-1; i >= 0; i--)
  1182.         {
  1183.           xoperands[0] = plus_constant (op0, i * 4);
  1184.           xoperands[1] = plus_constant (op1, i * 4);
  1185.           output_asm_insn ("ld.l %a1,%?r31\n\tst.l %?r31,%a0",
  1186.                    xoperands);
  1187.         }
  1188.           return "";
  1189.         }
  1190.     }
  1191.       else if ((align & 1) == 0 && (size & 1) == 0 && (size >> 1) <= 16)
  1192.     {
  1193.       if (memory_address_p (HImode, plus_constant (op0, size))
  1194.           && memory_address_p (HImode, plus_constant (op1, size)))
  1195.         {
  1196.           cc_status.flags &= ~CC_KNOW_HI_R31;
  1197.           for (i = (size>>1)-1; i >= 0; i--)
  1198.         {
  1199.           xoperands[0] = plus_constant (op0, i * 2);
  1200.           xoperands[1] = plus_constant (op1, i * 2);
  1201.           output_asm_insn ("ld.s %a1,%?r31\n\tst.s %?r31,%a0",
  1202.                    xoperands);
  1203.         }
  1204.           return "";
  1205.         }
  1206.     }
  1207.       else if (size <= 16)
  1208.     {
  1209.       if (memory_address_p (QImode, plus_constant (op0, size))
  1210.           && memory_address_p (QImode, plus_constant (op1, size)))
  1211.         {
  1212.           cc_status.flags &= ~CC_KNOW_HI_R31;
  1213.           for (i = size-1; i >= 0; i--)
  1214.         {
  1215.           xoperands[0] = plus_constant (op0, i);
  1216.           xoperands[1] = plus_constant (op1, i);
  1217.           output_asm_insn ("ld.b %a1,%?r31\n\tst.b %?r31,%a0",
  1218.                    xoperands);
  1219.         }
  1220.           return "";
  1221.         }
  1222.     }
  1223.     }
  1224.  
  1225.   /* Since we clobber untold things, nix the condition codes.  */
  1226.   CC_STATUS_INIT;
  1227.  
  1228.   /* This is the size of the transfer.
  1229.      Either use the register which already contains the size,
  1230.      or use a free register (used by no operands).  */
  1231.   output_size_for_block_move (operands[2], operands[4], alignrtx);
  1232.  
  1233. #if 0
  1234.   /* Also emit code to decrement the size value by ALIGN.  */
  1235.   zoperands[0] = operands[0];
  1236.   zoperands[3] = plus_constant (operands[0], align);
  1237.   output_load_address (zoperands);
  1238. #endif
  1239.  
  1240.   /* Generate number for unique label.  */
  1241.  
  1242.   xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++);
  1243.  
  1244.   /* Calculate the size of the chunks we will be trying to move first.  */
  1245.  
  1246. #if 0
  1247.   if ((align & 3) == 0)
  1248.     chunk_size = 4;
  1249.   else if ((align & 1) == 0)
  1250.     chunk_size = 2;
  1251.   else
  1252. #endif
  1253.     chunk_size = 1;
  1254.  
  1255.   /* Copy the increment (negative) to a register for bla insn.  */
  1256.  
  1257.   xoperands[4] = gen_rtx (CONST_INT, VOIDmode, - chunk_size);
  1258.   xoperands[5] = operands[5];
  1259.   output_asm_insn ("adds %4,%?r0,%5", xoperands);
  1260.  
  1261.   /* Predecrement the loop counter.  This happens again also in the `bla'
  1262.      instruction which precedes the loop, but we need to have it done
  1263.      two times before we enter the loop because of the bizarre semantics
  1264.      of the bla instruction.  */
  1265.  
  1266.   output_asm_insn ("adds %5,%2,%2", xoperands);
  1267.  
  1268.   /* Check for the case where the original count was less than or equal to
  1269.      zero.  Avoid going through the loop at all if the original count was
  1270.      indeed less than or equal to zero.  Note that we treat the count as
  1271.      if it were a signed 32-bit quantity here, rather than an unsigned one,
  1272.      even though we really shouldn't.  We have to do this because of the
  1273.      semantics of the `ble' instruction, which assume that the count is
  1274.      a signed 32-bit value.  Anyway, in practice it won't matter because
  1275.      nobody is going to try to do a memcpy() of more than half of the
  1276.      entire address space (i.e. 2 gigabytes) anyway.  */
  1277.  
  1278.   output_asm_insn ("bc .Le%3", xoperands);
  1279.  
  1280.   /* Make available a register which is a temporary.  */
  1281.  
  1282.   xoperands[6] = operands[6];
  1283.  
  1284.   /* Now the actual loop.
  1285.      In xoperands, elements 1 and 0 are the input and output vectors.
  1286.      Element 2 is the loop index.  Element 5 is the increment.  */
  1287.  
  1288.   output_asm_insn ("subs %1,%5,%1", xoperands);
  1289.   output_asm_insn ("bla %5,%2,.Lm%3", xoperands);
  1290.   output_asm_insn ("adds %0,%2,%6", xoperands);
  1291.   output_asm_insn ("\n.Lm%3:", xoperands);        /* Label for bla above.  */
  1292.   output_asm_insn ("\n.Ls%3:",  xoperands);        /* Loop start label. */
  1293.   output_asm_insn ("adds %5,%6,%6", xoperands);
  1294.  
  1295.   /* NOTE:  The code here which is supposed to handle the cases where the
  1296.      sources and destinations are known to start on a 4 or 2 byte boundary
  1297.      are currently broken.  They fail to do anything about the overflow
  1298.      bytes which might still need to be copied even after we have copied
  1299.      some number of words or halfwords.  Thus, for now we use the lowest
  1300.      common denominator, i.e. the code which just copies some number of
  1301.      totally unaligned individual bytes.  (See the calculation of
  1302.      chunk_size above.  */
  1303.  
  1304.   if (chunk_size == 4)
  1305.     {
  1306.       output_asm_insn ("ld.l %2(%1),%?r31", xoperands);
  1307.       output_asm_insn ("bla %5,%2,.Ls%3", xoperands);
  1308.       output_asm_insn ("st.l %?r31,8(%6)", xoperands);
  1309.     }
  1310.   else if (chunk_size == 2)
  1311.     {
  1312.       output_asm_insn ("ld.s %2(%1),%?r31", xoperands);
  1313.       output_asm_insn ("bla %5,%2,.Ls%3", xoperands);
  1314.       output_asm_insn ("st.s %?r31,4(%6)", xoperands);
  1315.     }
  1316.   else /* chunk_size == 1 */
  1317.     {
  1318.       output_asm_insn ("ld.b %2(%1),%?r31", xoperands);
  1319.       output_asm_insn ("bla %5,%2,.Ls%3", xoperands);
  1320.       output_asm_insn ("st.b %?r31,2(%6)", xoperands);
  1321.     }
  1322.   output_asm_insn ("\n.Le%3:", xoperands);        /* Here if count <= 0.  */
  1323.  
  1324.   return "";
  1325. }
  1326.  
  1327. /* Output a delayed branch insn with the delay insn in its
  1328.    branch slot.  The delayed branch insn template is in TEMPLATE,
  1329.    with operands OPERANDS.  The insn in its delay slot is INSN.
  1330.  
  1331.    As a special case, since we know that all memory transfers are via
  1332.    ld/st insns, if we see a (MEM (SYMBOL_REF ...)) we divide the memory
  1333.    reference around the branch as
  1334.  
  1335.     orh ha%x,%?r0,%?r31
  1336.     b ...
  1337.     ld/st l%x(%?r31),...
  1338.  
  1339.    As another special case, we handle loading (SYMBOL_REF ...) and
  1340.    other large constants around branches as well:
  1341.  
  1342.     orh h%x,%?r0,%0
  1343.     b ...
  1344.     or l%x,%0,%1
  1345.  
  1346.    */
  1347.  
  1348. char *
  1349. output_delayed_branch (template, operands, insn)
  1350.      char *template;
  1351.      rtx *operands;
  1352.      rtx insn;
  1353. {
  1354.   rtx src = XVECEXP (PATTERN (insn), 0, 1);
  1355.   rtx dest = XVECEXP (PATTERN (insn), 0, 0);
  1356.  
  1357.   /* See if we are doing some branch together with setting some register
  1358.      to some 32-bit value which does (or may) have some of the high-order
  1359.      16 bits set.  If so, we need to set the register in two stages.  One
  1360.      stage must be done before the branch, and the other one can be done
  1361.      in the delay slot.  */
  1362.  
  1363.   if ( (GET_CODE (src) == CONST_INT
  1364.     && ((unsigned) INTVAL (src) & (unsigned) 0xffff0000) != (unsigned) 0)
  1365.       || (GET_CODE (src) == SYMBOL_REF)
  1366.       || (GET_CODE (src) == LABEL_REF)
  1367.       || (GET_CODE (src) == CONST))
  1368.     {
  1369.       rtx xoperands[2];
  1370.       xoperands[0] = dest;
  1371.       xoperands[1] = src;
  1372.  
  1373.       CC_STATUS_PARTIAL_INIT;
  1374.       /* Output the `orh' insn.  */
  1375.       output_asm_insn ("orh %H1,%?r0,%0", xoperands);
  1376.  
  1377.       /* Output the branch instruction next.  */
  1378.       output_asm_insn (template, operands);
  1379.  
  1380.       /* Now output the `or' insn.  */
  1381.       output_asm_insn ("or %L1,%0,%0", xoperands);
  1382.     }
  1383.   else if ((GET_CODE (src) == MEM
  1384.         && CONSTANT_ADDRESS_P (XEXP (src, 0)))
  1385.        || (GET_CODE (dest) == MEM
  1386.            && CONSTANT_ADDRESS_P (XEXP (dest, 0))))
  1387.     {
  1388.       rtx xoperands[2];
  1389.       char *split_template;
  1390.       xoperands[0] = dest;
  1391.       xoperands[1] = src;
  1392.  
  1393.       /* Output the `orh' insn.  */
  1394.       if (GET_CODE (src) == MEM)
  1395.     {
  1396.       if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
  1397.          && (cc_prev_status.flags & CC_HI_R31_ADJ)
  1398.          && cc_prev_status.mdep == XEXP (operands[1], 0)))
  1399.         {
  1400.           CC_STATUS_INIT;
  1401.           output_asm_insn ("orh %h1,%?r0,%?r31", xoperands);
  1402.         }
  1403.       split_template = load_opcode (GET_MODE (dest),
  1404.                     "%L1(%?r31),%0", dest);
  1405.     }
  1406.       else
  1407.     {
  1408.       if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
  1409.          && (cc_prev_status.flags & CC_HI_R31_ADJ)
  1410.          && cc_prev_status.mdep == XEXP (operands[0], 0)))
  1411.         {
  1412.           CC_STATUS_INIT;
  1413.           output_asm_insn ("orh %h0,%?r0,%?r31", xoperands);
  1414.         }
  1415.       split_template = store_opcode (GET_MODE (dest),
  1416.                      "%r1,%L0(%?r31)", src);
  1417.     }
  1418.  
  1419.       /* Output the branch instruction next.  */
  1420.       output_asm_insn (template, operands);
  1421.  
  1422.       /* Now output the load or store.
  1423.      No need to do a CC_STATUS_INIT, because we are branching anyway.  */
  1424.       output_asm_insn (split_template, xoperands);
  1425.     }
  1426.   else
  1427.     {
  1428.       int insn_code_number;
  1429.       rtx pat = gen_rtx (SET, VOIDmode, dest, src);
  1430.       rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
  1431.       int i;
  1432.  
  1433.       /* Output the branch instruction first.  */
  1434.       output_asm_insn (template, operands);
  1435.  
  1436.       /* Now recognize the insn which we put in its delay slot.
  1437.      We must do this after outputting the branch insn,
  1438.      since operands may just be a pointer to `recog_operand'.  */
  1439.       INSN_CODE (delay_insn) = insn_code_number = recog (pat, delay_insn);
  1440.       if (insn_code_number == -1)
  1441.     abort ();
  1442.  
  1443.       for (i = 0; i < insn_n_operands[insn_code_number]; i++)
  1444.     {
  1445.       if (GET_CODE (recog_operand[i]) == SUBREG)
  1446.         recog_operand[i] = alter_subreg (recog_operand[i]);
  1447.     }
  1448.  
  1449.       insn_extract (delay_insn);
  1450.       if (! constrain_operands (insn_code_number, 1))
  1451.     fatal_insn_not_found (delay_insn);
  1452.  
  1453.       template = insn_template[insn_code_number];
  1454.       if (template == 0)
  1455.     template = (*insn_outfun[insn_code_number]) (recog_operand, delay_insn);
  1456.       output_asm_insn (template, recog_operand);
  1457.     }
  1458.   CC_STATUS_INIT;
  1459.   return "";
  1460. }
  1461.  
  1462. /* Output a newly constructed insn DELAY_INSN.  */
  1463. char *
  1464. output_delay_insn (delay_insn)
  1465.      rtx delay_insn;
  1466. {
  1467.   char *template;
  1468.   int insn_code_number;
  1469.   int i;
  1470.  
  1471.   /* Now recognize the insn which we put in its delay slot.
  1472.      We must do this after outputting the branch insn,
  1473.      since operands may just be a pointer to `recog_operand'.  */
  1474.   insn_code_number = recog_memoized (delay_insn);
  1475.   if (insn_code_number == -1)
  1476.     abort ();
  1477.  
  1478.   /* Extract the operands of this delay insn.  */
  1479.   INSN_CODE (delay_insn) = insn_code_number;
  1480.   insn_extract (delay_insn);
  1481.  
  1482.   /* It is possible that this insn has not been properly scanned by final
  1483.      yet.  If this insn's operands don't appear in the peephole's
  1484.      actual operands, then they won't be fixed up by final, so we
  1485.      make sure they get fixed up here.  -- This is a kludge.  */
  1486.   for (i = 0; i < insn_n_operands[insn_code_number]; i++)
  1487.     {
  1488.       if (GET_CODE (recog_operand[i]) == SUBREG)
  1489.     recog_operand[i] = alter_subreg (recog_operand[i]);
  1490.     }
  1491.  
  1492. #ifdef REGISTER_CONSTRAINTS
  1493.   if (! constrain_operands (insn_code_number))
  1494.     abort ();
  1495. #endif
  1496.  
  1497.   cc_prev_status = cc_status;
  1498.  
  1499.   /* Update `cc_status' for this instruction.
  1500.      The instruction's output routine may change it further.
  1501.      If the output routine for a jump insn needs to depend
  1502.      on the cc status, it should look at cc_prev_status.  */
  1503.  
  1504.   NOTICE_UPDATE_CC (PATTERN (delay_insn), delay_insn);
  1505.  
  1506.   /* Now get the template for what this insn would
  1507.      have been, without the branch.  */
  1508.  
  1509.   template = insn_template[insn_code_number];
  1510.   if (template == 0)
  1511.     template = (*insn_outfun[insn_code_number]) (recog_operand, delay_insn);
  1512.   output_asm_insn (template, recog_operand);
  1513.   return "";
  1514. }
  1515.  
  1516. /* Special routine to convert an SFmode value represented as a
  1517.    CONST_DOUBLE into its equivalent unsigned long bit pattern.
  1518.    We convert the value from a double precision floating-point
  1519.    value to single precision first, and thence to a bit-wise
  1520.    equivalent unsigned long value.  This routine is used when
  1521.    generating an immediate move of an SFmode value directly
  1522.    into a general register because the svr4 assembler doesn't
  1523.    grok floating literals in instruction operand contexts.  */
  1524.  
  1525. unsigned long
  1526. sfmode_constant_to_ulong (x)
  1527.      rtx x;
  1528. {
  1529.   REAL_VALUE_TYPE d;
  1530.   union { float f; unsigned long i; } u2;
  1531.  
  1532.   if (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != SFmode)
  1533.     abort ();
  1534.  
  1535. #if TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT
  1536.  error IEEE emulation needed
  1537. #endif
  1538.   REAL_VALUE_FROM_CONST_DOUBLE (d, x);
  1539.   u2.f = d;
  1540.   return u2.i;
  1541. }
  1542.  
  1543. /* This function generates the assembly code for function entry.
  1544.    The macro FUNCTION_PROLOGUE in i860.h is defined to call this function.
  1545.  
  1546.    ASM_FILE is a stdio stream to output the code to.
  1547.    SIZE is an int: how many units of temporary storage to allocate.
  1548.  
  1549.    Refer to the array `regs_ever_live' to determine which registers
  1550.    to save; `regs_ever_live[I]' is nonzero if register number I
  1551.    is ever used in the function.  This macro is responsible for
  1552.    knowing which registers should not be saved even if used.
  1553.  
  1554.    NOTE: `frame_lower_bytes' is the count of bytes which will lie
  1555.    between the new `fp' value and the new `sp' value after the
  1556.    prologue is done.  `frame_upper_bytes' is the count of bytes
  1557.    that will lie between the new `fp' and the *old* `sp' value
  1558.    after the new `fp' is setup (in the prologue).  The upper
  1559.    part of each frame always includes at least 2 words (8 bytes)
  1560.    to hold the saved frame pointer and the saved return address.
  1561.  
  1562.    The svr4 ABI for the i860 now requires that the values of the
  1563.    stack pointer and frame pointer registers be kept aligned to
  1564.    16-byte boundaries at all times.  We obey that restriction here.
  1565.  
  1566.    The svr4 ABI for the i860 is entirely vague when it comes to specifying
  1567.    exactly where the "preserved" registers should be saved.  The native
  1568.    svr4 C compiler I now have doesn't help to clarify the requirements
  1569.    very much because it is plainly out-of-date and non-ABI-compliant
  1570.    (in at least one important way, i.e. how it generates function
  1571.    epilogues).
  1572.  
  1573.    The native svr4 C compiler saves the "preserved" registers (i.e.
  1574.    r4-r15 and f2-f7) in the lower part of a frame (i.e. at negative
  1575.    offsets from the frame pointer).
  1576.  
  1577.    Previous versions of GCC also saved the "preserved" registers in the
  1578.    "negative" part of the frame, but they saved them using positive
  1579.    offsets from the (adjusted) stack pointer (after it had been adjusted
  1580.    to allocate space for the new frame).  That's just plain wrong
  1581.    because if the current function calls alloca(), the stack pointer
  1582.    will get moved, and it will be impossible to restore the registers
  1583.    properly again after that.
  1584.  
  1585.    Both compilers handled parameter registers (i.e. r16-r27 and f8-f15)
  1586.    by copying their values either into various "preserved" registers or
  1587.    into stack slots in the lower part of the current frame (as seemed
  1588.    appropriate, depending upon subsequent usage of these values).
  1589.  
  1590.    Here we want to save the preserved registers at some offset from the
  1591.    frame pointer register so as to avoid any possible problems arising
  1592.    from calls to alloca().  We can either save them at small positive
  1593.    offsets from the frame pointer, or at small negative offsets from
  1594.    the frame pointer.  If we save them at small negative offsets from
  1595.    the frame pointer (i.e. in the lower part of the frame) then we
  1596.    must tell the rest of GCC (via STARTING_FRAME_OFFSET) exactly how
  1597.    many bytes of space we plan to use in the lower part of the frame
  1598.    for this purpose.  Since other parts of the compiler reference the
  1599.    value of STARTING_FRAME_OFFSET long before final() calls this function,
  1600.    we would have to go ahead and assume the worst-case storage requirements
  1601.    for saving all of the "preserved" registers (and use that number, i.e.
  1602.    `80', to define STARTING_FRAME_OFFSET) if we wanted to save them in
  1603.    the lower part of the frame.  That could potentially be very wasteful,
  1604.    and that wastefulness could really hamper people compiling for embedded
  1605.    i860 targets with very tight limits on stack space.  Thus, we choose
  1606.    here to save the preserved registers in the upper part of the
  1607.    frame, so that we can decide at the very last minute how much (or how
  1608.    little) space we must allocate for this purpose.
  1609.  
  1610.    To satisfy the needs of the svr4 ABI "tdesc" scheme, preserved
  1611.    registers must always be saved so that the saved values of registers
  1612.    with higher numbers are at higher addresses.  We obey that restriction
  1613.    here.
  1614.  
  1615.    There are two somewhat different ways that you can generate prologues
  1616.    here... i.e. pedantically ABI-compliant, and the "other" way.  The
  1617.    "other" way is more consistent with what is currently generated by the
  1618.    "native" svr4 C compiler for the i860.  That's important if you want
  1619.    to use the current (as of 8/91) incarnation of svr4 SDB for the i860.
  1620.    The SVR4 SDB for the i860 insists on having function prologues be
  1621.    non-ABI-compliant!
  1622.  
  1623.    To get fully ABI-compliant prologues, define I860_STRICT_ABI_PROLOGUES
  1624.    in the i860svr4.h file.  (By default this is *not* defined).
  1625.  
  1626.    The differences between the ABI-compliant and non-ABI-compliant prologues
  1627.    are that (a) the ABI version seems to require the use of *signed*
  1628.    (rather than unsigned) adds and subtracts, and (b) the ordering of
  1629.    the various steps (e.g. saving preserved registers, saving the
  1630.    return address, setting up the new frame pointer value) is different.
  1631.  
  1632.    For strict ABI compliance, it seems to be the case that the very last
  1633.    thing that is supposed to happen in the prologue is getting the frame
  1634.    pointer set to its new value (but only after everything else has
  1635.    already been properly setup).  We do that here, but only if the symbol
  1636.    I860_STRICT_ABI_PROLOGUES is defined.
  1637. */
  1638.  
  1639. #ifndef STACK_ALIGNMENT
  1640. #define STACK_ALIGNMENT    16
  1641. #endif
  1642.  
  1643. extern char call_used_regs[];
  1644. extern int leaf_function_p ();
  1645.  
  1646. char *current_function_original_name;
  1647.  
  1648. static int must_preserve_r1;
  1649. static unsigned must_preserve_bytes;
  1650.  
  1651. void
  1652. function_prologue (asm_file, local_bytes)
  1653.      register FILE *asm_file;
  1654.      register unsigned local_bytes;
  1655. {
  1656.   register unsigned frame_lower_bytes;
  1657.   register unsigned frame_upper_bytes;
  1658.   register unsigned total_fsize;
  1659.   register unsigned preserved_reg_bytes = 0;
  1660.   register unsigned i;
  1661.   register unsigned preserved_so_far = 0;
  1662.  
  1663.   must_preserve_r1 = (optimize < 2 || ! leaf_function_p ());
  1664.   must_preserve_bytes = 4 + (must_preserve_r1 ? 4 : 0);
  1665.  
  1666.   /* Count registers that need preserving.  Ignore r0.  It never needs
  1667.      preserving.  */
  1668.  
  1669.   for (i = 1; i < FIRST_PSEUDO_REGISTER; i++)
  1670.     {
  1671.       if (regs_ever_live[i] && ! call_used_regs[i])
  1672.         preserved_reg_bytes += 4;
  1673.     }
  1674.  
  1675.   /* Round-up the frame_lower_bytes so that it's a multiple of 16. */
  1676.  
  1677.   frame_lower_bytes = (local_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
  1678.  
  1679.   /* The upper part of each frame will contain the saved fp,
  1680.      the saved r1, and stack slots for all of the other "preserved"
  1681.      registers that we find we will need to save & restore. */
  1682.  
  1683.   frame_upper_bytes = must_preserve_bytes + preserved_reg_bytes;
  1684.  
  1685.   /* Round-up the frame_upper_bytes so that it's a multiple of 16. */
  1686.  
  1687.   frame_upper_bytes
  1688.     = (frame_upper_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
  1689.  
  1690.   total_fsize = frame_upper_bytes + frame_lower_bytes;
  1691.  
  1692. #ifndef I860_STRICT_ABI_PROLOGUES
  1693.  
  1694.   /* There are two kinds of function prologues.
  1695.      You use the "small" version if the total frame size is
  1696.      small enough so that it can fit into an immediate 16-bit
  1697.      value in one instruction.  Otherwise, you use the "large"
  1698.      version of the function prologue.  */
  1699.  
  1700.   if (total_fsize > 0x7fff)
  1701.     {
  1702.       /* Adjust the stack pointer.  The ABI sez to do this using `adds',
  1703.      but the native C compiler on svr4 uses `addu'.  */
  1704.  
  1705.       fprintf (asm_file, "\taddu -%d,%ssp,%ssp\n",
  1706.     frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);
  1707.  
  1708.       /* Save the old frame pointer.  */
  1709.  
  1710.       fprintf (asm_file, "\tst.l %sfp,0(%ssp)\n",
  1711.     i860_reg_prefix, i860_reg_prefix);
  1712.  
  1713.       /* Setup the new frame pointer.  The ABI sez to do this after
  1714.      preserving registers (using adds), but that's not what the
  1715.      native C compiler on svr4 does.  */
  1716.  
  1717.       fprintf (asm_file, "\taddu 0,%ssp,%sfp\n",
  1718.     i860_reg_prefix, i860_reg_prefix);
  1719.  
  1720.       /* Get the value of frame_lower_bytes into r31.  */
  1721.  
  1722.       fprintf (asm_file, "\torh %d,%sr0,%sr31\n",
  1723.     frame_lower_bytes >> 16, i860_reg_prefix, i860_reg_prefix);
  1724.       fprintf (asm_file, "\tor %d,%sr31,%sr31\n",
  1725.     frame_lower_bytes & 0xffff, i860_reg_prefix, i860_reg_prefix);
  1726.  
  1727.       /* Now re-adjust the stack pointer using the value in r31.
  1728.      The ABI sez to do this with `subs' but SDB may prefer `subu'.  */
  1729.  
  1730.       fprintf (asm_file, "\tsubu %ssp,%sr31,%ssp\n",
  1731.     i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
  1732.  
  1733.       /* Preserve registers.  The ABI sez to do this before setting
  1734.      up the new frame pointer, but that's not what the native
  1735.      C compiler on svr4 does.  */
  1736.  
  1737.       for (i = 1; i < 32; i++)
  1738.         if (regs_ever_live[i] && ! call_used_regs[i])
  1739.           fprintf (asm_file, "\tst.l %s%s,%d(%sfp)\n",
  1740.         i860_reg_prefix, reg_names[i],
  1741.         must_preserve_bytes  + (4 * preserved_so_far++),
  1742.         i860_reg_prefix);
  1743.  
  1744.       for (i = 32; i < 64; i++)
  1745.         if (regs_ever_live[i] && ! call_used_regs[i])
  1746.           fprintf (asm_file, "\tfst.l %s%s,%d(%sfp)\n",
  1747.         i860_reg_prefix, reg_names[i],
  1748.         must_preserve_bytes + (4 * preserved_so_far++),
  1749.         i860_reg_prefix);
  1750.  
  1751.       /* Save the return address.  */
  1752.  
  1753.       if (must_preserve_r1)
  1754.         fprintf (asm_file, "\tst.l %sr1,4(%sfp)\n",
  1755.       i860_reg_prefix, i860_reg_prefix);
  1756.     }
  1757.   else
  1758.     {
  1759.       /* Adjust the stack pointer.  The ABI sez to do this using `adds',
  1760.      but the native C compiler on svr4 uses `addu'.  */
  1761.  
  1762.       fprintf (asm_file, "\taddu -%d,%ssp,%ssp\n",
  1763.     total_fsize, i860_reg_prefix, i860_reg_prefix);
  1764.  
  1765.       /* Save the old frame pointer.  */
  1766.  
  1767.       fprintf (asm_file, "\tst.l %sfp,%d(%ssp)\n",
  1768.     i860_reg_prefix, frame_lower_bytes, i860_reg_prefix);
  1769.  
  1770.       /* Setup the new frame pointer.  The ABI sez to do this after
  1771.      preserving registers and after saving the return address,
  1772.     (and its saz to do this using adds), but that's not what the
  1773.      native C compiler on svr4 does.  */
  1774.  
  1775.       fprintf (asm_file, "\taddu %d,%ssp,%sfp\n",
  1776.     frame_lower_bytes, i860_reg_prefix, i860_reg_prefix);
  1777.  
  1778.       /* Preserve registers.  The ABI sez to do this before setting
  1779.      up the new frame pointer, but that's not what the native
  1780.      compiler on svr4 does.  */
  1781.  
  1782.       for (i = 1; i < 32; i++)
  1783.         if (regs_ever_live[i] && ! call_used_regs[i])
  1784.           fprintf (asm_file, "\tst.l %s%s,%d(%sfp)\n",
  1785.         i860_reg_prefix, reg_names[i],
  1786.         must_preserve_bytes + (4 * preserved_so_far++),
  1787.         i860_reg_prefix);
  1788.  
  1789.       for (i = 32; i < 64; i++)
  1790.         if (regs_ever_live[i] && ! call_used_regs[i])
  1791.           fprintf (asm_file, "\tfst.l %s%s,%d(%sfp)\n",
  1792.         i860_reg_prefix, reg_names[i],
  1793.         must_preserve_bytes + (4 * preserved_so_far++),
  1794.         i860_reg_prefix);
  1795.  
  1796.       /* Save the return address.  The ABI sez to do this earlier,
  1797.      and also via an offset from %sp, but the native C compiler
  1798.      on svr4 does it later (i.e. now) and uses an offset from
  1799.      %fp.  */
  1800.  
  1801.       if (must_preserve_r1)
  1802.         fprintf (asm_file, "\tst.l %sr1,4(%sfp)\n",
  1803.       i860_reg_prefix, i860_reg_prefix);
  1804.     }
  1805.  
  1806. #else /* defined(I860_STRICT_ABI_PROLOGUES) */
  1807.  
  1808.   /* There are two kinds of function prologues.
  1809.      You use the "small" version if the total frame size is
  1810.      small enough so that it can fit into an immediate 16-bit
  1811.      value in one instruction.  Otherwise, you use the "large"
  1812.      version of the function prologue.  */
  1813.  
  1814.   if (total_fsize > 0x7fff)
  1815.     {
  1816.       /* Adjust the stack pointer (thereby allocating a new frame).  */
  1817.  
  1818.       fprintf (asm_file, "\tadds -%d,%ssp,%ssp\n",
  1819.     frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);
  1820.  
  1821.       /* Save the caller's frame pointer.  */
  1822.  
  1823.       fprintf (asm_file, "\tst.l %sfp,0(%ssp)\n",
  1824.     i860_reg_prefix, i860_reg_prefix);
  1825.  
  1826.       /* Save return address.  */
  1827.  
  1828.       if (must_preserve_r1)
  1829.         fprintf (asm_file, "\tst.l %sr1,4(%ssp)\n",
  1830.       i860_reg_prefix, i860_reg_prefix);
  1831.  
  1832.       /* Get the value of frame_lower_bytes into r31 for later use.  */
  1833.  
  1834.       fprintf (asm_file, "\torh %d,%sr0,%sr31\n",
  1835.     frame_lower_bytes >> 16, i860_reg_prefix, i860_reg_prefix);
  1836.       fprintf (asm_file, "\tor %d,%sr31,%sr31\n",
  1837.     frame_lower_bytes & 0xffff, i860_reg_prefix, i860_reg_prefix);
  1838.  
  1839.       /* Now re-adjust the stack pointer using the value in r31.  */
  1840.  
  1841.       fprintf (asm_file, "\tsubs %ssp,%sr31,%ssp\n",
  1842.     i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
  1843.  
  1844.       /* Pre-compute value to be used as the new frame pointer.  */
  1845.  
  1846.       fprintf (asm_file, "\tadds %ssp,%sr31,%sr31\n",
  1847.     i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
  1848.  
  1849.       /* Preserve registers.  */
  1850.  
  1851.       for (i = 1; i < 32; i++)
  1852.         if (regs_ever_live[i] && ! call_used_regs[i])
  1853.           fprintf (asm_file, "\tst.l %s%s,%d(%sr31)\n",
  1854.         i860_reg_prefix, reg_names[i],
  1855.         must_preserve_bytes + (4 * preserved_so_far++),
  1856.         i860_reg_prefix);
  1857.  
  1858.       for (i = 32; i < 64; i++)
  1859.         if (regs_ever_live[i] && ! call_used_regs[i])
  1860.           fprintf (asm_file, "\tfst.l %s%s,%d(%sr31)\n",
  1861.         i860_reg_prefix, reg_names[i],
  1862.         must_preserve_bytes + (4 * preserved_so_far++),
  1863.         i860_reg_prefix);
  1864.  
  1865.       /* Actually set the new value of the frame pointer.  */
  1866.  
  1867.       fprintf (asm_file, "\tmov %sr31,%sfp\n",
  1868.     i860_reg_prefix, i860_reg_prefix);
  1869.     }
  1870.   else
  1871.     {
  1872.       /* Adjust the stack pointer.  */
  1873.  
  1874.       fprintf (asm_file, "\tadds -%d,%ssp,%ssp\n",
  1875.     total_fsize, i860_reg_prefix, i860_reg_prefix);
  1876.  
  1877.       /* Save the caller's frame pointer.  */
  1878.  
  1879.       fprintf (asm_file, "\tst.l %sfp,%d(%ssp)\n",
  1880.     i860_reg_prefix, frame_lower_bytes, i860_reg_prefix);
  1881.  
  1882.       /* Save the return address.  */
  1883.  
  1884.       if (must_preserve_r1)
  1885.         fprintf (asm_file, "\tst.l %sr1,%d(%ssp)\n",
  1886.       i860_reg_prefix, frame_lower_bytes + 4, i860_reg_prefix);
  1887.  
  1888.       /* Preserve registers.  */
  1889.  
  1890.       for (i = 1; i < 32; i++)
  1891.         if (regs_ever_live[i] && ! call_used_regs[i])
  1892.           fprintf (asm_file, "\tst.l %s%s,%d(%ssp)\n",
  1893.         i860_reg_prefix, reg_names[i],
  1894.         frame_lower_bytes + must_preserve_bytes + (4 * preserved_so_far++),
  1895.         i860_reg_prefix);
  1896.  
  1897.       for (i = 32; i < 64; i++)
  1898.         if (regs_ever_live[i] && ! call_used_regs[i])
  1899.           fprintf (asm_file, "\tfst.l %s%s,%d(%ssp)\n",
  1900.         i860_reg_prefix, reg_names[i],
  1901.         frame_lower_bytes + must_preserve_bytes + (4 * preserved_so_far++),
  1902.         i860_reg_prefix);
  1903.  
  1904.       /* Setup the new frame pointer.  */
  1905.  
  1906.       fprintf (asm_file, "\tadds %d,%ssp,%sfp\n",
  1907.     frame_lower_bytes, i860_reg_prefix, i860_reg_prefix);
  1908.     }
  1909. #endif /* defined(I860_STRICT_ABI_PROLOGUES) */
  1910.  
  1911. #ifdef ASM_OUTPUT_PROLOGUE_SUFFIX
  1912.   ASM_OUTPUT_PROLOGUE_SUFFIX (asm_file);
  1913. #endif /* defined(ASM_OUTPUT_PROLOGUE_SUFFIX) */
  1914. }
  1915.  
  1916. /* This function generates the assembly code for function exit.
  1917.    The macro FUNCTION_EPILOGUE in i860.h is defined to call this function.
  1918.  
  1919.    ASM_FILE is a stdio stream to output the code to.
  1920.    SIZE is an int: how many units of temporary storage to allocate.
  1921.  
  1922.    The function epilogue should not depend on the current stack pointer!
  1923.    It should use the frame pointer only.  This is mandatory because
  1924.    of alloca; we also take advantage of it to omit stack adjustments
  1925.    before returning.
  1926.  
  1927.    Note that when we go to restore the preserved register values we must
  1928.    not try to address their slots by using offsets from the stack pointer.
  1929.    That's because the stack pointer may have been moved during the function
  1930.    execution due to a call to alloca().  Rather, we must restore all
  1931.    preserved registers via offsets from the frame pointer value.
  1932.  
  1933.    Note also that when the current frame is being "popped" (by adjusting
  1934.    the value of the stack pointer) on function exit, we must (for the
  1935.    sake of alloca) set the new value of the stack pointer based upon
  1936.    the current value of the frame pointer.  We can't just add what we
  1937.    believe to be the (static) frame size to the stack pointer because
  1938.    if we did that, and alloca() had been called during this function,
  1939.    we would end up returning *without* having fully deallocated all of
  1940.    the space grabbed by alloca.  If that happened, and a function
  1941.    containing one or more alloca() calls was called over and over again,
  1942.    then the stack would grow without limit!
  1943.  
  1944.    Finally note that the epilogues generated here are completely ABI
  1945.    compliant.  They go out of their way to insure that the value in
  1946.    the frame pointer register is never less than the value in the stack
  1947.    pointer register.  It's not clear why this relationship needs to be
  1948.    maintained at all times, but maintaining it only costs one extra
  1949.    instruction, so what the hell.
  1950. */
  1951.  
  1952. /* This corresponds to a version 4 TDESC structure. Lower numbered
  1953.    versions successively omit the last word of the structure. We
  1954.    don't try to handle version 5 here. */
  1955.  
  1956. typedef struct TDESC_flags {
  1957.     int version:4;
  1958.     int reg_packing:1;
  1959.     int callable_block:1;
  1960.     int reserved:4;
  1961.     int fregs:6;    /* fp regs 2-7 */
  1962.     int iregs:16;    /* regs 0-15 */
  1963. } TDESC_flags;
  1964.  
  1965. typedef struct TDESC {
  1966.     TDESC_flags flags;
  1967.     int integer_reg_offset;        /* same as must_preserve_bytes */
  1968.     int floating_point_reg_offset;
  1969.     unsigned int positive_frame_size;    /* same as frame_upper_bytes */
  1970.     unsigned int negative_frame_size;    /* same as frame_lower_bytes */
  1971. } TDESC;
  1972.  
  1973. void
  1974. function_epilogue (asm_file, local_bytes)
  1975.      register FILE *asm_file;
  1976.      register unsigned local_bytes;
  1977. {
  1978.   register unsigned frame_upper_bytes;
  1979.   register unsigned frame_lower_bytes;
  1980.   register unsigned preserved_reg_bytes = 0;
  1981.   register unsigned i;
  1982.   register unsigned restored_so_far = 0;
  1983.   register unsigned int_restored;
  1984.   register unsigned mask;
  1985.   unsigned intflags=0;
  1986.   register TDESC_flags *flags = (TDESC_flags *) &intflags;
  1987.  
  1988.   flags->version = 4;
  1989.   flags->reg_packing = 1;
  1990.   flags->iregs = 8;    /* old fp always gets saved */
  1991.  
  1992.   /* Round-up the frame_lower_bytes so that it's a multiple of 16. */
  1993.  
  1994.   frame_lower_bytes = (local_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
  1995.  
  1996.   /* Count the number of registers that were preserved in the prologue.
  1997.      Ignore r0.  It is never preserved.  */
  1998.  
  1999.   for (i = 1; i < FIRST_PSEUDO_REGISTER; i++)
  2000.     {
  2001.       if (regs_ever_live[i] && ! call_used_regs[i])
  2002.         preserved_reg_bytes += 4;
  2003.     }
  2004.  
  2005.   /* The upper part of each frame will contain only saved fp,
  2006.      the saved r1, and stack slots for all of the other "preserved"
  2007.      registers that we find we will need to save & restore. */
  2008.  
  2009.   frame_upper_bytes = must_preserve_bytes + preserved_reg_bytes;
  2010.  
  2011.   /* Round-up frame_upper_bytes so that t is a multiple of 16. */
  2012.  
  2013.   frame_upper_bytes
  2014.     = (frame_upper_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
  2015.  
  2016.   /* Restore all of the "preserved" registers that need restoring.  */
  2017.  
  2018.   mask = 2;
  2019.  
  2020.   for (i = 1; i < 32; i++, mask<<=1)
  2021.     if (regs_ever_live[i] && ! call_used_regs[i]) {
  2022.       fprintf (asm_file, "\tld.l %d(%sfp),%s%s\n",
  2023.     must_preserve_bytes + (4 * restored_so_far++),
  2024.     i860_reg_prefix, i860_reg_prefix, reg_names[i]);
  2025.       if (i > 3 && i < 16)
  2026.     flags->iregs |= mask;
  2027.     }
  2028.  
  2029.   int_restored = restored_so_far;
  2030.   mask = 1;
  2031.  
  2032.   for (i = 32; i < 64; i++) {
  2033.     if (regs_ever_live[i] && ! call_used_regs[i]) {
  2034.       fprintf (asm_file, "\tfld.l %d(%sfp),%s%s\n",
  2035.     must_preserve_bytes + (4 * restored_so_far++),
  2036.     i860_reg_prefix, i860_reg_prefix, reg_names[i]);
  2037.       if (i > 33 & i < 40)
  2038.     flags->fregs |= mask;
  2039.     }
  2040.     if (i > 33 && i < 40)
  2041.       mask<<=1;
  2042.   }
  2043.  
  2044.   /* Get the value we plan to use to restore the stack pointer into r31.  */
  2045.  
  2046.   fprintf (asm_file, "\tadds %d,%sfp,%sr31\n",
  2047.     frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);
  2048.  
  2049.   /* Restore the return address and the old frame pointer.  */
  2050.  
  2051.   if (must_preserve_r1) {
  2052.     fprintf (asm_file, "\tld.l 4(%sfp),%sr1\n",
  2053.       i860_reg_prefix, i860_reg_prefix);
  2054.     flags->iregs |= 2;
  2055.   }
  2056.  
  2057.   fprintf (asm_file, "\tld.l 0(%sfp),%sfp\n",
  2058.     i860_reg_prefix, i860_reg_prefix);
  2059.  
  2060.   /* Return and restore the old stack pointer value.  */
  2061.  
  2062.   fprintf (asm_file, "\tbri %sr1\n\tmov %sr31,%ssp\n",
  2063.     i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
  2064.  
  2065. #ifdef    OUTPUT_TDESC    /* Output an ABI-compliant TDESC entry */
  2066.   if (! frame_lower_bytes) {
  2067.     flags->version--;
  2068.     if (! frame_upper_bytes) {
  2069.       flags->version--;
  2070.       if (restored_so_far == int_restored)    /* No FP saves */
  2071.     flags->version--;
  2072.     }
  2073.   }
  2074.   assemble_name(asm_file,current_function_original_name);
  2075.   fputs(".TDESC:\n", asm_file);
  2076.   fprintf(asm_file, "%s 0x%0x\n", ASM_LONG, intflags);
  2077.   fprintf(asm_file, "%s %d\n", ASM_LONG,
  2078.     int_restored ? must_preserve_bytes : 0);
  2079.   if (flags->version > 1) {
  2080.     fprintf(asm_file, "%s %d\n", ASM_LONG,
  2081.     (restored_so_far == int_restored) ? 0 : must_preserve_bytes +
  2082.       (4 * int_restored));
  2083.     if (flags->version > 2) {
  2084.       fprintf(asm_file, "%s %d\n", ASM_LONG, frame_upper_bytes);
  2085.       if (flags->version > 3)
  2086.     fprintf(asm_file, "%s %d\n", ASM_LONG, frame_lower_bytes);
  2087.     }
  2088.   }
  2089.   tdesc_section();
  2090.   fprintf(asm_file, "%s ", ASM_LONG);
  2091.   assemble_name(asm_file, current_function_original_name);
  2092.   fprintf(asm_file, "\n%s ", ASM_LONG);
  2093.   assemble_name(asm_file, current_function_original_name);
  2094.   fputs(".TDESC\n", asm_file);
  2095.   text_section();
  2096. #endif
  2097. }
  2098.