|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.