home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cplusplus-8 / config / out-convex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-01  |  5.0 KB  |  220 lines

  1. /* Subroutines for insn-output.c for Convex.
  2.    Copyright (C) 1989, 1990 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* Boolean to keep track of whether the current section is .text or not.
  21.    Used by .align handler in tm-convex.h. */
  22.  
  23. int current_section_is_text;
  24.  
  25. /*
  26.  *  set_cmp (left_rtx, right_rtx, [bhwlsd])
  27.  *  gen_cmp (label_rtx, cmpop, [tf])
  28.  *
  29.  *  set_cmp saves the operands of a "cmp" insn,
  30.  *    along with the type character to be used in the compare instruction.
  31.  *
  32.  *  gen_cmp finds out what comparison is to be performed and
  33.  *    outputs the necessary instructions, eg,
  34.  *    "eq.w a1,a2 ! jbra.t L5"
  35.  *    for (cmpsi a1 a2) (beq L5)
  36.  */
  37.  
  38. static rtx xop0, xop1;
  39. static char typech, regch;
  40.  
  41. char *
  42. set_cmp (op0, op1, typechr)
  43.      rtx op0, op1;
  44.      char typechr;
  45. {
  46.   xop0 = op0;
  47.   xop1 = op1;
  48.   typech = typechr;
  49.   if (GET_CODE (op0) == REG)
  50.     regch = REGNO_OK_FOR_BASE_P (REGNO (op0)) ? 'a' : 's';
  51.   else if (GET_CODE (op1) == REG)
  52.     regch = REGNO_OK_FOR_BASE_P (REGNO (op1)) ? 'a' : 's';
  53.   else abort ();
  54.   return "";
  55. }
  56.  
  57. char *
  58. gen_cmp (label, cmpop, tf)
  59.      rtx label;
  60.      char *cmpop;
  61.      char tf;
  62. {
  63.   char buf[80];
  64.   char revop[4];
  65.   rtx ops[3];
  66.  
  67.   ops[2] = label;
  68.  
  69.   /* constant must be first; swap operands if necessary
  70.      if lt, le, ltu, leu are swapped, change to le, lt, leu, ltu
  71.      and reverse the sense of the jump */
  72.  
  73.   if (CONSTANT_P (xop1) || GET_CODE (xop1) == CONST_DOUBLE)
  74.     {
  75.       ops[0] = xop1;
  76.       ops[1] = xop0;
  77.       if (cmpop[0] == 'l')
  78.     {
  79.       bcopy (cmpop, revop, 4);
  80.       revop[1] ^= 'e' ^ 't';
  81.       tf ^= 't' ^ 'f';
  82.       cmpop = revop;
  83.     }
  84.     }
  85.   else
  86.     {
  87.       ops[0] = xop0;
  88.       ops[1] = xop1;
  89.     }
  90.  
  91.   sprintf (buf, "%s.%c %%0,%%1\n\tjbr%c.%c %%l2", cmpop, typech, regch, tf);
  92.   output_asm_insn (buf, ops);
  93.   return "";
  94. }
  95.  
  96. /*
  97.  * Routines to look at CONST_DOUBLEs without sinful knowledge of
  98.  * what the inside of u.d looks like
  99.  *
  100.  * const_double_high_int  -- high word of machine double or long long
  101.  * const_double_low_int   -- low word
  102.  * const_double_float_int -- the word of a machine float
  103.  */
  104.  
  105. static double frexp ();
  106. static void float_extract ();
  107.  
  108. int
  109. const_double_high_int (x)
  110.      rtx x;
  111. {
  112.   if (GET_MODE (x) == DImode)
  113.     return CONST_DOUBLE_HIGH (x);
  114.   else
  115.     {
  116.       int sign, expd, expf;
  117.       unsigned fracdh, fracdl, fracf;
  118.       float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);
  119.  
  120.       if (fracdh == 0)
  121.     return 0;
  122.       if (expd < -01777 || expd > 01777)
  123.     return 1 << 31;
  124.       return sign << 31 | (expd + 02000) << 20 | fracdh - (1 << 20);
  125.     }
  126. }
  127.  
  128. int
  129. const_double_low_int (x)
  130.      rtx x;
  131. {
  132.   if (GET_MODE (x) == DImode)
  133.     return CONST_DOUBLE_LOW (x);
  134.   else
  135.     {
  136.       int sign, expd, expf;
  137.       unsigned fracdh, fracdl, fracf;
  138.       float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);
  139.       return fracdl;
  140.     }
  141. }
  142.  
  143. int
  144. const_double_float_int (x)
  145.      rtx x;
  146. {
  147.   int sign, expd, expf;
  148.   unsigned fracdh, fracdl, fracf;
  149.   float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);
  150.  
  151.   if (fracf == 0)
  152.     return 0;
  153.   if (expf < -0177 || expf > 0177)
  154.     return 1 << 31;
  155.   return sign << 31 | (expf + 0200) << 20 | fracf - (1 << 23);
  156. }
  157.  
  158. #define T21  ((double) (1 << 21))
  159. #define T24  ((double) (1 << 24))
  160. #define T53  ((double) (1 << 27) * (double) (1 << 26))
  161.  
  162. static void
  163. float_extract (x, sign, expd, fracdh, fracdl, expf, fracf)
  164.      rtx x;
  165.      int *sign, *expd, *expf;
  166.      unsigned *fracdh, *fracdl, *fracf;
  167. {
  168.   int exp, round;
  169.   double d, r;
  170.   union real_extract u;
  171.  
  172.   bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);
  173.  
  174.   /* Get sign and exponent.  */
  175.  
  176.   if (*sign = u.d < 0)
  177.     u.d = -u.d;
  178.   d = frexp (u.d, &exp);  
  179.  
  180.   /* Get 21 fraction bits for high word and 32 for low word.  */
  181.  
  182.   for (round = 0; ; round = 1)
  183.     {
  184.       r = frexp (round ? d + 1.0 / T53 : d, expd);
  185.       *expd += exp;
  186.       *fracdh = r * T21;
  187.       *fracdl = (r - *fracdh / T21) * T53;
  188.       if (round || ((r - *fracdh / T21) - *fracdl / T53) < 0.5 * T53)
  189.     break;
  190.     }
  191.  
  192.   /* Get 24 bits for float fraction. */
  193.  
  194.   for (round = 0; ; round = 1)
  195.     {
  196.       r = frexp (round ? d + 1.0 / T24 : d, expf);
  197.       *expf += exp;
  198.       *fracf = r * T24;
  199.       if (round || (r - *fracf / T24) < 0.5 * T24)
  200.     break;
  201.     }
  202. }
  203.  
  204. static double
  205. frexp (d, exp)
  206.      double d;
  207.      int *exp;
  208. {
  209.   int e = 0;
  210.  
  211.   if (d > 0)
  212.     {
  213.       while (d < 0.5) d *= 2.0, e--;
  214.       while (d >= 1.0) d /= 2.0, e++;
  215.     }
  216.  
  217.   *exp = e;
  218.   return d;
  219. }
  220.