/* * FPArithmeticInstructions.java * * 30th may 2007 * (c) 2006 EduMips64 project - Trubia Massimo * * This file is part of the EduMIPS64 project, and is released under the GNU * General Public License. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.edumips64.core.is; import org.edumips64.core.*; import org.edumips64.utils.*; import org.edumips64.core.fpu.*; //per diagnostica /**This is the base class for the floatiing point arithmetic instructions * * @author Trubia Massimo */ public abstract class FPArithmeticInstructions extends ComputationalInstructions { final static int FD_FIELD = 0; final static int FS_FIELD = 1; final static int FT_FIELD = 2; static String COP1_FIELD = "010001"; final static int COP1_FIELD_INIT = 0; final static int FD_FIELD_INIT = 21; final static int FS_FIELD_INIT = 16; final static int FT_FIELD_INIT = 11; final static int FD_FIELD_LENGTH = 5; final static int FS_FIELD_LENGTH = 5; final static int FT_FIELD_LENGTH = 5; final static int OPCODE_VALUE_INIT = 26; final static int FMT_FIELD_INIT = 6; String OPCODE_VALUE = ""; String FMT_FIELD = ""; FPInstructionUtils fpInstructionUtils; FPArithmeticInstructions(FCSRRegister fcsr) { syntax = "%F,%F,%F"; paramCount = 3; fpInstructionUtils = new FPInstructionUtils(fcsr); } public void ID() throws RAWException, IrregularWriteOperationException, IrregularStringOfBitsException, WAWException { //if source registers are valid passing their own values into temporary registers RegisterFP fs = cpu.getRegisterFP(params.get(FS_FIELD)); RegisterFP ft = cpu.getRegisterFP(params.get(FT_FIELD)); if (fs.getWriteSemaphore() > 0 || ft.getWriteSemaphore() > 0) { throw new RAWException(); } TRfp[FS_FIELD].setBits(fs.getBinString(), 0); TRfp[FT_FIELD].setBits(ft.getBinString(), 0); //locking the destination register RegisterFP fd = cpu.getRegisterFP(params.get(FD_FIELD)); if (fd.getWAWSemaphore() > 0) { throw new WAWException(); } fd.incrWriteSemaphore(); fd.incrWAWSemaphore(); } public void EX() throws IrregularStringOfBitsException, IntegerOverflowException, TwosComplementSumException, IrregularWriteOperationException, DivisionByZeroException, FPInvalidOperationException, FPUnderflowException, FPOverflowException, FPDivideByZeroException { //getting values from temporary registers String operand1 = TRfp[FS_FIELD].getBinString(); String operand2 = TRfp[FT_FIELD].getBinString(); String outputstring = null; try { outputstring = doFPArith(operand1, operand2); TRfp[FD_FIELD].setBits(outputstring, 0); } catch (Exception ex) { //if the enable forwarding is turned on we have to ensure that registers //should be unlocked also if a synchronous exception occurs. This is performed //by executing the WB method before raising the trap if (cpu.isEnableForwarding()) { doWB(); } if (ex instanceof FPInvalidOperationException) { throw new FPInvalidOperationException(); } else if (ex instanceof FPUnderflowException) { throw new FPUnderflowException(); } else if (ex instanceof FPOverflowException) { throw new FPOverflowException(); } else if (ex instanceof FPDivideByZeroException) { throw new FPDivideByZeroException(); } else if (ex instanceof IrregularStringOfBitsException) { throw new IrregularStringOfBitsException(); } } if (cpu.isEnableForwarding()) { doWB(); } } protected abstract String doFPArith(String operand1, String operand2) throws FPInvalidOperationException, FPUnderflowException, FPOverflowException, FPDivideByZeroException, IrregularStringOfBitsException; public void MEM() throws IrregularStringOfBitsException, MemoryElementNotFoundException { cpu.getRegisterFP(params.get(FD_FIELD)).decrWAWSemaphore(); } public void WB() throws IrregularStringOfBitsException { if (!cpu.isEnableForwarding()) { doWB(); } } public void doWB() throws IrregularStringOfBitsException { //passing result from temporary register to destination register and unlocking it cpu.getRegisterFP(params.get(FD_FIELD)).setBits(TRfp[FD_FIELD].getBinString(), 0); cpu.getRegisterFP(params.get(FD_FIELD)).decrWriteSemaphore(); } public void pack() throws IrregularStringOfBitsException { //conversion of instruction parameters of "params" list to the "repr" form (32 binary value) repr.setBits(OPCODE_VALUE, OPCODE_VALUE_INIT); repr.setBits(Converter.intToBin(FS_FIELD_LENGTH, params.get(FS_FIELD)), FS_FIELD_INIT); repr.setBits(Converter.intToBin(FT_FIELD_LENGTH, params.get(FT_FIELD)), FT_FIELD_INIT); repr.setBits(Converter.intToBin(FD_FIELD_LENGTH, params.get(FD_FIELD)), FD_FIELD_INIT); repr.setBits(COP1_FIELD, COP1_FIELD_INIT); repr.setBits(FMT_FIELD, FMT_FIELD_INIT); } }