111160Ssteve.reinhardt@amd.com// Copyright (c) 2009 The Regents of The University of Michigan
211160Ssteve.reinhardt@amd.com// Copyright (c) 2015 Advanced Micro Devices, Inc.
311160Ssteve.reinhardt@amd.com//
46516Sgblack@eecs.umich.edu// All rights reserved.
56516Sgblack@eecs.umich.edu//
66516Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
76516Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
86516Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
96516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
106516Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
116516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
126516Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
136516Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
146516Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
156516Sgblack@eecs.umich.edu// this software without specific prior written permission.
166516Sgblack@eecs.umich.edu//
176516Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186516Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196516Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206516Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216516Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226516Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236516Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246516Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256516Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266516Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276516Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286516Sgblack@eecs.umich.edu//
296516Sgblack@eecs.umich.edu// Authors: Gabe Black
306516Sgblack@eecs.umich.edu
316516Sgblack@eecs.umich.edudef template MediaOpExecute {{
3212234Sgabeblack@google.com        Fault %(class_name)s::execute(ExecContext *xc,
336516Sgblack@eecs.umich.edu                Trace::InstRecord *traceData) const
346516Sgblack@eecs.umich.edu        {
356516Sgblack@eecs.umich.edu            Fault fault = NoFault;
366516Sgblack@eecs.umich.edu
376516Sgblack@eecs.umich.edu            %(op_decl)s;
386516Sgblack@eecs.umich.edu            %(op_rd)s;
396516Sgblack@eecs.umich.edu
406516Sgblack@eecs.umich.edu            %(code)s;
416516Sgblack@eecs.umich.edu
426516Sgblack@eecs.umich.edu            //Write the resulting state to the execution context
436516Sgblack@eecs.umich.edu            if(fault == NoFault)
446516Sgblack@eecs.umich.edu            {
456516Sgblack@eecs.umich.edu                %(op_wb)s;
466516Sgblack@eecs.umich.edu            }
476516Sgblack@eecs.umich.edu            return fault;
486516Sgblack@eecs.umich.edu        }
496516Sgblack@eecs.umich.edu}};
506516Sgblack@eecs.umich.edu
516516Sgblack@eecs.umich.edudef template MediaOpRegDeclare {{
526516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
536516Sgblack@eecs.umich.edu    {
546516Sgblack@eecs.umich.edu      public:
556516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
567620Sgblack@eecs.umich.edu                const char * instMnem, uint64_t setFlags,
576516Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
586545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
596516Sgblack@eecs.umich.edu
6012236Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
616516Sgblack@eecs.umich.edu    };
626516Sgblack@eecs.umich.edu}};
636516Sgblack@eecs.umich.edu
646516Sgblack@eecs.umich.edudef template MediaOpImmDeclare {{
656516Sgblack@eecs.umich.edu
666516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
676516Sgblack@eecs.umich.edu    {
686516Sgblack@eecs.umich.edu      public:
696516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
707620Sgblack@eecs.umich.edu                const char * instMnem, uint64_t setFlags,
716516Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
726545Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
736516Sgblack@eecs.umich.edu
7412236Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
756516Sgblack@eecs.umich.edu    };
766516Sgblack@eecs.umich.edu}};
776516Sgblack@eecs.umich.edu
786516Sgblack@eecs.umich.edudef template MediaOpRegConstructor {{
7910184SCurtis.Dunham@arm.com    %(class_name)s::%(class_name)s(
807620Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
816516Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
826545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
837620Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
846545Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _ext,
856516Sgblack@eecs.umich.edu                %(op_class)s)
866516Sgblack@eecs.umich.edu    {
877626Sgblack@eecs.umich.edu        %(constructor)s;
886516Sgblack@eecs.umich.edu    }
896516Sgblack@eecs.umich.edu}};
906516Sgblack@eecs.umich.edu
916516Sgblack@eecs.umich.edudef template MediaOpImmConstructor {{
9210184SCurtis.Dunham@arm.com    %(class_name)s::%(class_name)s(
937620Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
946516Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
956545Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
967620Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
976545Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _ext,
986516Sgblack@eecs.umich.edu                %(op_class)s)
996516Sgblack@eecs.umich.edu    {
1007626Sgblack@eecs.umich.edu        %(constructor)s;
1016516Sgblack@eecs.umich.edu    }
1026516Sgblack@eecs.umich.edu}};
1036516Sgblack@eecs.umich.edu
1046516Sgblack@eecs.umich.edulet {{
1056516Sgblack@eecs.umich.edu    # Make these empty strings so that concatenating onto
1066516Sgblack@eecs.umich.edu    # them will always work.
1076516Sgblack@eecs.umich.edu    header_output = ""
1086516Sgblack@eecs.umich.edu    decoder_output = ""
1096516Sgblack@eecs.umich.edu    exec_output = ""
1106516Sgblack@eecs.umich.edu
1116516Sgblack@eecs.umich.edu    immTemplates = (
1126516Sgblack@eecs.umich.edu            MediaOpImmDeclare,
1136516Sgblack@eecs.umich.edu            MediaOpImmConstructor,
1146516Sgblack@eecs.umich.edu            MediaOpExecute)
1156516Sgblack@eecs.umich.edu
1166516Sgblack@eecs.umich.edu    regTemplates = (
1176516Sgblack@eecs.umich.edu            MediaOpRegDeclare,
1186516Sgblack@eecs.umich.edu            MediaOpRegConstructor,
1196516Sgblack@eecs.umich.edu            MediaOpExecute)
1206516Sgblack@eecs.umich.edu
1216516Sgblack@eecs.umich.edu    class MediaOpMeta(type):
1226516Sgblack@eecs.umich.edu        def buildCppClasses(self, name, Name, suffix, code):
1236516Sgblack@eecs.umich.edu
1246516Sgblack@eecs.umich.edu            # Globals to stick the output in
1256516Sgblack@eecs.umich.edu            global header_output
1266516Sgblack@eecs.umich.edu            global decoder_output
1276516Sgblack@eecs.umich.edu            global exec_output
1286516Sgblack@eecs.umich.edu
1296516Sgblack@eecs.umich.edu            # If op2 is used anywhere, make register and immediate versions
1306516Sgblack@eecs.umich.edu            # of this code.
1318588Sgblack@eecs.umich.edu            matcher = re.compile(r"(?<!\w)(?P<prefix>s?)op2(?P<typeQual>_[^\W_]+)?")
1326516Sgblack@eecs.umich.edu            match = matcher.search(code)
1336516Sgblack@eecs.umich.edu            if match:
1346516Sgblack@eecs.umich.edu                typeQual = ""
1356516Sgblack@eecs.umich.edu                if match.group("typeQual"):
1366516Sgblack@eecs.umich.edu                    typeQual = match.group("typeQual")
1376583Sgblack@eecs.umich.edu                src2_name = "%sFpSrcReg2%s" % (match.group("prefix"), typeQual)
1386516Sgblack@eecs.umich.edu                self.buildCppClasses(name, Name, suffix,
1396516Sgblack@eecs.umich.edu                        matcher.sub(src2_name, code))
1406516Sgblack@eecs.umich.edu                self.buildCppClasses(name + "i", Name, suffix + "Imm",
1416516Sgblack@eecs.umich.edu                        matcher.sub("imm8", code))
1426516Sgblack@eecs.umich.edu                return
1436516Sgblack@eecs.umich.edu
1446516Sgblack@eecs.umich.edu            base = "X86ISA::MediaOp"
1456516Sgblack@eecs.umich.edu
1466516Sgblack@eecs.umich.edu            # If imm8 shows up in the code, use the immediate templates, if
1476516Sgblack@eecs.umich.edu            # not, hopefully the register ones will be correct.
1486516Sgblack@eecs.umich.edu            matcher = re.compile("(?<!\w)imm8(?!\w)")
1496516Sgblack@eecs.umich.edu            if matcher.search(code):
1506516Sgblack@eecs.umich.edu                base += "Imm"
1516516Sgblack@eecs.umich.edu                templates = immTemplates
1526516Sgblack@eecs.umich.edu            else:
1536516Sgblack@eecs.umich.edu                base += "Reg"
1546516Sgblack@eecs.umich.edu                templates = regTemplates
1556516Sgblack@eecs.umich.edu
1566516Sgblack@eecs.umich.edu            # Get everything ready for the substitution
15712707Sgabeblack@google.com            opt_args = []
15812707Sgabeblack@google.com            if self.op_class:
15912707Sgabeblack@google.com                opt_args.append(self.op_class)
16012707Sgabeblack@google.com            iop = InstObjParams(name, Name + suffix, base, {"code" : code},
16112707Sgabeblack@google.com                                opt_args)
1626516Sgblack@eecs.umich.edu
1636516Sgblack@eecs.umich.edu            # Generate the actual code (finally!)
1646516Sgblack@eecs.umich.edu            header_output += templates[0].subst(iop)
1656516Sgblack@eecs.umich.edu            decoder_output += templates[1].subst(iop)
1666516Sgblack@eecs.umich.edu            exec_output += templates[2].subst(iop)
1676516Sgblack@eecs.umich.edu
1686516Sgblack@eecs.umich.edu
1696516Sgblack@eecs.umich.edu        def __new__(mcls, Name, bases, dict):
1706516Sgblack@eecs.umich.edu            abstract = False
1716516Sgblack@eecs.umich.edu            name = Name.lower()
1726516Sgblack@eecs.umich.edu            if "abstract" in dict:
1736516Sgblack@eecs.umich.edu                abstract = dict['abstract']
1746516Sgblack@eecs.umich.edu                del dict['abstract']
17512707Sgabeblack@google.com            if not "op_class" in dict:
17612707Sgabeblack@google.com                dict["op_class"] = None
1776516Sgblack@eecs.umich.edu
1786516Sgblack@eecs.umich.edu            cls = super(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict)
1796516Sgblack@eecs.umich.edu            if not abstract:
1806516Sgblack@eecs.umich.edu                cls.className = Name
1816516Sgblack@eecs.umich.edu                cls.base_mnemonic = name
1826516Sgblack@eecs.umich.edu                code = cls.code
1836516Sgblack@eecs.umich.edu
1846516Sgblack@eecs.umich.edu                # Set up the C++ classes
1856516Sgblack@eecs.umich.edu                mcls.buildCppClasses(cls, name, Name, "", code)
1866516Sgblack@eecs.umich.edu
1876516Sgblack@eecs.umich.edu                # Hook into the microassembler dict
1886516Sgblack@eecs.umich.edu                global microopClasses
1896516Sgblack@eecs.umich.edu                microopClasses[name] = cls
1906516Sgblack@eecs.umich.edu
1916516Sgblack@eecs.umich.edu                # If op2 is used anywhere, make register and immediate versions
1926516Sgblack@eecs.umich.edu                # of this code.
1938588Sgblack@eecs.umich.edu                matcher = re.compile(r"op2(?P<typeQual>_[^\W_]+)?")
1946516Sgblack@eecs.umich.edu                if matcher.search(code):
1956516Sgblack@eecs.umich.edu                    microopClasses[name + 'i'] = cls
1966516Sgblack@eecs.umich.edu            return cls
1976516Sgblack@eecs.umich.edu
1986516Sgblack@eecs.umich.edu
1996516Sgblack@eecs.umich.edu    class MediaOp(X86Microop):
2006516Sgblack@eecs.umich.edu        __metaclass__ = MediaOpMeta
2016516Sgblack@eecs.umich.edu        # This class itself doesn't act as a microop
2026516Sgblack@eecs.umich.edu        abstract = True
2036516Sgblack@eecs.umich.edu
2046516Sgblack@eecs.umich.edu        def __init__(self, dest, src1, op2,
2056545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2066516Sgblack@eecs.umich.edu            self.dest = dest
2076516Sgblack@eecs.umich.edu            self.src1 = src1
2086516Sgblack@eecs.umich.edu            self.op2 = op2
2096516Sgblack@eecs.umich.edu            if size is not None:
2106516Sgblack@eecs.umich.edu                self.srcSize = size
2116516Sgblack@eecs.umich.edu                self.destSize = size
2126516Sgblack@eecs.umich.edu            if srcSize is not None:
2136516Sgblack@eecs.umich.edu                self.srcSize = srcSize
2146516Sgblack@eecs.umich.edu            if destSize is not None:
2156516Sgblack@eecs.umich.edu                self.destSize = destSize
2166516Sgblack@eecs.umich.edu            if self.srcSize is None:
2176516Sgblack@eecs.umich.edu                raise Exception, "Source size not set."
2186516Sgblack@eecs.umich.edu            if self.destSize is None:
2196516Sgblack@eecs.umich.edu                raise Exception, "Dest size not set."
2206545Sgblack@eecs.umich.edu            if ext is None:
2216545Sgblack@eecs.umich.edu                self.ext = 0
2226516Sgblack@eecs.umich.edu            else:
22311320Ssteve.reinhardt@amd.com                self.ext = ext
2246516Sgblack@eecs.umich.edu
2257620Sgblack@eecs.umich.edu        def getAllocator(self, microFlags):
2266516Sgblack@eecs.umich.edu            className = self.className
2276516Sgblack@eecs.umich.edu            if self.mnemonic == self.base_mnemonic + 'i':
2286516Sgblack@eecs.umich.edu                className += "Imm"
2297620Sgblack@eecs.umich.edu            allocator = '''new %(class_name)s(machInst, macrocodeBlock,
2306516Sgblack@eecs.umich.edu                    %(flags)s, %(src1)s, %(op2)s, %(dest)s,
2316545Sgblack@eecs.umich.edu                    %(srcSize)s, %(destSize)s, %(ext)s)''' % {
2326516Sgblack@eecs.umich.edu                "class_name" : className,
2336516Sgblack@eecs.umich.edu                "flags" : self.microFlagsText(microFlags),
2346516Sgblack@eecs.umich.edu                "src1" : self.src1, "op2" : self.op2,
2356516Sgblack@eecs.umich.edu                "dest" : self.dest,
2366516Sgblack@eecs.umich.edu                "srcSize" : self.srcSize,
2376516Sgblack@eecs.umich.edu                "destSize" : self.destSize,
2386545Sgblack@eecs.umich.edu                "ext" : self.ext}
2396516Sgblack@eecs.umich.edu            return allocator
2406516Sgblack@eecs.umich.edu
2416516Sgblack@eecs.umich.edu    class Mov2int(MediaOp):
2426589Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2 = 0, \
2436545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2446589Sgblack@eecs.umich.edu            super(Mov2int, self).__init__(dest, src1,\
2456589Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
24612707Sgabeblack@google.com        op_class = 'SimdMiscOp'
2476516Sgblack@eecs.umich.edu        code = '''
24813613Sgabeblack@google.com            int items = sizeof(double) / srcSize;
2496589Sgblack@eecs.umich.edu            int offset = imm8;
2506589Sgblack@eecs.umich.edu            if (bits(src1, 0) && (ext & 0x1))
2516589Sgblack@eecs.umich.edu                offset -= items;
2526589Sgblack@eecs.umich.edu            if (offset >= 0 && offset < items) {
2536589Sgblack@eecs.umich.edu                uint64_t fpSrcReg1 =
2548588Sgblack@eecs.umich.edu                    bits(FpSrcReg1_uqw,
2556589Sgblack@eecs.umich.edu                            (offset + 1) * srcSize * 8 - 1,
2566589Sgblack@eecs.umich.edu                            (offset + 0) * srcSize * 8);
2576589Sgblack@eecs.umich.edu                DestReg = merge(0, fpSrcReg1, destSize);
2586589Sgblack@eecs.umich.edu            } else {
2596589Sgblack@eecs.umich.edu                DestReg = DestReg;
2606589Sgblack@eecs.umich.edu            }
2616516Sgblack@eecs.umich.edu        '''
2626516Sgblack@eecs.umich.edu
2636516Sgblack@eecs.umich.edu    class Mov2fp(MediaOp):
2646589Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2 = 0, \
2656545Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2666589Sgblack@eecs.umich.edu            super(Mov2fp, self).__init__(dest, src1,\
2676589Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
26812707Sgabeblack@google.com        op_class = 'SimdMiscOp'
2696516Sgblack@eecs.umich.edu        code = '''
27013613Sgabeblack@google.com            int items = sizeof(double) / destSize;
2716589Sgblack@eecs.umich.edu            int offset = imm8;
2726589Sgblack@eecs.umich.edu            if (bits(dest, 0) && (ext & 0x1))
2736589Sgblack@eecs.umich.edu                offset -= items;
2746589Sgblack@eecs.umich.edu            if (offset >= 0 && offset < items) {
2756589Sgblack@eecs.umich.edu                uint64_t srcReg1 = pick(SrcReg1, 0, srcSize);
2768588Sgblack@eecs.umich.edu                FpDestReg_uqw =
2778588Sgblack@eecs.umich.edu                    insertBits(FpDestReg_uqw,
2786589Sgblack@eecs.umich.edu                            (offset + 1) * destSize * 8 - 1,
2796589Sgblack@eecs.umich.edu                            (offset + 0) * destSize * 8, srcReg1);
2806589Sgblack@eecs.umich.edu            } else {
2818588Sgblack@eecs.umich.edu                FpDestReg_uqw = FpDestReg_uqw;
2826589Sgblack@eecs.umich.edu            }
2836516Sgblack@eecs.umich.edu        '''
2846521Sgblack@eecs.umich.edu
2856592Sgblack@eecs.umich.edu    class Movsign(MediaOp):
2866592Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
2876592Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2886592Sgblack@eecs.umich.edu            super(Movsign, self).__init__(dest, src,\
2896592Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
29012707Sgabeblack@google.com        op_class = 'SimdMiscOp'
2916592Sgblack@eecs.umich.edu        code = '''
29213613Sgabeblack@google.com            int items = sizeof(double) / srcSize;
2936592Sgblack@eecs.umich.edu            uint64_t result = 0;
2946592Sgblack@eecs.umich.edu            int offset = (ext & 0x1) ? items : 0;
2956592Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
2966592Sgblack@eecs.umich.edu                uint64_t picked =
2978588Sgblack@eecs.umich.edu                    bits(FpSrcReg1_uqw, (i + 1) * 8 * srcSize - 1);
2986592Sgblack@eecs.umich.edu                result = insertBits(result, i + offset, i + offset, picked);
2996592Sgblack@eecs.umich.edu            }
3006592Sgblack@eecs.umich.edu            DestReg = DestReg | result;
3016592Sgblack@eecs.umich.edu        '''
3026592Sgblack@eecs.umich.edu
3036594Sgblack@eecs.umich.edu    class Maskmov(MediaOp):
30412707Sgabeblack@google.com        op_class = 'SimdMiscOp'
3056594Sgblack@eecs.umich.edu        code = '''
3066594Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3076594Sgblack@eecs.umich.edu            int size = srcSize;
3086594Sgblack@eecs.umich.edu            int sizeBits = size * 8;
3096799Sgblack@eecs.umich.edu            int items = numItems(size);
3108588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
3116594Sgblack@eecs.umich.edu
3126594Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3136594Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
3146594Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
3158588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
3168588Sgblack@eecs.umich.edu                if (bits(FpSrcReg2_uqw, hiIndex))
3176594Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
3186594Sgblack@eecs.umich.edu            }
3198588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
3206594Sgblack@eecs.umich.edu        '''
3216594Sgblack@eecs.umich.edu
3226596Sgblack@eecs.umich.edu    class shuffle(MediaOp):
32312707Sgabeblack@google.com        op_class = 'SimdMiscOp'
3246596Sgblack@eecs.umich.edu        code = '''
3256596Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3266596Sgblack@eecs.umich.edu            int size = srcSize;
3276596Sgblack@eecs.umich.edu            int sizeBits = size * 8;
32813613Sgabeblack@google.com            int items = sizeof(double) / size;
3296596Sgblack@eecs.umich.edu            int options;
3306596Sgblack@eecs.umich.edu            int optionBits;
3316596Sgblack@eecs.umich.edu            if (size == 8) {
3326596Sgblack@eecs.umich.edu                options = 2;
3336596Sgblack@eecs.umich.edu                optionBits = 1;
3346596Sgblack@eecs.umich.edu            } else {
3356596Sgblack@eecs.umich.edu                options = 4;
3366596Sgblack@eecs.umich.edu                optionBits = 2;
3376596Sgblack@eecs.umich.edu            }
3386596Sgblack@eecs.umich.edu
3396596Sgblack@eecs.umich.edu            uint64_t result = 0;
3406596Sgblack@eecs.umich.edu            uint8_t sel = ext;
3416596Sgblack@eecs.umich.edu
3426596Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3436596Sgblack@eecs.umich.edu                uint64_t resBits;
3446596Sgblack@eecs.umich.edu                uint8_t lsel = sel & mask(optionBits);
34513613Sgabeblack@google.com                if (lsel * size >= sizeof(double)) {
3466596Sgblack@eecs.umich.edu                    lsel -= options / 2;
3478588Sgblack@eecs.umich.edu                    resBits = bits(FpSrcReg2_uqw,
3486596Sgblack@eecs.umich.edu                            (lsel + 1) * sizeBits - 1,
3496596Sgblack@eecs.umich.edu                            (lsel + 0) * sizeBits);
3506596Sgblack@eecs.umich.edu                }  else {
3518588Sgblack@eecs.umich.edu                    resBits = bits(FpSrcReg1_uqw,
3526596Sgblack@eecs.umich.edu                            (lsel + 1) * sizeBits - 1,
3536596Sgblack@eecs.umich.edu                            (lsel + 0) * sizeBits);
3546596Sgblack@eecs.umich.edu                }
3556596Sgblack@eecs.umich.edu
3566596Sgblack@eecs.umich.edu                sel >>= optionBits;
3576596Sgblack@eecs.umich.edu
3586596Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
3596596Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
3606596Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
3616596Sgblack@eecs.umich.edu            }
3628588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
3636596Sgblack@eecs.umich.edu        '''
3646596Sgblack@eecs.umich.edu
3656521Sgblack@eecs.umich.edu    class Unpack(MediaOp):
36612707Sgabeblack@google.com        op_class = 'SimdMiscOp'
3676521Sgblack@eecs.umich.edu        code = '''
3686521Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3696521Sgblack@eecs.umich.edu            int size = destSize;
37013613Sgabeblack@google.com            int items = (sizeof(double) / size) / 2;
3716545Sgblack@eecs.umich.edu            int offset = ext ? items : 0;
3726521Sgblack@eecs.umich.edu            uint64_t result = 0;
3736521Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3746521Sgblack@eecs.umich.edu                uint64_t pickedLow =
3758588Sgblack@eecs.umich.edu                    bits(FpSrcReg1_uqw, (i + offset + 1) * 8 * size - 1,
3766521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
3776521Sgblack@eecs.umich.edu                result = insertBits(result,
3786521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size - 1,
3796521Sgblack@eecs.umich.edu                                    (2 * i + 0) * 8 * size,
3806521Sgblack@eecs.umich.edu                                    pickedLow);
3816521Sgblack@eecs.umich.edu                uint64_t pickedHigh =
3828588Sgblack@eecs.umich.edu                    bits(FpSrcReg2_uqw, (i + offset + 1) * 8 * size - 1,
3836521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
3846521Sgblack@eecs.umich.edu                result = insertBits(result,
3856521Sgblack@eecs.umich.edu                                    (2 * i + 2) * 8 * size - 1,
3866521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size,
3876521Sgblack@eecs.umich.edu                                    pickedHigh);
3886521Sgblack@eecs.umich.edu            }
3898588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
3906521Sgblack@eecs.umich.edu        '''
3916534Sgblack@eecs.umich.edu
3926546Sgblack@eecs.umich.edu    class Pack(MediaOp):
39312707Sgabeblack@google.com        op_class = 'SimdMiscOp'
3946546Sgblack@eecs.umich.edu        code = '''
3956546Sgblack@eecs.umich.edu            assert(srcSize == destSize * 2);
39613613Sgabeblack@google.com            int items = (sizeof(double) / destSize);
3976546Sgblack@eecs.umich.edu            int destBits = destSize * 8;
3986546Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
3996546Sgblack@eecs.umich.edu            uint64_t result = 0;
4006546Sgblack@eecs.umich.edu            int i;
4016546Sgblack@eecs.umich.edu            for (i = 0; i < items / 2; i++) {
4026546Sgblack@eecs.umich.edu                uint64_t picked =
4038588Sgblack@eecs.umich.edu                    bits(FpSrcReg1_uqw, (i + 1) * srcBits - 1,
4046546Sgblack@eecs.umich.edu                                        (i + 0) * srcBits);
4056546Sgblack@eecs.umich.edu                unsigned signBit = bits(picked, srcBits - 1);
4066546Sgblack@eecs.umich.edu                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
4076546Sgblack@eecs.umich.edu
4086546Sgblack@eecs.umich.edu                // Handle saturation.
4096546Sgblack@eecs.umich.edu                if (signBit) {
4106546Sgblack@eecs.umich.edu                    if (overflow != mask(destBits - srcBits + 1)) {
4116801Sgblack@eecs.umich.edu                        if (signedOp())
4126742Svince@csl.cornell.edu                            picked = (ULL(1) << (destBits - 1));
4136546Sgblack@eecs.umich.edu                        else
4146546Sgblack@eecs.umich.edu                            picked = 0;
4156546Sgblack@eecs.umich.edu                    }
4166546Sgblack@eecs.umich.edu                } else {
4176546Sgblack@eecs.umich.edu                    if (overflow != 0) {
4186801Sgblack@eecs.umich.edu                        if (signedOp())
4196546Sgblack@eecs.umich.edu                            picked = mask(destBits - 1);
4206546Sgblack@eecs.umich.edu                        else
4216546Sgblack@eecs.umich.edu                            picked = mask(destBits);
4226546Sgblack@eecs.umich.edu                    }
4236546Sgblack@eecs.umich.edu                }
4246546Sgblack@eecs.umich.edu                result = insertBits(result,
4256546Sgblack@eecs.umich.edu                                    (i + 1) * destBits - 1,
4266546Sgblack@eecs.umich.edu                                    (i + 0) * destBits,
4276546Sgblack@eecs.umich.edu                                    picked);
4286546Sgblack@eecs.umich.edu            }
4296546Sgblack@eecs.umich.edu            for (;i < items; i++) {
4306546Sgblack@eecs.umich.edu                uint64_t picked =
4318588Sgblack@eecs.umich.edu                    bits(FpSrcReg2_uqw, (i - items + 1) * srcBits - 1,
4326546Sgblack@eecs.umich.edu                                        (i - items + 0) * srcBits);
4336546Sgblack@eecs.umich.edu                unsigned signBit = bits(picked, srcBits - 1);
4346546Sgblack@eecs.umich.edu                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
4356546Sgblack@eecs.umich.edu
4366546Sgblack@eecs.umich.edu                // Handle saturation.
4376546Sgblack@eecs.umich.edu                if (signBit) {
4386546Sgblack@eecs.umich.edu                    if (overflow != mask(destBits - srcBits + 1)) {
4396801Sgblack@eecs.umich.edu                        if (signedOp())
4406742Svince@csl.cornell.edu                            picked = (ULL(1) << (destBits - 1));
4416546Sgblack@eecs.umich.edu                        else
4426546Sgblack@eecs.umich.edu                            picked = 0;
4436546Sgblack@eecs.umich.edu                    }
4446546Sgblack@eecs.umich.edu                } else {
4456546Sgblack@eecs.umich.edu                    if (overflow != 0) {
4466801Sgblack@eecs.umich.edu                        if (signedOp())
4476546Sgblack@eecs.umich.edu                            picked = mask(destBits - 1);
4486546Sgblack@eecs.umich.edu                        else
4496546Sgblack@eecs.umich.edu                            picked = mask(destBits);
4506546Sgblack@eecs.umich.edu                    }
4516546Sgblack@eecs.umich.edu                }
4526546Sgblack@eecs.umich.edu                result = insertBits(result,
4536546Sgblack@eecs.umich.edu                                    (i + 1) * destBits - 1,
4546546Sgblack@eecs.umich.edu                                    (i + 0) * destBits,
4556546Sgblack@eecs.umich.edu                                    picked);
4566546Sgblack@eecs.umich.edu            }
4578588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
4586546Sgblack@eecs.umich.edu        '''
4596546Sgblack@eecs.umich.edu
4606534Sgblack@eecs.umich.edu    class Mxor(MediaOp):
4616534Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4626534Sgblack@eecs.umich.edu            super(Mxor, self).__init__(dest, src1, src2, 1)
46312707Sgabeblack@google.com        op_class = 'SimdAluOp'
4646534Sgblack@eecs.umich.edu        code = '''
4658588Sgblack@eecs.umich.edu            FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;
4666534Sgblack@eecs.umich.edu        '''
4676537Sgblack@eecs.umich.edu
4686537Sgblack@eecs.umich.edu    class Mor(MediaOp):
4696537Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4706537Sgblack@eecs.umich.edu            super(Mor, self).__init__(dest, src1, src2, 1)
47112707Sgabeblack@google.com        op_class = 'SimdAluOp'
4726537Sgblack@eecs.umich.edu        code = '''
4738588Sgblack@eecs.umich.edu            FpDestReg_uqw = FpSrcReg1_uqw | FpSrcReg2_uqw;
4746537Sgblack@eecs.umich.edu        '''
4756539Sgblack@eecs.umich.edu
4766539Sgblack@eecs.umich.edu    class Mand(MediaOp):
4776539Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4786539Sgblack@eecs.umich.edu            super(Mand, self).__init__(dest, src1, src2, 1)
47912707Sgabeblack@google.com        op_class = 'SimdAluOp'
4806539Sgblack@eecs.umich.edu        code = '''
4818588Sgblack@eecs.umich.edu            FpDestReg_uqw = FpSrcReg1_uqw & FpSrcReg2_uqw;
4826539Sgblack@eecs.umich.edu        '''
4836541Sgblack@eecs.umich.edu
4846541Sgblack@eecs.umich.edu    class Mandn(MediaOp):
4856541Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
4866541Sgblack@eecs.umich.edu            super(Mandn, self).__init__(dest, src1, src2, 1)
48712707Sgabeblack@google.com        op_class = 'SimdAluOp'
4886541Sgblack@eecs.umich.edu        code = '''
4898588Sgblack@eecs.umich.edu            FpDestReg_uqw = ~FpSrcReg1_uqw & FpSrcReg2_uqw;
4906541Sgblack@eecs.umich.edu        '''
4916548Sgblack@eecs.umich.edu
4926548Sgblack@eecs.umich.edu    class Mminf(MediaOp):
49312707Sgabeblack@google.com        op_class = 'SimdFloatCmpOp'
4946548Sgblack@eecs.umich.edu        code = '''
4956548Sgblack@eecs.umich.edu            union floatInt
4966548Sgblack@eecs.umich.edu            {
4976548Sgblack@eecs.umich.edu                float f;
4986548Sgblack@eecs.umich.edu                uint32_t i;
4996548Sgblack@eecs.umich.edu            };
5006548Sgblack@eecs.umich.edu            union doubleInt
5016548Sgblack@eecs.umich.edu            {
5026548Sgblack@eecs.umich.edu                double d;
5036548Sgblack@eecs.umich.edu                uint64_t i;
5046548Sgblack@eecs.umich.edu            };
5056548Sgblack@eecs.umich.edu
5066548Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5076548Sgblack@eecs.umich.edu            int size = srcSize;
5086548Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5096548Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
5106799Sgblack@eecs.umich.edu            int items = numItems(size);
5118588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
5126548Sgblack@eecs.umich.edu
5136548Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
5146548Sgblack@eecs.umich.edu                double arg1, arg2;
5156548Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5166548Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5178588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
5188588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
5196548Sgblack@eecs.umich.edu
5206548Sgblack@eecs.umich.edu                if (size == 4) {
5216548Sgblack@eecs.umich.edu                    floatInt fi;
5226548Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
5236548Sgblack@eecs.umich.edu                    arg1 = fi.f;
5246548Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
5256548Sgblack@eecs.umich.edu                    arg2 = fi.f;
5266548Sgblack@eecs.umich.edu                } else {
5276548Sgblack@eecs.umich.edu                    doubleInt di;
5286548Sgblack@eecs.umich.edu                    di.i = arg1Bits;
5296548Sgblack@eecs.umich.edu                    arg1 = di.d;
5306548Sgblack@eecs.umich.edu                    di.i = arg2Bits;
5316548Sgblack@eecs.umich.edu                    arg2 = di.d;
5326548Sgblack@eecs.umich.edu                }
5336548Sgblack@eecs.umich.edu
5346548Sgblack@eecs.umich.edu                if (arg1 < arg2) {
5356548Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
5366548Sgblack@eecs.umich.edu                } else {
5376548Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
5386548Sgblack@eecs.umich.edu                }
5396548Sgblack@eecs.umich.edu            }
5408588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
5416548Sgblack@eecs.umich.edu        '''
5426550Sgblack@eecs.umich.edu
5436550Sgblack@eecs.umich.edu    class Mmaxf(MediaOp):
54412707Sgabeblack@google.com        op_class = 'SimdFloatCmpOp'
5456550Sgblack@eecs.umich.edu        code = '''
5466550Sgblack@eecs.umich.edu            union floatInt
5476550Sgblack@eecs.umich.edu            {
5486550Sgblack@eecs.umich.edu                float f;
5496550Sgblack@eecs.umich.edu                uint32_t i;
5506550Sgblack@eecs.umich.edu            };
5516550Sgblack@eecs.umich.edu            union doubleInt
5526550Sgblack@eecs.umich.edu            {
5536550Sgblack@eecs.umich.edu                double d;
5546550Sgblack@eecs.umich.edu                uint64_t i;
5556550Sgblack@eecs.umich.edu            };
5566550Sgblack@eecs.umich.edu
5576550Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5586550Sgblack@eecs.umich.edu            int size = srcSize;
5596550Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5606550Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
5616799Sgblack@eecs.umich.edu            int items = numItems(size);
5628588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
5636550Sgblack@eecs.umich.edu
5646550Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
5656550Sgblack@eecs.umich.edu                double arg1, arg2;
5666550Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5676550Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5688588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
5698588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
5706550Sgblack@eecs.umich.edu
5716550Sgblack@eecs.umich.edu                if (size == 4) {
5726550Sgblack@eecs.umich.edu                    floatInt fi;
5736550Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
5746550Sgblack@eecs.umich.edu                    arg1 = fi.f;
5756550Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
5766550Sgblack@eecs.umich.edu                    arg2 = fi.f;
5776550Sgblack@eecs.umich.edu                } else {
5786550Sgblack@eecs.umich.edu                    doubleInt di;
5796550Sgblack@eecs.umich.edu                    di.i = arg1Bits;
5806550Sgblack@eecs.umich.edu                    arg1 = di.d;
5816550Sgblack@eecs.umich.edu                    di.i = arg2Bits;
5826550Sgblack@eecs.umich.edu                    arg2 = di.d;
5836550Sgblack@eecs.umich.edu                }
5846550Sgblack@eecs.umich.edu
5856550Sgblack@eecs.umich.edu                if (arg1 > arg2) {
5866550Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
5876550Sgblack@eecs.umich.edu                } else {
5886550Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
5896550Sgblack@eecs.umich.edu                }
5906550Sgblack@eecs.umich.edu            }
5918588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
5926550Sgblack@eecs.umich.edu        '''
5936552Sgblack@eecs.umich.edu
5946572Sgblack@eecs.umich.edu    class Mmini(MediaOp):
59512707Sgabeblack@google.com        op_class = 'SimdCmpOp'
5966572Sgblack@eecs.umich.edu        code = '''
5976572Sgblack@eecs.umich.edu
5986572Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5996572Sgblack@eecs.umich.edu            int size = srcSize;
6006572Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6016799Sgblack@eecs.umich.edu            int items = numItems(size);
6028588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
6036572Sgblack@eecs.umich.edu
6046572Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6056572Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6066572Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6078588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
6086572Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
6096742Svince@csl.cornell.edu                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
6108588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
6116572Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
6126742Svince@csl.cornell.edu                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
6136572Sgblack@eecs.umich.edu                uint64_t resBits;
6146572Sgblack@eecs.umich.edu
6156801Sgblack@eecs.umich.edu                if (signedOp()) {
6166572Sgblack@eecs.umich.edu                    if (arg1 < arg2) {
6176572Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6186572Sgblack@eecs.umich.edu                    } else {
6196572Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6206572Sgblack@eecs.umich.edu                    }
6216572Sgblack@eecs.umich.edu                } else {
6226572Sgblack@eecs.umich.edu                    if (arg1Bits < arg2Bits) {
6236572Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6246572Sgblack@eecs.umich.edu                    } else {
6256572Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6266572Sgblack@eecs.umich.edu                    }
6276572Sgblack@eecs.umich.edu                }
6286572Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
6296572Sgblack@eecs.umich.edu            }
6308588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
6316572Sgblack@eecs.umich.edu        '''
6326572Sgblack@eecs.umich.edu
6336574Sgblack@eecs.umich.edu    class Mmaxi(MediaOp):
63412707Sgabeblack@google.com        op_class = 'SimdCmpOp'
6356574Sgblack@eecs.umich.edu        code = '''
6366574Sgblack@eecs.umich.edu
6376574Sgblack@eecs.umich.edu            assert(srcSize == destSize);
6386574Sgblack@eecs.umich.edu            int size = srcSize;
6396574Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6406799Sgblack@eecs.umich.edu            int items = numItems(size);
6418588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
6426574Sgblack@eecs.umich.edu
6436574Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6446574Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6456574Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6468588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
6476574Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
6486742Svince@csl.cornell.edu                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
6498588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
6506574Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
6516742Svince@csl.cornell.edu                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
6526574Sgblack@eecs.umich.edu                uint64_t resBits;
6536574Sgblack@eecs.umich.edu
6546801Sgblack@eecs.umich.edu                if (signedOp()) {
6556574Sgblack@eecs.umich.edu                    if (arg1 > arg2) {
6566574Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6576574Sgblack@eecs.umich.edu                    } else {
6586574Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6596574Sgblack@eecs.umich.edu                    }
6606574Sgblack@eecs.umich.edu                } else {
6616574Sgblack@eecs.umich.edu                    if (arg1Bits > arg2Bits) {
6626574Sgblack@eecs.umich.edu                        resBits = arg1Bits;
6636574Sgblack@eecs.umich.edu                    } else {
6646574Sgblack@eecs.umich.edu                        resBits = arg2Bits;
6656574Sgblack@eecs.umich.edu                    }
6666574Sgblack@eecs.umich.edu                }
6676574Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
6686574Sgblack@eecs.umich.edu            }
6698588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
6706574Sgblack@eecs.umich.edu        '''
6716574Sgblack@eecs.umich.edu
6726552Sgblack@eecs.umich.edu    class Msqrt(MediaOp):
67312707Sgabeblack@google.com        op_class = 'SimdFloatSqrtOp'
6746552Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
6756552Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
6766552Sgblack@eecs.umich.edu            super(Msqrt, self).__init__(dest, src,\
6776552Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
6786552Sgblack@eecs.umich.edu        code = '''
6796552Sgblack@eecs.umich.edu            union floatInt
6806552Sgblack@eecs.umich.edu            {
6816552Sgblack@eecs.umich.edu                float f;
6826552Sgblack@eecs.umich.edu                uint32_t i;
6836552Sgblack@eecs.umich.edu            };
6846552Sgblack@eecs.umich.edu            union doubleInt
6856552Sgblack@eecs.umich.edu            {
6866552Sgblack@eecs.umich.edu                double d;
6876552Sgblack@eecs.umich.edu                uint64_t i;
6886552Sgblack@eecs.umich.edu            };
6896552Sgblack@eecs.umich.edu
6906552Sgblack@eecs.umich.edu            assert(srcSize == destSize);
6916552Sgblack@eecs.umich.edu            int size = srcSize;
6926552Sgblack@eecs.umich.edu            int sizeBits = size * 8;
6936552Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
6946799Sgblack@eecs.umich.edu            int items = numItems(size);
6958588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
6966552Sgblack@eecs.umich.edu
6976552Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6986552Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6996552Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
7008588Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
7016552Sgblack@eecs.umich.edu
7026552Sgblack@eecs.umich.edu                if (size == 4) {
7036552Sgblack@eecs.umich.edu                    floatInt fi;
7046552Sgblack@eecs.umich.edu                    fi.i = argBits;
7056552Sgblack@eecs.umich.edu                    fi.f = sqrt(fi.f);
7066552Sgblack@eecs.umich.edu                    argBits = fi.i;
7076552Sgblack@eecs.umich.edu                } else {
7086552Sgblack@eecs.umich.edu                    doubleInt di;
7096552Sgblack@eecs.umich.edu                    di.i = argBits;
7106552Sgblack@eecs.umich.edu                    di.d = sqrt(di.d);
7116552Sgblack@eecs.umich.edu                    argBits = di.i;
7126552Sgblack@eecs.umich.edu                }
7136552Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, argBits);
7146552Sgblack@eecs.umich.edu            }
7158588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
7166552Sgblack@eecs.umich.edu        '''
7176554Sgblack@eecs.umich.edu
71811160Ssteve.reinhardt@amd.com    # compute approximate reciprocal --- single-precision only
71911160Ssteve.reinhardt@amd.com    class Mrcp(MediaOp):
72011160Ssteve.reinhardt@amd.com        def __init__(self, dest, src, \
72111160Ssteve.reinhardt@amd.com                size = None, destSize = None, srcSize = None, ext = None):
72211160Ssteve.reinhardt@amd.com            super(Mrcp, self).__init__(dest, src,\
72311160Ssteve.reinhardt@amd.com                    "InstRegIndex(0)", size, destSize, srcSize, ext)
72412707Sgabeblack@google.com        op_class = 'SimdFloatAluOp'
72511160Ssteve.reinhardt@amd.com        code = '''
72611160Ssteve.reinhardt@amd.com            union floatInt
72711160Ssteve.reinhardt@amd.com            {
72811160Ssteve.reinhardt@amd.com                float f;
72911160Ssteve.reinhardt@amd.com                uint32_t i;
73011160Ssteve.reinhardt@amd.com            };
73111160Ssteve.reinhardt@amd.com
73211160Ssteve.reinhardt@amd.com            assert(srcSize == 4);  // ISA defines single-precision only
73311160Ssteve.reinhardt@amd.com            assert(srcSize == destSize);
73411160Ssteve.reinhardt@amd.com            const int size = 4;
73511160Ssteve.reinhardt@amd.com            const int sizeBits = size * 8;
73611160Ssteve.reinhardt@amd.com            int items = numItems(size);
73711160Ssteve.reinhardt@amd.com            uint64_t result = FpDestReg_uqw;
73811160Ssteve.reinhardt@amd.com
73911160Ssteve.reinhardt@amd.com            for (int i = 0; i < items; i++) {
74011160Ssteve.reinhardt@amd.com                int hiIndex = (i + 1) * sizeBits - 1;
74111160Ssteve.reinhardt@amd.com                int loIndex = (i + 0) * sizeBits;
74211160Ssteve.reinhardt@amd.com                uint64_t argBits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
74311160Ssteve.reinhardt@amd.com
74411160Ssteve.reinhardt@amd.com                floatInt fi;
74511160Ssteve.reinhardt@amd.com                fi.i = argBits;
74611160Ssteve.reinhardt@amd.com                // This is more accuracy than HW provides, but oh well
74711160Ssteve.reinhardt@amd.com                fi.f = 1.0 / fi.f;
74811160Ssteve.reinhardt@amd.com                argBits = fi.i;
74911160Ssteve.reinhardt@amd.com                result = insertBits(result, hiIndex, loIndex, argBits);
75011160Ssteve.reinhardt@amd.com            }
75111160Ssteve.reinhardt@amd.com            FpDestReg_uqw = result;
75211160Ssteve.reinhardt@amd.com        '''
75311160Ssteve.reinhardt@amd.com
7546554Sgblack@eecs.umich.edu    class Maddf(MediaOp):
75512707Sgabeblack@google.com        op_class = 'SimdFloatAddOp'
7566554Sgblack@eecs.umich.edu        code = '''
7576554Sgblack@eecs.umich.edu            union floatInt
7586554Sgblack@eecs.umich.edu            {
7596554Sgblack@eecs.umich.edu                float f;
7606554Sgblack@eecs.umich.edu                uint32_t i;
7616554Sgblack@eecs.umich.edu            };
7626554Sgblack@eecs.umich.edu            union doubleInt
7636554Sgblack@eecs.umich.edu            {
7646554Sgblack@eecs.umich.edu                double d;
7656554Sgblack@eecs.umich.edu                uint64_t i;
7666554Sgblack@eecs.umich.edu            };
7676554Sgblack@eecs.umich.edu
7686554Sgblack@eecs.umich.edu            assert(srcSize == destSize);
7696554Sgblack@eecs.umich.edu            int size = srcSize;
7706554Sgblack@eecs.umich.edu            int sizeBits = size * 8;
7716554Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
7726799Sgblack@eecs.umich.edu            int items = numItems(size);
7738588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
7746554Sgblack@eecs.umich.edu
7756554Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
7766554Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
7776554Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
7788588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
7798588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
7806554Sgblack@eecs.umich.edu                uint64_t resBits;
7816554Sgblack@eecs.umich.edu
7826554Sgblack@eecs.umich.edu                if (size == 4) {
7836554Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
7846554Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7856554Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7866554Sgblack@eecs.umich.edu                    res.f = arg1.f + arg2.f;
7876554Sgblack@eecs.umich.edu                    resBits = res.i;
7886554Sgblack@eecs.umich.edu                } else {
7896554Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
7906554Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
7916554Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
7926554Sgblack@eecs.umich.edu                    res.d = arg1.d + arg2.d;
7936554Sgblack@eecs.umich.edu                    resBits = res.i;
7946554Sgblack@eecs.umich.edu                }
7956554Sgblack@eecs.umich.edu
7966554Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
7976554Sgblack@eecs.umich.edu            }
7988588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
7996554Sgblack@eecs.umich.edu        '''
8006556Sgblack@eecs.umich.edu
8016556Sgblack@eecs.umich.edu    class Msubf(MediaOp):
80212707Sgabeblack@google.com        op_class = 'SimdFloatAddOp'
8036556Sgblack@eecs.umich.edu        code = '''
8046556Sgblack@eecs.umich.edu            union floatInt
8056556Sgblack@eecs.umich.edu            {
8066556Sgblack@eecs.umich.edu                float f;
8076556Sgblack@eecs.umich.edu                uint32_t i;
8086556Sgblack@eecs.umich.edu            };
8096556Sgblack@eecs.umich.edu            union doubleInt
8106556Sgblack@eecs.umich.edu            {
8116556Sgblack@eecs.umich.edu                double d;
8126556Sgblack@eecs.umich.edu                uint64_t i;
8136556Sgblack@eecs.umich.edu            };
8146556Sgblack@eecs.umich.edu
8156556Sgblack@eecs.umich.edu            assert(srcSize == destSize);
8166556Sgblack@eecs.umich.edu            int size = srcSize;
8176556Sgblack@eecs.umich.edu            int sizeBits = size * 8;
8186556Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
8196799Sgblack@eecs.umich.edu            int items = numItems(size);
8208588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
8216556Sgblack@eecs.umich.edu
8226556Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8236556Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
8246556Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8258588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
8268588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
8276556Sgblack@eecs.umich.edu                uint64_t resBits;
8286556Sgblack@eecs.umich.edu
8296556Sgblack@eecs.umich.edu                if (size == 4) {
8306556Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
8316556Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8326556Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8336556Sgblack@eecs.umich.edu                    res.f = arg1.f - arg2.f;
8346556Sgblack@eecs.umich.edu                    resBits = res.i;
8356556Sgblack@eecs.umich.edu                } else {
8366556Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
8376556Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8386556Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8396556Sgblack@eecs.umich.edu                    res.d = arg1.d - arg2.d;
8406556Sgblack@eecs.umich.edu                    resBits = res.i;
8416556Sgblack@eecs.umich.edu                }
8426556Sgblack@eecs.umich.edu
8436556Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
8446556Sgblack@eecs.umich.edu            }
8458588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
8466556Sgblack@eecs.umich.edu        '''
8476558Sgblack@eecs.umich.edu
8486558Sgblack@eecs.umich.edu    class Mmulf(MediaOp):
84912707Sgabeblack@google.com        op_class = 'SimdFloatMultOp'
8506558Sgblack@eecs.umich.edu        code = '''
8516558Sgblack@eecs.umich.edu            union floatInt
8526558Sgblack@eecs.umich.edu            {
8536558Sgblack@eecs.umich.edu                float f;
8546558Sgblack@eecs.umich.edu                uint32_t i;
8556558Sgblack@eecs.umich.edu            };
8566558Sgblack@eecs.umich.edu            union doubleInt
8576558Sgblack@eecs.umich.edu            {
8586558Sgblack@eecs.umich.edu                double d;
8596558Sgblack@eecs.umich.edu                uint64_t i;
8606558Sgblack@eecs.umich.edu            };
8616558Sgblack@eecs.umich.edu
8626558Sgblack@eecs.umich.edu            assert(srcSize == destSize);
8636558Sgblack@eecs.umich.edu            int size = srcSize;
8646558Sgblack@eecs.umich.edu            int sizeBits = size * 8;
8656558Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
8666799Sgblack@eecs.umich.edu            int items = numItems(size);
8678588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
8686558Sgblack@eecs.umich.edu
8696558Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
8706558Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
8716558Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
8728588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
8738588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
8746558Sgblack@eecs.umich.edu                uint64_t resBits;
8756558Sgblack@eecs.umich.edu
8766558Sgblack@eecs.umich.edu                if (size == 4) {
8776558Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
8786558Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8796558Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8806558Sgblack@eecs.umich.edu                    res.f = arg1.f * arg2.f;
8816558Sgblack@eecs.umich.edu                    resBits = res.i;
8826558Sgblack@eecs.umich.edu                } else {
8836558Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
8846558Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
8856558Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
8866558Sgblack@eecs.umich.edu                    res.d = arg1.d * arg2.d;
8876558Sgblack@eecs.umich.edu                    resBits = res.i;
8886558Sgblack@eecs.umich.edu                }
8896558Sgblack@eecs.umich.edu
8906558Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
8916558Sgblack@eecs.umich.edu            }
8928588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
8936558Sgblack@eecs.umich.edu        '''
8946560Sgblack@eecs.umich.edu
8956560Sgblack@eecs.umich.edu    class Mdivf(MediaOp):
89612707Sgabeblack@google.com        op_class = 'SimdFloatDivOp'
8976560Sgblack@eecs.umich.edu        code = '''
8986560Sgblack@eecs.umich.edu            union floatInt
8996560Sgblack@eecs.umich.edu            {
9006560Sgblack@eecs.umich.edu                float f;
9016560Sgblack@eecs.umich.edu                uint32_t i;
9026560Sgblack@eecs.umich.edu            };
9036560Sgblack@eecs.umich.edu            union doubleInt
9046560Sgblack@eecs.umich.edu            {
9056560Sgblack@eecs.umich.edu                double d;
9066560Sgblack@eecs.umich.edu                uint64_t i;
9076560Sgblack@eecs.umich.edu            };
9086560Sgblack@eecs.umich.edu
9096560Sgblack@eecs.umich.edu            assert(srcSize == destSize);
9106560Sgblack@eecs.umich.edu            int size = srcSize;
9116560Sgblack@eecs.umich.edu            int sizeBits = size * 8;
9126560Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
9136799Sgblack@eecs.umich.edu            int items = numItems(size);
9148588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
9156560Sgblack@eecs.umich.edu
9166560Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9176560Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
9186560Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
9198588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
9208588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
9216560Sgblack@eecs.umich.edu                uint64_t resBits;
9226560Sgblack@eecs.umich.edu
9236560Sgblack@eecs.umich.edu                if (size == 4) {
9246560Sgblack@eecs.umich.edu                    floatInt arg1, arg2, res;
9256560Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
9266560Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
9276560Sgblack@eecs.umich.edu                    res.f = arg1.f / arg2.f;
9286560Sgblack@eecs.umich.edu                    resBits = res.i;
9296560Sgblack@eecs.umich.edu                } else {
9306560Sgblack@eecs.umich.edu                    doubleInt arg1, arg2, res;
9316560Sgblack@eecs.umich.edu                    arg1.i = arg1Bits;
9326560Sgblack@eecs.umich.edu                    arg2.i = arg2Bits;
9336560Sgblack@eecs.umich.edu                    res.d = arg1.d / arg2.d;
9346560Sgblack@eecs.umich.edu                    resBits = res.i;
9356560Sgblack@eecs.umich.edu                }
9366560Sgblack@eecs.umich.edu
9376560Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
9386560Sgblack@eecs.umich.edu            }
9398588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
9406560Sgblack@eecs.umich.edu        '''
9416562Sgblack@eecs.umich.edu
9426570Sgblack@eecs.umich.edu    class Maddi(MediaOp):
94312707Sgabeblack@google.com        op_class = 'SimdAddOp'
9446570Sgblack@eecs.umich.edu        code = '''
9456570Sgblack@eecs.umich.edu            assert(srcSize == destSize);
9466570Sgblack@eecs.umich.edu            int size = srcSize;
9476570Sgblack@eecs.umich.edu            int sizeBits = size * 8;
9486799Sgblack@eecs.umich.edu            int items = numItems(size);
9498588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
9506570Sgblack@eecs.umich.edu
9516570Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9526570Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
9536570Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
9548588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
9558588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
9566570Sgblack@eecs.umich.edu                uint64_t resBits = arg1Bits + arg2Bits;
95711320Ssteve.reinhardt@amd.com
9586570Sgblack@eecs.umich.edu                if (ext & 0x2) {
9596801Sgblack@eecs.umich.edu                    if (signedOp()) {
9606801Sgblack@eecs.umich.edu                        int arg1Sign = bits(arg1Bits, sizeBits - 1);
9616801Sgblack@eecs.umich.edu                        int arg2Sign = bits(arg2Bits, sizeBits - 1);
9626801Sgblack@eecs.umich.edu                        int resSign = bits(resBits, sizeBits - 1);
9636801Sgblack@eecs.umich.edu                        if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
9646801Sgblack@eecs.umich.edu                            if (resSign == 0)
9656801Sgblack@eecs.umich.edu                                resBits = (ULL(1) << (sizeBits - 1));
9666801Sgblack@eecs.umich.edu                            else
9676801Sgblack@eecs.umich.edu                                resBits = mask(sizeBits - 1);
9686801Sgblack@eecs.umich.edu                        }
9696801Sgblack@eecs.umich.edu                    } else {
9706801Sgblack@eecs.umich.edu                        if (findCarry(sizeBits, resBits, arg1Bits, arg2Bits))
9716801Sgblack@eecs.umich.edu                            resBits = mask(sizeBits);
9726570Sgblack@eecs.umich.edu                    }
9736570Sgblack@eecs.umich.edu                }
9746570Sgblack@eecs.umich.edu
9756570Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
9766570Sgblack@eecs.umich.edu            }
9778588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
9786570Sgblack@eecs.umich.edu        '''
9796570Sgblack@eecs.umich.edu
9806579Sgblack@eecs.umich.edu    class Msubi(MediaOp):
98112707Sgabeblack@google.com        op_class = 'SimdAddOp'
9826579Sgblack@eecs.umich.edu        code = '''
9836579Sgblack@eecs.umich.edu            assert(srcSize == destSize);
9846579Sgblack@eecs.umich.edu            int size = srcSize;
9856579Sgblack@eecs.umich.edu            int sizeBits = size * 8;
9866799Sgblack@eecs.umich.edu            int items = numItems(size);
9878588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
9886579Sgblack@eecs.umich.edu
9896579Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
9906579Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
9916579Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
9928588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
9938588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
9946579Sgblack@eecs.umich.edu                uint64_t resBits = arg1Bits - arg2Bits;
99511320Ssteve.reinhardt@amd.com
9966579Sgblack@eecs.umich.edu                if (ext & 0x2) {
9976801Sgblack@eecs.umich.edu                    if (signedOp()) {
9986801Sgblack@eecs.umich.edu                        int arg1Sign = bits(arg1Bits, sizeBits - 1);
9996801Sgblack@eecs.umich.edu                        int arg2Sign = !bits(arg2Bits, sizeBits - 1);
10006801Sgblack@eecs.umich.edu                        int resSign = bits(resBits, sizeBits - 1);
10016801Sgblack@eecs.umich.edu                        if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
10026801Sgblack@eecs.umich.edu                            if (resSign == 0)
10036801Sgblack@eecs.umich.edu                                resBits = (ULL(1) << (sizeBits - 1));
10046801Sgblack@eecs.umich.edu                            else
10056801Sgblack@eecs.umich.edu                                resBits = mask(sizeBits - 1);
10066801Sgblack@eecs.umich.edu                        }
10076801Sgblack@eecs.umich.edu                    } else {
10086801Sgblack@eecs.umich.edu                        if (arg2Bits > arg1Bits) {
10096801Sgblack@eecs.umich.edu                            resBits = 0;
10106801Sgblack@eecs.umich.edu                        } else if (!findCarry(sizeBits, resBits,
10116801Sgblack@eecs.umich.edu                                             arg1Bits, ~arg2Bits)) {
10126801Sgblack@eecs.umich.edu                            resBits = mask(sizeBits);
10136801Sgblack@eecs.umich.edu                        }
10146579Sgblack@eecs.umich.edu                    }
10156579Sgblack@eecs.umich.edu                }
10166579Sgblack@eecs.umich.edu
10176579Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
10186579Sgblack@eecs.umich.edu            }
10198588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
10206579Sgblack@eecs.umich.edu        '''
10216579Sgblack@eecs.umich.edu
10226577Sgblack@eecs.umich.edu    class Mmuli(MediaOp):
102312707Sgabeblack@google.com        op_class = 'SimdMultOp'
10246577Sgblack@eecs.umich.edu        code = '''
10256577Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
10266577Sgblack@eecs.umich.edu            int destBits = destSize * 8;
10276577Sgblack@eecs.umich.edu            assert(destBits <= 64);
10286577Sgblack@eecs.umich.edu            assert(destSize >= srcSize);
10296799Sgblack@eecs.umich.edu            int items = numItems(destSize);
10308588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
10316577Sgblack@eecs.umich.edu
10326577Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10336585Sgblack@eecs.umich.edu                int offset = 0;
10346585Sgblack@eecs.umich.edu                if (ext & 16) {
10356585Sgblack@eecs.umich.edu                    if (ext & 32)
10366585Sgblack@eecs.umich.edu                        offset = i * (destBits - srcBits);
10376585Sgblack@eecs.umich.edu                    else
10386585Sgblack@eecs.umich.edu                        offset = i * (destBits - srcBits) + srcBits;
10396585Sgblack@eecs.umich.edu                }
10406585Sgblack@eecs.umich.edu                int srcHiIndex = (i + 1) * srcBits - 1 + offset;
10416585Sgblack@eecs.umich.edu                int srcLoIndex = (i + 0) * srcBits + offset;
10428588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex);
10438588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, srcHiIndex, srcLoIndex);
10446577Sgblack@eecs.umich.edu                uint64_t resBits;
10456577Sgblack@eecs.umich.edu
10466801Sgblack@eecs.umich.edu                if (signedOp()) {
10476577Sgblack@eecs.umich.edu                    int64_t arg1 = arg1Bits |
10486742Svince@csl.cornell.edu                        (0 - (arg1Bits & (ULL(1) << (srcBits - 1))));
10496577Sgblack@eecs.umich.edu                    int64_t arg2 = arg2Bits |
10506742Svince@csl.cornell.edu                        (0 - (arg2Bits & (ULL(1) << (srcBits - 1))));
10516577Sgblack@eecs.umich.edu                    resBits = (uint64_t)(arg1 * arg2);
10526577Sgblack@eecs.umich.edu                } else {
10536577Sgblack@eecs.umich.edu                    resBits = arg1Bits * arg2Bits;
10546577Sgblack@eecs.umich.edu                }
10556577Sgblack@eecs.umich.edu
10566577Sgblack@eecs.umich.edu                if (ext & 0x4)
10576742Svince@csl.cornell.edu                    resBits += (ULL(1) << (destBits - 1));
105811320Ssteve.reinhardt@amd.com
10596800Sgblack@eecs.umich.edu                if (multHi())
10606577Sgblack@eecs.umich.edu                    resBits >>= destBits;
10616577Sgblack@eecs.umich.edu
10626577Sgblack@eecs.umich.edu                int destHiIndex = (i + 1) * destBits - 1;
10636577Sgblack@eecs.umich.edu                int destLoIndex = (i + 0) * destBits;
10646577Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, resBits);
10656577Sgblack@eecs.umich.edu            }
10668588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
10676577Sgblack@eecs.umich.edu        '''
10686577Sgblack@eecs.umich.edu
10696587Sgblack@eecs.umich.edu    class Mavg(MediaOp):
107012707Sgabeblack@google.com        op_class = 'SimdAddOp'
10716587Sgblack@eecs.umich.edu        code = '''
10726587Sgblack@eecs.umich.edu            assert(srcSize == destSize);
10736587Sgblack@eecs.umich.edu            int size = srcSize;
10746587Sgblack@eecs.umich.edu            int sizeBits = size * 8;
10756799Sgblack@eecs.umich.edu            int items = numItems(size);
10768588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
10776587Sgblack@eecs.umich.edu
10786587Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10796587Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
10806587Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
10818588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
10828588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
10836587Sgblack@eecs.umich.edu                uint64_t resBits = (arg1Bits + arg2Bits + 1) / 2;
108411320Ssteve.reinhardt@amd.com
10856587Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
10866587Sgblack@eecs.umich.edu            }
10878588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
10886587Sgblack@eecs.umich.edu        '''
10896587Sgblack@eecs.umich.edu
10906581Sgblack@eecs.umich.edu    class Msad(MediaOp):
109112707Sgabeblack@google.com        op_class = 'SimdAddOp'
10926581Sgblack@eecs.umich.edu        code = '''
10936581Sgblack@eecs.umich.edu            int srcBits = srcSize * 8;
109413613Sgabeblack@google.com            int items = sizeof(double) / srcSize;
10956581Sgblack@eecs.umich.edu
10966581Sgblack@eecs.umich.edu            uint64_t sum = 0;
10976581Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
10986581Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * srcBits - 1;
10996581Sgblack@eecs.umich.edu                int loIndex = (i + 0) * srcBits;
11008588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
11018588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
11026581Sgblack@eecs.umich.edu                int64_t resBits = arg1Bits - arg2Bits;
11036581Sgblack@eecs.umich.edu                if (resBits < 0)
11046581Sgblack@eecs.umich.edu                    resBits = -resBits;
11056581Sgblack@eecs.umich.edu                sum += resBits;
11066581Sgblack@eecs.umich.edu            }
11078588Sgblack@eecs.umich.edu            FpDestReg_uqw = sum & mask(destSize * 8);
11086581Sgblack@eecs.umich.edu        '''
11096581Sgblack@eecs.umich.edu
11106583Sgblack@eecs.umich.edu    class Msrl(MediaOp):
111112707Sgabeblack@google.com        op_class = 'SimdShiftOp'
11126583Sgblack@eecs.umich.edu        code = '''
11136583Sgblack@eecs.umich.edu
11146583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
11156583Sgblack@eecs.umich.edu            int size = srcSize;
11166583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
11176799Sgblack@eecs.umich.edu            int items = numItems(size);
11188588Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2_uqw;
11198588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
11206583Sgblack@eecs.umich.edu
11216583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
11226583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
11236583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
11248588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
11256583Sgblack@eecs.umich.edu                uint64_t resBits;
11266583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
11276583Sgblack@eecs.umich.edu                    resBits = 0;
11286583Sgblack@eecs.umich.edu                } else {
11296583Sgblack@eecs.umich.edu                    resBits = (arg1Bits >> shiftAmt) &
11306583Sgblack@eecs.umich.edu                        mask(sizeBits - shiftAmt);
11316583Sgblack@eecs.umich.edu                }
11326583Sgblack@eecs.umich.edu
11336583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
11346583Sgblack@eecs.umich.edu            }
11358588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
11366583Sgblack@eecs.umich.edu        '''
11376583Sgblack@eecs.umich.edu
11386583Sgblack@eecs.umich.edu    class Msra(MediaOp):
113912707Sgabeblack@google.com        op_class = 'SimdShiftOp'
11406583Sgblack@eecs.umich.edu        code = '''
11416583Sgblack@eecs.umich.edu
11426583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
11436583Sgblack@eecs.umich.edu            int size = srcSize;
11446583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
11456799Sgblack@eecs.umich.edu            int items = numItems(size);
11468588Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2_uqw;
11478588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
11486583Sgblack@eecs.umich.edu
11496583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
11506583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
11516583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
11528588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
11536583Sgblack@eecs.umich.edu                uint64_t resBits;
11546583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
11556583Sgblack@eecs.umich.edu                    if (bits(arg1Bits, sizeBits - 1))
11566583Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
11576583Sgblack@eecs.umich.edu                    else
11586583Sgblack@eecs.umich.edu                        resBits = 0;
11596583Sgblack@eecs.umich.edu                } else {
11606583Sgblack@eecs.umich.edu                    resBits = (arg1Bits >> shiftAmt);
11616583Sgblack@eecs.umich.edu                    resBits = resBits |
11626742Svince@csl.cornell.edu                        (0 - (resBits & (ULL(1) << (sizeBits - 1 - shiftAmt))));
11636583Sgblack@eecs.umich.edu                }
11646583Sgblack@eecs.umich.edu
11656583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
11666583Sgblack@eecs.umich.edu            }
11678588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
11686583Sgblack@eecs.umich.edu        '''
11696583Sgblack@eecs.umich.edu
11706583Sgblack@eecs.umich.edu    class Msll(MediaOp):
117112707Sgabeblack@google.com        op_class = 'SimdShiftOp'
11726583Sgblack@eecs.umich.edu        code = '''
11736583Sgblack@eecs.umich.edu
11746583Sgblack@eecs.umich.edu            assert(srcSize == destSize);
11756583Sgblack@eecs.umich.edu            int size = srcSize;
11766583Sgblack@eecs.umich.edu            int sizeBits = size * 8;
11776799Sgblack@eecs.umich.edu            int items = numItems(size);
11788588Sgblack@eecs.umich.edu            uint64_t shiftAmt = op2_uqw;
11798588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
11806583Sgblack@eecs.umich.edu
11816583Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
11826583Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
11836583Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
11848588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
11856583Sgblack@eecs.umich.edu                uint64_t resBits;
11866583Sgblack@eecs.umich.edu                if (shiftAmt >= sizeBits) {
11876583Sgblack@eecs.umich.edu                    resBits = 0;
11886583Sgblack@eecs.umich.edu                } else {
11896583Sgblack@eecs.umich.edu                    resBits = (arg1Bits << shiftAmt);
11906583Sgblack@eecs.umich.edu                }
11916583Sgblack@eecs.umich.edu
11926583Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
11936583Sgblack@eecs.umich.edu            }
11948588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
11956583Sgblack@eecs.umich.edu        '''
11966583Sgblack@eecs.umich.edu
11976605Sgblack@eecs.umich.edu    class Cvtf2i(MediaOp):
11986605Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
11996605Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
12006605Sgblack@eecs.umich.edu            super(Cvtf2i, self).__init__(dest, src,\
12016605Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
120212707Sgabeblack@google.com        op_class = 'SimdFloatCvtOp'
12036605Sgblack@eecs.umich.edu        code = '''
12046605Sgblack@eecs.umich.edu            union floatInt
12056605Sgblack@eecs.umich.edu            {
12066605Sgblack@eecs.umich.edu                float f;
12076605Sgblack@eecs.umich.edu                uint32_t i;
12086605Sgblack@eecs.umich.edu            };
12096605Sgblack@eecs.umich.edu            union doubleInt
12106605Sgblack@eecs.umich.edu            {
12116605Sgblack@eecs.umich.edu                double d;
12126605Sgblack@eecs.umich.edu                uint64_t i;
12136605Sgblack@eecs.umich.edu            };
12146605Sgblack@eecs.umich.edu
12156605Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
12166605Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
12176605Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
12186605Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
12196605Sgblack@eecs.umich.edu            int items;
12206605Sgblack@eecs.umich.edu            int srcStart = 0;
12216605Sgblack@eecs.umich.edu            int destStart = 0;
12226605Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
12236799Sgblack@eecs.umich.edu                items = numItems(srcSize);
12246605Sgblack@eecs.umich.edu                if (ext & 0x2)
12256605Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
12266605Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
12276799Sgblack@eecs.umich.edu                items = numItems(destSize);
12286605Sgblack@eecs.umich.edu                if (ext & 0x2)
12296605Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
12306605Sgblack@eecs.umich.edu            } else {
12316799Sgblack@eecs.umich.edu                items = numItems(destSize);
12326605Sgblack@eecs.umich.edu            }
12338588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
12346605Sgblack@eecs.umich.edu
12356605Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
12366605Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
12376605Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
12388588Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex);
12396605Sgblack@eecs.umich.edu                double arg;
12406605Sgblack@eecs.umich.edu
12416605Sgblack@eecs.umich.edu                if (srcSize == 4) {
12426605Sgblack@eecs.umich.edu                    floatInt fi;
12436605Sgblack@eecs.umich.edu                    fi.i = argBits;
12446605Sgblack@eecs.umich.edu                    arg = fi.f;
12456605Sgblack@eecs.umich.edu                } else {
12466605Sgblack@eecs.umich.edu                    doubleInt di;
12476605Sgblack@eecs.umich.edu                    di.i = argBits;
12486605Sgblack@eecs.umich.edu                    arg = di.d;
12496605Sgblack@eecs.umich.edu                }
12506605Sgblack@eecs.umich.edu
12516605Sgblack@eecs.umich.edu                if (ext & 0x4) {
12526605Sgblack@eecs.umich.edu                    if (arg >= 0)
12536605Sgblack@eecs.umich.edu                        arg += 0.5;
12546605Sgblack@eecs.umich.edu                    else
12556605Sgblack@eecs.umich.edu                        arg -= 0.5;
12566605Sgblack@eecs.umich.edu                }
12576605Sgblack@eecs.umich.edu
12586605Sgblack@eecs.umich.edu                if (destSize == 4) {
125911711Santhony.gutierrez@amd.com                    int32_t i_arg = (int32_t)arg;
126011711Santhony.gutierrez@amd.com                    argBits = *((uint32_t*)&i_arg);
12616605Sgblack@eecs.umich.edu                } else {
126211711Santhony.gutierrez@amd.com                    int64_t i_arg = (int64_t)arg;
126311711Santhony.gutierrez@amd.com                    argBits = *((uint64_t*)&i_arg);
12646605Sgblack@eecs.umich.edu                }
12656605Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
12666605Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
12676605Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
12686605Sgblack@eecs.umich.edu            }
12698588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
12706605Sgblack@eecs.umich.edu        '''
12716605Sgblack@eecs.umich.edu
12726562Sgblack@eecs.umich.edu    class Cvti2f(MediaOp):
12736562Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
12746562Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
12756562Sgblack@eecs.umich.edu            super(Cvti2f, self).__init__(dest, src,\
12766562Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
127712707Sgabeblack@google.com        op_class = 'SimdFloatCvtOp'
12786562Sgblack@eecs.umich.edu        code = '''
12796562Sgblack@eecs.umich.edu            union floatInt
12806562Sgblack@eecs.umich.edu            {
12816562Sgblack@eecs.umich.edu                float f;
12826562Sgblack@eecs.umich.edu                uint32_t i;
12836562Sgblack@eecs.umich.edu            };
12846562Sgblack@eecs.umich.edu            union doubleInt
12856562Sgblack@eecs.umich.edu            {
12866562Sgblack@eecs.umich.edu                double d;
12876562Sgblack@eecs.umich.edu                uint64_t i;
12886562Sgblack@eecs.umich.edu            };
12896562Sgblack@eecs.umich.edu
12906562Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
12916562Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
12926562Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
12936562Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
12946562Sgblack@eecs.umich.edu            int items;
12956562Sgblack@eecs.umich.edu            int srcStart = 0;
12966562Sgblack@eecs.umich.edu            int destStart = 0;
12976562Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
12986799Sgblack@eecs.umich.edu                items = numItems(srcSize);
12996562Sgblack@eecs.umich.edu                if (ext & 0x2)
13006562Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
13016562Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
13026799Sgblack@eecs.umich.edu                items = numItems(destSize);
13036562Sgblack@eecs.umich.edu                if (ext & 0x2)
13046562Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
13056562Sgblack@eecs.umich.edu            } else {
13066799Sgblack@eecs.umich.edu                items = numItems(destSize);
13076562Sgblack@eecs.umich.edu            }
13088588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
13096562Sgblack@eecs.umich.edu
13106562Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
13116562Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
13126562Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
13138588Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex);
13146742Svince@csl.cornell.edu
13157081Sgblack@eecs.umich.edu                int64_t sArg = argBits |
13167081Sgblack@eecs.umich.edu                    (0 - (argBits & (ULL(1) << (srcSizeBits - 1))));
13176562Sgblack@eecs.umich.edu                double arg = sArg;
13186562Sgblack@eecs.umich.edu
13196562Sgblack@eecs.umich.edu                if (destSize == 4) {
13206562Sgblack@eecs.umich.edu                    floatInt fi;
13216562Sgblack@eecs.umich.edu                    fi.f = arg;
13226562Sgblack@eecs.umich.edu                    argBits = fi.i;
13236562Sgblack@eecs.umich.edu                } else {
13246562Sgblack@eecs.umich.edu                    doubleInt di;
13256562Sgblack@eecs.umich.edu                    di.d = arg;
13266562Sgblack@eecs.umich.edu                    argBits = di.i;
13276562Sgblack@eecs.umich.edu                }
13286562Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
13296562Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
13306562Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
13316562Sgblack@eecs.umich.edu            }
13328588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
13336562Sgblack@eecs.umich.edu        '''
13346566Sgblack@eecs.umich.edu
13356568Sgblack@eecs.umich.edu    class Cvtf2f(MediaOp):
13366568Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
13376568Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
13386568Sgblack@eecs.umich.edu            super(Cvtf2f, self).__init__(dest, src,\
13396568Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
134012707Sgabeblack@google.com        op_class = 'SimdFloatCvtOp'
13416568Sgblack@eecs.umich.edu        code = '''
13426568Sgblack@eecs.umich.edu            union floatInt
13436568Sgblack@eecs.umich.edu            {
13446568Sgblack@eecs.umich.edu                float f;
13456568Sgblack@eecs.umich.edu                uint32_t i;
13466568Sgblack@eecs.umich.edu            };
13476568Sgblack@eecs.umich.edu            union doubleInt
13486568Sgblack@eecs.umich.edu            {
13496568Sgblack@eecs.umich.edu                double d;
13506568Sgblack@eecs.umich.edu                uint64_t i;
13516568Sgblack@eecs.umich.edu            };
13526568Sgblack@eecs.umich.edu
13536568Sgblack@eecs.umich.edu            assert(destSize == 4 || destSize == 8);
13546568Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
13556568Sgblack@eecs.umich.edu            int srcSizeBits = srcSize * 8;
13566568Sgblack@eecs.umich.edu            int destSizeBits = destSize * 8;
13576568Sgblack@eecs.umich.edu            int items;
13586568Sgblack@eecs.umich.edu            int srcStart = 0;
13596568Sgblack@eecs.umich.edu            int destStart = 0;
13606568Sgblack@eecs.umich.edu            if (srcSize == 2 * destSize) {
13616799Sgblack@eecs.umich.edu                items = numItems(srcSize);
13626568Sgblack@eecs.umich.edu                if (ext & 0x2)
13636568Sgblack@eecs.umich.edu                    destStart = destSizeBits * items;
13646568Sgblack@eecs.umich.edu            } else if (destSize == 2 * srcSize) {
13656799Sgblack@eecs.umich.edu                items = numItems(destSize);
13666568Sgblack@eecs.umich.edu                if (ext & 0x2)
13676568Sgblack@eecs.umich.edu                    srcStart = srcSizeBits * items;
13686568Sgblack@eecs.umich.edu            } else {
13696799Sgblack@eecs.umich.edu                items = numItems(destSize);
13706568Sgblack@eecs.umich.edu            }
13718588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
13726568Sgblack@eecs.umich.edu
13736568Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
13746568Sgblack@eecs.umich.edu                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
13756568Sgblack@eecs.umich.edu                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
13768588Sgblack@eecs.umich.edu                uint64_t argBits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex);
13776568Sgblack@eecs.umich.edu                double arg;
13786568Sgblack@eecs.umich.edu
13796568Sgblack@eecs.umich.edu                if (srcSize == 4) {
13806568Sgblack@eecs.umich.edu                    floatInt fi;
13816568Sgblack@eecs.umich.edu                    fi.i = argBits;
13826568Sgblack@eecs.umich.edu                    arg = fi.f;
13836568Sgblack@eecs.umich.edu                } else {
13846568Sgblack@eecs.umich.edu                    doubleInt di;
13856568Sgblack@eecs.umich.edu                    di.i = argBits;
13866568Sgblack@eecs.umich.edu                    arg = di.d;
13876568Sgblack@eecs.umich.edu                }
13886568Sgblack@eecs.umich.edu                if (destSize == 4) {
13896568Sgblack@eecs.umich.edu                    floatInt fi;
13906568Sgblack@eecs.umich.edu                    fi.f = arg;
13916568Sgblack@eecs.umich.edu                    argBits = fi.i;
13926568Sgblack@eecs.umich.edu                } else {
13936568Sgblack@eecs.umich.edu                    doubleInt di;
13946568Sgblack@eecs.umich.edu                    di.d = arg;
13956568Sgblack@eecs.umich.edu                    argBits = di.i;
13966568Sgblack@eecs.umich.edu                }
13976568Sgblack@eecs.umich.edu                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
13986568Sgblack@eecs.umich.edu                int destLoIndex = destStart + (i + 0) * destSizeBits;
13996568Sgblack@eecs.umich.edu                result = insertBits(result, destHiIndex, destLoIndex, argBits);
14006568Sgblack@eecs.umich.edu            }
14018588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
14026568Sgblack@eecs.umich.edu        '''
14036568Sgblack@eecs.umich.edu
14046566Sgblack@eecs.umich.edu    class Mcmpi2r(MediaOp):
140512707Sgabeblack@google.com        op_class = 'SimdCvtOp'
14066566Sgblack@eecs.umich.edu        code = '''
14076566Sgblack@eecs.umich.edu            union floatInt
14086566Sgblack@eecs.umich.edu            {
14096566Sgblack@eecs.umich.edu                float f;
14106566Sgblack@eecs.umich.edu                uint32_t i;
14116566Sgblack@eecs.umich.edu            };
14126566Sgblack@eecs.umich.edu            union doubleInt
14136566Sgblack@eecs.umich.edu            {
14146566Sgblack@eecs.umich.edu                double d;
14156566Sgblack@eecs.umich.edu                uint64_t i;
14166566Sgblack@eecs.umich.edu            };
14176566Sgblack@eecs.umich.edu
14186566Sgblack@eecs.umich.edu            assert(srcSize == destSize);
14196566Sgblack@eecs.umich.edu            int size = srcSize;
14206566Sgblack@eecs.umich.edu            int sizeBits = size * 8;
14216799Sgblack@eecs.umich.edu            int items = numItems(size);
14228588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
14236566Sgblack@eecs.umich.edu
14246566Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
14256566Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
14266566Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
14278588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
14286566Sgblack@eecs.umich.edu                int64_t arg1 = arg1Bits |
14296742Svince@csl.cornell.edu                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
14308588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
14316566Sgblack@eecs.umich.edu                int64_t arg2 = arg2Bits |
14326742Svince@csl.cornell.edu                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
14336566Sgblack@eecs.umich.edu
14346566Sgblack@eecs.umich.edu                uint64_t resBits = 0;
14356622Snate@binkert.org                if (((ext & 0x2) == 0 && arg1 == arg2) ||
14366622Snate@binkert.org                    ((ext & 0x2) == 0x2 && arg1 > arg2))
14376566Sgblack@eecs.umich.edu                    resBits = mask(sizeBits);
14386566Sgblack@eecs.umich.edu
14396566Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
14406566Sgblack@eecs.umich.edu            }
14418588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
14426566Sgblack@eecs.umich.edu        '''
14436601Sgblack@eecs.umich.edu
14446603Sgblack@eecs.umich.edu    class Mcmpf2r(MediaOp):
144512707Sgabeblack@google.com        op_class = 'SimdFloatCvtOp'
14466603Sgblack@eecs.umich.edu        code = '''
14476603Sgblack@eecs.umich.edu            union floatInt
14486603Sgblack@eecs.umich.edu            {
14496603Sgblack@eecs.umich.edu                float f;
14506603Sgblack@eecs.umich.edu                uint32_t i;
14516603Sgblack@eecs.umich.edu            };
14526603Sgblack@eecs.umich.edu            union doubleInt
14536603Sgblack@eecs.umich.edu            {
14546603Sgblack@eecs.umich.edu                double d;
14556603Sgblack@eecs.umich.edu                uint64_t i;
14566603Sgblack@eecs.umich.edu            };
14576603Sgblack@eecs.umich.edu
14586603Sgblack@eecs.umich.edu            assert(srcSize == destSize);
14596603Sgblack@eecs.umich.edu            int size = srcSize;
14606603Sgblack@eecs.umich.edu            int sizeBits = size * 8;
14616799Sgblack@eecs.umich.edu            int items = numItems(size);
14628588Sgblack@eecs.umich.edu            uint64_t result = FpDestReg_uqw;
14636603Sgblack@eecs.umich.edu
14646603Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
14656603Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
14666603Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
14678588Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex);
14688588Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex);
14696603Sgblack@eecs.umich.edu                double arg1, arg2;
14706603Sgblack@eecs.umich.edu
14716603Sgblack@eecs.umich.edu                if (size == 4) {
14726603Sgblack@eecs.umich.edu                    floatInt fi;
14736603Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
14746603Sgblack@eecs.umich.edu                    arg1 = fi.f;
14756603Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
14766603Sgblack@eecs.umich.edu                    arg2 = fi.f;
14776603Sgblack@eecs.umich.edu                } else {
14786603Sgblack@eecs.umich.edu                    doubleInt di;
14796603Sgblack@eecs.umich.edu                    di.i = arg1Bits;
14806603Sgblack@eecs.umich.edu                    arg1 = di.d;
14816603Sgblack@eecs.umich.edu                    di.i = arg2Bits;
14826603Sgblack@eecs.umich.edu                    arg2 = di.d;
14836603Sgblack@eecs.umich.edu                }
14846603Sgblack@eecs.umich.edu
14856603Sgblack@eecs.umich.edu                uint64_t resBits = 0;
14868946Sandreas.hansson@arm.com                bool nanop = std::isnan(arg1) || std::isnan(arg2);
14876603Sgblack@eecs.umich.edu                switch (ext & mask(3)) {
14886603Sgblack@eecs.umich.edu                  case 0:
14896603Sgblack@eecs.umich.edu                    if (arg1 == arg2 && !nanop)
14906603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14916603Sgblack@eecs.umich.edu                    break;
14926603Sgblack@eecs.umich.edu                  case 1:
14936603Sgblack@eecs.umich.edu                    if (arg1 < arg2 && !nanop)
14946603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14956603Sgblack@eecs.umich.edu                    break;
14966603Sgblack@eecs.umich.edu                  case 2:
14976603Sgblack@eecs.umich.edu                    if (arg1 <= arg2 && !nanop)
14986603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
14996603Sgblack@eecs.umich.edu                    break;
15006603Sgblack@eecs.umich.edu                  case 3:
15016603Sgblack@eecs.umich.edu                    if (nanop)
15026603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
15036603Sgblack@eecs.umich.edu                    break;
15046603Sgblack@eecs.umich.edu                  case 4:
15056603Sgblack@eecs.umich.edu                    if (arg1 != arg2 || nanop)
15066603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
15076603Sgblack@eecs.umich.edu                    break;
15086603Sgblack@eecs.umich.edu                  case 5:
15096603Sgblack@eecs.umich.edu                    if (!(arg1 < arg2) || nanop)
15106603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
15116603Sgblack@eecs.umich.edu                    break;
15126603Sgblack@eecs.umich.edu                  case 6:
15136603Sgblack@eecs.umich.edu                    if (!(arg1 <= arg2) || nanop)
15146603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
15156603Sgblack@eecs.umich.edu                    break;
15166603Sgblack@eecs.umich.edu                  case 7:
15176603Sgblack@eecs.umich.edu                    if (!nanop)
15186603Sgblack@eecs.umich.edu                        resBits = mask(sizeBits);
15196603Sgblack@eecs.umich.edu                    break;
15206603Sgblack@eecs.umich.edu                };
15216603Sgblack@eecs.umich.edu
15226603Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
15236603Sgblack@eecs.umich.edu            }
15248588Sgblack@eecs.umich.edu            FpDestReg_uqw = result;
15256603Sgblack@eecs.umich.edu        '''
15266603Sgblack@eecs.umich.edu
15276601Sgblack@eecs.umich.edu    class Mcmpf2rf(MediaOp):
15286601Sgblack@eecs.umich.edu        def __init__(self, src1, src2,\
15296601Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
15306601Sgblack@eecs.umich.edu            super(Mcmpf2rf, self).__init__("InstRegIndex(0)", src1,\
15316601Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
153212707Sgabeblack@google.com        op_class = 'SimdFloatCvtOp'
15336601Sgblack@eecs.umich.edu        code = '''
15346601Sgblack@eecs.umich.edu            union floatInt
15356601Sgblack@eecs.umich.edu            {
15366601Sgblack@eecs.umich.edu                float f;
15376601Sgblack@eecs.umich.edu                uint32_t i;
15386601Sgblack@eecs.umich.edu            };
15396601Sgblack@eecs.umich.edu            union doubleInt
15406601Sgblack@eecs.umich.edu            {
15416601Sgblack@eecs.umich.edu                double d;
15426601Sgblack@eecs.umich.edu                uint64_t i;
15436601Sgblack@eecs.umich.edu            };
15446601Sgblack@eecs.umich.edu
15456601Sgblack@eecs.umich.edu            assert(srcSize == destSize);
15466601Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
15476601Sgblack@eecs.umich.edu            int size = srcSize;
15486601Sgblack@eecs.umich.edu            int sizeBits = size * 8;
15496601Sgblack@eecs.umich.edu
15506601Sgblack@eecs.umich.edu            double arg1, arg2;
15518588Sgblack@eecs.umich.edu            uint64_t arg1Bits = bits(FpSrcReg1_uqw, sizeBits - 1, 0);
15528588Sgblack@eecs.umich.edu            uint64_t arg2Bits = bits(FpSrcReg2_uqw, sizeBits - 1, 0);
15536601Sgblack@eecs.umich.edu            if (size == 4) {
15546601Sgblack@eecs.umich.edu                floatInt fi;
15556601Sgblack@eecs.umich.edu                fi.i = arg1Bits;
15566601Sgblack@eecs.umich.edu                arg1 = fi.f;
15576601Sgblack@eecs.umich.edu                fi.i = arg2Bits;
15586601Sgblack@eecs.umich.edu                arg2 = fi.f;
15596601Sgblack@eecs.umich.edu            } else {
15606601Sgblack@eecs.umich.edu                doubleInt di;
15616601Sgblack@eecs.umich.edu                di.i = arg1Bits;
15626601Sgblack@eecs.umich.edu                arg1 = di.d;
15636601Sgblack@eecs.umich.edu                di.i = arg2Bits;
15646601Sgblack@eecs.umich.edu                arg2 = di.d;
15656601Sgblack@eecs.umich.edu            }
15666601Sgblack@eecs.umich.edu
15676601Sgblack@eecs.umich.edu            //               ZF PF CF
15686601Sgblack@eecs.umich.edu            // Unordered      1  1  1
15696601Sgblack@eecs.umich.edu            // Greater than   0  0  0
15706601Sgblack@eecs.umich.edu            // Less than      0  0  1
15716601Sgblack@eecs.umich.edu            // Equal          1  0  0
15726601Sgblack@eecs.umich.edu            //           OF = SF = AF = 0
15739010Snilay@cs.wisc.edu            ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit);
15749010Snilay@cs.wisc.edu            cfofBits   = cfofBits   & ~(OFBit | CFBit);
15759010Snilay@cs.wisc.edu
15769010Snilay@cs.wisc.edu            if (std::isnan(arg1) || std::isnan(arg2)) {
15779010Snilay@cs.wisc.edu                ccFlagBits = ccFlagBits | (ZFBit | PFBit);
15789010Snilay@cs.wisc.edu                cfofBits = cfofBits | CFBit;
15799010Snilay@cs.wisc.edu            }
15806601Sgblack@eecs.umich.edu            else if(arg1 < arg2)
15819010Snilay@cs.wisc.edu                cfofBits = cfofBits | CFBit;
15826601Sgblack@eecs.umich.edu            else if(arg1 == arg2)
15836601Sgblack@eecs.umich.edu                ccFlagBits = ccFlagBits | ZFBit;
15846601Sgblack@eecs.umich.edu        '''
15859471Snilay@cs.wisc.edu
15869471Snilay@cs.wisc.edu    class Emms(MediaOp):
158712707Sgabeblack@google.com        op_class = 'FloatMiscOp'
15889471Snilay@cs.wisc.edu        def __init__(self):
15899471Snilay@cs.wisc.edu            super(Emms, self).__init__('InstRegIndex(MISCREG_FTW)',
159010042Snilay@cs.wisc.edu                    'InstRegIndex(0)', 'InstRegIndex(0)', 2)
15919471Snilay@cs.wisc.edu        code = 'FTW = 0xFFFF;'
15926516Sgblack@eecs.umich.edu}};
1593