mediaop.isa revision 7626
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      public:
536516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
547620Sgblack@eecs.umich.edu                const char * instMnem, uint64_t setFlags,
556516Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
566545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
576516Sgblack@eecs.umich.edu
586516Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
596516Sgblack@eecs.umich.edu    };
606516Sgblack@eecs.umich.edu}};
616516Sgblack@eecs.umich.edu
626516Sgblack@eecs.umich.edudef template MediaOpImmDeclare {{
636516Sgblack@eecs.umich.edu
646516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
656516Sgblack@eecs.umich.edu    {
666516Sgblack@eecs.umich.edu      public:
676516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
687620Sgblack@eecs.umich.edu                const char * instMnem, uint64_t setFlags,
696516Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
706545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
716516Sgblack@eecs.umich.edu
726516Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
736516Sgblack@eecs.umich.edu    };
746516Sgblack@eecs.umich.edu}};
756516Sgblack@eecs.umich.edu
766516Sgblack@eecs.umich.edudef template MediaOpRegConstructor {{
776516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
787620Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
796516Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
806545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
817620Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
826545Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _ext,
836516Sgblack@eecs.umich.edu                %(op_class)s)
846516Sgblack@eecs.umich.edu    {
857626Sgblack@eecs.umich.edu        %(constructor)s;
866516Sgblack@eecs.umich.edu    }
876516Sgblack@eecs.umich.edu}};
886516Sgblack@eecs.umich.edu
896516Sgblack@eecs.umich.edudef template MediaOpImmConstructor {{
906516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
917620Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
926516Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
936545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
947620Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
956545Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _ext,
966516Sgblack@eecs.umich.edu                %(op_class)s)
976516Sgblack@eecs.umich.edu    {
987626Sgblack@eecs.umich.edu        %(constructor)s;
996516Sgblack@eecs.umich.edu    }
1006516Sgblack@eecs.umich.edu}};
1016516Sgblack@eecs.umich.edu
1026516Sgblack@eecs.umich.edulet {{
1036516Sgblack@eecs.umich.edu    # Make these empty strings so that concatenating onto
1046516Sgblack@eecs.umich.edu    # them will always work.
1056516Sgblack@eecs.umich.edu    header_output = ""
1066516Sgblack@eecs.umich.edu    decoder_output = ""
1076516Sgblack@eecs.umich.edu    exec_output = ""
1086516Sgblack@eecs.umich.edu
1096516Sgblack@eecs.umich.edu    immTemplates = (
1106516Sgblack@eecs.umich.edu            MediaOpImmDeclare,
1116516Sgblack@eecs.umich.edu            MediaOpImmConstructor,
1126516Sgblack@eecs.umich.edu            MediaOpExecute)
1136516Sgblack@eecs.umich.edu
1146516Sgblack@eecs.umich.edu    regTemplates = (
1156516Sgblack@eecs.umich.edu            MediaOpRegDeclare,
1166516Sgblack@eecs.umich.edu            MediaOpRegConstructor,
1176516Sgblack@eecs.umich.edu            MediaOpExecute)
1186516Sgblack@eecs.umich.edu
1196516Sgblack@eecs.umich.edu    class MediaOpMeta(type):
1206516Sgblack@eecs.umich.edu        def buildCppClasses(self, name, Name, suffix, code):
1216516Sgblack@eecs.umich.edu
1226516Sgblack@eecs.umich.edu            # Globals to stick the output in
1236516Sgblack@eecs.umich.edu            global header_output
1246516Sgblack@eecs.umich.edu            global decoder_output
1256516Sgblack@eecs.umich.edu            global exec_output
1266516Sgblack@eecs.umich.edu
1276516Sgblack@eecs.umich.edu            # If op2 is used anywhere, make register and immediate versions
1286516Sgblack@eecs.umich.edu            # of this code.
1296516Sgblack@eecs.umich.edu            matcher = re.compile("(?<!\\w)(?P<prefix>s?)op2(?P<typeQual>\\.\\w+)?")
1306516Sgblack@eecs.umich.edu            match = matcher.search(code)
1316516Sgblack@eecs.umich.edu            if match:
1326516Sgblack@eecs.umich.edu                typeQual = ""
1336516Sgblack@eecs.umich.edu                if match.group("typeQual"):
1346516Sgblack@eecs.umich.edu                    typeQual = match.group("typeQual")
1356583Sgblack@eecs.umich.edu                src2_name = "%sFpSrcReg2%s" % (match.group("prefix"), typeQual)
1366516Sgblack@eecs.umich.edu                self.buildCppClasses(name, Name, suffix,
1376516Sgblack@eecs.umich.edu                        matcher.sub(src2_name, code))
1386516Sgblack@eecs.umich.edu                self.buildCppClasses(name + "i", Name, suffix + "Imm",
1396516Sgblack@eecs.umich.edu                        matcher.sub("imm8", code))
1406516Sgblack@eecs.umich.edu                return
1416516Sgblack@eecs.umich.edu
1426516Sgblack@eecs.umich.edu            base = "X86ISA::MediaOp"
1436516Sgblack@eecs.umich.edu
1446516Sgblack@eecs.umich.edu            # If imm8 shows up in the code, use the immediate templates, if
1456516Sgblack@eecs.umich.edu            # not, hopefully the register ones will be correct.
1466516Sgblack@eecs.umich.edu            matcher = re.compile("(?<!\w)imm8(?!\w)")
1476516Sgblack@eecs.umich.edu            if matcher.search(code):
1486516Sgblack@eecs.umich.edu                base += "Imm"
1496516Sgblack@eecs.umich.edu                templates = immTemplates
1506516Sgblack@eecs.umich.edu            else:
1516516Sgblack@eecs.umich.edu                base += "Reg"
1526516Sgblack@eecs.umich.edu                templates = regTemplates
1536516Sgblack@eecs.umich.edu
1546516Sgblack@eecs.umich.edu            # Get everything ready for the substitution
1556516Sgblack@eecs.umich.edu            iop = InstObjParams(name, Name + suffix, base, {"code" : code})
1566516Sgblack@eecs.umich.edu
1576516Sgblack@eecs.umich.edu            # Generate the actual code (finally!)
1586516Sgblack@eecs.umich.edu            header_output += templates[0].subst(iop)
1596516Sgblack@eecs.umich.edu            decoder_output += templates[1].subst(iop)
1606516Sgblack@eecs.umich.edu            exec_output += templates[2].subst(iop)
1616516Sgblack@eecs.umich.edu
1626516Sgblack@eecs.umich.edu
1636516Sgblack@eecs.umich.edu        def __new__(mcls, Name, bases, dict):
1646516Sgblack@eecs.umich.edu            abstract = False
1656516Sgblack@eecs.umich.edu            name = Name.lower()
1666516Sgblack@eecs.umich.edu            if "abstract" in dict:
1676516Sgblack@eecs.umich.edu                abstract = dict['abstract']
1686516Sgblack@eecs.umich.edu                del dict['abstract']
1696516Sgblack@eecs.umich.edu
1706516Sgblack@eecs.umich.edu            cls = super(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict)
1716516Sgblack@eecs.umich.edu            if not abstract:
1726516Sgblack@eecs.umich.edu                cls.className = Name
1736516Sgblack@eecs.umich.edu                cls.base_mnemonic = name
1746516Sgblack@eecs.umich.edu                code = cls.code
1756516Sgblack@eecs.umich.edu
1766516Sgblack@eecs.umich.edu                # Set up the C++ classes
1776516Sgblack@eecs.umich.edu                mcls.buildCppClasses(cls, name, Name, "", code)
1786516Sgblack@eecs.umich.edu
1796516Sgblack@eecs.umich.edu                # Hook into the microassembler dict
1806516Sgblack@eecs.umich.edu                global microopClasses
1816516Sgblack@eecs.umich.edu                microopClasses[name] = cls
1826516Sgblack@eecs.umich.edu
1836516Sgblack@eecs.umich.edu                # If op2 is used anywhere, make register and immediate versions
1846516Sgblack@eecs.umich.edu                # of this code.
1856516Sgblack@eecs.umich.edu                matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
1866516Sgblack@eecs.umich.edu                if matcher.search(code):
1876516Sgblack@eecs.umich.edu                    microopClasses[name + 'i'] = cls
1886516Sgblack@eecs.umich.edu            return cls
1896516Sgblack@eecs.umich.edu
1906516Sgblack@eecs.umich.edu
1916516Sgblack@eecs.umich.edu    class MediaOp(X86Microop):
1926516Sgblack@eecs.umich.edu        __metaclass__ = MediaOpMeta
1936516Sgblack@eecs.umich.edu        # This class itself doesn't act as a microop
1946516Sgblack@eecs.umich.edu        abstract = True
1956516Sgblack@eecs.umich.edu
1966516Sgblack@eecs.umich.edu        def __init__(self, dest, src1, op2,
1976545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
1986516Sgblack@eecs.umich.edu            self.dest = dest
1996516Sgblack@eecs.umich.edu            self.src1 = src1
2006516Sgblack@eecs.umich.edu            self.op2 = op2
2016516Sgblack@eecs.umich.edu            if size is not None:
2026516Sgblack@eecs.umich.edu                self.srcSize = size
2036516Sgblack@eecs.umich.edu                self.destSize = size
2046516Sgblack@eecs.umich.edu            if srcSize is not None:
2056516Sgblack@eecs.umich.edu                self.srcSize = srcSize
2066516Sgblack@eecs.umich.edu            if destSize is not None:
2076516Sgblack@eecs.umich.edu                self.destSize = destSize
2086516Sgblack@eecs.umich.edu            if self.srcSize is None:
2096516Sgblack@eecs.umich.edu                raise Exception, "Source size not set."
2106516Sgblack@eecs.umich.edu            if self.destSize is None:
2116516Sgblack@eecs.umich.edu                raise Exception, "Dest size not set."
2126545Sgblack@eecs.umich.edu            if ext is None:
2136545Sgblack@eecs.umich.edu                self.ext = 0
2146516Sgblack@eecs.umich.edu            else:
2156545Sgblack@eecs.umich.edu                self.ext = ext 
2166516Sgblack@eecs.umich.edu
2177620Sgblack@eecs.umich.edu        def getAllocator(self, microFlags):
2186516Sgblack@eecs.umich.edu            className = self.className
2196516Sgblack@eecs.umich.edu            if self.mnemonic == self.base_mnemonic + 'i':
2206516Sgblack@eecs.umich.edu                className += "Imm"
2217620Sgblack@eecs.umich.edu            allocator = '''new %(class_name)s(machInst, macrocodeBlock,
2226516Sgblack@eecs.umich.edu                    %(flags)s, %(src1)s, %(op2)s, %(dest)s,
2236545Sgblack@eecs.umich.edu                    %(srcSize)s, %(destSize)s, %(ext)s)''' % {
2246516Sgblack@eecs.umich.edu                "class_name" : className,
2256516Sgblack@eecs.umich.edu                "flags" : self.microFlagsText(microFlags),
2266516Sgblack@eecs.umich.edu                "src1" : self.src1, "op2" : self.op2,
2276516Sgblack@eecs.umich.edu                "dest" : self.dest,
2286516Sgblack@eecs.umich.edu                "srcSize" : self.srcSize,
2296516Sgblack@eecs.umich.edu                "destSize" : self.destSize,
2306545Sgblack@eecs.umich.edu                "ext" : self.ext}
2316516Sgblack@eecs.umich.edu            return allocator
2326516Sgblack@eecs.umich.edu
2336516Sgblack@eecs.umich.edu    class Mov2int(MediaOp):
2346589Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2 = 0, \
2356545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2366589Sgblack@eecs.umich.edu            super(Mov2int, self).__init__(dest, src1,\
2376589Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
2386516Sgblack@eecs.umich.edu        code = '''
2396589Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / srcSize;
2406589Sgblack@eecs.umich.edu            int offset = imm8;
2416589Sgblack@eecs.umich.edu            if (bits(src1, 0) && (ext & 0x1))
2426589Sgblack@eecs.umich.edu                offset -= items;
2436589Sgblack@eecs.umich.edu            if (offset >= 0 && offset < items) {
2446589Sgblack@eecs.umich.edu                uint64_t fpSrcReg1 =
2456589Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw,
2466589Sgblack@eecs.umich.edu                            (offset + 1) * srcSize * 8 - 1,
2476589Sgblack@eecs.umich.edu                            (offset + 0) * srcSize * 8);
2486589Sgblack@eecs.umich.edu                DestReg = merge(0, fpSrcReg1, destSize);
2496589Sgblack@eecs.umich.edu            } else {
2506589Sgblack@eecs.umich.edu                DestReg = DestReg;
2516589Sgblack@eecs.umich.edu            }
2526516Sgblack@eecs.umich.edu        '''
2536516Sgblack@eecs.umich.edu
2546516Sgblack@eecs.umich.edu    class Mov2fp(MediaOp):
2556589Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2 = 0, \
2566545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2576589Sgblack@eecs.umich.edu            super(Mov2fp, self).__init__(dest, src1,\
2586589Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
2596516Sgblack@eecs.umich.edu        code = '''
2606589Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / destSize;
2616589Sgblack@eecs.umich.edu            int offset = imm8;
2626589Sgblack@eecs.umich.edu            if (bits(dest, 0) && (ext & 0x1))
2636589Sgblack@eecs.umich.edu                offset -= items;
2646589Sgblack@eecs.umich.edu            if (offset >= 0 && offset < items) {
2656589Sgblack@eecs.umich.edu                uint64_t srcReg1 = pick(SrcReg1, 0, srcSize);
2666589Sgblack@eecs.umich.edu                FpDestReg.uqw =
2676589Sgblack@eecs.umich.edu                    insertBits(FpDestReg.uqw,
2686589Sgblack@eecs.umich.edu                            (offset + 1) * destSize * 8 - 1,
2696589Sgblack@eecs.umich.edu                            (offset + 0) * destSize * 8, srcReg1);
2706589Sgblack@eecs.umich.edu            } else {
2716589Sgblack@eecs.umich.edu                FpDestReg.uqw = FpDestReg.uqw;
2726589Sgblack@eecs.umich.edu            }
2736516Sgblack@eecs.umich.edu        '''
2746521Sgblack@eecs.umich.edu
2756592Sgblack@eecs.umich.edu    class Movsign(MediaOp):
2766592Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
2776592Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2786592Sgblack@eecs.umich.edu            super(Movsign, self).__init__(dest, src,\
2796592Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
2806592Sgblack@eecs.umich.edu        code = '''
2816592Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / srcSize;
2826592Sgblack@eecs.umich.edu            uint64_t result = 0;
2836592Sgblack@eecs.umich.edu            int offset = (ext & 0x1) ? items : 0;
2846592Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
2856592Sgblack@eecs.umich.edu                uint64_t picked =
2866592Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + 1) * 8 * srcSize - 1);
2876592Sgblack@eecs.umich.edu                result = insertBits(result, i + offset, i + offset, picked);
2886592Sgblack@eecs.umich.edu            }
2896592Sgblack@eecs.umich.edu            DestReg = DestReg | result;
2906592Sgblack@eecs.umich.edu        '''
2916592Sgblack@eecs.umich.edu
2926594Sgblack@eecs.umich.edu    class Maskmov(MediaOp):
2936594Sgblack@eecs.umich.edu        code = '''
2946594Sgblack@eecs.umich.edu            assert(srcSize == destSize);
2956594Sgblack@eecs.umich.edu            int size = srcSize;
2966594Sgblack@eecs.umich.edu            int sizeBits = size * 8;
2976799Sgblack@eecs.umich.edu            int items = numItems(size);
2986594Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
2996594Sgblack@eecs.umich.edu
3006594Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3016594Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
3026594Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
3036594Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
3046594Sgblack@eecs.umich.edu                if (bits(FpSrcReg2.uqw, hiIndex))
3056594Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
3066594Sgblack@eecs.umich.edu            }
3076594Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
3086594Sgblack@eecs.umich.edu        '''
3096594Sgblack@eecs.umich.edu
3106596Sgblack@eecs.umich.edu    class shuffle(MediaOp):
3116596Sgblack@eecs.umich.edu        code = '''
3126596Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3136596Sgblack@eecs.umich.edu            int size = srcSize;
3146596Sgblack@eecs.umich.edu            int sizeBits = size * 8;
3156596Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / size;
3166596Sgblack@eecs.umich.edu            int options;
3176596Sgblack@eecs.umich.edu            int optionBits;
3186596Sgblack@eecs.umich.edu            if (size == 8) {
3196596Sgblack@eecs.umich.edu                options = 2;
3206596Sgblack@eecs.umich.edu                optionBits = 1;
3216596Sgblack@eecs.umich.edu            } else {
3226596Sgblack@eecs.umich.edu                options = 4;
3236596Sgblack@eecs.umich.edu                optionBits = 2;
3246596Sgblack@eecs.umich.edu            }
3256596Sgblack@eecs.umich.edu
3266596Sgblack@eecs.umich.edu            uint64_t result = 0;
3276596Sgblack@eecs.umich.edu            uint8_t sel = ext;
3286596Sgblack@eecs.umich.edu
3296596Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3306596Sgblack@eecs.umich.edu                uint64_t resBits;
3316596Sgblack@eecs.umich.edu                uint8_t lsel = sel & mask(optionBits);
3326596Sgblack@eecs.umich.edu                if (lsel * size >= sizeof(FloatRegBits)) {
3336596Sgblack@eecs.umich.edu                    lsel -= options / 2;
3346596Sgblack@eecs.umich.edu                    resBits = bits(FpSrcReg2.uqw,
3356596Sgblack@eecs.umich.edu                            (lsel + 1) * sizeBits - 1,
3366596Sgblack@eecs.umich.edu                            (lsel + 0) * sizeBits);
3376596Sgblack@eecs.umich.edu                }  else {
3386596Sgblack@eecs.umich.edu                    resBits = bits(FpSrcReg1.uqw,
3396596Sgblack@eecs.umich.edu                            (lsel + 1) * sizeBits - 1,
3406596Sgblack@eecs.umich.edu                            (lsel + 0) * sizeBits);
3416596Sgblack@eecs.umich.edu                }
3426596Sgblack@eecs.umich.edu
3436596Sgblack@eecs.umich.edu                sel >>= optionBits;
3446596Sgblack@eecs.umich.edu
3456596Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
3466596Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
3476596Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
3486596Sgblack@eecs.umich.edu            }
3496596Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
3506596Sgblack@eecs.umich.edu        '''
3516596Sgblack@eecs.umich.edu
3526521Sgblack@eecs.umich.edu    class Unpack(MediaOp):
3536521Sgblack@eecs.umich.edu        code = '''
3546521Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3556521Sgblack@eecs.umich.edu            int size = destSize;
3566521Sgblack@eecs.umich.edu            int items = (sizeof(FloatRegBits) / size) / 2;
3576545Sgblack@eecs.umich.edu            int offset = ext ? items : 0;
3586521Sgblack@eecs.umich.edu            uint64_t result = 0;
3596521Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3606521Sgblack@eecs.umich.edu                uint64_t pickedLow =
3616521Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + offset + 1) * 8 * size - 1,
3626521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
3636521Sgblack@eecs.umich.edu                result = insertBits(result,
3646521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size - 1,
3656521Sgblack@eecs.umich.edu                                    (2 * i + 0) * 8 * size,
3666521Sgblack@eecs.umich.edu                                    pickedLow);
3676521Sgblack@eecs.umich.edu                uint64_t pickedHigh =
3686521Sgblack@eecs.umich.edu                    bits(FpSrcReg2.uqw, (i + offset + 1) * 8 * size - 1,
3696521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
3706521Sgblack@eecs.umich.edu                result = insertBits(result,
3716521Sgblack@eecs.umich.edu                                    (2 * i + 2) * 8 * size - 1,
3726521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size,
3736521Sgblack@eecs.umich.edu                                    pickedHigh);
3746521Sgblack@eecs.umich.edu            }
3756521Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
3766521Sgblack@eecs.umich.edu        '''
3776534Sgblack@eecs.umich.edu
3786546Sgblack@eecs.umich.edu    class Pack(MediaOp):
3796546Sgblack@eecs.umich.edu        code = '''
3806546Sgblack@eecs.umich.edu            assert(srcSize == destSize * 2);
3816546Sgblack@eecs.umich.edu            int items = (sizeof(FloatRegBits) / destSize);
3826546Sgblack@eecs.umich.edu            int destBits = destSize * 8;
3836546Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
3846546Sgblack@eecs.umich.edu            uint64_t result = 0;
3856546Sgblack@eecs.umich.edu            int i;
3866546Sgblack@eecs.umich.edu            for (i = 0; i < items / 2; i++) {
3876546Sgblack@eecs.umich.edu                uint64_t picked =
3886546Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + 1) * srcBits - 1,
3896546Sgblack@eecs.umich.edu                                        (i + 0) * srcBits);
3906546Sgblack@eecs.umich.edu                unsigned signBit = bits(picked, srcBits - 1);
3916546Sgblack@eecs.umich.edu                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
3926546Sgblack@eecs.umich.edu
3936546Sgblack@eecs.umich.edu                // Handle saturation.
3946546Sgblack@eecs.umich.edu                if (signBit) {
3956546Sgblack@eecs.umich.edu                    if (overflow != mask(destBits - srcBits + 1)) {
3966801Sgblack@eecs.umich.edu                        if (signedOp())
3976742Svince@csl.cornell.edu                            picked = (ULL(1) << (destBits - 1));
3986546Sgblack@eecs.umich.edu                        else
3996546Sgblack@eecs.umich.edu                            picked = 0;
4006546Sgblack@eecs.umich.edu                    }
4016546Sgblack@eecs.umich.edu                } else {
4026546Sgblack@eecs.umich.edu                    if (overflow != 0) {
4036801Sgblack@eecs.umich.edu                        if (signedOp())
4046546Sgblack@eecs.umich.edu                            picked = mask(destBits - 1);
4056546Sgblack@eecs.umich.edu                        else
4066546Sgblack@eecs.umich.edu                            picked = mask(destBits);
4076546Sgblack@eecs.umich.edu                    }
4086546Sgblack@eecs.umich.edu                }
4096546Sgblack@eecs.umich.edu                result = insertBits(result,
4106546Sgblack@eecs.umich.edu                                    (i + 1) * destBits - 1,
4116546Sgblack@eecs.umich.edu                                    (i + 0) * destBits,
4126546Sgblack@eecs.umich.edu                                    picked);
4136546Sgblack@eecs.umich.edu            }
4146546Sgblack@eecs.umich.edu            for (;i < items; i++) {
4156546Sgblack@eecs.umich.edu                uint64_t picked =
4166546Sgblack@eecs.umich.edu                    bits(FpSrcReg2.uqw, (i - items + 1) * srcBits - 1,
4176546Sgblack@eecs.umich.edu                                        (i - items + 0) * srcBits);
4186546Sgblack@eecs.umich.edu                unsigned signBit = bits(picked, srcBits - 1);
4196546Sgblack@eecs.umich.edu                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
4206546Sgblack@eecs.umich.edu
4216546Sgblack@eecs.umich.edu                // Handle saturation.
4226546Sgblack@eecs.umich.edu                if (signBit) {
4236546Sgblack@eecs.umich.edu                    if (overflow != mask(destBits - srcBits + 1)) {
4246801Sgblack@eecs.umich.edu                        if (signedOp())
4256742Svince@csl.cornell.edu                            picked = (ULL(1) << (destBits - 1));
4266546Sgblack@eecs.umich.edu                        else
4276546Sgblack@eecs.umich.edu                            picked = 0;
4286546Sgblack@eecs.umich.edu                    }
4296546Sgblack@eecs.umich.edu                } else {
4306546Sgblack@eecs.umich.edu                    if (overflow != 0) {
4316801Sgblack@eecs.umich.edu                        if (signedOp())
4326546Sgblack@eecs.umich.edu                            picked = mask(destBits - 1);
4336546Sgblack@eecs.umich.edu                        else
4346546Sgblack@eecs.umich.edu                            picked = mask(destBits);
4356546Sgblack@eecs.umich.edu                    }
4366546Sgblack@eecs.umich.edu                }
4376546Sgblack@eecs.umich.edu                result = insertBits(result,
4386546Sgblack@eecs.umich.edu                                    (i + 1) * destBits - 1,
4396546Sgblack@eecs.umich.edu                                    (i + 0) * destBits,
4406546Sgblack@eecs.umich.edu                                    picked);
4416546Sgblack@eecs.umich.edu            }
4426546Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
4436546Sgblack@eecs.umich.edu        '''
4446546Sgblack@eecs.umich.edu
4456534Sgblack@eecs.umich.edu    class Mxor(MediaOp):
4466534Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4476534Sgblack@eecs.umich.edu            super(Mxor, self).__init__(dest, src1, src2, 1)
4486534Sgblack@eecs.umich.edu        code = '''
4496534Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw;
4506534Sgblack@eecs.umich.edu        '''
4516537Sgblack@eecs.umich.edu
4526537Sgblack@eecs.umich.edu    class Mor(MediaOp):
4536537Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4546537Sgblack@eecs.umich.edu            super(Mor, self).__init__(dest, src1, src2, 1)
4556537Sgblack@eecs.umich.edu        code = '''
4566537Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw | FpSrcReg2.uqw;
4576537Sgblack@eecs.umich.edu        '''
4586539Sgblack@eecs.umich.edu
4596539Sgblack@eecs.umich.edu    class Mand(MediaOp):
4606539Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4616539Sgblack@eecs.umich.edu            super(Mand, self).__init__(dest, src1, src2, 1)
4626539Sgblack@eecs.umich.edu        code = '''
4636539Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw & FpSrcReg2.uqw;
4646539Sgblack@eecs.umich.edu        '''
4656541Sgblack@eecs.umich.edu
4666541Sgblack@eecs.umich.edu    class Mandn(MediaOp):
4676541Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4686541Sgblack@eecs.umich.edu            super(Mandn, self).__init__(dest, src1, src2, 1)
4696541Sgblack@eecs.umich.edu        code = '''
4706541Sgblack@eecs.umich.edu            FpDestReg.uqw = ~FpSrcReg1.uqw & FpSrcReg2.uqw;
4716541Sgblack@eecs.umich.edu        '''
4726548Sgblack@eecs.umich.edu
4736548Sgblack@eecs.umich.edu    class Mminf(MediaOp):
4746548Sgblack@eecs.umich.edu        code = '''
4756548Sgblack@eecs.umich.edu            union floatInt
4766548Sgblack@eecs.umich.edu            {
4776548Sgblack@eecs.umich.edu                float f;
4786548Sgblack@eecs.umich.edu                uint32_t i;
4796548Sgblack@eecs.umich.edu            };
4806548Sgblack@eecs.umich.edu            union doubleInt
4816548Sgblack@eecs.umich.edu            {
4826548Sgblack@eecs.umich.edu                double d;
4836548Sgblack@eecs.umich.edu                uint64_t i;
4846548Sgblack@eecs.umich.edu            };
4856548Sgblack@eecs.umich.edu
4866548Sgblack@eecs.umich.edu            assert(srcSize == destSize);
4876548Sgblack@eecs.umich.edu            int size = srcSize;
4886548Sgblack@eecs.umich.edu            int sizeBits = size * 8;
4896548Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
4906799Sgblack@eecs.umich.edu            int items = numItems(size);
4916548Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
4926548Sgblack@eecs.umich.edu
4936548Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
4946548Sgblack@eecs.umich.edu                double arg1, arg2;
4956548Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
4966548Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
4976548Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
4986548Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
4996548Sgblack@eecs.umich.edu
5006548Sgblack@eecs.umich.edu                if (size == 4) {
5016548Sgblack@eecs.umich.edu                    floatInt fi;
5026548Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
5036548Sgblack@eecs.umich.edu                    arg1 = fi.f;
5046548Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
5056548Sgblack@eecs.umich.edu                    arg2 = fi.f;
5066548Sgblack@eecs.umich.edu                } else {
5076548Sgblack@eecs.umich.edu                    doubleInt di;
5086548Sgblack@eecs.umich.edu                    di.i = arg1Bits;
5096548Sgblack@eecs.umich.edu                    arg1 = di.d;
5106548Sgblack@eecs.umich.edu                    di.i = arg2Bits;
5116548Sgblack@eecs.umich.edu                    arg2 = di.d;
5126548Sgblack@eecs.umich.edu                }
5136548Sgblack@eecs.umich.edu
5146548Sgblack@eecs.umich.edu                if (arg1 < arg2) {
5156548Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
5166548Sgblack@eecs.umich.edu                } else {
5176548Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
5186548Sgblack@eecs.umich.edu                }
5196548Sgblack@eecs.umich.edu            }
5206548Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
5216548Sgblack@eecs.umich.edu        '''
5226550Sgblack@eecs.umich.edu
5236550Sgblack@eecs.umich.edu    class Mmaxf(MediaOp):
5246550Sgblack@eecs.umich.edu        code = '''
5256550Sgblack@eecs.umich.edu            union floatInt
5266550Sgblack@eecs.umich.edu            {
5276550Sgblack@eecs.umich.edu                float f;
5286550Sgblack@eecs.umich.edu                uint32_t i;
5296550Sgblack@eecs.umich.edu            };
5306550Sgblack@eecs.umich.edu            union doubleInt
5316550Sgblack@eecs.umich.edu            {
5326550Sgblack@eecs.umich.edu                double d;
5336550Sgblack@eecs.umich.edu                uint64_t i;
5346550Sgblack@eecs.umich.edu            };
5356550Sgblack@eecs.umich.edu
5366550Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5376550Sgblack@eecs.umich.edu            int size = srcSize;
5386550Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5396550Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
5406799Sgblack@eecs.umich.edu            int items = numItems(size);
5416550Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
5426550Sgblack@eecs.umich.edu
5436550Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
5446550Sgblack@eecs.umich.edu                double arg1, arg2;
5456550Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5466550Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5476550Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
5486550Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
5496550Sgblack@eecs.umich.edu
5506550Sgblack@eecs.umich.edu                if (size == 4) {
5516550Sgblack@eecs.umich.edu                    floatInt fi;
5526550Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
5536550Sgblack@eecs.umich.edu                    arg1 = fi.f;
5546550Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
5556550Sgblack@eecs.umich.edu                    arg2 = fi.f;
5566550Sgblack@eecs.umich.edu                } else {
5576550Sgblack@eecs.umich.edu                    doubleInt di;
5586550Sgblack@eecs.umich.edu                    di.i = arg1Bits;
5596550Sgblack@eecs.umich.edu                    arg1 = di.d;
5606550Sgblack@eecs.umich.edu                    di.i = arg2Bits;
5616550Sgblack@eecs.umich.edu                    arg2 = di.d;
5626550Sgblack@eecs.umich.edu                }
5636550Sgblack@eecs.umich.edu
5646550Sgblack@eecs.umich.edu                if (arg1 > arg2) {
5656550Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
5666550Sgblack@eecs.umich.edu                } else {
5676550Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
5686550Sgblack@eecs.umich.edu                }
5696550Sgblack@eecs.umich.edu            }
5706550Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
5716550Sgblack@eecs.umich.edu        '''
5726552Sgblack@eecs.umich.edu
5736572Sgblack@eecs.umich.edu    class Mmini(MediaOp):
5746572Sgblack@eecs.umich.edu        code = '''
5756572Sgblack@eecs.umich.edu
5766572Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5776572Sgblack@eecs.umich.edu            int size = srcSize;
5786572Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5796799Sgblack@eecs.umich.edu            int items = numItems(size);
5806572Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
5816572Sgblack@eecs.umich.edu
5826572Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
5836572Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5846572Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5856572Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
5866572Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
5876742Svince@csl.cornell.edu                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
5886572Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
5896572Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
5906742Svince@csl.cornell.edu                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
5916572Sgblack@eecs.umich.edu                uint64_t resBits;
5926572Sgblack@eecs.umich.edu
5936801Sgblack@eecs.umich.edu                if (signedOp()) {
5946572Sgblack@eecs.umich.edu                    if (arg1 < arg2) {
5956572Sgblack@eecs.umich.edu                        resBits = arg1Bits;
5966572Sgblack@eecs.umich.edu                    } else {
5976572Sgblack@eecs.umich.edu                        resBits = arg2Bits;
5986572Sgblack@eecs.umich.edu                    }
5996572Sgblack@eecs.umich.edu                } else {
6006572Sgblack@eecs.umich.edu                    if (arg1Bits < arg2Bits) {
6016572Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6026572Sgblack@eecs.umich.edu                    } else {
6036572Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6046572Sgblack@eecs.umich.edu                    }
6056572Sgblack@eecs.umich.edu                }
6066572Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
6076572Sgblack@eecs.umich.edu            }
6086572Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
6096572Sgblack@eecs.umich.edu        '''
6106572Sgblack@eecs.umich.edu
6116574Sgblack@eecs.umich.edu    class Mmaxi(MediaOp):
6126574Sgblack@eecs.umich.edu        code = '''
6136574Sgblack@eecs.umich.edu
6146574Sgblack@eecs.umich.edu            assert(srcSize == destSize);
6156574Sgblack@eecs.umich.edu            int size = srcSize;
6166574Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6176799Sgblack@eecs.umich.edu            int items = numItems(size);
6186574Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
6196574Sgblack@eecs.umich.edu
6206574Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6216574Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6226574Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6236574Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
6246574Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
6256742Svince@csl.cornell.edu                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
6266574Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
6276574Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
6286742Svince@csl.cornell.edu                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
6296574Sgblack@eecs.umich.edu                uint64_t resBits;
6306574Sgblack@eecs.umich.edu
6316801Sgblack@eecs.umich.edu                if (signedOp()) {
6326574Sgblack@eecs.umich.edu                    if (arg1 > arg2) {
6336574Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6346574Sgblack@eecs.umich.edu                    } else {
6356574Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6366574Sgblack@eecs.umich.edu                    }
6376574Sgblack@eecs.umich.edu                } else {
6386574Sgblack@eecs.umich.edu                    if (arg1Bits > arg2Bits) {
6396574Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6406574Sgblack@eecs.umich.edu                    } else {
6416574Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6426574Sgblack@eecs.umich.edu                    }
6436574Sgblack@eecs.umich.edu                }
6446574Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
6456574Sgblack@eecs.umich.edu            }
6466574Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
6476574Sgblack@eecs.umich.edu        '''
6486574Sgblack@eecs.umich.edu
6496552Sgblack@eecs.umich.edu    class Msqrt(MediaOp):
6506552Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
6516552Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
6526552Sgblack@eecs.umich.edu            super(Msqrt, self).__init__(dest, src,\
6536552Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
6546552Sgblack@eecs.umich.edu        code = '''
6556552Sgblack@eecs.umich.edu            union floatInt
6566552Sgblack@eecs.umich.edu            {
6576552Sgblack@eecs.umich.edu                float f;
6586552Sgblack@eecs.umich.edu                uint32_t i;
6596552Sgblack@eecs.umich.edu            };
6606552Sgblack@eecs.umich.edu            union doubleInt
6616552Sgblack@eecs.umich.edu            {
6626552Sgblack@eecs.umich.edu                double d;
6636552Sgblack@eecs.umich.edu                uint64_t i;
6646552Sgblack@eecs.umich.edu            };
6656552Sgblack@eecs.umich.edu
6666552Sgblack@eecs.umich.edu            assert(srcSize == destSize);
6676552Sgblack@eecs.umich.edu            int size = srcSize;
6686552Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6696552Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
6706799Sgblack@eecs.umich.edu            int items = numItems(size);
6716552Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
6726552Sgblack@eecs.umich.edu
6736552Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6746552Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6756552Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6766552Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
6776552Sgblack@eecs.umich.edu
6786552Sgblack@eecs.umich.edu                if (size == 4) {
6796552Sgblack@eecs.umich.edu                    floatInt fi;
6806552Sgblack@eecs.umich.edu                    fi.i = argBits;
6816552Sgblack@eecs.umich.edu                    fi.f = sqrt(fi.f);
6826552Sgblack@eecs.umich.edu                    argBits = fi.i;
6836552Sgblack@eecs.umich.edu                } else {
6846552Sgblack@eecs.umich.edu                    doubleInt di;
6856552Sgblack@eecs.umich.edu                    di.i = argBits;
6866552Sgblack@eecs.umich.edu                    di.d = sqrt(di.d);
6876552Sgblack@eecs.umich.edu                    argBits = di.i;
6886552Sgblack@eecs.umich.edu                }
6896552Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, argBits);
6906552Sgblack@eecs.umich.edu            }
6916552Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
6926552Sgblack@eecs.umich.edu        '''
6936554Sgblack@eecs.umich.edu
6946554Sgblack@eecs.umich.edu    class Maddf(MediaOp):
6956554Sgblack@eecs.umich.edu        code = '''
6966554Sgblack@eecs.umich.edu            union floatInt
6976554Sgblack@eecs.umich.edu            {
6986554Sgblack@eecs.umich.edu                float f;
6996554Sgblack@eecs.umich.edu                uint32_t i;
7006554Sgblack@eecs.umich.edu            };
7016554Sgblack@eecs.umich.edu            union doubleInt
7026554Sgblack@eecs.umich.edu            {
7036554Sgblack@eecs.umich.edu                double d;
7046554Sgblack@eecs.umich.edu                uint64_t i;
7056554Sgblack@eecs.umich.edu            };
7066554Sgblack@eecs.umich.edu
7076554Sgblack@eecs.umich.edu            assert(srcSize == destSize);
7086554Sgblack@eecs.umich.edu            int size = srcSize;
7096554Sgblack@eecs.umich.edu            int sizeBits = size * 8;
7106554Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
7116799Sgblack@eecs.umich.edu            int items = numItems(size);
7126554Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
7136554Sgblack@eecs.umich.edu
7146554Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
7156554Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
7166554Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
7176554Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
7186554Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
7196554Sgblack@eecs.umich.edu                uint64_t resBits;
7206554Sgblack@eecs.umich.edu
7216554Sgblack@eecs.umich.edu                if (size == 4) {
7226554Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
7236554Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7246554Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7256554Sgblack@eecs.umich.edu                    res.f = arg1.f + arg2.f;
7266554Sgblack@eecs.umich.edu                    resBits = res.i;
7276554Sgblack@eecs.umich.edu                } else {
7286554Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
7296554Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7306554Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7316554Sgblack@eecs.umich.edu                    res.d = arg1.d + arg2.d;
7326554Sgblack@eecs.umich.edu                    resBits = res.i;
7336554Sgblack@eecs.umich.edu                }
7346554Sgblack@eecs.umich.edu
7356554Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
7366554Sgblack@eecs.umich.edu            }
7376554Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
7386554Sgblack@eecs.umich.edu        '''
7396556Sgblack@eecs.umich.edu
7406556Sgblack@eecs.umich.edu    class Msubf(MediaOp):
7416556Sgblack@eecs.umich.edu        code = '''
7426556Sgblack@eecs.umich.edu            union floatInt
7436556Sgblack@eecs.umich.edu            {
7446556Sgblack@eecs.umich.edu                float f;
7456556Sgblack@eecs.umich.edu                uint32_t i;
7466556Sgblack@eecs.umich.edu            };
7476556Sgblack@eecs.umich.edu            union doubleInt
7486556Sgblack@eecs.umich.edu            {
7496556Sgblack@eecs.umich.edu                double d;
7506556Sgblack@eecs.umich.edu                uint64_t i;
7516556Sgblack@eecs.umich.edu            };
7526556Sgblack@eecs.umich.edu
7536556Sgblack@eecs.umich.edu            assert(srcSize == destSize);
7546556Sgblack@eecs.umich.edu            int size = srcSize;
7556556Sgblack@eecs.umich.edu            int sizeBits = size * 8;
7566556Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
7576799Sgblack@eecs.umich.edu            int items = numItems(size);
7586556Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
7596556Sgblack@eecs.umich.edu
7606556Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
7616556Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
7626556Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
7636556Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
7646556Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
7656556Sgblack@eecs.umich.edu                uint64_t resBits;
7666556Sgblack@eecs.umich.edu
7676556Sgblack@eecs.umich.edu                if (size == 4) {
7686556Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
7696556Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7706556Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7716556Sgblack@eecs.umich.edu                    res.f = arg1.f - arg2.f;
7726556Sgblack@eecs.umich.edu                    resBits = res.i;
7736556Sgblack@eecs.umich.edu                } else {
7746556Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
7756556Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7766556Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7776556Sgblack@eecs.umich.edu                    res.d = arg1.d - arg2.d;
7786556Sgblack@eecs.umich.edu                    resBits = res.i;
7796556Sgblack@eecs.umich.edu                }
7806556Sgblack@eecs.umich.edu
7816556Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
7826556Sgblack@eecs.umich.edu            }
7836556Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
7846556Sgblack@eecs.umich.edu        '''
7856558Sgblack@eecs.umich.edu
7866558Sgblack@eecs.umich.edu    class Mmulf(MediaOp):
7876558Sgblack@eecs.umich.edu        code = '''
7886558Sgblack@eecs.umich.edu            union floatInt
7896558Sgblack@eecs.umich.edu            {
7906558Sgblack@eecs.umich.edu                float f;
7916558Sgblack@eecs.umich.edu                uint32_t i;
7926558Sgblack@eecs.umich.edu            };
7936558Sgblack@eecs.umich.edu            union doubleInt
7946558Sgblack@eecs.umich.edu            {
7956558Sgblack@eecs.umich.edu                double d;
7966558Sgblack@eecs.umich.edu                uint64_t i;
7976558Sgblack@eecs.umich.edu            };
7986558Sgblack@eecs.umich.edu
7996558Sgblack@eecs.umich.edu            assert(srcSize == destSize);
8006558Sgblack@eecs.umich.edu            int size = srcSize;
8016558Sgblack@eecs.umich.edu            int sizeBits = size * 8;
8026558Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
8036799Sgblack@eecs.umich.edu            int items = numItems(size);
8046558Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
8056558Sgblack@eecs.umich.edu
8066558Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8076558Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
8086558Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8096558Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
8106558Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
8116558Sgblack@eecs.umich.edu                uint64_t resBits;
8126558Sgblack@eecs.umich.edu
8136558Sgblack@eecs.umich.edu                if (size == 4) {
8146558Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
8156558Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8166558Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8176558Sgblack@eecs.umich.edu                    res.f = arg1.f * arg2.f;
8186558Sgblack@eecs.umich.edu                    resBits = res.i;
8196558Sgblack@eecs.umich.edu                } else {
8206558Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
8216558Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8226558Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8236558Sgblack@eecs.umich.edu                    res.d = arg1.d * arg2.d;
8246558Sgblack@eecs.umich.edu                    resBits = res.i;
8256558Sgblack@eecs.umich.edu                }
8266558Sgblack@eecs.umich.edu
8276558Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
8286558Sgblack@eecs.umich.edu            }
8296558Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
8306558Sgblack@eecs.umich.edu        '''
8316560Sgblack@eecs.umich.edu
8326560Sgblack@eecs.umich.edu    class Mdivf(MediaOp):
8336560Sgblack@eecs.umich.edu        code = '''
8346560Sgblack@eecs.umich.edu            union floatInt
8356560Sgblack@eecs.umich.edu            {
8366560Sgblack@eecs.umich.edu                float f;
8376560Sgblack@eecs.umich.edu                uint32_t i;
8386560Sgblack@eecs.umich.edu            };
8396560Sgblack@eecs.umich.edu            union doubleInt
8406560Sgblack@eecs.umich.edu            {
8416560Sgblack@eecs.umich.edu                double d;
8426560Sgblack@eecs.umich.edu                uint64_t i;
8436560Sgblack@eecs.umich.edu            };
8446560Sgblack@eecs.umich.edu
8456560Sgblack@eecs.umich.edu            assert(srcSize == destSize);
8466560Sgblack@eecs.umich.edu            int size = srcSize;
8476560Sgblack@eecs.umich.edu            int sizeBits = size * 8;
8486560Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
8496799Sgblack@eecs.umich.edu            int items = numItems(size);
8506560Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
8516560Sgblack@eecs.umich.edu
8526560Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8536560Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
8546560Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8556560Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
8566560Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
8576560Sgblack@eecs.umich.edu                uint64_t resBits;
8586560Sgblack@eecs.umich.edu
8596560Sgblack@eecs.umich.edu                if (size == 4) {
8606560Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
8616560Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8626560Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8636560Sgblack@eecs.umich.edu                    res.f = arg1.f / arg2.f;
8646560Sgblack@eecs.umich.edu                    resBits = res.i;
8656560Sgblack@eecs.umich.edu                } else {
8666560Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
8676560Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8686560Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8696560Sgblack@eecs.umich.edu                    res.d = arg1.d / arg2.d;
8706560Sgblack@eecs.umich.edu                    resBits = res.i;
8716560Sgblack@eecs.umich.edu                }
8726560Sgblack@eecs.umich.edu
8736560Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
8746560Sgblack@eecs.umich.edu            }
8756560Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
8766560Sgblack@eecs.umich.edu        '''
8776562Sgblack@eecs.umich.edu
8786570Sgblack@eecs.umich.edu    class Maddi(MediaOp):
8796570Sgblack@eecs.umich.edu        code = '''
8806570Sgblack@eecs.umich.edu            assert(srcSize == destSize);
8816570Sgblack@eecs.umich.edu            int size = srcSize;
8826570Sgblack@eecs.umich.edu            int sizeBits = size * 8;
8836799Sgblack@eecs.umich.edu            int items = numItems(size);
8846570Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
8856570Sgblack@eecs.umich.edu
8866570Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8876570Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
8886570Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8896570Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
8906570Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
8916570Sgblack@eecs.umich.edu                uint64_t resBits = arg1Bits + arg2Bits;
8926570Sgblack@eecs.umich.edu                
8936570Sgblack@eecs.umich.edu                if (ext & 0x2) {
8946801Sgblack@eecs.umich.edu                    if (signedOp()) {
8956801Sgblack@eecs.umich.edu                        int arg1Sign = bits(arg1Bits, sizeBits - 1);
8966801Sgblack@eecs.umich.edu                        int arg2Sign = bits(arg2Bits, sizeBits - 1);
8976801Sgblack@eecs.umich.edu                        int resSign = bits(resBits, sizeBits - 1);
8986801Sgblack@eecs.umich.edu                        if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
8996801Sgblack@eecs.umich.edu                            if (resSign == 0)
9006801Sgblack@eecs.umich.edu                                resBits = (ULL(1) << (sizeBits - 1));
9016801Sgblack@eecs.umich.edu                            else
9026801Sgblack@eecs.umich.edu                                resBits = mask(sizeBits - 1);
9036801Sgblack@eecs.umich.edu                        }
9046801Sgblack@eecs.umich.edu                    } else {
9056801Sgblack@eecs.umich.edu                        if (findCarry(sizeBits, resBits, arg1Bits, arg2Bits))
9066801Sgblack@eecs.umich.edu                            resBits = mask(sizeBits);
9076570Sgblack@eecs.umich.edu                    }
9086570Sgblack@eecs.umich.edu                }
9096570Sgblack@eecs.umich.edu
9106570Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
9116570Sgblack@eecs.umich.edu            }
9126570Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
9136570Sgblack@eecs.umich.edu        '''
9146570Sgblack@eecs.umich.edu
9156579Sgblack@eecs.umich.edu    class Msubi(MediaOp):
9166579Sgblack@eecs.umich.edu        code = '''
9176579Sgblack@eecs.umich.edu            assert(srcSize == destSize);
9186579Sgblack@eecs.umich.edu            int size = srcSize;
9196579Sgblack@eecs.umich.edu            int sizeBits = size * 8;
9206799Sgblack@eecs.umich.edu            int items = numItems(size);
9216579Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
9226579Sgblack@eecs.umich.edu
9236579Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9246579Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
9256579Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
9266579Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
9276579Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
9286579Sgblack@eecs.umich.edu                uint64_t resBits = arg1Bits - arg2Bits;
9296579Sgblack@eecs.umich.edu                
9306579Sgblack@eecs.umich.edu                if (ext & 0x2) {
9316801Sgblack@eecs.umich.edu                    if (signedOp()) {
9326801Sgblack@eecs.umich.edu                        int arg1Sign = bits(arg1Bits, sizeBits - 1);
9336801Sgblack@eecs.umich.edu                        int arg2Sign = !bits(arg2Bits, sizeBits - 1);
9346801Sgblack@eecs.umich.edu                        int resSign = bits(resBits, sizeBits - 1);
9356801Sgblack@eecs.umich.edu                        if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
9366801Sgblack@eecs.umich.edu                            if (resSign == 0)
9376801Sgblack@eecs.umich.edu                                resBits = (ULL(1) << (sizeBits - 1));
9386801Sgblack@eecs.umich.edu                            else
9396801Sgblack@eecs.umich.edu                                resBits = mask(sizeBits - 1);
9406801Sgblack@eecs.umich.edu                        }
9416801Sgblack@eecs.umich.edu                    } else {
9426801Sgblack@eecs.umich.edu                        if (arg2Bits > arg1Bits) {
9436801Sgblack@eecs.umich.edu                            resBits = 0;
9446801Sgblack@eecs.umich.edu                        } else if (!findCarry(sizeBits, resBits,
9456801Sgblack@eecs.umich.edu                                             arg1Bits, ~arg2Bits)) {
9466801Sgblack@eecs.umich.edu                            resBits = mask(sizeBits);
9476801Sgblack@eecs.umich.edu                        }
9486579Sgblack@eecs.umich.edu                    }
9496579Sgblack@eecs.umich.edu                }
9506579Sgblack@eecs.umich.edu
9516579Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
9526579Sgblack@eecs.umich.edu            }
9536579Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
9546579Sgblack@eecs.umich.edu        '''
9556579Sgblack@eecs.umich.edu
9566577Sgblack@eecs.umich.edu    class Mmuli(MediaOp):
9576577Sgblack@eecs.umich.edu        code = '''
9586577Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
9596577Sgblack@eecs.umich.edu            int destBits = destSize * 8;
9606577Sgblack@eecs.umich.edu            assert(destBits <= 64);
9616577Sgblack@eecs.umich.edu            assert(destSize >= srcSize);
9626799Sgblack@eecs.umich.edu            int items = numItems(destSize);
9636577Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
9646577Sgblack@eecs.umich.edu
9656577Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9666585Sgblack@eecs.umich.edu                int offset = 0;
9676585Sgblack@eecs.umich.edu                if (ext & 16) {
9686585Sgblack@eecs.umich.edu                    if (ext & 32)
9696585Sgblack@eecs.umich.edu                        offset = i * (destBits - srcBits);
9706585Sgblack@eecs.umich.edu                    else
9716585Sgblack@eecs.umich.edu                        offset = i * (destBits - srcBits) + srcBits;
9726585Sgblack@eecs.umich.edu                }
9736585Sgblack@eecs.umich.edu                int srcHiIndex = (i + 1) * srcBits - 1 + offset;
9746585Sgblack@eecs.umich.edu                int srcLoIndex = (i + 0) * srcBits + offset;
9756577Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
9766577Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, srcHiIndex, srcLoIndex);
9776577Sgblack@eecs.umich.edu                uint64_t resBits;
9786577Sgblack@eecs.umich.edu
9796801Sgblack@eecs.umich.edu                if (signedOp()) {
9806577Sgblack@eecs.umich.edu                    int64_t arg1 = arg1Bits |
9816742Svince@csl.cornell.edu                        (0 - (arg1Bits & (ULL(1) << (srcBits - 1))));
9826577Sgblack@eecs.umich.edu                    int64_t arg2 = arg2Bits |
9836742Svince@csl.cornell.edu                        (0 - (arg2Bits & (ULL(1) << (srcBits - 1))));
9846577Sgblack@eecs.umich.edu                    resBits = (uint64_t)(arg1 * arg2);
9856577Sgblack@eecs.umich.edu                } else {
9866577Sgblack@eecs.umich.edu                    resBits = arg1Bits * arg2Bits;
9876577Sgblack@eecs.umich.edu                }
9886577Sgblack@eecs.umich.edu
9896577Sgblack@eecs.umich.edu                if (ext & 0x4)
9906742Svince@csl.cornell.edu                    resBits += (ULL(1) << (destBits - 1));
9916577Sgblack@eecs.umich.edu                
9926800Sgblack@eecs.umich.edu                if (multHi())
9936577Sgblack@eecs.umich.edu                    resBits >>= destBits;
9946577Sgblack@eecs.umich.edu
9956577Sgblack@eecs.umich.edu                int destHiIndex = (i + 1) * destBits - 1;
9966577Sgblack@eecs.umich.edu                int destLoIndex = (i + 0) * destBits;
9976577Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, resBits);
9986577Sgblack@eecs.umich.edu            }
9996577Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
10006577Sgblack@eecs.umich.edu        '''
10016577Sgblack@eecs.umich.edu
10026587Sgblack@eecs.umich.edu    class Mavg(MediaOp):
10036587Sgblack@eecs.umich.edu        code = '''
10046587Sgblack@eecs.umich.edu            assert(srcSize == destSize);
10056587Sgblack@eecs.umich.edu            int size = srcSize;
10066587Sgblack@eecs.umich.edu            int sizeBits = size * 8;
10076799Sgblack@eecs.umich.edu            int items = numItems(size);
10086587Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
10096587Sgblack@eecs.umich.edu
10106587Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10116587Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
10126587Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
10136587Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
10146587Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
10156587Sgblack@eecs.umich.edu                uint64_t resBits = (arg1Bits + arg2Bits + 1) / 2;
10166587Sgblack@eecs.umich.edu                
10176587Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
10186587Sgblack@eecs.umich.edu            }
10196587Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
10206587Sgblack@eecs.umich.edu        '''
10216587Sgblack@eecs.umich.edu
10226581Sgblack@eecs.umich.edu    class Msad(MediaOp):
10236581Sgblack@eecs.umich.edu        code = '''
10246581Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
10256581Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / srcSize;
10266581Sgblack@eecs.umich.edu
10276581Sgblack@eecs.umich.edu            uint64_t sum = 0;
10286581Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10296581Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * srcBits - 1;
10306581Sgblack@eecs.umich.edu                int loIndex = (i + 0) * srcBits;
10316581Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
10326581Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
10336581Sgblack@eecs.umich.edu                int64_t resBits = arg1Bits - arg2Bits;
10346581Sgblack@eecs.umich.edu                if (resBits < 0)
10356581Sgblack@eecs.umich.edu                    resBits = -resBits;
10366581Sgblack@eecs.umich.edu                sum += resBits;
10376581Sgblack@eecs.umich.edu            }
10386581Sgblack@eecs.umich.edu            FpDestReg.uqw = sum & mask(destSize * 8);
10396581Sgblack@eecs.umich.edu        '''
10406581Sgblack@eecs.umich.edu
10416583Sgblack@eecs.umich.edu    class Msrl(MediaOp):
10426583Sgblack@eecs.umich.edu        code = '''
10436583Sgblack@eecs.umich.edu
10446583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
10456583Sgblack@eecs.umich.edu            int size = srcSize;
10466583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
10476799Sgblack@eecs.umich.edu            int items = numItems(size);
10486583Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2.uqw;
10496583Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
10506583Sgblack@eecs.umich.edu
10516583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10526583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
10536583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
10546583Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
10556583Sgblack@eecs.umich.edu                uint64_t resBits;
10566583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
10576583Sgblack@eecs.umich.edu                    resBits = 0;
10586583Sgblack@eecs.umich.edu                } else {
10596583Sgblack@eecs.umich.edu                    resBits = (arg1Bits >> shiftAmt) &
10606583Sgblack@eecs.umich.edu                        mask(sizeBits - shiftAmt);
10616583Sgblack@eecs.umich.edu                }
10626583Sgblack@eecs.umich.edu
10636583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
10646583Sgblack@eecs.umich.edu            }
10656583Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
10666583Sgblack@eecs.umich.edu        '''
10676583Sgblack@eecs.umich.edu
10686583Sgblack@eecs.umich.edu    class Msra(MediaOp):
10696583Sgblack@eecs.umich.edu        code = '''
10706583Sgblack@eecs.umich.edu
10716583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
10726583Sgblack@eecs.umich.edu            int size = srcSize;
10736583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
10746799Sgblack@eecs.umich.edu            int items = numItems(size);
10756583Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2.uqw;
10766583Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
10776583Sgblack@eecs.umich.edu
10786583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10796583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
10806583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
10816583Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
10826583Sgblack@eecs.umich.edu                uint64_t resBits;
10836583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
10846583Sgblack@eecs.umich.edu                    if (bits(arg1Bits, sizeBits - 1))
10856583Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
10866583Sgblack@eecs.umich.edu                    else
10876583Sgblack@eecs.umich.edu                        resBits = 0;
10886583Sgblack@eecs.umich.edu                } else {
10896583Sgblack@eecs.umich.edu                    resBits = (arg1Bits >> shiftAmt);
10906583Sgblack@eecs.umich.edu                    resBits = resBits |
10916742Svince@csl.cornell.edu                        (0 - (resBits & (ULL(1) << (sizeBits - 1 - shiftAmt))));
10926583Sgblack@eecs.umich.edu                }
10936583Sgblack@eecs.umich.edu
10946583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
10956583Sgblack@eecs.umich.edu            }
10966583Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
10976583Sgblack@eecs.umich.edu        '''
10986583Sgblack@eecs.umich.edu
10996583Sgblack@eecs.umich.edu    class Msll(MediaOp):
11006583Sgblack@eecs.umich.edu        code = '''
11016583Sgblack@eecs.umich.edu
11026583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
11036583Sgblack@eecs.umich.edu            int size = srcSize;
11046583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
11056799Sgblack@eecs.umich.edu            int items = numItems(size);
11066583Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2.uqw;
11076583Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
11086583Sgblack@eecs.umich.edu
11096583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
11106583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
11116583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
11126583Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
11136583Sgblack@eecs.umich.edu                uint64_t resBits;
11146583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
11156583Sgblack@eecs.umich.edu                    resBits = 0;
11166583Sgblack@eecs.umich.edu                } else {
11176583Sgblack@eecs.umich.edu                    resBits = (arg1Bits << shiftAmt);
11186583Sgblack@eecs.umich.edu                }
11196583Sgblack@eecs.umich.edu
11206583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
11216583Sgblack@eecs.umich.edu            }
11226583Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
11236583Sgblack@eecs.umich.edu        '''
11246583Sgblack@eecs.umich.edu
11256605Sgblack@eecs.umich.edu    class Cvtf2i(MediaOp):
11266605Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
11276605Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
11286605Sgblack@eecs.umich.edu            super(Cvtf2i, self).__init__(dest, src,\
11296605Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
11306605Sgblack@eecs.umich.edu        code = '''
11316605Sgblack@eecs.umich.edu            union floatInt
11326605Sgblack@eecs.umich.edu            {
11336605Sgblack@eecs.umich.edu                float f;
11346605Sgblack@eecs.umich.edu                uint32_t i;
11356605Sgblack@eecs.umich.edu            };
11366605Sgblack@eecs.umich.edu            union doubleInt
11376605Sgblack@eecs.umich.edu            {
11386605Sgblack@eecs.umich.edu                double d;
11396605Sgblack@eecs.umich.edu                uint64_t i;
11406605Sgblack@eecs.umich.edu            };
11416605Sgblack@eecs.umich.edu
11426605Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
11436605Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
11446605Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
11456605Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
11466605Sgblack@eecs.umich.edu            int items;
11476605Sgblack@eecs.umich.edu            int srcStart = 0;
11486605Sgblack@eecs.umich.edu            int destStart = 0;
11496605Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
11506799Sgblack@eecs.umich.edu                items = numItems(srcSize);
11516605Sgblack@eecs.umich.edu                if (ext & 0x2)
11526605Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
11536605Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
11546799Sgblack@eecs.umich.edu                items = numItems(destSize);
11556605Sgblack@eecs.umich.edu                if (ext & 0x2)
11566605Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
11576605Sgblack@eecs.umich.edu            } else {
11586799Sgblack@eecs.umich.edu                items = numItems(destSize);
11596605Sgblack@eecs.umich.edu            }
11606605Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
11616605Sgblack@eecs.umich.edu
11626605Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
11636605Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
11646605Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
11656605Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
11666605Sgblack@eecs.umich.edu                double arg;
11676605Sgblack@eecs.umich.edu
11686605Sgblack@eecs.umich.edu                if (srcSize == 4) {
11696605Sgblack@eecs.umich.edu                    floatInt fi;
11706605Sgblack@eecs.umich.edu                    fi.i = argBits;
11716605Sgblack@eecs.umich.edu                    arg = fi.f;
11726605Sgblack@eecs.umich.edu                } else {
11736605Sgblack@eecs.umich.edu                    doubleInt di;
11746605Sgblack@eecs.umich.edu                    di.i = argBits;
11756605Sgblack@eecs.umich.edu                    arg = di.d;
11766605Sgblack@eecs.umich.edu                }
11776605Sgblack@eecs.umich.edu
11786605Sgblack@eecs.umich.edu                if (ext & 0x4) {
11796605Sgblack@eecs.umich.edu                    if (arg >= 0)
11806605Sgblack@eecs.umich.edu                        arg += 0.5;
11816605Sgblack@eecs.umich.edu                    else
11826605Sgblack@eecs.umich.edu                        arg -= 0.5;
11836605Sgblack@eecs.umich.edu                }
11846605Sgblack@eecs.umich.edu
11856605Sgblack@eecs.umich.edu                if (destSize == 4) {
11866732Svince@csl.cornell.edu                    argBits = (uint32_t)arg;
11876605Sgblack@eecs.umich.edu                } else {
11886605Sgblack@eecs.umich.edu                    argBits = (uint64_t)arg;
11896605Sgblack@eecs.umich.edu                }
11906605Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
11916605Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
11926605Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
11936605Sgblack@eecs.umich.edu            }
11946605Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
11956605Sgblack@eecs.umich.edu        '''
11966605Sgblack@eecs.umich.edu
11976562Sgblack@eecs.umich.edu    class Cvti2f(MediaOp):
11986562Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
11996562Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
12006562Sgblack@eecs.umich.edu            super(Cvti2f, self).__init__(dest, src,\
12016562Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
12026562Sgblack@eecs.umich.edu        code = '''
12036562Sgblack@eecs.umich.edu            union floatInt
12046562Sgblack@eecs.umich.edu            {
12056562Sgblack@eecs.umich.edu                float f;
12066562Sgblack@eecs.umich.edu                uint32_t i;
12076562Sgblack@eecs.umich.edu            };
12086562Sgblack@eecs.umich.edu            union doubleInt
12096562Sgblack@eecs.umich.edu            {
12106562Sgblack@eecs.umich.edu                double d;
12116562Sgblack@eecs.umich.edu                uint64_t i;
12126562Sgblack@eecs.umich.edu            };
12136562Sgblack@eecs.umich.edu
12146562Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
12156562Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
12166562Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
12176562Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
12186562Sgblack@eecs.umich.edu            int items;
12196562Sgblack@eecs.umich.edu            int srcStart = 0;
12206562Sgblack@eecs.umich.edu            int destStart = 0;
12216562Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
12226799Sgblack@eecs.umich.edu                items = numItems(srcSize);
12236562Sgblack@eecs.umich.edu                if (ext & 0x2)
12246562Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
12256562Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
12266799Sgblack@eecs.umich.edu                items = numItems(destSize);
12276562Sgblack@eecs.umich.edu                if (ext & 0x2)
12286562Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
12296562Sgblack@eecs.umich.edu            } else {
12306799Sgblack@eecs.umich.edu                items = numItems(destSize);
12316562Sgblack@eecs.umich.edu            }
12326562Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
12336562Sgblack@eecs.umich.edu
12346562Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
12356562Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
12366562Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
12376562Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
12386742Svince@csl.cornell.edu
12397081Sgblack@eecs.umich.edu                int64_t sArg = argBits |
12407081Sgblack@eecs.umich.edu                    (0 - (argBits & (ULL(1) << (srcSizeBits - 1))));
12416562Sgblack@eecs.umich.edu                double arg = sArg;
12426562Sgblack@eecs.umich.edu
12436562Sgblack@eecs.umich.edu                if (destSize == 4) {
12446562Sgblack@eecs.umich.edu                    floatInt fi;
12456562Sgblack@eecs.umich.edu                    fi.f = arg;
12466562Sgblack@eecs.umich.edu                    argBits = fi.i;
12476562Sgblack@eecs.umich.edu                } else {
12486562Sgblack@eecs.umich.edu                    doubleInt di;
12496562Sgblack@eecs.umich.edu                    di.d = arg;
12506562Sgblack@eecs.umich.edu                    argBits = di.i;
12516562Sgblack@eecs.umich.edu                }
12526562Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
12536562Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
12546562Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
12556562Sgblack@eecs.umich.edu            }
12566562Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
12576562Sgblack@eecs.umich.edu        '''
12586566Sgblack@eecs.umich.edu
12596568Sgblack@eecs.umich.edu    class Cvtf2f(MediaOp):
12606568Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
12616568Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
12626568Sgblack@eecs.umich.edu            super(Cvtf2f, self).__init__(dest, src,\
12636568Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
12646568Sgblack@eecs.umich.edu        code = '''
12656568Sgblack@eecs.umich.edu            union floatInt
12666568Sgblack@eecs.umich.edu            {
12676568Sgblack@eecs.umich.edu                float f;
12686568Sgblack@eecs.umich.edu                uint32_t i;
12696568Sgblack@eecs.umich.edu            };
12706568Sgblack@eecs.umich.edu            union doubleInt
12716568Sgblack@eecs.umich.edu            {
12726568Sgblack@eecs.umich.edu                double d;
12736568Sgblack@eecs.umich.edu                uint64_t i;
12746568Sgblack@eecs.umich.edu            };
12756568Sgblack@eecs.umich.edu
12766568Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
12776568Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
12786568Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
12796568Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
12806568Sgblack@eecs.umich.edu            int items;
12816568Sgblack@eecs.umich.edu            int srcStart = 0;
12826568Sgblack@eecs.umich.edu            int destStart = 0;
12836568Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
12846799Sgblack@eecs.umich.edu                items = numItems(srcSize);
12856568Sgblack@eecs.umich.edu                if (ext & 0x2)
12866568Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
12876568Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
12886799Sgblack@eecs.umich.edu                items = numItems(destSize);
12896568Sgblack@eecs.umich.edu                if (ext & 0x2)
12906568Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
12916568Sgblack@eecs.umich.edu            } else {
12926799Sgblack@eecs.umich.edu                items = numItems(destSize);
12936568Sgblack@eecs.umich.edu            }
12946568Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
12956568Sgblack@eecs.umich.edu
12966568Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
12976568Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
12986568Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
12996568Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
13006568Sgblack@eecs.umich.edu                double arg;
13016568Sgblack@eecs.umich.edu
13026568Sgblack@eecs.umich.edu                if (srcSize == 4) {
13036568Sgblack@eecs.umich.edu                    floatInt fi;
13046568Sgblack@eecs.umich.edu                    fi.i = argBits;
13056568Sgblack@eecs.umich.edu                    arg = fi.f;
13066568Sgblack@eecs.umich.edu                } else {
13076568Sgblack@eecs.umich.edu                    doubleInt di;
13086568Sgblack@eecs.umich.edu                    di.i = argBits;
13096568Sgblack@eecs.umich.edu                    arg = di.d;
13106568Sgblack@eecs.umich.edu                }
13116568Sgblack@eecs.umich.edu                if (destSize == 4) {
13126568Sgblack@eecs.umich.edu                    floatInt fi;
13136568Sgblack@eecs.umich.edu                    fi.f = arg;
13146568Sgblack@eecs.umich.edu                    argBits = fi.i;
13156568Sgblack@eecs.umich.edu                } else {
13166568Sgblack@eecs.umich.edu                    doubleInt di;
13176568Sgblack@eecs.umich.edu                    di.d = arg;
13186568Sgblack@eecs.umich.edu                    argBits = di.i;
13196568Sgblack@eecs.umich.edu                }
13206568Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
13216568Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
13226568Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
13236568Sgblack@eecs.umich.edu            }
13246568Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
13256568Sgblack@eecs.umich.edu        '''
13266568Sgblack@eecs.umich.edu
13276566Sgblack@eecs.umich.edu    class Mcmpi2r(MediaOp):
13286566Sgblack@eecs.umich.edu        code = '''
13296566Sgblack@eecs.umich.edu            union floatInt
13306566Sgblack@eecs.umich.edu            {
13316566Sgblack@eecs.umich.edu                float f;
13326566Sgblack@eecs.umich.edu                uint32_t i;
13336566Sgblack@eecs.umich.edu            };
13346566Sgblack@eecs.umich.edu            union doubleInt
13356566Sgblack@eecs.umich.edu            {
13366566Sgblack@eecs.umich.edu                double d;
13376566Sgblack@eecs.umich.edu                uint64_t i;
13386566Sgblack@eecs.umich.edu            };
13396566Sgblack@eecs.umich.edu
13406566Sgblack@eecs.umich.edu            assert(srcSize == destSize);
13416566Sgblack@eecs.umich.edu            int size = srcSize;
13426566Sgblack@eecs.umich.edu            int sizeBits = size * 8;
13436799Sgblack@eecs.umich.edu            int items = numItems(size);
13446566Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
13456566Sgblack@eecs.umich.edu
13466566Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
13476566Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
13486566Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
13496566Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
13506566Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
13516742Svince@csl.cornell.edu                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
13526566Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
13536566Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
13546742Svince@csl.cornell.edu                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
13556566Sgblack@eecs.umich.edu
13566566Sgblack@eecs.umich.edu                uint64_t resBits = 0;
13576622Snate@binkert.org                if (((ext & 0x2) == 0 && arg1 == arg2) ||
13586622Snate@binkert.org                    ((ext & 0x2) == 0x2 && arg1 > arg2))
13596566Sgblack@eecs.umich.edu                    resBits = mask(sizeBits);
13606566Sgblack@eecs.umich.edu
13616566Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
13626566Sgblack@eecs.umich.edu            }
13636566Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
13646566Sgblack@eecs.umich.edu        '''
13656601Sgblack@eecs.umich.edu
13666603Sgblack@eecs.umich.edu    class Mcmpf2r(MediaOp):
13676603Sgblack@eecs.umich.edu        code = '''
13686603Sgblack@eecs.umich.edu            union floatInt
13696603Sgblack@eecs.umich.edu            {
13706603Sgblack@eecs.umich.edu                float f;
13716603Sgblack@eecs.umich.edu                uint32_t i;
13726603Sgblack@eecs.umich.edu            };
13736603Sgblack@eecs.umich.edu            union doubleInt
13746603Sgblack@eecs.umich.edu            {
13756603Sgblack@eecs.umich.edu                double d;
13766603Sgblack@eecs.umich.edu                uint64_t i;
13776603Sgblack@eecs.umich.edu            };
13786603Sgblack@eecs.umich.edu
13796603Sgblack@eecs.umich.edu            assert(srcSize == destSize);
13806603Sgblack@eecs.umich.edu            int size = srcSize;
13816603Sgblack@eecs.umich.edu            int sizeBits = size * 8;
13826799Sgblack@eecs.umich.edu            int items = numItems(size);
13836603Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
13846603Sgblack@eecs.umich.edu
13856603Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
13866603Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
13876603Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
13886603Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
13896603Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
13906603Sgblack@eecs.umich.edu                double arg1, arg2;
13916603Sgblack@eecs.umich.edu
13926603Sgblack@eecs.umich.edu                if (size == 4) {
13936603Sgblack@eecs.umich.edu                    floatInt fi;
13946603Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
13956603Sgblack@eecs.umich.edu                    arg1 = fi.f;
13966603Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
13976603Sgblack@eecs.umich.edu                    arg2 = fi.f;
13986603Sgblack@eecs.umich.edu                } else {
13996603Sgblack@eecs.umich.edu                    doubleInt di;
14006603Sgblack@eecs.umich.edu                    di.i = arg1Bits;
14016603Sgblack@eecs.umich.edu                    arg1 = di.d;
14026603Sgblack@eecs.umich.edu                    di.i = arg2Bits;
14036603Sgblack@eecs.umich.edu                    arg2 = di.d;
14046603Sgblack@eecs.umich.edu                }
14056603Sgblack@eecs.umich.edu
14066603Sgblack@eecs.umich.edu                uint64_t resBits = 0;
14076603Sgblack@eecs.umich.edu                bool nanop = isnan(arg1) || isnan(arg2);
14086603Sgblack@eecs.umich.edu                switch (ext & mask(3)) {
14096603Sgblack@eecs.umich.edu                  case 0:
14106603Sgblack@eecs.umich.edu                    if (arg1 == arg2 && !nanop)
14116603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14126603Sgblack@eecs.umich.edu                    break;
14136603Sgblack@eecs.umich.edu                  case 1:
14146603Sgblack@eecs.umich.edu                    if (arg1 < arg2 && !nanop)
14156603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14166603Sgblack@eecs.umich.edu                    break;
14176603Sgblack@eecs.umich.edu                  case 2:
14186603Sgblack@eecs.umich.edu                    if (arg1 <= arg2 && !nanop)
14196603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14206603Sgblack@eecs.umich.edu                    break;
14216603Sgblack@eecs.umich.edu                  case 3:
14226603Sgblack@eecs.umich.edu                    if (nanop)
14236603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14246603Sgblack@eecs.umich.edu                    break;
14256603Sgblack@eecs.umich.edu                  case 4:
14266603Sgblack@eecs.umich.edu                    if (arg1 != arg2 || nanop)
14276603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14286603Sgblack@eecs.umich.edu                    break;
14296603Sgblack@eecs.umich.edu                  case 5:
14306603Sgblack@eecs.umich.edu                    if (!(arg1 < arg2) || nanop)
14316603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14326603Sgblack@eecs.umich.edu                    break;
14336603Sgblack@eecs.umich.edu                  case 6:
14346603Sgblack@eecs.umich.edu                    if (!(arg1 <= arg2) || nanop)
14356603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14366603Sgblack@eecs.umich.edu                    break;
14376603Sgblack@eecs.umich.edu                  case 7:
14386603Sgblack@eecs.umich.edu                    if (!nanop)
14396603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14406603Sgblack@eecs.umich.edu                    break;
14416603Sgblack@eecs.umich.edu                };
14426603Sgblack@eecs.umich.edu
14436603Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
14446603Sgblack@eecs.umich.edu            }
14456603Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
14466603Sgblack@eecs.umich.edu        '''
14476603Sgblack@eecs.umich.edu
14486601Sgblack@eecs.umich.edu    class Mcmpf2rf(MediaOp):
14496601Sgblack@eecs.umich.edu        def __init__(self, src1, src2,\
14506601Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
14516601Sgblack@eecs.umich.edu            super(Mcmpf2rf, self).__init__("InstRegIndex(0)", src1,\
14526601Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
14536601Sgblack@eecs.umich.edu        code = '''
14546601Sgblack@eecs.umich.edu            union floatInt
14556601Sgblack@eecs.umich.edu            {
14566601Sgblack@eecs.umich.edu                float f;
14576601Sgblack@eecs.umich.edu                uint32_t i;
14586601Sgblack@eecs.umich.edu            };
14596601Sgblack@eecs.umich.edu            union doubleInt
14606601Sgblack@eecs.umich.edu            {
14616601Sgblack@eecs.umich.edu                double d;
14626601Sgblack@eecs.umich.edu                uint64_t i;
14636601Sgblack@eecs.umich.edu            };
14646601Sgblack@eecs.umich.edu
14656601Sgblack@eecs.umich.edu            assert(srcSize == destSize);
14666601Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
14676601Sgblack@eecs.umich.edu            int size = srcSize;
14686601Sgblack@eecs.umich.edu            int sizeBits = size * 8;
14696601Sgblack@eecs.umich.edu
14706601Sgblack@eecs.umich.edu            double arg1, arg2;
14716601Sgblack@eecs.umich.edu            uint64_t arg1Bits = bits(FpSrcReg1.uqw, sizeBits - 1, 0);
14726601Sgblack@eecs.umich.edu            uint64_t arg2Bits = bits(FpSrcReg2.uqw, sizeBits - 1, 0);
14736601Sgblack@eecs.umich.edu            if (size == 4) {
14746601Sgblack@eecs.umich.edu                floatInt fi;
14756601Sgblack@eecs.umich.edu                fi.i = arg1Bits;
14766601Sgblack@eecs.umich.edu                arg1 = fi.f;
14776601Sgblack@eecs.umich.edu                fi.i = arg2Bits;
14786601Sgblack@eecs.umich.edu                arg2 = fi.f;
14796601Sgblack@eecs.umich.edu            } else {
14806601Sgblack@eecs.umich.edu                doubleInt di;
14816601Sgblack@eecs.umich.edu                di.i = arg1Bits;
14826601Sgblack@eecs.umich.edu                arg1 = di.d;
14836601Sgblack@eecs.umich.edu                di.i = arg2Bits;
14846601Sgblack@eecs.umich.edu                arg2 = di.d;
14856601Sgblack@eecs.umich.edu            }
14866601Sgblack@eecs.umich.edu
14876601Sgblack@eecs.umich.edu            //               ZF PF CF
14886601Sgblack@eecs.umich.edu            // Unordered      1  1  1
14896601Sgblack@eecs.umich.edu            // Greater than   0  0  0
14906601Sgblack@eecs.umich.edu            // Less than      0  0  1
14916601Sgblack@eecs.umich.edu            // Equal          1  0  0
14926601Sgblack@eecs.umich.edu            //           OF = SF = AF = 0
14936601Sgblack@eecs.umich.edu            ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit |
14946601Sgblack@eecs.umich.edu                                        ZFBit | PFBit | CFBit);
14956601Sgblack@eecs.umich.edu            if (isnan(arg1) || isnan(arg2))
14966601Sgblack@eecs.umich.edu                ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit);
14976601Sgblack@eecs.umich.edu            else if(arg1 < arg2)
14986601Sgblack@eecs.umich.edu                ccFlagBits = ccFlagBits | CFBit;
14996601Sgblack@eecs.umich.edu            else if(arg1 == arg2)
15006601Sgblack@eecs.umich.edu                ccFlagBits = ccFlagBits | ZFBit;
15016601Sgblack@eecs.umich.edu        '''
15026516Sgblack@eecs.umich.edu}};
1503