📄 fpustate64.java
字号:
checkExceptions(); return Double.NaN; // QNaN if masked } double x = data[top]; tag[top] = FPU_TAG_EMPTY; if (++top >= STACK_DEPTH) top = 0; return x; }// public BigDecimal popBig() throws ProcessorException// {// return new BigDecimal(pop());// } public double ST(int index) throws ProcessorException { int i = ((top + index) & 0x7); if (tag[i] == FPU_TAG_EMPTY) { // an attempt to read an empty register is technically // a "stack underflow" setInvalidOperation(); setStackFault(); conditionCode &= ~2; // C1 cleared to indicate stack underflow checkExceptions(); } else if (specialTag[i] == FPU_SPECIAL_TAG_SNAN) { setInvalidOperation(); checkExceptions(); return Double.NaN; // QNaN if masked } return data[i]; }// public BigDecimal bigST(int index) throws ProcessorException// {// return new BigDecimal(ST(index));// } public int getTag(int index) { int i = ((top + index) & 0x7); return tag[i]; } public int getSpecialTag(int index) { int i = ((top + index) & 0x7); return specialTag[i]; } public void setST(int index, double value) { // FST says that no exception is generated if the destination // is a non-empty register, so we don't generate an exception // here. TODO: check to see if this is a general rule. int i = ((top + index) & 0x7); data[i] = value; tag[i] = tagCode(value); specialTag[i] = specialTagCode(value); }// public void setBigST(int index, BigDecimal value)// {// setST(index, value.doubleValue());// } public int getStatus() { int w = statusWord; if (getErrorSummaryStatus()) w |= 0x80; if (getBusy()) w |= 0x8000; w |= (top << 11); w |= ((conditionCode & 0x7) << 8); w |= ((conditionCode & 0x8) << 11); return w; } public void setStatus(int w) { statusWord &= ~0x7f; statusWord |= (w & 0x7f); top = ((w >> 11) & 0x7); conditionCode = ((w >> 8) & 0x7); conditionCode |= ((w >>> 14) & 1); } public int getControl() { int w = maskWord; w |= ((precisionControl & 0x3) << 8); w |= ((roundingControl & 0x3) << 10); if (infinityControl) w |= 0x1000; return w; } public void setControl(int w) { maskWord &= ~0x3f; maskWord |= (w & 0x3f); infinityControl = ((w & 0x1000) != 0); setPrecisionControl((w >> 8) & 3); setRoundingControl((w >> 10) & 3); } public int getTagWord() { int w = 0; for (int i = STACK_DEPTH - 1; i >= 0; --i) w = ((w << 2) | (tag[i] & 0x3)); return w; } public void setTagWord(int w) { for (int i = 0; i < STACK_DEPTH; ++i) { int t = (w & 0x3); if (t == FPU_TAG_EMPTY) { tag[i] = FPU_TAG_EMPTY; } else { tag[i] = tagCode(data[i]); if (specialTag[i] != FPU_SPECIAL_TAG_SNAN) specialTag[i] = specialTagCode(data[i]); // SNaN is sticky, and Java doesn't preserve the bit pattern. } w >>= 2; } } // STRICTLY SPEAKING, the x87 should preserve the SNaN and QNaN // bit pattern; v1 sec 4.8.3.6 of the manual, in fact, says that // these bits can be used to store diagnostic information. // But Java will probably eliminate all these bits to get a code // it understands (which looks like an infinity). For now we // simply don't support using NaN bits in this way. public static byte[] doubleToExtended(double x, boolean isSignalNaN) { byte[] b = new byte[10]; long fraction = 0; int iexp = 0; // other special forms? if (isSignalNaN) { fraction = 0xc000000000000000L; // is this right? } else { long n = Double.doubleToRawLongBits(x); fraction = (n & ~(0xfff << 52)); iexp = ((int)(n >> 52) & 0x7ff); boolean sgn = ((n & (1 << 63)) != 0); // insert implicit 1 fraction |= (1 << 52); fraction <<= 11; // re-bias exponent iexp += (16383 - 1023); if (sgn) iexp |= 0x8000; } for (int i = 0; i < 8; ++i) { b[i] = (byte)fraction; fraction >>>= 8; } b[8] = (byte)iexp; b[9] = (byte)(iexp >>> 8); return b; } public static int specialTagCode(byte[] b) { long fraction = 0; for (int i = 7; i >= 0; --i) { long w = ((long)b[i] & 0xff); fraction |= w; fraction <<= 8; } int iexp = (((int)b[8] & 0xff) | (((int)b[9] & 0x7f) << 8)); boolean sgn = ((b[9] & 0x80) != 0); boolean integ = ((b[7] & 0x80) != 0); // explicit integer bit if (iexp == 0) { if (integ) { // "pseudo-denormals" - treated like a normal denormal return FPU_SPECIAL_TAG_DENORMAL; } else { // normal denormals return FPU_SPECIAL_TAG_DENORMAL; } } else if (iexp == 0x7fff) { if (fraction == 0L) { // "pseudo-infinity" return FPU_SPECIAL_TAG_UNSUPPORTED; } else if (integ) { if ((fraction << 1) == 0) { // infinity return FPU_SPECIAL_TAG_INFINITY; } else { // NaN's if ((fraction >>> 62) == 0) return FPU_SPECIAL_TAG_SNAN; else return FPU_SPECIAL_TAG_NAN; } } else { // pseudo-NaN return FPU_SPECIAL_TAG_UNSUPPORTED; } } else { if (integ) { // normal float return FPU_SPECIAL_TAG_NONE; } else { // "unnormal" return FPU_SPECIAL_TAG_UNSUPPORTED; } } } public static double extendedToDouble(byte[] b) { long fraction = 0; for (int i = 7; i >= 0; --i) { long w = ((long)b[i] & 0xff); fraction |= w; fraction <<= 8; } int iexp = (((int)b[8] & 0xff) | (((int)b[9] & 0x7f) << 8)); boolean sgn = ((b[9] & 0x80) != 0); boolean integ = ((b[7] & 0x80) != 0); // explicit integer bit if (iexp == 0) { if (integ) { // "pseudo-denormals" - treat exponent as value 1 and // mantissa as the same // (http://www.ragestorm.net/downloads/387intel.txt) iexp = 1; } // now treat as a normal denormal (from denormal). // actually, given that min unbiased exponent is -16383 for // extended, and only -1023 for double, a denormalized // extended is pretty much zero in double! return 0.0; } else if (iexp == 0x7fff) { if (fraction == 0L) { // "pseudo-infinity": if #IA masked, return QNaN // more technically, sign bit should be set to indicate // "QNaN floating-point indefinite" return Double.NaN; } else if (integ) { if ((fraction << 1) == 0) { return (sgn) ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; } else { // a conventional NaN return Double.NaN; } } else { // pseudo-NaN return Double.NaN; } } else { if (integ) { // normal float: decode iexp += 1023 - 16383; // rebias for double format fraction >>>= 11; // truncate rounding (is this the right way?) if (iexp > 0x7ff) { // too big an exponent return (sgn) ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; } else if (iexp < 0) { // denormal (from normal) fraction >>>= (- iexp); iexp = 0; } fraction &= ~(0xfffL << 52); // this cuts off explicit 1 fraction |= (((long)iexp & 0x7ff) << 52); if (sgn) fraction |= (1 << 63); return Double.longBitsToDouble(fraction); } else { // "unnormal": if #IA masked, return QNaN FP indefinite return Double.NaN; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -