From a43beba0b254ba53030f425a65026c99c4d69276 Mon Sep 17 00:00:00 2001
From: Mars2Lars_NUAAers <t202410287992756@eduxiji.net>
Date: Tue, 2 Jul 2024 12:15:22 +0800
Subject: [PATCH] =?UTF-8?q?feat(InstructionSet):=20=E5=A2=9E=E5=8A=A0?=
 =?UTF-8?q?=E4=BA=86=E6=B5=AE=E7=82=B9=E8=BF=90=E7=AE=97=E6=8C=87=E4=BB=A4?=
 =?UTF-8?q?=E4=BE=8B=E5=AD=90/=E5=B0=86=E6=B5=AE=E7=82=B9=E4=BE=8B?=
 =?UTF-8?q?=E5=A4=96=E5=88=A4=E6=96=AD=E5=B0=81=E8=A3=85=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 XraysTest.asm                                 |   4 +-
 .../instructions/BasicInstruction.java        |   1 +
 .../instructions/InstructionSet.java          | 337 ++++++++++++++++--
 lars/simulator/FloatingException.java         |  96 ++++-
 .../lars/simulator/Simulator$SimThread.class  | Bin 7562 -> 7512 bytes
 .../lars/simulator/Simulator$UpdateGUI.class  | Bin 1688 -> 1658 bytes
 6 files changed, 402 insertions(+), 36 deletions(-)

diff --git a/XraysTest.asm b/XraysTest.asm
index f3735621..be1ee56a 100644
--- a/XraysTest.asm
+++ b/XraysTest.asm
@@ -1,5 +1,5 @@
 .data 
-	fib:.word 0x7F810000
+	fib:.word 0x007FFFFF
 	pi:.float 3.14
 .text
 
@@ -14,7 +14,7 @@
 	la $t1,fib
 	#fadd.s $f0,$f1,$f3
 	fld.s $f1,$t1,0
-	fadd.s $f2,$f1,$f1
+	fadd.s $f2,$f3,$f1
 	fadd.s $f2,$f2,$f1
 	fadd.s $f2,$f2,$f1
 	fadd.s $f2,$f2,$f1
diff --git a/lars/loongarch/instructions/BasicInstruction.java b/lars/loongarch/instructions/BasicInstruction.java
index be225763..8318529c 100644
--- a/lars/loongarch/instructions/BasicInstruction.java
+++ b/lars/loongarch/instructions/BasicInstruction.java
@@ -36,6 +36,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  * @author Pete Sanderson and Ken Vollmar
  * @version August 2003
  */
+
 public class BasicInstruction extends Instruction {
 
     private String instructionName;
diff --git a/lars/loongarch/instructions/InstructionSet.java b/lars/loongarch/instructions/InstructionSet.java
index 836a90c7..6841e703 100644
--- a/lars/loongarch/instructions/InstructionSet.java
+++ b/lars/loongarch/instructions/InstructionSet.java
@@ -919,6 +919,8 @@ public class InstructionSet {
 
        /////////////////////// Floating Point Instructions Start Here ////////////////
 
+
+       //---------------------------------------F{ADD/SUB/MUL/DIV}.{S/D}----------------------------------------------//
        instructionList.add(
                new BasicInstruction("fadd.s $f0,$f1,$f3",
                        "Floating point addition single precision : Set $f0 to single-precision floating point value of $f1 plus $f3",
@@ -932,63 +934,346 @@ public class InstructionSet {
                                ArrayList<Integer> exception = new ArrayList<>();
                                float src1=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[1]));
                                float src2=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[2]));
-                               Quadruple add1=new Quadruple(src1);
-                               Quadruple add2=new Quadruple(src2);
+                               Quadruple operator1=new Quadruple(src1);
+                               Quadruple operator2=new Quadruple(src2);
 
                                //非法操作异常
 
-                               if(FloatingException.isFloatSNaN(src1)||FloatingException.isFloatSNaN(src2)
+                               if(FloatingException.isSNaN(src1)||FloatingException.isSNaN(src2)
                                        ||(src1==Float.NEGATIVE_INFINITY&&src2==Float.POSITIVE_INFINITY)
                                        ||(src2==Float.NEGATIVE_INFINITY&&src1==Float.POSITIVE_INFINITY)){
                                     exception.add(FloatingException.INVALID_OPERATION);
                                }
 
                                //进行运算
-                               add1.add(add2);
+                               operator2.add(operator1);
                                //运算后舍入
-                               float result=FloatingException.getRoundOffResultFloat(add1);
-                               //舍入后进行异常判断
+                               float result=FloatingException.getRoundOffResultFloat(operator2);
+                               exception.addAll(FloatingException.getExceptionList(new Quadruple(result),operator2));
+                               //送入异常判断
+                               int ex=FloatingException.isFloatingTrapIn(exception);
+                               if(ex!=-1){
+                                   throw new ProcessingException(statement,FloatingException.getExceptionMessage(ex),ex,(Coprocessor0.getValue(Coprocessor0.FCSR3)&0x0000_0300)>>8);
+                               }
+
+                               //判断是否有Nan的存在 选择最优先的Nan作为结果
+                               if(FloatingException.isContainQNaN(src1,src2)){
+                                  result=FloatingException.getPriorityQNaN(src1,src2);
+                              }
+                               Coprocessor1.updateRegisterFloat(operands[0], Float.floatToIntBits(result));
+                           }
+                       }));
+
+       //---------------------------------------F{MADD/MSUB/NMADD/NMSUB}.{S/D}----------------------------------------------//
 
+       //f0 = f1*f2 + f3
+       instructionList.add(
+               new BasicInstruction("fmadd.s $f0,$f1,$f2,$f3",
+                       "Floating point addition single precision : Set $f0 to single-precision floating point value of $f1 plus $f3",
+                       BasicInstructionFormat.FOUR_R_TYPE,
+                       "000010000001 ddddd ccccc bbbbb aaaaa",
+                       new SimulationCode()
+                       {
+                           public void simulate(ProgramStatement statement) throws ProcessingException
+                           {
                                //创建异常数组
-                                //异常捕获
+                               int[] operands = statement.getOperands();
+                               ArrayList<Integer> exception = new ArrayList<>();
+                               float src1=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[1]));
+                               float src2=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[2]));
+                               float src3=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[3]));
+                               Quadruple operator1=new Quadruple(src1);
+                               Quadruple operator2=new Quadruple(src2);
+                               Quadruple operator3=new Quadruple(src3);
+                               //非法操作异常
+                               if(FloatingException.isSNaN(src1)
+                                       ||FloatingException.isSNaN(src2)
+                                       ||FloatingException.isSNaN(src3) //对SNan的操作
+                                       ||(src1==Float.NEGATIVE_INFINITY&&src2==Float.POSITIVE_INFINITY) //正负无穷相加
+                                       ||(src2==Float.NEGATIVE_INFINITY&&src1==Float.POSITIVE_INFINITY)
+                                       ||(Float.isInfinite(src1*src2)&&src3==0)){//0和无穷做乘法
+                                   exception.add(FloatingException.INVALID_OPERATION);
+                               }
+                               //进行运算
+                               operator2.multiply(operator1);
+                               operator2.add(operator3);
+                               //运算后舍入
+                               float result=FloatingException.getRoundOffResultFloat(operator2);
+                               exception.addAll(FloatingException.getExceptionList(new Quadruple(result),operator2));
+                               //送入异常判断
+                               int ex=FloatingException.isFloatingTrapIn(exception);
+                               if(ex!=-1){
+                                   throw new ProcessingException(statement,FloatingException.getExceptionMessage(ex),ex,(Coprocessor0.getValue(Coprocessor0.FCSR3)&0x0000_0300)>>8);
+                               }
 
