mediaop.isa revision 11711
111160Ssteve.reinhardt@amd.com// Copyright (c) 2009 The Regents of The University of Michigan
211160Ssteve.reinhardt@amd.com// Copyright (c) 2015 Advanced Micro Devices, Inc.
311160Ssteve.reinhardt@amd.com//
46516Sgblack@eecs.umich.edu// All rights reserved.
56516Sgblack@eecs.umich.edu//
66516Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
76516Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
86516Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
96516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
106516Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
116516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
126516Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
136516Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
146516Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
156516Sgblack@eecs.umich.edu// this software without specific prior written permission.
166516Sgblack@eecs.umich.edu//
176516Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186516Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196516Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206516Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216516Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226516Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236516Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246516Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256516Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266516Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276516Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286516Sgblack@eecs.umich.edu//
296516Sgblack@eecs.umich.edu// Authors: Gabe Black
306516Sgblack@eecs.umich.edu
316516Sgblack@eecs.umich.edudef template MediaOpExecute {{
3210196SCurtis.Dunham@arm.com        Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
336516Sgblack@eecs.umich.edu                Trace::InstRecord *traceData) const
346516Sgblack@eecs.umich.edu        {
356516Sgblack@eecs.umich.edu            Fault fault = NoFault;
366516Sgblack@eecs.umich.edu
376516Sgblack@eecs.umich.edu            %(op_decl)s;
386516Sgblack@eecs.umich.edu            %(op_rd)s;
396516Sgblack@eecs.umich.edu
406516Sgblack@eecs.umich.edu            %(code)s;
416516Sgblack@eecs.umich.edu
426516Sgblack@eecs.umich.edu            //Write the resulting state to the execution context
436516Sgblack@eecs.umich.edu            if(fault == NoFault)
446516Sgblack@eecs.umich.edu            {
456516Sgblack@eecs.umich.edu                %(op_wb)s;
466516Sgblack@eecs.umich.edu            }
476516Sgblack@eecs.umich.edu            return fault;
486516Sgblack@eecs.umich.edu        }
496516Sgblack@eecs.umich.edu}};
506516Sgblack@eecs.umich.edu
516516Sgblack@eecs.umich.edudef template MediaOpRegDeclare {{
526516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
536516Sgblack@eecs.umich.edu    {
546516Sgblack@eecs.umich.edu      public:
556516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
567620Sgblack@eecs.umich.edu                const char * instMnem, uint64_t setFlags,
576516Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
586545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
596516Sgblack@eecs.umich.edu
606516Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
616516Sgblack@eecs.umich.edu    };
626516Sgblack@eecs.umich.edu}};
636516Sgblack@eecs.umich.edu
646516Sgblack@eecs.umich.edudef template MediaOpImmDeclare {{
656516Sgblack@eecs.umich.edu
666516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
676516Sgblack@eecs.umich.edu    {
686516Sgblack@eecs.umich.edu      public:
696516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
707620Sgblack@eecs.umich.edu                const char * instMnem, uint64_t setFlags,
716516Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
726545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
736516Sgblack@eecs.umich.edu
746516Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
756516Sgblack@eecs.umich.edu    };
766516Sgblack@eecs.umich.edu}};
776516Sgblack@eecs.umich.edu
786516Sgblack@eecs.umich.edudef template MediaOpRegConstructor {{
7910184SCurtis.Dunham@arm.com    %(class_name)s::%(class_name)s(
807620Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
816516Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
826545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
837620Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
846545Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _ext,
856516Sgblack@eecs.umich.edu                %(op_class)s)
866516Sgblack@eecs.umich.edu    {
877626Sgblack@eecs.umich.edu        %(constructor)s;
886516Sgblack@eecs.umich.edu    }
896516Sgblack@eecs.umich.edu}};
906516Sgblack@eecs.umich.edu
916516Sgblack@eecs.umich.edudef template MediaOpImmConstructor {{
9210184SCurtis.Dunham@arm.com    %(class_name)s::%(class_name)s(
937620Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
946516Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
956545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
967620Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
976545Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _ext,
986516Sgblack@eecs.umich.edu                %(op_class)s)
996516Sgblack@eecs.umich.edu    {
1007626Sgblack@eecs.umich.edu        %(constructor)s;
1016516Sgblack@eecs.umich.edu    }
1026516Sgblack@eecs.umich.edu}};
1036516Sgblack@eecs.umich.edu
1046516Sgblack@eecs.umich.edulet {{
1056516Sgblack@eecs.umich.edu    # Make these empty strings so that concatenating onto
1066516Sgblack@eecs.umich.edu    # them will always work.
1076516Sgblack@eecs.umich.edu    header_output = ""
1086516Sgblack@eecs.umich.edu    decoder_output = ""
1096516Sgblack@eecs.umich.edu    exec_output = ""
1106516Sgblack@eecs.umich.edu
1116516Sgblack@eecs.umich.edu    immTemplates = (
1126516Sgblack@eecs.umich.edu            MediaOpImmDeclare,
1136516Sgblack@eecs.umich.edu            MediaOpImmConstructor,
1146516Sgblack@eecs.umich.edu            MediaOpExecute)
1156516Sgblack@eecs.umich.edu
1166516Sgblack@eecs.umich.edu    regTemplates = (
1176516Sgblack@eecs.umich.edu            MediaOpRegDeclare,
1186516Sgblack@eecs.umich.edu            MediaOpRegConstructor,
1196516Sgblack@eecs.umich.edu            MediaOpExecute)
1206516Sgblack@eecs.umich.edu
1216516Sgblack@eecs.umich.edu    class MediaOpMeta(type):
1226516Sgblack@eecs.umich.edu        def buildCppClasses(self, name, Name, suffix, code):
1236516Sgblack@eecs.umich.edu
1246516Sgblack@eecs.umich.edu            # Globals to stick the output in
1256516Sgblack@eecs.umich.edu            global header_output
1266516Sgblack@eecs.umich.edu            global decoder_output
1276516Sgblack@eecs.umich.edu            global exec_output
1286516Sgblack@eecs.umich.edu
1296516Sgblack@eecs.umich.edu            # If op2 is used anywhere, make register and immediate versions
1306516Sgblack@eecs.umich.edu            # of this code.
1318588Sgblack@eecs.umich.edu            matcher = re.compile(r"(?<!\w)(?P<prefix>s?)op2(?P<typeQual>_[^\W_]+)?")
1326516Sgblack@eecs.umich.edu            match = matcher.search(code)
1336516Sgblack@eecs.umich.edu            if match:
1346516Sgblack@eecs.umich.edu                typeQual = ""
1356516Sgblack@eecs.umich.edu                if match.group("typeQual"):
1366516Sgblack@eecs.umich.edu                    typeQual = match.group("typeQual")
1376583Sgblack@eecs.umich.edu                src2_name = "%sFpSrcReg2%s" % (match.group("prefix"), typeQual)
1386516Sgblack@eecs.umich.edu                self.buildCppClasses(name, Name, suffix,
1396516Sgblack@eecs.umich.edu                        matcher.sub(src2_name, code))
1406516Sgblack@eecs.umich.edu                self.buildCppClasses(name + "i", Name, suffix + "Imm",
1416516Sgblack@eecs.umich.edu                        matcher.sub("imm8", code))
1426516Sgblack@eecs.umich.edu                return
1436516Sgblack@eecs.umich.edu
1446516Sgblack@eecs.umich.edu            base = "X86ISA::MediaOp"
1456516Sgblack@eecs.umich.edu
1466516Sgblack@eecs.umich.edu            # If imm8 shows up in the code, use the immediate templates, if
1476516Sgblack@eecs.umich.edu            # not, hopefully the register ones will be correct.
1486516Sgblack@eecs.umich.edu            matcher = re.compile("(?<!\w)imm8(?!\w)")
1496516Sgblack@eecs.umich.edu            if matcher.search(code):
1506516Sgblack@eecs.umich.edu                base += "Imm"
1516516Sgblack@eecs.umich.edu                templates = immTemplates
1526516Sgblack@eecs.umich.edu            else:
1536516Sgblack@eecs.umich.edu                base += "Reg"
1546516Sgblack@eecs.umich.edu                templates = regTemplates
1556516Sgblack@eecs.umich.edu
1566516Sgblack@eecs.umich.edu            # Get everything ready for the substitution
1576516Sgblack@eecs.umich.edu            iop = InstObjParams(name, Name + suffix, base, {"code" : code})
1586516Sgblack@eecs.umich.edu
1596516Sgblack@eecs.umich.edu            # Generate the actual code (finally!)
1606516Sgblack@eecs.umich.edu            header_output += templates[0].subst(iop)
1616516Sgblack@eecs.umich.edu            decoder_output += templates[1].subst(iop)
1626516Sgblack@eecs.umich.edu            exec_output += templates[2].subst(iop)
1636516Sgblack@eecs.umich.edu
1646516Sgblack@eecs.umich.edu
1656516Sgblack@eecs.umich.edu        def __new__(mcls, Name, bases, dict):
1666516Sgblack@eecs.umich.edu            abstract = False
1676516Sgblack@eecs.umich.edu            name = Name.lower()
1686516Sgblack@eecs.umich.edu            if "abstract" in dict:
1696516Sgblack@eecs.umich.edu                abstract = dict['abstract']
1706516Sgblack@eecs.umich.edu                del dict['abstract']
1716516Sgblack@eecs.umich.edu
1726516Sgblack@eecs.umich.edu            cls = super(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict)
1736516Sgblack@eecs.umich.edu            if not abstract:
1746516Sgblack@eecs.umich.edu                cls.className = Name
1756516Sgblack@eecs.umich.edu                cls.base_mnemonic = name
1766516Sgblack@eecs.umich.edu                code = cls.code
1776516Sgblack@eecs.umich.edu
1786516Sgblack@eecs.umich.edu                # Set up the C++ classes
1796516Sgblack@eecs.umich.edu                mcls.buildCppClasses(cls, name, Name, "", code)
1806516Sgblack@eecs.umich.edu
1816516Sgblack@eecs.umich.edu                # Hook into the microassembler dict
1826516Sgblack@eecs.umich.edu                global microopClasses
1836516Sgblack@eecs.umich.edu                microopClasses[name] = cls
1846516Sgblack@eecs.umich.edu
1856516Sgblack@eecs.umich.edu                # If op2 is used anywhere, make register and immediate versions
1866516Sgblack@eecs.umich.edu                # of this code.
1878588Sgblack@eecs.umich.edu                matcher = re.compile(r"op2(?P<typeQual>_[^\W_]+)?")
1886516Sgblack@eecs.umich.edu                if matcher.search(code):
1896516Sgblack@eecs.umich.edu                    microopClasses[name + 'i'] = cls
1906516Sgblack@eecs.umich.edu            return cls
1916516Sgblack@eecs.umich.edu
1926516Sgblack@eecs.umich.edu
1936516Sgblack@eecs.umich.edu    class MediaOp(X86Microop):
1946516Sgblack@eecs.umich.edu        __metaclass__ = MediaOpMeta
1956516Sgblack@eecs.umich.edu        # This class itself doesn't act as a microop
1966516Sgblack@eecs.umich.edu        abstract = True
1976516Sgblack@eecs.umich.edu
1986516Sgblack@eecs.umich.edu        def __init__(self, dest, src1, op2,
1996545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2006516Sgblack@eecs.umich.edu            self.dest = dest
2016516Sgblack@eecs.umich.edu            self.src1 = src1
2026516Sgblack@eecs.umich.edu            self.op2 = op2
2036516Sgblack@eecs.umich.edu            if size is not None:
2046516Sgblack@eecs.umich.edu                self.srcSize = size
2056516Sgblack@eecs.umich.edu                self.destSize = size
2066516Sgblack@eecs.umich.edu            if srcSize is not None:
2076516Sgblack@eecs.umich.edu                self.srcSize = srcSize
2086516Sgblack@eecs.umich.edu            if destSize is not None:
2096516Sgblack@eecs.umich.edu                self.destSize = destSize
2106516Sgblack@eecs.umich.edu            if self.srcSize is None:
2116516Sgblack@eecs.umich.edu                raise Exception, "Source size not set."
2126516Sgblack@eecs.umich.edu            if self.destSize is None:
2136516Sgblack@eecs.umich.edu                raise Exception, "Dest size not set."
2146545Sgblack@eecs.umich.edu            if ext is None:
2156545Sgblack@eecs.umich.edu                self.ext = 0
2166516Sgblack@eecs.umich.edu            else:
21711320Ssteve.reinhardt@amd.com                self.ext = ext
2186516Sgblack@eecs.umich.edu
2197620Sgblack@eecs.umich.edu        def getAllocator(self, microFlags):
2206516Sgblack@eecs.umich.edu            className = self.className
2216516Sgblack@eecs.umich.edu            if self.mnemonic == self.base_mnemonic + 'i':
2226516Sgblack@eecs.umich.edu                className += "Imm"
2237620Sgblack@eecs.umich.edu            allocator = '''new %(class_name)s(machInst, macrocodeBlock,
2246516Sgblack@eecs.umich.edu                    %(flags)s, %(src1)s, %(op2)s, %(dest)s,
2256545Sgblack@eecs.umich.edu                    %(srcSize)s, %(destSize)s, %(ext)s)''' % {
2266516Sgblack@eecs.umich.edu                "class_name" : className,
2276516Sgblack@eecs.umich.edu                "flags" : self.microFlagsText(microFlags),
2286516Sgblack@eecs.umich.edu                "src1" : self.src1, "op2" : self.op2,
2296516Sgblack@eecs.umich.edu                "dest" : self.dest,
2306516Sgblack@eecs.umich.edu                "srcSize" : self.srcSize,
2316516Sgblack@eecs.umich.edu                "destSize" : self.destSize,
2326545Sgblack@eecs.umich.edu                "ext" : self.ext}
2336516Sgblack@eecs.umich.edu            return allocator
2346516Sgblack@eecs.umich.edu
2356516Sgblack@eecs.umich.edu    class Mov2int(MediaOp):
2366589Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2 = 0, \
2376545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2386589Sgblack@eecs.umich.edu            super(Mov2int, self).__init__(dest, src1,\
2396589Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
2406516Sgblack@eecs.umich.edu        code = '''
2416589Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / srcSize;
2426589Sgblack@eecs.umich.edu            int offset = imm8;
2436589Sgblack@eecs.umich.edu            if (bits(src1, 0) && (ext & 0x1))
2446589Sgblack@eecs.umich.edu                offset -= items;
2456589Sgblack@eecs.umich.edu            if (offset >= 0 && offset < items) {
2466589Sgblack@eecs.umich.edu                uint64_t fpSrcReg1 =
2478588Sgblack@eecs.umich.edu                    bits(FpSrcReg1_uqw,
2486589Sgblack@eecs.umich.edu                            (offset + 1) * srcSize * 8 - 1,
2496589Sgblack@eecs.umich.edu                            (offset + 0) * srcSize * 8);
2506589Sgblack@eecs.umich.edu                DestReg = merge(0, fpSrcReg1, destSize);
2516589Sgblack@eecs.umich.edu            } else {
2526589Sgblack@eecs.umich.edu                DestReg = DestReg;
2536589Sgblack@eecs.umich.edu            }
2546516Sgblack@eecs.umich.edu        '''
2556516Sgblack@eecs.umich.edu
2566516Sgblack@eecs.umich.edu    class Mov2fp(MediaOp):
2576589Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2 = 0, \
2586545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2596589Sgblack@eecs.umich.edu            super(Mov2fp, self).__init__(dest, src1,\
2606589Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
2616516Sgblack@eecs.umich.edu        code = '''
2626589Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / destSize;
2636589Sgblack@eecs.umich.edu            int offset = imm8;
2646589Sgblack@eecs.umich.edu            if (bits(dest, 0) && (ext & 0x1))
2656589Sgblack@eecs.umich.edu                offset -= items;
2666589Sgblack@eecs.umich.edu            if (offset >= 0 && offset < items) {
2676589Sgblack@eecs.umich.edu                uint64_t srcReg1 = pick(SrcReg1, 0, srcSize);
2688588Sgblack@eecs.umich.edu                FpDestReg_uqw =
2698588Sgblack@eecs.umich.edu                    insertBits(FpDestReg_uqw,
2706589Sgblack@eecs.umich.edu                            (offset + 1) * destSize * 8 - 1,
2716589Sgblack@eecs.umich.edu                            (offset + 0) * destSize * 8, srcReg1);
2726589Sgblack@eecs.umich.edu            } else {
2738588Sgblack@eecs.umich.edu                FpDestReg_uqw = FpDestReg_uqw;
2746589Sgblack@eecs.umich.edu            }
2756516Sgblack@eecs.umich.edu        '''
2766521Sgblack@eecs.umich.edu
2776592Sgblack@eecs.umich.edu    class Movsign(MediaOp):
2786592Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
2796592Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2806592Sgblack@eecs.umich.edu            super(Movsign, self).__init__(dest, src,\
2816592Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
2826592Sgblack@eecs.umich.edu        code = '''
2836592Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / srcSize;
2846592Sgblack@eecs.umich.edu            uint64_t result = 0;
2856592Sgblack@eecs.umich.edu            int offset = (ext & 0x1) ? items : 0;
2866592Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
2876592Sgblack@eecs.umich.edu                uint64_t picked =
2888588Sgblack@eecs.umich.edu                    bits(FpSrcReg1_uqw, (i + 1) * 8 * srcSize - 1);
2896592Sgblack@eecs.umich.edu                result = insertBits(result, i + offset, i + offset, picked);
2906592Sgblack@eecs.umich.edu            }
2916592Sgblack@eecs.umich.edu            DestReg = DestReg | result;
2926592Sgblack@eecs.umich.edu        '''
2936592Sgblack@eecs.umich.edu
2946594Sgblack@eecs.umich.edu    class Maskmov(MediaOp):
2956594Sgblack@eecs.umich.edu        code = '''
2966594Sgblack@eecs.umich.edu            assert(srcSize == destSize);
2976594Sgblack@eecs.umich.edu            int size = srcSize;
2986594Sgblack@eecs.umich.edu            int sizeBits = size * 8;
2996799Sgblack@eecs.umich.edu            int items = numItems(size);
3008588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
3016594Sgblack@eecs.umich.edu
3026594Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3036594Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
3046594Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
3058588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
3068588Sgblack@eecs.umich.edu                if (bits(FpSrcReg2_uqw, hiIndex))
3076594Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
3086594Sgblack@eecs.umich.edu            }
3098588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
3106594Sgblack@eecs.umich.edu        '''
3116594Sgblack@eecs.umich.edu
3126596Sgblack@eecs.umich.edu    class shuffle(MediaOp):
3136596Sgblack@eecs.umich.edu        code = '''
3146596Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3156596Sgblack@eecs.umich.edu            int size = srcSize;
3166596Sgblack@eecs.umich.edu            int sizeBits = size * 8;
3176596Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / size;
3186596Sgblack@eecs.umich.edu            int options;
3196596Sgblack@eecs.umich.edu            int optionBits;
3206596Sgblack@eecs.umich.edu            if (size == 8) {
3216596Sgblack@eecs.umich.edu                options = 2;
3226596Sgblack@eecs.umich.edu                optionBits = 1;
3236596Sgblack@eecs.umich.edu            } else {
3246596Sgblack@eecs.umich.edu                options = 4;
3256596Sgblack@eecs.umich.edu                optionBits = 2;
3266596Sgblack@eecs.umich.edu            }
3276596Sgblack@eecs.umich.edu
3286596Sgblack@eecs.umich.edu            uint64_t result = 0;
3296596Sgblack@eecs.umich.edu            uint8_t sel = ext;
3306596Sgblack@eecs.umich.edu
3316596Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3326596Sgblack@eecs.umich.edu                uint64_t resBits;
3336596Sgblack@eecs.umich.edu                uint8_t lsel = sel & mask(optionBits);
3346596Sgblack@eecs.umich.edu                if (lsel * size >= sizeof(FloatRegBits)) {
3356596Sgblack@eecs.umich.edu                    lsel -= options / 2;
3368588Sgblack@eecs.umich.edu                    resBits = bits(FpSrcReg2_uqw,
3376596Sgblack@eecs.umich.edu                            (lsel + 1) * sizeBits - 1,
3386596Sgblack@eecs.umich.edu                            (lsel + 0) * sizeBits);
3396596Sgblack@eecs.umich.edu                }  else {
3408588Sgblack@eecs.umich.edu                    resBits = bits(FpSrcReg1_uqw,
3416596Sgblack@eecs.umich.edu                            (lsel + 1) * sizeBits - 1,
3426596Sgblack@eecs.umich.edu                            (lsel + 0) * sizeBits);
3436596Sgblack@eecs.umich.edu                }
3446596Sgblack@eecs.umich.edu
3456596Sgblack@eecs.umich.edu                sel >>= optionBits;
3466596Sgblack@eecs.umich.edu
3476596Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
3486596Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
3496596Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
3506596Sgblack@eecs.umich.edu            }
3518588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
3526596Sgblack@eecs.umich.edu        '''
3536596Sgblack@eecs.umich.edu
3546521Sgblack@eecs.umich.edu    class Unpack(MediaOp):
3556521Sgblack@eecs.umich.edu        code = '''
3566521Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3576521Sgblack@eecs.umich.edu            int size = destSize;
3586521Sgblack@eecs.umich.edu            int items = (sizeof(FloatRegBits) / size) / 2;
3596545Sgblack@eecs.umich.edu            int offset = ext ? items : 0;
3606521Sgblack@eecs.umich.edu            uint64_t result = 0;
3616521Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3626521Sgblack@eecs.umich.edu                uint64_t pickedLow =
3638588Sgblack@eecs.umich.edu                    bits(FpSrcReg1_uqw, (i + offset + 1) * 8 * size - 1,
3646521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
3656521Sgblack@eecs.umich.edu                result = insertBits(result,
3666521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size - 1,
3676521Sgblack@eecs.umich.edu                                    (2 * i + 0) * 8 * size,
3686521Sgblack@eecs.umich.edu                                    pickedLow);
3696521Sgblack@eecs.umich.edu                uint64_t pickedHigh =
3708588Sgblack@eecs.umich.edu                    bits(FpSrcReg2_uqw, (i + offset + 1) * 8 * size - 1,
3716521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
3726521Sgblack@eecs.umich.edu                result = insertBits(result,
3736521Sgblack@eecs.umich.edu                                    (2 * i + 2) * 8 * size - 1,
3746521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size,
3756521Sgblack@eecs.umich.edu                                    pickedHigh);
3766521Sgblack@eecs.umich.edu            }
3778588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
3786521Sgblack@eecs.umich.edu        '''
3796534Sgblack@eecs.umich.edu
3806546Sgblack@eecs.umich.edu    class Pack(MediaOp):
3816546Sgblack@eecs.umich.edu        code = '''
3826546Sgblack@eecs.umich.edu            assert(srcSize == destSize * 2);
3836546Sgblack@eecs.umich.edu            int items = (sizeof(FloatRegBits) / destSize);
3846546Sgblack@eecs.umich.edu            int destBits = destSize * 8;
3856546Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
3866546Sgblack@eecs.umich.edu            uint64_t result = 0;
3876546Sgblack@eecs.umich.edu            int i;
3886546Sgblack@eecs.umich.edu            for (i = 0; i < items / 2; i++) {
3896546Sgblack@eecs.umich.edu                uint64_t picked =
3908588Sgblack@eecs.umich.edu                    bits(FpSrcReg1_uqw, (i + 1) * srcBits - 1,
3916546Sgblack@eecs.umich.edu                                        (i + 0) * srcBits);
3926546Sgblack@eecs.umich.edu                unsigned signBit = bits(picked, srcBits - 1);
3936546Sgblack@eecs.umich.edu                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
3946546Sgblack@eecs.umich.edu
3956546Sgblack@eecs.umich.edu                // Handle saturation.
3966546Sgblack@eecs.umich.edu                if (signBit) {
3976546Sgblack@eecs.umich.edu                    if (overflow != mask(destBits - srcBits + 1)) {
3986801Sgblack@eecs.umich.edu                        if (signedOp())
3996742Svince@csl.cornell.edu                            picked = (ULL(1) << (destBits - 1));
4006546Sgblack@eecs.umich.edu                        else
4016546Sgblack@eecs.umich.edu                            picked = 0;
4026546Sgblack@eecs.umich.edu                    }
4036546Sgblack@eecs.umich.edu                } else {
4046546Sgblack@eecs.umich.edu                    if (overflow != 0) {
4056801Sgblack@eecs.umich.edu                        if (signedOp())
4066546Sgblack@eecs.umich.edu                            picked = mask(destBits - 1);
4076546Sgblack@eecs.umich.edu                        else
4086546Sgblack@eecs.umich.edu                            picked = mask(destBits);
4096546Sgblack@eecs.umich.edu                    }
4106546Sgblack@eecs.umich.edu                }
4116546Sgblack@eecs.umich.edu                result = insertBits(result,
4126546Sgblack@eecs.umich.edu                                    (i + 1) * destBits - 1,
4136546Sgblack@eecs.umich.edu                                    (i + 0) * destBits,
4146546Sgblack@eecs.umich.edu                                    picked);
4156546Sgblack@eecs.umich.edu            }
4166546Sgblack@eecs.umich.edu            for (;i < items; i++) {
4176546Sgblack@eecs.umich.edu                uint64_t picked =
4188588Sgblack@eecs.umich.edu                    bits(FpSrcReg2_uqw, (i - items + 1) * srcBits - 1,
4196546Sgblack@eecs.umich.edu                                        (i - items + 0) * srcBits);
4206546Sgblack@eecs.umich.edu                unsigned signBit = bits(picked, srcBits - 1);
4216546Sgblack@eecs.umich.edu                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
4226546Sgblack@eecs.umich.edu
4236546Sgblack@eecs.umich.edu                // Handle saturation.
4246546Sgblack@eecs.umich.edu                if (signBit) {
4256546Sgblack@eecs.umich.edu                    if (overflow != mask(destBits - srcBits + 1)) {
4266801Sgblack@eecs.umich.edu                        if (signedOp())
4276742Svince@csl.cornell.edu                            picked = (ULL(1) << (destBits - 1));
4286546Sgblack@eecs.umich.edu                        else
4296546Sgblack@eecs.umich.edu                            picked = 0;
4306546Sgblack@eecs.umich.edu                    }
4316546Sgblack@eecs.umich.edu                } else {
4326546Sgblack@eecs.umich.edu                    if (overflow != 0) {
4336801Sgblack@eecs.umich.edu                        if (signedOp())
4346546Sgblack@eecs.umich.edu                            picked = mask(destBits - 1);
4356546Sgblack@eecs.umich.edu                        else
4366546Sgblack@eecs.umich.edu                            picked = mask(destBits);
4376546Sgblack@eecs.umich.edu                    }
4386546Sgblack@eecs.umich.edu                }
4396546Sgblack@eecs.umich.edu                result = insertBits(result,
4406546Sgblack@eecs.umich.edu                                    (i + 1) * destBits - 1,
4416546Sgblack@eecs.umich.edu                                    (i + 0) * destBits,
4426546Sgblack@eecs.umich.edu                                    picked);
4436546Sgblack@eecs.umich.edu            }
4448588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
4456546Sgblack@eecs.umich.edu        '''
4466546Sgblack@eecs.umich.edu
4476534Sgblack@eecs.umich.edu    class Mxor(MediaOp):
4486534Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4496534Sgblack@eecs.umich.edu            super(Mxor, self).__init__(dest, src1, src2, 1)
4506534Sgblack@eecs.umich.edu        code = '''
4518588Sgblack@eecs.umich.edu            FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;
4526534Sgblack@eecs.umich.edu        '''
4536537Sgblack@eecs.umich.edu
4546537Sgblack@eecs.umich.edu    class Mor(MediaOp):
4556537Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4566537Sgblack@eecs.umich.edu            super(Mor, self).__init__(dest, src1, src2, 1)
4576537Sgblack@eecs.umich.edu        code = '''
4588588Sgblack@eecs.umich.edu            FpDestReg_uqw = FpSrcReg1_uqw | FpSrcReg2_uqw;
4596537Sgblack@eecs.umich.edu        '''
4606539Sgblack@eecs.umich.edu
4616539Sgblack@eecs.umich.edu    class Mand(MediaOp):
4626539Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4636539Sgblack@eecs.umich.edu            super(Mand, self).__init__(dest, src1, src2, 1)
4646539Sgblack@eecs.umich.edu        code = '''
4658588Sgblack@eecs.umich.edu            FpDestReg_uqw = FpSrcReg1_uqw & FpSrcReg2_uqw;
4666539Sgblack@eecs.umich.edu        '''
4676541Sgblack@eecs.umich.edu
4686541Sgblack@eecs.umich.edu    class Mandn(MediaOp):
4696541Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4706541Sgblack@eecs.umich.edu            super(Mandn, self).__init__(dest, src1, src2, 1)
4716541Sgblack@eecs.umich.edu        code = '''
4728588Sgblack@eecs.umich.edu            FpDestReg_uqw = ~FpSrcReg1_uqw & FpSrcReg2_uqw;
4736541Sgblack@eecs.umich.edu        '''
4746548Sgblack@eecs.umich.edu
4756548Sgblack@eecs.umich.edu    class Mminf(MediaOp):
4766548Sgblack@eecs.umich.edu        code = '''
4776548Sgblack@eecs.umich.edu            union floatInt
4786548Sgblack@eecs.umich.edu            {
4796548Sgblack@eecs.umich.edu                float f;
4806548Sgblack@eecs.umich.edu                uint32_t i;
4816548Sgblack@eecs.umich.edu            };
4826548Sgblack@eecs.umich.edu            union doubleInt
4836548Sgblack@eecs.umich.edu            {
4846548Sgblack@eecs.umich.edu                double d;
4856548Sgblack@eecs.umich.edu                uint64_t i;
4866548Sgblack@eecs.umich.edu            };
4876548Sgblack@eecs.umich.edu
4886548Sgblack@eecs.umich.edu            assert(srcSize == destSize);
4896548Sgblack@eecs.umich.edu            int size = srcSize;
4906548Sgblack@eecs.umich.edu            int sizeBits = size * 8;
4916548Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
4926799Sgblack@eecs.umich.edu            int items = numItems(size);
4938588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
4946548Sgblack@eecs.umich.edu
4956548Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
4966548Sgblack@eecs.umich.edu                double arg1, arg2;
4976548Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
4986548Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
4998588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
5008588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
5016548Sgblack@eecs.umich.edu
5026548Sgblack@eecs.umich.edu                if (size == 4) {
5036548Sgblack@eecs.umich.edu                    floatInt fi;
5046548Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
5056548Sgblack@eecs.umich.edu                    arg1 = fi.f;
5066548Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
5076548Sgblack@eecs.umich.edu                    arg2 = fi.f;
5086548Sgblack@eecs.umich.edu                } else {
5096548Sgblack@eecs.umich.edu                    doubleInt di;
5106548Sgblack@eecs.umich.edu                    di.i = arg1Bits;
5116548Sgblack@eecs.umich.edu                    arg1 = di.d;
5126548Sgblack@eecs.umich.edu                    di.i = arg2Bits;
5136548Sgblack@eecs.umich.edu                    arg2 = di.d;
5146548Sgblack@eecs.umich.edu                }
5156548Sgblack@eecs.umich.edu
5166548Sgblack@eecs.umich.edu                if (arg1 < arg2) {
5176548Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
5186548Sgblack@eecs.umich.edu                } else {
5196548Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
5206548Sgblack@eecs.umich.edu                }
5216548Sgblack@eecs.umich.edu            }
5228588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
5236548Sgblack@eecs.umich.edu        '''
5246550Sgblack@eecs.umich.edu
5256550Sgblack@eecs.umich.edu    class Mmaxf(MediaOp):
5266550Sgblack@eecs.umich.edu        code = '''
5276550Sgblack@eecs.umich.edu            union floatInt
5286550Sgblack@eecs.umich.edu            {
5296550Sgblack@eecs.umich.edu                float f;
5306550Sgblack@eecs.umich.edu                uint32_t i;
5316550Sgblack@eecs.umich.edu            };
5326550Sgblack@eecs.umich.edu            union doubleInt
5336550Sgblack@eecs.umich.edu            {
5346550Sgblack@eecs.umich.edu                double d;
5356550Sgblack@eecs.umich.edu                uint64_t i;
5366550Sgblack@eecs.umich.edu            };
5376550Sgblack@eecs.umich.edu
5386550Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5396550Sgblack@eecs.umich.edu            int size = srcSize;
5406550Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5416550Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
5426799Sgblack@eecs.umich.edu            int items = numItems(size);
5438588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
5446550Sgblack@eecs.umich.edu
5456550Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
5466550Sgblack@eecs.umich.edu                double arg1, arg2;
5476550Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5486550Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5498588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
5508588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
5516550Sgblack@eecs.umich.edu
5526550Sgblack@eecs.umich.edu                if (size == 4) {
5536550Sgblack@eecs.umich.edu                    floatInt fi;
5546550Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
5556550Sgblack@eecs.umich.edu                    arg1 = fi.f;
5566550Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
5576550Sgblack@eecs.umich.edu                    arg2 = fi.f;
5586550Sgblack@eecs.umich.edu                } else {
5596550Sgblack@eecs.umich.edu                    doubleInt di;
5606550Sgblack@eecs.umich.edu                    di.i = arg1Bits;
5616550Sgblack@eecs.umich.edu                    arg1 = di.d;
5626550Sgblack@eecs.umich.edu                    di.i = arg2Bits;
5636550Sgblack@eecs.umich.edu                    arg2 = di.d;
5646550Sgblack@eecs.umich.edu                }
5656550Sgblack@eecs.umich.edu
5666550Sgblack@eecs.umich.edu                if (arg1 > arg2) {
5676550Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
5686550Sgblack@eecs.umich.edu                } else {
5696550Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
5706550Sgblack@eecs.umich.edu                }
5716550Sgblack@eecs.umich.edu            }
5728588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
5736550Sgblack@eecs.umich.edu        '''
5746552Sgblack@eecs.umich.edu
5756572Sgblack@eecs.umich.edu    class Mmini(MediaOp):
5766572Sgblack@eecs.umich.edu        code = '''
5776572Sgblack@eecs.umich.edu
5786572Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5796572Sgblack@eecs.umich.edu            int size = srcSize;
5806572Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5816799Sgblack@eecs.umich.edu            int items = numItems(size);
5828588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
5836572Sgblack@eecs.umich.edu
5846572Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
5856572Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5866572Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5878588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
5886572Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
5896742Svince@csl.cornell.edu                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
5908588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
5916572Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
5926742Svince@csl.cornell.edu                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
5936572Sgblack@eecs.umich.edu                uint64_t resBits;
5946572Sgblack@eecs.umich.edu
5956801Sgblack@eecs.umich.edu                if (signedOp()) {
5966572Sgblack@eecs.umich.edu                    if (arg1 < arg2) {
5976572Sgblack@eecs.umich.edu                        resBits = arg1Bits;
5986572Sgblack@eecs.umich.edu                    } else {
5996572Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6006572Sgblack@eecs.umich.edu                    }
6016572Sgblack@eecs.umich.edu                } else {
6026572Sgblack@eecs.umich.edu                    if (arg1Bits < arg2Bits) {
6036572Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6046572Sgblack@eecs.umich.edu                    } else {
6056572Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6066572Sgblack@eecs.umich.edu                    }
6076572Sgblack@eecs.umich.edu                }
6086572Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
6096572Sgblack@eecs.umich.edu            }
6108588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
6116572Sgblack@eecs.umich.edu        '''
6126572Sgblack@eecs.umich.edu
6136574Sgblack@eecs.umich.edu    class Mmaxi(MediaOp):
6146574Sgblack@eecs.umich.edu        code = '''
6156574Sgblack@eecs.umich.edu
6166574Sgblack@eecs.umich.edu            assert(srcSize == destSize);
6176574Sgblack@eecs.umich.edu            int size = srcSize;
6186574Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6196799Sgblack@eecs.umich.edu            int items = numItems(size);
6208588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
6216574Sgblack@eecs.umich.edu
6226574Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6236574Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6246574Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6258588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
6266574Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
6276742Svince@csl.cornell.edu                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
6288588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
6296574Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
6306742Svince@csl.cornell.edu                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
6316574Sgblack@eecs.umich.edu                uint64_t resBits;
6326574Sgblack@eecs.umich.edu
6336801Sgblack@eecs.umich.edu                if (signedOp()) {
6346574Sgblack@eecs.umich.edu                    if (arg1 > arg2) {
6356574Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6366574Sgblack@eecs.umich.edu                    } else {
6376574Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6386574Sgblack@eecs.umich.edu                    }
6396574Sgblack@eecs.umich.edu                } else {
6406574Sgblack@eecs.umich.edu                    if (arg1Bits > arg2Bits) {
6416574Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6426574Sgblack@eecs.umich.edu                    } else {
6436574Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6446574Sgblack@eecs.umich.edu                    }
6456574Sgblack@eecs.umich.edu                }
6466574Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
6476574Sgblack@eecs.umich.edu            }
6488588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
6496574Sgblack@eecs.umich.edu        '''
6506574Sgblack@eecs.umich.edu
6516552Sgblack@eecs.umich.edu    class Msqrt(MediaOp):
6526552Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
6536552Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
6546552Sgblack@eecs.umich.edu            super(Msqrt, self).__init__(dest, src,\
6556552Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
6566552Sgblack@eecs.umich.edu        code = '''
6576552Sgblack@eecs.umich.edu            union floatInt
6586552Sgblack@eecs.umich.edu            {
6596552Sgblack@eecs.umich.edu                float f;
6606552Sgblack@eecs.umich.edu                uint32_t i;
6616552Sgblack@eecs.umich.edu            };
6626552Sgblack@eecs.umich.edu            union doubleInt
6636552Sgblack@eecs.umich.edu            {
6646552Sgblack@eecs.umich.edu                double d;
6656552Sgblack@eecs.umich.edu                uint64_t i;
6666552Sgblack@eecs.umich.edu            };
6676552Sgblack@eecs.umich.edu
6686552Sgblack@eecs.umich.edu            assert(srcSize == destSize);
6696552Sgblack@eecs.umich.edu            int size = srcSize;
6706552Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6716552Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
6726799Sgblack@eecs.umich.edu            int items = numItems(size);
6738588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
6746552Sgblack@eecs.umich.edu
6756552Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6766552Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6776552Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6788588Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
6796552Sgblack@eecs.umich.edu
6806552Sgblack@eecs.umich.edu                if (size == 4) {
6816552Sgblack@eecs.umich.edu                    floatInt fi;
6826552Sgblack@eecs.umich.edu                    fi.i = argBits;
6836552Sgblack@eecs.umich.edu                    fi.f = sqrt(fi.f);
6846552Sgblack@eecs.umich.edu                    argBits = fi.i;
6856552Sgblack@eecs.umich.edu                } else {
6866552Sgblack@eecs.umich.edu                    doubleInt di;
6876552Sgblack@eecs.umich.edu                    di.i = argBits;
6886552Sgblack@eecs.umich.edu                    di.d = sqrt(di.d);
6896552Sgblack@eecs.umich.edu                    argBits = di.i;
6906552Sgblack@eecs.umich.edu                }
6916552Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, argBits);
6926552Sgblack@eecs.umich.edu            }
6938588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
6946552Sgblack@eecs.umich.edu        '''
6956554Sgblack@eecs.umich.edu
69611160Ssteve.reinhardt@amd.com    # compute approximate reciprocal --- single-precision only
69711160Ssteve.reinhardt@amd.com    class Mrcp(MediaOp):
69811160Ssteve.reinhardt@amd.com        def __init__(self, dest, src, \
69911160Ssteve.reinhardt@amd.com                size = None, destSize = None, srcSize = None, ext = None):
70011160Ssteve.reinhardt@amd.com            super(Mrcp, self).__init__(dest, src,\
70111160Ssteve.reinhardt@amd.com                    "InstRegIndex(0)", size, destSize, srcSize, ext)
70211160Ssteve.reinhardt@amd.com        code = '''
70311160Ssteve.reinhardt@amd.com            union floatInt
70411160Ssteve.reinhardt@amd.com            {
70511160Ssteve.reinhardt@amd.com                float f;
70611160Ssteve.reinhardt@amd.com                uint32_t i;
70711160Ssteve.reinhardt@amd.com            };
70811160Ssteve.reinhardt@amd.com
70911160Ssteve.reinhardt@amd.com            assert(srcSize == 4);  // ISA defines single-precision only
71011160Ssteve.reinhardt@amd.com            assert(srcSize == destSize);
71111160Ssteve.reinhardt@amd.com            const int size = 4;
71211160Ssteve.reinhardt@amd.com            const int sizeBits = size * 8;
71311160Ssteve.reinhardt@amd.com            int items = numItems(size);
71411160Ssteve.reinhardt@amd.com            uint64_t result = FpDestReg_uqw;
71511160Ssteve.reinhardt@amd.com
71611160Ssteve.reinhardt@amd.com            for (int i = 0; i < items; i++) {
71711160Ssteve.reinhardt@amd.com                int hiIndex = (i + 1) * sizeBits - 1;
71811160Ssteve.reinhardt@amd.com                int loIndex = (i + 0) * sizeBits;
71911160Ssteve.reinhardt@amd.com                uint64_t argBits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
72011160Ssteve.reinhardt@amd.com
72111160Ssteve.reinhardt@amd.com                floatInt fi;
72211160Ssteve.reinhardt@amd.com                fi.i = argBits;
72311160Ssteve.reinhardt@amd.com                // This is more accuracy than HW provides, but oh well
72411160Ssteve.reinhardt@amd.com                fi.f = 1.0 / fi.f;
72511160Ssteve.reinhardt@amd.com                argBits = fi.i;
72611160Ssteve.reinhardt@amd.com                result = insertBits(result, hiIndex, loIndex, argBits);
72711160Ssteve.reinhardt@amd.com            }
72811160Ssteve.reinhardt@amd.com            FpDestReg_uqw = result;
72911160Ssteve.reinhardt@amd.com        '''
73011160Ssteve.reinhardt@amd.com
7316554Sgblack@eecs.umich.edu    class Maddf(MediaOp):
7326554Sgblack@eecs.umich.edu        code = '''
7336554Sgblack@eecs.umich.edu            union floatInt
7346554Sgblack@eecs.umich.edu            {
7356554Sgblack@eecs.umich.edu                float f;
7366554Sgblack@eecs.umich.edu                uint32_t i;
7376554Sgblack@eecs.umich.edu            };
7386554Sgblack@eecs.umich.edu            union doubleInt
7396554Sgblack@eecs.umich.edu            {
7406554Sgblack@eecs.umich.edu                double d;
7416554Sgblack@eecs.umich.edu                uint64_t i;
7426554Sgblack@eecs.umich.edu            };
7436554Sgblack@eecs.umich.edu
7446554Sgblack@eecs.umich.edu            assert(srcSize == destSize);
7456554Sgblack@eecs.umich.edu            int size = srcSize;
7466554Sgblack@eecs.umich.edu            int sizeBits = size * 8;
7476554Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
7486799Sgblack@eecs.umich.edu            int items = numItems(size);
7498588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
7506554Sgblack@eecs.umich.edu
7516554Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
7526554Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
7536554Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
7548588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
7558588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
7566554Sgblack@eecs.umich.edu                uint64_t resBits;
7576554Sgblack@eecs.umich.edu
7586554Sgblack@eecs.umich.edu                if (size == 4) {
7596554Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
7606554Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7616554Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7626554Sgblack@eecs.umich.edu                    res.f = arg1.f + arg2.f;
7636554Sgblack@eecs.umich.edu                    resBits = res.i;
7646554Sgblack@eecs.umich.edu                } else {
7656554Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
7666554Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7676554Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7686554Sgblack@eecs.umich.edu                    res.d = arg1.d + arg2.d;
7696554Sgblack@eecs.umich.edu                    resBits = res.i;
7706554Sgblack@eecs.umich.edu                }
7716554Sgblack@eecs.umich.edu
7726554Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
7736554Sgblack@eecs.umich.edu            }
7748588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
7756554Sgblack@eecs.umich.edu        '''
7766556Sgblack@eecs.umich.edu
7776556Sgblack@eecs.umich.edu    class Msubf(MediaOp):
7786556Sgblack@eecs.umich.edu        code = '''
7796556Sgblack@eecs.umich.edu            union floatInt
7806556Sgblack@eecs.umich.edu            {
7816556Sgblack@eecs.umich.edu                float f;
7826556Sgblack@eecs.umich.edu                uint32_t i;
7836556Sgblack@eecs.umich.edu            };
7846556Sgblack@eecs.umich.edu            union doubleInt
7856556Sgblack@eecs.umich.edu            {
7866556Sgblack@eecs.umich.edu                double d;
7876556Sgblack@eecs.umich.edu                uint64_t i;
7886556Sgblack@eecs.umich.edu            };
7896556Sgblack@eecs.umich.edu
7906556Sgblack@eecs.umich.edu            assert(srcSize == destSize);
7916556Sgblack@eecs.umich.edu            int size = srcSize;
7926556Sgblack@eecs.umich.edu            int sizeBits = size * 8;
7936556Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
7946799Sgblack@eecs.umich.edu            int items = numItems(size);
7958588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
7966556Sgblack@eecs.umich.edu
7976556Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
7986556Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
7996556Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8008588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
8018588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
8026556Sgblack@eecs.umich.edu                uint64_t resBits;
8036556Sgblack@eecs.umich.edu
8046556Sgblack@eecs.umich.edu                if (size == 4) {
8056556Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
8066556Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8076556Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8086556Sgblack@eecs.umich.edu                    res.f = arg1.f - arg2.f;
8096556Sgblack@eecs.umich.edu                    resBits = res.i;
8106556Sgblack@eecs.umich.edu                } else {
8116556Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
8126556Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8136556Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8146556Sgblack@eecs.umich.edu                    res.d = arg1.d - arg2.d;
8156556Sgblack@eecs.umich.edu                    resBits = res.i;
8166556Sgblack@eecs.umich.edu                }
8176556Sgblack@eecs.umich.edu
8186556Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
8196556Sgblack@eecs.umich.edu            }
8208588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
8216556Sgblack@eecs.umich.edu        '''
8226558Sgblack@eecs.umich.edu
8236558Sgblack@eecs.umich.edu    class Mmulf(MediaOp):
8246558Sgblack@eecs.umich.edu        code = '''
8256558Sgblack@eecs.umich.edu            union floatInt
8266558Sgblack@eecs.umich.edu            {
8276558Sgblack@eecs.umich.edu                float f;
8286558Sgblack@eecs.umich.edu                uint32_t i;
8296558Sgblack@eecs.umich.edu            };
8306558Sgblack@eecs.umich.edu            union doubleInt
8316558Sgblack@eecs.umich.edu            {
8326558Sgblack@eecs.umich.edu                double d;
8336558Sgblack@eecs.umich.edu                uint64_t i;
8346558Sgblack@eecs.umich.edu            };
8356558Sgblack@eecs.umich.edu
8366558Sgblack@eecs.umich.edu            assert(srcSize == destSize);
8376558Sgblack@eecs.umich.edu            int size = srcSize;
8386558Sgblack@eecs.umich.edu            int sizeBits = size * 8;
8396558Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
8406799Sgblack@eecs.umich.edu            int items = numItems(size);
8418588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
8426558Sgblack@eecs.umich.edu
8436558Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8446558Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
8456558Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8468588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
8478588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
8486558Sgblack@eecs.umich.edu                uint64_t resBits;
8496558Sgblack@eecs.umich.edu
8506558Sgblack@eecs.umich.edu                if (size == 4) {
8516558Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
8526558Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8536558Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8546558Sgblack@eecs.umich.edu                    res.f = arg1.f * arg2.f;
8556558Sgblack@eecs.umich.edu                    resBits = res.i;
8566558Sgblack@eecs.umich.edu                } else {
8576558Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
8586558Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8596558Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8606558Sgblack@eecs.umich.edu                    res.d = arg1.d * arg2.d;
8616558Sgblack@eecs.umich.edu                    resBits = res.i;
8626558Sgblack@eecs.umich.edu                }
8636558Sgblack@eecs.umich.edu
8646558Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
8656558Sgblack@eecs.umich.edu            }
8668588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
8676558Sgblack@eecs.umich.edu        '''
8686560Sgblack@eecs.umich.edu
8696560Sgblack@eecs.umich.edu    class Mdivf(MediaOp):
8706560Sgblack@eecs.umich.edu        code = '''
8716560Sgblack@eecs.umich.edu            union floatInt
8726560Sgblack@eecs.umich.edu            {
8736560Sgblack@eecs.umich.edu                float f;
8746560Sgblack@eecs.umich.edu                uint32_t i;
8756560Sgblack@eecs.umich.edu            };
8766560Sgblack@eecs.umich.edu            union doubleInt
8776560Sgblack@eecs.umich.edu            {
8786560Sgblack@eecs.umich.edu                double d;
8796560Sgblack@eecs.umich.edu                uint64_t i;
8806560Sgblack@eecs.umich.edu            };
8816560Sgblack@eecs.umich.edu
8826560Sgblack@eecs.umich.edu            assert(srcSize == destSize);
8836560Sgblack@eecs.umich.edu            int size = srcSize;
8846560Sgblack@eecs.umich.edu            int sizeBits = size * 8;
8856560Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
8866799Sgblack@eecs.umich.edu            int items = numItems(size);
8878588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
8886560Sgblack@eecs.umich.edu
8896560Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8906560Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
8916560Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8928588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
8938588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
8946560Sgblack@eecs.umich.edu                uint64_t resBits;
8956560Sgblack@eecs.umich.edu
8966560Sgblack@eecs.umich.edu                if (size == 4) {
8976560Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
8986560Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8996560Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
9006560Sgblack@eecs.umich.edu                    res.f = arg1.f / arg2.f;
9016560Sgblack@eecs.umich.edu                    resBits = res.i;
9026560Sgblack@eecs.umich.edu                } else {
9036560Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
9046560Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
9056560Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
9066560Sgblack@eecs.umich.edu                    res.d = arg1.d / arg2.d;
9076560Sgblack@eecs.umich.edu                    resBits = res.i;
9086560Sgblack@eecs.umich.edu                }
9096560Sgblack@eecs.umich.edu
9106560Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
9116560Sgblack@eecs.umich.edu            }
9128588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
9136560Sgblack@eecs.umich.edu        '''
9146562Sgblack@eecs.umich.edu
9156570Sgblack@eecs.umich.edu    class Maddi(MediaOp):
9166570Sgblack@eecs.umich.edu        code = '''
9176570Sgblack@eecs.umich.edu            assert(srcSize == destSize);
9186570Sgblack@eecs.umich.edu            int size = srcSize;
9196570Sgblack@eecs.umich.edu            int sizeBits = size * 8;
9206799Sgblack@eecs.umich.edu            int items = numItems(size);
9218588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
9226570Sgblack@eecs.umich.edu
9236570Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9246570Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
9256570Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
9268588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
9278588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
9286570Sgblack@eecs.umich.edu                uint64_t resBits = arg1Bits + arg2Bits;
92911320Ssteve.reinhardt@amd.com
9306570Sgblack@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 (findCarry(sizeBits, resBits, arg1Bits, arg2Bits))
9436801Sgblack@eecs.umich.edu                            resBits = mask(sizeBits);
9446570Sgblack@eecs.umich.edu                    }
9456570Sgblack@eecs.umich.edu                }
9466570Sgblack@eecs.umich.edu
9476570Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
9486570Sgblack@eecs.umich.edu            }
9498588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
9506570Sgblack@eecs.umich.edu        '''
9516570Sgblack@eecs.umich.edu
9526579Sgblack@eecs.umich.edu    class Msubi(MediaOp):
9536579Sgblack@eecs.umich.edu        code = '''
9546579Sgblack@eecs.umich.edu            assert(srcSize == destSize);
9556579Sgblack@eecs.umich.edu            int size = srcSize;
9566579Sgblack@eecs.umich.edu            int sizeBits = size * 8;
9576799Sgblack@eecs.umich.edu            int items = numItems(size);
9588588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
9596579Sgblack@eecs.umich.edu
9606579Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9616579Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
9626579Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
9638588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
9648588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
9656579Sgblack@eecs.umich.edu                uint64_t resBits = arg1Bits - arg2Bits;
96611320Ssteve.reinhardt@amd.com
9676579Sgblack@eecs.umich.edu                if (ext & 0x2) {
9686801Sgblack@eecs.umich.edu                    if (signedOp()) {
9696801Sgblack@eecs.umich.edu                        int arg1Sign = bits(arg1Bits, sizeBits - 1);
9706801Sgblack@eecs.umich.edu                        int arg2Sign = !bits(arg2Bits, sizeBits - 1);
9716801Sgblack@eecs.umich.edu                        int resSign = bits(resBits, sizeBits - 1);
9726801Sgblack@eecs.umich.edu                        if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
9736801Sgblack@eecs.umich.edu                            if (resSign == 0)
9746801Sgblack@eecs.umich.edu                                resBits = (ULL(1) << (sizeBits - 1));
9756801Sgblack@eecs.umich.edu                            else
9766801Sgblack@eecs.umich.edu                                resBits = mask(sizeBits - 1);
9776801Sgblack@eecs.umich.edu                        }
9786801Sgblack@eecs.umich.edu                    } else {
9796801Sgblack@eecs.umich.edu                        if (arg2Bits > arg1Bits) {
9806801Sgblack@eecs.umich.edu                            resBits = 0;
9816801Sgblack@eecs.umich.edu                        } else if (!findCarry(sizeBits, resBits,
9826801Sgblack@eecs.umich.edu                                             arg1Bits, ~arg2Bits)) {
9836801Sgblack@eecs.umich.edu                            resBits = mask(sizeBits);
9846801Sgblack@eecs.umich.edu                        }
9856579Sgblack@eecs.umich.edu                    }
9866579Sgblack@eecs.umich.edu                }
9876579Sgblack@eecs.umich.edu
9886579Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
9896579Sgblack@eecs.umich.edu            }
9908588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
9916579Sgblack@eecs.umich.edu        '''
9926579Sgblack@eecs.umich.edu
9936577Sgblack@eecs.umich.edu    class Mmuli(MediaOp):
9946577Sgblack@eecs.umich.edu        code = '''
9956577Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
9966577Sgblack@eecs.umich.edu            int destBits = destSize * 8;
9976577Sgblack@eecs.umich.edu            assert(destBits <= 64);
9986577Sgblack@eecs.umich.edu            assert(destSize >= srcSize);
9996799Sgblack@eecs.umich.edu            int items = numItems(destSize);
10008588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
10016577Sgblack@eecs.umich.edu
10026577Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10036585Sgblack@eecs.umich.edu                int offset = 0;
10046585Sgblack@eecs.umich.edu                if (ext & 16) {
10056585Sgblack@eecs.umich.edu                    if (ext & 32)
10066585Sgblack@eecs.umich.edu                        offset = i * (destBits - srcBits);
10076585Sgblack@eecs.umich.edu                    else
10086585Sgblack@eecs.umich.edu                        offset = i * (destBits - srcBits) + srcBits;
10096585Sgblack@eecs.umich.edu                }
10106585Sgblack@eecs.umich.edu                int srcHiIndex = (i + 1) * srcBits - 1 + offset;
10116585Sgblack@eecs.umich.edu                int srcLoIndex = (i + 0) * srcBits + offset;
10128588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex);
10138588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, srcHiIndex, srcLoIndex);
10146577Sgblack@eecs.umich.edu                uint64_t resBits;
10156577Sgblack@eecs.umich.edu
10166801Sgblack@eecs.umich.edu                if (signedOp()) {
10176577Sgblack@eecs.umich.edu                    int64_t arg1 = arg1Bits |
10186742Svince@csl.cornell.edu                        (0 - (arg1Bits & (ULL(1) << (srcBits - 1))));
10196577Sgblack@eecs.umich.edu                    int64_t arg2 = arg2Bits |
10206742Svince@csl.cornell.edu                        (0 - (arg2Bits & (ULL(1) << (srcBits - 1))));
10216577Sgblack@eecs.umich.edu                    resBits = (uint64_t)(arg1 * arg2);
10226577Sgblack@eecs.umich.edu                } else {
10236577Sgblack@eecs.umich.edu                    resBits = arg1Bits * arg2Bits;
10246577Sgblack@eecs.umich.edu                }
10256577Sgblack@eecs.umich.edu
10266577Sgblack@eecs.umich.edu                if (ext & 0x4)
10276742Svince@csl.cornell.edu                    resBits += (ULL(1) << (destBits - 1));
102811320Ssteve.reinhardt@amd.com
10296800Sgblack@eecs.umich.edu                if (multHi())
10306577Sgblack@eecs.umich.edu                    resBits >>= destBits;
10316577Sgblack@eecs.umich.edu
10326577Sgblack@eecs.umich.edu                int destHiIndex = (i + 1) * destBits - 1;
10336577Sgblack@eecs.umich.edu                int destLoIndex = (i + 0) * destBits;
10346577Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, resBits);
10356577Sgblack@eecs.umich.edu            }
10368588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
10376577Sgblack@eecs.umich.edu        '''
10386577Sgblack@eecs.umich.edu
10396587Sgblack@eecs.umich.edu    class Mavg(MediaOp):
10406587Sgblack@eecs.umich.edu        code = '''
10416587Sgblack@eecs.umich.edu            assert(srcSize == destSize);
10426587Sgblack@eecs.umich.edu            int size = srcSize;
10436587Sgblack@eecs.umich.edu            int sizeBits = size * 8;
10446799Sgblack@eecs.umich.edu            int items = numItems(size);
10458588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
10466587Sgblack@eecs.umich.edu
10476587Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10486587Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
10496587Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
10508588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
10518588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
10526587Sgblack@eecs.umich.edu                uint64_t resBits = (arg1Bits + arg2Bits + 1) / 2;
105311320Ssteve.reinhardt@amd.com
10546587Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
10556587Sgblack@eecs.umich.edu            }
10568588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
10576587Sgblack@eecs.umich.edu        '''
10586587Sgblack@eecs.umich.edu
10596581Sgblack@eecs.umich.edu    class Msad(MediaOp):
10606581Sgblack@eecs.umich.edu        code = '''
10616581Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
10626581Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / srcSize;
10636581Sgblack@eecs.umich.edu
10646581Sgblack@eecs.umich.edu            uint64_t sum = 0;
10656581Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10666581Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * srcBits - 1;
10676581Sgblack@eecs.umich.edu                int loIndex = (i + 0) * srcBits;
10688588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
10698588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
10706581Sgblack@eecs.umich.edu                int64_t resBits = arg1Bits - arg2Bits;
10716581Sgblack@eecs.umich.edu                if (resBits < 0)
10726581Sgblack@eecs.umich.edu                    resBits = -resBits;
10736581Sgblack@eecs.umich.edu                sum += resBits;
10746581Sgblack@eecs.umich.edu            }
10758588Sgblack@eecs.umich.edu            FpDestReg_uqw = sum & mask(destSize * 8);
10766581Sgblack@eecs.umich.edu        '''
10776581Sgblack@eecs.umich.edu
10786583Sgblack@eecs.umich.edu    class Msrl(MediaOp):
10796583Sgblack@eecs.umich.edu        code = '''
10806583Sgblack@eecs.umich.edu
10816583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
10826583Sgblack@eecs.umich.edu            int size = srcSize;
10836583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
10846799Sgblack@eecs.umich.edu            int items = numItems(size);
10858588Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2_uqw;
10868588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
10876583Sgblack@eecs.umich.edu
10886583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10896583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
10906583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
10918588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
10926583Sgblack@eecs.umich.edu                uint64_t resBits;
10936583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
10946583Sgblack@eecs.umich.edu                    resBits = 0;
10956583Sgblack@eecs.umich.edu                } else {
10966583Sgblack@eecs.umich.edu                    resBits = (arg1Bits >> shiftAmt) &
10976583Sgblack@eecs.umich.edu                        mask(sizeBits - shiftAmt);
10986583Sgblack@eecs.umich.edu                }
10996583Sgblack@eecs.umich.edu
11006583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
11016583Sgblack@eecs.umich.edu            }
11028588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
11036583Sgblack@eecs.umich.edu        '''
11046583Sgblack@eecs.umich.edu
11056583Sgblack@eecs.umich.edu    class Msra(MediaOp):
11066583Sgblack@eecs.umich.edu        code = '''
11076583Sgblack@eecs.umich.edu
11086583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
11096583Sgblack@eecs.umich.edu            int size = srcSize;
11106583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
11116799Sgblack@eecs.umich.edu            int items = numItems(size);
11128588Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2_uqw;
11138588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
11146583Sgblack@eecs.umich.edu
11156583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
11166583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
11176583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
11188588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
11196583Sgblack@eecs.umich.edu                uint64_t resBits;
11206583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
11216583Sgblack@eecs.umich.edu                    if (bits(arg1Bits, sizeBits - 1))
11226583Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
11236583Sgblack@eecs.umich.edu                    else
11246583Sgblack@eecs.umich.edu                        resBits = 0;
11256583Sgblack@eecs.umich.edu                } else {
11266583Sgblack@eecs.umich.edu                    resBits = (arg1Bits >> shiftAmt);
11276583Sgblack@eecs.umich.edu                    resBits = resBits |
11286742Svince@csl.cornell.edu                        (0 - (resBits & (ULL(1) << (sizeBits - 1 - shiftAmt))));
11296583Sgblack@eecs.umich.edu                }
11306583Sgblack@eecs.umich.edu
11316583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
11326583Sgblack@eecs.umich.edu            }
11338588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
11346583Sgblack@eecs.umich.edu        '''
11356583Sgblack@eecs.umich.edu
11366583Sgblack@eecs.umich.edu    class Msll(MediaOp):
11376583Sgblack@eecs.umich.edu        code = '''
11386583Sgblack@eecs.umich.edu
11396583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
11406583Sgblack@eecs.umich.edu            int size = srcSize;
11416583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
11426799Sgblack@eecs.umich.edu            int items = numItems(size);
11438588Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2_uqw;
11448588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
11456583Sgblack@eecs.umich.edu
11466583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
11476583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
11486583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
11498588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
11506583Sgblack@eecs.umich.edu                uint64_t resBits;
11516583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
11526583Sgblack@eecs.umich.edu                    resBits = 0;
11536583Sgblack@eecs.umich.edu                } else {
11546583Sgblack@eecs.umich.edu                    resBits = (arg1Bits << shiftAmt);
11556583Sgblack@eecs.umich.edu                }
11566583Sgblack@eecs.umich.edu
11576583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
11586583Sgblack@eecs.umich.edu            }
11598588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
11606583Sgblack@eecs.umich.edu        '''
11616583Sgblack@eecs.umich.edu
11626605Sgblack@eecs.umich.edu    class Cvtf2i(MediaOp):
11636605Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
11646605Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
11656605Sgblack@eecs.umich.edu            super(Cvtf2i, self).__init__(dest, src,\
11666605Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
11676605Sgblack@eecs.umich.edu        code = '''
11686605Sgblack@eecs.umich.edu            union floatInt
11696605Sgblack@eecs.umich.edu            {
11706605Sgblack@eecs.umich.edu                float f;
11716605Sgblack@eecs.umich.edu                uint32_t i;
11726605Sgblack@eecs.umich.edu            };
11736605Sgblack@eecs.umich.edu            union doubleInt
11746605Sgblack@eecs.umich.edu            {
11756605Sgblack@eecs.umich.edu                double d;
11766605Sgblack@eecs.umich.edu                uint64_t i;
11776605Sgblack@eecs.umich.edu            };
11786605Sgblack@eecs.umich.edu
11796605Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
11806605Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
11816605Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
11826605Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
11836605Sgblack@eecs.umich.edu            int items;
11846605Sgblack@eecs.umich.edu            int srcStart = 0;
11856605Sgblack@eecs.umich.edu            int destStart = 0;
11866605Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
11876799Sgblack@eecs.umich.edu                items = numItems(srcSize);
11886605Sgblack@eecs.umich.edu                if (ext & 0x2)
11896605Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
11906605Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
11916799Sgblack@eecs.umich.edu                items = numItems(destSize);
11926605Sgblack@eecs.umich.edu                if (ext & 0x2)
11936605Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
11946605Sgblack@eecs.umich.edu            } else {
11956799Sgblack@eecs.umich.edu                items = numItems(destSize);
11966605Sgblack@eecs.umich.edu            }
11978588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
11986605Sgblack@eecs.umich.edu
11996605Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
12006605Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
12016605Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
12028588Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex);
12036605Sgblack@eecs.umich.edu                double arg;
12046605Sgblack@eecs.umich.edu
12056605Sgblack@eecs.umich.edu                if (srcSize == 4) {
12066605Sgblack@eecs.umich.edu                    floatInt fi;
12076605Sgblack@eecs.umich.edu                    fi.i = argBits;
12086605Sgblack@eecs.umich.edu                    arg = fi.f;
12096605Sgblack@eecs.umich.edu                } else {
12106605Sgblack@eecs.umich.edu                    doubleInt di;
12116605Sgblack@eecs.umich.edu                    di.i = argBits;
12126605Sgblack@eecs.umich.edu                    arg = di.d;
12136605Sgblack@eecs.umich.edu                }
12146605Sgblack@eecs.umich.edu
12156605Sgblack@eecs.umich.edu                if (ext & 0x4) {
12166605Sgblack@eecs.umich.edu                    if (arg >= 0)
12176605Sgblack@eecs.umich.edu                        arg += 0.5;
12186605Sgblack@eecs.umich.edu                    else
12196605Sgblack@eecs.umich.edu                        arg -= 0.5;
12206605Sgblack@eecs.umich.edu                }
12216605Sgblack@eecs.umich.edu
12226605Sgblack@eecs.umich.edu                if (destSize == 4) {
122311711Santhony.gutierrez@amd.com                    int32_t i_arg = (int32_t)arg;
122411711Santhony.gutierrez@amd.com                    argBits = *((uint32_t*)&i_arg);
12256605Sgblack@eecs.umich.edu                } else {
122611711Santhony.gutierrez@amd.com                    int64_t i_arg = (int64_t)arg;
122711711Santhony.gutierrez@amd.com                    argBits = *((uint64_t*)&i_arg);
12286605Sgblack@eecs.umich.edu                }
12296605Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
12306605Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
12316605Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
12326605Sgblack@eecs.umich.edu            }
12338588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
12346605Sgblack@eecs.umich.edu        '''
12356605Sgblack@eecs.umich.edu
12366562Sgblack@eecs.umich.edu    class Cvti2f(MediaOp):
12376562Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
12386562Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
12396562Sgblack@eecs.umich.edu            super(Cvti2f, self).__init__(dest, src,\
12406562Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
12416562Sgblack@eecs.umich.edu        code = '''
12426562Sgblack@eecs.umich.edu            union floatInt
12436562Sgblack@eecs.umich.edu            {
12446562Sgblack@eecs.umich.edu                float f;
12456562Sgblack@eecs.umich.edu                uint32_t i;
12466562Sgblack@eecs.umich.edu            };
12476562Sgblack@eecs.umich.edu            union doubleInt
12486562Sgblack@eecs.umich.edu            {
12496562Sgblack@eecs.umich.edu                double d;
12506562Sgblack@eecs.umich.edu                uint64_t i;
12516562Sgblack@eecs.umich.edu            };
12526562Sgblack@eecs.umich.edu
12536562Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
12546562Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
12556562Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
12566562Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
12576562Sgblack@eecs.umich.edu            int items;
12586562Sgblack@eecs.umich.edu            int srcStart = 0;
12596562Sgblack@eecs.umich.edu            int destStart = 0;
12606562Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
12616799Sgblack@eecs.umich.edu                items = numItems(srcSize);
12626562Sgblack@eecs.umich.edu                if (ext & 0x2)
12636562Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
12646562Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
12656799Sgblack@eecs.umich.edu                items = numItems(destSize);
12666562Sgblack@eecs.umich.edu                if (ext & 0x2)
12676562Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
12686562Sgblack@eecs.umich.edu            } else {
12696799Sgblack@eecs.umich.edu                items = numItems(destSize);
12706562Sgblack@eecs.umich.edu            }
12718588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
12726562Sgblack@eecs.umich.edu
12736562Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
12746562Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
12756562Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
12768588Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex);
12776742Svince@csl.cornell.edu
12787081Sgblack@eecs.umich.edu                int64_t sArg = argBits |
12797081Sgblack@eecs.umich.edu                    (0 - (argBits & (ULL(1) << (srcSizeBits - 1))));
12806562Sgblack@eecs.umich.edu                double arg = sArg;
12816562Sgblack@eecs.umich.edu
12826562Sgblack@eecs.umich.edu                if (destSize == 4) {
12836562Sgblack@eecs.umich.edu                    floatInt fi;
12846562Sgblack@eecs.umich.edu                    fi.f = arg;
12856562Sgblack@eecs.umich.edu                    argBits = fi.i;
12866562Sgblack@eecs.umich.edu                } else {
12876562Sgblack@eecs.umich.edu                    doubleInt di;
12886562Sgblack@eecs.umich.edu                    di.d = arg;
12896562Sgblack@eecs.umich.edu                    argBits = di.i;
12906562Sgblack@eecs.umich.edu                }
12916562Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
12926562Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
12936562Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
12946562Sgblack@eecs.umich.edu            }
12958588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
12966562Sgblack@eecs.umich.edu        '''
12976566Sgblack@eecs.umich.edu
12986568Sgblack@eecs.umich.edu    class Cvtf2f(MediaOp):
12996568Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
13006568Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
13016568Sgblack@eecs.umich.edu            super(Cvtf2f, self).__init__(dest, src,\
13026568Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
13036568Sgblack@eecs.umich.edu        code = '''
13046568Sgblack@eecs.umich.edu            union floatInt
13056568Sgblack@eecs.umich.edu            {
13066568Sgblack@eecs.umich.edu                float f;
13076568Sgblack@eecs.umich.edu                uint32_t i;
13086568Sgblack@eecs.umich.edu            };
13096568Sgblack@eecs.umich.edu            union doubleInt
13106568Sgblack@eecs.umich.edu            {
13116568Sgblack@eecs.umich.edu                double d;
13126568Sgblack@eecs.umich.edu                uint64_t i;
13136568Sgblack@eecs.umich.edu            };
13146568Sgblack@eecs.umich.edu
13156568Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
13166568Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
13176568Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
13186568Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
13196568Sgblack@eecs.umich.edu            int items;
13206568Sgblack@eecs.umich.edu            int srcStart = 0;
13216568Sgblack@eecs.umich.edu            int destStart = 0;
13226568Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
13236799Sgblack@eecs.umich.edu                items = numItems(srcSize);
13246568Sgblack@eecs.umich.edu                if (ext & 0x2)
13256568Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
13266568Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
13276799Sgblack@eecs.umich.edu                items = numItems(destSize);
13286568Sgblack@eecs.umich.edu                if (ext & 0x2)
13296568Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
13306568Sgblack@eecs.umich.edu            } else {
13316799Sgblack@eecs.umich.edu                items = numItems(destSize);
13326568Sgblack@eecs.umich.edu            }
13338588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
13346568Sgblack@eecs.umich.edu
13356568Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
13366568Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
13376568Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
13388588Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex);
13396568Sgblack@eecs.umich.edu                double arg;
13406568Sgblack@eecs.umich.edu
13416568Sgblack@eecs.umich.edu                if (srcSize == 4) {
13426568Sgblack@eecs.umich.edu                    floatInt fi;
13436568Sgblack@eecs.umich.edu                    fi.i = argBits;
13446568Sgblack@eecs.umich.edu                    arg = fi.f;
13456568Sgblack@eecs.umich.edu                } else {
13466568Sgblack@eecs.umich.edu                    doubleInt di;
13476568Sgblack@eecs.umich.edu                    di.i = argBits;
13486568Sgblack@eecs.umich.edu                    arg = di.d;
13496568Sgblack@eecs.umich.edu                }
13506568Sgblack@eecs.umich.edu                if (destSize == 4) {
13516568Sgblack@eecs.umich.edu                    floatInt fi;
13526568Sgblack@eecs.umich.edu                    fi.f = arg;
13536568Sgblack@eecs.umich.edu                    argBits = fi.i;
13546568Sgblack@eecs.umich.edu                } else {
13556568Sgblack@eecs.umich.edu                    doubleInt di;
13566568Sgblack@eecs.umich.edu                    di.d = arg;
13576568Sgblack@eecs.umich.edu                    argBits = di.i;
13586568Sgblack@eecs.umich.edu                }
13596568Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
13606568Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
13616568Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
13626568Sgblack@eecs.umich.edu            }
13638588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
13646568Sgblack@eecs.umich.edu        '''
13656568Sgblack@eecs.umich.edu
13666566Sgblack@eecs.umich.edu    class Mcmpi2r(MediaOp):
13676566Sgblack@eecs.umich.edu        code = '''
13686566Sgblack@eecs.umich.edu            union floatInt
13696566Sgblack@eecs.umich.edu            {
13706566Sgblack@eecs.umich.edu                float f;
13716566Sgblack@eecs.umich.edu                uint32_t i;
13726566Sgblack@eecs.umich.edu            };
13736566Sgblack@eecs.umich.edu            union doubleInt
13746566Sgblack@eecs.umich.edu            {
13756566Sgblack@eecs.umich.edu                double d;
13766566Sgblack@eecs.umich.edu                uint64_t i;
13776566Sgblack@eecs.umich.edu            };
13786566Sgblack@eecs.umich.edu
13796566Sgblack@eecs.umich.edu            assert(srcSize == destSize);
13806566Sgblack@eecs.umich.edu            int size = srcSize;
13816566Sgblack@eecs.umich.edu            int sizeBits = size * 8;
13826799Sgblack@eecs.umich.edu            int items = numItems(size);
13838588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
13846566Sgblack@eecs.umich.edu
13856566Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
13866566Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
13876566Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
13888588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
13896566Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
13906742Svince@csl.cornell.edu                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
13918588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
13926566Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
13936742Svince@csl.cornell.edu                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
13946566Sgblack@eecs.umich.edu
13956566Sgblack@eecs.umich.edu                uint64_t resBits = 0;
13966622Snate@binkert.org                if (((ext & 0x2) == 0 && arg1 == arg2) ||
13976622Snate@binkert.org                    ((ext & 0x2) == 0x2 && arg1 > arg2))
13986566Sgblack@eecs.umich.edu                    resBits = mask(sizeBits);
13996566Sgblack@eecs.umich.edu
14006566Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
14016566Sgblack@eecs.umich.edu            }
14028588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
14036566Sgblack@eecs.umich.edu        '''
14046601Sgblack@eecs.umich.edu
14056603Sgblack@eecs.umich.edu    class Mcmpf2r(MediaOp):
14066603Sgblack@eecs.umich.edu        code = '''
14076603Sgblack@eecs.umich.edu            union floatInt
14086603Sgblack@eecs.umich.edu            {
14096603Sgblack@eecs.umich.edu                float f;
14106603Sgblack@eecs.umich.edu                uint32_t i;
14116603Sgblack@eecs.umich.edu            };
14126603Sgblack@eecs.umich.edu            union doubleInt
14136603Sgblack@eecs.umich.edu            {
14146603Sgblack@eecs.umich.edu                double d;
14156603Sgblack@eecs.umich.edu                uint64_t i;
14166603Sgblack@eecs.umich.edu            };
14176603Sgblack@eecs.umich.edu
14186603Sgblack@eecs.umich.edu            assert(srcSize == destSize);
14196603Sgblack@eecs.umich.edu            int size = srcSize;
14206603Sgblack@eecs.umich.edu            int sizeBits = size * 8;
14216799Sgblack@eecs.umich.edu            int items = numItems(size);
14228588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
14236603Sgblack@eecs.umich.edu
14246603Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
14256603Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
14266603Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
14278588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
14288588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
14296603Sgblack@eecs.umich.edu                double arg1, arg2;
14306603Sgblack@eecs.umich.edu
14316603Sgblack@eecs.umich.edu                if (size == 4) {
14326603Sgblack@eecs.umich.edu                    floatInt fi;
14336603Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
14346603Sgblack@eecs.umich.edu                    arg1 = fi.f;
14356603Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
14366603Sgblack@eecs.umich.edu                    arg2 = fi.f;
14376603Sgblack@eecs.umich.edu                } else {
14386603Sgblack@eecs.umich.edu                    doubleInt di;
14396603Sgblack@eecs.umich.edu                    di.i = arg1Bits;
14406603Sgblack@eecs.umich.edu                    arg1 = di.d;
14416603Sgblack@eecs.umich.edu                    di.i = arg2Bits;
14426603Sgblack@eecs.umich.edu                    arg2 = di.d;
14436603Sgblack@eecs.umich.edu                }
14446603Sgblack@eecs.umich.edu
14456603Sgblack@eecs.umich.edu                uint64_t resBits = 0;
14468946Sandreas.hansson@arm.com                bool nanop = std::isnan(arg1) || std::isnan(arg2);
14476603Sgblack@eecs.umich.edu                switch (ext & mask(3)) {
14486603Sgblack@eecs.umich.edu                  case 0:
14496603Sgblack@eecs.umich.edu                    if (arg1 == arg2 && !nanop)
14506603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14516603Sgblack@eecs.umich.edu                    break;
14526603Sgblack@eecs.umich.edu                  case 1:
14536603Sgblack@eecs.umich.edu                    if (arg1 < arg2 && !nanop)
14546603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14556603Sgblack@eecs.umich.edu                    break;
14566603Sgblack@eecs.umich.edu                  case 2:
14576603Sgblack@eecs.umich.edu                    if (arg1 <= arg2 && !nanop)
14586603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14596603Sgblack@eecs.umich.edu                    break;
14606603Sgblack@eecs.umich.edu                  case 3:
14616603Sgblack@eecs.umich.edu                    if (nanop)
14626603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14636603Sgblack@eecs.umich.edu                    break;
14646603Sgblack@eecs.umich.edu                  case 4:
14656603Sgblack@eecs.umich.edu                    if (arg1 != arg2 || nanop)
14666603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14676603Sgblack@eecs.umich.edu                    break;
14686603Sgblack@eecs.umich.edu                  case 5:
14696603Sgblack@eecs.umich.edu                    if (!(arg1 < arg2) || nanop)
14706603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14716603Sgblack@eecs.umich.edu                    break;
14726603Sgblack@eecs.umich.edu                  case 6:
14736603Sgblack@eecs.umich.edu                    if (!(arg1 <= arg2) || nanop)
14746603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14756603Sgblack@eecs.umich.edu                    break;
14766603Sgblack@eecs.umich.edu                  case 7:
14776603Sgblack@eecs.umich.edu                    if (!nanop)
14786603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14796603Sgblack@eecs.umich.edu                    break;
14806603Sgblack@eecs.umich.edu                };
14816603Sgblack@eecs.umich.edu
14826603Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
14836603Sgblack@eecs.umich.edu            }
14848588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
14856603Sgblack@eecs.umich.edu        '''
14866603Sgblack@eecs.umich.edu
14876601Sgblack@eecs.umich.edu    class Mcmpf2rf(MediaOp):
14886601Sgblack@eecs.umich.edu        def __init__(self, src1, src2,\
14896601Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
14906601Sgblack@eecs.umich.edu            super(Mcmpf2rf, self).__init__("InstRegIndex(0)", src1,\
14916601Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
14926601Sgblack@eecs.umich.edu        code = '''
14936601Sgblack@eecs.umich.edu            union floatInt
14946601Sgblack@eecs.umich.edu            {
14956601Sgblack@eecs.umich.edu                float f;
14966601Sgblack@eecs.umich.edu                uint32_t i;
14976601Sgblack@eecs.umich.edu            };
14986601Sgblack@eecs.umich.edu            union doubleInt
14996601Sgblack@eecs.umich.edu            {
15006601Sgblack@eecs.umich.edu                double d;
15016601Sgblack@eecs.umich.edu                uint64_t i;
15026601Sgblack@eecs.umich.edu            };
15036601Sgblack@eecs.umich.edu
15046601Sgblack@eecs.umich.edu            assert(srcSize == destSize);
15056601Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
15066601Sgblack@eecs.umich.edu            int size = srcSize;
15076601Sgblack@eecs.umich.edu            int sizeBits = size * 8;
15086601Sgblack@eecs.umich.edu
15096601Sgblack@eecs.umich.edu            double arg1, arg2;
15108588Sgblack@eecs.umich.edu            uint64_t arg1Bits = bits(FpSrcReg1_uqw, sizeBits - 1, 0);
15118588Sgblack@eecs.umich.edu            uint64_t arg2Bits = bits(FpSrcReg2_uqw, sizeBits - 1, 0);
15126601Sgblack@eecs.umich.edu            if (size == 4) {
15136601Sgblack@eecs.umich.edu                floatInt fi;
15146601Sgblack@eecs.umich.edu                fi.i = arg1Bits;
15156601Sgblack@eecs.umich.edu                arg1 = fi.f;
15166601Sgblack@eecs.umich.edu                fi.i = arg2Bits;
15176601Sgblack@eecs.umich.edu                arg2 = fi.f;
15186601Sgblack@eecs.umich.edu            } else {
15196601Sgblack@eecs.umich.edu                doubleInt di;
15206601Sgblack@eecs.umich.edu                di.i = arg1Bits;
15216601Sgblack@eecs.umich.edu                arg1 = di.d;
15226601Sgblack@eecs.umich.edu                di.i = arg2Bits;
15236601Sgblack@eecs.umich.edu                arg2 = di.d;
15246601Sgblack@eecs.umich.edu            }
15256601Sgblack@eecs.umich.edu
15266601Sgblack@eecs.umich.edu            //               ZF PF CF
15276601Sgblack@eecs.umich.edu            // Unordered      1  1  1
15286601Sgblack@eecs.umich.edu            // Greater than   0  0  0
15296601Sgblack@eecs.umich.edu            // Less than      0  0  1
15306601Sgblack@eecs.umich.edu            // Equal          1  0  0
15316601Sgblack@eecs.umich.edu            //           OF = SF = AF = 0
15329010Snilay@cs.wisc.edu            ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit);
15339010Snilay@cs.wisc.edu            cfofBits   = cfofBits   & ~(OFBit | CFBit);
15349010Snilay@cs.wisc.edu
15359010Snilay@cs.wisc.edu            if (std::isnan(arg1) || std::isnan(arg2)) {
15369010Snilay@cs.wisc.edu                ccFlagBits = ccFlagBits | (ZFBit | PFBit);
15379010Snilay@cs.wisc.edu                cfofBits = cfofBits | CFBit;
15389010Snilay@cs.wisc.edu            }
15396601Sgblack@eecs.umich.edu            else if(arg1 < arg2)
15409010Snilay@cs.wisc.edu                cfofBits = cfofBits | CFBit;
15416601Sgblack@eecs.umich.edu            else if(arg1 == arg2)
15426601Sgblack@eecs.umich.edu                ccFlagBits = ccFlagBits | ZFBit;
15436601Sgblack@eecs.umich.edu        '''
15449471Snilay@cs.wisc.edu
15459471Snilay@cs.wisc.edu    class Emms(MediaOp):
15469471Snilay@cs.wisc.edu        def __init__(self):
15479471Snilay@cs.wisc.edu            super(Emms, self).__init__('InstRegIndex(MISCREG_FTW)',
154810042Snilay@cs.wisc.edu                    'InstRegIndex(0)', 'InstRegIndex(0)', 2)
15499471Snilay@cs.wisc.edu        code = 'FTW = 0xFFFF;'
15506516Sgblack@eecs.umich.edu}};
1551