mediaop.isa revision 6799:36131e4dfb6e
17202Sgblack@eecs.umich.edu/// Copyright (c) 2009 The Regents of The University of Michigan
27202Sgblack@eecs.umich.edu// All rights reserved.
312503Snikos.nikoleris@arm.com//
47202Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
57202Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
67202Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
77202Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
87202Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
97202Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
107202Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
117202Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
127202Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
137202Sgblack@eecs.umich.edu// this software without specific prior written permission.
147202Sgblack@eecs.umich.edu//
157202Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
167202Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
177202Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
187202Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
197202Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
207202Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
217202Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
227202Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
237202Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
247202Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
257202Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
267202Sgblack@eecs.umich.edu//
277202Sgblack@eecs.umich.edu// Authors: Gabe Black
287202Sgblack@eecs.umich.edu
297202Sgblack@eecs.umich.edudef template MediaOpExecute {{
307202Sgblack@eecs.umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
317202Sgblack@eecs.umich.edu                Trace::InstRecord *traceData) const
327202Sgblack@eecs.umich.edu        {
337202Sgblack@eecs.umich.edu            Fault fault = NoFault;
347202Sgblack@eecs.umich.edu
357202Sgblack@eecs.umich.edu            %(op_decl)s;
367202Sgblack@eecs.umich.edu            %(op_rd)s;
377202Sgblack@eecs.umich.edu
387202Sgblack@eecs.umich.edu            %(code)s;
397202Sgblack@eecs.umich.edu
407202Sgblack@eecs.umich.edu            //Write the resulting state to the execution context
417202Sgblack@eecs.umich.edu            if(fault == NoFault)
427202Sgblack@eecs.umich.edu            {
437202Sgblack@eecs.umich.edu                %(op_wb)s;
447202Sgblack@eecs.umich.edu            }
457202Sgblack@eecs.umich.edu            return fault;
467202Sgblack@eecs.umich.edu        }
4712236Sgabeblack@google.com}};
487202Sgblack@eecs.umich.edu
497202Sgblack@eecs.umich.edudef template MediaOpRegDeclare {{
507202Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
517202Sgblack@eecs.umich.edu    {
5210184SCurtis.Dunham@arm.com      protected:
537202Sgblack@eecs.umich.edu        void buildMe();
547202Sgblack@eecs.umich.edu
557202Sgblack@eecs.umich.edu      public:
567202Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
577848SAli.Saidi@ARM.com                const char * instMnem,
587848SAli.Saidi@ARM.com                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
597848SAli.Saidi@ARM.com                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
607848SAli.Saidi@ARM.com                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
617848SAli.Saidi@ARM.com
627202Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
637202Sgblack@eecs.umich.edu                const char * instMnem,
647202Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
6510037SARM gem5 Developers                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
6610037SARM gem5 Developers
6710037SARM gem5 Developers        %(BasicExecDeclare)s
6810037SARM gem5 Developers    };
6910037SARM gem5 Developers}};
7010037SARM gem5 Developers
7110037SARM gem5 Developersdef template MediaOpImmDeclare {{
7210037SARM gem5 Developers
7310037SARM gem5 Developers    class %(class_name)s : public %(base_class)s
7410037SARM gem5 Developers    {
7510037SARM gem5 Developers      protected:
7612236Sgabeblack@google.com        void buildMe();
7710037SARM gem5 Developers
7810037SARM gem5 Developers      public:
7910037SARM gem5 Developers        %(class_name)s(ExtMachInst _machInst,
8010037SARM gem5 Developers                const char * instMnem,
8110184SCurtis.Dunham@arm.com                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
8210037SARM gem5 Developers                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
8310037SARM gem5 Developers                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
8410037SARM gem5 Developers
8510037SARM gem5 Developers        %(class_name)s(ExtMachInst _machInst,
8610037SARM gem5 Developers                const char * instMnem,
8710037SARM gem5 Developers                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
8810037SARM gem5 Developers                uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
8910037SARM gem5 Developers
9010037SARM gem5 Developers        %(BasicExecDeclare)s
9110037SARM gem5 Developers    };
9210037SARM gem5 Developers}};
9310037SARM gem5 Developers
9410037SARM gem5 Developersdef template MediaOpRegConstructor {{
9510037SARM gem5 Developers
9610037SARM gem5 Developers    inline void %(class_name)s::buildMe()
9710037SARM gem5 Developers    {
9810037SARM gem5 Developers        %(constructor)s;
9910037SARM gem5 Developers    }
10010037SARM gem5 Developers
10110037SARM gem5 Developers    inline %(class_name)s::%(class_name)s(
10210037SARM gem5 Developers            ExtMachInst machInst, const char * instMnem,
10310037SARM gem5 Developers            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
10410037SARM gem5 Developers            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
10510037SARM gem5 Developers        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
10610037SARM gem5 Developers                false, false, false, false,
10712236Sgabeblack@google.com                _src1, _src2, _dest, _srcSize, _destSize, _ext,
10810037SARM gem5 Developers                %(op_class)s)
10910037SARM gem5 Developers    {
11010037SARM gem5 Developers        buildMe();
11110037SARM gem5 Developers    }
11210184SCurtis.Dunham@arm.com
11310037SARM gem5 Developers    inline %(class_name)s::%(class_name)s(
11410037SARM gem5 Developers            ExtMachInst machInst, const char * instMnem,
11510037SARM gem5 Developers            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
11610037SARM gem5 Developers            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
11710037SARM gem5 Developers            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
11810037SARM gem5 Developers        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
11910037SARM gem5 Developers                isMicro, isDelayed, isFirst, isLast,
12010037SARM gem5 Developers                _src1, _src2, _dest, _srcSize, _destSize, _ext,
12110037SARM gem5 Developers                %(op_class)s)
12210037SARM gem5 Developers    {
12310037SARM gem5 Developers        buildMe();
12410037SARM gem5 Developers    }
12510037SARM gem5 Developers}};
12610037SARM gem5 Developers
12710037SARM gem5 Developersdef template MediaOpImmConstructor {{
1287202Sgblack@eecs.umich.edu
1297202Sgblack@eecs.umich.edu    inline void %(class_name)s::buildMe()
1307202Sgblack@eecs.umich.edu    {
1317202Sgblack@eecs.umich.edu        %(constructor)s;
1327202Sgblack@eecs.umich.edu    }
1337202Sgblack@eecs.umich.edu
1347202Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
13512236Sgabeblack@google.com            ExtMachInst machInst, const char * instMnem,
1367202Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
1377202Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
1387202Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1397202Sgblack@eecs.umich.edu                false, false, false, false,
14010184SCurtis.Dunham@arm.com                _src1, _imm8, _dest, _srcSize, _destSize, _ext,
1417202Sgblack@eecs.umich.edu                %(op_class)s)
1427202Sgblack@eecs.umich.edu    {
1437202Sgblack@eecs.umich.edu        buildMe();
1447202Sgblack@eecs.umich.edu    }
1457202Sgblack@eecs.umich.edu
1467848SAli.Saidi@ARM.com    inline %(class_name)s::%(class_name)s(
1477848SAli.Saidi@ARM.com            ExtMachInst machInst, const char * instMnem,
1487848SAli.Saidi@ARM.com            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
1497848SAli.Saidi@ARM.com            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
1507848SAli.Saidi@ARM.com            uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
1517202Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1527202Sgblack@eecs.umich.edu                isMicro, isDelayed, isFirst, isLast,
1537202Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _ext,
1547202Sgblack@eecs.umich.edu                %(op_class)s)
1557202Sgblack@eecs.umich.edu    {
1567202Sgblack@eecs.umich.edu        buildMe();
1577202Sgblack@eecs.umich.edu    }
1587202Sgblack@eecs.umich.edu}};
1597202Sgblack@eecs.umich.edu
1607202Sgblack@eecs.umich.edulet {{
16112236Sgabeblack@google.com    # Make these empty strings so that concatenating onto
1627202Sgblack@eecs.umich.edu    # them will always work.
1637202Sgblack@eecs.umich.edu    header_output = ""
1647202Sgblack@eecs.umich.edu    decoder_output = ""
1657202Sgblack@eecs.umich.edu    exec_output = ""
16610184SCurtis.Dunham@arm.com
1677202Sgblack@eecs.umich.edu    immTemplates = (
1687202Sgblack@eecs.umich.edu            MediaOpImmDeclare,
1697202Sgblack@eecs.umich.edu            MediaOpImmConstructor,
1707202Sgblack@eecs.umich.edu            MediaOpExecute)
1717202Sgblack@eecs.umich.edu
1727848SAli.Saidi@ARM.com    regTemplates = (
1737848SAli.Saidi@ARM.com            MediaOpRegDeclare,
1747848SAli.Saidi@ARM.com            MediaOpRegConstructor,
1757848SAli.Saidi@ARM.com            MediaOpExecute)
1767848SAli.Saidi@ARM.com
1777202Sgblack@eecs.umich.edu    class MediaOpMeta(type):
1787202Sgblack@eecs.umich.edu        def buildCppClasses(self, name, Name, suffix, code):
1797208Sgblack@eecs.umich.edu
18010037SARM gem5 Developers            # Globals to stick the output in
18110037SARM gem5 Developers            global header_output
18210037SARM gem5 Developers            global decoder_output
18310037SARM gem5 Developers            global exec_output
18410037SARM gem5 Developers
18510037SARM gem5 Developers            # If op2 is used anywhere, make register and immediate versions
18610420Sandreas.hansson@arm.com            # of this code.
18710037SARM gem5 Developers            matcher = re.compile("(?<!\\w)(?P<prefix>s?)op2(?P<typeQual>\\.\\w+)?")
18812236Sgabeblack@google.com            match = matcher.search(code)
18910037SARM gem5 Developers            if match:
19010037SARM gem5 Developers                typeQual = ""
19110037SARM gem5 Developers                if match.group("typeQual"):
19210037SARM gem5 Developers                    typeQual = match.group("typeQual")
19310184SCurtis.Dunham@arm.com                src2_name = "%sFpSrcReg2%s" % (match.group("prefix"), typeQual)
19410420Sandreas.hansson@arm.com                self.buildCppClasses(name, Name, suffix,
19510037SARM gem5 Developers                        matcher.sub(src2_name, code))
19610037SARM gem5 Developers                self.buildCppClasses(name + "i", Name, suffix + "Imm",
19710037SARM gem5 Developers                        matcher.sub("imm8", code))
19810037SARM gem5 Developers                return
19910037SARM gem5 Developers
20010037SARM gem5 Developers            base = "X86ISA::MediaOp"
20110037SARM gem5 Developers
20210037SARM gem5 Developers            # If imm8 shows up in the code, use the immediate templates, if
20310037SARM gem5 Developers            # not, hopefully the register ones will be correct.
20410037SARM gem5 Developers            matcher = re.compile("(?<!\w)imm8(?!\w)")
20510037SARM gem5 Developers            if matcher.search(code):
20610037SARM gem5 Developers                base += "Imm"
20710037SARM gem5 Developers                templates = immTemplates
20810037SARM gem5 Developers            else:
20910037SARM gem5 Developers                base += "Reg"
21010037SARM gem5 Developers                templates = regTemplates
21110037SARM gem5 Developers
21210037SARM gem5 Developers            # Get everything ready for the substitution
21310037SARM gem5 Developers            iop = InstObjParams(name, Name + suffix, base, {"code" : code})
21410037SARM gem5 Developers
21510037SARM gem5 Developers            # Generate the actual code (finally!)
21610037SARM gem5 Developers            header_output += templates[0].subst(iop)
21710420Sandreas.hansson@arm.com            decoder_output += templates[1].subst(iop)
21812236Sgabeblack@google.com            exec_output += templates[2].subst(iop)
21910037SARM gem5 Developers
22010037SARM gem5 Developers
22110037SARM gem5 Developers        def __new__(mcls, Name, bases, dict):
22210037SARM gem5 Developers            abstract = False
22310184SCurtis.Dunham@arm.com            name = Name.lower()
22410037SARM gem5 Developers            if "abstract" in dict:
22510037SARM gem5 Developers                abstract = dict['abstract']
22610420Sandreas.hansson@arm.com                del dict['abstract']
22710037SARM gem5 Developers
22810037SARM gem5 Developers            cls = super(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict)
22910037SARM gem5 Developers            if not abstract:
23010037SARM gem5 Developers                cls.className = Name
23110037SARM gem5 Developers                cls.base_mnemonic = name
23210037SARM gem5 Developers                code = cls.code
23310037SARM gem5 Developers
23410037SARM gem5 Developers                # Set up the C++ classes
23510037SARM gem5 Developers                mcls.buildCppClasses(cls, name, Name, "", code)
23610037SARM gem5 Developers
23710037SARM gem5 Developers                # Hook into the microassembler dict
23810037SARM gem5 Developers                global microopClasses
23910037SARM gem5 Developers                microopClasses[name] = cls
2407306Sgblack@eecs.umich.edu
2417306Sgblack@eecs.umich.edu                # If op2 is used anywhere, make register and immediate versions
2427306Sgblack@eecs.umich.edu                # of this code.
2437306Sgblack@eecs.umich.edu                matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
2447306Sgblack@eecs.umich.edu                if matcher.search(code):
2457306Sgblack@eecs.umich.edu                    microopClasses[name + 'i'] = cls
2467330Sgblack@eecs.umich.edu            return cls
24712236Sgabeblack@google.com
2487306Sgblack@eecs.umich.edu
2497306Sgblack@eecs.umich.edu    class MediaOp(X86Microop):
2507306Sgblack@eecs.umich.edu        __metaclass__ = MediaOpMeta
2517306Sgblack@eecs.umich.edu        # This class itself doesn't act as a microop
25210184SCurtis.Dunham@arm.com        abstract = True
2537306Sgblack@eecs.umich.edu
2547306Sgblack@eecs.umich.edu        def __init__(self, dest, src1, op2,
2557306Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2567848SAli.Saidi@ARM.com            self.dest = dest
2577848SAli.Saidi@ARM.com            self.src1 = src1
2587848SAli.Saidi@ARM.com            self.op2 = op2
2597848SAli.Saidi@ARM.com            if size is not None:
2607848SAli.Saidi@ARM.com                self.srcSize = size
2617306Sgblack@eecs.umich.edu                self.destSize = size
2627306Sgblack@eecs.umich.edu            if srcSize is not None:
2637306Sgblack@eecs.umich.edu                self.srcSize = srcSize
2647332Sgblack@eecs.umich.edu            if destSize is not None:
2657332Sgblack@eecs.umich.edu                self.destSize = destSize
2667332Sgblack@eecs.umich.edu            if self.srcSize is None:
2677332Sgblack@eecs.umich.edu                raise Exception, "Source size not set."
2687332Sgblack@eecs.umich.edu            if self.destSize is None:
2697332Sgblack@eecs.umich.edu                raise Exception, "Dest size not set."
2707332Sgblack@eecs.umich.edu            if ext is None:
27112236Sgabeblack@google.com                self.ext = 0
2727332Sgblack@eecs.umich.edu            else:
2737332Sgblack@eecs.umich.edu                self.ext = ext 
2747332Sgblack@eecs.umich.edu
2757332Sgblack@eecs.umich.edu        def getAllocator(self, *microFlags):
27610184SCurtis.Dunham@arm.com            className = self.className
2777332Sgblack@eecs.umich.edu            if self.mnemonic == self.base_mnemonic + 'i':
2787332Sgblack@eecs.umich.edu                className += "Imm"
2797332Sgblack@eecs.umich.edu            allocator = '''new %(class_name)s(machInst, macrocodeBlock
2807332Sgblack@eecs.umich.edu                    %(flags)s, %(src1)s, %(op2)s, %(dest)s,
2817848SAli.Saidi@ARM.com                    %(srcSize)s, %(destSize)s, %(ext)s)''' % {
2827848SAli.Saidi@ARM.com                "class_name" : className,
2837848SAli.Saidi@ARM.com                "flags" : self.microFlagsText(microFlags),
2847848SAli.Saidi@ARM.com                "src1" : self.src1, "op2" : self.op2,
2857848SAli.Saidi@ARM.com                "dest" : self.dest,
2867332Sgblack@eecs.umich.edu                "srcSize" : self.srcSize,
2877332Sgblack@eecs.umich.edu                "destSize" : self.destSize,
2887332Sgblack@eecs.umich.edu                "ext" : self.ext}
2897261Sgblack@eecs.umich.edu            return allocator
2907208Sgblack@eecs.umich.edu
2917208Sgblack@eecs.umich.edu    class Mov2int(MediaOp):
2927208Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2 = 0, \
2937208Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
2947208Sgblack@eecs.umich.edu            super(Mov2int, self).__init__(dest, src1,\
2957208Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
2967208Sgblack@eecs.umich.edu        code = '''
29712236Sgabeblack@google.com            int items = sizeof(FloatRegBits) / srcSize;
2987208Sgblack@eecs.umich.edu            int offset = imm8;
2997208Sgblack@eecs.umich.edu            if (bits(src1, 0) && (ext & 0x1))
3007208Sgblack@eecs.umich.edu                offset -= items;
3017261Sgblack@eecs.umich.edu            if (offset >= 0 && offset < items) {
30210184SCurtis.Dunham@arm.com                uint64_t fpSrcReg1 =
3037208Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw,
3047208Sgblack@eecs.umich.edu                            (offset + 1) * srcSize * 8 - 1,
3057208Sgblack@eecs.umich.edu                            (offset + 0) * srcSize * 8);
3067208Sgblack@eecs.umich.edu                DestReg = merge(0, fpSrcReg1, destSize);
3077848SAli.Saidi@ARM.com            } else {
3087848SAli.Saidi@ARM.com                DestReg = DestReg;
3097848SAli.Saidi@ARM.com            }
3107848SAli.Saidi@ARM.com        '''
3117848SAli.Saidi@ARM.com
3127208Sgblack@eecs.umich.edu    class Mov2fp(MediaOp):
3137208Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2 = 0, \
3147225Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
3157233Sgblack@eecs.umich.edu            super(Mov2fp, self).__init__(dest, src1,\
3167233Sgblack@eecs.umich.edu                    src2, size, destSize, srcSize, ext)
3177233Sgblack@eecs.umich.edu        code = '''
3187233Sgblack@eecs.umich.edu            int items = sizeof(FloatRegBits) / destSize;
3197233Sgblack@eecs.umich.edu            int offset = imm8;
3207233Sgblack@eecs.umich.edu            if (bits(dest, 0) && (ext & 0x1))
3217233Sgblack@eecs.umich.edu                offset -= items;
3227233Sgblack@eecs.umich.edu            if (offset >= 0 && offset < items) {
3237330Sgblack@eecs.umich.edu                uint64_t srcReg1 = pick(SrcReg1, 0, srcSize);
32412236Sgabeblack@google.com                FpDestReg.uqw =
3257233Sgblack@eecs.umich.edu                    insertBits(FpDestReg.uqw,
3267233Sgblack@eecs.umich.edu                            (offset + 1) * destSize * 8 - 1,
3277233Sgblack@eecs.umich.edu                            (offset + 0) * destSize * 8, srcReg1);
3287233Sgblack@eecs.umich.edu            } else {
32910184SCurtis.Dunham@arm.com                FpDestReg.uqw = FpDestReg.uqw;
3307233Sgblack@eecs.umich.edu            }
3317233Sgblack@eecs.umich.edu        '''
3327233Sgblack@eecs.umich.edu
3337330Sgblack@eecs.umich.edu    class Movsign(MediaOp):
3347233Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
3357233Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, ext = None):
3367233Sgblack@eecs.umich.edu            super(Movsign, self).__init__(dest, src,\
3377233Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, ext)
3387848SAli.Saidi@ARM.com        code = '''
3397848SAli.Saidi@ARM.com            int items = sizeof(FloatRegBits) / srcSize;
3407848SAli.Saidi@ARM.com            uint64_t result = 0;
3417848SAli.Saidi@ARM.com            int offset = (ext & 0x1) ? items : 0;
3427848SAli.Saidi@ARM.com            for (int i = 0; i < items; i++) {
3437233Sgblack@eecs.umich.edu                uint64_t picked =
3447233Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + 1) * 8 * srcSize - 1);
3457233Sgblack@eecs.umich.edu                result = insertBits(result, i + offset, i + offset, picked);
3467241Sgblack@eecs.umich.edu            }
3477241Sgblack@eecs.umich.edu            DestReg = DestReg | result;
3487241Sgblack@eecs.umich.edu        '''
3497241Sgblack@eecs.umich.edu
3507241Sgblack@eecs.umich.edu    class Maskmov(MediaOp):
3517241Sgblack@eecs.umich.edu        code = '''
3527241Sgblack@eecs.umich.edu            assert(srcSize == destSize);
3537241Sgblack@eecs.umich.edu            int size = srcSize;
3547241Sgblack@eecs.umich.edu            int sizeBits = size * 8;
35512236Sgabeblack@google.com            int items = numItems(size);
3567241Sgblack@eecs.umich.edu            uint64_t result = FpDestReg.uqw;
3577241Sgblack@eecs.umich.edu
3587241Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3597241Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
36010184SCurtis.Dunham@arm.com                int loIndex = (i + 0) * sizeBits;
3617241Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
3627241Sgblack@eecs.umich.edu                if (bits(FpSrcReg2.uqw, hiIndex))
3637241Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
3647241Sgblack@eecs.umich.edu            }
3657241Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
3667241Sgblack@eecs.umich.edu        '''
3677241Sgblack@eecs.umich.edu
3687241Sgblack@eecs.umich.edu    class shuffle(MediaOp):
3697848SAli.Saidi@ARM.com        code = '''
3707848SAli.Saidi@ARM.com            assert(srcSize == destSize);
3717848SAli.Saidi@ARM.com            int size = srcSize;
3727848SAli.Saidi@ARM.com            int sizeBits = size * 8;
3737848SAli.Saidi@ARM.com            int items = sizeof(FloatRegBits) / size;
3747241Sgblack@eecs.umich.edu            int options;
3757241Sgblack@eecs.umich.edu            int optionBits;
3767241Sgblack@eecs.umich.edu            if (size == 8) {
3777238Sgblack@eecs.umich.edu                options = 2;
3787238Sgblack@eecs.umich.edu                optionBits = 1;
3797238Sgblack@eecs.umich.edu            } else {
3807238Sgblack@eecs.umich.edu                options = 4;
3817238Sgblack@eecs.umich.edu                optionBits = 2;
3827238Sgblack@eecs.umich.edu            }
3837238Sgblack@eecs.umich.edu
3847238Sgblack@eecs.umich.edu            uint64_t result = 0;
38512236Sgabeblack@google.com            uint8_t sel = ext;
3867238Sgblack@eecs.umich.edu
3877238Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
3887238Sgblack@eecs.umich.edu                uint64_t resBits;
3897238Sgblack@eecs.umich.edu                uint8_t lsel = sel & mask(optionBits);
39010184SCurtis.Dunham@arm.com                if (lsel * size >= sizeof(FloatRegBits)) {
3917238Sgblack@eecs.umich.edu                    lsel -= options / 2;
3927238Sgblack@eecs.umich.edu                    resBits = bits(FpSrcReg2.uqw,
3937238Sgblack@eecs.umich.edu                            (lsel + 1) * sizeBits - 1,
3947238Sgblack@eecs.umich.edu                            (lsel + 0) * sizeBits);
3957238Sgblack@eecs.umich.edu                }  else {
3967238Sgblack@eecs.umich.edu                    resBits = bits(FpSrcReg1.uqw,
3977238Sgblack@eecs.umich.edu                            (lsel + 1) * sizeBits - 1,
3987848SAli.Saidi@ARM.com                            (lsel + 0) * sizeBits);
3997848SAli.Saidi@ARM.com                }
4007848SAli.Saidi@ARM.com
4017848SAli.Saidi@ARM.com                sel >>= optionBits;
4027848SAli.Saidi@ARM.com
4037238Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
4047238Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
4057238Sgblack@eecs.umich.edu                result = insertBits(result, hiIndex, loIndex, resBits);
4067331Sgblack@eecs.umich.edu            }
4077331Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
4087331Sgblack@eecs.umich.edu        '''
4097331Sgblack@eecs.umich.edu
4107331Sgblack@eecs.umich.edu    class Unpack(MediaOp):
4117331Sgblack@eecs.umich.edu        code = '''
4127331Sgblack@eecs.umich.edu            assert(srcSize == destSize);
4137331Sgblack@eecs.umich.edu            int size = destSize;
4147331Sgblack@eecs.umich.edu            int items = (sizeof(FloatRegBits) / size) / 2;
41512236Sgabeblack@google.com            int offset = ext ? items : 0;
4167331Sgblack@eecs.umich.edu            uint64_t result = 0;
4177331Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
4187331Sgblack@eecs.umich.edu                uint64_t pickedLow =
4197331Sgblack@eecs.umich.edu                    bits(FpSrcReg1.uqw, (i + offset + 1) * 8 * size - 1,
42010184SCurtis.Dunham@arm.com                                        (i + offset) * 8 * size);
4217331Sgblack@eecs.umich.edu                result = insertBits(result,
4227331Sgblack@eecs.umich.edu                                    (2 * i + 1) * 8 * size - 1,
4237331Sgblack@eecs.umich.edu                                    (2 * i + 0) * 8 * size,
4247331Sgblack@eecs.umich.edu                                    pickedLow);
4257331Sgblack@eecs.umich.edu                uint64_t pickedHigh =
4267331Sgblack@eecs.umich.edu                    bits(FpSrcReg2.uqw, (i + offset + 1) * 8 * size - 1,
4277331Sgblack@eecs.umich.edu                                        (i + offset) * 8 * size);
4287848SAli.Saidi@ARM.com                result = insertBits(result,
4297848SAli.Saidi@ARM.com                                    (2 * i + 2) * 8 * size - 1,
4307848SAli.Saidi@ARM.com                                    (2 * i + 1) * 8 * size,
4317848SAli.Saidi@ARM.com                                    pickedHigh);
4327848SAli.Saidi@ARM.com            }
4337331Sgblack@eecs.umich.edu            FpDestReg.uqw = result;
4347331Sgblack@eecs.umich.edu        '''
4357331Sgblack@eecs.umich.edu
43610418Sandreas.hansson@arm.com    class Pack(MediaOp):
43710418Sandreas.hansson@arm.com        code = '''
43810418Sandreas.hansson@arm.com            assert(srcSize == destSize * 2);
43910418Sandreas.hansson@arm.com            int items = (sizeof(FloatRegBits) / destSize);
44010418Sandreas.hansson@arm.com            int destBits = destSize * 8;
44110418Sandreas.hansson@arm.com            int srcBits = srcSize * 8;
44210418Sandreas.hansson@arm.com            uint64_t result = 0;
44310418Sandreas.hansson@arm.com            int i;
44410418Sandreas.hansson@arm.com            for (i = 0; i < items / 2; i++) {
44512236Sgabeblack@google.com                uint64_t picked =
44610418Sandreas.hansson@arm.com                    bits(FpSrcReg1.uqw, (i + 1) * srcBits - 1,
44710418Sandreas.hansson@arm.com                                        (i + 0) * srcBits);
44810418Sandreas.hansson@arm.com                unsigned signBit = bits(picked, srcBits - 1);
44910418Sandreas.hansson@arm.com                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
45010418Sandreas.hansson@arm.com
45110418Sandreas.hansson@arm.com                // Handle saturation.
45210418Sandreas.hansson@arm.com                if (signBit) {
45310418Sandreas.hansson@arm.com                    if (overflow != mask(destBits - srcBits + 1)) {
45410418Sandreas.hansson@arm.com                        if (ext & 0x1)
45510418Sandreas.hansson@arm.com                            picked = (ULL(1) << (destBits - 1));
45610418Sandreas.hansson@arm.com                        else
45710418Sandreas.hansson@arm.com                            picked = 0;
45810418Sandreas.hansson@arm.com                    }
45910418Sandreas.hansson@arm.com                } else {
46010418Sandreas.hansson@arm.com                    if (overflow != 0) {
46110418Sandreas.hansson@arm.com                        if (ext & 0x1)
46210418Sandreas.hansson@arm.com                            picked = mask(destBits - 1);
46310418Sandreas.hansson@arm.com                        else
46410418Sandreas.hansson@arm.com                            picked = mask(destBits);
46510418Sandreas.hansson@arm.com                    }
46610418Sandreas.hansson@arm.com                }
46710418Sandreas.hansson@arm.com                result = insertBits(result,
46810418Sandreas.hansson@arm.com                                    (i + 1) * destBits - 1,
46910418Sandreas.hansson@arm.com                                    (i + 0) * destBits,
47010418Sandreas.hansson@arm.com                                    picked);
47110418Sandreas.hansson@arm.com            }
47210418Sandreas.hansson@arm.com            for (;i < items; i++) {
47310418Sandreas.hansson@arm.com                uint64_t picked =
47410418Sandreas.hansson@arm.com                    bits(FpSrcReg2.uqw, (i - items + 1) * srcBits - 1,
47512236Sgabeblack@google.com                                        (i - items + 0) * srcBits);
47610418Sandreas.hansson@arm.com                unsigned signBit = bits(picked, srcBits - 1);
47710418Sandreas.hansson@arm.com                uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
47810418Sandreas.hansson@arm.com
47910418Sandreas.hansson@arm.com                // Handle saturation.
48010418Sandreas.hansson@arm.com                if (signBit) {
48110418Sandreas.hansson@arm.com                    if (overflow != mask(destBits - srcBits + 1)) {
48210418Sandreas.hansson@arm.com                        if (ext & 0x1)
48310418Sandreas.hansson@arm.com                            picked = (ULL(1) << (destBits - 1));
48410418Sandreas.hansson@arm.com                        else
48510418Sandreas.hansson@arm.com                            picked = 0;
48610418Sandreas.hansson@arm.com                    }
48710418Sandreas.hansson@arm.com                } else {
48810418Sandreas.hansson@arm.com                    if (overflow != 0) {
48910418Sandreas.hansson@arm.com                        if (ext & 0x1)
49010418Sandreas.hansson@arm.com                            picked = mask(destBits - 1);
49110418Sandreas.hansson@arm.com                        else
49210418Sandreas.hansson@arm.com                            picked = mask(destBits);
49310418Sandreas.hansson@arm.com                    }
49410418Sandreas.hansson@arm.com                }
49510418Sandreas.hansson@arm.com                result = insertBits(result,
49610037SARM gem5 Developers                                    (i + 1) * destBits - 1,
49710037SARM gem5 Developers                                    (i + 0) * destBits,
49810037SARM gem5 Developers                                    picked);
49910037SARM gem5 Developers            }
50010037SARM gem5 Developers            FpDestReg.uqw = result;
50110037SARM gem5 Developers        '''
50210037SARM gem5 Developers
50310037SARM gem5 Developers    class Mxor(MediaOp):
50412236Sgabeblack@google.com        def __init__(self, dest, src1, src2):
50510037SARM gem5 Developers            super(Mxor, self).__init__(dest, src1, src2, 1)
50610037SARM gem5 Developers        code = '''
50710037SARM gem5 Developers            FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw;
50810037SARM gem5 Developers        '''
50910184SCurtis.Dunham@arm.com
51010037SARM gem5 Developers    class Mor(MediaOp):
51110037SARM gem5 Developers        def __init__(self, dest, src1, src2):
51210037SARM gem5 Developers            super(Mor, self).__init__(dest, src1, src2, 1)
51310037SARM gem5 Developers        code = '''
51410037SARM gem5 Developers            FpDestReg.uqw = FpSrcReg1.uqw | FpSrcReg2.uqw;
51510037SARM gem5 Developers        '''
51610037SARM gem5 Developers
51710037SARM gem5 Developers    class Mand(MediaOp):
51810037SARM gem5 Developers        def __init__(self, dest, src1, src2):
51910037SARM gem5 Developers            super(Mand, self).__init__(dest, src1, src2, 1)
52010037SARM gem5 Developers        code = '''
52110037SARM gem5 Developers            FpDestReg.uqw = FpSrcReg1.uqw & FpSrcReg2.uqw;
52210037SARM gem5 Developers        '''
52310037SARM gem5 Developers
52410037SARM gem5 Developers    class Mandn(MediaOp):
5257253Sgblack@eecs.umich.edu        def __init__(self, dest, src1, src2):
5267253Sgblack@eecs.umich.edu            super(Mandn, self).__init__(dest, src1, src2, 1)
5277253Sgblack@eecs.umich.edu        code = '''
5287253Sgblack@eecs.umich.edu            FpDestReg.uqw = ~FpSrcReg1.uqw & FpSrcReg2.uqw;
5297253Sgblack@eecs.umich.edu        '''
5307253Sgblack@eecs.umich.edu
5317253Sgblack@eecs.umich.edu    class Mminf(MediaOp):
5327253Sgblack@eecs.umich.edu        code = '''
5337330Sgblack@eecs.umich.edu            union floatInt
53412236Sgabeblack@google.com            {
5357253Sgblack@eecs.umich.edu                float f;
5367253Sgblack@eecs.umich.edu                uint32_t i;
5377253Sgblack@eecs.umich.edu            };
5387253Sgblack@eecs.umich.edu            union doubleInt
53910184SCurtis.Dunham@arm.com            {
5407253Sgblack@eecs.umich.edu                double d;
5417253Sgblack@eecs.umich.edu                uint64_t i;
5427330Sgblack@eecs.umich.edu            };
5437330Sgblack@eecs.umich.edu
5447253Sgblack@eecs.umich.edu            assert(srcSize == destSize);
5457253Sgblack@eecs.umich.edu            int size = srcSize;
5467253Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5477253Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
5487848SAli.Saidi@ARM.com            int items = numItems(size);
5497848SAli.Saidi@ARM.com            uint64_t result = FpDestReg.uqw;
5507848SAli.Saidi@ARM.com
5517848SAli.Saidi@ARM.com            for (int i = 0; i < items; i++) {
5527848SAli.Saidi@ARM.com                double arg1, arg2;
5537253Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
5547253Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
5557253Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
5567232Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
5577225Sgblack@eecs.umich.edu
5587225Sgblack@eecs.umich.edu                if (size == 4) {
5597225Sgblack@eecs.umich.edu                    floatInt fi;
5607225Sgblack@eecs.umich.edu                    fi.i = arg1Bits;
5617225Sgblack@eecs.umich.edu                    arg1 = fi.f;
5627225Sgblack@eecs.umich.edu                    fi.i = arg2Bits;
5637330Sgblack@eecs.umich.edu                    arg2 = fi.f;
56412236Sgabeblack@google.com                } else {
5657225Sgblack@eecs.umich.edu                    doubleInt di;
5667225Sgblack@eecs.umich.edu                    di.i = arg1Bits;
5677225Sgblack@eecs.umich.edu                    arg1 = di.d;
5687232Sgblack@eecs.umich.edu                    di.i = arg2Bits;
56910184SCurtis.Dunham@arm.com                    arg2 = di.d;
5707225Sgblack@eecs.umich.edu                }
5717330Sgblack@eecs.umich.edu
5727225Sgblack@eecs.umich.edu                if (arg1 < arg2) {
5737225Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
5747232Sgblack@eecs.umich.edu                } else {
5757225Sgblack@eecs.umich.edu                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
5767225Sgblack@eecs.umich.edu                }
5777848SAli.Saidi@ARM.com            }
5787848SAli.Saidi@ARM.com            FpDestReg.uqw = result;
5797848SAli.Saidi@ARM.com        '''
5807848SAli.Saidi@ARM.com
5817848SAli.Saidi@ARM.com    class Mmaxf(MediaOp):
5827225Sgblack@eecs.umich.edu        code = '''
5837225Sgblack@eecs.umich.edu            union floatInt
5847225Sgblack@eecs.umich.edu            {
5857232Sgblack@eecs.umich.edu                float f;
5867225Sgblack@eecs.umich.edu                uint32_t i;
5877225Sgblack@eecs.umich.edu            };
5887225Sgblack@eecs.umich.edu            union doubleInt
5897225Sgblack@eecs.umich.edu            {
5907225Sgblack@eecs.umich.edu                double d;
5917225Sgblack@eecs.umich.edu                uint64_t i;
5927330Sgblack@eecs.umich.edu            };
5937225Sgblack@eecs.umich.edu
59412236Sgabeblack@google.com            assert(srcSize == destSize);
5957225Sgblack@eecs.umich.edu            int size = srcSize;
5967225Sgblack@eecs.umich.edu            int sizeBits = size * 8;
5977225Sgblack@eecs.umich.edu            assert(srcSize == 4 || srcSize == 8);
5987232Sgblack@eecs.umich.edu            int items = numItems(size);
59910184SCurtis.Dunham@arm.com            uint64_t result = FpDestReg.uqw;
6007225Sgblack@eecs.umich.edu
6017330Sgblack@eecs.umich.edu            for (int i = 0; i < items; i++) {
6027225Sgblack@eecs.umich.edu                double arg1, arg2;
6037225Sgblack@eecs.umich.edu                int hiIndex = (i + 1) * sizeBits - 1;
6047225Sgblack@eecs.umich.edu                int loIndex = (i + 0) * sizeBits;
6057225Sgblack@eecs.umich.edu                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
6067232Sgblack@eecs.umich.edu                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
6077225Sgblack@eecs.umich.edu
6087225Sgblack@eecs.umich.edu                if (size == 4) {
6097848SAli.Saidi@ARM.com                    floatInt fi;
6107848SAli.Saidi@ARM.com                    fi.i = arg1Bits;
6117848SAli.Saidi@ARM.com                    arg1 = fi.f;
6127848SAli.Saidi@ARM.com                    fi.i = arg2Bits;
6137848SAli.Saidi@ARM.com                    arg2 = fi.f;
6147225Sgblack@eecs.umich.edu                } else {
6157225Sgblack@eecs.umich.edu                    doubleInt di;
6167609SGene.Wu@arm.com                    di.i = arg1Bits;
61712358Snikos.nikoleris@arm.com                    arg1 = di.d;
61812358Snikos.nikoleris@arm.com                    di.i = arg2Bits;
61912358Snikos.nikoleris@arm.com                    arg2 = di.d;
62012358Snikos.nikoleris@arm.com                }
62112358Snikos.nikoleris@arm.com
62212358Snikos.nikoleris@arm.com                if (arg1 > arg2) {
62312358Snikos.nikoleris@arm.com                    result = insertBits(result, hiIndex, loIndex, arg1Bits);
62412358Snikos.nikoleris@arm.com                } else {
62512358Snikos.nikoleris@arm.com                    result = insertBits(result, hiIndex, loIndex, arg2Bits);
62612358Snikos.nikoleris@arm.com                }
62712358Snikos.nikoleris@arm.com            }
62812358Snikos.nikoleris@arm.com            FpDestReg.uqw = result;
62912358Snikos.nikoleris@arm.com        '''
63012358Snikos.nikoleris@arm.com
63112358Snikos.nikoleris@arm.com    class Mmini(MediaOp):
63212358Snikos.nikoleris@arm.com        code = '''
63312358Snikos.nikoleris@arm.com
63412358Snikos.nikoleris@arm.com            assert(srcSize == destSize);
63512358Snikos.nikoleris@arm.com            int size = srcSize;
63612358Snikos.nikoleris@arm.com            int sizeBits = size * 8;
63712358Snikos.nikoleris@arm.com            int items = numItems(size);
63812358Snikos.nikoleris@arm.com            uint64_t result = FpDestReg.uqw;
63912358Snikos.nikoleris@arm.com
64012358Snikos.nikoleris@arm.com            for (int i = 0; i < items; i++) {
64112358Snikos.nikoleris@arm.com                int hiIndex = (i + 1) * sizeBits - 1;
64212358Snikos.nikoleris@arm.com                int loIndex = (i + 0) * sizeBits;
64312358Snikos.nikoleris@arm.com                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
64412358Snikos.nikoleris@arm.com                int64_t arg1 = arg1Bits |
64512358Snikos.nikoleris@arm.com                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
64612358Snikos.nikoleris@arm.com                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
64712358Snikos.nikoleris@arm.com                int64_t arg2 = arg2Bits |
64812358Snikos.nikoleris@arm.com                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
64912503Snikos.nikoleris@arm.com                uint64_t resBits;
65012503Snikos.nikoleris@arm.com
65112503Snikos.nikoleris@arm.com                if (ext & 0x2) {
65212358Snikos.nikoleris@arm.com                    if (arg1 < arg2) {
65312358Snikos.nikoleris@arm.com                        resBits = arg1Bits;
65412358Snikos.nikoleris@arm.com                    } else {
65512358Snikos.nikoleris@arm.com                        resBits = arg2Bits;
65612358Snikos.nikoleris@arm.com                    }
65712358Snikos.nikoleris@arm.com                } else {
65812358Snikos.nikoleris@arm.com                    if (arg1Bits < arg2Bits) {
65912358Snikos.nikoleris@arm.com                        resBits = arg1Bits;
66012358Snikos.nikoleris@arm.com                    } else {
66112358Snikos.nikoleris@arm.com                        resBits = arg2Bits;
66212358Snikos.nikoleris@arm.com                    }
66312358Snikos.nikoleris@arm.com                }
66412358Snikos.nikoleris@arm.com                result = insertBits(result, hiIndex, loIndex, resBits);
66512358Snikos.nikoleris@arm.com            }
66612358Snikos.nikoleris@arm.com            FpDestReg.uqw = result;
66712358Snikos.nikoleris@arm.com        '''
66812358Snikos.nikoleris@arm.com
66912358Snikos.nikoleris@arm.com    class Mmaxi(MediaOp):
67012358Snikos.nikoleris@arm.com        code = '''
67112358Snikos.nikoleris@arm.com
67212358Snikos.nikoleris@arm.com            assert(srcSize == destSize);
67312358Snikos.nikoleris@arm.com            int size = srcSize;
67412358Snikos.nikoleris@arm.com            int sizeBits = size * 8;
67512358Snikos.nikoleris@arm.com            int items = numItems(size);
67612358Snikos.nikoleris@arm.com            uint64_t result = FpDestReg.uqw;
67712358Snikos.nikoleris@arm.com
67812503Snikos.nikoleris@arm.com            for (int i = 0; i < items; i++) {
67912503Snikos.nikoleris@arm.com                int hiIndex = (i + 1) * sizeBits - 1;
68012503Snikos.nikoleris@arm.com                int loIndex = (i + 0) * sizeBits;
68112358Snikos.nikoleris@arm.com                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
68212358Snikos.nikoleris@arm.com                int64_t arg1 = arg1Bits |
68312358Snikos.nikoleris@arm.com                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
68412358Snikos.nikoleris@arm.com                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
68512358Snikos.nikoleris@arm.com                int64_t arg2 = arg2Bits |
68612358Snikos.nikoleris@arm.com                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
68712358Snikos.nikoleris@arm.com                uint64_t resBits;
68812358Snikos.nikoleris@arm.com
68912358Snikos.nikoleris@arm.com                if (ext & 0x2) {
69012358Snikos.nikoleris@arm.com                    if (arg1 > arg2) {
69112358Snikos.nikoleris@arm.com                        resBits = arg1Bits;
69212358Snikos.nikoleris@arm.com                    } else {
69312358Snikos.nikoleris@arm.com                        resBits = arg2Bits;
69412358Snikos.nikoleris@arm.com                    }
69512358Snikos.nikoleris@arm.com                } else {
69612358Snikos.nikoleris@arm.com                    if (arg1Bits > arg2Bits) {
69712358Snikos.nikoleris@arm.com                        resBits = arg1Bits;
698                    } else {
699                        resBits = arg2Bits;
700                    }
701                }
702                result = insertBits(result, hiIndex, loIndex, resBits);
703            }
704            FpDestReg.uqw = result;
705        '''
706
707    class Msqrt(MediaOp):
708        def __init__(self, dest, src, \
709                size = None, destSize = None, srcSize = None, ext = None):
710            super(Msqrt, self).__init__(dest, src,\
711                    "InstRegIndex(0)", size, destSize, srcSize, ext)
712        code = '''
713            union floatInt
714            {
715                float f;
716                uint32_t i;
717            };
718            union doubleInt
719            {
720                double d;
721                uint64_t i;
722            };
723
724            assert(srcSize == destSize);
725            int size = srcSize;
726            int sizeBits = size * 8;
727            assert(srcSize == 4 || srcSize == 8);
728            int items = numItems(size);
729            uint64_t result = FpDestReg.uqw;
730
731            for (int i = 0; i < items; i++) {
732                int hiIndex = (i + 1) * sizeBits - 1;
733                int loIndex = (i + 0) * sizeBits;
734                uint64_t argBits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
735
736                if (size == 4) {
737                    floatInt fi;
738                    fi.i = argBits;
739                    fi.f = sqrt(fi.f);
740                    argBits = fi.i;
741                } else {
742                    doubleInt di;
743                    di.i = argBits;
744                    di.d = sqrt(di.d);
745                    argBits = di.i;
746                }
747                result = insertBits(result, hiIndex, loIndex, argBits);
748            }
749            FpDestReg.uqw = result;
750        '''
751
752    class Maddf(MediaOp):
753        code = '''
754            union floatInt
755            {
756                float f;
757                uint32_t i;
758            };
759            union doubleInt
760            {
761                double d;
762                uint64_t i;
763            };
764
765            assert(srcSize == destSize);
766            int size = srcSize;
767            int sizeBits = size * 8;
768            assert(srcSize == 4 || srcSize == 8);
769            int items = numItems(size);
770            uint64_t result = FpDestReg.uqw;
771
772            for (int i = 0; i < items; i++) {
773                int hiIndex = (i + 1) * sizeBits - 1;
774                int loIndex = (i + 0) * sizeBits;
775                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
776                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
777                uint64_t resBits;
778
779                if (size == 4) {
780                    floatInt arg1, arg2, res;
781                    arg1.i = arg1Bits;
782                    arg2.i = arg2Bits;
783                    res.f = arg1.f + arg2.f;
784                    resBits = res.i;
785                } else {
786                    doubleInt arg1, arg2, res;
787                    arg1.i = arg1Bits;
788                    arg2.i = arg2Bits;
789                    res.d = arg1.d + arg2.d;
790                    resBits = res.i;
791                }
792
793                result = insertBits(result, hiIndex, loIndex, resBits);
794            }
795            FpDestReg.uqw = result;
796        '''
797
798    class Msubf(MediaOp):
799        code = '''
800            union floatInt
801            {
802                float f;
803                uint32_t i;
804            };
805            union doubleInt
806            {
807                double d;
808                uint64_t i;
809            };
810
811            assert(srcSize == destSize);
812            int size = srcSize;
813            int sizeBits = size * 8;
814            assert(srcSize == 4 || srcSize == 8);
815            int items = numItems(size);
816            uint64_t result = FpDestReg.uqw;
817
818            for (int i = 0; i < items; i++) {
819                int hiIndex = (i + 1) * sizeBits - 1;
820                int loIndex = (i + 0) * sizeBits;
821                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
822                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
823                uint64_t resBits;
824
825                if (size == 4) {
826                    floatInt arg1, arg2, res;
827                    arg1.i = arg1Bits;
828                    arg2.i = arg2Bits;
829                    res.f = arg1.f - arg2.f;
830                    resBits = res.i;
831                } else {
832                    doubleInt arg1, arg2, res;
833                    arg1.i = arg1Bits;
834                    arg2.i = arg2Bits;
835                    res.d = arg1.d - arg2.d;
836                    resBits = res.i;
837                }
838
839                result = insertBits(result, hiIndex, loIndex, resBits);
840            }
841            FpDestReg.uqw = result;
842        '''
843
844    class Mmulf(MediaOp):
845        code = '''
846            union floatInt
847            {
848                float f;
849                uint32_t i;
850            };
851            union doubleInt
852            {
853                double d;
854                uint64_t i;
855            };
856
857            assert(srcSize == destSize);
858            int size = srcSize;
859            int sizeBits = size * 8;
860            assert(srcSize == 4 || srcSize == 8);
861            int items = numItems(size);
862            uint64_t result = FpDestReg.uqw;
863
864            for (int i = 0; i < items; i++) {
865                int hiIndex = (i + 1) * sizeBits - 1;
866                int loIndex = (i + 0) * sizeBits;
867                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
868                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
869                uint64_t resBits;
870
871                if (size == 4) {
872                    floatInt arg1, arg2, res;
873                    arg1.i = arg1Bits;
874                    arg2.i = arg2Bits;
875                    res.f = arg1.f * arg2.f;
876                    resBits = res.i;
877                } else {
878                    doubleInt arg1, arg2, res;
879                    arg1.i = arg1Bits;
880                    arg2.i = arg2Bits;
881                    res.d = arg1.d * arg2.d;
882                    resBits = res.i;
883                }
884
885                result = insertBits(result, hiIndex, loIndex, resBits);
886            }
887            FpDestReg.uqw = result;
888        '''
889
890    class Mdivf(MediaOp):
891        code = '''
892            union floatInt
893            {
894                float f;
895                uint32_t i;
896            };
897            union doubleInt
898            {
899                double d;
900                uint64_t i;
901            };
902
903            assert(srcSize == destSize);
904            int size = srcSize;
905            int sizeBits = size * 8;
906            assert(srcSize == 4 || srcSize == 8);
907            int items = numItems(size);
908            uint64_t result = FpDestReg.uqw;
909
910            for (int i = 0; i < items; i++) {
911                int hiIndex = (i + 1) * sizeBits - 1;
912                int loIndex = (i + 0) * sizeBits;
913                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
914                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
915                uint64_t resBits;
916
917                if (size == 4) {
918                    floatInt arg1, arg2, res;
919                    arg1.i = arg1Bits;
920                    arg2.i = arg2Bits;
921                    res.f = arg1.f / arg2.f;
922                    resBits = res.i;
923                } else {
924                    doubleInt arg1, arg2, res;
925                    arg1.i = arg1Bits;
926                    arg2.i = arg2Bits;
927                    res.d = arg1.d / arg2.d;
928                    resBits = res.i;
929                }
930
931                result = insertBits(result, hiIndex, loIndex, resBits);
932            }
933            FpDestReg.uqw = result;
934        '''
935
936    class Maddi(MediaOp):
937        code = '''
938            assert(srcSize == destSize);
939            int size = srcSize;
940            int sizeBits = size * 8;
941            int items = numItems(size);
942            uint64_t result = FpDestReg.uqw;
943
944            for (int i = 0; i < items; i++) {
945                int hiIndex = (i + 1) * sizeBits - 1;
946                int loIndex = (i + 0) * sizeBits;
947                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
948                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
949                uint64_t resBits = arg1Bits + arg2Bits;
950                
951                if (ext & 0x2) {
952                    if (findCarry(sizeBits, resBits, arg1Bits, arg2Bits))
953                        resBits = mask(sizeBits);
954                } else if (ext & 0x4) {
955                    int arg1Sign = bits(arg1Bits, sizeBits - 1);
956                    int arg2Sign = bits(arg2Bits, sizeBits - 1);
957                    int resSign = bits(resBits, sizeBits - 1);
958                    if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
959                        if (resSign == 0)
960                            resBits = (ULL(1) << (sizeBits - 1));
961                        else
962                            resBits = mask(sizeBits - 1);
963                    }
964                }
965
966                result = insertBits(result, hiIndex, loIndex, resBits);
967            }
968            FpDestReg.uqw = result;
969        '''
970
971    class Msubi(MediaOp):
972        code = '''
973            assert(srcSize == destSize);
974            int size = srcSize;
975            int sizeBits = size * 8;
976            int items = numItems(size);
977            uint64_t result = FpDestReg.uqw;
978
979            for (int i = 0; i < items; i++) {
980                int hiIndex = (i + 1) * sizeBits - 1;
981                int loIndex = (i + 0) * sizeBits;
982                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
983                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
984                uint64_t resBits = arg1Bits - arg2Bits;
985                
986                if (ext & 0x2) {
987                    if (arg2Bits > arg1Bits) {
988                        resBits = 0;
989                    } else if (!findCarry(sizeBits, resBits,
990                                         arg1Bits, ~arg2Bits)) {
991                        resBits = mask(sizeBits);
992                    }
993                } else if (ext & 0x4) {
994                    int arg1Sign = bits(arg1Bits, sizeBits - 1);
995                    int arg2Sign = !bits(arg2Bits, sizeBits - 1);
996                    int resSign = bits(resBits, sizeBits - 1);
997                    if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
998                        if (resSign == 0)
999                            resBits = (ULL(1) << (sizeBits - 1));
1000                        else
1001                            resBits = mask(sizeBits - 1);
1002                    }
1003                }
1004
1005                result = insertBits(result, hiIndex, loIndex, resBits);
1006            }
1007            FpDestReg.uqw = result;
1008        '''
1009
1010    class Mmuli(MediaOp):
1011        code = '''
1012            int srcBits = srcSize * 8;
1013            int destBits = destSize * 8;
1014            assert(destBits <= 64);
1015            assert(destSize >= srcSize);
1016            int items = numItems(destSize);
1017            uint64_t result = FpDestReg.uqw;
1018
1019            for (int i = 0; i < items; i++) {
1020                int offset = 0;
1021                if (ext & 16) {
1022                    if (ext & 32)
1023                        offset = i * (destBits - srcBits);
1024                    else
1025                        offset = i * (destBits - srcBits) + srcBits;
1026                }
1027                int srcHiIndex = (i + 1) * srcBits - 1 + offset;
1028                int srcLoIndex = (i + 0) * srcBits + offset;
1029                uint64_t arg1Bits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
1030                uint64_t arg2Bits = bits(FpSrcReg2.uqw, srcHiIndex, srcLoIndex);
1031                uint64_t resBits;
1032
1033                if (ext & 0x2) {
1034                    int64_t arg1 = arg1Bits |
1035                        (0 - (arg1Bits & (ULL(1) << (srcBits - 1))));
1036                    int64_t arg2 = arg2Bits |
1037                        (0 - (arg2Bits & (ULL(1) << (srcBits - 1))));
1038                    resBits = (uint64_t)(arg1 * arg2);
1039                } else {
1040                    resBits = arg1Bits * arg2Bits;
1041                }
1042
1043                if (ext & 0x4)
1044                    resBits += (ULL(1) << (destBits - 1));
1045                
1046                if (ext & 0x8)
1047                    resBits >>= destBits;
1048
1049                int destHiIndex = (i + 1) * destBits - 1;
1050                int destLoIndex = (i + 0) * destBits;
1051                result = insertBits(result, destHiIndex, destLoIndex, resBits);
1052            }
1053            FpDestReg.uqw = result;
1054        '''
1055
1056    class Mavg(MediaOp):
1057        code = '''
1058            assert(srcSize == destSize);
1059            int size = srcSize;
1060            int sizeBits = size * 8;
1061            int items = numItems(size);
1062            uint64_t result = FpDestReg.uqw;
1063
1064            for (int i = 0; i < items; i++) {
1065                int hiIndex = (i + 1) * sizeBits - 1;
1066                int loIndex = (i + 0) * sizeBits;
1067                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
1068                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
1069                uint64_t resBits = (arg1Bits + arg2Bits + 1) / 2;
1070                
1071                result = insertBits(result, hiIndex, loIndex, resBits);
1072            }
1073            FpDestReg.uqw = result;
1074        '''
1075
1076    class Msad(MediaOp):
1077        code = '''
1078            int srcBits = srcSize * 8;
1079            int items = sizeof(FloatRegBits) / srcSize;
1080
1081            uint64_t sum = 0;
1082            for (int i = 0; i < items; i++) {
1083                int hiIndex = (i + 1) * srcBits - 1;
1084                int loIndex = (i + 0) * srcBits;
1085                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
1086                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
1087                int64_t resBits = arg1Bits - arg2Bits;
1088                if (resBits < 0)
1089                    resBits = -resBits;
1090                sum += resBits;
1091            }
1092            FpDestReg.uqw = sum & mask(destSize * 8);
1093        '''
1094
1095    class Msrl(MediaOp):
1096        code = '''
1097
1098            assert(srcSize == destSize);
1099            int size = srcSize;
1100            int sizeBits = size * 8;
1101            int items = numItems(size);
1102            uint64_t shiftAmt = op2.uqw;
1103            uint64_t result = FpDestReg.uqw;
1104
1105            for (int i = 0; i < items; i++) {
1106                int hiIndex = (i + 1) * sizeBits - 1;
1107                int loIndex = (i + 0) * sizeBits;
1108                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
1109                uint64_t resBits;
1110                if (shiftAmt >= sizeBits) {
1111                    resBits = 0;
1112                } else {
1113                    resBits = (arg1Bits >> shiftAmt) &
1114                        mask(sizeBits - shiftAmt);
1115                }
1116
1117                result = insertBits(result, hiIndex, loIndex, resBits);
1118            }
1119            FpDestReg.uqw = result;
1120        '''
1121
1122    class Msra(MediaOp):
1123        code = '''
1124
1125            assert(srcSize == destSize);
1126            int size = srcSize;
1127            int sizeBits = size * 8;
1128            int items = numItems(size);
1129            uint64_t shiftAmt = op2.uqw;
1130            uint64_t result = FpDestReg.uqw;
1131
1132            for (int i = 0; i < items; i++) {
1133                int hiIndex = (i + 1) * sizeBits - 1;
1134                int loIndex = (i + 0) * sizeBits;
1135                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
1136                uint64_t resBits;
1137                if (shiftAmt >= sizeBits) {
1138                    if (bits(arg1Bits, sizeBits - 1))
1139                        resBits = mask(sizeBits);
1140                    else
1141                        resBits = 0;
1142                } else {
1143                    resBits = (arg1Bits >> shiftAmt);
1144                    resBits = resBits |
1145                        (0 - (resBits & (ULL(1) << (sizeBits - 1 - shiftAmt))));
1146                }
1147
1148                result = insertBits(result, hiIndex, loIndex, resBits);
1149            }
1150            FpDestReg.uqw = result;
1151        '''
1152
1153    class Msll(MediaOp):
1154        code = '''
1155
1156            assert(srcSize == destSize);
1157            int size = srcSize;
1158            int sizeBits = size * 8;
1159            int items = numItems(size);
1160            uint64_t shiftAmt = op2.uqw;
1161            uint64_t result = FpDestReg.uqw;
1162
1163            for (int i = 0; i < items; i++) {
1164                int hiIndex = (i + 1) * sizeBits - 1;
1165                int loIndex = (i + 0) * sizeBits;
1166                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
1167                uint64_t resBits;
1168                if (shiftAmt >= sizeBits) {
1169                    resBits = 0;
1170                } else {
1171                    resBits = (arg1Bits << shiftAmt);
1172                }
1173
1174                result = insertBits(result, hiIndex, loIndex, resBits);
1175            }
1176            FpDestReg.uqw = result;
1177        '''
1178
1179    class Cvtf2i(MediaOp):
1180        def __init__(self, dest, src, \
1181                size = None, destSize = None, srcSize = None, ext = None):
1182            super(Cvtf2i, self).__init__(dest, src,\
1183                    "InstRegIndex(0)", size, destSize, srcSize, ext)
1184        code = '''
1185            union floatInt
1186            {
1187                float f;
1188                uint32_t i;
1189            };
1190            union doubleInt
1191            {
1192                double d;
1193                uint64_t i;
1194            };
1195
1196            assert(destSize == 4 || destSize == 8);
1197            assert(srcSize == 4 || srcSize == 8);
1198            int srcSizeBits = srcSize * 8;
1199            int destSizeBits = destSize * 8;
1200            int items;
1201            int srcStart = 0;
1202            int destStart = 0;
1203            if (srcSize == 2 * destSize) {
1204                items = numItems(srcSize);
1205                if (ext & 0x2)
1206                    destStart = destSizeBits * items;
1207            } else if (destSize == 2 * srcSize) {
1208                items = numItems(destSize);
1209                if (ext & 0x2)
1210                    srcStart = srcSizeBits * items;
1211            } else {
1212                items = numItems(destSize);
1213            }
1214            uint64_t result = FpDestReg.uqw;
1215
1216            for (int i = 0; i < items; i++) {
1217                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
1218                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
1219                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
1220                double arg;
1221
1222                if (srcSize == 4) {
1223                    floatInt fi;
1224                    fi.i = argBits;
1225                    arg = fi.f;
1226                } else {
1227                    doubleInt di;
1228                    di.i = argBits;
1229                    arg = di.d;
1230                }
1231
1232                if (ext & 0x4) {
1233                    if (arg >= 0)
1234                        arg += 0.5;
1235                    else
1236                        arg -= 0.5;
1237                }
1238
1239                if (destSize == 4) {
1240                    argBits = (uint32_t)arg;
1241                } else {
1242                    argBits = (uint64_t)arg;
1243                }
1244                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
1245                int destLoIndex = destStart + (i + 0) * destSizeBits;
1246                result = insertBits(result, destHiIndex, destLoIndex, argBits);
1247            }
1248            FpDestReg.uqw = result;
1249        '''
1250
1251    class Cvti2f(MediaOp):
1252        def __init__(self, dest, src, \
1253                size = None, destSize = None, srcSize = None, ext = None):
1254            super(Cvti2f, self).__init__(dest, src,\
1255                    "InstRegIndex(0)", size, destSize, srcSize, ext)
1256        code = '''
1257            union floatInt
1258            {
1259                float f;
1260                uint32_t i;
1261            };
1262            union doubleInt
1263            {
1264                double d;
1265                uint64_t i;
1266            };
1267
1268            assert(destSize == 4 || destSize == 8);
1269            assert(srcSize == 4 || srcSize == 8);
1270            int srcSizeBits = srcSize * 8;
1271            int destSizeBits = destSize * 8;
1272            int items;
1273            int srcStart = 0;
1274            int destStart = 0;
1275            if (srcSize == 2 * destSize) {
1276                items = numItems(srcSize);
1277                if (ext & 0x2)
1278                    destStart = destSizeBits * items;
1279            } else if (destSize == 2 * srcSize) {
1280                items = numItems(destSize);
1281                if (ext & 0x2)
1282                    srcStart = srcSizeBits * items;
1283            } else {
1284                items = numItems(destSize);
1285            }
1286            uint64_t result = FpDestReg.uqw;
1287
1288            for (int i = 0; i < items; i++) {
1289                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
1290                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
1291                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
1292
1293                int64_t sArg = argBits | (0 - (argBits & (ULL(1) << srcHiIndex)));
1294                double arg = sArg;
1295
1296                if (destSize == 4) {
1297                    floatInt fi;
1298                    fi.f = arg;
1299                    argBits = fi.i;
1300                } else {
1301                    doubleInt di;
1302                    di.d = arg;
1303                    argBits = di.i;
1304                }
1305                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
1306                int destLoIndex = destStart + (i + 0) * destSizeBits;
1307                result = insertBits(result, destHiIndex, destLoIndex, argBits);
1308            }
1309            FpDestReg.uqw = result;
1310        '''
1311
1312    class Cvtf2f(MediaOp):
1313        def __init__(self, dest, src, \
1314                size = None, destSize = None, srcSize = None, ext = None):
1315            super(Cvtf2f, self).__init__(dest, src,\
1316                    "InstRegIndex(0)", size, destSize, srcSize, ext)
1317        code = '''
1318            union floatInt
1319            {
1320                float f;
1321                uint32_t i;
1322            };
1323            union doubleInt
1324            {
1325                double d;
1326                uint64_t i;
1327            };
1328
1329            assert(destSize == 4 || destSize == 8);
1330            assert(srcSize == 4 || srcSize == 8);
1331            int srcSizeBits = srcSize * 8;
1332            int destSizeBits = destSize * 8;
1333            int items;
1334            int srcStart = 0;
1335            int destStart = 0;
1336            if (srcSize == 2 * destSize) {
1337                items = numItems(srcSize);
1338                if (ext & 0x2)
1339                    destStart = destSizeBits * items;
1340            } else if (destSize == 2 * srcSize) {
1341                items = numItems(destSize);
1342                if (ext & 0x2)
1343                    srcStart = srcSizeBits * items;
1344            } else {
1345                items = numItems(destSize);
1346            }
1347            uint64_t result = FpDestReg.uqw;
1348
1349            for (int i = 0; i < items; i++) {
1350                int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
1351                int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
1352                uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
1353                double arg;
1354
1355                if (srcSize == 4) {
1356                    floatInt fi;
1357                    fi.i = argBits;
1358                    arg = fi.f;
1359                } else {
1360                    doubleInt di;
1361                    di.i = argBits;
1362                    arg = di.d;
1363                }
1364                if (destSize == 4) {
1365                    floatInt fi;
1366                    fi.f = arg;
1367                    argBits = fi.i;
1368                } else {
1369                    doubleInt di;
1370                    di.d = arg;
1371                    argBits = di.i;
1372                }
1373                int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
1374                int destLoIndex = destStart + (i + 0) * destSizeBits;
1375                result = insertBits(result, destHiIndex, destLoIndex, argBits);
1376            }
1377            FpDestReg.uqw = result;
1378        '''
1379
1380    class Mcmpi2r(MediaOp):
1381        code = '''
1382            union floatInt
1383            {
1384                float f;
1385                uint32_t i;
1386            };
1387            union doubleInt
1388            {
1389                double d;
1390                uint64_t i;
1391            };
1392
1393            assert(srcSize == destSize);
1394            int size = srcSize;
1395            int sizeBits = size * 8;
1396            int items = numItems(size);
1397            uint64_t result = FpDestReg.uqw;
1398
1399            for (int i = 0; i < items; i++) {
1400                int hiIndex = (i + 1) * sizeBits - 1;
1401                int loIndex = (i + 0) * sizeBits;
1402                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
1403                int64_t arg1 = arg1Bits |
1404                    (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
1405                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
1406                int64_t arg2 = arg2Bits |
1407                    (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
1408
1409                uint64_t resBits = 0;
1410                if (((ext & 0x2) == 0 && arg1 == arg2) ||
1411                    ((ext & 0x2) == 0x2 && arg1 > arg2))
1412                    resBits = mask(sizeBits);
1413
1414                result = insertBits(result, hiIndex, loIndex, resBits);
1415            }
1416            FpDestReg.uqw = result;
1417        '''
1418
1419    class Mcmpf2r(MediaOp):
1420        code = '''
1421            union floatInt
1422            {
1423                float f;
1424                uint32_t i;
1425            };
1426            union doubleInt
1427            {
1428                double d;
1429                uint64_t i;
1430            };
1431
1432            assert(srcSize == destSize);
1433            int size = srcSize;
1434            int sizeBits = size * 8;
1435            int items = numItems(size);
1436            uint64_t result = FpDestReg.uqw;
1437
1438            for (int i = 0; i < items; i++) {
1439                int hiIndex = (i + 1) * sizeBits - 1;
1440                int loIndex = (i + 0) * sizeBits;
1441                uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
1442                uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
1443                double arg1, arg2;
1444
1445                if (size == 4) {
1446                    floatInt fi;
1447                    fi.i = arg1Bits;
1448                    arg1 = fi.f;
1449                    fi.i = arg2Bits;
1450                    arg2 = fi.f;
1451                } else {
1452                    doubleInt di;
1453                    di.i = arg1Bits;
1454                    arg1 = di.d;
1455                    di.i = arg2Bits;
1456                    arg2 = di.d;
1457                }
1458
1459                uint64_t resBits = 0;
1460                bool nanop = isnan(arg1) || isnan(arg2);
1461                switch (ext & mask(3)) {
1462                  case 0:
1463                    if (arg1 == arg2 && !nanop)
1464                        resBits = mask(sizeBits);
1465                    break;
1466                  case 1:
1467                    if (arg1 < arg2 && !nanop)
1468                        resBits = mask(sizeBits);
1469                    break;
1470                  case 2:
1471                    if (arg1 <= arg2 && !nanop)
1472                        resBits = mask(sizeBits);
1473                    break;
1474                  case 3:
1475                    if (nanop)
1476                        resBits = mask(sizeBits);
1477                    break;
1478                  case 4:
1479                    if (arg1 != arg2 || nanop)
1480                        resBits = mask(sizeBits);
1481                    break;
1482                  case 5:
1483                    if (!(arg1 < arg2) || nanop)
1484                        resBits = mask(sizeBits);
1485                    break;
1486                  case 6:
1487                    if (!(arg1 <= arg2) || nanop)
1488                        resBits = mask(sizeBits);
1489                    break;
1490                  case 7:
1491                    if (!nanop)
1492                        resBits = mask(sizeBits);
1493                    break;
1494                };
1495
1496                result = insertBits(result, hiIndex, loIndex, resBits);
1497            }
1498            FpDestReg.uqw = result;
1499        '''
1500
1501    class Mcmpf2rf(MediaOp):
1502        def __init__(self, src1, src2,\
1503                size = None, destSize = None, srcSize = None, ext = None):
1504            super(Mcmpf2rf, self).__init__("InstRegIndex(0)", src1,\
1505                    src2, size, destSize, srcSize, ext)
1506        code = '''
1507            union floatInt
1508            {
1509                float f;
1510                uint32_t i;
1511            };
1512            union doubleInt
1513            {
1514                double d;
1515                uint64_t i;
1516            };
1517
1518            assert(srcSize == destSize);
1519            assert(srcSize == 4 || srcSize == 8);
1520            int size = srcSize;
1521            int sizeBits = size * 8;
1522
1523            double arg1, arg2;
1524            uint64_t arg1Bits = bits(FpSrcReg1.uqw, sizeBits - 1, 0);
1525            uint64_t arg2Bits = bits(FpSrcReg2.uqw, sizeBits - 1, 0);
1526            if (size == 4) {
1527                floatInt fi;
1528                fi.i = arg1Bits;
1529                arg1 = fi.f;
1530                fi.i = arg2Bits;
1531                arg2 = fi.f;
1532            } else {
1533                doubleInt di;
1534                di.i = arg1Bits;
1535                arg1 = di.d;
1536                di.i = arg2Bits;
1537                arg2 = di.d;
1538            }
1539
1540            //               ZF PF CF
1541            // Unordered      1  1  1
1542            // Greater than   0  0  0
1543            // Less than      0  0  1
1544            // Equal          1  0  0
1545            //           OF = SF = AF = 0
1546            ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit |
1547                                        ZFBit | PFBit | CFBit);
1548            if (isnan(arg1) || isnan(arg2))
1549                ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit);
1550            else if(arg1 < arg2)
1551                ccFlagBits = ccFlagBits | CFBit;
1552            else if(arg1 == arg2)
1553                ccFlagBits = ccFlagBits | ZFBit;
1554        '''
1555}};
1556