-                               //非精确异常
-                               if(FloatingException.isInexact(add1,new Quadruple(result))){
-                                   exception.add(FloatingException.INEXACT);
+                               //判断是否有Nan的存在 选择最优先的Nan作为结果
+                               if(FloatingException.isContainQNaN(src1,src2,src3)){
+                                   result=FloatingException.getPriorityQNaN(src1,src2,src3);
                                }
 
-                               //下溢异常
-                               if(FloatingException.isUnderflowDouble(add1)){
-                                   if(FloatingException.isInexact(add1,new Quadruple(result))
-                                   ||(Coprocessor0.getValue(Coprocessor0.FCSR1)&0x0000_0002)!=0){
-                                       exception.add(FloatingException.UNDERFLOW);
-                                   }
+                               Coprocessor1.updateRegisterFloat(operands[0], Float.floatToIntBits(result));
+                           }
+                       }));
+
+       //---------------------------------------F{MAX/MIN}.{S/D}----------------------------------------------//
+       instructionList.add(
+               new BasicInstruction("fmax.s $f0,$f1,$f2",
+                       "Floating point addition single precision : Set $f0 to single-precision floating point value of $f1 plus $f3",
+                       BasicInstructionFormat.THREE_R_TYPE,
+                       "00000001000010001 ccccc bbbbb aaaaa",
+                       new SimulationCode()
+                       {
+                           public void simulate(ProgramStatement statement) throws ProcessingException
+                           {
+                               //创建异常数组
+                               int[] operands = statement.getOperands();
+                               ArrayList<Integer> exception = new ArrayList<>();
+                               float src1=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[1]));
+                               float src2=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[2]));
+                               Quadruple operator1=new Quadruple(src1);
+                               Quadruple operator2=new Quadruple(src2);
+                               //非法操作异常
+                               if(FloatingException.isSNaN(src1)
+                                       ||FloatingException.isSNaN(src2)){
+                                   exception.add(FloatingException.INVALID_OPERATION);
                                }
+                               //进行运算
+                               operator2.assignMax(operator1);
+                               //运算后舍入
+                               float result=FloatingException.getRoundOffResultFloat(operator2);
+                               //获取例外列表
+                               exception.addAll(FloatingException.getExceptionList(new Quadruple(result),operator2));
+                               //送入异常判断
+                               int ex=FloatingException.isFloatingTrapIn(exception);
+                               if(ex!=-1){
+                                   throw new ProcessingException(statement,FloatingException.getExceptionMessage(ex),ex,(Coprocessor0.getValue(Coprocessor0.FCSR3)&0x0000_0300)>>8);
+                               }
+                               //判断是否有Nan的存在 选择最优先的Nan作为结果
+                               if(FloatingException.isContainQNaN(src1,src2)){
+                                   result=FloatingException.getPriorityQNaN(src1,src2);
+                               }
+                               Coprocessor1.updateRegisterFloat(operands[0], Float.floatToIntBits(result));
+                           }
+                       }));
+
 
