mediaop.isa revision 6537
16516Sgblack@eecs.umich.edu/// Copyright (c) 2009 The Regents of The University of Michigan
26516Sgblack@eecs.umich.edu// All rights reserved.
36516Sgblack@eecs.umich.edu//
46516Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
56516Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
66516Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
76516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
86516Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
96516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
106516Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
116516Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
126516Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
136516Sgblack@eecs.umich.edu// this software without specific prior written permission.
146516Sgblack@eecs.umich.edu//
156516Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
166516Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
176516Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
186516Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
196516Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
206516Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
216516Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
226516Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236516Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
246516Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
256516Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266516Sgblack@eecs.umich.edu//
276516Sgblack@eecs.umich.edu// Authors: Gabe Black
286516Sgblack@eecs.umich.edu
296516Sgblack@eecs.umich.edudef template MediaOpExecute {{
306516Sgblack@eecs.umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
316516Sgblack@eecs.umich.edu                Trace::InstRecord *traceData) const
326516Sgblack@eecs.umich.edu        {
336516Sgblack@eecs.umich.edu            Fault fault = NoFault;
346516Sgblack@eecs.umich.edu
356516Sgblack@eecs.umich.edu            %(op_decl)s;
366516Sgblack@eecs.umich.edu            %(op_rd)s;
376516Sgblack@eecs.umich.edu
386516Sgblack@eecs.umich.edu            %(code)s;
396516Sgblack@eecs.umich.edu
406516Sgblack@eecs.umich.edu            //Write the resulting state to the execution context
416516Sgblack@eecs.umich.edu            if(fault == NoFault)
426516Sgblack@eecs.umich.edu            {
436516Sgblack@eecs.umich.edu                %(op_wb)s;
446516Sgblack@eecs.umich.edu            }
456516Sgblack@eecs.umich.edu            return fault;
466516Sgblack@eecs.umich.edu        }
476516Sgblack@eecs.umich.edu}};
486516Sgblack@eecs.umich.edu
496516Sgblack@eecs.umich.edudef template MediaOpRegDeclare {{
506516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
516516Sgblack@eecs.umich.edu    {
526516Sgblack@eecs.umich.edu      protected:
536516Sgblack@eecs.umich.edu        void buildMe();
546516Sgblack@eecs.umich.edu
556516Sgblack@eecs.umich.edu      public:
566516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
576516Sgblack@eecs.umich.edu                const char * instMnem,
586516Sgblack@eecs.umich.edu                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
596516Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
606516Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _sel);
616516Sgblack@eecs.umich.edu
626516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
636516Sgblack@eecs.umich.edu                const char * instMnem,
646516Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
656516Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _sel);
666516Sgblack@eecs.umich.edu
676516Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
686516Sgblack@eecs.umich.edu    };
696516Sgblack@eecs.umich.edu}};
706516Sgblack@eecs.umich.edu
716516Sgblack@eecs.umich.edudef template MediaOpImmDeclare {{
726516Sgblack@eecs.umich.edu
736516Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
746516Sgblack@eecs.umich.edu    {
756516Sgblack@eecs.umich.edu      protected:
766516Sgblack@eecs.umich.edu        void buildMe();
776516Sgblack@eecs.umich.edu
786516Sgblack@eecs.umich.edu      public:
796516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
806516Sgblack@eecs.umich.edu                const char * instMnem,
816516Sgblack@eecs.umich.edu                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
826516Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
836516Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _sel);
846516Sgblack@eecs.umich.edu
856516Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
866516Sgblack@eecs.umich.edu                const char * instMnem,
876516Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
886516Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _sel);
896516Sgblack@eecs.umich.edu
906516Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
916516Sgblack@eecs.umich.edu    };
926516Sgblack@eecs.umich.edu}};
936516Sgblack@eecs.umich.edu
946516Sgblack@eecs.umich.edudef template MediaOpRegConstructor {{
956516Sgblack@eecs.umich.edu
966516Sgblack@eecs.umich.edu    inline void %(class_name)s::buildMe()
976516Sgblack@eecs.umich.edu    {
986516Sgblack@eecs.umich.edu        %(constructor)s;
996516Sgblack@eecs.umich.edu    }
1006516Sgblack@eecs.umich.edu
1016516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1026516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1036516Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
1046516Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _sel) :
1056516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1066516Sgblack@eecs.umich.edu                false, false, false, false,
1076516Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _sel,
1086516Sgblack@eecs.umich.edu                %(op_class)s)
1096516Sgblack@eecs.umich.edu    {
1106516Sgblack@eecs.umich.edu        buildMe();
1116516Sgblack@eecs.umich.edu    }
1126516Sgblack@eecs.umich.edu
1136516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1146516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1156516Sgblack@eecs.umich.edu            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
1166516Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
1176516Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _sel) :
1186516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1196516Sgblack@eecs.umich.edu                isMicro, isDelayed, isFirst, isLast,
1206516Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _sel,
1216516Sgblack@eecs.umich.edu                %(op_class)s)
1226516Sgblack@eecs.umich.edu    {
1236516Sgblack@eecs.umich.edu        buildMe();
1246516Sgblack@eecs.umich.edu    }
1256516Sgblack@eecs.umich.edu}};
1266516Sgblack@eecs.umich.edu
1276516Sgblack@eecs.umich.edudef template MediaOpImmConstructor {{
1286516Sgblack@eecs.umich.edu
1296516Sgblack@eecs.umich.edu    inline void %(class_name)s::buildMe()
1306516Sgblack@eecs.umich.edu    {
1316516Sgblack@eecs.umich.edu        %(constructor)s;
1326516Sgblack@eecs.umich.edu    }
1336516Sgblack@eecs.umich.edu
1346516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1356516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1366516Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
1376516Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _sel) :
1386516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1396516Sgblack@eecs.umich.edu                false, false, false, false,
1406516Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _sel,
1416516Sgblack@eecs.umich.edu                %(op_class)s)
1426516Sgblack@eecs.umich.edu    {
1436516Sgblack@eecs.umich.edu        buildMe();
1446516Sgblack@eecs.umich.edu    }
1456516Sgblack@eecs.umich.edu
1466516Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1476516Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1486516Sgblack@eecs.umich.edu            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
1496516Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
1506516Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _sel) :
1516516Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1526516Sgblack@eecs.umich.edu                isMicro, isDelayed, isFirst, isLast,
1536516Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _sel,
1546516Sgblack@eecs.umich.edu                %(op_class)s)
1556516Sgblack@eecs.umich.edu    {
1566516Sgblack@eecs.umich.edu        buildMe();
1576516Sgblack@eecs.umich.edu    }
1586516Sgblack@eecs.umich.edu}};
1596516Sgblack@eecs.umich.edu
1606516Sgblack@eecs.umich.edulet {{
1616516Sgblack@eecs.umich.edu    # Make these empty strings so that concatenating onto
1626516Sgblack@eecs.umich.edu    # them will always work.
1636516Sgblack@eecs.umich.edu    header_output = ""
1646516Sgblack@eecs.umich.edu    decoder_output = ""
1656516Sgblack@eecs.umich.edu    exec_output = ""
1666516Sgblack@eecs.umich.edu
1676516Sgblack@eecs.umich.edu    immTemplates = (
1686516Sgblack@eecs.umich.edu            MediaOpImmDeclare,
1696516Sgblack@eecs.umich.edu            MediaOpImmConstructor,
1706516Sgblack@eecs.umich.edu            MediaOpExecute)
1716516Sgblack@eecs.umich.edu
1726516Sgblack@eecs.umich.edu    regTemplates = (
1736516Sgblack@eecs.umich.edu            MediaOpRegDeclare,
1746516Sgblack@eecs.umich.edu            MediaOpRegConstructor,
1756516Sgblack@eecs.umich.edu            MediaOpExecute)
1766516Sgblack@eecs.umich.edu
1776516Sgblack@eecs.umich.edu    class MediaOpMeta(type):
1786516Sgblack@eecs.umich.edu        def buildCppClasses(self, name, Name, suffix, code):
1796516Sgblack@eecs.umich.edu
1806516Sgblack@eecs.umich.edu            # Globals to stick the output in
1816516Sgblack@eecs.umich.edu            global header_output
1826516Sgblack@eecs.umich.edu            global decoder_output
1836516Sgblack@eecs.umich.edu            global exec_output
1846516Sgblack@eecs.umich.edu
1856516Sgblack@eecs.umich.edu            # If op2 is used anywhere, make register and immediate versions
1866516Sgblack@eecs.umich.edu            # of this code.
1876516Sgblack@eecs.umich.edu            matcher = re.compile("(?<!\\w)(?P<prefix>s?)op2(?P<typeQual>\\.\\w+)?")
1886516Sgblack@eecs.umich.edu            match = matcher.search(code)
1896516Sgblack@eecs.umich.edu            if match:
1906516Sgblack@eecs.umich.edu                typeQual = ""
1916516Sgblack@eecs.umich.edu                if match.group("typeQual"):
1926516Sgblack@eecs.umich.edu                    typeQual = match.group("typeQual")
1936516Sgblack@eecs.umich.edu                src2_name = "%spsrc2%s" % (match.group("prefix"), typeQual)
1946516Sgblack@eecs.umich.edu                self.buildCppClasses(name, Name, suffix,
1956516Sgblack@eecs.umich.edu                        matcher.sub(src2_name, code))
1966516Sgblack@eecs.umich.edu                self.buildCppClasses(name + "i", Name, suffix + "Imm",
1976516Sgblack@eecs.umich.edu                        matcher.sub("imm8", code))
1986516Sgblack@eecs.umich.edu                return
1996516Sgblack@eecs.umich.edu
2006516Sgblack@eecs.umich.edu            base = "X86ISA::MediaOp"
2016516Sgblack@eecs.umich.edu
2026516Sgblack@eecs.umich.edu            # If imm8 shows up in the code, use the immediate templates, if
2036516Sgblack@eecs.umich.edu            # not, hopefully the register ones will be correct.
2046516Sgblack@eecs.umich.edu            matcher = re.compile("(?<!\w)imm8(?!\w)")
2056516Sgblack@eecs.umich.edu            if matcher.search(code):
2066516Sgblack@eecs.umich.edu                base += "Imm"
2076516Sgblack@eecs.umich.edu                templates = immTemplates
2086516Sgblack@eecs.umich.edu            else:
2096516Sgblack@eecs.umich.edu                base += "Reg"
2106516Sgblack@eecs.umich.edu                templates = regTemplates
2116516Sgblack@eecs.umich.edu
2126516Sgblack@eecs.umich.edu            # Get everything ready for the substitution
2136516Sgblack@eecs.umich.edu            iop = InstObjParams(name, Name + suffix, base, {"code" : code})
2146516Sgblack@eecs.umich.edu
2156516Sgblack@eecs.umich.edu            # Generate the actual code (finally!)
2166516Sgblack@eecs.umich.edu            header_output += templates[0].subst(iop)
2176516Sgblack@eecs.umich.edu            decoder_output += templates[1].subst(iop)
2186516Sgblack@eecs.umich.edu            exec_output += templates[2].subst(iop)
2196516Sgblack@eecs.umich.edu
2206516Sgblack@eecs.umich.edu
2216516Sgblack@eecs.umich.edu        def __new__(mcls, Name, bases, dict):
2226516Sgblack@eecs.umich.edu            abstract = False
2236516Sgblack@eecs.umich.edu            name = Name.lower()
2246516Sgblack@eecs.umich.edu            if "abstract" in dict:
2256516Sgblack@eecs.umich.edu                abstract = dict['abstract']
2266516Sgblack@eecs.umich.edu                del dict['abstract']
2276516Sgblack@eecs.umich.edu
2286516Sgblack@eecs.umich.edu            cls = super(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict)
2296516Sgblack@eecs.umich.edu            if not abstract:
2306516Sgblack@eecs.umich.edu                cls.className = Name
2316516Sgblack@eecs.umich.edu                cls.base_mnemonic = name
2326516Sgblack@eecs.umich.edu                code = cls.code
2336516Sgblack@eecs.umich.edu
2346516Sgblack@eecs.umich.edu                # Set up the C++ classes
2356516Sgblack@eecs.umich.edu                mcls.buildCppClasses(cls, name, Name, "", code)
2366516Sgblack@eecs.umich.edu
2376516Sgblack@eecs.umich.edu                # Hook into the microassembler dict
2386516Sgblack@eecs.umich.edu                global microopClasses
2396516Sgblack@eecs.umich.edu                microopClasses[name] = cls
2406516Sgblack@eecs.umich.edu
2416516Sgblack@eecs.umich.edu                # If op2 is used anywhere, make register and immediate versions
2426516Sgblack@eecs.umich.edu                # of this code.
2436516Sgblack@eecs.umich.edu                matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
2446516Sgblack@eecs.umich.edu                if matcher.search(code):
2456516Sgblack@eecs.umich.edu                    microopClasses[name + 'i'] = cls
2466516Sgblack@eecs.umich.edu            return cls
2476516Sgblack@eecs.umich.edu
2486516Sgblack@eecs.umich.edu
2496516Sgblack@eecs.umich.edu    class MediaOp(X86Microop):
2506516Sgblack@eecs.umich.edu        __metaclass__ = MediaOpMeta
2516516Sgblack@eecs.umich.edu        # This class itself doesn't act as a microop
2526516Sgblack@eecs.umich.edu        abstract = True
2536516Sgblack@eecs.umich.edu
2546516Sgblack@eecs.umich.edu        def __init__(self, dest, src1, op2,
2556516Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, sel = None):
2566516Sgblack@eecs.umich.edu            self.dest = dest
2576516Sgblack@eecs.umich.edu            self.src1 = src1
2586516Sgblack@eecs.umich.edu            self.op2 = op2
2596516Sgblack@eecs.umich.edu            if size is not None:
2606516Sgblack@eecs.umich.edu                self.srcSize = size
2616516Sgblack@eecs.umich.edu                self.destSize = size
2626516Sgblack@eecs.umich.edu            if srcSize is not None:
2636516Sgblack@eecs.umich.edu                self.srcSize = srcSize
2646516Sgblack@eecs.umich.edu            if destSize is not None:
2656516Sgblack@eecs.umich.edu                self.destSize = destSize
2666516Sgblack@eecs.umich.edu            if self.srcSize is None:
2676516Sgblack@eecs.umich.edu                raise Exception, "Source size not set."
2686516Sgblack@eecs.umich.edu            if self.destSize is None:
2696516Sgblack@eecs.umich.edu                raise Exception, "Dest size not set."
2706516Sgblack@eecs.umich.edu            if sel is None:
2716516Sgblack@eecs.umich.edu                self.sel = 0
2726516Sgblack@eecs.umich.edu            else:
2736516Sgblack@eecs.umich.edu                self.sel = sel
2746516Sgblack@eecs.umich.edu
2756516Sgblack@eecs.umich.edu        def getAllocator(self, *microFlags):
2766516Sgblack@eecs.umich.edu            className = self.className
2776516Sgblack@eecs.umich.edu            if self.mnemonic == self.base_mnemonic + 'i':
2786516Sgblack@eecs.umich.edu                className += "Imm"
2796516Sgblack@eecs.umich.edu            allocator = '''new %(class_name)s(machInst, macrocodeBlock
2806516Sgblack@eecs.umich.edu                    %(flags)s, %(src1)s, %(op2)s, %(dest)s,
2816516Sgblack@eecs.umich.edu                    %(srcSize)s, %(destSize)s, %(sel)s)''' % {
2826516Sgblack@eecs.umich.edu                "class_name" : className,
2836516Sgblack@eecs.umich.edu                "flags" : self.microFlagsText(microFlags),
2846516Sgblack@eecs.umich.edu                "src1" : self.src1, "op2" : self.op2,
2856516Sgblack@eecs.umich.edu                "dest" : self.dest,
2866516Sgblack@eecs.umich.edu                "srcSize" : self.srcSize,
2876516Sgblack@eecs.umich.edu                "destSize" : self.destSize,
2886516Sgblack@eecs.umich.edu                "sel" : self.sel}
2896516Sgblack@eecs.umich.edu            return allocator
2906516Sgblack@eecs.umich.edu
2916516Sgblack@eecs.umich.edu    class Mov2int(MediaOp):
2926516Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
2936516Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, sel = None):
2946516Sgblack@eecs.umich.edu            super(Mov2int, self).__init__(dest, src,\
2956516Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, sel)
2966516Sgblack@eecs.umich.edu        code = '''
2976516Sgblack@eecs.umich.edu            uint64_t fpSrcReg1 = bits(FpSrcReg1.uqw, srcSize * 8 - 1, 0);
2986516Sgblack@eecs.umich.edu            DestReg = merge(DestReg, fpSrcReg1, destSize);
2996516Sgblack@eecs.umich.edu        '''
3006516Sgblack@eecs.umich.edu
3016516Sgblack@eecs.umich.edu    class Mov2fp(MediaOp):
3026516Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
3036516Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, sel = None):
3046516Sgblack@eecs.umich.edu            super(Mov2fp, self).__init__(dest, src,\
3056516Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, sel)
3066516Sgblack@eecs.umich.edu        code = '''
3076516Sgblack@eecs.umich.edu            uint64_t srcReg1 = pick(SrcReg1, 0, srcSize);
3086516Sgblack@eecs.umich.edu            FpDestReg.uqw =
3096516Sgblack@eecs.umich.edu                insertBits(FpDestReg.uqw, destSize * 8 - 1, 0, srcReg1);
3106516Sgblack@eecs.umich.edu        '''
3116521Sgblack@eecs.umich.edu
3126521Sgblack@eecs.umich.edu    class Unpack(MediaOp):
3136521Sgblack@eecs.umich.edu        code = '''
3146521Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3156521Sgblack@eecs.umich.edu            int size = destSize;
3166521Sgblack@eecs.umich.edu            int items = (sizeof(FloatRegBits) / size) / 2;
3176521Sgblack@eecs.umich.edu            int offset = sel ? items : 0;
3186521Sgblack@eecs.umich.edu            uint64_t result = 0;
3196521Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3206521Sgblack@eecs.umich.edu                uint64_t pickedLow =
3216521Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + offset + 1) * 8 * size - 1,
3226521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
3236521Sgblack@eecs.umich.edu                result = insertBits(result,
3246521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size - 1,
3256521Sgblack@eecs.umich.edu                                    (2 * i + 0) * 8 * size,
3266521Sgblack@eecs.umich.edu                                    pickedLow);
3276521Sgblack@eecs.umich.edu                uint64_t pickedHigh =
3286521Sgblack@eecs.umich.edu                    bits(FpSrcReg2.uqw, (i + offset + 1) * 8 * size - 1,
3296521Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
3306521Sgblack@eecs.umich.edu                result = insertBits(result,
3316521Sgblack@eecs.umich.edu                                    (2 * i + 2) * 8 * size - 1,
3326521Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size,
3336521Sgblack@eecs.umich.edu                                    pickedHigh);
3346521Sgblack@eecs.umich.edu            }
3356521Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
3366521Sgblack@eecs.umich.edu        '''
3376534Sgblack@eecs.umich.edu
3386534Sgblack@eecs.umich.edu    class Mxor(MediaOp):
3396534Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
3406534Sgblack@eecs.umich.edu            super(Mxor, self).__init__(dest, src1, src2, 1)
3416534Sgblack@eecs.umich.edu        code = '''
3426534Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw;
3436534Sgblack@eecs.umich.edu        '''
3446537Sgblack@eecs.umich.edu
3456537Sgblack@eecs.umich.edu    class Mor(MediaOp):
3466537Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
3476537Sgblack@eecs.umich.edu            super(Mor, self).__init__(dest, src1, src2, 1)
3486537Sgblack@eecs.umich.edu        code = '''
3496537Sgblack@eecs.umich.edu            FpDestReg.uqw = FpSrcReg1.uqw | FpSrcReg2.uqw;
3506537Sgblack@eecs.umich.edu        '''
3516516Sgblack@eecs.umich.edu}};
352