fpop.isa revision 9894
16242Sgblack@eecs.umich.edu// Copyright (c) 2007 The Hewlett-Packard Development Company 214128Sgiacomo.travaglini@arm.com// Copyright (c) 2012-2013 Mark D. Hill and David A. Wood 37093Sgblack@eecs.umich.edu// All rights reserved. 47093Sgblack@eecs.umich.edu// 57093Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall 67093Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual 77093Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating 87093Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software 97093Sgblack@eecs.umich.edu// licensed hereunder. You may use the software subject to the license 107093Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated 117093Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software, 127093Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form. 137093Sgblack@eecs.umich.edu// 146242Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 156242Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 166242Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 176242Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 186242Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 196242Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 206242Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 216242Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 226242Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 236242Sgblack@eecs.umich.edu// this software without specific prior written permission. 246242Sgblack@eecs.umich.edu// 256242Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 266242Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 276242Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 286242Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 296242Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 306242Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 316242Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326242Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 336242Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 346242Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 356242Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 366242Sgblack@eecs.umich.edu// 376242Sgblack@eecs.umich.edu// Authors: Gabe Black 386242Sgblack@eecs.umich.edu// Nilay Vaish 396242Sgblack@eecs.umich.edu 406242Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////// 4110037SARM gem5 Developers// 426242Sgblack@eecs.umich.edu// FpOp Microop templates 436242Sgblack@eecs.umich.edu// 446242Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////// 456242Sgblack@eecs.umich.edu 4610037SARM gem5 Developersdef template MicroFpOpExecute {{ 4711939Snikos.nikoleris@arm.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 4810037SARM gem5 Developers Trace::InstRecord *traceData) const 4913115Sgiacomo.travaglini@arm.com { 509256SAndreas.Sandberg@arm.com Fault fault = NoFault; 516242Sgblack@eecs.umich.edu 5210037SARM gem5 Developers DPRINTF(X86, "The data size is %d\n", dataSize); 5310037SARM gem5 Developers %(op_decl)s; 5410037SARM gem5 Developers %(op_rd)s; 556242Sgblack@eecs.umich.edu 566242Sgblack@eecs.umich.edu if(%(cond_check)s) 576242Sgblack@eecs.umich.edu { 5813392Sgiacomo.travaglini@arm.com %(code)s; 5913392Sgiacomo.travaglini@arm.com %(flag_code)s; 6013392Sgiacomo.travaglini@arm.com %(tag_code)s; 6113392Sgiacomo.travaglini@arm.com %(top_code)s; 6213392Sgiacomo.travaglini@arm.com } 6313392Sgiacomo.travaglini@arm.com else 6413392Sgiacomo.travaglini@arm.com { 6513392Sgiacomo.travaglini@arm.com %(else_code)s; 6613392Sgiacomo.travaglini@arm.com } 6713392Sgiacomo.travaglini@arm.com 6813392Sgiacomo.travaglini@arm.com //Write the resulting state to the execution context 6913392Sgiacomo.travaglini@arm.com if(fault == NoFault) 7013392Sgiacomo.travaglini@arm.com { 7113392Sgiacomo.travaglini@arm.com %(op_wb)s; 7213392Sgiacomo.travaglini@arm.com } 737259Sgblack@eecs.umich.edu return fault; 7410037SARM gem5 Developers } 7513392Sgiacomo.travaglini@arm.com}}; 7613392Sgiacomo.travaglini@arm.com 7713392Sgiacomo.travaglini@arm.comdef template MicroFpOpDeclare {{ 7813392Sgiacomo.travaglini@arm.com class %(class_name)s : public %(base_class)s 7913392Sgiacomo.travaglini@arm.com { 8013392Sgiacomo.travaglini@arm.com public: 8113392Sgiacomo.travaglini@arm.com %(class_name)s(ExtMachInst _machInst, 8213392Sgiacomo.travaglini@arm.com const char * instMnem, uint64_t setFlags, 8313392Sgiacomo.travaglini@arm.com InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, 8413392Sgiacomo.travaglini@arm.com uint8_t _dataSize, int8_t _spm); 8513392Sgiacomo.travaglini@arm.com 8613392Sgiacomo.travaglini@arm.com %(BasicExecDeclare)s 8713392Sgiacomo.travaglini@arm.com }; 8813392Sgiacomo.travaglini@arm.com}}; 8913392Sgiacomo.travaglini@arm.com 908868SMatt.Horsnell@arm.comdef template MicroFpOpConstructor {{ 9110037SARM gem5 Developers inline %(class_name)s::%(class_name)s( 9213392Sgiacomo.travaglini@arm.com ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 9313392Sgiacomo.travaglini@arm.com InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, 9413392Sgiacomo.travaglini@arm.com uint8_t _dataSize, int8_t _spm) : 9513392Sgiacomo.travaglini@arm.com %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 9613392Sgiacomo.travaglini@arm.com _src1, _src2, _dest, _dataSize, _spm, 9713392Sgiacomo.travaglini@arm.com %(op_class)s) 9813392Sgiacomo.travaglini@arm.com { 9913392Sgiacomo.travaglini@arm.com %(constructor)s; 10013392Sgiacomo.travaglini@arm.com } 10113392Sgiacomo.travaglini@arm.com}}; 10213392Sgiacomo.travaglini@arm.com 10313392Sgiacomo.travaglini@arm.comlet {{ 10413392Sgiacomo.travaglini@arm.com # Make these empty strings so that concatenating onto 10513392Sgiacomo.travaglini@arm.com # them will always work. 10613392Sgiacomo.travaglini@arm.com header_output = "" 10713392Sgiacomo.travaglini@arm.com decoder_output = "" 10813392Sgiacomo.travaglini@arm.com exec_output = "" 10913392Sgiacomo.travaglini@arm.com 11013392Sgiacomo.travaglini@arm.com class FpOpMeta(type): 11113392Sgiacomo.travaglini@arm.com def buildCppClasses(self, name, Name, suffix, \ 11213392Sgiacomo.travaglini@arm.com code, flag_code, cond_check, else_code, op_class): 11313392Sgiacomo.travaglini@arm.com 11413392Sgiacomo.travaglini@arm.com # Globals to stick the output in 11513392Sgiacomo.travaglini@arm.com global header_output 11613392Sgiacomo.travaglini@arm.com global decoder_output 11713392Sgiacomo.travaglini@arm.com global exec_output 11813392Sgiacomo.travaglini@arm.com 11913392Sgiacomo.travaglini@arm.com # Stick all the code together so it can be searched at once 12013392Sgiacomo.travaglini@arm.com allCode = "|".join((code, flag_code, cond_check, else_code)) 12113392Sgiacomo.travaglini@arm.com 12213392Sgiacomo.travaglini@arm.com # If there's something optional to do with flags, generate 12313392Sgiacomo.travaglini@arm.com # a version without it and fix up this version to use it. 12413392Sgiacomo.travaglini@arm.com if flag_code is not "" or cond_check is not "true": 12513392Sgiacomo.travaglini@arm.com self.buildCppClasses(name, Name, suffix, 12613392Sgiacomo.travaglini@arm.com code, "", "true", else_code, op_class) 12713392Sgiacomo.travaglini@arm.com suffix = "Flags" + suffix 12813392Sgiacomo.travaglini@arm.com 12913392Sgiacomo.travaglini@arm.com base = "X86ISA::FpOp" 13013392Sgiacomo.travaglini@arm.com 13113392Sgiacomo.travaglini@arm.com # Get everything ready for the substitution 13213392Sgiacomo.travaglini@arm.com iop_tag = InstObjParams(name, Name + suffix + "TopTag", base, 13313392Sgiacomo.travaglini@arm.com {"code" : code, 13413392Sgiacomo.travaglini@arm.com "flag_code" : flag_code, 13513392Sgiacomo.travaglini@arm.com "cond_check" : cond_check, 13613392Sgiacomo.travaglini@arm.com "else_code" : else_code, 13713392Sgiacomo.travaglini@arm.com "tag_code" : "FTW = genX87Tags(FTW, TOP, spm);", 13813392Sgiacomo.travaglini@arm.com "top_code" : "TOP = (TOP + spm + 8) % 8;", 13913392Sgiacomo.travaglini@arm.com "op_class" : op_class}) 14013392Sgiacomo.travaglini@arm.com iop_top = InstObjParams(name, Name + suffix + "Top", base, 14113392Sgiacomo.travaglini@arm.com {"code" : code, 1427351Sgblack@eecs.umich.edu "flag_code" : flag_code, 14310037SARM gem5 Developers "cond_check" : cond_check, 14413392Sgiacomo.travaglini@arm.com "else_code" : else_code, 14513392Sgiacomo.travaglini@arm.com "tag_code" : ";", 14613392Sgiacomo.travaglini@arm.com "top_code" : "TOP = (TOP + spm + 8) % 8;", 14713392Sgiacomo.travaglini@arm.com "op_class" : op_class}) 14813392Sgiacomo.travaglini@arm.com iop = InstObjParams(name, Name + suffix, base, 14913392Sgiacomo.travaglini@arm.com {"code" : code, 15013392Sgiacomo.travaglini@arm.com "flag_code" : flag_code, 15113392Sgiacomo.travaglini@arm.com "cond_check" : cond_check, 15213392Sgiacomo.travaglini@arm.com "else_code" : else_code, 15313392Sgiacomo.travaglini@arm.com "tag_code" : ";", 15413392Sgiacomo.travaglini@arm.com "top_code" : ";", 15513392Sgiacomo.travaglini@arm.com "op_class" : op_class}) 15613392Sgiacomo.travaglini@arm.com 15713392Sgiacomo.travaglini@arm.com # Generate the actual code (finally!) 15813392Sgiacomo.travaglini@arm.com header_output += MicroFpOpDeclare.subst(iop_tag) 15913392Sgiacomo.travaglini@arm.com decoder_output += MicroFpOpConstructor.subst(iop_tag) 16013392Sgiacomo.travaglini@arm.com exec_output += MicroFpOpExecute.subst(iop_tag) 16113392Sgiacomo.travaglini@arm.com header_output += MicroFpOpDeclare.subst(iop_top) 16213392Sgiacomo.travaglini@arm.com decoder_output += MicroFpOpConstructor.subst(iop_top) 16313392Sgiacomo.travaglini@arm.com exec_output += MicroFpOpExecute.subst(iop_top) 16413392Sgiacomo.travaglini@arm.com header_output += MicroFpOpDeclare.subst(iop) 16513392Sgiacomo.travaglini@arm.com decoder_output += MicroFpOpConstructor.subst(iop) 16613392Sgiacomo.travaglini@arm.com exec_output += MicroFpOpExecute.subst(iop) 16713392Sgiacomo.travaglini@arm.com 16813392Sgiacomo.travaglini@arm.com 16913392Sgiacomo.travaglini@arm.com def __new__(mcls, Name, bases, dict): 17013392Sgiacomo.travaglini@arm.com abstract = False 17113392Sgiacomo.travaglini@arm.com name = Name.lower() 17213392Sgiacomo.travaglini@arm.com if "abstract" in dict: 17313392Sgiacomo.travaglini@arm.com abstract = dict['abstract'] 17413392Sgiacomo.travaglini@arm.com del dict['abstract'] 17513392Sgiacomo.travaglini@arm.com 17613392Sgiacomo.travaglini@arm.com cls = super(FpOpMeta, mcls).__new__(mcls, Name, bases, dict) 17713392Sgiacomo.travaglini@arm.com if not abstract: 17813392Sgiacomo.travaglini@arm.com cls.className = Name 17913392Sgiacomo.travaglini@arm.com cls.mnemonic = name 18013392Sgiacomo.travaglini@arm.com code = cls.code 18113392Sgiacomo.travaglini@arm.com flag_code = cls.flag_code 18213392Sgiacomo.travaglini@arm.com cond_check = cls.cond_check 18313392Sgiacomo.travaglini@arm.com else_code = cls.else_code 18413392Sgiacomo.travaglini@arm.com op_class = cls.op_class 18513392Sgiacomo.travaglini@arm.com 18613392Sgiacomo.travaglini@arm.com # Set up the C++ classes 18713392Sgiacomo.travaglini@arm.com mcls.buildCppClasses(cls, name, Name, "", 18813392Sgiacomo.travaglini@arm.com code, flag_code, cond_check, else_code, op_class) 18913392Sgiacomo.travaglini@arm.com 19013392Sgiacomo.travaglini@arm.com # Hook into the microassembler dict 19113392Sgiacomo.travaglini@arm.com global microopClasses 19213392Sgiacomo.travaglini@arm.com microopClasses[name] = cls 19313392Sgiacomo.travaglini@arm.com 19413392Sgiacomo.travaglini@arm.com return cls 19513392Sgiacomo.travaglini@arm.com 19613392Sgiacomo.travaglini@arm.com class FpUnaryOp(X86Microop): 19713392Sgiacomo.travaglini@arm.com __metaclass__ = FpOpMeta 19813392Sgiacomo.travaglini@arm.com # This class itself doesn't act as a microop 19913392Sgiacomo.travaglini@arm.com abstract = True 20013392Sgiacomo.travaglini@arm.com 20113392Sgiacomo.travaglini@arm.com # Default template parameter values 20213392Sgiacomo.travaglini@arm.com flag_code = "" 20313392Sgiacomo.travaglini@arm.com cond_check = "true" 20413392Sgiacomo.travaglini@arm.com else_code = ";" 20513392Sgiacomo.travaglini@arm.com op_class = "FloatAddOp" 20613392Sgiacomo.travaglini@arm.com 20713392Sgiacomo.travaglini@arm.com def __init__(self, dest, src1, spm=0, \ 20813392Sgiacomo.travaglini@arm.com SetStatus=False, UpdateFTW=True, dataSize="env.dataSize"): 20913392Sgiacomo.travaglini@arm.com self.dest = dest 21013392Sgiacomo.travaglini@arm.com self.src1 = src1 21113392Sgiacomo.travaglini@arm.com self.src2 = "InstRegIndex(0)" 21213392Sgiacomo.travaglini@arm.com self.spm = spm 21313392Sgiacomo.travaglini@arm.com self.dataSize = dataSize 21413392Sgiacomo.travaglini@arm.com if SetStatus: 21513392Sgiacomo.travaglini@arm.com self.className += "Flags" 21613392Sgiacomo.travaglini@arm.com if spm: 21713392Sgiacomo.travaglini@arm.com self.className += "Top" 21813392Sgiacomo.travaglini@arm.com if spm and UpdateFTW: 21913392Sgiacomo.travaglini@arm.com self.className += "Tag" 22013392Sgiacomo.travaglini@arm.com 22113392Sgiacomo.travaglini@arm.com def getAllocator(self, microFlags): 22213392Sgiacomo.travaglini@arm.com return '''new %(class_name)s(machInst, macrocodeBlock, 22313392Sgiacomo.travaglini@arm.com %(flags)s, %(src1)s, %(src2)s, %(dest)s, 22413392Sgiacomo.travaglini@arm.com %(dataSize)s, %(spm)d)''' % { 22513392Sgiacomo.travaglini@arm.com "class_name" : self.className, 22613392Sgiacomo.travaglini@arm.com "flags" : self.microFlagsText(microFlags), 22713392Sgiacomo.travaglini@arm.com "src1" : self.src1, "src2" : self.src2, 22813392Sgiacomo.travaglini@arm.com "dest" : self.dest, 22913392Sgiacomo.travaglini@arm.com "dataSize" : self.dataSize, 23013392Sgiacomo.travaglini@arm.com "spm" : self.spm} 23113392Sgiacomo.travaglini@arm.com 23213392Sgiacomo.travaglini@arm.com class FpBinaryOp(X86Microop): 23313392Sgiacomo.travaglini@arm.com __metaclass__ = FpOpMeta 23413392Sgiacomo.travaglini@arm.com # This class itself doesn't act as a microop 23513392Sgiacomo.travaglini@arm.com abstract = True 23613392Sgiacomo.travaglini@arm.com 23713392Sgiacomo.travaglini@arm.com # Default template parameter values 23813392Sgiacomo.travaglini@arm.com flag_code = "" 23913392Sgiacomo.travaglini@arm.com cond_check = "true" 24013392Sgiacomo.travaglini@arm.com else_code = ";" 24113392Sgiacomo.travaglini@arm.com op_class = "FloatAddOp" 24213392Sgiacomo.travaglini@arm.com 24313392Sgiacomo.travaglini@arm.com def __init__(self, dest, src1, src2, spm=0, \ 24413392Sgiacomo.travaglini@arm.com SetStatus=False, UpdateFTW=True, dataSize="env.dataSize"): 24513392Sgiacomo.travaglini@arm.com self.dest = dest 24613392Sgiacomo.travaglini@arm.com self.src1 = src1 24713392Sgiacomo.travaglini@arm.com self.src2 = src2 24813392Sgiacomo.travaglini@arm.com self.spm = spm 24913392Sgiacomo.travaglini@arm.com self.dataSize = dataSize 25013392Sgiacomo.travaglini@arm.com if SetStatus: 25113392Sgiacomo.travaglini@arm.com self.className += "Flags" 25213392Sgiacomo.travaglini@arm.com if spm: 25313392Sgiacomo.travaglini@arm.com self.className += "Top" 25413392Sgiacomo.travaglini@arm.com if spm and UpdateFTW: 25513392Sgiacomo.travaglini@arm.com self.className += "Tag" 25613392Sgiacomo.travaglini@arm.com 25713392Sgiacomo.travaglini@arm.com def getAllocator(self, microFlags): 25813392Sgiacomo.travaglini@arm.com return '''new %(class_name)s(machInst, macrocodeBlock, 25913392Sgiacomo.travaglini@arm.com %(flags)s, %(src1)s, %(src2)s, %(dest)s, 26013392Sgiacomo.travaglini@arm.com %(dataSize)s, %(spm)d)''' % { 26113392Sgiacomo.travaglini@arm.com "class_name" : self.className, 26213392Sgiacomo.travaglini@arm.com "flags" : self.microFlagsText(microFlags), 26313392Sgiacomo.travaglini@arm.com "src1" : self.src1, "src2" : self.src2, 26413392Sgiacomo.travaglini@arm.com "dest" : self.dest, 26513392Sgiacomo.travaglini@arm.com "dataSize" : self.dataSize, 26613392Sgiacomo.travaglini@arm.com "spm" : self.spm} 26713392Sgiacomo.travaglini@arm.com 26813392Sgiacomo.travaglini@arm.com class Movfp(FpUnaryOp): 26913392Sgiacomo.travaglini@arm.com code = 'FpDestReg_uqw = FpSrcReg1_uqw;' 27013392Sgiacomo.travaglini@arm.com else_code = 'FpDestReg_uqw = FpDestReg_uqw;' 27113392Sgiacomo.travaglini@arm.com cond_check = "checkCondition(ccFlagBits | cfofBits | dfBit | \ 27213392Sgiacomo.travaglini@arm.com ecfBit | ezfBit, src2)" 27313392Sgiacomo.travaglini@arm.com 27413392Sgiacomo.travaglini@arm.com class Xorfp(FpBinaryOp): 27513392Sgiacomo.travaglini@arm.com code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;' 27613392Sgiacomo.travaglini@arm.com 27713392Sgiacomo.travaglini@arm.com class Sqrtfp(FpBinaryOp): 27813392Sgiacomo.travaglini@arm.com code = 'FpDestReg = sqrt(FpSrcReg2);' 27913392Sgiacomo.travaglini@arm.com op_class = 'FloatSqrtOp' 28013392Sgiacomo.travaglini@arm.com 28113392Sgiacomo.travaglini@arm.com class Cosfp(FpUnaryOp): 28213392Sgiacomo.travaglini@arm.com code = 'FpDestReg = cos(FpSrcReg1);' 28313392Sgiacomo.travaglini@arm.com op_class = 'FloatSqrtOp' 28413392Sgiacomo.travaglini@arm.com 28513392Sgiacomo.travaglini@arm.com class Sinfp(FpUnaryOp): 28613392Sgiacomo.travaglini@arm.com code = 'FpDestReg = sin(FpSrcReg1);' 28713392Sgiacomo.travaglini@arm.com op_class = 'FloatSqrtOp' 28813392Sgiacomo.travaglini@arm.com 28913392Sgiacomo.travaglini@arm.com class Tanfp(FpUnaryOp): 29013392Sgiacomo.travaglini@arm.com code = 'FpDestReg = tan(FpSrcReg1);' 29113392Sgiacomo.travaglini@arm.com op_class = 'FloatSqrtOp' 29213392Sgiacomo.travaglini@arm.com 29313392Sgiacomo.travaglini@arm.com 29413392Sgiacomo.travaglini@arm.com # Conversion microops 29513392Sgiacomo.travaglini@arm.com class ConvOp(FpBinaryOp): 29613392Sgiacomo.travaglini@arm.com abstract = True 29713392Sgiacomo.travaglini@arm.com op_class = 'FloatCvtOp' 29813392Sgiacomo.travaglini@arm.com def __init__(self, dest, src1, **kwargs): 29913392Sgiacomo.travaglini@arm.com super(ConvOp, self).__init__(dest, src1, \ 30013392Sgiacomo.travaglini@arm.com "InstRegIndex(FLOATREG_MICROFP0)", \ 30113392Sgiacomo.travaglini@arm.com **kwargs) 30213392Sgiacomo.travaglini@arm.com 30313392Sgiacomo.travaglini@arm.com # These probably shouldn't look at the ExtMachInst directly to figure 30413392Sgiacomo.travaglini@arm.com # out what size to use and should instead delegate that to the macroop's 30513392Sgiacomo.travaglini@arm.com # constructor. That would be more efficient, and it would make the 30613392Sgiacomo.travaglini@arm.com # microops a little more modular. 30713392Sgiacomo.travaglini@arm.com class cvtf_i2d(ConvOp): 30813392Sgiacomo.travaglini@arm.com code = ''' 30913392Sgiacomo.travaglini@arm.com X86IntReg intReg = SSrcReg1; 31013392Sgiacomo.travaglini@arm.com if (REX_W) 31113392Sgiacomo.travaglini@arm.com FpDestReg = intReg.SR; 31213392Sgiacomo.travaglini@arm.com else 31313392Sgiacomo.travaglini@arm.com FpDestReg = intReg.SE; 31413392Sgiacomo.travaglini@arm.com ''' 31513392Sgiacomo.travaglini@arm.com 31613392Sgiacomo.travaglini@arm.com class cvtf_i2d_hi(ConvOp): 31713392Sgiacomo.travaglini@arm.com code = 'FpDestReg = bits(SSrcReg1, 63, 32);' 31813392Sgiacomo.travaglini@arm.com 31913392Sgiacomo.travaglini@arm.com class cvtf_d2i(ConvOp): 32013392Sgiacomo.travaglini@arm.com code = ''' 32113392Sgiacomo.travaglini@arm.com int64_t intSrcReg1 = static_cast<int64_t>(FpSrcReg1); 32213392Sgiacomo.travaglini@arm.com if (REX_W) 32313392Sgiacomo.travaglini@arm.com SDestReg = intSrcReg1; 32413392Sgiacomo.travaglini@arm.com else 32513392Sgiacomo.travaglini@arm.com SDestReg = merge(SDestReg, intSrcReg1, 4); 32613392Sgiacomo.travaglini@arm.com ''' 32713392Sgiacomo.travaglini@arm.com 32813392Sgiacomo.travaglini@arm.com # Convert two integers registers representing an 80-bit floating 32913392Sgiacomo.travaglini@arm.com # point number to an x87 register. 33013392Sgiacomo.travaglini@arm.com class cvtint_fp80(FpBinaryOp): 33113392Sgiacomo.travaglini@arm.com code = ''' 33213392Sgiacomo.travaglini@arm.com uint8_t bits[10]; 33313392Sgiacomo.travaglini@arm.com *(uint64_t *)(bits + 0) = SSrcReg1; 33413392Sgiacomo.travaglini@arm.com *(uint16_t *)(bits + 8) = (uint16_t)SSrcReg2; 33513392Sgiacomo.travaglini@arm.com FpDestReg = loadFloat80(bits); 33613392Sgiacomo.travaglini@arm.com ''' 33713392Sgiacomo.travaglini@arm.com 33813392Sgiacomo.travaglini@arm.com # Convert an x87 register (double) into extended precision and 33913392Sgiacomo.travaglini@arm.com # extract the highest 64 bits. 34013392Sgiacomo.travaglini@arm.com class cvtfp80h_int(ConvOp): 34113392Sgiacomo.travaglini@arm.com code = ''' 34213392Sgiacomo.travaglini@arm.com char bits[10]; 34313392Sgiacomo.travaglini@arm.com storeFloat80(bits, FpSrcReg1); 34413392Sgiacomo.travaglini@arm.com SDestReg = *(uint64_t *)(bits + 0); 34513392Sgiacomo.travaglini@arm.com ''' 34613392Sgiacomo.travaglini@arm.com 34713392Sgiacomo.travaglini@arm.com # Convert an x87 register (double) into extended precision and 34813392Sgiacomo.travaglini@arm.com # extract the lowest 16 bits. 34913392Sgiacomo.travaglini@arm.com class cvtfp80l_int(ConvOp): 35013392Sgiacomo.travaglini@arm.com code = ''' 35113392Sgiacomo.travaglini@arm.com char bits[10]; 35213392Sgiacomo.travaglini@arm.com storeFloat80(bits, FpSrcReg1); 35313392Sgiacomo.travaglini@arm.com SDestReg = *(uint16_t *)(bits + 8); 35413392Sgiacomo.travaglini@arm.com ''' 35513392Sgiacomo.travaglini@arm.com 35613392Sgiacomo.travaglini@arm.com # These need to consider size at some point. They'll always use doubles 35713392Sgiacomo.travaglini@arm.com # for the moment. 35813392Sgiacomo.travaglini@arm.com class addfp(FpBinaryOp): 35913392Sgiacomo.travaglini@arm.com code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;' 36013392Sgiacomo.travaglini@arm.com 36113392Sgiacomo.travaglini@arm.com class mulfp(FpBinaryOp): 36213392Sgiacomo.travaglini@arm.com code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;' 36313392Sgiacomo.travaglini@arm.com op_class = 'FloatMultOp' 36413392Sgiacomo.travaglini@arm.com 36513392Sgiacomo.travaglini@arm.com class divfp(FpBinaryOp): 36613392Sgiacomo.travaglini@arm.com code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;' 36713392Sgiacomo.travaglini@arm.com op_class = 'FloatDivOp' 36813392Sgiacomo.travaglini@arm.com 36913392Sgiacomo.travaglini@arm.com class subfp(FpBinaryOp): 37013392Sgiacomo.travaglini@arm.com code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;' 37113392Sgiacomo.travaglini@arm.com 37213392Sgiacomo.travaglini@arm.com class Yl2xFp(FpBinaryOp): 37313392Sgiacomo.travaglini@arm.com code = ''' 37413392Sgiacomo.travaglini@arm.com FpDestReg = FpSrcReg2 * (log(FpSrcReg1) / log(2)); 37513392Sgiacomo.travaglini@arm.com ''' 37613392Sgiacomo.travaglini@arm.com op_class = 'FloatSqrtOp' 37713392Sgiacomo.travaglini@arm.com 37813392Sgiacomo.travaglini@arm.com class PremFp(FpBinaryOp): 37913392Sgiacomo.travaglini@arm.com code = ''' 38013392Sgiacomo.travaglini@arm.com MiscReg new_fsw(FSW); 38113392Sgiacomo.travaglini@arm.com int src1_exp; 38213392Sgiacomo.travaglini@arm.com int src2_exp; 38313392Sgiacomo.travaglini@arm.com std::frexp(FpSrcReg1, &src1_exp); 3847259Sgblack@eecs.umich.edu std::frexp(FpSrcReg2, &src2_exp); 38510037SARM gem5 Developers 38613392Sgiacomo.travaglini@arm.com const int d(src2_exp - src1_exp); 38713392Sgiacomo.travaglini@arm.com if (d < 64) { 38813392Sgiacomo.travaglini@arm.com const int64_t q(std::trunc(FpSrcReg2 / FpSrcReg1)); 38913392Sgiacomo.travaglini@arm.com FpDestReg = FpSrcReg2 - FpSrcReg1 * q; 39013392Sgiacomo.travaglini@arm.com new_fsw &= ~(CC0Bit | CC1Bit | CC2Bit | CC2Bit); 39113392Sgiacomo.travaglini@arm.com new_fsw |= (q & 0x1) ? CC1Bit : 0; 39213392Sgiacomo.travaglini@arm.com new_fsw |= (q & 0x2) ? CC3Bit : 0; 39313392Sgiacomo.travaglini@arm.com new_fsw |= (q & 0x4) ? CC0Bit : 0; 39413392Sgiacomo.travaglini@arm.com } else { 39513392Sgiacomo.travaglini@arm.com const int n(42); 39613392Sgiacomo.travaglini@arm.com const int64_t qq(std::trunc( 39713392Sgiacomo.travaglini@arm.com FpSrcReg2 / std::ldexp(FpSrcReg1, d - n))); 39813392Sgiacomo.travaglini@arm.com FpDestReg = FpSrcReg2 - std::ldexp(FpSrcReg1 * qq, d - n); 39913392Sgiacomo.travaglini@arm.com new_fsw |= CC2Bit; 40013392Sgiacomo.travaglini@arm.com } 40113392Sgiacomo.travaglini@arm.com DPRINTF(X86, "src1: %lf, src2: %lf, dest: %lf, FSW: 0x%x\\n", 40213392Sgiacomo.travaglini@arm.com FpSrcReg1, FpSrcReg2, FpDestReg, new_fsw); 40313392Sgiacomo.travaglini@arm.com ''' 40413392Sgiacomo.travaglini@arm.com op_class = 'FloatDivOp' 40513392Sgiacomo.travaglini@arm.com 40613392Sgiacomo.travaglini@arm.com flag_code = 'FSW = new_fsw;' 40713392Sgiacomo.travaglini@arm.com 40813392Sgiacomo.travaglini@arm.com class Compfp(FpBinaryOp): 40913392Sgiacomo.travaglini@arm.com def __init__(self, src1, src2, spm=0, setStatus=False, updateFTW=True, \ 41013392Sgiacomo.travaglini@arm.com dataSize="env.dataSize"): 41113392Sgiacomo.travaglini@arm.com super(Compfp, self).__init__("InstRegIndex(FLOATREG_MICROFP0)", \ 41213392Sgiacomo.travaglini@arm.com src1, src2, spm, setStatus, updateFTW, dataSize) 41313392Sgiacomo.travaglini@arm.com # This class sets the condition codes in rflags according to the 41413392Sgiacomo.travaglini@arm.com # rules for comparing floating point. 41513392Sgiacomo.travaglini@arm.com code = ''' 41613392Sgiacomo.travaglini@arm.com // ZF PF CF 41713392Sgiacomo.travaglini@arm.com // Unordered 1 1 1 41813392Sgiacomo.travaglini@arm.com // Greater than 0 0 0 41913392Sgiacomo.travaglini@arm.com // Less than 0 0 1 42013392Sgiacomo.travaglini@arm.com // Equal 1 0 0 42113392Sgiacomo.travaglini@arm.com // OF = SF = AF = 0 42213392Sgiacomo.travaglini@arm.com ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit); 42313392Sgiacomo.travaglini@arm.com cfofBits = cfofBits & ~(OFBit | CFBit); 42413392Sgiacomo.travaglini@arm.com 42513392Sgiacomo.travaglini@arm.com if (std::isnan(FpSrcReg1) || std::isnan(FpSrcReg2)) { 4267259Sgblack@eecs.umich.edu ccFlagBits = ccFlagBits | (ZFBit | PFBit); 42710037SARM gem5 Developers cfofBits = cfofBits | CFBit; 42813392Sgiacomo.travaglini@arm.com } 42913392Sgiacomo.travaglini@arm.com else if(FpSrcReg1 < FpSrcReg2) 43013392Sgiacomo.travaglini@arm.com cfofBits = cfofBits | CFBit; 43113392Sgiacomo.travaglini@arm.com else if(FpSrcReg1 == FpSrcReg2) 43213392Sgiacomo.travaglini@arm.com ccFlagBits = ccFlagBits | ZFBit; 43313392Sgiacomo.travaglini@arm.com ''' 43413392Sgiacomo.travaglini@arm.com op_class = 'FloatCmpOp' 43513392Sgiacomo.travaglini@arm.com 43613392Sgiacomo.travaglini@arm.com class absfp(FpUnaryOp): 43713392Sgiacomo.travaglini@arm.com code = 'FpDestReg = fabs(FpSrcReg1);' 43813392Sgiacomo.travaglini@arm.com flag_code = 'FSW = FSW & (~CC1Bit);' 43913392Sgiacomo.travaglini@arm.com 44013392Sgiacomo.travaglini@arm.com class chsfp(FpUnaryOp): 44113392Sgiacomo.travaglini@arm.com code = 'FpDestReg = (-1) * (FpSrcReg1);' 44213392Sgiacomo.travaglini@arm.com flag_code = 'FSW = FSW & (~CC1Bit);' 44313392Sgiacomo.travaglini@arm.com 44413392Sgiacomo.travaglini@arm.com class Pop87(FpUnaryOp): 44513392Sgiacomo.travaglini@arm.com def __init__(self, spm=1, UpdateFTW=True): 44613392Sgiacomo.travaglini@arm.com super(Pop87, self).__init__( \ 44713392Sgiacomo.travaglini@arm.com "InstRegIndex(FLOATREG_MICROFP0)", \ 44813392Sgiacomo.travaglini@arm.com "InstRegIndex(FLOATREG_MICROFP0)", \ 44913392Sgiacomo.travaglini@arm.com spm=spm, SetStatus=False, UpdateFTW=UpdateFTW) 45013392Sgiacomo.travaglini@arm.com 45113392Sgiacomo.travaglini@arm.com code = '' 45213392Sgiacomo.travaglini@arm.com}}; 45313392Sgiacomo.travaglini@arm.com