-                               //上溢异常
-                               if(FloatingException.isOverflowFloat(add1)){
-                                   exception.add(FloatingException.OVERFLOW);
+       //---------------------------------------F{MAXA/MINA}.{S/D}----------------------------------------------//
+       instructionList.add(
+               new BasicInstruction("fmaxa.s $f0,$f1,$f2",
+                       "Floating point addition single precision : Set $f0 to single-precision floating point value of $f1 plus $f3",
+                       BasicInstructionFormat.THREE_R_TYPE,
+                       "00000001000011001 ccccc bbbbb aaaaa",
+                       new SimulationCode()
+                       {
+                           public void simulate(ProgramStatement statement) throws ProcessingException
+                           {
+                               //创建异常数组
+                               int[] operands = statement.getOperands();
+                               ArrayList<Integer> exception = new ArrayList<>();
+                               float src1=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[1]));
+                               float src2=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[2]));
+                               Quadruple operator1=new Quadruple(src1);
+                               Quadruple operator2=new Quadruple(src2);
+                               //非法操作异常
+                               if(FloatingException.isSNaN(src1)
+                                       ||FloatingException.isSNaN(src2)){
+                                   exception.add(FloatingException.INVALID_OPERATION);
                                }
+                               operator2.abs();
+                               operator1.abs();
+                               //进行运算
+                               operator2.assignMax(operator1);
+                               //运算后舍入
+                               float result;
+                               if(operator2.equals(operator2.abs())){
+                                   result=FloatingException.getRoundOffResultFloat(new Quadruple(src2));
+                                   operator2=new Quadruple(src2);
+                                   exception.addAll(FloatingException.getExceptionList(new Quadruple(result),operator2));
+                               }
+                               else{
+                                   result=FloatingException.getRoundOffResultFloat(new Quadruple(src1));
+                                   operator1=new Quadruple(src1);
+                                   exception.addAll(FloatingException.getExceptionList(new Quadruple(result),operator2));
+                               }
+                               int ex=FloatingException.isFloatingTrapIn(exception);
+                               if(ex!=-1){
+                                   throw new ProcessingException(statement,FloatingException.getExceptionMessage(ex),ex,(Coprocessor0.getValue(Coprocessor0.FCSR3)&0x0000_0300)>>8);
+                               }
+                               //判断是否有Nan的存在 选择最优先的Nan作为结果
+                               if(FloatingException.isContainQNaN(src1,src2)){
+                                   result=FloatingException.getPriorityQNaN(src1,src2);
+                               }
+                               Coprocessor1.updateRegisterFloat(operands[0], Float.floatToIntBits(result));
+                           }
+                       }));
 
-                               //除0异常 没有
+       //---------------------------------------F{ABS/NEG}.{S/D}----------------------------------------------//
 
+       instructionList.add(
+               new BasicInstruction("fabs.s $f0,$f1",
+                       "Floating point addition single precision : Set $f0 to single-precision floating point value of $f1 plus $f3",
+                       BasicInstructionFormat.TWO_R_TYPE,
+                       "0000000100010100000001 bbbbb aaaaa",
+                       new SimulationCode()
+                       {
+                           public void simulate(ProgramStatement statement) throws ProcessingException
+                           {
+                               //创建异常数组
+                               int[] operands = statement.getOperands();
+                               ArrayList<Integer> exception = new ArrayList<>();
+                               float src1=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[1]));
+                               Quadruple operator1=new Quadruple(src1);
+                               //非法操作异常
+                               if(FloatingException.isSNaN(src1)){
+                                   exception.add(FloatingException.INVALID_OPERATION);
+                               }
+                               //进行运算
+                               operator1.abs();
+                               //运算后舍入
+                               float result=FloatingException.getRoundOffResultFloat(operator1);
+                               //获取例外列表
+                               exception.addAll(FloatingException.getExceptionList(new Quadruple(result),operator1));
                                //送入异常判断
                                int ex=FloatingException.isFloatingTrapIn(exception);
                                if(ex!=-1){
                                    throw new ProcessingException(statement,FloatingException.getExceptionMessage(ex),ex,(Coprocessor0.getValue(Coprocessor0.FCSR3)&0x0000_0300)>>8);
                                }
+                               //判断是否有Nan的存在 选择最优先的Nan作为结果
+                               if(FloatingException.isQNaN(src1)){
+                                   result=src1;
+                               }
+                               Coprocessor1.updateRegisterFloat(operands[0], Float.floatToIntBits(result));
+                           }
+                       }));
+       //---------------------------------------F{SQRT/RECIP/RSQRT}.{S/D}----------------------------------------------//
 
