mediaop.isa revision 6516:b5b420d15a20
16019Shines@cs.fsu.edu/// Copyright (c) 2009 The Regents of The University of Michigan
26019Shines@cs.fsu.edu// All rights reserved.
313354Sciro.santilli@arm.com//
47152Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
57152Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
67152Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
77152Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
87152Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
97152Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
107152Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
117152Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
127152Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
137152Sgblack@eecs.umich.edu// this software without specific prior written permission.
147152Sgblack@eecs.umich.edu//
156019Shines@cs.fsu.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
166019Shines@cs.fsu.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
176019Shines@cs.fsu.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
186019Shines@cs.fsu.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
196019Shines@cs.fsu.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
206019Shines@cs.fsu.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
216019Shines@cs.fsu.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
226019Shines@cs.fsu.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236019Shines@cs.fsu.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
246019Shines@cs.fsu.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
256019Shines@cs.fsu.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266019Shines@cs.fsu.edu//
276019Shines@cs.fsu.edu// Authors: Gabe Black
286019Shines@cs.fsu.edu
296019Shines@cs.fsu.edudef template MediaOpExecute {{
306019Shines@cs.fsu.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
316019Shines@cs.fsu.edu                Trace::InstRecord *traceData) const
326019Shines@cs.fsu.edu        {
336019Shines@cs.fsu.edu            Fault fault = NoFault;
346019Shines@cs.fsu.edu
356019Shines@cs.fsu.edu            %(op_decl)s;
366019Shines@cs.fsu.edu            %(op_rd)s;
376019Shines@cs.fsu.edu
386019Shines@cs.fsu.edu            %(code)s;
396019Shines@cs.fsu.edu
406019Shines@cs.fsu.edu            //Write the resulting state to the execution context
416019Shines@cs.fsu.edu            if(fault == NoFault)
426019Shines@cs.fsu.edu            {
436019Shines@cs.fsu.edu                %(op_wb)s;
446019Shines@cs.fsu.edu            }
456019Shines@cs.fsu.edu            return fault;
466019Shines@cs.fsu.edu        }
476019Shines@cs.fsu.edu}};
487152Sgblack@eecs.umich.edu
497152Sgblack@eecs.umich.edudef template MediaOpRegDeclare {{
507152Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
517152Sgblack@eecs.umich.edu    {
527152Sgblack@eecs.umich.edu      protected:
537602SGene.Wu@arm.com        void buildMe();
547152Sgblack@eecs.umich.edu
557152Sgblack@eecs.umich.edu      public:
567152Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
577152Sgblack@eecs.umich.edu                const char * instMnem,
587152Sgblack@eecs.umich.edu                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
597152Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
607152Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _sel);
617152Sgblack@eecs.umich.edu
627152Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
637152Sgblack@eecs.umich.edu                const char * instMnem,
647152Sgblack@eecs.umich.edu                InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
657152Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _sel);
667602SGene.Wu@arm.com
677152Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
687152Sgblack@eecs.umich.edu    };
697152Sgblack@eecs.umich.edu}};
707152Sgblack@eecs.umich.edu
717152Sgblack@eecs.umich.edudef template MediaOpImmDeclare {{
727152Sgblack@eecs.umich.edu
737152Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
747252Sgblack@eecs.umich.edu    {
757152Sgblack@eecs.umich.edu      protected:
767252Sgblack@eecs.umich.edu        void buildMe();
777252Sgblack@eecs.umich.edu
787252Sgblack@eecs.umich.edu      public:
797252Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
807252Sgblack@eecs.umich.edu                const char * instMnem,
817252Sgblack@eecs.umich.edu                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
827252Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
837252Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _sel);
847252Sgblack@eecs.umich.edu
857252Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
867252Sgblack@eecs.umich.edu                const char * instMnem,
877252Sgblack@eecs.umich.edu                InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
887152Sgblack@eecs.umich.edu                uint8_t _srcSize, uint8_t _destSize, uint16_t _sel);
897152Sgblack@eecs.umich.edu
907152Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
917152Sgblack@eecs.umich.edu    };
927152Sgblack@eecs.umich.edu}};
937152Sgblack@eecs.umich.edu
947152Sgblack@eecs.umich.edudef template MediaOpRegConstructor {{
957152Sgblack@eecs.umich.edu
967152Sgblack@eecs.umich.edu    inline void %(class_name)s::buildMe()
977154Sgblack@eecs.umich.edu    {
987154Sgblack@eecs.umich.edu        %(constructor)s;
997154Sgblack@eecs.umich.edu    }
1007154Sgblack@eecs.umich.edu
1017154Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1027154Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1037154Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
10410037SARM gem5 Developers            uint8_t _srcSize, uint8_t _destSize, uint16_t _sel) :
1057154Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1067154Sgblack@eecs.umich.edu                false, false, false, false,
1077281Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _sel,
1087154Sgblack@eecs.umich.edu                %(op_class)s)
1097154Sgblack@eecs.umich.edu    {
1107154Sgblack@eecs.umich.edu        buildMe();
1117154Sgblack@eecs.umich.edu    }
1127154Sgblack@eecs.umich.edu
1137154Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1147154Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1157154Sgblack@eecs.umich.edu            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
1167154Sgblack@eecs.umich.edu            InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
1177154Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _sel) :
1187155Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1197154Sgblack@eecs.umich.edu                isMicro, isDelayed, isFirst, isLast,
1207155Sgblack@eecs.umich.edu                _src1, _src2, _dest, _srcSize, _destSize, _sel,
1217155Sgblack@eecs.umich.edu                %(op_class)s)
1227155Sgblack@eecs.umich.edu    {
1237155Sgblack@eecs.umich.edu        buildMe();
1247155Sgblack@eecs.umich.edu    }
1257155Sgblack@eecs.umich.edu}};
1267155Sgblack@eecs.umich.edu
1277281Sgblack@eecs.umich.edudef template MediaOpImmConstructor {{
1287281Sgblack@eecs.umich.edu
1297155Sgblack@eecs.umich.edu    inline void %(class_name)s::buildMe()
13010037SARM gem5 Developers    {
1317155Sgblack@eecs.umich.edu        %(constructor)s;
1327155Sgblack@eecs.umich.edu    }
1337155Sgblack@eecs.umich.edu
1347155Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1357155Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1367155Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
1377155Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _sel) :
1387155Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
1397155Sgblack@eecs.umich.edu                false, false, false, false,
1407155Sgblack@eecs.umich.edu                _src1, _imm8, _dest, _srcSize, _destSize, _sel,
1417155Sgblack@eecs.umich.edu                %(op_class)s)
1427155Sgblack@eecs.umich.edu    {
1437155Sgblack@eecs.umich.edu        buildMe();
14410037SARM gem5 Developers    }
1457155Sgblack@eecs.umich.edu
1467155Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(
1477155Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem,
1487204Sgblack@eecs.umich.edu            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
1497204Sgblack@eecs.umich.edu            InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
1507204Sgblack@eecs.umich.edu            uint8_t _srcSize, uint8_t _destSize, uint16_t _sel) :
1517204Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
15210037SARM gem5 Developers                isMicro, isDelayed, isFirst, isLast,
15310037SARM gem5 Developers                _src1, _imm8, _dest, _srcSize, _destSize, _sel,
15410037SARM gem5 Developers                %(op_class)s)
15510037SARM gem5 Developers    {
15610037SARM gem5 Developers        buildMe();
15710037SARM gem5 Developers    }
15810037SARM gem5 Developers}};
15910037SARM gem5 Developers
16010037SARM gem5 Developerslet {{
16110037SARM gem5 Developers    # Make these empty strings so that concatenating onto
16210037SARM gem5 Developers    # them will always work.
16310037SARM gem5 Developers    header_output = ""
1647204Sgblack@eecs.umich.edu    decoder_output = ""
1657155Sgblack@eecs.umich.edu    exec_output = ""
1667155Sgblack@eecs.umich.edu
1677155Sgblack@eecs.umich.edu    immTemplates = (
16813354Sciro.santilli@arm.com            MediaOpImmDeclare,
16913354Sciro.santilli@arm.com            MediaOpImmConstructor,
1707155Sgblack@eecs.umich.edu            MediaOpExecute)
1717316Sgblack@eecs.umich.edu
1727316Sgblack@eecs.umich.edu    regTemplates = (
1737316Sgblack@eecs.umich.edu            MediaOpRegDeclare,
1747316Sgblack@eecs.umich.edu            MediaOpRegConstructor,
17513354Sciro.santilli@arm.com            MediaOpExecute)
1767613SGene.Wu@arm.com
1777155Sgblack@eecs.umich.edu    class MediaOpMeta(type):
17813354Sciro.santilli@arm.com        def buildCppClasses(self, name, Name, suffix, code):
1797155Sgblack@eecs.umich.edu
18013354Sciro.santilli@arm.com            # Globals to stick the output in
18113354Sciro.santilli@arm.com            global header_output
18213354Sciro.santilli@arm.com            global decoder_output
18313354Sciro.santilli@arm.com            global exec_output
18413354Sciro.santilli@arm.com
18513354Sciro.santilli@arm.com            # If op2 is used anywhere, make register and immediate versions
18613354Sciro.santilli@arm.com            # of this code.
18713354Sciro.santilli@arm.com            matcher = re.compile("(?<!\\w)(?P<prefix>s?)op2(?P<typeQual>\\.\\w+)?")
18813354Sciro.santilli@arm.com            match = matcher.search(code)
18913354Sciro.santilli@arm.com            if match:
19013354Sciro.santilli@arm.com                typeQual = ""
19113354Sciro.santilli@arm.com                if match.group("typeQual"):
19213354Sciro.santilli@arm.com                    typeQual = match.group("typeQual")
19313354Sciro.santilli@arm.com                src2_name = "%spsrc2%s" % (match.group("prefix"), typeQual)
19413354Sciro.santilli@arm.com                self.buildCppClasses(name, Name, suffix,
19513354Sciro.santilli@arm.com                        matcher.sub(src2_name, code))
1967155Sgblack@eecs.umich.edu                self.buildCppClasses(name + "i", Name, suffix + "Imm",
19713354Sciro.santilli@arm.com                        matcher.sub("imm8", code))
19813354Sciro.santilli@arm.com                return
19913354Sciro.santilli@arm.com
20013354Sciro.santilli@arm.com            base = "X86ISA::MediaOp"
20113354Sciro.santilli@arm.com
20213354Sciro.santilli@arm.com            # If imm8 shows up in the code, use the immediate templates, if
20313354Sciro.santilli@arm.com            # not, hopefully the register ones will be correct.
20413354Sciro.santilli@arm.com            matcher = re.compile("(?<!\w)imm8(?!\w)")
20513354Sciro.santilli@arm.com            if matcher.search(code):
20613354Sciro.santilli@arm.com                base += "Imm"
20713354Sciro.santilli@arm.com                templates = immTemplates
2087155Sgblack@eecs.umich.edu            else:
2097155Sgblack@eecs.umich.edu                base += "Reg"
2107155Sgblack@eecs.umich.edu                templates = regTemplates
21113354Sciro.santilli@arm.com
21213354Sciro.santilli@arm.com            # Get everything ready for the substitution
2137155Sgblack@eecs.umich.edu            iop = InstObjParams(name, Name + suffix, base, {"code" : code})
2147155Sgblack@eecs.umich.edu
2157155Sgblack@eecs.umich.edu            # Generate the actual code (finally!)
2167155Sgblack@eecs.umich.edu            header_output += templates[0].subst(iop)
2177155Sgblack@eecs.umich.edu            decoder_output += templates[1].subst(iop)
2187155Sgblack@eecs.umich.edu            exec_output += templates[2].subst(iop)
2197284Sgblack@eecs.umich.edu
2207155Sgblack@eecs.umich.edu
2217284Sgblack@eecs.umich.edu        def __new__(mcls, Name, bases, dict):
2227155Sgblack@eecs.umich.edu            abstract = False
2237603SGene.Wu@arm.com            name = Name.lower()
2247155Sgblack@eecs.umich.edu            if "abstract" in dict:
22510037SARM gem5 Developers                abstract = dict['abstract']
2267155Sgblack@eecs.umich.edu                del dict['abstract']
22710037SARM gem5 Developers
2287155Sgblack@eecs.umich.edu            cls = super(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict)
22910037SARM gem5 Developers            if not abstract:
2307155Sgblack@eecs.umich.edu                cls.className = Name
2317155Sgblack@eecs.umich.edu                cls.base_mnemonic = name
2327155Sgblack@eecs.umich.edu                code = cls.code
2337155Sgblack@eecs.umich.edu
2347155Sgblack@eecs.umich.edu                # Set up the C++ classes
2357155Sgblack@eecs.umich.edu                mcls.buildCppClasses(cls, name, Name, "", code)
2367344SAli.Saidi@ARM.com
23710037SARM gem5 Developers                # Hook into the microassembler dict
2387344SAli.Saidi@ARM.com                global microopClasses
2397344SAli.Saidi@ARM.com                microopClasses[name] = cls
2407344SAli.Saidi@ARM.com
2417155Sgblack@eecs.umich.edu                # If op2 is used anywhere, make register and immediate versions
2427188Sgblack@eecs.umich.edu                # of this code.
2437188Sgblack@eecs.umich.edu                matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
24410037SARM gem5 Developers                if matcher.search(code):
24510037SARM gem5 Developers                    microopClasses[name + 'i'] = cls
24610037SARM gem5 Developers            return cls
24710037SARM gem5 Developers
24810037SARM gem5 Developers
24910037SARM gem5 Developers    class MediaOp(X86Microop):
2507188Sgblack@eecs.umich.edu        __metaclass__ = MediaOpMeta
2517155Sgblack@eecs.umich.edu        # This class itself doesn't act as a microop
25210037SARM gem5 Developers        abstract = True
2537204Sgblack@eecs.umich.edu
25410037SARM gem5 Developers        def __init__(self, dest, src1, op2,
2557204Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, sel = None):
2567204Sgblack@eecs.umich.edu            self.dest = dest
25710037SARM gem5 Developers            self.src1 = src1
25810037SARM gem5 Developers            self.op2 = op2
25910037SARM gem5 Developers            if size is not None:
26010037SARM gem5 Developers                self.srcSize = size
26110037SARM gem5 Developers                self.destSize = size
26210037SARM gem5 Developers            if srcSize is not None:
26310037SARM gem5 Developers                self.srcSize = srcSize
26410037SARM gem5 Developers            if destSize is not None:
26510037SARM gem5 Developers                self.destSize = destSize
26610037SARM gem5 Developers            if self.srcSize is None:
26710037SARM gem5 Developers                raise Exception, "Source size not set."
26810037SARM gem5 Developers            if self.destSize is None:
2697204Sgblack@eecs.umich.edu                raise Exception, "Dest size not set."
27012248Sgiacomo.travaglini@arm.com            if sel is None:
2717204Sgblack@eecs.umich.edu                self.sel = 0
27210037SARM gem5 Developers            else:
27310037SARM gem5 Developers                self.sel = sel
27410037SARM gem5 Developers
2757204Sgblack@eecs.umich.edu        def getAllocator(self, *microFlags):
2767155Sgblack@eecs.umich.edu            className = self.className
2777155Sgblack@eecs.umich.edu            if self.mnemonic == self.base_mnemonic + 'i':
2787155Sgblack@eecs.umich.edu                className += "Imm"
2797155Sgblack@eecs.umich.edu            allocator = '''new %(class_name)s(machInst, macrocodeBlock
2807155Sgblack@eecs.umich.edu                    %(flags)s, %(src1)s, %(op2)s, %(dest)s,
2817155Sgblack@eecs.umich.edu                    %(srcSize)s, %(destSize)s, %(sel)s)''' % {
2827155Sgblack@eecs.umich.edu                "class_name" : className,
2837155Sgblack@eecs.umich.edu                "flags" : self.microFlagsText(microFlags),
2847155Sgblack@eecs.umich.edu                "src1" : self.src1, "op2" : self.op2,
2857155Sgblack@eecs.umich.edu                "dest" : self.dest,
2867155Sgblack@eecs.umich.edu                "srcSize" : self.srcSize,
2877155Sgblack@eecs.umich.edu                "destSize" : self.destSize,
2887155Sgblack@eecs.umich.edu                "sel" : self.sel}
2898909SAli.Saidi@ARM.com            return allocator
2907155Sgblack@eecs.umich.edu
2917155Sgblack@eecs.umich.edu    class Mov2int(MediaOp):
2927155Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
2937290Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, sel = None):
2947290Sgblack@eecs.umich.edu            super(Mov2int, self).__init__(dest, src,\
2957290Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, sel)
2967155Sgblack@eecs.umich.edu        code = '''
2977155Sgblack@eecs.umich.edu            uint64_t fpSrcReg1 = bits(FpSrcReg1.uqw, srcSize * 8 - 1, 0);
2987155Sgblack@eecs.umich.edu            DestReg = merge(DestReg, fpSrcReg1, destSize);
2997155Sgblack@eecs.umich.edu        '''
3007155Sgblack@eecs.umich.edu
3017155Sgblack@eecs.umich.edu    class Mov2fp(MediaOp):
3027155Sgblack@eecs.umich.edu        def __init__(self, dest, src, \
3037155Sgblack@eecs.umich.edu                size = None, destSize = None, srcSize = None, sel = None):
3048909SAli.Saidi@ARM.com            super(Mov2fp, self).__init__(dest, src,\
3057155Sgblack@eecs.umich.edu                    "InstRegIndex(0)", size, destSize, srcSize, sel)
3067155Sgblack@eecs.umich.edu        code = '''
3077155Sgblack@eecs.umich.edu            uint64_t srcReg1 = pick(SrcReg1, 0, srcSize);
3087155Sgblack@eecs.umich.edu            FpDestReg.uqw =
3097155Sgblack@eecs.umich.edu                insertBits(FpDestReg.uqw, destSize * 8 - 1, 0, srcReg1);
3107155Sgblack@eecs.umich.edu        '''
3117155Sgblack@eecs.umich.edu}};
3127155Sgblack@eecs.umich.edu