mediaop.isa revision 6572
16516Sgblack@eecs.umich.edu/// Copyright (c) 2009 The Regents of The University of Michigan
26516Sgblack@eecs.umich.edu// All rights reserved.
36516Sgblack@eecs.umich.edu//
46516Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
56516Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
66516Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
76516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
86516Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
96516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
106516Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
116516Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
126516Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
136516Sgblack@eecs.umich.edu// this software without specific prior written permission.
146516Sgblack@eecs.umich.edu//
156516Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
166516Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
176516Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
186516Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
196516Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
206516Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
216516Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
226516Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236516Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
246516Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
256516Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266516Sgblack@eecs.umich.edu//
276516Sgblack@eecs.umich.edu// Authors: Gabe Black
286516Sgblack@eecs.umich.edu
296516Sgblack@eecs.umich.edudef template MediaOpExecute {{
306516Sgblack@eecs.umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
316516Sgblack@eecs.umich.edu                Trace::InstRecord *traceData) const
326516Sgblack@eecs.umich.edu        {
336516Sgblack@eecs.umich.edu            Fault fault = NoFault;
346516Sgblack@eecs.umich.edu
356516Sgblack@eecs.umich.edu            %(op_decl)s;
366516Sgblack@eecs.umich.edu            %(op_rd)s;
376516Sgblack@eecs.umich.edu
386516Sgblack@eecs.umich.edu            %(code)s;
396516Sgblack@eecs.umich.edu
406516Sgblack@eecs.umich.edu            //Write the resulting state to the execution context
416516Sgblack@eecs.umich.edu            if(fault == NoFault)
426516Sgblack@eecs.umich.edu            {
436516Sgblack@eecs.umich.edu                %(op_wb)s;
446516Sgblack@eecs.umich.edu            }
456516Sgblack@eecs.umich.edu            return fault;
466516Sgblack@eecs.umich.edu        }
476516Sgblack@eecs.umich.edu}};
486516Sgblack@eecs.umich.edu
496516Sgblack@eecs.umich.edudef template MediaOpRegDeclare {{
506516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
516516Sgblack@eecs.umich.edu    {
526516Sgblack@eecs.umich.edu      protected:
536516Sgblack@eecs.umich.edu        void buildMe();
546516Sgblack@eecs.umich.edu
556516Sgblack@eecs.umich.edu      public:
566516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
576516Sgblack@eecs.umich.edu                const char * instMnem,
586516Sgblack@eecs.umich.edu                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
596516Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
606545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
616516Sgblack@eecs.umich.edu
626516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
636516Sgblack@eecs.umich.edu                const char * instMnem,
646516Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
656545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
666516Sgblack@eecs.umich.edu
676516Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
686516Sgblack@eecs.umich.edu    };
696516Sgblack@eecs.umich.edu}};
706516Sgblack@eecs.umich.edu
716516Sgblack@eecs.umich.edudef template MediaOpImmDeclare {{
726516Sgblack@eecs.umich.edu
736516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
746516Sgblack@eecs.umich.edu    {
756516Sgblack@eecs.umich.edu      protected:
766516Sgblack@eecs.umich.edu        void buildMe();
776516Sgblack@eecs.umich.edu
786516Sgblack@eecs.umich.edu      public:
796516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
806516Sgblack@eecs.umich.edu                const char * instMnem,
816516Sgblack@eecs.umich.edu                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
826516Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
836545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
846516Sgblack@eecs.umich.edu
856516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
866516Sgblack@eecs.umich.edu                const char * instMnem,
876516Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
886545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
896516Sgblack@eecs.umich.edu
906516Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
916516Sgblack@eecs.umich.edu    };
926516Sgblack@eecs.umich.edu}};
936516Sgblack@eecs.umich.edu
946516Sgblack@eecs.umich.edudef template MediaOpRegConstructor {{
956516Sgblack@eecs.umich.edu
966516Sgblack@eecs.umich.edu    inline void %(class_name)s::buildMe()
976516Sgblack@eecs.umich.edu    {
986516Sgblack@eecs.umich.edu        %(constructor)s;
996516Sgblack@eecs.umich.edu    }
1006516Sgblack@eecs.umich.edu
1016516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1026516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1036516Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
1046545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
1056516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1066516Sgblack@eecs.umich.edu                false, false, false, false,
1076545Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _ext,
1086516Sgblack@eecs.umich.edu                %(op_class)s)
1096516Sgblack@eecs.umich.edu    {
1106516Sgblack@eecs.umich.edu        buildMe();
1116516Sgblack@eecs.umich.edu    }
1126516Sgblack@eecs.umich.edu
1136516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1146516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1156516Sgblack@eecs.umich.edu            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
1166516Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
1176545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
1186516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1196516Sgblack@eecs.umich.edu                isMicro, isDelayed, isFirst, isLast,
1206545Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _ext,
1216516Sgblack@eecs.umich.edu                %(op_class)s)
1226516Sgblack@eecs.umich.edu    {
1236516Sgblack@eecs.umich.edu        buildMe();
1246516Sgblack@eecs.umich.edu    }
1256516Sgblack@eecs.umich.edu}};
1266516Sgblack@eecs.umich.edu
1276516Sgblack@eecs.umich.edudef template MediaOpImmConstructor {{
1286516Sgblack@eecs.umich.edu
1296516Sgblack@eecs.umich.edu    inline void %(class_name)s::buildMe()
1306516Sgblack@eecs.umich.edu    {
1316516Sgblack@eecs.umich.edu        %(constructor)s;
1326516Sgblack@eecs.umich.edu    }
1336516Sgblack@eecs.umich.edu
1346516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1356516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1366516Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
1376545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
1386516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1396516Sgblack@eecs.umich.edu                false, false, false, false,
1406545Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _ext,
1416516Sgblack@eecs.umich.edu                %(op_class)s)
1426516Sgblack@eecs.umich.edu    {
1436516Sgblack@eecs.umich.edu        buildMe();
1446516Sgblack@eecs.umich.edu    }
1456516Sgblack@eecs.umich.edu
1466516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1476516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1486516Sgblack@eecs.umich.edu            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
1496516Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
1506545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
1516516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1526516Sgblack@eecs.umich.edu                isMicro, isDelayed, isFirst, isLast,
1536545Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _ext,
1546516Sgblack@eecs.umich.edu                %(op_class)s)
1556516Sgblack@eecs.umich.edu    {
1566516Sgblack@eecs.umich.edu        buildMe();
1576516Sgblack@eecs.umich.edu    }
1586516Sgblack@eecs.umich.edu}};
1596516Sgblack@eecs.umich.edu
1606516Sgblack@eecs.umich.edulet {{
1616516Sgblack@eecs.umich.edu    # Make these empty strings so that concatenating onto
1626516Sgblack@eecs.umich.edu    # them will always work.
1636516Sgblack@eecs.umich.edu    header_output = ""
1646516Sgblack@eecs.umich.edu    decoder_output = ""
1656516Sgblack@eecs.umich.edu    exec_output = ""
1666516Sgblack@eecs.umich.edu
1676516Sgblack@eecs.umich.edu    immTemplates = (
1686516Sgblack@eecs.umich.edu            MediaOpImmDeclare,
1696516Sgblack@eecs.umich.edu            MediaOpImmConstructor,
1706516Sgblack@eecs.umich.edu            MediaOpExecute)
1716516Sgblack@eecs.umich.edu
1726516Sgblack@eecs.umich.edu    regTemplates = (
1736516Sgblack@eecs.umich.edu            MediaOpRegDeclare,
1746516Sgblack@eecs.umich.edu            MediaOpRegConstructor,
1756516Sgblack@eecs.umich.edu            MediaOpExecute)
1766516Sgblack@eecs.umich.edu
1776516Sgblack@eecs.umich.edu    class MediaOpMeta(type):
1786516Sgblack@eecs.umich.edu        def buildCppClasses(self, name, Name, suffix, code):
1796516Sgblack@eecs.umich.edu
1806516Sgblack@eecs.umich.edu            # Globals to stick the output in
1816516Sgblack@eecs.umich.edu            global header_output
1826516Sgblack@eecs.umich.edu            global decoder_output
1836516Sgblack@eecs.umich.edu            global exec_output
1846516Sgblack@eecs.umich.edu
1856516Sgblack@eecs.umich.edu            # If op2 is used anywhere, make register and immediate versions
1866516Sgblack@eecs.umich.edu            # of this code.
1876516Sgblack@eecs.umich.edu            matcher = re.compile("(?<!\\w)(?P<prefix>s?)op2(?P<typeQual>\\.\\w+)?")
1886516Sgblack@eecs.umich.edu            match = matcher.search(code)
1896516Sgblack@eecs.umich.edu            if match:
1906516Sgblack@eecs.umich.edu                typeQual = ""
1916516Sgblack@eecs.umich.edu                if match.group("typeQual"):
1926516Sgblack@eecs.umich.edu                    typeQual = match.group("typeQual")
1936516Sgblack@eecs.umich.edu                src2_name = "%spsrc2%s" % (match.group("prefix"), typeQual)
1946516Sgblack@eecs.umich.edu                self.buildCppClasses(name, Name, suffix,
1956516Sgblack@eecs.umich.edu                        matcher.sub(src2_name, code))
1966516Sgblack@eecs.umich.edu                self.buildCppClasses(name + "i", Name, suffix + "Imm",
1976516Sgblack@eecs.umich.edu                        matcher.sub("imm8", code))
1986516Sgblack@eecs.umich.edu                return
1996516Sgblack@eecs.umich.edu
2006516Sgblack@eecs.umich.edu            base = "X86ISA::MediaOp"
2016516Sgblack@eecs.umich.edu
2026516Sgblack@eecs.umich.edu            # If imm8 shows up in the code, use the immediate templates, if
2036516Sgblack@eecs.umich.edu            # not, hopefully the register ones will be correct.
2046516Sgblack@eecs.umich.edu            matcher = re.compile("(?<!\w)imm8(?!\w)")
2056516Sgblack@eecs.umich.edu            if matcher.search(code):
2066516Sgblack@eecs.umich.edu                base += "Imm"
2076516Sgblack@eecs.umich.edu                templates = immTemplates
2086516Sgblack@eecs.umich.edu            else:
2096516Sgblack@eecs.umich.edu                base += "Reg"
2106516Sgblack@eecs.umich.edu                templates = regTemplates
2116516Sgblack@eecs.umich.edu
2126516Sgblack@eecs.umich.edu            # Get everything ready for the substitution
2136516Sgblack@eecs.umich.edu            iop = InstObjParams(name, Name + suffix, base, {"code" : code})
2146516Sgblack@eecs.umich.edu
2156516Sgblack@eecs.umich.edu            # Generate the actual code (finally!)
2166516Sgblack@eecs.umich.edu            header_output += templates[0].subst(iop)
2176516Sgblack@eecs.umich.edu            decoder_output += templates[1].subst(iop)
2186516Sgblack@eecs.umich.edu            exec_output += templates[2].subst(iop)
2196516Sgblack@eecs.umich.edu
2206516Sgblack@eecs.umich.edu
2216516Sgblack@eecs.umich.edu        def __new__(mcls, Name, bases, dict):
2226516Sgblack@eecs.umich.edu            abstract = False
2236516Sgblack@eecs.umich.edu            name = Name.lower()
2246516Sgblack@eecs.umich.edu            if "abstract" in dict:
2256516Sgblack@eecs.umich.edu                abstract = dict['abstract']
2266516Sgblack@eecs.umich.edu                del dict['abstract']
2276516Sgblack@eecs.umich.edu
2286516Sgblack@eecs.umich.edu            cls = super(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict)
2296516Sgblack@eecs.umich.edu            if not abstract:
2306516Sgblack@eecs.umich.edu                cls.className = Name
2316516Sgblack@eecs.umich.edu                cls.base_mnemonic = name
2326516Sgblack@eecs.umich.edu                code = cls.code
2336516Sgblack@eecs.umich.edu
2346516Sgblack@eecs.umich.edu                # Set up the C++ classes
2356516Sgblack@eecs.umich.edu                mcls.buildCppClasses(cls, name, Name, "", code)
2366516Sgblack@eecs.umich.edu
2376516Sgblack@eecs.umich.edu                # Hook into the microassembler dict
2386516Sgblack@eecs.umich.edu                global microopClasses
2396516Sgblack@eecs.umich.edu                microopClasses[name] = cls
2406516Sgblack@eecs.umich.edu
2416516Sgblack@eecs.umich.edu                # If op2 is used anywhere, make register and immediate versions
2426516Sgblack@eecs.umich.edu                # of this code.
2436516Sgblack@eecs.umich.edu                matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
2446516Sgblack@eecs.umich.edu                if matcher.search(code):
2456516Sgblack@eecs.umich.edu                    microopClasses[name + 'i'] = cls
2466516Sgblack@eecs.umich.edu            return cls
2476516Sgblack@eecs.umich.edu
2486516Sgblack@eecs.umich.edu
2496516Sgblack@eecs.umich.edu    class MediaOp(X86Microop):
2506516Sgblack@eecs.umich.edu        __metaclass__ = MediaOpMeta
2516516Sgblack@eecs.umich.edu        # This class itself doesn't act as a microop
2526516Sgblack@eecs.umich.edu        abstract = True
2536516Sgblack@eecs.umich.edu
2546516Sgblack@eecs.umich.edu        def __init__(self, dest, src1, op2,
2556545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2566516Sgblack@eecs.umich.edu            self.dest = dest
2576516Sgblack@eecs.umich.edu            self.src1 = src1
2586516Sgblack@eecs.umich.edu            self.op2 = op2
2596516Sgblack@eecs.umich.edu            if size is not None:
2606516Sgblack@eecs.umich.edu                self.srcSize = size
2616516Sgblack@eecs.umich.edu                self.destSize = size
2626516Sgblack@eecs.umich.edu            if srcSize is not None:
2636516Sgblack@eecs.umich.edu                self.srcSize = srcSize
2646516Sgblack@eecs.umich.edu            if destSize is not None:
2656516Sgblack@eecs.umich.edu                self.destSize = destSize
2666516Sgblack@eecs.umich.edu            if self.srcSize is None:
2676516Sgblack@eecs.umich.edu                raise Exception, "Source size not set."
2686516Sgblack@eecs.umich.edu            if self.destSize is None:
2696516Sgblack@eecs.umich.edu                raise Exception, "Dest size not set."
2706545Sgblack@eecs.umich.edu            if ext is None:
2716545Sgblack@eecs.umich.edu                self.ext = 0
2726516Sgblack@eecs.umich.edu            else:
2736545Sgblack@eecs.umich.edu                self.ext = ext 
2746516Sgblack@eecs.umich.edu
2756516Sgblack@eecs.umich.edu        def getAllocator(self, *microFlags):
2766516Sgblack@eecs.umich.edu            className = self.className
2776516Sgblack@eecs.umich.edu            if self.mnemonic == self.base_mnemonic + 'i':
2786516Sgblack@eecs.umich.edu                className += "Imm"
2796516Sgblack@eecs.umich.edu            allocator = '''new %(class_name)s(machInst, macrocodeBlock
2806516Sgblack@eecs.umich.edu                    %(flags)s, %(src1)s, %(op2)s, %(dest)s,
2816545Sgblack@eecs.umich.edu                    %(srcSize)s, %(destSize)s, %(ext)s)''' % {
2826516Sgblack@eecs.umich.edu                "class_name" : className,
2836516Sgblack@eecs.umich.edu                "flags" : self.microFlagsText(microFlags),
2846516Sgblack@eecs.umich.edu                "src1" : self.src1, "op2" : self.op2,
2856516Sgblack@eecs.umich.edu                "dest" : self.dest,
2866516Sgblack@eecs.umich.edu                "srcSize" : self.srcSize,
2876516Sgblack@eecs.umich.edu                "destSize" : self.destSize,
2886545Sgblack@eecs.umich.edu                "ext" : self.ext}
2896516Sgblack@eecs.umich.edu            return allocator
2906516Sgblack@eecs.umich.edu
2916516Sgblack@eecs.umich.edu    class Mov2int(MediaOp):
2926516Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
2936545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2946516Sgblack@eecs.umich.edu            super(Mov2int, self).__init__(dest, src,\
2956545Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
2966516Sgblack@eecs.umich.edu        code = '''
2976516Sgblack@eecs.umich.edu            uint64_t fpSrcReg1 = bits(FpSrcReg1.uqw, srcSize * 8 - 1, 0);
2986516Sgblack@eecs.umich.edu            DestReg = merge(DestReg, fpSrcReg1, destSize);
2996516Sgblack@eecs.umich.edu        '''
3006516Sgblack@eecs.umich.edu
3016516Sgblack@eecs.umich.edu    class Mov2fp(MediaOp):
3026516Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
3036545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
3046516Sgblack@eecs.umich.edu            super(Mov2fp, self).__init__(dest, src,\
3056545Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
3066516Sgblack@eecs.umich.edu        code = '''
3076516Sgblack@eecs.umich.edu            uint64_t srcReg1 = pick(SrcReg1, 0, srcSize);
3086516Sgblack@eecs.umich.edu            FpDestReg.uqw =
3096516Sgblack@eecs.umich.edu                insertBits(FpDestReg.uqw, destSize * 8 - 1, 0, srcReg1);
3106516Sgblack@eecs.umich.edu        '''
3116521Sgblack@eecs.umich.edu
3126521Sgblack@eecs.umich.edu    class Unpack(MediaOp):
3136521Sgblack@eecs.umich.edu        code = '''
3146521Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3156521Sgblack@eecs.umich.edu            int size = destSize;
3166521Sgblack@eecs.umich.edu            int items = (sizeof(FloatRegBits) / size) / 2;
3176545Sgblack@eecs.umich.edu            int offset = ext ? items : 0;
3186521Sgblack@eecs.umich.edu            uint64_t result = 0;
3196521Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3206521Sgblack@eecs.umich.edu                uint64_t pickedLow =
3216521Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + offset + 1) * 8 * size - 1,
3226521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
3236521Sgblack@eecs.umich.edu                result = insertBits(result,
3246521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size - 1,
3256521Sgblack@eecs.umich.edu                                    (2 * i + 0) * 8 * size,
3266521Sgblack@eecs.umich.edu                                    pickedLow);
3276521Sgblack@eecs.umich.edu                uint64_t pickedHigh =
3286521Sgblack@eecs.umich.edu                    bits(FpSrcReg2.uqw, (i + offset + 1) * 8 * size - 1,
3296521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
3306521Sgblack@eecs.umich.edu                result = insertBits(result,
3316521Sgblack@eecs.umich.edu                                    (2 * i + 2) * 8 * size - 1,
3326521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size,
3336521Sgblack@eecs.umich.edu                                    pickedHigh);
3346521Sgblack@eecs.umich.edu            }
3356521Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
3366521Sgblack@eecs.umich.edu        '''
3376534Sgblack@eecs.umich.edu
3386546Sgblack@eecs.umich.edu    class Pack(MediaOp):
3396546Sgblack@eecs.umich.edu        code = '''
3406546Sgblack@eecs.umich.edu            assert(srcSize == destSize * 2);
3416546Sgblack@eecs.umich.edu            int items = (sizeof(FloatRegBits) / destSize);
3426546Sgblack@eecs.umich.edu            int destBits = destSize * 8;
3436546Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
3446546Sgblack@eecs.umich.edu            uint64_t result = 0;
3456546Sgblack@eecs.umich.edu            int i;
3466546Sgblack@eecs.umich.edu            for (i = 0; i < items / 2; i++) {
3476546Sgblack@eecs.umich.edu                uint64_t picked =
3486546Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + 1) * srcBits - 1,
3496546Sgblack@eecs.umich.edu                                        (i + 0) * srcBits);
3506546Sgblack@eecs.umich.edu                unsigned signBit = bits(picked, srcBits - 1);
3516546Sgblack@eecs.umich.edu                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
3526546Sgblack@eecs.umich.edu
3536546Sgblack@eecs.umich.edu                // Handle saturation.
3546546Sgblack@eecs.umich.edu                if (signBit) {
3556546Sgblack@eecs.umich.edu                    if (overflow != mask(destBits - srcBits + 1)) {
3566546Sgblack@eecs.umich.edu                        if (ext & 0x1)
3576546Sgblack@eecs.umich.edu                            picked = (1 << (destBits - 1));
3586546Sgblack@eecs.umich.edu                        else
3596546Sgblack@eecs.umich.edu                            picked = 0;
3606546Sgblack@eecs.umich.edu                    }
3616546Sgblack@eecs.umich.edu                } else {
3626546Sgblack@eecs.umich.edu                    if (overflow != 0) {
3636546Sgblack@eecs.umich.edu                        if (ext & 0x1)
3646546Sgblack@eecs.umich.edu                            picked = mask(destBits - 1);
3656546Sgblack@eecs.umich.edu                        else
3666546Sgblack@eecs.umich.edu                            picked = mask(destBits);
3676546Sgblack@eecs.umich.edu                    }
3686546Sgblack@eecs.umich.edu                }
3696546Sgblack@eecs.umich.edu                result = insertBits(result,
3706546Sgblack@eecs.umich.edu                                    (i + 1) * destBits - 1,
3716546Sgblack@eecs.umich.edu                                    (i + 0) * destBits,
3726546Sgblack@eecs.umich.edu                                    picked);
3736546Sgblack@eecs.umich.edu            }
3746546Sgblack@eecs.umich.edu            for (;i < items; i++) {
3756546Sgblack@eecs.umich.edu                uint64_t picked =
3766546Sgblack@eecs.umich.edu                    bits(FpSrcReg2.uqw, (i - items + 1) * srcBits - 1,
3776546Sgblack@eecs.umich.edu                                        (i - items + 0) * srcBits);
3786546Sgblack@eecs.umich.edu                unsigned signBit = bits(picked, srcBits - 1);
3796546Sgblack@eecs.umich.edu                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
3806546Sgblack@eecs.umich.edu
3816546Sgblack@eecs.umich.edu                // Handle saturation.
3826546Sgblack@eecs.umich.edu                if (signBit) {
3836546Sgblack@eecs.umich.edu                    if (overflow != mask(destBits - srcBits + 1)) {
3846546Sgblack@eecs.umich.edu                        if (ext & 0x1)
3856546Sgblack@eecs.umich.edu                            picked = (1 << (destBits - 1));
3866546Sgblack@eecs.umich.edu                        else
3876546Sgblack@eecs.umich.edu                            picked = 0;
3886546Sgblack@eecs.umich.edu                    }
3896546Sgblack@eecs.umich.edu                } else {
3906546Sgblack@eecs.umich.edu                    if (overflow != 0) {
3916546Sgblack@eecs.umich.edu                        if (ext & 0x1)
3926546Sgblack@eecs.umich.edu                            picked = mask(destBits - 1);
3936546Sgblack@eecs.umich.edu                        else
3946546Sgblack@eecs.umich.edu                            picked = mask(destBits);
3956546Sgblack@eecs.umich.edu                    }
3966546Sgblack@eecs.umich.edu                }
3976546Sgblack@eecs.umich.edu                result = insertBits(result,
3986546Sgblack@eecs.umich.edu                                    (i + 1) * destBits - 1,
3996546Sgblack@eecs.umich.edu                                    (i + 0) * destBits,
4006546Sgblack@eecs.umich.edu                                    picked);
4016546Sgblack@eecs.umich.edu            }
4026546Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
4036546Sgblack@eecs.umich.edu        '''
4046546Sgblack@eecs.umich.edu
4056534Sgblack@eecs.umich.edu    class Mxor(MediaOp):
4066534Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4076534Sgblack@eecs.umich.edu            super(Mxor, self).__init__(dest, src1, src2, 1)
4086534Sgblack@eecs.umich.edu        code = '''
4096534Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw;
4106534Sgblack@eecs.umich.edu        '''
4116537Sgblack@eecs.umich.edu
4126537Sgblack@eecs.umich.edu    class Mor(MediaOp):
4136537Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4146537Sgblack@eecs.umich.edu            super(Mor, self).__init__(dest, src1, src2, 1)
4156537Sgblack@eecs.umich.edu        code = '''
4166537Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw | FpSrcReg2.uqw;
4176537Sgblack@eecs.umich.edu        '''
4186539Sgblack@eecs.umich.edu
4196539Sgblack@eecs.umich.edu    class Mand(MediaOp):
4206539Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4216539Sgblack@eecs.umich.edu            super(Mand, self).__init__(dest, src1, src2, 1)
4226539Sgblack@eecs.umich.edu        code = '''
4236539Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw & FpSrcReg2.uqw;
4246539Sgblack@eecs.umich.edu        '''
4256541Sgblack@eecs.umich.edu
4266541Sgblack@eecs.umich.edu    class Mandn(MediaOp):
4276541Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4286541Sgblack@eecs.umich.edu            super(Mandn, self).__init__(dest, src1, src2, 1)
4296541Sgblack@eecs.umich.edu        code = '''
4306541Sgblack@eecs.umich.edu            FpDestReg.uqw = ~FpSrcReg1.uqw & FpSrcReg2.uqw;
4316541Sgblack@eecs.umich.edu        '''
4326548Sgblack@eecs.umich.edu
4336548Sgblack@eecs.umich.edu    class Mminf(MediaOp):
4346548Sgblack@eecs.umich.edu        code = '''
4356548Sgblack@eecs.umich.edu            union floatInt
4366548Sgblack@eecs.umich.edu            {
4376548Sgblack@eecs.umich.edu                float f;
4386548Sgblack@eecs.umich.edu                uint32_t i;
4396548Sgblack@eecs.umich.edu            };
4406548Sgblack@eecs.umich.edu            union doubleInt
4416548Sgblack@eecs.umich.edu            {
4426548Sgblack@eecs.umich.edu                double d;
4436548Sgblack@eecs.umich.edu                uint64_t i;
4446548Sgblack@eecs.umich.edu            };
4456548Sgblack@eecs.umich.edu
4466548Sgblack@eecs.umich.edu            assert(srcSize == destSize);
4476548Sgblack@eecs.umich.edu            int size = srcSize;
4486548Sgblack@eecs.umich.edu            int sizeBits = size * 8;
4496548Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
4506548Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
4516548Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
4526548Sgblack@eecs.umich.edu
4536548Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
4546548Sgblack@eecs.umich.edu                double arg1, arg2;
4556548Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
4566548Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
4576548Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
4586548Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
4596548Sgblack@eecs.umich.edu
4606548Sgblack@eecs.umich.edu                if (size == 4) {
4616548Sgblack@eecs.umich.edu                    floatInt fi;
4626548Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
4636548Sgblack@eecs.umich.edu                    arg1 = fi.f;
4646548Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
4656548Sgblack@eecs.umich.edu                    arg2 = fi.f;
4666548Sgblack@eecs.umich.edu                } else {
4676548Sgblack@eecs.umich.edu                    doubleInt di;
4686548Sgblack@eecs.umich.edu                    di.i = arg1Bits;
4696548Sgblack@eecs.umich.edu                    arg1 = di.d;
4706548Sgblack@eecs.umich.edu                    di.i = arg2Bits;
4716548Sgblack@eecs.umich.edu                    arg2 = di.d;
4726548Sgblack@eecs.umich.edu                }
4736548Sgblack@eecs.umich.edu
4746548Sgblack@eecs.umich.edu                if (arg1 < arg2) {
4756548Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
4766548Sgblack@eecs.umich.edu                } else {
4776548Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
4786548Sgblack@eecs.umich.edu                }
4796548Sgblack@eecs.umich.edu            }
4806548Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
4816548Sgblack@eecs.umich.edu        '''
4826550Sgblack@eecs.umich.edu
4836550Sgblack@eecs.umich.edu    class Mmaxf(MediaOp):
4846550Sgblack@eecs.umich.edu        code = '''
4856550Sgblack@eecs.umich.edu            union floatInt
4866550Sgblack@eecs.umich.edu            {
4876550Sgblack@eecs.umich.edu                float f;
4886550Sgblack@eecs.umich.edu                uint32_t i;
4896550Sgblack@eecs.umich.edu            };
4906550Sgblack@eecs.umich.edu            union doubleInt
4916550Sgblack@eecs.umich.edu            {
4926550Sgblack@eecs.umich.edu                double d;
4936550Sgblack@eecs.umich.edu                uint64_t i;
4946550Sgblack@eecs.umich.edu            };
4956550Sgblack@eecs.umich.edu
4966550Sgblack@eecs.umich.edu            assert(srcSize == destSize);
4976550Sgblack@eecs.umich.edu            int size = srcSize;
4986550Sgblack@eecs.umich.edu            int sizeBits = size * 8;
4996550Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
5006550Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
5016550Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
5026550Sgblack@eecs.umich.edu
5036550Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
5046550Sgblack@eecs.umich.edu                double arg1, arg2;
5056550Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5066550Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5076550Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
5086550Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
5096550Sgblack@eecs.umich.edu
5106550Sgblack@eecs.umich.edu                if (size == 4) {
5116550Sgblack@eecs.umich.edu                    floatInt fi;
5126550Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
5136550Sgblack@eecs.umich.edu                    arg1 = fi.f;
5146550Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
5156550Sgblack@eecs.umich.edu                    arg2 = fi.f;
5166550Sgblack@eecs.umich.edu                } else {
5176550Sgblack@eecs.umich.edu                    doubleInt di;
5186550Sgblack@eecs.umich.edu                    di.i = arg1Bits;
5196550Sgblack@eecs.umich.edu                    arg1 = di.d;
5206550Sgblack@eecs.umich.edu                    di.i = arg2Bits;
5216550Sgblack@eecs.umich.edu                    arg2 = di.d;
5226550Sgblack@eecs.umich.edu                }
5236550Sgblack@eecs.umich.edu
5246550Sgblack@eecs.umich.edu                if (arg1 > arg2) {
5256550Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
5266550Sgblack@eecs.umich.edu                } else {
5276550Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
5286550Sgblack@eecs.umich.edu                }
5296550Sgblack@eecs.umich.edu            }
5306550Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
5316550Sgblack@eecs.umich.edu        '''
5326552Sgblack@eecs.umich.edu
5336572Sgblack@eecs.umich.edu    class Mmini(MediaOp):
5346572Sgblack@eecs.umich.edu        code = '''
5356572Sgblack@eecs.umich.edu
5366572Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5376572Sgblack@eecs.umich.edu            int size = srcSize;
5386572Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5396572Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
5406572Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
5416572Sgblack@eecs.umich.edu
5426572Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
5436572Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5446572Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5456572Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
5466572Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
5476572Sgblack@eecs.umich.edu                    (0 - (arg1Bits & (1 << (sizeBits - 1))));
5486572Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
5496572Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
5506572Sgblack@eecs.umich.edu                    (0 - (arg2Bits & (1 << (sizeBits - 1))));
5516572Sgblack@eecs.umich.edu                uint64_t resBits;
5526572Sgblack@eecs.umich.edu
5536572Sgblack@eecs.umich.edu                if (ext & 0x2) {
5546572Sgblack@eecs.umich.edu                    if (arg1 < arg2) {
5556572Sgblack@eecs.umich.edu                        resBits = arg1Bits;
5566572Sgblack@eecs.umich.edu                    } else {
5576572Sgblack@eecs.umich.edu                        resBits = arg2Bits;
5586572Sgblack@eecs.umich.edu                    }
5596572Sgblack@eecs.umich.edu                } else {
5606572Sgblack@eecs.umich.edu                    if (arg1Bits < arg2Bits) {
5616572Sgblack@eecs.umich.edu                        resBits = arg1Bits;
5626572Sgblack@eecs.umich.edu                    } else {
5636572Sgblack@eecs.umich.edu                        resBits = arg2Bits;
5646572Sgblack@eecs.umich.edu                    }
5656572Sgblack@eecs.umich.edu                }
5666572Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
5676572Sgblack@eecs.umich.edu            }
5686572Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
5696572Sgblack@eecs.umich.edu        '''
5706572Sgblack@eecs.umich.edu
5716552Sgblack@eecs.umich.edu    class Msqrt(MediaOp):
5726552Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
5736552Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
5746552Sgblack@eecs.umich.edu            super(Msqrt, self).__init__(dest, src,\
5756552Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
5766552Sgblack@eecs.umich.edu        code = '''
5776552Sgblack@eecs.umich.edu            union floatInt
5786552Sgblack@eecs.umich.edu            {
5796552Sgblack@eecs.umich.edu                float f;
5806552Sgblack@eecs.umich.edu                uint32_t i;
5816552Sgblack@eecs.umich.edu            };
5826552Sgblack@eecs.umich.edu            union doubleInt
5836552Sgblack@eecs.umich.edu            {
5846552Sgblack@eecs.umich.edu                double d;
5856552Sgblack@eecs.umich.edu                uint64_t i;
5866552Sgblack@eecs.umich.edu            };
5876552Sgblack@eecs.umich.edu
5886552Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5896552Sgblack@eecs.umich.edu            int size = srcSize;
5906552Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5916552Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
5926552Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
5936552Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
5946552Sgblack@eecs.umich.edu
5956552Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
5966552Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5976552Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5986552Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
5996552Sgblack@eecs.umich.edu
6006552Sgblack@eecs.umich.edu                if (size == 4) {
6016552Sgblack@eecs.umich.edu                    floatInt fi;
6026552Sgblack@eecs.umich.edu                    fi.i = argBits;
6036552Sgblack@eecs.umich.edu                    fi.f = sqrt(fi.f);
6046552Sgblack@eecs.umich.edu                    argBits = fi.i;
6056552Sgblack@eecs.umich.edu                } else {
6066552Sgblack@eecs.umich.edu                    doubleInt di;
6076552Sgblack@eecs.umich.edu                    di.i = argBits;
6086552Sgblack@eecs.umich.edu                    di.d = sqrt(di.d);
6096552Sgblack@eecs.umich.edu                    argBits = di.i;
6106552Sgblack@eecs.umich.edu                }
6116552Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, argBits);
6126552Sgblack@eecs.umich.edu            }
6136552Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
6146552Sgblack@eecs.umich.edu        '''
6156554Sgblack@eecs.umich.edu
6166554Sgblack@eecs.umich.edu    class Maddf(MediaOp):
6176554Sgblack@eecs.umich.edu        code = '''
6186554Sgblack@eecs.umich.edu            union floatInt
6196554Sgblack@eecs.umich.edu            {
6206554Sgblack@eecs.umich.edu                float f;
6216554Sgblack@eecs.umich.edu                uint32_t i;
6226554Sgblack@eecs.umich.edu            };
6236554Sgblack@eecs.umich.edu            union doubleInt
6246554Sgblack@eecs.umich.edu            {
6256554Sgblack@eecs.umich.edu                double d;
6266554Sgblack@eecs.umich.edu                uint64_t i;
6276554Sgblack@eecs.umich.edu            };
6286554Sgblack@eecs.umich.edu
6296554Sgblack@eecs.umich.edu            assert(srcSize == destSize);
6306554Sgblack@eecs.umich.edu            int size = srcSize;
6316554Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6326554Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
6336554Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
6346554Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
6356554Sgblack@eecs.umich.edu
6366554Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6376554Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6386554Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6396554Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
6406554Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
6416554Sgblack@eecs.umich.edu                uint64_t resBits;
6426554Sgblack@eecs.umich.edu
6436554Sgblack@eecs.umich.edu                if (size == 4) {
6446554Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
6456554Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
6466554Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
6476554Sgblack@eecs.umich.edu                    res.f = arg1.f + arg2.f;
6486554Sgblack@eecs.umich.edu                    resBits = res.i;
6496554Sgblack@eecs.umich.edu                } else {
6506554Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
6516554Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
6526554Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
6536554Sgblack@eecs.umich.edu                    res.d = arg1.d + arg2.d;
6546554Sgblack@eecs.umich.edu                    resBits = res.i;
6556554Sgblack@eecs.umich.edu                }
6566554Sgblack@eecs.umich.edu
6576554Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
6586554Sgblack@eecs.umich.edu            }
6596554Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
6606554Sgblack@eecs.umich.edu        '''
6616556Sgblack@eecs.umich.edu
6626556Sgblack@eecs.umich.edu    class Msubf(MediaOp):
6636556Sgblack@eecs.umich.edu        code = '''
6646556Sgblack@eecs.umich.edu            union floatInt
6656556Sgblack@eecs.umich.edu            {
6666556Sgblack@eecs.umich.edu                float f;
6676556Sgblack@eecs.umich.edu                uint32_t i;
6686556Sgblack@eecs.umich.edu            };
6696556Sgblack@eecs.umich.edu            union doubleInt
6706556Sgblack@eecs.umich.edu            {
6716556Sgblack@eecs.umich.edu                double d;
6726556Sgblack@eecs.umich.edu                uint64_t i;
6736556Sgblack@eecs.umich.edu            };
6746556Sgblack@eecs.umich.edu
6756556Sgblack@eecs.umich.edu            assert(srcSize == destSize);
6766556Sgblack@eecs.umich.edu            int size = srcSize;
6776556Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6786556Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
6796556Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
6806556Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
6816556Sgblack@eecs.umich.edu
6826556Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6836556Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6846556Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6856556Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
6866556Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
6876556Sgblack@eecs.umich.edu                uint64_t resBits;
6886556Sgblack@eecs.umich.edu
6896556Sgblack@eecs.umich.edu                if (size == 4) {
6906556Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
6916556Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
6926556Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
6936556Sgblack@eecs.umich.edu                    res.f = arg1.f - arg2.f;
6946556Sgblack@eecs.umich.edu                    resBits = res.i;
6956556Sgblack@eecs.umich.edu                } else {
6966556Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
6976556Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
6986556Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
6996556Sgblack@eecs.umich.edu                    res.d = arg1.d - arg2.d;
7006556Sgblack@eecs.umich.edu                    resBits = res.i;
7016556Sgblack@eecs.umich.edu                }
7026556Sgblack@eecs.umich.edu
7036556Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
7046556Sgblack@eecs.umich.edu            }
7056556Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
7066556Sgblack@eecs.umich.edu        '''
7076558Sgblack@eecs.umich.edu
7086558Sgblack@eecs.umich.edu    class Mmulf(MediaOp):
7096558Sgblack@eecs.umich.edu        code = '''
7106558Sgblack@eecs.umich.edu            union floatInt
7116558Sgblack@eecs.umich.edu            {
7126558Sgblack@eecs.umich.edu                float f;
7136558Sgblack@eecs.umich.edu                uint32_t i;
7146558Sgblack@eecs.umich.edu            };
7156558Sgblack@eecs.umich.edu            union doubleInt
7166558Sgblack@eecs.umich.edu            {
7176558Sgblack@eecs.umich.edu                double d;
7186558Sgblack@eecs.umich.edu                uint64_t i;
7196558Sgblack@eecs.umich.edu            };
7206558Sgblack@eecs.umich.edu
7216558Sgblack@eecs.umich.edu            assert(srcSize == destSize);
7226558Sgblack@eecs.umich.edu            int size = srcSize;
7236558Sgblack@eecs.umich.edu            int sizeBits = size * 8;
7246558Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
7256558Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
7266558Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
7276558Sgblack@eecs.umich.edu
7286558Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
7296558Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
7306558Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
7316558Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
7326558Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
7336558Sgblack@eecs.umich.edu                uint64_t resBits;
7346558Sgblack@eecs.umich.edu
7356558Sgblack@eecs.umich.edu                if (size == 4) {
7366558Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
7376558Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7386558Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7396558Sgblack@eecs.umich.edu                    res.f = arg1.f * arg2.f;
7406558Sgblack@eecs.umich.edu                    resBits = res.i;
7416558Sgblack@eecs.umich.edu                } else {
7426558Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
7436558Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7446558Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7456558Sgblack@eecs.umich.edu                    res.d = arg1.d * arg2.d;
7466558Sgblack@eecs.umich.edu                    resBits = res.i;
7476558Sgblack@eecs.umich.edu                }
7486558Sgblack@eecs.umich.edu
7496558Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
7506558Sgblack@eecs.umich.edu            }
7516558Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
7526558Sgblack@eecs.umich.edu        '''
7536560Sgblack@eecs.umich.edu
7546560Sgblack@eecs.umich.edu    class Mdivf(MediaOp):
7556560Sgblack@eecs.umich.edu        code = '''
7566560Sgblack@eecs.umich.edu            union floatInt
7576560Sgblack@eecs.umich.edu            {
7586560Sgblack@eecs.umich.edu                float f;
7596560Sgblack@eecs.umich.edu                uint32_t i;
7606560Sgblack@eecs.umich.edu            };
7616560Sgblack@eecs.umich.edu            union doubleInt
7626560Sgblack@eecs.umich.edu            {
7636560Sgblack@eecs.umich.edu                double d;
7646560Sgblack@eecs.umich.edu                uint64_t i;
7656560Sgblack@eecs.umich.edu            };
7666560Sgblack@eecs.umich.edu
7676560Sgblack@eecs.umich.edu            assert(srcSize == destSize);
7686560Sgblack@eecs.umich.edu            int size = srcSize;
7696560Sgblack@eecs.umich.edu            int sizeBits = size * 8;
7706560Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
7716560Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
7726560Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
7736560Sgblack@eecs.umich.edu
7746560Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
7756560Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
7766560Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
7776560Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
7786560Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
7796560Sgblack@eecs.umich.edu                uint64_t resBits;
7806560Sgblack@eecs.umich.edu
7816560Sgblack@eecs.umich.edu                if (size == 4) {
7826560Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
7836560Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7846560Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7856560Sgblack@eecs.umich.edu                    res.f = arg1.f / arg2.f;
7866560Sgblack@eecs.umich.edu                    resBits = res.i;
7876560Sgblack@eecs.umich.edu                } else {
7886560Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
7896560Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7906560Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7916560Sgblack@eecs.umich.edu                    res.d = arg1.d / arg2.d;
7926560Sgblack@eecs.umich.edu                    resBits = res.i;
7936560Sgblack@eecs.umich.edu                }
7946560Sgblack@eecs.umich.edu
7956560Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
7966560Sgblack@eecs.umich.edu            }
7976560Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
7986560Sgblack@eecs.umich.edu        '''
7996562Sgblack@eecs.umich.edu
8006570Sgblack@eecs.umich.edu    class Maddi(MediaOp):
8016570Sgblack@eecs.umich.edu        code = '''
8026570Sgblack@eecs.umich.edu            assert(srcSize == destSize);
8036570Sgblack@eecs.umich.edu            int size = srcSize;
8046570Sgblack@eecs.umich.edu            int sizeBits = size * 8;
8056570Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
8066570Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
8076570Sgblack@eecs.umich.edu
8086570Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8096570Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
8106570Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8116570Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
8126570Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
8136570Sgblack@eecs.umich.edu                uint64_t resBits = arg1Bits + arg2Bits;
8146570Sgblack@eecs.umich.edu                
8156570Sgblack@eecs.umich.edu                if (ext & 0x2) {
8166570Sgblack@eecs.umich.edu                    if (findCarry(sizeBits, resBits, arg1Bits, arg2Bits))
8176570Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
8186570Sgblack@eecs.umich.edu                } else if (ext & 0x4) {
8196570Sgblack@eecs.umich.edu                    int arg1Sign = bits(arg1Bits, sizeBits - 1);
8206570Sgblack@eecs.umich.edu                    int arg2Sign = bits(arg2Bits, sizeBits - 1);
8216570Sgblack@eecs.umich.edu                    int resSign = bits(resBits, sizeBits - 1);
8226570Sgblack@eecs.umich.edu                    if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
8236570Sgblack@eecs.umich.edu                        if (resSign == 0)
8246570Sgblack@eecs.umich.edu                            resBits = (1 << (sizeBits - 1));
8256570Sgblack@eecs.umich.edu                        else
8266570Sgblack@eecs.umich.edu                            resBits = mask(sizeBits - 1);
8276570Sgblack@eecs.umich.edu                    }
8286570Sgblack@eecs.umich.edu                }
8296570Sgblack@eecs.umich.edu
8306570Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
8316570Sgblack@eecs.umich.edu            }
8326570Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
8336570Sgblack@eecs.umich.edu        '''
8346570Sgblack@eecs.umich.edu
8356562Sgblack@eecs.umich.edu    class Cvti2f(MediaOp):
8366562Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
8376562Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
8386562Sgblack@eecs.umich.edu            super(Cvti2f, self).__init__(dest, src,\
8396562Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
8406562Sgblack@eecs.umich.edu        code = '''
8416562Sgblack@eecs.umich.edu            union floatInt
8426562Sgblack@eecs.umich.edu            {
8436562Sgblack@eecs.umich.edu                float f;
8446562Sgblack@eecs.umich.edu                uint32_t i;
8456562Sgblack@eecs.umich.edu            };
8466562Sgblack@eecs.umich.edu            union doubleInt
8476562Sgblack@eecs.umich.edu            {
8486562Sgblack@eecs.umich.edu                double d;
8496562Sgblack@eecs.umich.edu                uint64_t i;
8506562Sgblack@eecs.umich.edu            };
8516562Sgblack@eecs.umich.edu
8526562Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
8536562Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
8546562Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
8556562Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
8566562Sgblack@eecs.umich.edu            int items;
8576562Sgblack@eecs.umich.edu            int srcStart = 0;
8586562Sgblack@eecs.umich.edu            int destStart = 0;
8596562Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
8606562Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / srcSize;
8616562Sgblack@eecs.umich.edu                if (ext & 0x2)
8626562Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
8636562Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
8646562Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
8656562Sgblack@eecs.umich.edu                if (ext & 0x2)
8666562Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
8676562Sgblack@eecs.umich.edu            } else {
8686562Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
8696562Sgblack@eecs.umich.edu            }
8706562Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
8716562Sgblack@eecs.umich.edu
8726562Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8736562Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
8746562Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
8756562Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
8766562Sgblack@eecs.umich.edu                int64_t sArg = argBits | (0 - (argBits & (1 << srcHiIndex)));
8776562Sgblack@eecs.umich.edu                double arg = sArg;
8786562Sgblack@eecs.umich.edu
8796562Sgblack@eecs.umich.edu                if (destSize == 4) {
8806562Sgblack@eecs.umich.edu                    floatInt fi;
8816562Sgblack@eecs.umich.edu                    fi.f = arg;
8826562Sgblack@eecs.umich.edu                    argBits = fi.i;
8836562Sgblack@eecs.umich.edu                } else {
8846562Sgblack@eecs.umich.edu                    doubleInt di;
8856562Sgblack@eecs.umich.edu                    di.d = arg;
8866562Sgblack@eecs.umich.edu                    argBits = di.i;
8876562Sgblack@eecs.umich.edu                }
8886562Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
8896562Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
8906562Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
8916562Sgblack@eecs.umich.edu            }
8926562Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
8936562Sgblack@eecs.umich.edu        '''
8946566Sgblack@eecs.umich.edu
8956568Sgblack@eecs.umich.edu    class Cvtf2f(MediaOp):
8966568Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
8976568Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
8986568Sgblack@eecs.umich.edu            super(Cvtf2f, self).__init__(dest, src,\
8996568Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
9006568Sgblack@eecs.umich.edu        code = '''
9016568Sgblack@eecs.umich.edu            union floatInt
9026568Sgblack@eecs.umich.edu            {
9036568Sgblack@eecs.umich.edu                float f;
9046568Sgblack@eecs.umich.edu                uint32_t i;
9056568Sgblack@eecs.umich.edu            };
9066568Sgblack@eecs.umich.edu            union doubleInt
9076568Sgblack@eecs.umich.edu            {
9086568Sgblack@eecs.umich.edu                double d;
9096568Sgblack@eecs.umich.edu                uint64_t i;
9106568Sgblack@eecs.umich.edu            };
9116568Sgblack@eecs.umich.edu
9126568Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
9136568Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
9146568Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
9156568Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
9166568Sgblack@eecs.umich.edu            int items;
9176568Sgblack@eecs.umich.edu            int srcStart = 0;
9186568Sgblack@eecs.umich.edu            int destStart = 0;
9196568Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
9206568Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / srcSize;
9216568Sgblack@eecs.umich.edu                if (ext & 0x2)
9226568Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
9236568Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
9246568Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
9256568Sgblack@eecs.umich.edu                if (ext & 0x2)
9266568Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
9276568Sgblack@eecs.umich.edu            } else {
9286568Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
9296568Sgblack@eecs.umich.edu            }
9306568Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
9316568Sgblack@eecs.umich.edu
9326568Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9336568Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
9346568Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
9356568Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
9366568Sgblack@eecs.umich.edu                double arg;
9376568Sgblack@eecs.umich.edu
9386568Sgblack@eecs.umich.edu                if (srcSize == 4) {
9396568Sgblack@eecs.umich.edu                    floatInt fi;
9406568Sgblack@eecs.umich.edu                    fi.i = argBits;
9416568Sgblack@eecs.umich.edu                    arg = fi.f;
9426568Sgblack@eecs.umich.edu                } else {
9436568Sgblack@eecs.umich.edu                    doubleInt di;
9446568Sgblack@eecs.umich.edu                    di.i = argBits;
9456568Sgblack@eecs.umich.edu                    arg = di.d;
9466568Sgblack@eecs.umich.edu                }
9476568Sgblack@eecs.umich.edu                if (destSize == 4) {
9486568Sgblack@eecs.umich.edu                    floatInt fi;
9496568Sgblack@eecs.umich.edu                    fi.f = arg;
9506568Sgblack@eecs.umich.edu                    argBits = fi.i;
9516568Sgblack@eecs.umich.edu                } else {
9526568Sgblack@eecs.umich.edu                    doubleInt di;
9536568Sgblack@eecs.umich.edu                    di.d = arg;
9546568Sgblack@eecs.umich.edu                    argBits = di.i;
9556568Sgblack@eecs.umich.edu                }
9566568Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
9576568Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
9586568Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
9596568Sgblack@eecs.umich.edu            }
9606568Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
9616568Sgblack@eecs.umich.edu        '''
9626568Sgblack@eecs.umich.edu
9636566Sgblack@eecs.umich.edu    class Mcmpi2r(MediaOp):
9646566Sgblack@eecs.umich.edu        code = '''
9656566Sgblack@eecs.umich.edu            union floatInt
9666566Sgblack@eecs.umich.edu            {
9676566Sgblack@eecs.umich.edu                float f;
9686566Sgblack@eecs.umich.edu                uint32_t i;
9696566Sgblack@eecs.umich.edu            };
9706566Sgblack@eecs.umich.edu            union doubleInt
9716566Sgblack@eecs.umich.edu            {
9726566Sgblack@eecs.umich.edu                double d;
9736566Sgblack@eecs.umich.edu                uint64_t i;
9746566Sgblack@eecs.umich.edu            };
9756566Sgblack@eecs.umich.edu
9766566Sgblack@eecs.umich.edu            assert(srcSize == destSize);
9776566Sgblack@eecs.umich.edu            int size = srcSize;
9786566Sgblack@eecs.umich.edu            int sizeBits = size * 8;
9796566Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
9806566Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
9816566Sgblack@eecs.umich.edu
9826566Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9836566Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
9846566Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
9856566Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
9866566Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
9876566Sgblack@eecs.umich.edu                    (0 - (arg1Bits & (1 << (sizeBits - 1))));
9886566Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
9896566Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
9906566Sgblack@eecs.umich.edu                    (0 - (arg2Bits & (1 << (sizeBits - 1))));
9916566Sgblack@eecs.umich.edu
9926566Sgblack@eecs.umich.edu                uint64_t resBits = 0;
9936566Sgblack@eecs.umich.edu                if ((ext & 0x2) == 0 && arg1 == arg2 ||
9946566Sgblack@eecs.umich.edu                        (ext & 0x2) == 0x2 && arg1 > arg2)
9956566Sgblack@eecs.umich.edu                    resBits = mask(sizeBits);
9966566Sgblack@eecs.umich.edu
9976566Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
9986566Sgblack@eecs.umich.edu            }
9996566Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
10006566Sgblack@eecs.umich.edu        '''
10016516Sgblack@eecs.umich.edu}};
1002