Annotation of gcc/config/out-convex.c, revision 1.1.1.1

1.1       root        1: /* Subroutines for insn-output.c for Convex.
                      2:    Copyright (C) 1989 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: /*
                     21:  *  set_cmp (left_rtx, right_rtx, [bhwlsd])
                     22:  *  gen_cmp (label_rtx, cmpop, [tf])
                     23:  *
                     24:  *  set_cmp saves the operands of a "cmp" insn,
                     25:  *    along with the type character to be used in the compare instruction.
                     26:  *
                     27:  *  gen_cmp finds out what comparison is to be performed and
                     28:  *    outputs the necessary instructions, eg,
                     29:  *    "eq.w a1,a2 ! jbra.t L5"
                     30:  *    for (cmpsi a1 a2) (beq L5)
                     31:  */
                     32:  
                     33: static rtx xop0, xop1;
                     34: static char typech, regch;
                     35: 
                     36: char *
                     37: set_cmp (op0, op1, typechr)
                     38:      rtx op0, op1;
                     39:      char typechr;
                     40: {
                     41:   xop0 = op0;
                     42:   xop1 = op1;
                     43:   typech = typechr;
                     44:   if (GET_CODE (op0) == REG)
                     45:     regch = REGNO_OK_FOR_BASE_P (REGNO (op0)) ? 'a' : 's';
                     46:   else if (GET_CODE (op1) == REG)
                     47:     regch = REGNO_OK_FOR_BASE_P (REGNO (op1)) ? 'a' : 's';
                     48:   else abort ();
                     49:   return "";
                     50: }
                     51: 
                     52: char *
                     53: gen_cmp (label, cmpop, tf)
                     54:      rtx label;
                     55:      char *cmpop;
                     56:      char tf;
                     57: {
                     58:   char buf[80];
                     59:   char revop[4];
                     60:   rtx ops[3];
                     61: 
                     62:   ops[2] = label;
                     63: 
                     64:   /* constant must be first; swap operands if necessary
                     65:      if lt, le, ltu, leu are swapped, change to le, lt, leu, ltu
                     66:      and reverse the sense of the jump */
                     67: 
                     68:   if (CONSTANT_P (xop1) || GET_CODE (xop1) == CONST_DOUBLE)
                     69:     {
                     70:       ops[0] = xop1;
                     71:       ops[1] = xop0;
                     72:       if (cmpop[0] == 'l')
                     73:        {
                     74:          bcopy (cmpop, revop, 4);
                     75:          revop[1] ^= 'e' ^ 't';
                     76:          tf ^= 't' ^ 'f';
                     77:          cmpop = revop;
                     78:        }
                     79:     }
                     80:   else
                     81:     {
                     82:       ops[0] = xop0;
                     83:       ops[1] = xop1;
                     84:     }
                     85: 
                     86:   sprintf (buf, "%s.%c %%0,%%1\n\tjbr%c.%c %%l2", cmpop, typech, regch, tf);
                     87:   output_asm_insn (buf, ops);
                     88:   return "";
                     89: }
                     90: 
                     91: /*
                     92:  *  pick target machine if not specified, the same as the host
                     93:  */
                     94: 
                     95: extern int target_flags;
                     96: 
                     97: override_options ()
                     98: {
                     99: #ifdef convex
                    100: #include <sys/sysinfo.h>    
                    101:   if (! (TARGET_C1 || TARGET_C2))
                    102:     {
                    103:       struct system_information sysinfo;
                    104:       getsysinfo (sizeof sysinfo, &sysinfo);
                    105:       if (sysinfo.cpu_type >= SI_CPUTYPE_C2MP)
                    106:        target_flags |= 2;
                    107:       else
                    108:        target_flags |= 1;
                    109:     }
                    110: #endif
                    111: }
                    112: 
                    113: /*
                    114:  * Routines to look at CONST_DOUBLEs without sinful knowledge of
                    115:  * what the inside of u.d looks like
                    116:  *
                    117:  * const_double_high_int  -- high word of machine double or long long
                    118:  * const_double_low_int   -- low word
                    119:  * const_double_float_int -- the word of a machine float
                    120:  */
                    121: 
                    122: static double frexp ();
                    123: static void float_extract ();
                    124: 
                    125: int
                    126: const_double_high_int (x)
                    127:      rtx x;
                    128: {
                    129:   if (GET_MODE (x) == DImode)
                    130:     return CONST_DOUBLE_HIGH (x);
                    131:   else
                    132:     {
                    133:       int sign, expd, expf;
                    134:       unsigned fracdh, fracdl, fracf;
                    135:       float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);
                    136: 
                    137:       if (fracdh == 0)
                    138:        return 0;
                    139:       if (expd < -01777 || expd > 01777)
                    140:        return 1 << 31;
                    141:       return sign << 31 | (expd + 02000) << 20 | fracdh - (1 << 20);
                    142:     }
                    143: }
                    144: 
                    145: int
                    146: const_double_low_int (x)
                    147:      rtx x;
                    148: {
                    149:   if (GET_MODE (x) == DImode)
                    150:     return CONST_DOUBLE_LOW (x);
                    151:   else
                    152:     {
                    153:       int sign, expd, expf;
                    154:       unsigned fracdh, fracdl, fracf;
                    155:       float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);
                    156:       return fracdl;
                    157:     }
                    158: }
                    159: 
                    160: int
                    161: const_double_float_int (x)
                    162:      rtx x;
                    163: {
                    164:   int sign, expd, expf;
                    165:   unsigned fracdh, fracdl, fracf;
                    166:   float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);
                    167: 
                    168:   if (fracf == 0)
                    169:     return 0;
                    170:   if (expf < -0177 || expf > 0177)
                    171:     return 1 << 31;
                    172:   return sign << 31 | (expf + 0200) << 20 | fracf - (1 << 23);
                    173: }
                    174: 
                    175: #define T21  ((double) (1 << 21))
                    176: #define T24  ((double) (1 << 24))
                    177: #define T53  ((double) (1 << 27) * (double) (1 << 26))
                    178: 
                    179: static void
                    180: float_extract (x, sign, expd, fracdh, fracdl, expf, fracf)
                    181:      rtx x;
                    182:      int *sign, *expd, *expf;
                    183:      unsigned *fracdh, *fracdl, *fracf;
                    184: {
                    185:   int exp, round;
                    186:   double d, r;
                    187:   union real_extract u;
                    188: 
                    189:   bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);
                    190: 
                    191:   /* Get sign and exponent.  */
                    192: 
                    193:   if (*sign = u.d < 0)
                    194:     u.d = -u.d;
                    195:   d = frexp (u.d, &exp);  
                    196: 
                    197:   /* Get 21 fraction bits for high word and 32 for low word.  */
                    198: 
                    199:   for (round = 0; ; round = 1)
                    200:     {
                    201:       r = frexp (round ? d + 1.0 / T53 : d, expd);
                    202:       *expd += exp;
                    203:       *fracdh = r * T21;
                    204:       *fracdl = (r - *fracdh / T21) * T53;
                    205:       if (round || ((r - *fracdh / T21) - *fracdl / T53) < 0.5 * T53)
                    206:        break;
                    207:     }
                    208: 
                    209:   /* Get 24 bits for float fraction. */
                    210: 
                    211:   for (round = 0; ; round = 1)
                    212:     {
                    213:       r = frexp (round ? d + 1.0 / T24 : d, expf);
                    214:       *expf += exp;
                    215:       *fracf = r * T24;
                    216:       if (round || (r - *fracf / T24) < 0.5 * T24)
                    217:        break;
                    218:     }
                    219: }
                    220: 
                    221: static double
                    222: frexp (d, exp)
                    223:      double d;
                    224:      int *exp;
                    225: {
                    226:   int e = 0;
                    227: 
                    228:   if (d > 0)
                    229:     {
                    230:       while (d < 0.5) d *= 2.0, e--;
                    231:       while (d >= 1.0) d /= 2.0, e++;
                    232:     }
                    233: 
                    234:   *exp = e;
                    235:   return d;
                    236: }
                    237: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.