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