fpop.isa revision 10313
12SN/A// Copyright (c) 2007 The Hewlett-Packard Development Company 28733Sgeoffrey.blake@arm.com// Copyright (c) 2012-2013 Mark D. Hill and David A. Wood 38733Sgeoffrey.blake@arm.com// All rights reserved. 48733Sgeoffrey.blake@arm.com// 58733Sgeoffrey.blake@arm.com// The license below extends only to copyright in the software and shall 68733Sgeoffrey.blake@arm.com// not be construed as granting a license to any other intellectual 78733Sgeoffrey.blake@arm.com// property including but not limited to intellectual property relating 88733Sgeoffrey.blake@arm.com// to a hardware implementation of the functionality of the software 98733Sgeoffrey.blake@arm.com// licensed hereunder. You may use the software subject to the license 108733Sgeoffrey.blake@arm.com// terms below provided that you ensure that this notice is replicated 118733Sgeoffrey.blake@arm.com// unmodified and in its entirety in all distributions of the software, 128733Sgeoffrey.blake@arm.com// modified or unmodified, in source code or in binary form. 138733Sgeoffrey.blake@arm.com// 142190SN/A// Redistribution and use in source and binary forms, with or without 152SN/A// modification, are permitted provided that the following conditions are 162SN/A// met: redistributions of source code must retain the above copyright 172SN/A// notice, this list of conditions and the following disclaimer; 182SN/A// redistributions in binary form must reproduce the above copyright 192SN/A// notice, this list of conditions and the following disclaimer in the 202SN/A// documentation and/or other materials provided with the distribution; 212SN/A// neither the name of the copyright holders nor the names of its 222SN/A// contributors may be used to endorse or promote products derived from 232SN/A// this software without specific prior written permission. 242SN/A// 252SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 262SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 272SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 312SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 322SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 332SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 342SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 352SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 362SN/A// 372SN/A// Authors: Gabe Black 382SN/A// Nilay Vaish 392665SN/A 402665SN/A////////////////////////////////////////////////////////////////////////// 412SN/A// 422SN/A// FpOp Microop templates 432680Sktlim@umich.edu// 442680Sktlim@umich.edu////////////////////////////////////////////////////////////////////////// 452SN/A 468229Snate@binkert.orgdef template MicroFpOpExecute {{ 477680Sgblack@eecs.umich.edu Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 487680Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 496329Sgblack@eecs.umich.edu { 503453Sgblack@eecs.umich.edu Fault fault = NoFault; 516216Snate@binkert.org 521858SN/A DPRINTF(X86, "The data size is %d\n", dataSize); 536658Snate@binkert.org %(op_decl)s; 548733Sgeoffrey.blake@arm.com %(op_rd)s; 552SN/A 562190SN/A if(%(cond_check)s) 572190SN/A { 583453Sgblack@eecs.umich.edu %(code)s; 593453Sgblack@eecs.umich.edu %(flag_code)s; 606022Sgblack@eecs.umich.edu %(tag_code)s; 613453Sgblack@eecs.umich.edu %(top_code)s; 622190SN/A } 637680Sgblack@eecs.umich.edu else 648541Sgblack@eecs.umich.edu { 652313SN/A %(else_code)s; 668706Sandreas.hansson@arm.com } 678706Sandreas.hansson@arm.com 688706Sandreas.hansson@arm.com //Write the resulting state to the execution context 692190SN/A if(fault == NoFault) 702190SN/A { 713548Sgblack@eecs.umich.edu %(op_wb)s; 723548Sgblack@eecs.umich.edu } 733548Sgblack@eecs.umich.edu return fault; 743548Sgblack@eecs.umich.edu } 752330SN/A}}; 762SN/A 772680Sktlim@umich.edudef template MicroFpOpDeclare {{ 782680Sktlim@umich.edu class %(class_name)s : public %(base_class)s 792680Sktlim@umich.edu { 802680Sktlim@umich.edu public: 812680Sktlim@umich.edu %(class_name)s(ExtMachInst _machInst, 822680Sktlim@umich.edu const char * instMnem, uint64_t setFlags, 832680Sktlim@umich.edu InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, 842680Sktlim@umich.edu uint8_t _dataSize, int8_t _spm); 852680Sktlim@umich.edu 862680Sktlim@umich.edu %(BasicExecDeclare)s 872680Sktlim@umich.edu }; 882682Sktlim@umich.edu}}; 892680Sktlim@umich.edu 902680Sktlim@umich.edudef template MicroFpOpConstructor {{ 912680Sktlim@umich.edu %(class_name)s::%(class_name)s( 922680Sktlim@umich.edu ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 932680Sktlim@umich.edu InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, 942SN/A uint8_t _dataSize, int8_t _spm) : 952107SN/A %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 962107SN/A _src1, _src2, _dest, _dataSize, _spm, 972190SN/A %(op_class)s) 982455SN/A { 992455SN/A %(constructor)s; 1002159SN/A } 1012SN/A}}; 1026029Ssteve.reinhardt@amd.com 103246SN/Alet {{ 104246SN/A # Make these empty strings so that concatenating onto 105246SN/A # them will always work. 106246SN/A header_output = "" 107246SN/A decoder_output = "" 108246SN/A exec_output = "" 109246SN/A 1102190SN/A class FpOpMeta(type): 111246SN/A def buildCppClasses(self, name, Name, suffix, \ 112246SN/A code, flag_code, cond_check, else_code, op_class): 113246SN/A 114246SN/A # Globals to stick the output in 115246SN/A global header_output 116246SN/A global decoder_output 117246SN/A global exec_output 1182SN/A 1192680Sktlim@umich.edu # Stick all the code together so it can be searched at once 1202423SN/A allCode = "|".join((code, flag_code, cond_check, else_code)) 1212190SN/A 122180SN/A # If there's something optional to do with flags, generate 1235712Shsul@eecs.umich.edu # a version without it and fix up this version to use it. 1242190SN/A if flag_code is not "" or cond_check is not "true": 1255715Shsul@eecs.umich.edu self.buildCppClasses(name, Name, suffix, 1265715Shsul@eecs.umich.edu code, "", "true", else_code, op_class) 1275715Shsul@eecs.umich.edu suffix = "Flags" + suffix 1285714Shsul@eecs.umich.edu 1295714Shsul@eecs.umich.edu base = "X86ISA::FpOp" 1305714Shsul@eecs.umich.edu 1315714Shsul@eecs.umich.edu # Get everything ready for the substitution 1325714Shsul@eecs.umich.edu iop_tag = InstObjParams(name, Name + suffix + "TopTag", base, 1336022Sgblack@eecs.umich.edu {"code" : code, 1342190SN/A "flag_code" : flag_code, 1356022Sgblack@eecs.umich.edu "cond_check" : cond_check, 1362521SN/A "else_code" : else_code, 1378733Sgeoffrey.blake@arm.com "tag_code" : "FTW = genX87Tags(FTW, TOP, spm);", 1388733Sgeoffrey.blake@arm.com "top_code" : "TOP = (TOP + spm + 8) % 8;", 1398733Sgeoffrey.blake@arm.com "op_class" : op_class}) 1408733Sgeoffrey.blake@arm.com iop_top = InstObjParams(name, Name + suffix + "Top", base, 1418541Sgblack@eecs.umich.edu {"code" : code, 1428541Sgblack@eecs.umich.edu "flag_code" : flag_code, 1434997Sgblack@eecs.umich.edu "cond_check" : cond_check, 1444997Sgblack@eecs.umich.edu "else_code" : else_code, 1455803Snate@binkert.org "tag_code" : ";", 1463548Sgblack@eecs.umich.edu "top_code" : "TOP = (TOP + spm + 8) % 8;", 1472654SN/A "op_class" : op_class}) 1488706Sandreas.hansson@arm.com iop = InstObjParams(name, Name + suffix, base, 1492521SN/A {"code" : code, 1508706Sandreas.hansson@arm.com "flag_code" : flag_code, 1513673Srdreslin@umich.edu "cond_check" : cond_check, 1528706Sandreas.hansson@arm.com "else_code" : else_code, 1538706Sandreas.hansson@arm.com "tag_code" : ";", 1548706Sandreas.hansson@arm.com "top_code" : ";", 1558706Sandreas.hansson@arm.com "op_class" : op_class}) 1568706Sandreas.hansson@arm.com 1578706Sandreas.hansson@arm.com # Generate the actual code (finally!) 1588706Sandreas.hansson@arm.com header_output += MicroFpOpDeclare.subst(iop_tag) 1592190SN/A decoder_output += MicroFpOpConstructor.subst(iop_tag) 1608706Sandreas.hansson@arm.com exec_output += MicroFpOpExecute.subst(iop_tag) 1612518SN/A header_output += MicroFpOpDeclare.subst(iop_top) 1622190SN/A decoder_output += MicroFpOpConstructor.subst(iop_top) 1632190SN/A exec_output += MicroFpOpExecute.subst(iop_top) 1642190SN/A header_output += MicroFpOpDeclare.subst(iop) 1652190SN/A decoder_output += MicroFpOpConstructor.subst(iop) 1662159SN/A exec_output += MicroFpOpExecute.subst(iop) 1672235SN/A 1682103SN/A 169393SN/A def __new__(mcls, Name, bases, dict): 170393SN/A abstract = False 1712190SN/A name = Name.lower() 172393SN/A if "abstract" in dict: 173393SN/A abstract = dict['abstract'] 1745250Sksewell@umich.edu del dict['abstract'] 175393SN/A 176393SN/A cls = super(FpOpMeta, mcls).__new__(mcls, Name, bases, dict) 1775250Sksewell@umich.edu if not abstract: 1782159SN/A cls.className = Name 1792159SN/A cls.mnemonic = name 1802190SN/A code = cls.code 1812159SN/A flag_code = cls.flag_code 1822159SN/A cond_check = cls.cond_check 1832680Sktlim@umich.edu else_code = cls.else_code 1842159SN/A op_class = cls.op_class 1852190SN/A 1862159SN/A # Set up the C++ classes 1872190SN/A mcls.buildCppClasses(cls, name, Name, "", 1882190SN/A code, flag_code, cond_check, else_code, op_class) 1892159SN/A 1902235SN/A # Hook into the microassembler dict 1912313SN/A global microopClasses 1922235SN/A microopClasses[name] = cls 1932235SN/A 1942235SN/A return cls 1952235SN/A 1962235SN/A class FpUnaryOp(X86Microop): 1972254SN/A __metaclass__ = FpOpMeta 1982254SN/A # This class itself doesn't act as a microop 1992254SN/A abstract = True 2002235SN/A 2012235SN/A # Default template parameter values 2022680Sktlim@umich.edu flag_code = "" 2032159SN/A cond_check = "true" 2042190SN/A else_code = ";" 2052159SN/A op_class = "FloatAddOp" 2062159SN/A 2072159SN/A def __init__(self, dest, src1, spm=0, \ 2082159SN/A SetStatus=False, UpdateFTW=True, dataSize="env.dataSize"): 2092190SN/A self.dest = dest 2102159SN/A self.src1 = src1 2112455SN/A self.src2 = "InstRegIndex(0)" 2122159SN/A self.spm = spm 2132455SN/A self.dataSize = dataSize 2142159SN/A if SetStatus: 2152190SN/A self.className += "Flags" 2162159SN/A if spm: 2172455SN/A self.className += "Top" 2182159SN/A if spm and UpdateFTW: 2192455SN/A self.className += "Tag" 2202455SN/A 2217720Sgblack@eecs.umich.edu def getAllocator(self, microFlags): 2222159SN/A return '''new %(class_name)s(machInst, macrocodeBlock, 2237720Sgblack@eecs.umich.edu %(flags)s, %(src1)s, %(src2)s, %(dest)s, 2242159SN/A %(dataSize)s, %(spm)d)''' % { 2258733Sgeoffrey.blake@arm.com "class_name" : self.className, 2268733Sgeoffrey.blake@arm.com "flags" : self.microFlagsText(microFlags), 2278733Sgeoffrey.blake@arm.com "src1" : self.src1, "src2" : self.src2, 2288733Sgeoffrey.blake@arm.com "dest" : self.dest, 2297720Sgblack@eecs.umich.edu "dataSize" : self.dataSize, 2302159SN/A "spm" : self.spm} 2317720Sgblack@eecs.umich.edu 2322159SN/A class FpBinaryOp(X86Microop): 2337720Sgblack@eecs.umich.edu __metaclass__ = FpOpMeta 2345260Sksewell@umich.edu # This class itself doesn't act as a microop 2354172Ssaidi@eecs.umich.edu abstract = True 2364172Ssaidi@eecs.umich.edu 2372190SN/A # Default template parameter values 2382159SN/A flag_code = "" 2394172Ssaidi@eecs.umich.edu cond_check = "true" 2402190SN/A else_code = ";" 2413468Sgblack@eecs.umich.edu op_class = "FloatAddOp" 2422190SN/A 2436313Sgblack@eecs.umich.edu def __init__(self, dest, src1, src2, spm=0, \ 2446313Sgblack@eecs.umich.edu SetStatus=False, UpdateFTW=True, dataSize="env.dataSize"): 2456313Sgblack@eecs.umich.edu self.dest = dest 2466221Snate@binkert.org self.src1 = src1 2476221Snate@binkert.org self.src2 = src2 2486221Snate@binkert.org self.spm = spm 2496221Snate@binkert.org self.dataSize = dataSize 2506221Snate@binkert.org if SetStatus: 2514661Sksewell@umich.edu self.className += "Flags" 2526221Snate@binkert.org if spm: 2536221Snate@binkert.org self.className += "Top" 2546221Snate@binkert.org if spm and UpdateFTW: 2556221Snate@binkert.org self.className += "Tag" 2564661Sksewell@umich.edu 2572235SN/A def getAllocator(self, microFlags): 2582235SN/A return '''new %(class_name)s(machInst, macrocodeBlock, 2592190SN/A %(flags)s, %(src1)s, %(src2)s, %(dest)s, 2602190SN/A %(dataSize)s, %(spm)d)''' % { 2612190SN/A "class_name" : self.className, 2622159SN/A "flags" : self.microFlagsText(microFlags), 2632235SN/A "src1" : self.src1, "src2" : self.src2, 2642190SN/A "dest" : self.dest, 2652190SN/A "dataSize" : self.dataSize, 2662159SN/A "spm" : self.spm} 2672235SN/A 2682190SN/A class Movfp(FpUnaryOp): 2692834Sksewell@umich.edu code = 'FpDestReg_uqw = FpSrcReg1_uqw;' 2704111Sgblack@eecs.umich.edu else_code = 'FpDestReg_uqw = FpDestReg_uqw;' 2714111Sgblack@eecs.umich.edu cond_check = "checkCondition(ccFlagBits | cfofBits | dfBit | \ 2722834Sksewell@umich.edu ecfBit | ezfBit, src2)" 2732834Sksewell@umich.edu op_class = 'IntAluOp' 2742834Sksewell@umich.edu 2752834Sksewell@umich.edu class Xorfp(FpBinaryOp): 2762159SN/A code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;' 2772525SN/A 2785217Ssaidi@eecs.umich.edu class Sqrtfp(FpBinaryOp): 2795217Ssaidi@eecs.umich.edu code = 'FpDestReg = sqrt(FpSrcReg2);' 2802159SN/A op_class = 'FloatSqrtOp' 2812159SN/A 2822682Sktlim@umich.edu class Cosfp(FpUnaryOp): 2832682Sktlim@umich.edu code = 'FpDestReg = cos(FpSrcReg1);' 2842682Sktlim@umich.edu op_class = 'FloatSqrtOp' 2852682Sktlim@umich.edu 2862682Sktlim@umich.edu class Sinfp(FpUnaryOp): 2872682Sktlim@umich.edu code = 'FpDestReg = sin(FpSrcReg1);' 2882682Sktlim@umich.edu op_class = 'FloatSqrtOp' 2892682Sktlim@umich.edu 2902682Sktlim@umich.edu class Tanfp(FpUnaryOp): 2912682Sktlim@umich.edu code = 'FpDestReg = tan(FpSrcReg1);' 2922680Sktlim@umich.edu op_class = 'FloatSqrtOp' 2932680Sktlim@umich.edu 2942190SN/A 2952190SN/A # Conversion microops 2962680Sktlim@umich.edu class ConvOp(FpBinaryOp): 2972680Sktlim@umich.edu abstract = True 2982159SN/A op_class = 'FloatCvtOp' 2992190SN/A def __init__(self, dest, src1, **kwargs): 3002680Sktlim@umich.edu super(ConvOp, self).__init__(dest, src1, \ 3012SN/A "InstRegIndex(FLOATREG_MICROFP0)", \ 3022SN/A **kwargs) 3032SN/A 3042680Sktlim@umich.edu # These probably shouldn't look at the ExtMachInst directly to figure 3052SN/A # out what size to use and should instead delegate that to the macroop's 3065712Shsul@eecs.umich.edu # constructor. That would be more efficient, and it would make the 3072SN/A # microops a little more modular. 3085715Shsul@eecs.umich.edu class cvtf_i2d(ConvOp): 3095715Shsul@eecs.umich.edu code = ''' 3105715Shsul@eecs.umich.edu X86IntReg intReg = SSrcReg1; 3115714Shsul@eecs.umich.edu if (REX_W) 3125714Shsul@eecs.umich.edu FpDestReg = intReg.SR; 3135714Shsul@eecs.umich.edu else 3145714Shsul@eecs.umich.edu FpDestReg = intReg.SE; 3155714Shsul@eecs.umich.edu ''' 3166022Sgblack@eecs.umich.edu 3171917SN/A class cvtf_i2d_hi(ConvOp): 3186022Sgblack@eecs.umich.edu code = 'FpDestReg = bits(SSrcReg1, 63, 32);' 3192521SN/A 3208733Sgeoffrey.blake@arm.com class cvtf_d2i(ConvOp): 3218733Sgeoffrey.blake@arm.com code = ''' 3228733Sgeoffrey.blake@arm.com int64_t intSrcReg1 = static_cast<int64_t>(FpSrcReg1); 3238733Sgeoffrey.blake@arm.com if (REX_W) 3248541Sgblack@eecs.umich.edu SDestReg = intSrcReg1; 3258541Sgblack@eecs.umich.edu else 3264997Sgblack@eecs.umich.edu SDestReg = merge(SDestReg, intSrcReg1, 4); 3274997Sgblack@eecs.umich.edu ''' 3285803Snate@binkert.org 3293548Sgblack@eecs.umich.edu # Convert two integers registers representing an 80-bit floating 3303548Sgblack@eecs.umich.edu # point number to an x87 register. 3312654SN/A class cvtint_fp80(FpBinaryOp): 3328706Sandreas.hansson@arm.com code = ''' 3332521SN/A uint8_t bits[10]; 3348706Sandreas.hansson@arm.com *(uint64_t *)(bits + 0) = SSrcReg1; 3353673Srdreslin@umich.edu *(uint16_t *)(bits + 8) = (uint16_t)SSrcReg2; 3368706Sandreas.hansson@arm.com FpDestReg = loadFloat80(bits); 3372SN/A ''' 3388706Sandreas.hansson@arm.com 3392518SN/A # Convert an x87 register (double) into extended precision and 3402680Sktlim@umich.edu # extract the highest 64 bits. 3412SN/A class cvtfp80h_int(ConvOp): 3422SN/A code = ''' 3432680Sktlim@umich.edu char bits[10]; 344595SN/A storeFloat80(bits, FpSrcReg1); 3452680Sktlim@umich.edu SDestReg = *(uint64_t *)(bits + 0); 3462SN/A ''' 3472190SN/A 3482190SN/A # Convert an x87 register (double) into extended precision and 3492680Sktlim@umich.edu # extract the lowest 16 bits. 3502SN/A class cvtfp80l_int(ConvOp): 3512190SN/A code = ''' 3525250Sksewell@umich.edu char bits[10]; 3532SN/A storeFloat80(bits, FpSrcReg1); 3542190SN/A SDestReg = *(uint16_t *)(bits + 8); 3555250Sksewell@umich.edu ''' 356217SN/A 3571858SN/A # These need to consider size at some point. They'll always use doubles 3582680Sktlim@umich.edu # for the moment. 3592190SN/A class addfp(FpBinaryOp): 3602190SN/A code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;' 3612680Sktlim@umich.edu 3622680Sktlim@umich.edu class mulfp(FpBinaryOp): 3632190SN/A code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;' 3642680Sktlim@umich.edu op_class = 'FloatMultOp' 3652190SN/A 3662680Sktlim@umich.edu class divfp(FpBinaryOp): 3672190SN/A code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;' 3682680Sktlim@umich.edu op_class = 'FloatDivOp' 3692190SN/A 3702235SN/A class subfp(FpBinaryOp): 3712680Sktlim@umich.edu code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;' 3722235SN/A 3732680Sktlim@umich.edu class Yl2xFp(FpBinaryOp): 3742680Sktlim@umich.edu code = ''' 3752254SN/A FpDestReg = FpSrcReg2 * (log(FpSrcReg1) / log(2)); 3762680Sktlim@umich.edu ''' 3772680Sktlim@umich.edu op_class = 'FloatSqrtOp' 3782235SN/A 3792SN/A class PremFp(FpBinaryOp): 3802190SN/A code = ''' 3812680Sktlim@umich.edu MiscReg new_fsw(FSW); 3822SN/A int src1_exp; 3832680Sktlim@umich.edu int src2_exp; 384716SN/A std::frexp(FpSrcReg1, &src1_exp); 3852SN/A std::frexp(FpSrcReg2, &src2_exp); 3862SN/A 3872SN/A const int d(src2_exp - src1_exp); 3882SN/A if (d < 64) { 3892680Sktlim@umich.edu const int64_t q(std::trunc(FpSrcReg2 / FpSrcReg1)); 3902SN/A FpDestReg = FpSrcReg2 - FpSrcReg1 * q; 3912455SN/A new_fsw &= ~(CC0Bit | CC1Bit | CC2Bit | CC2Bit); 3922680Sktlim@umich.edu new_fsw |= (q & 0x1) ? CC1Bit : 0; 3932SN/A new_fsw |= (q & 0x2) ? CC3Bit : 0; 3942455SN/A new_fsw |= (q & 0x4) ? CC0Bit : 0; 3952680Sktlim@umich.edu } else { 3962SN/A const int n(42); 3972SN/A const int64_t qq(std::trunc( 3982680Sktlim@umich.edu FpSrcReg2 / std::ldexp(FpSrcReg1, d - n))); 3992SN/A FpDestReg = FpSrcReg2 - std::ldexp(FpSrcReg1 * qq, d - n); 4002455SN/A new_fsw |= CC2Bit; 4012680Sktlim@umich.edu } 4022SN/A DPRINTF(X86, "src1: %lf, src2: %lf, dest: %lf, FSW: 0x%x\\n", 4032455SN/A FpSrcReg1, FpSrcReg2, FpDestReg, new_fsw); 4042680Sktlim@umich.edu ''' 4052SN/A op_class = 'FloatDivOp' 4067720Sgblack@eecs.umich.edu 4072SN/A flag_code = 'FSW = new_fsw;' 4087720Sgblack@eecs.umich.edu 4092206SN/A class Compfp(FpBinaryOp): 4108733Sgeoffrey.blake@arm.com def __init__(self, src1, src2, spm=0, setStatus=False, updateFTW=True, \ 4118733Sgeoffrey.blake@arm.com dataSize="env.dataSize"): 4128733Sgeoffrey.blake@arm.com super(Compfp, self).__init__("InstRegIndex(FLOATREG_MICROFP0)", \ 4138733Sgeoffrey.blake@arm.com src1, src2, spm, setStatus, updateFTW, dataSize) 4147720Sgblack@eecs.umich.edu # This class sets the condition codes in rflags according to the 4157720Sgblack@eecs.umich.edu # rules for comparing floating point. 4167720Sgblack@eecs.umich.edu code = ''' 4175260Sksewell@umich.edu // ZF PF CF 4187597Sminkyu.jeong@arm.com // Unordered 1 1 1 4197597Sminkyu.jeong@arm.com // Greater than 0 0 0 4207597Sminkyu.jeong@arm.com // Less than 0 0 1 4217597Sminkyu.jeong@arm.com // Equal 1 0 0 4227597Sminkyu.jeong@arm.com // OF = SF = AF = 0 4234172Ssaidi@eecs.umich.edu ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit); 4244172Ssaidi@eecs.umich.edu cfofBits = cfofBits & ~(OFBit | CFBit); 4254172Ssaidi@eecs.umich.edu 4262159SN/A if (std::isnan(FpSrcReg1) || std::isnan(FpSrcReg2)) { 4272680Sktlim@umich.edu ccFlagBits = ccFlagBits | (ZFBit | PFBit); 4282SN/A cfofBits = cfofBits | CFBit; 4294172Ssaidi@eecs.umich.edu } 4304172Ssaidi@eecs.umich.edu else if(FpSrcReg1 < FpSrcReg2) 4312SN/A cfofBits = cfofBits | CFBit; 4323468Sgblack@eecs.umich.edu else if(FpSrcReg1 == FpSrcReg2) 4332680Sktlim@umich.edu ccFlagBits = ccFlagBits | ZFBit; 4342SN/A ''' 4356313Sgblack@eecs.umich.edu op_class = 'FloatCmpOp' 4366313Sgblack@eecs.umich.edu 4376313Sgblack@eecs.umich.edu class absfp(FpUnaryOp): 4386313Sgblack@eecs.umich.edu code = 'FpDestReg = fabs(FpSrcReg1);' 4396313Sgblack@eecs.umich.edu flag_code = 'FSW = FSW & (~CC1Bit);' 4406313Sgblack@eecs.umich.edu 4412190SN/A class chsfp(FpUnaryOp): 4422680Sktlim@umich.edu code = 'FpDestReg = (-1) * (FpSrcReg1);' 4432190SN/A flag_code = 'FSW = FSW & (~CC1Bit);' 4442190SN/A 4452680Sktlim@umich.edu class Pop87(FpUnaryOp): 4462SN/A def __init__(self, spm=1, UpdateFTW=True): 4472190SN/A super(Pop87, self).__init__( \ 4482680Sktlim@umich.edu "InstRegIndex(FLOATREG_MICROFP0)", \ 4492190SN/A "InstRegIndex(FLOATREG_MICROFP0)", \ 4501858SN/A spm=spm, SetStatus=False, UpdateFTW=UpdateFTW) 4514111Sgblack@eecs.umich.edu 4524111Sgblack@eecs.umich.edu code = '' 4534111Sgblack@eecs.umich.edu op_class = 'IntAluOp' 4542680Sktlim@umich.edu}}; 4552SN/A