+       instructionList.add(
+               new BasicInstruction("fsqrt.s $f0,$f1",
+                       "Floating point addition single precision : Set $f0 to single-precision floating point value of $f1 plus $f3",
+                       BasicInstructionFormat.TWO_R_TYPE,
+                       "0000000100010100010001 bbbbb aaaaa",
+                       new SimulationCode()
+                       {
+                           public void simulate(ProgramStatement statement) throws ProcessingException
+                           {
+                               //创建异常数组
+                               int[] operands = statement.getOperands();
+                               ArrayList<Integer> exception = new ArrayList<>();
+                               float src1=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[1]));
+                               Quadruple operator1=new Quadruple(src1);
+                               //非法操作异常
+                               if(FloatingException.isSNaN(src1)){
+                                   exception.add(FloatingException.INVALID_OPERATION);
+                               }
+                               //进行运算
+                               operator1.sqrt();
+                               //运算后舍入
+                               float result=FloatingException.getRoundOffResultFloat(operator1);
+                               //获取例外列表
+                               exception.addAll(FloatingException.getExceptionList(new Quadruple(result),operator1));
+                               //送入异常判断
+                               int ex=FloatingException.isFloatingTrapIn(exception);
+                               if(ex!=-1){
+                                   throw new ProcessingException(statement,FloatingException.getExceptionMessage(ex),ex,(Coprocessor0.getValue(Coprocessor0.FCSR3)&0x0000_0300)>>8);
+                               }
+                               //判断是否有Nan的存在 选择最优先的Nan作为结果
+                               if(FloatingException.isQNaN(src1)){
+                                   result=src1;
+                               }
+                               Coprocessor1.updateRegisterFloat(operands[0], Float.floatToIntBits(result));
+                           }
+                       }));
+       //---------------------------------------FCOPYSIGN.{S/D}----------------------------------------------//
+       instructionList.add(
+               new BasicInstruction("fcopysign.s $f0,$f1,$f2",
+                       "Floating point addition single precision : Set $f0 to single-precision floating point value of $f1 plus $f3",
+                       BasicInstructionFormat.THREE_R_TYPE,
+                       "00000001000100101 ccccc bbbbb aaaaa",
+                       new SimulationCode()
+                       {
+                           public void simulate(ProgramStatement statement) throws ProcessingException
+                           {
+                               //创建异常数组
+                               int[] operands = statement.getOperands();
+                               ArrayList<Integer> exception = new ArrayList<>();
+                               float src1=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[1]));
+                               float src2=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[2]));
+                               Quadruple operator1=new Quadruple(src1);
+                               Quadruple operator2=new Quadruple(src2);
+                               //非法操作异常
+                               if(FloatingException.isSNaN(src1)
+                                       ||FloatingException.isSNaN(src2)){
+                                   exception.add(FloatingException.INVALID_OPERATION);
+                               }
+                               //进行运算
+                               //如果符号不同就取反
+                               if((operator1.isNegative()&&!operator2.isNegative())
+                                       ||(!operator1.isNegative()&&operator2.isNegative())){
+                                   operator1.negate();
+                               }
+                               //运算后舍入
+                               float result=FloatingException.getRoundOffResultFloat(operator1);
 
+                               exception.addAll(FloatingException.getExceptionList(new Quadruple(result),operator1));
 
-                               // overflow detected when sum is positive or negative infinity.
-                  /*
-                  if (sum == Float.NEGATIVE_INFINITY || sum == Float.POSITIVE_INFINITY) {
-                    throw new ProcessingException(statement,"arithmetic overflow");
-                  }
-                  */
+                               int ex=FloatingException.isFloatingTrapIn(exception);
+                               if(ex!=-1){
+                                   throw new ProcessingException(statement,FloatingException.getExceptionMessage(ex),ex,(Coprocessor0.getValue(Coprocessor0.FCSR3)&0x0000_0300)>>8);
+                               }
+                               //判断是否有Nan的存在 选择最优先的Nan作为结果
+                               if(FloatingException.isContainQNaN(src1,src2)){
+                                   result=FloatingException.getPriorityQNaN(src1,src2);
+                               }
                                Coprocessor1.updateRegisterFloat(operands[0], Float.floatToIntBits(result));
                            }
                        }));
