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 / alpha.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  41KB  |  1,517 lines

  1. /* Subroutines used for code generation on the DEC Alpha.
  2.    Copyright (C) 1992 Free Software Foundation, Inc.
  3.    Contributed by Richard Kenner (kenner@nyu.edu)
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21.  
  22. #include <stdio.h>
  23. #include "config.h"
  24. #include "rtl.h"
  25. #include "regs.h"
  26. #include "hard-reg-set.h"
  27. #include "real.h"
  28. #include "insn-config.h"
  29. #include "conditions.h"
  30. #include "insn-flags.h"
  31. #include "output.h"
  32. #include "insn-attr.h"
  33. #include "flags.h"
  34. #include "recog.h"
  35. #include "reload.h"
  36. #include "expr.h"
  37. #include "obstack.h"
  38. #include "tree.h"
  39.  
  40. /* Save information from a "cmpxx" operation until the branch or scc is
  41.    emitted.  */
  42.  
  43. rtx alpha_compare_op0, alpha_compare_op1;
  44. int alpha_compare_fp_p;
  45.  
  46. /* Save the name of the current function as used by the assembler.  This
  47.    is used by the epilogue.  */
  48.  
  49. char *alpha_function_name;
  50.  
  51. /* Nonzero if the current function needs gp.  */
  52.  
  53. int alpha_function_needs_gp;
  54.  
  55. /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
  56.  
  57. int
  58. zap_mask (value)
  59.      HOST_WIDE_INT value;
  60. {
  61.   int i;
  62.  
  63.   for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
  64.        i++, value >>= 8)
  65.     if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
  66.       return 0;
  67.  
  68.   return 1;
  69. }
  70.  
  71. /* Returns 1 if OP is either the constant zero or a register.  If a
  72.    register, it must be in the proper mode unless MODE is VOIDmode.  */
  73.  
  74. int
  75. reg_or_0_operand (op, mode)
  76.       register rtx op;
  77.       enum machine_mode mode;
  78. {
  79.   return op == const0_rtx || register_operand (op, mode);
  80. }
  81.  
  82. /* Return 1 if OP is an 8-bit constant or any register.  */
  83.  
  84. int
  85. reg_or_8bit_operand (op, mode)
  86.      register rtx op;
  87.      enum machine_mode mode;
  88. {
  89.   return ((GET_CODE (op) == CONST_INT
  90.        && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
  91.       || register_operand (op, mode));
  92. }
  93.  
  94. /* Return 1 if the operand is a valid second operand to an add insn.  */
  95.  
  96. int
  97. add_operand (op, mode)
  98.      register rtx op;
  99.      enum machine_mode mode;
  100. {
  101.   if (GET_CODE (op) == CONST_INT)
  102.     return ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) < 0x10000
  103.         || ((INTVAL (op) & 0xffff) == 0
  104.         && (INTVAL (op) >> 31 == -1
  105.             || INTVAL (op) >> 31 == 0)));
  106.  
  107.   return register_operand (op, mode);
  108. }
  109.  
  110. /* Return 1 if the operand is a valid second operand to a sign-extending
  111.    add insn.  */
  112.  
  113. int
  114. sext_add_operand (op, mode)
  115.      register rtx op;
  116.      enum machine_mode mode;
  117. {
  118.   if (GET_CODE (op) == CONST_INT)
  119.     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
  120.         || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
  121.  
  122.   return register_operand (op, mode);
  123. }
  124.  
  125. /* Return 1 if OP is the constant 4 or 8.  */
  126.  
  127. int
  128. const48_operand (op, mode)
  129.      register rtx op;
  130.      enum machine_mode mode;
  131. {
  132.   return (GET_CODE (op) == CONST_INT
  133.       && (INTVAL (op) == 4 || INTVAL (op) == 8));
  134. }
  135.  
  136. /* Return 1 if OP is a valid first operand to an AND insn.  */
  137.  
  138. int
  139. and_operand (op, mode)
  140.      register rtx op;
  141.      enum machine_mode mode;
  142. {
  143.   if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
  144.     return (zap_mask (CONST_DOUBLE_LOW (op))
  145.         && zap_mask (CONST_DOUBLE_HIGH (op)));
  146.  
  147.   if (GET_CODE (op) == CONST_INT)
  148.     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
  149.         || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
  150.         || zap_mask (INTVAL (op)));
  151.  
  152.   return register_operand (op, mode);
  153. }
  154.  
  155. /* Return 1 if OP is a constant that is the width, in bits, of an integral
  156.    mode smaller than DImode.  */
  157.  
  158. int
  159. mode_width_operand (op, mode)
  160.      register rtx op;
  161.      enum machine_mode mode;
  162. {
  163.   return (GET_CODE (op) == CONST_INT
  164.       && (INTVAL (op) == 8 || INTVAL (op) == 16 || INTVAL (op) == 32));
  165. }
  166.  
  167. /* Return 1 if OP is a constant that is the width of an integral machine mode
  168.    smaller than an integer.  */
  169.  
  170. int
  171. mode_mask_operand (op, mode)
  172.      register rtx op;
  173.      enum machine_mode mode;
  174. {
  175. #if HOST_BITS_PER_WIDE_INT == 32
  176.   if (GET_CODE (op) == CONST_DOUBLE)
  177.     return CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == -1;
  178. #endif
  179.  
  180.   if (GET_CODE (op) == CONST_INT)
  181.     return (INTVAL (op) == 0xff
  182.         || INTVAL (op) == 0xffff
  183. #if HOST_BITS_PER_WIDE_INT == 64
  184.         || INTVAL (op) == 0xffffffff
  185. #endif
  186.         );
  187. }
  188.  
  189. /* Return 1 if OP is a multiple of 8 less than 64.  */
  190.  
  191. int
  192. mul8_operand (op, mode)
  193.      register rtx op;
  194.      enum machine_mode mode;
  195. {
  196.   return (GET_CODE (op) == CONST_INT
  197.       && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
  198.       && (INTVAL (op) & 7) == 0);
  199. }
  200.  
  201. /* Return 1 if OP is the constant zero in floating-point.  */
  202.  
  203. int
  204. fp0_operand (op, mode)
  205.      register rtx op;
  206.      enum machine_mode mode;
  207. {
  208.   return (GET_MODE (op) == mode
  209.       && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
  210. }
  211.  
  212. /* Return 1 if OP is the floating-point constant zero or a register.  */
  213.  
  214. int
  215. reg_or_fp0_operand (op, mode)
  216.      register rtx op;
  217.      enum machine_mode mode;
  218. {
  219.   return fp0_operand (op, mode) || register_operand (op, mode);
  220. }
  221.  
  222. /* Return 1 if OP is a register or a constant integer.  */
  223.  
  224.  
  225. int
  226. reg_or_cint_operand (op, mode)
  227.     register rtx op;
  228.     enum machine_mode mode;
  229. {
  230.      return GET_CODE (op) == CONST_INT || register_operand (op, mode);
  231. }
  232.  
  233. /* Return 1 if OP is a valid operand for the source of a move insn.  */
  234.  
  235. int
  236. input_operand (op, mode)
  237.      register rtx op;
  238.      enum machine_mode mode;
  239. {
  240.   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
  241.     return 0;
  242.  
  243.   if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
  244.     return 0;
  245.  
  246.   switch (GET_CODE (op))
  247.     {
  248.     case LABEL_REF:
  249.     case SYMBOL_REF:
  250.     case CONST:
  251.       return mode == DImode;
  252.  
  253.     case REG:
  254.       return 1;
  255.  
  256.     case SUBREG:
  257.       if (register_operand (op, mode))
  258.     return 1;
  259.       /* ... fall through ... */
  260.     case MEM:
  261.       return mode != HImode && mode != QImode && general_operand (op, mode);
  262.  
  263.     case CONST_DOUBLE:
  264.       return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
  265.  
  266.     case CONST_INT:
  267.       return mode == QImode || mode == HImode || add_operand (op, mode);
  268.     }
  269.  
  270.   return 0;
  271. }
  272.  
  273. /* Return 1 if OP is a SYMBOL_REF for the current function.  */
  274.  
  275. int
  276. current_function_operand (op, mode)
  277.      rtx op;
  278.      enum machine_mode mode;
  279. {
  280.   return (GET_CODE (op) == SYMBOL_REF
  281.       && ! strcmp (XSTR (op, 0), current_function_name));
  282. }
  283.  
  284. /* Return 1 if OP is a valid Alpha comparison operator.  Here we know which
  285.    comparisons are valid in which insn.  */
  286.  
  287. int
  288. alpha_comparison_operator (op, mode)
  289.      register rtx op;
  290.      enum machine_mode mode;
  291. {
  292.   enum rtx_code code = GET_CODE (op);
  293.  
  294.   if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
  295.     return 0;
  296.  
  297.   return (code == EQ || code == LE || code == LT
  298.       || (mode == DImode && (code == LEU || code == LTU)));
  299. }
  300.  
  301. /* Return 1 if OP is a signed comparison operation.  */
  302.  
  303. int
  304. signed_comparison_operator (op, mode)
  305.      register rtx op;
  306.      enum machine_mode mode;
  307. {
  308.   switch (GET_CODE (op))
  309.     {
  310.     case EQ:  case NE:  case LE:  case LT:  case GE:   case GT:
  311.       return 1;
  312.     }
  313.  
  314.   return 0;
  315. }
  316.  
  317. /* Return 1 if this is a divide or modulus operator.  */
  318.  
  319. int
  320. divmod_operator (op, mode)
  321.      register rtx op;
  322.      enum machine_mode mode;
  323. {
  324.   switch (GET_CODE (op))
  325.     {
  326.     case DIV:  case MOD:  case UDIV:  case UMOD:
  327.       return 1;
  328.     }
  329.  
  330.   return 0;
  331. }
  332.  
  333. /* Return 1 if this memory address is a known aligned register plus
  334.    a constant.  It must be a valid address.  This means that we can do
  335.    this as an aligned reference plus some offset.
  336.  
  337.    Take into account what reload will do.
  338.  
  339.    We could say that out-of-range stack slots are alignable, but that would
  340.    complicate get_aligned_mem a