⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fpustate64.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*    JPC: A x86 PC Hardware Emulator for a pure Java Virtual Machine    Release Version 2.0    A project from the Physics Dept, The University of Oxford    Copyright (C) 2007 Isis Innovation Limited    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License version 2 as published by    the Free Software Foundation.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License along    with this program; if not, write to the Free Software Foundation, Inc.,    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.     Details (including contact information) can be found at:     www.physics.ox.ac.uk/jpc*/package org.jpc.emulator.processor.fpu64;// import java.math.BigDecimal;import org.jpc.emulator.processor.*;import java.io.*;public class FpuState64 extends FpuState{    public final static int FPU_SPECIAL_TAG_NONE = 0;    public final static int FPU_SPECIAL_TAG_NAN = 1;    public final static int FPU_SPECIAL_TAG_UNSUPPORTED = 2;    public final static int FPU_SPECIAL_TAG_INFINITY = 3;    public final static int FPU_SPECIAL_TAG_DENORMAL = 4;    public final static int FPU_SPECIAL_TAG_SNAN = 5;    public final static double UNDERFLOW_THRESHOLD = Math.pow(2.0, -1022.0);    private final Processor cpu;    double[] data;    int[] tag;    int[] specialTag;    // status word    private int statusWord;    private boolean invalidOperation;    private boolean denormalizedOperand;    private boolean zeroDivide;    private boolean overflow;    private boolean underflow;    private boolean precision;    private boolean stackFault;    public void dumpState(DataOutput output) throws IOException    {        output.writeInt(statusWord);        output.writeInt(maskWord);        output.writeInt(precisionControl);        output.writeInt(roundingControl);        output.writeBoolean(invalidOperation);        output.writeBoolean(denormalizedOperand);        output.writeBoolean(zeroDivide);        output.writeBoolean(overflow);        output.writeBoolean(underflow);        output.writeBoolean(precision);        output.writeBoolean(stackFault);        output.writeInt(data.length);        for (int i=0; i< data.length; i++)            output.writeDouble(data[i]);        output.writeInt(tag.length);        for (int i=0; i< tag.length; i++)            output.writeInt(tag[i]);        output.writeInt(specialTag.length);        for (int i=0; i< specialTag.length; i++)            output.writeInt(specialTag[i]);    }    public void loadState(DataInput input) throws IOException    {        statusWord  = input.readInt();        maskWord = input.readInt();        precisionControl = input.readInt();        roundingControl = input.readInt();        invalidOperation = input.readBoolean();        denormalizedOperand = input.readBoolean();        zeroDivide = input.readBoolean();        overflow = input.readBoolean();        underflow = input.readBoolean();        precision = input.readBoolean();        stackFault = input.readBoolean();        int len = input.readInt();        data = new double[len];        for (int i=0; i< data.length; i++)            data[i]  = input.readDouble();        len = input.readInt();        tag = new int[len];        for (int i=0; i< tag.length; i++)            tag[i] = input.readInt();        len = input.readInt();        specialTag = new int[len];        for (int i=0; i< specialTag.length; i++)            specialTag[i] = input.readInt();    }    public boolean getInvalidOperation() { return ((statusWord & 0x01) != 0); }    public boolean getDenormalizedOperand() { return ((statusWord&0x02) != 0); }    public boolean getZeroDivide() { return ((statusWord & 0x04) != 0); }    public boolean getOverflow() { return ((statusWord & 0x08) != 0); }    public boolean getUnderflow() { return ((statusWord & 0x10) != 0); }    public boolean getPrecision() { return ((statusWord & 0x20) != 0); }    public boolean getStackFault() { return ((statusWord & 0x40) != 0); }    public void setInvalidOperation() { statusWord |= 0x01;}    public void setDenormalizedOperand() { statusWord |= 0x02;}    public void setZeroDivide() { statusWord |= 0x04;}    public void setOverflow() { statusWord |= 0x08;}    public void setUnderflow() {statusWord |= 0x10;}    public void setPrecision() { statusWord |= 0x20;}    public void setStackFault() { statusWord |= 0x40;}    public boolean getBusy() { return getErrorSummaryStatus(); }    public boolean getErrorSummaryStatus()    {        // (note stack fault is a subset of invalid operation)        return (((statusWord & 0x3f) & ~maskWord) != 0);    }    public void checkExceptions() throws ProcessorException    {        if (getErrorSummaryStatus())	    cpu.reportFPUException();    }    public void clearExceptions() { statusWord = 0; }    // control word    private int maskWord;    private int precisionControl;    private int roundingControl;    public boolean getInvalidOperationMask() { return ((maskWord & 1) != 0); }    public boolean getDenormalizedOperandMask() { return ((maskWord & 2) != 0);}    public boolean getZeroDivideMask() { return ((maskWord & 4) != 0); }    public boolean getOverflowMask() { return ((maskWord & 8) != 0); }    public boolean getUnderflowMask() { return ((maskWord & 0x10) != 0); }    public boolean getPrecisionMask() { return ((maskWord & 0x20) != 0); }    public int getPrecisionControl() { return precisionControl; }    public int getRoundingControl() { return roundingControl; }    public void setInvalidOperationMask(boolean value)    {         if (value) maskWord |= 1;        else maskWord &= ~1;    }    public void setDenormalizedOperandMask(boolean value)    {         if (value) maskWord |= 2;        else maskWord &= ~2;    }    public void setZeroDivideMask(boolean value)    {         if (value) maskWord |= 4;        else maskWord &= ~4;    }    public void setOverflowMask(boolean value)    {         if (value) maskWord |= 8;        else maskWord &= ~8;    }    public void setUnderflowMask(boolean value)    {         if (value) maskWord |= 0x10;        else maskWord &= ~0x10;    }    public void setPrecisionMask(boolean value)    {         if (value) maskWord |= 0x20;        else maskWord &= ~0x20;    }    public void setAllMasks(boolean value)    {        if (value) maskWord |= 0x3f;        else maskWord = 0;    }    public void setPrecisionControl(int value)    {         if (value != FPU_PRECISION_CONTROL_DOUBLE)        {            // trying to set precision to other than double            System.err.println("WARNING:  attempt to set non-double FP " +                               "precision in Fpu64 mode");        }        precisionControl = FPU_PRECISION_CONTROL_DOUBLE;    }    public void setRoundingControl(int value)    {         if (value != FPU_ROUNDING_CONTROL_EVEN)        {            // trying to set directed or truncate rounding            System.err.println("WARNING:  attempt to set non-nearest rounding "                             + "in Fpu64 mode");        }        roundingControl = FPU_ROUNDING_CONTROL_EVEN;    }    // constructor    public FpuState64(Processor owner)    {	cpu = owner;        data = new double[STACK_DEPTH];        tag = new int[STACK_DEPTH];        specialTag = new int[STACK_DEPTH];        init();    }    public void init()    {        // tag word (and non-x87 special tags)        for (int i = 0; i < STACK_DEPTH; ++i) tag[i] = FPU_TAG_EMPTY;        for (int i = 0; i < STACK_DEPTH; ++i)            specialTag[i] = FPU_SPECIAL_TAG_NONE;        // status word        clearExceptions();        conditionCode = 0;        top = 0;        // control word        setAllMasks(true);        infinityControl = false;        setPrecisionControl(FPU_PRECISION_CONTROL_DOUBLE); // 64 bits default            // (x87 uses 80-bit precision as default!)        setRoundingControl(FPU_ROUNDING_CONTROL_EVEN); // default        lastIP = lastData = lastOpcode = 0;    }    public int tagCode(double x)    {        if (x == 0.0) return FPU_TAG_ZERO;        else if (Double.isNaN(x)||Double.isInfinite(x)) return FPU_TAG_SPECIAL;        else return FPU_TAG_VALID;    }    public static boolean isDenormal(double x)    {        long n = Double.doubleToRawLongBits(x);        int exponent = (int)((n >> 52) & 0x7ff);        if (exponent != 0) return false;        long fraction = (n & ~(0xfffL << 52));        if (fraction == 0L) return false;        return true;    }    public static boolean isSNaN(long n)    {        // have to determine this based on 64-bit bit pattern,        // since reassignment might cause Java to rationalize it to infinity        int exponent = (int)((n >> 52) & 0x7ff);        if (exponent != 0x7ff) return false;        long fraction = (n & ~(0xfffL << 52));        if ((fraction & (1L << 51)) != 0) return false;        return (fraction != 0L);    }    // SNaN's aren't generated internally by x87.  Instead, they are    // detected when they are read in from memory.  So if you push()    // from memory, find out before whether it's an SNaN, then push(),    // then set the tag word accordingly.    public static int specialTagCode(double x)    {        // decode special:  NaN, unsupported, infinity, or denormal        if (Double.isNaN(x)) return FPU_SPECIAL_TAG_NAN; // QNaN by default        else if (Double.isInfinite(x)) return FPU_SPECIAL_TAG_INFINITY;        //else if (Math.abs(x) < UNDERFLOW_THRESHOLD)        else if (isDenormal(x))            return FPU_SPECIAL_TAG_DENORMAL;        else return FPU_SPECIAL_TAG_NONE;    }    public void push(double x) throws ProcessorException    {        if (--top < 0) top = STACK_DEPTH - 1;        if (tag[top] != FPU_TAG_EMPTY)        {            setInvalidOperation();            setStackFault();            conditionCode |= 2; // C1 set to indicate stack overflow            checkExceptions();            // if IE is masked, then we just continue and overwrite        }        data[top] = x;        tag[top] = tagCode(x);        specialTag[top] = specialTagCode(x);    }//     public void pushBig(BigDecimal x) throws ProcessorException//     {//         push(x.doubleValue());//     }    public double pop() throws ProcessorException    {        if (tag[top] == FPU_TAG_EMPTY)        {            setInvalidOperation();            setStackFault();            conditionCode &= ~2; // C1 cleared to indicate stack underflow            checkExceptions();            // TODO:  if IE masked, do we just return whatever            // random contents there are?  That's what it seems            // from the reference.        }        else if (specialTag[top] == FPU_SPECIAL_TAG_SNAN)        {            setInvalidOperation();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -