fp.isa

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· ISA 代码 · 共 393 行

ISA
393
字号
// -*- mode:c++ -*-// Copyright (c) 2007 MIPS Technologies, Inc.  All Rights Reserved//  This software is part of the M5 simulator.//  THIS IS A LEGAL AGREEMENT.  BY DOWNLOADING, USING, COPYING, CREATING//  DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING//  TO THESE TERMS AND CONDITIONS.//  Permission is granted to use, copy, create derivative works and//  distribute this software and such derivative works for any purpose,//  so long as (1) the copyright notice above, this grant of permission,//  and the disclaimer below appear in all copies and derivative works//  made, (2) the copyright notice above is augmented as appropriate to//  reflect the addition of any new copyrightable work in a derivative//  work (e.g., Copyright (c) <Publication Year> Copyright Owner), and (3)//  the name of MIPS Technologies, Inc. ($(B!H(BMIPS$(B!I(B) is not used in any//  advertising or publicity pertaining to the use or distribution of//  this software without specific, written prior authorization.//  THIS SOFTWARE IS PROVIDED $(B!H(BAS IS.$(B!I(B  MIPS MAKES NO WARRANTIES AND//  DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR//  OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND//  NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE.//  IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT,//  INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF//  ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT,//  THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY//  IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR//  STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE//  POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE.//Authors: Korey L. Sewell//////////////////////////////////////////////////////////////////////// Floating Point operate instructions//output header {{	/**	 * Base class for FP operations.	 */	class FPOp : public MipsStaticInst	{		protected:				/// Constructor		FPOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)		{		}	    //std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;   	        //needs function to check for fpEnable or not	};	class FPCompareOp : public FPOp	{	  protected:	    FPCompareOp(const char *mnem, MachInst _machInst, OpClass __opClass) : FPOp(mnem, _machInst, __opClass)		{		}	    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;	};}};output decoder {{	std::string FPCompareOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const	{	    std::stringstream ss;	    ccprintf(ss, "%-10s ", mnemonic);	    ccprintf(ss,"%d",CC);	    if(_numSrcRegs > 0) {		ss << ", ";		printReg(ss, _srcRegIdx[0]);	    }	    if(_numSrcRegs > 1) {		ss << ", ";		printReg(ss, _srcRegIdx[1]);	    }    	    return ss.str();	}}};output exec {{        inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)	{	    //@TODO: Implement correct CP0 checks to see if the CP1	    // unit is enable or not	  if (!isCoprocessorEnabled(xc, 1))	     return new CoprocessorUnusableFault(1);	  return NoFault;	}        //If any operand is Nan return the appropriate QNaN        template <class T>	bool 	fpNanOperands(FPOp *inst, %(CPU_exec_context)s *xc, const T &src_type, 		      Trace::InstRecord *traceData)	{	    uint64_t mips_nan = 0;	    T src_op = 0;	    int size = sizeof(src_op) * 8;	    for (int i = 0; i < inst->numSrcRegs(); i++) {    		uint64_t src_bits = xc->readFloatRegOperandBits(inst, 0, size);		if (isNan(&src_bits, size) ) {		    if (isSnan(&src_bits, size)) {			switch (size) 			{			  case 32: mips_nan = MIPS32_QNAN; break;			  case 64: mips_nan = MIPS64_QNAN; break;			  default: panic("Unsupported Floating Point Size (%d)", size);			}		    } else {			mips_nan = src_bits;		    }		    xc->setFloatRegOperandBits(inst, 0, mips_nan, size);		    if (traceData) { traceData->setData(mips_nan); }		    return true;		} 	    }	    return false;	}        template <class T>	bool 	fpInvalidOp(FPOp *inst, %(CPU_exec_context)s *cpu, const T dest_val,		    Trace::InstRecord *traceData)	{	    uint64_t mips_nan = 0;	    T src_op = dest_val;	    int size = sizeof(src_op) * 8;	    	    if (isNan(&src_op, size)) {		switch (size) 		{		  case 32: mips_nan = MIPS32_QNAN; break;		  case 64: mips_nan = MIPS64_QNAN; break;		  default: panic("Unsupported Floating Point Size (%d)", size);		}		//Set value to QNAN		cpu->setFloatRegOperandBits(inst, 0, mips_nan, size);		//Read FCSR from FloatRegFile		uint32_t fcsr_bits = cpu->tcBase()->readFloatRegBits(FCSR);		uint32_t new_fcsr = genInvalidVector(fcsr_bits);		//Write FCSR from FloatRegFile		cpu->tcBase()->setFloatRegBits(FCSR, new_fcsr);		if (traceData) { traceData->setData(mips_nan); }		return true;	    } 	    	    return false;	}	void 	fpResetCauseBits(%(CPU_exec_context)s *cpu)	{	    //Read FCSR from FloatRegFile	    uint32_t fcsr = cpu->tcBase()->readFloatRegBits(FCSR);	    // TODO: Use utility function here	    fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);	    //Write FCSR from FloatRegFile	    cpu->tcBase()->setFloatRegBits(FCSR, fcsr);	}}};def template FloatingPointExecute {{	Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const	{		Fault fault = NoFault;		%(fp_enable_check)s;				//When is the right time to reset cause bits?		//start of every instruction or every cycle?#if FULL_SYSTEM 		fpResetCauseBits(xc);#endif		%(op_decl)s;		%(op_rd)s;		//Check if any FP operand is a NaN value 		if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {		    %(code)s;				    		    //Change this code for Full-System/Sycall Emulation		    //separation		    //----		    //Should Full System-Mode throw a fault here?		    //----		    //Check for IEEE 754 FP Exceptions		    //fault = fpNanOperands((FPOp*)this, xc, Fd, traceData);		    if (#if FULL_SYSTEM 			!fpInvalidOp((FPOp*)this, xc, Fd, traceData) &&#endif			fault == NoFault)		    {			%(op_wb)s;		    }		}		return fault;	}}};// Primary format for float point operate instructions:def format FloatOp(code, *flags) {{         	iop = InstObjParams(name, Name, 'FPOp', code, flags)	header_output = BasicDeclare.subst(iop)	decoder_output = BasicConstructor.subst(iop)	decode_block = BasicDecode.subst(iop)	exec_output = FloatingPointExecute.subst(iop)}};def format FloatCompareOp(cond_code, *flags) {{        import sys    code = 'bool cond;\n'       if '.sf' in cond_code or 'SinglePrecision' in flags:	if 'QnanException' in flags:	    code += 'if (isQnan(&Fs.sf, 32) || isQnan(&Ft.sf, 32)) {\n'	    code += '\tFCSR = genInvalidVector(FCSR);\n'	    code += '\treturn NoFault;'	    code += '}\n else '	code += 'if (isNan(&Fs.sf, 32) || isNan(&Ft.sf, 32)) {\n'    elif '.df' in cond_code or 'DoublePrecision' in flags:	if 'QnanException' in flags:	    code += 'if (isQnan(&Fs.df, 64) || isQnan(&Ft.df, 64)) {\n'	    code += '\tFCSR = genInvalidVector(FCSR);\n'	    code += '\treturn NoFault;'	    code += '}\n else '    	code += 'if (isNan(&Fs.df, 64) || isNan(&Ft.df, 64)) {\n'       else:       sys.exit('Decoder Failed: Can\'t Determine Operand Type\n')    if 'UnorderedTrue' in flags:       code += 'cond = 1;\n'        elif 'UnorderedFalse' in flags:       code += 'cond = 0;\n'    else:       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')    code += '} else {\n'    code +=  cond_code + '}'    code += 'FCSR = genCCVector(FCSR, CC, cond);\n'    iop = InstObjParams(name, Name, 'FPCompareOp', code)    header_output = BasicDeclare.subst(iop)    decoder_output = BasicConstructor.subst(iop)    decode_block = BasicDecode.subst(iop)    exec_output = BasicExecute.subst(iop)}};def format FloatConvertOp(code, *flags) {{    import sys    #Determine Source Type    convert = 'fpConvert('    if '.sf' in code:	code = 'float ' + code + '\n'	convert += 'SINGLE_TO_'    elif '.df' in code:	code = 'double ' + code + '\n'	convert += 'DOUBLE_TO_'    elif '.uw' in code:	code = 'uint32_t ' + code + '\n'	convert += 'WORD_TO_'    elif '.ud' in code:	code = 'uint64_t ' + code + '\n'	convert += 'LONG_TO_'    else:        sys.exit("Error Determining Source Type for Conversion")    #Determine Destination Type    if 'ToSingle' in flags:	code += 'Fd.uw = ' + convert + 'SINGLE, '    elif 'ToDouble' in flags:	code += 'Fd.ud = ' + convert + 'DOUBLE, '    elif 'ToWord' in flags:	code += 'Fd.uw = ' + convert + 'WORD, '    elif 'ToLong' in flags:	code += 'Fd.ud = ' + convert + 'LONG, '    else:        sys.exit("Error Determining Destination Type for Conversion")    #Figure out how to round value    if 'Ceil' in flags:	code += 'ceil(val)); '    elif 'Floor' in flags:	code += 'floor(val)); '    elif 'Round' in flags:	code += 'roundFP(val, 0)); '    elif 'Trunc' in flags:	code += 'truncFP(val));'    else:	code += 'val); '    iop = InstObjParams(name, Name, 'FPOp', code)    header_output = BasicDeclare.subst(iop)    decoder_output = BasicConstructor.subst(iop)    decode_block = BasicDecode.subst(iop)    exec_output = BasicExecute.subst(iop)}};def format FloatAccOp(code, *flags) {{         	iop = InstObjParams(name, Name, 'FPOp', code, flags)	header_output = BasicDeclare.subst(iop)	decoder_output = BasicConstructor.subst(iop)	decode_block = BasicDecode.subst(iop)	exec_output = BasicExecute.subst(iop)}};// Primary format for float64 operate instructions:def format Float64Op(code, *flags) {{	iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags)	header_output = BasicDeclare.subst(iop)	decoder_output = BasicConstructor.subst(iop)	decode_block = BasicDecode.subst(iop)	exec_output = BasicExecute.subst(iop)}};def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{        import sys    code = 'bool cond1, cond2;\n'    code += 'bool code_block1, code_block2;\n'    code += 'code_block1 = code_block2 = true;\n'     if 'QnanException' in flags:        code += 'if (isQnan(&Fs1.sf, 32) || isQnan(&Ft1.sf, 32)) {\n'	code += '\tFCSR = genInvalidVector(FCSR);\n'	code += 'code_block1 = false;'	code += '}\n'        code += 'if (isQnan(&Fs2.sf, 32) || isQnan(&Ft2.sf, 32)) {\n'	code += '\tFCSR = genInvalidVector(FCSR);\n'        code += 'code_block2 = false;'	code += '}\n'    code += 'if (code_block1) {'    code += '\tif (isNan(&Fs1.sf, 32) || isNan(&Ft1.sf, 32)) {\n'    if 'UnorderedTrue' in flags:       code += 'cond1 = 1;\n'        elif 'UnorderedFalse' in flags:       code += 'cond1 = 0;\n'    else:       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')    code += '} else {\n'    code +=  cond_code1    code += 'FCSR = genCCVector(FCSR, CC, cond1);}\n}\n'    code += 'if (code_block2) {'    code += '\tif (isNan(&Fs2.sf, 32) || isNan(&Ft2.sf, 32)) {\n'    if 'UnorderedTrue' in flags:       code += 'cond2 = 1;\n'        elif 'UnorderedFalse' in flags:       code += 'cond2 = 0;\n'    else:       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')    code += '} else {\n'    code +=  cond_code2    code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}'    iop = InstObjParams(name, Name, 'FPCompareOp', code)    header_output = BasicDeclare.subst(iop)    decoder_output = BasicConstructor.subst(iop)    decode_block = BasicDecode.subst(iop)    exec_output = BasicExecute.subst(iop)}};

⌨️ 快捷键说明

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