|
|
1.1 root 1: /* Subroutines for insn-output.c for Convex. 1.1.1.2 ! root 2: Copyright (C) 1989, 1990 Free Software Foundation, Inc. 1.1 root 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: 1.1.1.2 ! root 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: 1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.