home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / config / i860.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  61KB  |  2,049 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@ncd.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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  25.  
  26.  
  27. #include "config.h"
  28. #include "flags.h"
  29. #include "rtl.h"
  30. #include "regs.h"
  31. #include "hard-reg-set.h"
  32. #include "real.h"
  33. #include "insn-config.h"
  34. #include "conditions.h"
  35. #include "insn-flags.h"
  36. #include "output.h"
  37. #include "recog.h"
  38. #include "insn-attr.h"
  39.  
  40. #include <stdio.h>
  41.  
  42. static rtx find_addr_reg ();
  43.  
  44. #ifndef I860_REG_PREFIX
  45. #define I860_REG_PREFIX ""
  46. #endif
  47.  
  48. char *i860_reg_prefix = I860_REG_PREFIX;
  49.  
  50. /* Save information from a "cmpxx" operation until the branch is emitted.  */
  51.  
  52. rtx i860_compare_op0, i860_compare_op1;
  53.  
  54. /* Return non-zero if this pattern, can be evaluated safely, even if it
  55.    was not asked for.  */
  56. int
  57. safe_insn_src_p (op, mode)
  58.      rtx op;
  59.      enum machine_mode mode;
  60. {
  61.   /* Just experimenting.  */
  62.  
  63.   /* No floating point src is safe if it contains an arithmetic
  64.      operation, since that operation may trap.  */
  65.   switch (GET_CODE (op))
  66.     {
  67.     case CONST_INT:
  68.     case LABEL_REF:
  69.     case SYMBOL_REF:
  70.     case CONST:
  71.       return 1;
  72.  
  73.     case REG:
  74.       return 1;
  75.  
  76.     case MEM:
  77.       return CONSTANT_ADDRESS_P (XEXP (op, 0));
  78.  
  79.       /* We never need to negate or complement constants.  */
  80.     case NEG:
  81.       return (mode != SFmode && mode != DFmode);
  82.     case NOT:
  83.     case ZERO_EXTEND:
  84.       return 1;
  85.  
  86.     case EQ:
  87.     case NE:
  88.     case LT:
  89.     case GT:
  90.     case LE:
  91.     case GE:
  92.     case LTU:
  93.     case GTU:
  94.     case LEU:
  95.     case GEU:
  96.     case MINUS:
  97.     case PLUS:
  98.       return (mode != SFmode && mode != DFmode);
  99.     case AND:
  100.     case IOR:
  101.     case XOR:
  102.     case LSHIFT:
  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 LSHIFT:
  330.     case ASHIFT:
  331.     case ASHIFTRT:
  332.     case LSHIFTRT:
  333.       return 1;
  334.  
  335.     case SUBREG:
  336.       if (SUBREG_WORD (op) != 0)
  337.     return 0;
  338.