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