mediaop.isa revision 6622
16516Sgblack@eecs.umich.edu/// Copyright (c) 2009 The Regents of The University of Michigan
26516Sgblack@eecs.umich.edu// All rights reserved.
36516Sgblack@eecs.umich.edu//
46516Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
56516Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
66516Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
76516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
86516Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
96516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
106516Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
116516Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
126516Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
136516Sgblack@eecs.umich.edu// this software without specific prior written permission.
146516Sgblack@eecs.umich.edu//
156516Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
166516Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
176516Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
186516Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
196516Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
206516Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
216516Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
226516Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236516Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
246516Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
256516Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266516Sgblack@eecs.umich.edu//
276516Sgblack@eecs.umich.edu// Authors: Gabe Black
286516Sgblack@eecs.umich.edu
296516Sgblack@eecs.umich.edudef template MediaOpExecute {{
306516Sgblack@eecs.umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
316516Sgblack@eecs.umich.edu                Trace::InstRecord *traceData) const
326516Sgblack@eecs.umich.edu        {
336516Sgblack@eecs.umich.edu            Fault fault = NoFault;
346516Sgblack@eecs.umich.edu
356516Sgblack@eecs.umich.edu            %(op_decl)s;
366516Sgblack@eecs.umich.edu            %(op_rd)s;
376516Sgblack@eecs.umich.edu
386516Sgblack@eecs.umich.edu            %(code)s;
396516Sgblack@eecs.umich.edu
406516Sgblack@eecs.umich.edu            //Write the resulting state to the execution context
416516Sgblack@eecs.umich.edu            if(fault == NoFault)
426516Sgblack@eecs.umich.edu            {
436516Sgblack@eecs.umich.edu                %(op_wb)s;
446516Sgblack@eecs.umich.edu            }
456516Sgblack@eecs.umich.edu            return fault;
466516Sgblack@eecs.umich.edu        }
476516Sgblack@eecs.umich.edu}};
486516Sgblack@eecs.umich.edu
496516Sgblack@eecs.umich.edudef template MediaOpRegDeclare {{
506516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
516516Sgblack@eecs.umich.edu    {
526516Sgblack@eecs.umich.edu      protected:
536516Sgblack@eecs.umich.edu        void buildMe();
546516Sgblack@eecs.umich.edu
556516Sgblack@eecs.umich.edu      public:
566516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
576516Sgblack@eecs.umich.edu                const char * instMnem,
586516Sgblack@eecs.umich.edu                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
596516Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
606545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
616516Sgblack@eecs.umich.edu
626516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
636516Sgblack@eecs.umich.edu                const char * instMnem,
646516Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
656545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
666516Sgblack@eecs.umich.edu
676516Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
686516Sgblack@eecs.umich.edu    };
696516Sgblack@eecs.umich.edu}};
706516Sgblack@eecs.umich.edu
716516Sgblack@eecs.umich.edudef template MediaOpImmDeclare {{
726516Sgblack@eecs.umich.edu
736516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
746516Sgblack@eecs.umich.edu    {
756516Sgblack@eecs.umich.edu      protected:
766516Sgblack@eecs.umich.edu        void buildMe();
776516Sgblack@eecs.umich.edu
786516Sgblack@eecs.umich.edu      public:
796516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
806516Sgblack@eecs.umich.edu                const char * instMnem,
816516Sgblack@eecs.umich.edu                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
826516Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
836545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
846516Sgblack@eecs.umich.edu
856516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
866516Sgblack@eecs.umich.edu                const char * instMnem,
876516Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
886545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
896516Sgblack@eecs.umich.edu
906516Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
916516Sgblack@eecs.umich.edu    };
926516Sgblack@eecs.umich.edu}};
936516Sgblack@eecs.umich.edu
946516Sgblack@eecs.umich.edudef template MediaOpRegConstructor {{
956516Sgblack@eecs.umich.edu
966516Sgblack@eecs.umich.edu    inline void %(class_name)s::buildMe()
976516Sgblack@eecs.umich.edu    {
986516Sgblack@eecs.umich.edu        %(constructor)s;
996516Sgblack@eecs.umich.edu    }
1006516Sgblack@eecs.umich.edu
1016516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1026516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1036516Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
1046545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
1056516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1066516Sgblack@eecs.umich.edu                false, false, false, false,
1076545Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _ext,
1086516Sgblack@eecs.umich.edu                %(op_class)s)
1096516Sgblack@eecs.umich.edu    {
1106516Sgblack@eecs.umich.edu        buildMe();
1116516Sgblack@eecs.umich.edu    }
1126516Sgblack@eecs.umich.edu
1136516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1146516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1156516Sgblack@eecs.umich.edu            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
1166516Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
1176545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
1186516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1196516Sgblack@eecs.umich.edu                isMicro, isDelayed, isFirst, isLast,
1206545Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _ext,
1216516Sgblack@eecs.umich.edu                %(op_class)s)
1226516Sgblack@eecs.umich.edu    {
1236516Sgblack@eecs.umich.edu        buildMe();
1246516Sgblack@eecs.umich.edu    }
1256516Sgblack@eecs.umich.edu}};
1266516Sgblack@eecs.umich.edu
1276516Sgblack@eecs.umich.edudef template MediaOpImmConstructor {{
1286516Sgblack@eecs.umich.edu
1296516Sgblack@eecs.umich.edu    inline void %(class_name)s::buildMe()
1306516Sgblack@eecs.umich.edu    {
1316516Sgblack@eecs.umich.edu        %(constructor)s;
1326516Sgblack@eecs.umich.edu    }
1336516Sgblack@eecs.umich.edu
1346516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1356516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1366516Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
1376545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
1386516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1396516Sgblack@eecs.umich.edu                false, false, false, false,
1406545Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _ext,
1416516Sgblack@eecs.umich.edu                %(op_class)s)
1426516Sgblack@eecs.umich.edu    {
1436516Sgblack@eecs.umich.edu        buildMe();
1446516Sgblack@eecs.umich.edu    }
1456516Sgblack@eecs.umich.edu
1466516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1476516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1486516Sgblack@eecs.umich.edu            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
1496516Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
1506545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
1516516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1526516Sgblack@eecs.umich.edu                isMicro, isDelayed, isFirst, isLast,
1536545Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _ext,
1546516Sgblack@eecs.umich.edu                %(op_class)s)
1556516Sgblack@eecs.umich.edu    {
1566516Sgblack@eecs.umich.edu        buildMe();
1576516Sgblack@eecs.umich.edu    }
1586516Sgblack@eecs.umich.edu}};
1596516Sgblack@eecs.umich.edu
1606516Sgblack@eecs.umich.edulet {{
1616516Sgblack@eecs.umich.edu    # Make these empty strings so that concatenating onto
1626516Sgblack@eecs.umich.edu    # them will always work.
1636516Sgblack@eecs.umich.edu    header_output = ""
1646516Sgblack@eecs.umich.edu    decoder_output = ""
1656516Sgblack@eecs.umich.edu    exec_output = ""
1666516Sgblack@eecs.umich.edu
1676516Sgblack@eecs.umich.edu    immTemplates = (
1686516Sgblack@eecs.umich.edu            MediaOpImmDeclare,
1696516Sgblack@eecs.umich.edu            MediaOpImmConstructor,
1706516Sgblack@eecs.umich.edu            MediaOpExecute)
1716516Sgblack@eecs.umich.edu
1726516Sgblack@eecs.umich.edu    regTemplates = (
1736516Sgblack@eecs.umich.edu            MediaOpRegDeclare,
1746516Sgblack@eecs.umich.edu            MediaOpRegConstructor,
1756516Sgblack@eecs.umich.edu            MediaOpExecute)
1766516Sgblack@eecs.umich.edu
1776516Sgblack@eecs.umich.edu    class MediaOpMeta(type):
1786516Sgblack@eecs.umich.edu        def buildCppClasses(self, name, Name, suffix, code):
1796516Sgblack@eecs.umich.edu
1806516Sgblack@eecs.umich.edu            # Globals to stick the output in
1816516Sgblack@eecs.umich.edu            global header_output
1826516Sgblack@eecs.umich.edu            global decoder_output
1836516Sgblack@eecs.umich.edu            global exec_output
1846516Sgblack@eecs.umich.edu
1856516Sgblack@eecs.umich.edu            # If op2 is used anywhere, make register and immediate versions
1866516Sgblack@eecs.umich.edu            # of this code.
1876516Sgblack@eecs.umich.edu            matcher = re.compile("(?<!\\w)(?P<prefix>s?)op2(?P<typeQual>\\.\\w+)?")
1886516Sgblack@eecs.umich.edu            match = matcher.search(code)
1896516Sgblack@eecs.umich.edu            if match:
1906516Sgblack@eecs.umich.edu                typeQual = ""
1916516Sgblack@eecs.umich.edu                if match.group("typeQual"):
1926516Sgblack@eecs.umich.edu                    typeQual = match.group("typeQual")
1936583Sgblack@eecs.umich.edu                src2_name = "%sFpSrcReg2%s" % (match.group("prefix"), typeQual)
1946516Sgblack@eecs.umich.edu                self.buildCppClasses(name, Name, suffix,
1956516Sgblack@eecs.umich.edu                        matcher.sub(src2_name, code))
1966516Sgblack@eecs.umich.edu                self.buildCppClasses(name + "i", Name, suffix + "Imm",
1976516Sgblack@eecs.umich.edu                        matcher.sub("imm8", code))
1986516Sgblack@eecs.umich.edu                return
1996516Sgblack@eecs.umich.edu
2006516Sgblack@eecs.umich.edu            base = "X86ISA::MediaOp"
2016516Sgblack@eecs.umich.edu
2026516Sgblack@eecs.umich.edu            # If imm8 shows up in the code, use the immediate templates, if
2036516Sgblack@eecs.umich.edu            # not, hopefully the register ones will be correct.
2046516Sgblack@eecs.umich.edu            matcher = re.compile("(?<!\w)imm8(?!\w)")
2056516Sgblack@eecs.umich.edu            if matcher.search(code):
2066516Sgblack@eecs.umich.edu                base += "Imm"
2076516Sgblack@eecs.umich.edu                templates = immTemplates
2086516Sgblack@eecs.umich.edu            else:
2096516Sgblack@eecs.umich.edu                base += "Reg"
2106516Sgblack@eecs.umich.edu                templates = regTemplates
2116516Sgblack@eecs.umich.edu
2126516Sgblack@eecs.umich.edu            # Get everything ready for the substitution
2136516Sgblack@eecs.umich.edu            iop = InstObjParams(name, Name + suffix, base, {"code" : code})
2146516Sgblack@eecs.umich.edu
2156516Sgblack@eecs.umich.edu            # Generate the actual code (finally!)
2166516Sgblack@eecs.umich.edu            header_output += templates[0].subst(iop)
2176516Sgblack@eecs.umich.edu            decoder_output += templates[1].subst(iop)
2186516Sgblack@eecs.umich.edu            exec_output += templates[2].subst(iop)
2196516Sgblack@eecs.umich.edu
2206516Sgblack@eecs.umich.edu
2216516Sgblack@eecs.umich.edu        def __new__(mcls, Name, bases, dict):
2226516Sgblack@eecs.umich.edu            abstract = False
2236516Sgblack@eecs.umich.edu            name = Name.lower()
2246516Sgblack@eecs.umich.edu            if "abstract" in dict:
2256516Sgblack@eecs.umich.edu                abstract = dict['abstract']
2266516Sgblack@eecs.umich.edu                del dict['abstract']
2276516Sgblack@eecs.umich.edu
2286516Sgblack@eecs.umich.edu            cls = super(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict)
2296516Sgblack@eecs.umich.edu            if not abstract:
2306516Sgblack@eecs.umich.edu                cls.className = Name
2316516Sgblack@eecs.umich.edu                cls.base_mnemonic = name
2326516Sgblack@eecs.umich.edu                code = cls.code
2336516Sgblack@eecs.umich.edu
2346516Sgblack@eecs.umich.edu                # Set up the C++ classes
2356516Sgblack@eecs.umich.edu                mcls.buildCppClasses(cls, name, Name, "", code)
2366516Sgblack@eecs.umich.edu
2376516Sgblack@eecs.umich.edu                # Hook into the microassembler dict
2386516Sgblack@eecs.umich.edu                global microopClasses
2396516Sgblack@eecs.umich.edu                microopClasses[name] = cls
2406516Sgblack@eecs.umich.edu
2416516Sgblack@eecs.umich.edu                # If op2 is used anywhere, make register and immediate versions
2426516Sgblack@eecs.umich.edu                # of this code.
2436516Sgblack@eecs.umich.edu                matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
2446516Sgblack@eecs.umich.edu                if matcher.search(code):
2456516Sgblack@eecs.umich.edu                    microopClasses[name + 'i'] = cls
2466516Sgblack@eecs.umich.edu            return cls
2476516Sgblack@eecs.umich.edu
2486516Sgblack@eecs.umich.edu
2496516Sgblack@eecs.umich.edu    class MediaOp(X86Microop):
2506516Sgblack@eecs.umich.edu        __metaclass__ = MediaOpMeta
2516516Sgblack@eecs.umich.edu        # This class itself doesn't act as a microop
2526516Sgblack@eecs.umich.edu        abstract = True
2536516Sgblack@eecs.umich.edu
2546516Sgblack@eecs.umich.edu        def __init__(self, dest, src1, op2,
2556545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2566516Sgblack@eecs.umich.edu            self.dest = dest
2576516Sgblack@eecs.umich.edu            self.src1 = src1
2586516Sgblack@eecs.umich.edu            self.op2 = op2
2596516Sgblack@eecs.umich.edu            if size is not None:
2606516Sgblack@eecs.umich.edu                self.srcSize = size
2616516Sgblack@eecs.umich.edu                self.destSize = size
2626516Sgblack@eecs.umich.edu            if srcSize is not None:
2636516Sgblack@eecs.umich.edu                self.srcSize = srcSize
2646516Sgblack@eecs.umich.edu            if destSize is not None:
2656516Sgblack@eecs.umich.edu                self.destSize = destSize
2666516Sgblack@eecs.umich.edu            if self.srcSize is None:
2676516Sgblack@eecs.umich.edu                raise Exception, "Source size not set."
2686516Sgblack@eecs.umich.edu            if self.destSize is None:
2696516Sgblack@eecs.umich.edu                raise Exception, "Dest size not set."
2706545Sgblack@eecs.umich.edu            if ext is None:
2716545Sgblack@eecs.umich.edu                self.ext = 0
2726516Sgblack@eecs.umich.edu            else:
2736545Sgblack@eecs.umich.edu                self.ext = ext 
2746516Sgblack@eecs.umich.edu
2756516Sgblack@eecs.umich.edu        def getAllocator(self, *microFlags):
2766516Sgblack@eecs.umich.edu            className = self.className
2776516Sgblack@eecs.umich.edu            if self.mnemonic == self.base_mnemonic + 'i':
2786516Sgblack@eecs.umich.edu                className += "Imm"
2796516Sgblack@eecs.umich.edu            allocator = '''new %(class_name)s(machInst, macrocodeBlock
2806516Sgblack@eecs.umich.edu                    %(flags)s, %(src1)s, %(op2)s, %(dest)s,
2816545Sgblack@eecs.umich.edu                    %(srcSize)s, %(destSize)s, %(ext)s)''' % {
2826516Sgblack@eecs.umich.edu                "class_name" : className,
2836516Sgblack@eecs.umich.edu                "flags" : self.microFlagsText(microFlags),
2846516Sgblack@eecs.umich.edu                "src1" : self.src1, "op2" : self.op2,
2856516Sgblack@eecs.umich.edu                "dest" : self.dest,
2866516Sgblack@eecs.umich.edu                "srcSize" : self.srcSize,
2876516Sgblack@eecs.umich.edu                "destSize" : self.destSize,
2886545Sgblack@eecs.umich.edu                "ext" : self.ext}
2896516Sgblack@eecs.umich.edu            return allocator
2906516Sgblack@eecs.umich.edu
2916516Sgblack@eecs.umich.edu    class Mov2int(MediaOp):
2926589Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2 = 0, \
2936545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2946589Sgblack@eecs.umich.edu            super(Mov2int, self).__init__(dest, src1,\
2956589Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
2966516Sgblack@eecs.umich.edu        code = '''
2976589Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / srcSize;
2986589Sgblack@eecs.umich.edu            int offset = imm8;
2996589Sgblack@eecs.umich.edu            if (bits(src1, 0) && (ext & 0x1))
3006589Sgblack@eecs.umich.edu                offset -= items;
3016589Sgblack@eecs.umich.edu            if (offset >= 0 && offset < items) {
3026589Sgblack@eecs.umich.edu                uint64_t fpSrcReg1 =
3036589Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw,
3046589Sgblack@eecs.umich.edu                            (offset + 1) * srcSize * 8 - 1,
3056589Sgblack@eecs.umich.edu                            (offset + 0) * srcSize * 8);
3066589Sgblack@eecs.umich.edu                DestReg = merge(0, fpSrcReg1, destSize);
3076589Sgblack@eecs.umich.edu            } else {
3086589Sgblack@eecs.umich.edu                DestReg = DestReg;
3096589Sgblack@eecs.umich.edu            }
3106516Sgblack@eecs.umich.edu        '''
3116516Sgblack@eecs.umich.edu
3126516Sgblack@eecs.umich.edu    class Mov2fp(MediaOp):
3136589Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2 = 0, \
3146545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
3156589Sgblack@eecs.umich.edu            super(Mov2fp, self).__init__(dest, src1,\
3166589Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
3176516Sgblack@eecs.umich.edu        code = '''
3186589Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / destSize;
3196589Sgblack@eecs.umich.edu            int offset = imm8;
3206589Sgblack@eecs.umich.edu            if (bits(dest, 0) && (ext & 0x1))
3216589Sgblack@eecs.umich.edu                offset -= items;
3226589Sgblack@eecs.umich.edu            if (offset >= 0 && offset < items) {
3236589Sgblack@eecs.umich.edu                uint64_t srcReg1 = pick(SrcReg1, 0, srcSize);
3246589Sgblack@eecs.umich.edu                FpDestReg.uqw =
3256589Sgblack@eecs.umich.edu                    insertBits(FpDestReg.uqw,
3266589Sgblack@eecs.umich.edu                            (offset + 1) * destSize * 8 - 1,
3276589Sgblack@eecs.umich.edu                            (offset + 0) * destSize * 8, srcReg1);
3286589Sgblack@eecs.umich.edu            } else {
3296589Sgblack@eecs.umich.edu                FpDestReg.uqw = FpDestReg.uqw;
3306589Sgblack@eecs.umich.edu            }
3316516Sgblack@eecs.umich.edu        '''
3326521Sgblack@eecs.umich.edu
3336592Sgblack@eecs.umich.edu    class Movsign(MediaOp):
3346592Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
3356592Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
3366592Sgblack@eecs.umich.edu            super(Movsign, self).__init__(dest, src,\
3376592Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
3386592Sgblack@eecs.umich.edu        code = '''
3396592Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / srcSize;
3406592Sgblack@eecs.umich.edu            uint64_t result = 0;
3416592Sgblack@eecs.umich.edu            int offset = (ext & 0x1) ? items : 0;
3426592Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3436592Sgblack@eecs.umich.edu                uint64_t picked =
3446592Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + 1) * 8 * srcSize - 1);
3456592Sgblack@eecs.umich.edu                result = insertBits(result, i + offset, i + offset, picked);
3466592Sgblack@eecs.umich.edu            }
3476592Sgblack@eecs.umich.edu            DestReg = DestReg | result;
3486592Sgblack@eecs.umich.edu        '''
3496592Sgblack@eecs.umich.edu
3506594Sgblack@eecs.umich.edu    class Maskmov(MediaOp):
3516594Sgblack@eecs.umich.edu        code = '''
3526594Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3536594Sgblack@eecs.umich.edu            int size = srcSize;
3546594Sgblack@eecs.umich.edu            int sizeBits = size * 8;
3556594Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
3566594Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
3576594Sgblack@eecs.umich.edu
3586594Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3596594Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
3606594Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
3616594Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
3626594Sgblack@eecs.umich.edu                if (bits(FpSrcReg2.uqw, hiIndex))
3636594Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
3646594Sgblack@eecs.umich.edu            }
3656594Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
3666594Sgblack@eecs.umich.edu        '''
3676594Sgblack@eecs.umich.edu
3686596Sgblack@eecs.umich.edu    class shuffle(MediaOp):
3696596Sgblack@eecs.umich.edu        code = '''
3706596Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3716596Sgblack@eecs.umich.edu            int size = srcSize;
3726596Sgblack@eecs.umich.edu            int sizeBits = size * 8;
3736596Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / size;
3746596Sgblack@eecs.umich.edu            int options;
3756596Sgblack@eecs.umich.edu            int optionBits;
3766596Sgblack@eecs.umich.edu            if (size == 8) {
3776596Sgblack@eecs.umich.edu                options = 2;
3786596Sgblack@eecs.umich.edu                optionBits = 1;
3796596Sgblack@eecs.umich.edu            } else {
3806596Sgblack@eecs.umich.edu                options = 4;
3816596Sgblack@eecs.umich.edu                optionBits = 2;
3826596Sgblack@eecs.umich.edu            }
3836596Sgblack@eecs.umich.edu
3846596Sgblack@eecs.umich.edu            uint64_t result = 0;
3856596Sgblack@eecs.umich.edu            uint8_t sel = ext;
3866596Sgblack@eecs.umich.edu
3876596Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3886596Sgblack@eecs.umich.edu                uint64_t resBits;
3896596Sgblack@eecs.umich.edu                uint8_t lsel = sel & mask(optionBits);
3906596Sgblack@eecs.umich.edu                if (lsel * size >= sizeof(FloatRegBits)) {
3916596Sgblack@eecs.umich.edu                    lsel -= options / 2;
3926596Sgblack@eecs.umich.edu                    resBits = bits(FpSrcReg2.uqw,
3936596Sgblack@eecs.umich.edu                            (lsel + 1) * sizeBits - 1,
3946596Sgblack@eecs.umich.edu                            (lsel + 0) * sizeBits);
3956596Sgblack@eecs.umich.edu                }  else {
3966596Sgblack@eecs.umich.edu                    resBits = bits(FpSrcReg1.uqw,
3976596Sgblack@eecs.umich.edu                            (lsel + 1) * sizeBits - 1,
3986596Sgblack@eecs.umich.edu                            (lsel + 0) * sizeBits);
3996596Sgblack@eecs.umich.edu                }
4006596Sgblack@eecs.umich.edu
4016596Sgblack@eecs.umich.edu                sel >>= optionBits;
4026596Sgblack@eecs.umich.edu
4036596Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
4046596Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
4056596Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
4066596Sgblack@eecs.umich.edu            }
4076596Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
4086596Sgblack@eecs.umich.edu        '''
4096596Sgblack@eecs.umich.edu
4106521Sgblack@eecs.umich.edu    class Unpack(MediaOp):
4116521Sgblack@eecs.umich.edu        code = '''
4126521Sgblack@eecs.umich.edu            assert(srcSize == destSize);
4136521Sgblack@eecs.umich.edu            int size = destSize;
4146521Sgblack@eecs.umich.edu            int items = (sizeof(FloatRegBits) / size) / 2;
4156545Sgblack@eecs.umich.edu            int offset = ext ? items : 0;
4166521Sgblack@eecs.umich.edu            uint64_t result = 0;
4176521Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
4186521Sgblack@eecs.umich.edu                uint64_t pickedLow =
4196521Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + offset + 1) * 8 * size - 1,
4206521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
4216521Sgblack@eecs.umich.edu                result = insertBits(result,
4226521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size - 1,
4236521Sgblack@eecs.umich.edu                                    (2 * i + 0) * 8 * size,
4246521Sgblack@eecs.umich.edu                                    pickedLow);
4256521Sgblack@eecs.umich.edu                uint64_t pickedHigh =
4266521Sgblack@eecs.umich.edu                    bits(FpSrcReg2.uqw, (i + offset + 1) * 8 * size - 1,
4276521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
4286521Sgblack@eecs.umich.edu                result = insertBits(result,
4296521Sgblack@eecs.umich.edu                                    (2 * i + 2) * 8 * size - 1,
4306521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size,
4316521Sgblack@eecs.umich.edu                                    pickedHigh);
4326521Sgblack@eecs.umich.edu            }
4336521Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
4346521Sgblack@eecs.umich.edu        '''
4356534Sgblack@eecs.umich.edu
4366546Sgblack@eecs.umich.edu    class Pack(MediaOp):
4376546Sgblack@eecs.umich.edu        code = '''
4386546Sgblack@eecs.umich.edu            assert(srcSize == destSize * 2);
4396546Sgblack@eecs.umich.edu            int items = (sizeof(FloatRegBits) / destSize);
4406546Sgblack@eecs.umich.edu            int destBits = destSize * 8;
4416546Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
4426546Sgblack@eecs.umich.edu            uint64_t result = 0;
4436546Sgblack@eecs.umich.edu            int i;
4446546Sgblack@eecs.umich.edu            for (i = 0; i < items / 2; i++) {
4456546Sgblack@eecs.umich.edu                uint64_t picked =
4466546Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + 1) * srcBits - 1,
4476546Sgblack@eecs.umich.edu                                        (i + 0) * srcBits);
4486546Sgblack@eecs.umich.edu                unsigned signBit = bits(picked, srcBits - 1);
4496546Sgblack@eecs.umich.edu                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
4506546Sgblack@eecs.umich.edu
4516546Sgblack@eecs.umich.edu                // Handle saturation.
4526546Sgblack@eecs.umich.edu                if (signBit) {
4536546Sgblack@eecs.umich.edu                    if (overflow != mask(destBits - srcBits + 1)) {
4546546Sgblack@eecs.umich.edu                        if (ext & 0x1)
4556546Sgblack@eecs.umich.edu                            picked = (1 << (destBits - 1));
4566546Sgblack@eecs.umich.edu                        else
4576546Sgblack@eecs.umich.edu                            picked = 0;
4586546Sgblack@eecs.umich.edu                    }
4596546Sgblack@eecs.umich.edu                } else {
4606546Sgblack@eecs.umich.edu                    if (overflow != 0) {
4616546Sgblack@eecs.umich.edu                        if (ext & 0x1)
4626546Sgblack@eecs.umich.edu                            picked = mask(destBits - 1);
4636546Sgblack@eecs.umich.edu                        else
4646546Sgblack@eecs.umich.edu                            picked = mask(destBits);
4656546Sgblack@eecs.umich.edu                    }
4666546Sgblack@eecs.umich.edu                }
4676546Sgblack@eecs.umich.edu                result = insertBits(result,
4686546Sgblack@eecs.umich.edu                                    (i + 1) * destBits - 1,
4696546Sgblack@eecs.umich.edu                                    (i + 0) * destBits,
4706546Sgblack@eecs.umich.edu                                    picked);
4716546Sgblack@eecs.umich.edu            }
4726546Sgblack@eecs.umich.edu            for (;i < items; i++) {
4736546Sgblack@eecs.umich.edu                uint64_t picked =
4746546Sgblack@eecs.umich.edu                    bits(FpSrcReg2.uqw, (i - items + 1) * srcBits - 1,
4756546Sgblack@eecs.umich.edu                                        (i - items + 0) * srcBits);
4766546Sgblack@eecs.umich.edu                unsigned signBit = bits(picked, srcBits - 1);
4776546Sgblack@eecs.umich.edu                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
4786546Sgblack@eecs.umich.edu
4796546Sgblack@eecs.umich.edu                // Handle saturation.
4806546Sgblack@eecs.umich.edu                if (signBit) {
4816546Sgblack@eecs.umich.edu                    if (overflow != mask(destBits - srcBits + 1)) {
4826546Sgblack@eecs.umich.edu                        if (ext & 0x1)
4836546Sgblack@eecs.umich.edu                            picked = (1 << (destBits - 1));
4846546Sgblack@eecs.umich.edu                        else
4856546Sgblack@eecs.umich.edu                            picked = 0;
4866546Sgblack@eecs.umich.edu                    }
4876546Sgblack@eecs.umich.edu                } else {
4886546Sgblack@eecs.umich.edu                    if (overflow != 0) {
4896546Sgblack@eecs.umich.edu                        if (ext & 0x1)
4906546Sgblack@eecs.umich.edu                            picked = mask(destBits - 1);
4916546Sgblack@eecs.umich.edu                        else
4926546Sgblack@eecs.umich.edu                            picked = mask(destBits);
4936546Sgblack@eecs.umich.edu                    }
4946546Sgblack@eecs.umich.edu                }
4956546Sgblack@eecs.umich.edu                result = insertBits(result,
4966546Sgblack@eecs.umich.edu                                    (i + 1) * destBits - 1,
4976546Sgblack@eecs.umich.edu                                    (i + 0) * destBits,
4986546Sgblack@eecs.umich.edu                                    picked);
4996546Sgblack@eecs.umich.edu            }
5006546Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
5016546Sgblack@eecs.umich.edu        '''
5026546Sgblack@eecs.umich.edu
5036534Sgblack@eecs.umich.edu    class Mxor(MediaOp):
5046534Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
5056534Sgblack@eecs.umich.edu            super(Mxor, self).__init__(dest, src1, src2, 1)
5066534Sgblack@eecs.umich.edu        code = '''
5076534Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw;
5086534Sgblack@eecs.umich.edu        '''
5096537Sgblack@eecs.umich.edu
5106537Sgblack@eecs.umich.edu    class Mor(MediaOp):
5116537Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
5126537Sgblack@eecs.umich.edu            super(Mor, self).__init__(dest, src1, src2, 1)
5136537Sgblack@eecs.umich.edu        code = '''
5146537Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw | FpSrcReg2.uqw;
5156537Sgblack@eecs.umich.edu        '''
5166539Sgblack@eecs.umich.edu
5176539Sgblack@eecs.umich.edu    class Mand(MediaOp):
5186539Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
5196539Sgblack@eecs.umich.edu            super(Mand, self).__init__(dest, src1, src2, 1)
5206539Sgblack@eecs.umich.edu        code = '''
5216539Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw & FpSrcReg2.uqw;
5226539Sgblack@eecs.umich.edu        '''
5236541Sgblack@eecs.umich.edu
5246541Sgblack@eecs.umich.edu    class Mandn(MediaOp):
5256541Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
5266541Sgblack@eecs.umich.edu            super(Mandn, self).__init__(dest, src1, src2, 1)
5276541Sgblack@eecs.umich.edu        code = '''
5286541Sgblack@eecs.umich.edu            FpDestReg.uqw = ~FpSrcReg1.uqw & FpSrcReg2.uqw;
5296541Sgblack@eecs.umich.edu        '''
5306548Sgblack@eecs.umich.edu
5316548Sgblack@eecs.umich.edu    class Mminf(MediaOp):
5326548Sgblack@eecs.umich.edu        code = '''
5336548Sgblack@eecs.umich.edu            union floatInt
5346548Sgblack@eecs.umich.edu            {
5356548Sgblack@eecs.umich.edu                float f;
5366548Sgblack@eecs.umich.edu                uint32_t i;
5376548Sgblack@eecs.umich.edu            };
5386548Sgblack@eecs.umich.edu            union doubleInt
5396548Sgblack@eecs.umich.edu            {
5406548Sgblack@eecs.umich.edu                double d;
5416548Sgblack@eecs.umich.edu                uint64_t i;
5426548Sgblack@eecs.umich.edu            };
5436548Sgblack@eecs.umich.edu
5446548Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5456548Sgblack@eecs.umich.edu            int size = srcSize;
5466548Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5476548Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
5486548Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
5496548Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
5506548Sgblack@eecs.umich.edu
5516548Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
5526548Sgblack@eecs.umich.edu                double arg1, arg2;
5536548Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5546548Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5556548Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
5566548Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
5576548Sgblack@eecs.umich.edu
5586548Sgblack@eecs.umich.edu                if (size == 4) {
5596548Sgblack@eecs.umich.edu                    floatInt fi;
5606548Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
5616548Sgblack@eecs.umich.edu                    arg1 = fi.f;
5626548Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
5636548Sgblack@eecs.umich.edu                    arg2 = fi.f;
5646548Sgblack@eecs.umich.edu                } else {
5656548Sgblack@eecs.umich.edu                    doubleInt di;
5666548Sgblack@eecs.umich.edu                    di.i = arg1Bits;
5676548Sgblack@eecs.umich.edu                    arg1 = di.d;
5686548Sgblack@eecs.umich.edu                    di.i = arg2Bits;
5696548Sgblack@eecs.umich.edu                    arg2 = di.d;
5706548Sgblack@eecs.umich.edu                }
5716548Sgblack@eecs.umich.edu
5726548Sgblack@eecs.umich.edu                if (arg1 < arg2) {
5736548Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
5746548Sgblack@eecs.umich.edu                } else {
5756548Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
5766548Sgblack@eecs.umich.edu                }
5776548Sgblack@eecs.umich.edu            }
5786548Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
5796548Sgblack@eecs.umich.edu        '''
5806550Sgblack@eecs.umich.edu
5816550Sgblack@eecs.umich.edu    class Mmaxf(MediaOp):
5826550Sgblack@eecs.umich.edu        code = '''
5836550Sgblack@eecs.umich.edu            union floatInt
5846550Sgblack@eecs.umich.edu            {
5856550Sgblack@eecs.umich.edu                float f;
5866550Sgblack@eecs.umich.edu                uint32_t i;
5876550Sgblack@eecs.umich.edu            };
5886550Sgblack@eecs.umich.edu            union doubleInt
5896550Sgblack@eecs.umich.edu            {
5906550Sgblack@eecs.umich.edu                double d;
5916550Sgblack@eecs.umich.edu                uint64_t i;
5926550Sgblack@eecs.umich.edu            };
5936550Sgblack@eecs.umich.edu
5946550Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5956550Sgblack@eecs.umich.edu            int size = srcSize;
5966550Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5976550Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
5986550Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
5996550Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
6006550Sgblack@eecs.umich.edu
6016550Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6026550Sgblack@eecs.umich.edu                double arg1, arg2;
6036550Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6046550Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6056550Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
6066550Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
6076550Sgblack@eecs.umich.edu
6086550Sgblack@eecs.umich.edu                if (size == 4) {
6096550Sgblack@eecs.umich.edu                    floatInt fi;
6106550Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
6116550Sgblack@eecs.umich.edu                    arg1 = fi.f;
6126550Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
6136550Sgblack@eecs.umich.edu                    arg2 = fi.f;
6146550Sgblack@eecs.umich.edu                } else {
6156550Sgblack@eecs.umich.edu                    doubleInt di;
6166550Sgblack@eecs.umich.edu                    di.i = arg1Bits;
6176550Sgblack@eecs.umich.edu                    arg1 = di.d;
6186550Sgblack@eecs.umich.edu                    di.i = arg2Bits;
6196550Sgblack@eecs.umich.edu                    arg2 = di.d;
6206550Sgblack@eecs.umich.edu                }
6216550Sgblack@eecs.umich.edu
6226550Sgblack@eecs.umich.edu                if (arg1 > arg2) {
6236550Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
6246550Sgblack@eecs.umich.edu                } else {
6256550Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
6266550Sgblack@eecs.umich.edu                }
6276550Sgblack@eecs.umich.edu            }
6286550Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
6296550Sgblack@eecs.umich.edu        '''
6306552Sgblack@eecs.umich.edu
6316572Sgblack@eecs.umich.edu    class Mmini(MediaOp):
6326572Sgblack@eecs.umich.edu        code = '''
6336572Sgblack@eecs.umich.edu
6346572Sgblack@eecs.umich.edu            assert(srcSize == destSize);
6356572Sgblack@eecs.umich.edu            int size = srcSize;
6366572Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6376572Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
6386572Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
6396572Sgblack@eecs.umich.edu
6406572Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6416572Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6426572Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6436572Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
6446572Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
6456572Sgblack@eecs.umich.edu                    (0 - (arg1Bits & (1 << (sizeBits - 1))));
6466572Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
6476572Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
6486572Sgblack@eecs.umich.edu                    (0 - (arg2Bits & (1 << (sizeBits - 1))));
6496572Sgblack@eecs.umich.edu                uint64_t resBits;
6506572Sgblack@eecs.umich.edu
6516572Sgblack@eecs.umich.edu                if (ext & 0x2) {
6526572Sgblack@eecs.umich.edu                    if (arg1 < arg2) {
6536572Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6546572Sgblack@eecs.umich.edu                    } else {
6556572Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6566572Sgblack@eecs.umich.edu                    }
6576572Sgblack@eecs.umich.edu                } else {
6586572Sgblack@eecs.umich.edu                    if (arg1Bits < arg2Bits) {
6596572Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6606572Sgblack@eecs.umich.edu                    } else {
6616572Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6626572Sgblack@eecs.umich.edu                    }
6636572Sgblack@eecs.umich.edu                }
6646572Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
6656572Sgblack@eecs.umich.edu            }
6666572Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
6676572Sgblack@eecs.umich.edu        '''
6686572Sgblack@eecs.umich.edu
6696574Sgblack@eecs.umich.edu    class Mmaxi(MediaOp):
6706574Sgblack@eecs.umich.edu        code = '''
6716574Sgblack@eecs.umich.edu
6726574Sgblack@eecs.umich.edu            assert(srcSize == destSize);
6736574Sgblack@eecs.umich.edu            int size = srcSize;
6746574Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6756574Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
6766574Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
6776574Sgblack@eecs.umich.edu
6786574Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6796574Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6806574Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6816574Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
6826574Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
6836574Sgblack@eecs.umich.edu                    (0 - (arg1Bits & (1 << (sizeBits - 1))));
6846574Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
6856574Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
6866574Sgblack@eecs.umich.edu                    (0 - (arg2Bits & (1 << (sizeBits - 1))));
6876574Sgblack@eecs.umich.edu                uint64_t resBits;
6886574Sgblack@eecs.umich.edu
6896574Sgblack@eecs.umich.edu                if (ext & 0x2) {
6906574Sgblack@eecs.umich.edu                    if (arg1 > arg2) {
6916574Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6926574Sgblack@eecs.umich.edu                    } else {
6936574Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6946574Sgblack@eecs.umich.edu                    }
6956574Sgblack@eecs.umich.edu                } else {
6966574Sgblack@eecs.umich.edu                    if (arg1Bits > arg2Bits) {
6976574Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6986574Sgblack@eecs.umich.edu                    } else {
6996574Sgblack@eecs.umich.edu                        resBits = arg2Bits;
7006574Sgblack@eecs.umich.edu                    }
7016574Sgblack@eecs.umich.edu                }
7026574Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
7036574Sgblack@eecs.umich.edu            }
7046574Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
7056574Sgblack@eecs.umich.edu        '''
7066574Sgblack@eecs.umich.edu
7076552Sgblack@eecs.umich.edu    class Msqrt(MediaOp):
7086552Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
7096552Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
7106552Sgblack@eecs.umich.edu            super(Msqrt, self).__init__(dest, src,\
7116552Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
7126552Sgblack@eecs.umich.edu        code = '''
7136552Sgblack@eecs.umich.edu            union floatInt
7146552Sgblack@eecs.umich.edu            {
7156552Sgblack@eecs.umich.edu                float f;
7166552Sgblack@eecs.umich.edu                uint32_t i;
7176552Sgblack@eecs.umich.edu            };
7186552Sgblack@eecs.umich.edu            union doubleInt
7196552Sgblack@eecs.umich.edu            {
7206552Sgblack@eecs.umich.edu                double d;
7216552Sgblack@eecs.umich.edu                uint64_t i;
7226552Sgblack@eecs.umich.edu            };
7236552Sgblack@eecs.umich.edu
7246552Sgblack@eecs.umich.edu            assert(srcSize == destSize);
7256552Sgblack@eecs.umich.edu            int size = srcSize;
7266552Sgblack@eecs.umich.edu            int sizeBits = size * 8;
7276552Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
7286552Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
7296552Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
7306552Sgblack@eecs.umich.edu
7316552Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
7326552Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
7336552Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
7346552Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
7356552Sgblack@eecs.umich.edu
7366552Sgblack@eecs.umich.edu                if (size == 4) {
7376552Sgblack@eecs.umich.edu                    floatInt fi;
7386552Sgblack@eecs.umich.edu                    fi.i = argBits;
7396552Sgblack@eecs.umich.edu                    fi.f = sqrt(fi.f);
7406552Sgblack@eecs.umich.edu                    argBits = fi.i;
7416552Sgblack@eecs.umich.edu                } else {
7426552Sgblack@eecs.umich.edu                    doubleInt di;
7436552Sgblack@eecs.umich.edu                    di.i = argBits;
7446552Sgblack@eecs.umich.edu                    di.d = sqrt(di.d);
7456552Sgblack@eecs.umich.edu                    argBits = di.i;
7466552Sgblack@eecs.umich.edu                }
7476552Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, argBits);
7486552Sgblack@eecs.umich.edu            }
7496552Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
7506552Sgblack@eecs.umich.edu        '''
7516554Sgblack@eecs.umich.edu
7526554Sgblack@eecs.umich.edu    class Maddf(MediaOp):
7536554Sgblack@eecs.umich.edu        code = '''
7546554Sgblack@eecs.umich.edu            union floatInt
7556554Sgblack@eecs.umich.edu            {
7566554Sgblack@eecs.umich.edu                float f;
7576554Sgblack@eecs.umich.edu                uint32_t i;
7586554Sgblack@eecs.umich.edu            };
7596554Sgblack@eecs.umich.edu            union doubleInt
7606554Sgblack@eecs.umich.edu            {
7616554Sgblack@eecs.umich.edu                double d;
7626554Sgblack@eecs.umich.edu                uint64_t i;
7636554Sgblack@eecs.umich.edu            };
7646554Sgblack@eecs.umich.edu
7656554Sgblack@eecs.umich.edu            assert(srcSize == destSize);
7666554Sgblack@eecs.umich.edu            int size = srcSize;
7676554Sgblack@eecs.umich.edu            int sizeBits = size * 8;
7686554Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
7696554Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
7706554Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
7716554Sgblack@eecs.umich.edu
7726554Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
7736554Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
7746554Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
7756554Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
7766554Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
7776554Sgblack@eecs.umich.edu                uint64_t resBits;
7786554Sgblack@eecs.umich.edu
7796554Sgblack@eecs.umich.edu                if (size == 4) {
7806554Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
7816554Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7826554Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7836554Sgblack@eecs.umich.edu                    res.f = arg1.f + arg2.f;
7846554Sgblack@eecs.umich.edu                    resBits = res.i;
7856554Sgblack@eecs.umich.edu                } else {
7866554Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
7876554Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7886554Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7896554Sgblack@eecs.umich.edu                    res.d = arg1.d + arg2.d;
7906554Sgblack@eecs.umich.edu                    resBits = res.i;
7916554Sgblack@eecs.umich.edu                }
7926554Sgblack@eecs.umich.edu
7936554Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
7946554Sgblack@eecs.umich.edu            }
7956554Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
7966554Sgblack@eecs.umich.edu        '''
7976556Sgblack@eecs.umich.edu
7986556Sgblack@eecs.umich.edu    class Msubf(MediaOp):
7996556Sgblack@eecs.umich.edu        code = '''
8006556Sgblack@eecs.umich.edu            union floatInt
8016556Sgblack@eecs.umich.edu            {
8026556Sgblack@eecs.umich.edu                float f;
8036556Sgblack@eecs.umich.edu                uint32_t i;
8046556Sgblack@eecs.umich.edu            };
8056556Sgblack@eecs.umich.edu            union doubleInt
8066556Sgblack@eecs.umich.edu            {
8076556Sgblack@eecs.umich.edu                double d;
8086556Sgblack@eecs.umich.edu                uint64_t i;
8096556Sgblack@eecs.umich.edu            };
8106556Sgblack@eecs.umich.edu
8116556Sgblack@eecs.umich.edu            assert(srcSize == destSize);
8126556Sgblack@eecs.umich.edu            int size = srcSize;
8136556Sgblack@eecs.umich.edu            int sizeBits = size * 8;
8146556Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
8156556Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
8166556Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
8176556Sgblack@eecs.umich.edu
8186556Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8196556Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
8206556Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8216556Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
8226556Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
8236556Sgblack@eecs.umich.edu                uint64_t resBits;
8246556Sgblack@eecs.umich.edu
8256556Sgblack@eecs.umich.edu                if (size == 4) {
8266556Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
8276556Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8286556Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8296556Sgblack@eecs.umich.edu                    res.f = arg1.f - arg2.f;
8306556Sgblack@eecs.umich.edu                    resBits = res.i;
8316556Sgblack@eecs.umich.edu                } else {
8326556Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
8336556Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8346556Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8356556Sgblack@eecs.umich.edu                    res.d = arg1.d - arg2.d;
8366556Sgblack@eecs.umich.edu                    resBits = res.i;
8376556Sgblack@eecs.umich.edu                }
8386556Sgblack@eecs.umich.edu
8396556Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
8406556Sgblack@eecs.umich.edu            }
8416556Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
8426556Sgblack@eecs.umich.edu        '''
8436558Sgblack@eecs.umich.edu
8446558Sgblack@eecs.umich.edu    class Mmulf(MediaOp):
8456558Sgblack@eecs.umich.edu        code = '''
8466558Sgblack@eecs.umich.edu            union floatInt
8476558Sgblack@eecs.umich.edu            {
8486558Sgblack@eecs.umich.edu                float f;
8496558Sgblack@eecs.umich.edu                uint32_t i;
8506558Sgblack@eecs.umich.edu            };
8516558Sgblack@eecs.umich.edu            union doubleInt
8526558Sgblack@eecs.umich.edu            {
8536558Sgblack@eecs.umich.edu                double d;
8546558Sgblack@eecs.umich.edu                uint64_t i;
8556558Sgblack@eecs.umich.edu            };
8566558Sgblack@eecs.umich.edu
8576558Sgblack@eecs.umich.edu            assert(srcSize == destSize);
8586558Sgblack@eecs.umich.edu            int size = srcSize;
8596558Sgblack@eecs.umich.edu            int sizeBits = size * 8;
8606558Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
8616558Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
8626558Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
8636558Sgblack@eecs.umich.edu
8646558Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8656558Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
8666558Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8676558Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
8686558Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
8696558Sgblack@eecs.umich.edu                uint64_t resBits;
8706558Sgblack@eecs.umich.edu
8716558Sgblack@eecs.umich.edu                if (size == 4) {
8726558Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
8736558Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8746558Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8756558Sgblack@eecs.umich.edu                    res.f = arg1.f * arg2.f;
8766558Sgblack@eecs.umich.edu                    resBits = res.i;
8776558Sgblack@eecs.umich.edu                } else {
8786558Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
8796558Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8806558Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8816558Sgblack@eecs.umich.edu                    res.d = arg1.d * arg2.d;
8826558Sgblack@eecs.umich.edu                    resBits = res.i;
8836558Sgblack@eecs.umich.edu                }
8846558Sgblack@eecs.umich.edu
8856558Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
8866558Sgblack@eecs.umich.edu            }
8876558Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
8886558Sgblack@eecs.umich.edu        '''
8896560Sgblack@eecs.umich.edu
8906560Sgblack@eecs.umich.edu    class Mdivf(MediaOp):
8916560Sgblack@eecs.umich.edu        code = '''
8926560Sgblack@eecs.umich.edu            union floatInt
8936560Sgblack@eecs.umich.edu            {
8946560Sgblack@eecs.umich.edu                float f;
8956560Sgblack@eecs.umich.edu                uint32_t i;
8966560Sgblack@eecs.umich.edu            };
8976560Sgblack@eecs.umich.edu            union doubleInt
8986560Sgblack@eecs.umich.edu            {
8996560Sgblack@eecs.umich.edu                double d;
9006560Sgblack@eecs.umich.edu                uint64_t i;
9016560Sgblack@eecs.umich.edu            };
9026560Sgblack@eecs.umich.edu
9036560Sgblack@eecs.umich.edu            assert(srcSize == destSize);
9046560Sgblack@eecs.umich.edu            int size = srcSize;
9056560Sgblack@eecs.umich.edu            int sizeBits = size * 8;
9066560Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
9076560Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
9086560Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
9096560Sgblack@eecs.umich.edu
9106560Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9116560Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
9126560Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
9136560Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
9146560Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
9156560Sgblack@eecs.umich.edu                uint64_t resBits;
9166560Sgblack@eecs.umich.edu
9176560Sgblack@eecs.umich.edu                if (size == 4) {
9186560Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
9196560Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
9206560Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
9216560Sgblack@eecs.umich.edu                    res.f = arg1.f / arg2.f;
9226560Sgblack@eecs.umich.edu                    resBits = res.i;
9236560Sgblack@eecs.umich.edu                } else {
9246560Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
9256560Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
9266560Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
9276560Sgblack@eecs.umich.edu                    res.d = arg1.d / arg2.d;
9286560Sgblack@eecs.umich.edu                    resBits = res.i;
9296560Sgblack@eecs.umich.edu                }
9306560Sgblack@eecs.umich.edu
9316560Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
9326560Sgblack@eecs.umich.edu            }
9336560Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
9346560Sgblack@eecs.umich.edu        '''
9356562Sgblack@eecs.umich.edu
9366570Sgblack@eecs.umich.edu    class Maddi(MediaOp):
9376570Sgblack@eecs.umich.edu        code = '''
9386570Sgblack@eecs.umich.edu            assert(srcSize == destSize);
9396570Sgblack@eecs.umich.edu            int size = srcSize;
9406570Sgblack@eecs.umich.edu            int sizeBits = size * 8;
9416570Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
9426570Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
9436570Sgblack@eecs.umich.edu
9446570Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9456570Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
9466570Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
9476570Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
9486570Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
9496570Sgblack@eecs.umich.edu                uint64_t resBits = arg1Bits + arg2Bits;
9506570Sgblack@eecs.umich.edu                
9516570Sgblack@eecs.umich.edu                if (ext & 0x2) {
9526570Sgblack@eecs.umich.edu                    if (findCarry(sizeBits, resBits, arg1Bits, arg2Bits))
9536570Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
9546570Sgblack@eecs.umich.edu                } else if (ext & 0x4) {
9556570Sgblack@eecs.umich.edu                    int arg1Sign = bits(arg1Bits, sizeBits - 1);
9566570Sgblack@eecs.umich.edu                    int arg2Sign = bits(arg2Bits, sizeBits - 1);
9576570Sgblack@eecs.umich.edu                    int resSign = bits(resBits, sizeBits - 1);
9586570Sgblack@eecs.umich.edu                    if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
9596570Sgblack@eecs.umich.edu                        if (resSign == 0)
9606570Sgblack@eecs.umich.edu                            resBits = (1 << (sizeBits - 1));
9616570Sgblack@eecs.umich.edu                        else
9626570Sgblack@eecs.umich.edu                            resBits = mask(sizeBits - 1);
9636570Sgblack@eecs.umich.edu                    }
9646570Sgblack@eecs.umich.edu                }
9656570Sgblack@eecs.umich.edu
9666570Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
9676570Sgblack@eecs.umich.edu            }
9686570Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
9696570Sgblack@eecs.umich.edu        '''
9706570Sgblack@eecs.umich.edu
9716579Sgblack@eecs.umich.edu    class Msubi(MediaOp):
9726579Sgblack@eecs.umich.edu        code = '''
9736579Sgblack@eecs.umich.edu            assert(srcSize == destSize);
9746579Sgblack@eecs.umich.edu            int size = srcSize;
9756579Sgblack@eecs.umich.edu            int sizeBits = size * 8;
9766579Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
9776579Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
9786579Sgblack@eecs.umich.edu
9796579Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9806579Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
9816579Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
9826579Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
9836579Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
9846579Sgblack@eecs.umich.edu                uint64_t resBits = arg1Bits - arg2Bits;
9856579Sgblack@eecs.umich.edu                
9866579Sgblack@eecs.umich.edu                if (ext & 0x2) {
9876579Sgblack@eecs.umich.edu                    if (arg2Bits > arg1Bits) {
9886579Sgblack@eecs.umich.edu                        resBits = 0;
9896579Sgblack@eecs.umich.edu                    } else if (!findCarry(sizeBits, resBits,
9906579Sgblack@eecs.umich.edu                                         arg1Bits, ~arg2Bits)) {
9916579Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
9926579Sgblack@eecs.umich.edu                    }
9936579Sgblack@eecs.umich.edu                } else if (ext & 0x4) {
9946579Sgblack@eecs.umich.edu                    int arg1Sign = bits(arg1Bits, sizeBits - 1);
9956579Sgblack@eecs.umich.edu                    int arg2Sign = !bits(arg2Bits, sizeBits - 1);
9966579Sgblack@eecs.umich.edu                    int resSign = bits(resBits, sizeBits - 1);
9976579Sgblack@eecs.umich.edu                    if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
9986579Sgblack@eecs.umich.edu                        if (resSign == 0)
9996579Sgblack@eecs.umich.edu                            resBits = (1 << (sizeBits - 1));
10006579Sgblack@eecs.umich.edu                        else
10016579Sgblack@eecs.umich.edu                            resBits = mask(sizeBits - 1);
10026579Sgblack@eecs.umich.edu                    }
10036579Sgblack@eecs.umich.edu                }
10046579Sgblack@eecs.umich.edu
10056579Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
10066579Sgblack@eecs.umich.edu            }
10076579Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
10086579Sgblack@eecs.umich.edu        '''
10096579Sgblack@eecs.umich.edu
10106577Sgblack@eecs.umich.edu    class Mmuli(MediaOp):
10116577Sgblack@eecs.umich.edu        code = '''
10126577Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
10136577Sgblack@eecs.umich.edu            int destBits = destSize * 8;
10146577Sgblack@eecs.umich.edu            assert(destBits <= 64);
10156577Sgblack@eecs.umich.edu            assert(destSize >= srcSize);
10166577Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / destSize);
10176577Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
10186577Sgblack@eecs.umich.edu
10196577Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10206585Sgblack@eecs.umich.edu                int offset = 0;
10216585Sgblack@eecs.umich.edu                if (ext & 16) {
10226585Sgblack@eecs.umich.edu                    if (ext & 32)
10236585Sgblack@eecs.umich.edu                        offset = i * (destBits - srcBits);
10246585Sgblack@eecs.umich.edu                    else
10256585Sgblack@eecs.umich.edu                        offset = i * (destBits - srcBits) + srcBits;
10266585Sgblack@eecs.umich.edu                }
10276585Sgblack@eecs.umich.edu                int srcHiIndex = (i + 1) * srcBits - 1 + offset;
10286585Sgblack@eecs.umich.edu                int srcLoIndex = (i + 0) * srcBits + offset;
10296577Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
10306577Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, srcHiIndex, srcLoIndex);
10316577Sgblack@eecs.umich.edu                uint64_t resBits;
10326577Sgblack@eecs.umich.edu
10336577Sgblack@eecs.umich.edu                if (ext & 0x2) {
10346577Sgblack@eecs.umich.edu                    int64_t arg1 = arg1Bits |
10356577Sgblack@eecs.umich.edu                        (0 - (arg1Bits & (1 << (srcBits - 1))));
10366577Sgblack@eecs.umich.edu                    int64_t arg2 = arg2Bits |
10376577Sgblack@eecs.umich.edu                        (0 - (arg2Bits & (1 << (srcBits - 1))));
10386577Sgblack@eecs.umich.edu                    resBits = (uint64_t)(arg1 * arg2);
10396577Sgblack@eecs.umich.edu                } else {
10406577Sgblack@eecs.umich.edu                    resBits = arg1Bits * arg2Bits;
10416577Sgblack@eecs.umich.edu                }
10426577Sgblack@eecs.umich.edu
10436577Sgblack@eecs.umich.edu                if (ext & 0x4)
10446577Sgblack@eecs.umich.edu                    resBits += (1 << (destBits - 1));
10456577Sgblack@eecs.umich.edu                
10466577Sgblack@eecs.umich.edu                if (ext & 0x8)
10476577Sgblack@eecs.umich.edu                    resBits >>= destBits;
10486577Sgblack@eecs.umich.edu
10496577Sgblack@eecs.umich.edu                int destHiIndex = (i + 1) * destBits - 1;
10506577Sgblack@eecs.umich.edu                int destLoIndex = (i + 0) * destBits;
10516577Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, resBits);
10526577Sgblack@eecs.umich.edu            }
10536577Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
10546577Sgblack@eecs.umich.edu        '''
10556577Sgblack@eecs.umich.edu
10566587Sgblack@eecs.umich.edu    class Mavg(MediaOp):
10576587Sgblack@eecs.umich.edu        code = '''
10586587Sgblack@eecs.umich.edu            assert(srcSize == destSize);
10596587Sgblack@eecs.umich.edu            int size = srcSize;
10606587Sgblack@eecs.umich.edu            int sizeBits = size * 8;
10616587Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
10626587Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
10636587Sgblack@eecs.umich.edu
10646587Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10656587Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
10666587Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
10676587Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
10686587Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
10696587Sgblack@eecs.umich.edu                uint64_t resBits = (arg1Bits + arg2Bits + 1) / 2;
10706587Sgblack@eecs.umich.edu                
10716587Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
10726587Sgblack@eecs.umich.edu            }
10736587Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
10746587Sgblack@eecs.umich.edu        '''
10756587Sgblack@eecs.umich.edu
10766581Sgblack@eecs.umich.edu    class Msad(MediaOp):
10776581Sgblack@eecs.umich.edu        code = '''
10786581Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
10796581Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / srcSize;
10806581Sgblack@eecs.umich.edu
10816581Sgblack@eecs.umich.edu            uint64_t sum = 0;
10826581Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10836581Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * srcBits - 1;
10846581Sgblack@eecs.umich.edu                int loIndex = (i + 0) * srcBits;
10856581Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
10866581Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
10876581Sgblack@eecs.umich.edu                int64_t resBits = arg1Bits - arg2Bits;
10886581Sgblack@eecs.umich.edu                if (resBits < 0)
10896581Sgblack@eecs.umich.edu                    resBits = -resBits;
10906581Sgblack@eecs.umich.edu                sum += resBits;
10916581Sgblack@eecs.umich.edu            }
10926581Sgblack@eecs.umich.edu            FpDestReg.uqw = sum & mask(destSize * 8);
10936581Sgblack@eecs.umich.edu        '''
10946581Sgblack@eecs.umich.edu
10956583Sgblack@eecs.umich.edu    class Msrl(MediaOp):
10966583Sgblack@eecs.umich.edu        code = '''
10976583Sgblack@eecs.umich.edu
10986583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
10996583Sgblack@eecs.umich.edu            int size = srcSize;
11006583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
11016583Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
11026583Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2.uqw;
11036583Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
11046583Sgblack@eecs.umich.edu
11056583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
11066583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
11076583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
11086583Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
11096583Sgblack@eecs.umich.edu                uint64_t resBits;
11106583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
11116583Sgblack@eecs.umich.edu                    resBits = 0;
11126583Sgblack@eecs.umich.edu                } else {
11136583Sgblack@eecs.umich.edu                    resBits = (arg1Bits >> shiftAmt) &
11146583Sgblack@eecs.umich.edu                        mask(sizeBits - shiftAmt);
11156583Sgblack@eecs.umich.edu                }
11166583Sgblack@eecs.umich.edu
11176583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
11186583Sgblack@eecs.umich.edu            }
11196583Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
11206583Sgblack@eecs.umich.edu        '''
11216583Sgblack@eecs.umich.edu
11226583Sgblack@eecs.umich.edu    class Msra(MediaOp):
11236583Sgblack@eecs.umich.edu        code = '''
11246583Sgblack@eecs.umich.edu
11256583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
11266583Sgblack@eecs.umich.edu            int size = srcSize;
11276583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
11286583Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
11296583Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2.uqw;
11306583Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
11316583Sgblack@eecs.umich.edu
11326583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
11336583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
11346583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
11356583Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
11366583Sgblack@eecs.umich.edu                uint64_t resBits;
11376583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
11386583Sgblack@eecs.umich.edu                    if (bits(arg1Bits, sizeBits - 1))
11396583Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
11406583Sgblack@eecs.umich.edu                    else
11416583Sgblack@eecs.umich.edu                        resBits = 0;
11426583Sgblack@eecs.umich.edu                } else {
11436583Sgblack@eecs.umich.edu                    resBits = (arg1Bits >> shiftAmt);
11446583Sgblack@eecs.umich.edu                    resBits = resBits |
11456583Sgblack@eecs.umich.edu                        (0 - (resBits & (1 << (sizeBits - 1 - shiftAmt))));
11466583Sgblack@eecs.umich.edu                }
11476583Sgblack@eecs.umich.edu
11486583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
11496583Sgblack@eecs.umich.edu            }
11506583Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
11516583Sgblack@eecs.umich.edu        '''
11526583Sgblack@eecs.umich.edu
11536583Sgblack@eecs.umich.edu    class Msll(MediaOp):
11546583Sgblack@eecs.umich.edu        code = '''
11556583Sgblack@eecs.umich.edu
11566583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
11576583Sgblack@eecs.umich.edu            int size = srcSize;
11586583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
11596583Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
11606583Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2.uqw;
11616583Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
11626583Sgblack@eecs.umich.edu
11636583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
11646583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
11656583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
11666583Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
11676583Sgblack@eecs.umich.edu                uint64_t resBits;
11686583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
11696583Sgblack@eecs.umich.edu                    resBits = 0;
11706583Sgblack@eecs.umich.edu                } else {
11716583Sgblack@eecs.umich.edu                    resBits = (arg1Bits << shiftAmt);
11726583Sgblack@eecs.umich.edu                }
11736583Sgblack@eecs.umich.edu
11746583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
11756583Sgblack@eecs.umich.edu            }
11766583Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
11776583Sgblack@eecs.umich.edu        '''
11786583Sgblack@eecs.umich.edu
11796605Sgblack@eecs.umich.edu    class Cvtf2i(MediaOp):
11806605Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
11816605Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
11826605Sgblack@eecs.umich.edu            super(Cvtf2i, self).__init__(dest, src,\
11836605Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
11846605Sgblack@eecs.umich.edu        code = '''
11856605Sgblack@eecs.umich.edu            union floatInt
11866605Sgblack@eecs.umich.edu            {
11876605Sgblack@eecs.umich.edu                float f;
11886605Sgblack@eecs.umich.edu                uint32_t i;
11896605Sgblack@eecs.umich.edu            };
11906605Sgblack@eecs.umich.edu            union doubleInt
11916605Sgblack@eecs.umich.edu            {
11926605Sgblack@eecs.umich.edu                double d;
11936605Sgblack@eecs.umich.edu                uint64_t i;
11946605Sgblack@eecs.umich.edu            };
11956605Sgblack@eecs.umich.edu
11966605Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
11976605Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
11986605Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
11996605Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
12006605Sgblack@eecs.umich.edu            int items;
12016605Sgblack@eecs.umich.edu            int srcStart = 0;
12026605Sgblack@eecs.umich.edu            int destStart = 0;
12036605Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
12046605Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / srcSize;
12056605Sgblack@eecs.umich.edu                if (ext & 0x2)
12066605Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
12076605Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
12086605Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
12096605Sgblack@eecs.umich.edu                if (ext & 0x2)
12106605Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
12116605Sgblack@eecs.umich.edu            } else {
12126605Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
12136605Sgblack@eecs.umich.edu            }
12146605Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
12156605Sgblack@eecs.umich.edu
12166605Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
12176605Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
12186605Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
12196605Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
12206605Sgblack@eecs.umich.edu                double arg;
12216605Sgblack@eecs.umich.edu
12226605Sgblack@eecs.umich.edu                if (srcSize == 4) {
12236605Sgblack@eecs.umich.edu                    floatInt fi;
12246605Sgblack@eecs.umich.edu                    fi.i = argBits;
12256605Sgblack@eecs.umich.edu                    arg = fi.f;
12266605Sgblack@eecs.umich.edu                } else {
12276605Sgblack@eecs.umich.edu                    doubleInt di;
12286605Sgblack@eecs.umich.edu                    di.i = argBits;
12296605Sgblack@eecs.umich.edu                    arg = di.d;
12306605Sgblack@eecs.umich.edu                }
12316605Sgblack@eecs.umich.edu
12326605Sgblack@eecs.umich.edu                if (ext & 0x4) {
12336605Sgblack@eecs.umich.edu                    if (arg >= 0)
12346605Sgblack@eecs.umich.edu                        arg += 0.5;
12356605Sgblack@eecs.umich.edu                    else
12366605Sgblack@eecs.umich.edu                        arg -= 0.5;
12376605Sgblack@eecs.umich.edu                }
12386605Sgblack@eecs.umich.edu
12396605Sgblack@eecs.umich.edu                if (destSize == 4) {
12406605Sgblack@eecs.umich.edu                    argBits = (uint32_t)(float)arg;
12416605Sgblack@eecs.umich.edu                } else {
12426605Sgblack@eecs.umich.edu                    argBits = (uint64_t)arg;
12436605Sgblack@eecs.umich.edu                }
12446605Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
12456605Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
12466605Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
12476605Sgblack@eecs.umich.edu            }
12486605Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
12496605Sgblack@eecs.umich.edu        '''
12506605Sgblack@eecs.umich.edu
12516562Sgblack@eecs.umich.edu    class Cvti2f(MediaOp):
12526562Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
12536562Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
12546562Sgblack@eecs.umich.edu            super(Cvti2f, self).__init__(dest, src,\
12556562Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
12566562Sgblack@eecs.umich.edu        code = '''
12576562Sgblack@eecs.umich.edu            union floatInt
12586562Sgblack@eecs.umich.edu            {
12596562Sgblack@eecs.umich.edu                float f;
12606562Sgblack@eecs.umich.edu                uint32_t i;
12616562Sgblack@eecs.umich.edu            };
12626562Sgblack@eecs.umich.edu            union doubleInt
12636562Sgblack@eecs.umich.edu            {
12646562Sgblack@eecs.umich.edu                double d;
12656562Sgblack@eecs.umich.edu                uint64_t i;
12666562Sgblack@eecs.umich.edu            };
12676562Sgblack@eecs.umich.edu
12686562Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
12696562Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
12706562Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
12716562Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
12726562Sgblack@eecs.umich.edu            int items;
12736562Sgblack@eecs.umich.edu            int srcStart = 0;
12746562Sgblack@eecs.umich.edu            int destStart = 0;
12756562Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
12766562Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / srcSize;
12776562Sgblack@eecs.umich.edu                if (ext & 0x2)
12786562Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
12796562Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
12806562Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
12816562Sgblack@eecs.umich.edu                if (ext & 0x2)
12826562Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
12836562Sgblack@eecs.umich.edu            } else {
12846562Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
12856562Sgblack@eecs.umich.edu            }
12866562Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
12876562Sgblack@eecs.umich.edu
12886562Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
12896562Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
12906562Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
12916562Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
12926562Sgblack@eecs.umich.edu                int64_t sArg = argBits | (0 - (argBits & (1 << srcHiIndex)));
12936562Sgblack@eecs.umich.edu                double arg = sArg;
12946562Sgblack@eecs.umich.edu
12956562Sgblack@eecs.umich.edu                if (destSize == 4) {
12966562Sgblack@eecs.umich.edu                    floatInt fi;
12976562Sgblack@eecs.umich.edu                    fi.f = arg;
12986562Sgblack@eecs.umich.edu                    argBits = fi.i;
12996562Sgblack@eecs.umich.edu                } else {
13006562Sgblack@eecs.umich.edu                    doubleInt di;
13016562Sgblack@eecs.umich.edu                    di.d = arg;
13026562Sgblack@eecs.umich.edu                    argBits = di.i;
13036562Sgblack@eecs.umich.edu                }
13046562Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
13056562Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
13066562Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
13076562Sgblack@eecs.umich.edu            }
13086562Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
13096562Sgblack@eecs.umich.edu        '''
13106566Sgblack@eecs.umich.edu
13116568Sgblack@eecs.umich.edu    class Cvtf2f(MediaOp):
13126568Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
13136568Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
13146568Sgblack@eecs.umich.edu            super(Cvtf2f, self).__init__(dest, src,\
13156568Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
13166568Sgblack@eecs.umich.edu        code = '''
13176568Sgblack@eecs.umich.edu            union floatInt
13186568Sgblack@eecs.umich.edu            {
13196568Sgblack@eecs.umich.edu                float f;
13206568Sgblack@eecs.umich.edu                uint32_t i;
13216568Sgblack@eecs.umich.edu            };
13226568Sgblack@eecs.umich.edu            union doubleInt
13236568Sgblack@eecs.umich.edu            {
13246568Sgblack@eecs.umich.edu                double d;
13256568Sgblack@eecs.umich.edu                uint64_t i;
13266568Sgblack@eecs.umich.edu            };
13276568Sgblack@eecs.umich.edu
13286568Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
13296568Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
13306568Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
13316568Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
13326568Sgblack@eecs.umich.edu            int items;
13336568Sgblack@eecs.umich.edu            int srcStart = 0;
13346568Sgblack@eecs.umich.edu            int destStart = 0;
13356568Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
13366568Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / srcSize;
13376568Sgblack@eecs.umich.edu                if (ext & 0x2)
13386568Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
13396568Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
13406568Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
13416568Sgblack@eecs.umich.edu                if (ext & 0x2)
13426568Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
13436568Sgblack@eecs.umich.edu            } else {
13446568Sgblack@eecs.umich.edu                items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
13456568Sgblack@eecs.umich.edu            }
13466568Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
13476568Sgblack@eecs.umich.edu
13486568Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
13496568Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
13506568Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
13516568Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
13526568Sgblack@eecs.umich.edu                double arg;
13536568Sgblack@eecs.umich.edu
13546568Sgblack@eecs.umich.edu                if (srcSize == 4) {
13556568Sgblack@eecs.umich.edu                    floatInt fi;
13566568Sgblack@eecs.umich.edu                    fi.i = argBits;
13576568Sgblack@eecs.umich.edu                    arg = fi.f;
13586568Sgblack@eecs.umich.edu                } else {
13596568Sgblack@eecs.umich.edu                    doubleInt di;
13606568Sgblack@eecs.umich.edu                    di.i = argBits;
13616568Sgblack@eecs.umich.edu                    arg = di.d;
13626568Sgblack@eecs.umich.edu                }
13636568Sgblack@eecs.umich.edu                if (destSize == 4) {
13646568Sgblack@eecs.umich.edu                    floatInt fi;
13656568Sgblack@eecs.umich.edu                    fi.f = arg;
13666568Sgblack@eecs.umich.edu                    argBits = fi.i;
13676568Sgblack@eecs.umich.edu                } else {
13686568Sgblack@eecs.umich.edu                    doubleInt di;
13696568Sgblack@eecs.umich.edu                    di.d = arg;
13706568Sgblack@eecs.umich.edu                    argBits = di.i;
13716568Sgblack@eecs.umich.edu                }
13726568Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
13736568Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
13746568Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
13756568Sgblack@eecs.umich.edu            }
13766568Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
13776568Sgblack@eecs.umich.edu        '''
13786568Sgblack@eecs.umich.edu
13796566Sgblack@eecs.umich.edu    class Mcmpi2r(MediaOp):
13806566Sgblack@eecs.umich.edu        code = '''
13816566Sgblack@eecs.umich.edu            union floatInt
13826566Sgblack@eecs.umich.edu            {
13836566Sgblack@eecs.umich.edu                float f;
13846566Sgblack@eecs.umich.edu                uint32_t i;
13856566Sgblack@eecs.umich.edu            };
13866566Sgblack@eecs.umich.edu            union doubleInt
13876566Sgblack@eecs.umich.edu            {
13886566Sgblack@eecs.umich.edu                double d;
13896566Sgblack@eecs.umich.edu                uint64_t i;
13906566Sgblack@eecs.umich.edu            };
13916566Sgblack@eecs.umich.edu
13926566Sgblack@eecs.umich.edu            assert(srcSize == destSize);
13936566Sgblack@eecs.umich.edu            int size = srcSize;
13946566Sgblack@eecs.umich.edu            int sizeBits = size * 8;
13956566Sgblack@eecs.umich.edu            int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
13966566Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
13976566Sgblack@eecs.umich.edu
13986566Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
13996566Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
14006566Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
14016566Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
14026566Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
14036566Sgblack@eecs.umich.edu                    (0 - (arg1Bits & (1 << (sizeBits - 1))));
14046566Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
14056566Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
14066566Sgblack@eecs.umich.edu                    (0 - (arg2Bits & (1 << (sizeBits - 1))));
14076566Sgblack@eecs.umich.edu
14086566Sgblack@eecs.umich.edu                uint64_t resBits = 0;
14096622Snate@binkert.org                if (((ext & 0x2) == 0 && arg1 == arg2) ||
14106622Snate@binkert.org                    ((ext & 0x2) == 0x2 && arg1 > arg2))
14116566Sgblack@eecs.umich.edu                    resBits = mask(sizeBits);
14126566Sgblack@eecs.umich.edu
14136566Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
14146566Sgblack@eecs.umich.edu            }
14156566Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
14166566Sgblack@eecs.umich.edu        '''
14176601Sgblack@eecs.umich.edu
14186603Sgblack@eecs.umich.edu    class Mcmpf2r(MediaOp):
14196603Sgblack@eecs.umich.edu        code = '''
14206603Sgblack@eecs.umich.edu            union floatInt
14216603Sgblack@eecs.umich.edu            {
14226603Sgblack@eecs.umich.edu                float f;
14236603Sgblack@eecs.umich.edu                uint32_t i;
14246603Sgblack@eecs.umich.edu            };
14256603Sgblack@eecs.umich.edu            union doubleInt
14266603Sgblack@eecs.umich.edu            {
14276603Sgblack@eecs.umich.edu                double d;
14286603Sgblack@eecs.umich.edu                uint64_t i;
14296603Sgblack@eecs.umich.edu            };
14306603Sgblack@eecs.umich.edu
14316603Sgblack@eecs.umich.edu            assert(srcSize == destSize);
14326603Sgblack@eecs.umich.edu            int size = srcSize;
14336603Sgblack@eecs.umich.edu            int sizeBits = size * 8;
14346603Sgblack@eecs.umich.edu            int items = (ext & 0x8) ? 1: (sizeof(FloatRegBits) / size);
14356603Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
14366603Sgblack@eecs.umich.edu
14376603Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
14386603Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
14396603Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
14406603Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
14416603Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
14426603Sgblack@eecs.umich.edu                double arg1, arg2;
14436603Sgblack@eecs.umich.edu
14446603Sgblack@eecs.umich.edu                if (size == 4) {
14456603Sgblack@eecs.umich.edu                    floatInt fi;
14466603Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
14476603Sgblack@eecs.umich.edu                    arg1 = fi.f;
14486603Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
14496603Sgblack@eecs.umich.edu                    arg2 = fi.f;
14506603Sgblack@eecs.umich.edu                } else {
14516603Sgblack@eecs.umich.edu                    doubleInt di;
14526603Sgblack@eecs.umich.edu                    di.i = arg1Bits;
14536603Sgblack@eecs.umich.edu                    arg1 = di.d;
14546603Sgblack@eecs.umich.edu                    di.i = arg2Bits;
14556603Sgblack@eecs.umich.edu                    arg2 = di.d;
14566603Sgblack@eecs.umich.edu                }
14576603Sgblack@eecs.umich.edu
14586603Sgblack@eecs.umich.edu                uint64_t resBits = 0;
14596603Sgblack@eecs.umich.edu                bool nanop = isnan(arg1) || isnan(arg2);
14606603Sgblack@eecs.umich.edu                switch (ext & mask(3)) {
14616603Sgblack@eecs.umich.edu                  case 0:
14626603Sgblack@eecs.umich.edu                    if (arg1 == arg2 && !nanop)
14636603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14646603Sgblack@eecs.umich.edu                    break;
14656603Sgblack@eecs.umich.edu                  case 1:
14666603Sgblack@eecs.umich.edu                    if (arg1 < arg2 && !nanop)
14676603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14686603Sgblack@eecs.umich.edu                    break;
14696603Sgblack@eecs.umich.edu                  case 2:
14706603Sgblack@eecs.umich.edu                    if (arg1 <= arg2 && !nanop)
14716603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14726603Sgblack@eecs.umich.edu                    break;
14736603Sgblack@eecs.umich.edu                  case 3:
14746603Sgblack@eecs.umich.edu                    if (nanop)
14756603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14766603Sgblack@eecs.umich.edu                    break;
14776603Sgblack@eecs.umich.edu                  case 4:
14786603Sgblack@eecs.umich.edu                    if (arg1 != arg2 || nanop)
14796603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14806603Sgblack@eecs.umich.edu                    break;
14816603Sgblack@eecs.umich.edu                  case 5:
14826603Sgblack@eecs.umich.edu                    if (!(arg1 < arg2) || nanop)
14836603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14846603Sgblack@eecs.umich.edu                    break;
14856603Sgblack@eecs.umich.edu                  case 6:
14866603Sgblack@eecs.umich.edu                    if (!(arg1 <= arg2) || nanop)
14876603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14886603Sgblack@eecs.umich.edu                    break;
14896603Sgblack@eecs.umich.edu                  case 7:
14906603Sgblack@eecs.umich.edu                    if (!nanop)
14916603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14926603Sgblack@eecs.umich.edu                    break;
14936603Sgblack@eecs.umich.edu                };
14946603Sgblack@eecs.umich.edu
14956603Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
14966603Sgblack@eecs.umich.edu            }
14976603Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
14986603Sgblack@eecs.umich.edu        '''
14996603Sgblack@eecs.umich.edu
15006601Sgblack@eecs.umich.edu    class Mcmpf2rf(MediaOp):
15016601Sgblack@eecs.umich.edu        def __init__(self, src1, src2,\
15026601Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
15036601Sgblack@eecs.umich.edu            super(Mcmpf2rf, self).__init__("InstRegIndex(0)", src1,\
15046601Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
15056601Sgblack@eecs.umich.edu        code = '''
15066601Sgblack@eecs.umich.edu            union floatInt
15076601Sgblack@eecs.umich.edu            {
15086601Sgblack@eecs.umich.edu                float f;
15096601Sgblack@eecs.umich.edu                uint32_t i;
15106601Sgblack@eecs.umich.edu            };
15116601Sgblack@eecs.umich.edu            union doubleInt
15126601Sgblack@eecs.umich.edu            {
15136601Sgblack@eecs.umich.edu                double d;
15146601Sgblack@eecs.umich.edu                uint64_t i;
15156601Sgblack@eecs.umich.edu            };
15166601Sgblack@eecs.umich.edu
15176601Sgblack@eecs.umich.edu            assert(srcSize == destSize);
15186601Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
15196601Sgblack@eecs.umich.edu            int size = srcSize;
15206601Sgblack@eecs.umich.edu            int sizeBits = size * 8;
15216601Sgblack@eecs.umich.edu
15226601Sgblack@eecs.umich.edu            double arg1, arg2;
15236601Sgblack@eecs.umich.edu            uint64_t arg1Bits = bits(FpSrcReg1.uqw, sizeBits - 1, 0);
15246601Sgblack@eecs.umich.edu            uint64_t arg2Bits = bits(FpSrcReg2.uqw, sizeBits - 1, 0);
15256601Sgblack@eecs.umich.edu            if (size == 4) {
15266601Sgblack@eecs.umich.edu                floatInt fi;
15276601Sgblack@eecs.umich.edu                fi.i = arg1Bits;
15286601Sgblack@eecs.umich.edu                arg1 = fi.f;
15296601Sgblack@eecs.umich.edu                fi.i = arg2Bits;
15306601Sgblack@eecs.umich.edu                arg2 = fi.f;
15316601Sgblack@eecs.umich.edu            } else {
15326601Sgblack@eecs.umich.edu                doubleInt di;
15336601Sgblack@eecs.umich.edu                di.i = arg1Bits;
15346601Sgblack@eecs.umich.edu                arg1 = di.d;
15356601Sgblack@eecs.umich.edu                di.i = arg2Bits;
15366601Sgblack@eecs.umich.edu                arg2 = di.d;
15376601Sgblack@eecs.umich.edu            }
15386601Sgblack@eecs.umich.edu
15396601Sgblack@eecs.umich.edu            //               ZF PF CF
15406601Sgblack@eecs.umich.edu            // Unordered      1  1  1
15416601Sgblack@eecs.umich.edu            // Greater than   0  0  0
15426601Sgblack@eecs.umich.edu            // Less than      0  0  1
15436601Sgblack@eecs.umich.edu            // Equal          1  0  0
15446601Sgblack@eecs.umich.edu            //           OF = SF = AF = 0
15456601Sgblack@eecs.umich.edu            ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit |
15466601Sgblack@eecs.umich.edu                                        ZFBit | PFBit | CFBit);
15476601Sgblack@eecs.umich.edu            if (isnan(arg1) || isnan(arg2))
15486601Sgblack@eecs.umich.edu                ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit);
15496601Sgblack@eecs.umich.edu            else if(arg1 < arg2)
15506601Sgblack@eecs.umich.edu                ccFlagBits = ccFlagBits | CFBit;
15516601Sgblack@eecs.umich.edu            else if(arg1 == arg2)
15526601Sgblack@eecs.umich.edu                ccFlagBits = ccFlagBits | ZFBit;
15536601Sgblack@eecs.umich.edu        '''
15546516Sgblack@eecs.umich.edu}};
1555