+       //---------------------------------------FCLASS.{S/D}----------------------------------------------//
+
+       instructionList.add(
+               new BasicInstruction("fsqrt.s $f0,$f1",
+                       "Floating point addition single precision : Set $f0 to single-precision floating point value of $f1 plus $f3",
+                       BasicInstructionFormat.TWO_R_TYPE,
+                       "0000000100010100001101  bbbbb aaaaa",
+                       new SimulationCode()
+                       {
+                           public void simulate(ProgramStatement statement) throws ProcessingException
+                           {
+                               int[] operands = statement.getOperands();
+                               float src1=Float.intBitsToFloat(Coprocessor1.get32bitValue(operands[1]));
+                               Quadruple operator1=new Quadruple(src1);
+                               //进行运算
+                               int result=0;
+                               int positiveBias=2;
+                               int negativeBias=2+4;
+                               boolean isPositive=((Float.floatToRawIntBits(src1)&FloatingException.FLOAT_SIGN_MASK)==0);
+                               //SNan
+                               if(FloatingException.isSNaN(src1)){
+                                   result=1;
+                               }
+                               //QNan
+                               else if(FloatingException.isQNaN(src1)){
+                                   result=1<<1;
+                               }
+                               //positive
+                               else{
+                                    if(Float.isInfinite(src1)){
+                                        result=1<<((isPositive?positiveBias:negativeBias));
+                                    }
+                                    else if((Float.floatToRawIntBits(src1)&FloatingException.FLOAT_EXPONENT_MASK)!=0){
+                                        result=1<<((isPositive?positiveBias:negativeBias)+1);
+                                    }
+                                    else if((Float.floatToRawIntBits(src1)&FloatingException.FLOAT_EXPONENT_MASK)==0&&src1!=0){
+                                        result=1<<((isPositive?positiveBias:negativeBias)+2);
+                                    }
+                                    else{
+                                        result=1<<((isPositive?positiveBias:negativeBias)+3);
+                                    }
+                               }
+                               Coprocessor1.updateRegisterFloat(operands[0], result);
+                           }
+                       }));
+       //---------------------------------------FCMP.cond.{S/D}----------------------------------------------//
+
        instructionList.add(
                new BasicInstruction("fld.s $f1,$t2,-1000",
                        "Load word into Coprocessor 1 (FPU) : Set $f1 to 32-bit value from effective memory word address",
diff --git a/lars/simulator/FloatingException.java b/lars/simulator/FloatingException.java
index 79966fe4..97562864 100644
--- a/lars/simulator/FloatingException.java
+++ b/lars/simulator/FloatingException.java
@@ -2,7 +2,6 @@ package lars.simulator;
 
 import lars.Quadruple;
 import lars.loongarch.hardware.Coprocessor0;
-import lars.loongarch.hardware.RegisterFile;
 
 import java.util.ArrayList;
 
@@ -188,14 +187,14 @@ public class FloatingException {
     }
 
     //判断是规格化是非规格化
-    public static boolean isNormal(double d){
+    public static boolean isSubNormal(double d){
         if(Double.isNaN(d)|| Double.isInfinite(d)){
             return false;
         }
         return d<Double.MIN_NORMAL && d>(-Double.MIN_NORMAL) && d!=0;
     }
 
-    public static boolean isNormal(float f){
+    public static boolean isSubNormal(float f){
         if(Float.isNaN(f)|| Float.isInfinite(f)){
             return false;
         }
@@ -226,26 +225,107 @@ public class FloatingException {
      *other is infinite
      */
 
-    //todo 对于指令的Nan和Inf情况的舍入,以及例外判断情况仍未实现。
     //按理来说程序不会无缘无故提供一个sNan
     //判断NAN是静默的还是非静默的
-    public static boolean isFloatSNaN(float f){
+    public static boolean isSNaN(float f){
         return Float.isNaN(f)&((Float.floatToIntBits(f)>>22)&1)==1;
     }
 
-    public static boolean isFloatQNaN(float f){
+    public static boolean isQNaN(float f){
         return Float.isNaN(f)&((Float.floatToIntBits(f)>>22)&1)==0;
     }
 
-    public static boolean isDoubleSNaN(double f){
+    public static boolean isSNaN(double f){
         return Double.isNaN(f)&((Double.doubleToRawLongBits(f)>>51)&1)==1;
     }
 
-    public static boolean isDoubleQNaN(double f){
+    public static boolean isQNaN(double f){
         return Double.isNaN(f)&((Double.doubleToRawLongBits(f)>>51)&1)==0;
     }
 
 
+    //使用getPriorityQNan之前需要判断是否存在QNan
+    public static boolean isContainQNaN(float fa,float fj,float fk){
+        return isQNaN(fa)|| isQNaN(fj)|| isQNaN(fk);
+    }
+
+    public static boolean isContainQNaN(float fa,float fj){
+        return isQNaN(fa)|| isQNaN(fj);
+    }
+
+    public static float getPriorityQNaN(float fa,float fj,float fk){
+        if(isQNaN(fa))
+            return fa;
+        if(isQNaN(fj))
+            return fj;
+        if(isQNaN(fk))
+            return fk;
+        return 0;
+    }
+
+    public static float getPriorityQNaN(float fa,float fj){
+        if(isQNaN(fa))
+            return fa;
+        if(isQNaN(fj))
+            return fj;
+        return 0;
+    }
+
+    public static boolean isContainQNaN(double fa,double fj,double fk){
+        return isQNaN(fa)|| isQNaN(fj)|| isQNaN(fk);
+    }
+
+    public static boolean isContainQNaN(double fa,double fj){
+        return isQNaN(fa)|| isQNaN(fj);
+    }
+
+    public static double getPriorityQNaN(double fa,double fj,double fk){
+        if(isQNaN(fa))
+            return fa;
+        if(isQNaN(fj))
+            return fj;
+        if(isQNaN(fk))
+            return fk;
+        return 0;
+    }
+
+    public static double getPriorityQNaN(double fa,double fj){
+        if(isQNaN(fa))
+            return fa;
+        if(isQNaN(fj))
+            return fj;
+        return 0;
+    }
+
+    //获取例外列表 (此方法不包含非法操作例外和除零例外的获取,只对舍入结果和中间结果判断相关例外有效)
+
+    public static ArrayList<Integer> getExceptionList(Quadruple result,Quadruple intermediateResult){
+        ArrayList<Integer> exception=new ArrayList<>();
+        //非精确
+        if(FloatingException.isInexact(intermediateResult,result)){
+            exception.add(FloatingException.INEXACT);
+        }
+
+        //下溢异常
+        if(FloatingException.isUnderflowDouble(intermediateResult)){
+            //如果是精确的 cause就不置为1
+            //如果是非精确的 cause就置为1
+            //如果是陷入的 无论是否精确都要置为1
+            if(FloatingException.isInexact(intermediateResult,result)
+                    ||(Coprocessor0.getValue(Coprocessor0.FCSR1)&0x0000_0002)!=0){
+                exception.add(FloatingException.UNDERFLOW);
+            }
+        }
+
+        //上溢异常
+        if(FloatingException.isOverflowFloat(intermediateResult)){
+            exception.add(FloatingException.OVERFLOW);
+        }
+        return exception;
+    }
+
+
+
     //判断正负无穷直接调用库函数即可
 
 
diff --git a/out/production/LARS/lars/simulator/Simulator$SimThread.class b/out/production/LARS/lars/simulator/Simulator$SimThread.class
index b9d711e7efdc06155dc207fafbf6c75f3768ab91..fccc5fab4dcefdff38d31248dcf8de6cf7907679 100644
GIT binary patch
delta 438
zcmXYsy-!nN6vm(Dy|pji+tA)C4KcNafes}2MKmPVgvmkD3JL;Rq*hA-Q9vnzw!*|>
zOc~z9P5uYcG$ss^5T?2?5*7v<jFU5x2nWJ)&U1bz&-wVA*u7)d{%`yMaF<K#_E4}=
z2&TywW+xP8&K!iwZqUzZn=_o%d>cTC?@Z0zvKm-03vQh6%{TXo`Qk-=ABniR?lqgg
zo;E+di@p*OI|oJ5OkFzmgG}*(S#9cZdeI3=-N%QOdeg59%a7O(3n}C|z{gOu;c^hI
zaM*?fhd3<iE0TP|rwA~IC0xZdI931|o_Zb2!o-=^2COySXOFzqZDp7i2T@gjI3n{D
zzN_D85oKXR)%lF0@L@Bg_L&js$F|zzbB>z9NEfrF9Esn|YOH8fL5(ps9-`x(=F5N3
zUPJq>&Q>R{8Dmm<N0@Y!{4`dnM{ct@&vDrX)Xr}Sqsj@6n;X%V#H4V=SDZS{VtFmO
aQOFz7b7yg$3&K3<`h+b4{J<hV;qnQ4|5vI2

delta 497
zcmZXPJx>&26ot=uXWf^~Y}lC*L&)Mn!4xJck!VO<5-SS{EBFa2>oCjCvaEdQGN34e
zjg5uPn^^K6WV11$(8O5L(ij^HOpHH4O~4DW;}-WmIXCBie7*dpVDId2e*`eZjraC=
z)^m$-Qd_KyMU7}aPU6N=Gt8FQIZe3rXeH{Oixy`3N6YniI?;^HuKU(%<Dwb#13ob&
zzuU{ExnwipvgS$#YkX=N-e<GwpH96X0<-A_Y0Z~JUNCR={DjI(oID6vlq<T@z$;ha
zc#zjQYDyi$&KL$jkT-a<xz(|EV&fKX!$J{N-r-#++VD7zUO4PSffKwZ^bRAu&j-k`
zf_0q3c{o-EArHNdWubQDwE=6B*ElTuuUH``#X+>xFP3DU!Uy#eJwg_?)ek;oh!j4#
z>N}?d)A*vkF=A-?a)T_J$y{)utnpf-1!}}>|BbU(H7kFh{kAg~2YQ{VW}YL``-@pe
z$xqehR_+ozXIPVMz|Q|$PNBtF*35o)PoXZl;v>!-R<X=WZ5O2>yl|8s^O<PAbW@_O
L0({OjuA}Q8JjY<c

diff --git a/out/production/LARS/lars/simulator/Simulator$UpdateGUI.class b/out/production/LARS/lars/simulator/Simulator$UpdateGUI.class
index d637808ce7da02d8ef4e10969efc40697fa45901..ffc87a2ebc2ff97fc1ff10b6c3069f8cf92777b1 100644
GIT binary patch
delta 94
zcmbQi`-_L`)W2Q(7#J9A7?L(}?P8gHoyDFdo{>Rf@_ZJF$wsUejEs}BS*@8F86qcd
rVcn@61ystyz@){;z|0U0WHT|uFvNoCIEDlu&Bee76pLd>WMBdSkmeGS

delta 123
zcmeyxGlQ4w)W2Q(7#J9A7?L+~?P3uW@J%hr$WIAKEK1BxElDjZo_vVKktKnVL1OZJ
z7KzF7tQL$+lOtHI`67XuSQ!}@1Oylu8KNdnW8JA84HRNwVAA4aU}lH`vY8lS8REcn
TJVPRo<^rl@Vu)u*VqgLQ7oQnt

-- 
GitLab