regop.isa revision 4612
12914SN/A// Copyright (c) 2007 The Hewlett-Packard Development Company
210713Sandreas.hansson@arm.com// All rights reserved.
38856SN/A//
48856SN/A// Redistribution and use of this software in source and binary forms,
58856SN/A// with or without modification, are permitted provided that the
68856SN/A// following conditions are met:
78856SN/A//
88856SN/A// The software must be used only for Non-Commercial Use which means any
98856SN/A// use which is NOT directed to receiving any direct monetary
108856SN/A// compensation for, or commercial advantage from such use.  Illustrative
118856SN/A// examples of non-commercial use are academic research, personal study,
128856SN/A// teaching, education and corporate research & development.
138856SN/A// Illustrative examples of commercial use are distributing products for
142914SN/A// commercial advantage and providing services using the software for
152914SN/A// commercial advantage.
162914SN/A//
172914SN/A// If you wish to use this software or functionality therein that may be
182914SN/A// covered by patents for commercial use, please contact:
192914SN/A//     Director of Intellectual Property Licensing
202914SN/A//     Office of Strategy and Technology
212914SN/A//     Hewlett-Packard Company
222914SN/A//     1501 Page Mill Road
232914SN/A//     Palo Alto, California  94304
242914SN/A//
252914SN/A// Redistributions of source code must retain the above copyright notice,
262914SN/A// this list of conditions and the following disclaimer.  Redistributions
272914SN/A// in binary form must reproduce the above copyright notice, this list of
282914SN/A// conditions and the following disclaimer in the documentation and/or
292914SN/A// other materials provided with the distribution.  Neither the name of
302914SN/A// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
312914SN/A// contributors may be used to endorse or promote products derived from
322914SN/A// this software without specific prior written permission.  No right of
332914SN/A// sublicense is granted herewith.  Derivatives of the software and
342914SN/A// output created using the software may be prepared, but only for
352914SN/A// Non-Commercial Uses.  Derivatives of the software may be shared with
362914SN/A// others provided: (i) the others agree to abide by the list of
372914SN/A// conditions herein which includes the Non-Commercial Use restrictions;
382914SN/A// and (ii) such Derivatives of the software include the above copyright
392914SN/A// notice to acknowledge the contribution from this software where
402914SN/A// applicable, this list of conditions and the disclaimer below.
418856SN/A//
422914SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
432914SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
449356Snilay@cs.wisc.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
459152Satgutier@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
468914Sandreas.hansson@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
478914Sandreas.hansson@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
482914SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
495740SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
505740SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
518975Sandreas.hansson@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
5210913Sandreas.sandberg@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
535740SN/A//
545740SN/A// Authors: Gabe Black
555740SN/A
565740SN/A//////////////////////////////////////////////////////////////////////////
578914Sandreas.hansson@arm.com//
585740SN/A// RegOp Microop templates
595740SN/A//
605740SN/A//////////////////////////////////////////////////////////////////////////
618914Sandreas.hansson@arm.com
628914Sandreas.hansson@arm.comoutput header {{
638914Sandreas.hansson@arm.com    /**
648914Sandreas.hansson@arm.com     * Base classes for RegOps which provides a generateDisassembly method.
658914Sandreas.hansson@arm.com     */
6610713Sandreas.hansson@arm.com    class RegOp : public X86MicroopBase
678914Sandreas.hansson@arm.com    {
688914Sandreas.hansson@arm.com      protected:
698914Sandreas.hansson@arm.com        const RegIndex src1;
704929SN/A        const RegIndex src2;
7110713Sandreas.hansson@arm.com        const RegIndex dest;
7210713Sandreas.hansson@arm.com        const bool setStatus;
7310713Sandreas.hansson@arm.com        const uint8_t dataSize;
7410713Sandreas.hansson@arm.com        const uint8_t ext;
7510713Sandreas.hansson@arm.com
7610713Sandreas.hansson@arm.com        // Constructor
7710713Sandreas.hansson@arm.com        RegOp(ExtMachInst _machInst,
7810713Sandreas.hansson@arm.com                const char *mnem, const char *_instMnem,
7910713Sandreas.hansson@arm.com                bool isMicro, bool isDelayed,
8010713Sandreas.hansson@arm.com                bool isFirst, bool isLast,
8110713Sandreas.hansson@arm.com                RegIndex _src1, RegIndex _src2, RegIndex _dest,
8210713Sandreas.hansson@arm.com                bool _setStatus, uint8_t _dataSize, uint8_t _ext,
838914Sandreas.hansson@arm.com                OpClass __opClass) :
843091SN/A            X86MicroopBase(_machInst, mnem, _instMnem,
858856SN/A                    isMicro, isDelayed, isFirst, isLast,
868856SN/A                    __opClass),
8710322Sandreas.hansson@arm.com            src1(_src1), src2(_src2), dest(_dest),
888856SN/A            setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
893296SN/A        {
9010322Sandreas.hansson@arm.com        }
918856SN/A
928856SN/A        std::string generateDisassembly(Addr pc,
938856SN/A            const SymbolTable *symtab) const;
948856SN/A    };
953284SN/A
964929SN/A    class RegOpImm : public X86MicroopBase
978856SN/A    {
988856SN/A      protected:
998856SN/A        const RegIndex src1;
1004490SN/A        const uint8_t imm8;
1013342SN/A        const RegIndex dest;
1024490SN/A        const bool setStatus;
10310722Sstephan.diestelhorst@arm.com        const uint8_t dataSize;
1043403SN/A        const uint8_t ext;
10510722Sstephan.diestelhorst@arm.com
10610722Sstephan.diestelhorst@arm.com        // Constructor
10710722Sstephan.diestelhorst@arm.com        RegOpImm(ExtMachInst _machInst,
10810713Sandreas.hansson@arm.com                const char * mnem, const char *_instMnem,
1099160Sandreas.hansson@arm.com                bool isMicro, bool isDelayed,
1109160Sandreas.hansson@arm.com                bool isFirst, bool isLast,
1114492SN/A                RegIndex _src1, uint8_t _imm8, RegIndex _dest,
1129163Sandreas.hansson@arm.com                bool _setStatus, uint8_t _dataSize, uint8_t _ext,
1139163Sandreas.hansson@arm.com                OpClass __opClass) :
1149163Sandreas.hansson@arm.com            X86MicroopBase(_machInst, mnem, _instMnem,
1159390Sandreas.hansson@arm.com                    isMicro, isDelayed, isFirst, isLast,
1169390Sandreas.hansson@arm.com                    __opClass),
1179390Sandreas.hansson@arm.com            src1(_src1), imm8(_imm8), dest(_dest),
1189390Sandreas.hansson@arm.com            setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
1199390Sandreas.hansson@arm.com        {
1209390Sandreas.hansson@arm.com        }
1219390Sandreas.hansson@arm.com
12210722Sstephan.diestelhorst@arm.com        std::string generateDisassembly(Addr pc,
12310722Sstephan.diestelhorst@arm.com            const SymbolTable *symtab) const;
12410722Sstephan.diestelhorst@arm.com    };
12510722Sstephan.diestelhorst@arm.com}};
12610722Sstephan.diestelhorst@arm.com
12710722Sstephan.diestelhorst@arm.comoutput decoder {{
12810722Sstephan.diestelhorst@arm.com    std::string RegOp::generateDisassembly(Addr pc,
12910722Sstephan.diestelhorst@arm.com            const SymbolTable *symtab) const
13010722Sstephan.diestelhorst@arm.com    {
13110722Sstephan.diestelhorst@arm.com        std::stringstream response;
13210722Sstephan.diestelhorst@arm.com
13310722Sstephan.diestelhorst@arm.com        printMnemonic(response, instMnem, mnemonic);
13410722Sstephan.diestelhorst@arm.com        printReg(response, dest);
13510722Sstephan.diestelhorst@arm.com        response << ", ";
13610722Sstephan.diestelhorst@arm.com        printReg(response, src1);
1378914Sandreas.hansson@arm.com        response << ", ";
1388914Sandreas.hansson@arm.com        printReg(response, src2);
1394666SN/A        return response.str();
14010722Sstephan.diestelhorst@arm.com    }
14110722Sstephan.diestelhorst@arm.com
1428914Sandreas.hansson@arm.com    std::string RegOpImm::generateDisassembly(Addr pc,
1438914Sandreas.hansson@arm.com            const SymbolTable *symtab) const
1448914Sandreas.hansson@arm.com    {
14510922Sandreas.hansson@arm.com        std::stringstream response;
1464666SN/A
1474666SN/A        printMnemonic(response, instMnem, mnemonic);
1484666SN/A        printReg(response, dest);
1494666SN/A        response << ", ";
15010713Sandreas.hansson@arm.com        printReg(response, src1);
15110713Sandreas.hansson@arm.com        ccprintf(response, ", %#x", imm8);
15210713Sandreas.hansson@arm.com        return response.str();
15310713Sandreas.hansson@arm.com    }
15410713Sandreas.hansson@arm.com}};
15510713Sandreas.hansson@arm.com
15610713Sandreas.hansson@arm.comdef template MicroRegOpExecute {{
15710713Sandreas.hansson@arm.com        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
1588914Sandreas.hansson@arm.com                Trace::InstRecord *traceData) const
1594666SN/A        {
16010922Sandreas.hansson@arm.com            Fault fault = NoFault;
1613450SN/A
1623403SN/A            %(op_decl)s;
1633450SN/A            %(op_rd)s;
16410722Sstephan.diestelhorst@arm.com            %(code)s;
16510722Sstephan.diestelhorst@arm.com            %(flag_code)s;
16610722Sstephan.diestelhorst@arm.com
1678914Sandreas.hansson@arm.com            //Write the resulting state to the execution context
16810322Sandreas.hansson@arm.com            if(fault == NoFault)
1698914Sandreas.hansson@arm.com            {
1708914Sandreas.hansson@arm.com                %(op_wb)s;
1718914Sandreas.hansson@arm.com            }
17210922Sandreas.hansson@arm.com            return fault;
1738856SN/A        }
1748856SN/A}};
1758856SN/A
17610713Sandreas.hansson@arm.comdef template MicroRegOpImmExecute {{
1778856SN/A        Fault %(class_name)sImm::execute(%(CPU_exec_context)s *xc,
17810713Sandreas.hansson@arm.com                Trace::InstRecord *traceData) const
17910713Sandreas.hansson@arm.com        {
18010713Sandreas.hansson@arm.com            Fault fault = NoFault;
18110713Sandreas.hansson@arm.com
18210713Sandreas.hansson@arm.com            %(op_decl)s;
18310713Sandreas.hansson@arm.com            %(op_rd)s;
1848914Sandreas.hansson@arm.com            %(code)s;
18510713Sandreas.hansson@arm.com            %(flag_code)s;
18610713Sandreas.hansson@arm.com
18710713Sandreas.hansson@arm.com            //Write the resulting state to the execution context
18810713Sandreas.hansson@arm.com            if(fault == NoFault)
18910713Sandreas.hansson@arm.com            {
19010713Sandreas.hansson@arm.com                %(op_wb)s;
19110423Sandreas.hansson@arm.com            }
19210713Sandreas.hansson@arm.com            return fault;
19310713Sandreas.hansson@arm.com        }
19410423Sandreas.hansson@arm.com}};
19510423Sandreas.hansson@arm.com
19610713Sandreas.hansson@arm.comdef template MicroRegOpDeclare {{
19710423Sandreas.hansson@arm.com    class %(class_name)s : public %(base_class)s
1988856SN/A    {
19910713Sandreas.hansson@arm.com      protected:
20010713Sandreas.hansson@arm.com        void buildMe();
20110913Sandreas.sandberg@arm.com
20210913Sandreas.sandberg@arm.com      public:
20310913Sandreas.sandberg@arm.com        %(class_name)s(ExtMachInst _machInst,
2049152Satgutier@umich.edu                const char * instMnem,
2059152Satgutier@umich.edu                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
20610913Sandreas.sandberg@arm.com                RegIndex _src1, RegIndex _src2, RegIndex _dest,
2078856SN/A                bool _setStatus, uint8_t _dataSize, uint8_t _ext);
2088856SN/A
2098856SN/A        %(class_name)s(ExtMachInst _machInst,
2104492SN/A                const char * instMnem,
2113403SN/A                RegIndex _src1, RegIndex _src2, RegIndex _dest,
2128914Sandreas.hansson@arm.com                bool _setStatus, uint8_t _dataSize, uint8_t _ext);
2132914SN/A
21410713Sandreas.hansson@arm.com        %(BasicExecDeclare)s
21510713Sandreas.hansson@arm.com    };
21610713Sandreas.hansson@arm.com}};
21710713Sandreas.hansson@arm.com
21810713Sandreas.hansson@arm.comdef template MicroRegOpImmDeclare {{
21910713Sandreas.hansson@arm.com
22010713Sandreas.hansson@arm.com    class %(class_name)sImm : public %(base_class)s
22110713Sandreas.hansson@arm.com    {
22210713Sandreas.hansson@arm.com      protected:
22310713Sandreas.hansson@arm.com        void buildMe();
22410713Sandreas.hansson@arm.com
22510713Sandreas.hansson@arm.com      public:
22610713Sandreas.hansson@arm.com        %(class_name)sImm(ExtMachInst _machInst,
22710713Sandreas.hansson@arm.com                const char * instMnem,
22810713Sandreas.hansson@arm.com                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
22910713Sandreas.hansson@arm.com                RegIndex _src1, uint8_t _imm8, RegIndex _dest,
2304492SN/A                bool _setStatus, uint8_t _dataSize, uint8_t _ext);
2318856SN/A
2328856SN/A        %(class_name)sImm(ExtMachInst _machInst,
2338856SN/A                const char * instMnem,
23410713Sandreas.hansson@arm.com                RegIndex _src1, uint8_t _imm8, RegIndex _dest,
23510713Sandreas.hansson@arm.com                bool _setStatus, uint8_t _dataSize, uint8_t _ext);
23610713Sandreas.hansson@arm.com
23710745Sandreas.hansson@arm.com        %(BasicExecDeclare)s
2384492SN/A    };
2394492SN/A}};
2404492SN/A
2414492SN/Adef template MicroRegOpConstructor {{
2428914Sandreas.hansson@arm.com
2434492SN/A    inline void %(class_name)s::buildMe()
2444492SN/A    {
2454492SN/A        %(constructor)s;
2462914SN/A    }
2472914SN/A
24810913Sandreas.sandberg@arm.com    inline %(class_name)s::%(class_name)s(
24910913Sandreas.sandberg@arm.com            ExtMachInst machInst, const char * instMnem,
2502914SN/A            RegIndex _src1, RegIndex _src2, RegIndex _dest,
25110913Sandreas.sandberg@arm.com            bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
25210913Sandreas.sandberg@arm.com        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
25310913Sandreas.sandberg@arm.com                false, false, false, false,
25410913Sandreas.sandberg@arm.com                _src1, _src2, _dest, _setStatus, _dataSize, _ext,
25510913Sandreas.sandberg@arm.com                %(op_class)s)
25610913Sandreas.sandberg@arm.com    {
2572914SN/A        buildMe();
2588975Sandreas.hansson@arm.com    }
25910713Sandreas.hansson@arm.com
26010713Sandreas.hansson@arm.com    inline %(class_name)s::%(class_name)s(
2618975Sandreas.hansson@arm.com            ExtMachInst machInst, const char * instMnem,
2628975Sandreas.hansson@arm.com            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
2638975Sandreas.hansson@arm.com            RegIndex _src1, RegIndex _src2, RegIndex _dest,
2648975Sandreas.hansson@arm.com            bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
2658975Sandreas.hansson@arm.com        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
26610713Sandreas.hansson@arm.com                isMicro, isDelayed, isFirst, isLast,
2678975Sandreas.hansson@arm.com                _src1, _src2, _dest, _setStatus, _dataSize, _ext,
26810713Sandreas.hansson@arm.com                %(op_class)s)
2698975Sandreas.hansson@arm.com    {
2708975Sandreas.hansson@arm.com        buildMe();
27110713Sandreas.hansson@arm.com    }
27210713Sandreas.hansson@arm.com}};
27310713Sandreas.hansson@arm.com
27410713Sandreas.hansson@arm.comdef template MicroRegOpImmConstructor {{
27510713Sandreas.hansson@arm.com
27610713Sandreas.hansson@arm.com    inline void %(class_name)sImm::buildMe()
27710713Sandreas.hansson@arm.com    {
27810713Sandreas.hansson@arm.com        %(constructor)s;
27910713Sandreas.hansson@arm.com    }
28010713Sandreas.hansson@arm.com
28110713Sandreas.hansson@arm.com    inline %(class_name)sImm::%(class_name)sImm(
28210713Sandreas.hansson@arm.com            ExtMachInst machInst, const char * instMnem,
28310713Sandreas.hansson@arm.com            RegIndex _src1, uint8_t _imm8, RegIndex _dest,
28410713Sandreas.hansson@arm.com            bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
28510713Sandreas.hansson@arm.com        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
2868975Sandreas.hansson@arm.com                false, false, false, false,
2878975Sandreas.hansson@arm.com                _src1, _imm8, _dest, _setStatus, _dataSize, _ext,
2888975Sandreas.hansson@arm.com                %(op_class)s)
2898975Sandreas.hansson@arm.com    {
2908975Sandreas.hansson@arm.com        buildMe();
29110713Sandreas.hansson@arm.com    }
2928975Sandreas.hansson@arm.com
2938975Sandreas.hansson@arm.com    inline %(class_name)sImm::%(class_name)sImm(
2948975Sandreas.hansson@arm.com            ExtMachInst machInst, const char * instMnem,
295            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
296            RegIndex _src1, uint8_t _imm8, RegIndex _dest,
297            bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
298        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
299                isMicro, isDelayed, isFirst, isLast,
300                _src1, _imm8, _dest, _setStatus, _dataSize, _ext,
301                %(op_class)s)
302    {
303        buildMe();
304    }
305}};
306
307let {{
308    class RegOp(X86Microop):
309        def __init__(self, dest, src1, src2, setStatus):
310            self.dest = dest
311            self.src1 = src1
312            self.src2 = src2
313            self.setStatus = setStatus
314            self.dataSize = "env.dataSize"
315            self.ext = 0
316
317        def getAllocator(self, *microFlags):
318            allocator = '''new %(class_name)s(machInst, mnemonic
319                    %(flags)s, %(src1)s, %(src2)s, %(dest)s,
320                    %(setStatus)s, %(dataSize)s, %(ext)s)''' % {
321                "class_name" : self.className,
322                "flags" : self.microFlagsText(microFlags),
323                "src1" : self.src1, "src2" : self.src2,
324                "dest" : self.dest,
325                "setStatus" : self.cppBool(self.setStatus),
326                "dataSize" : self.dataSize,
327                "ext" : self.ext}
328            return allocator
329
330    class RegOpImm(X86Microop):
331        def __init__(self, dest, src1, imm8, setStatus):
332            self.dest = dest
333            self.src1 = src1
334            self.imm8 = imm8
335            self.setStatus = setStatus
336            self.dataSize = "env.dataSize"
337            self.ext = 0
338
339        def getAllocator(self, *microFlags):
340            allocator = '''new %(class_name)s(machInst, mnemonic
341                    %(flags)s, %(src1)s, %(imm8)s, %(dest)s,
342                    %(setStatus)s, %(dataSize)s, %(ext)s)''' % {
343                "class_name" : self.className,
344                "flags" : self.microFlagsText(microFlags),
345                "src1" : self.src1, "imm8" : self.imm8,
346                "dest" : self.dest,
347                "setStatus" : self.cppBool(self.setStatus),
348                "dataSize" : self.dataSize,
349                "ext" : self.ext}
350            return allocator
351}};
352
353let {{
354
355    # Make these empty strings so that concatenating onto
356    # them will always work.
357    header_output = ""
358    decoder_output = ""
359    exec_output = ""
360
361    def setUpMicroRegOp(name, Name, base, code, child, flagCode):
362        global header_output
363        global decoder_output
364        global exec_output
365        global microopClasses
366
367        iop = InstObjParams(name, Name, base,
368                {"code" : code,
369                 "flag_code" : flagCode})
370        header_output += MicroRegOpDeclare.subst(iop)
371        decoder_output += MicroRegOpConstructor.subst(iop)
372        exec_output += MicroRegOpExecute.subst(iop)
373
374        microopClasses[name] = child
375
376    def defineMicroRegOp(mnemonic, code, flagCode):
377        Name = mnemonic
378        name = mnemonic.lower()
379
380        # Find op2 in each of the instruction definitions. Create two versions
381        # of the code, one with an integer operand, and one with an immediate
382        # operand.
383        matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
384        regCode = matcher.sub("SrcReg2", code)
385        immCode = matcher.sub("imm8", code)
386
387        # Build the all register version of this micro op
388        class RegOpChild(RegOp):
389            def __init__(self, dest, src1, src2, setStatus=False):
390                super(RegOpChild, self).__init__(dest, src1, src2, setStatus)
391                self.className = Name
392                self.mnemonic = name
393
394        setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, flagCode);
395
396        # Build the immediate version of this micro op
397        class RegOpChildImm(RegOpImm):
398            def __init__(self, dest, src1, src2, setStatus=False):
399                super(RegOpChildImm, self).__init__(dest, src1, src2, setStatus)
400                self.className = Name + "Imm"
401                self.mnemonic = name + "i"
402
403        setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, flagCode);
404
405    defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to set OF,CF,SF
406    defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)', "")
407    defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to add in CF, set OF,CF,SF
408    defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to subtract CF, set OF,CF,SF
409    defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', "")
410    defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to set OF,CF,SF
411    defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', "")
412    defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', "") #Needs to set OF,CF,SF and not DestReg
413    defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', "")
414
415    # This has it's own function because Wr ops have implicit destinations
416    def defineMicroRegOpWr(mnemonic, code):
417        Name = mnemonic
418        name = mnemonic.lower()
419
420        # Find op2 in each of the instruction definitions. Create two versions
421        # of the code, one with an integer operand, and one with an immediate
422        # operand.
423        matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
424        regCode = matcher.sub("SrcReg2", code)
425        immCode = matcher.sub("imm8", code)
426
427        # Build the all register version of this micro op
428        class RegOpChild(RegOp):
429            def __init__(self, src1, src2):
430                super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, False)
431                self.className = Name
432                self.mnemonic = name
433
434        setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, "");
435
436        # Build the immediate version of this micro op
437        class RegOpChildImm(RegOpImm):
438            def __init__(self, src1, src2):
439                super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, False)
440                self.className = Name + "Imm"
441                self.mnemonic = name + "i"
442
443        setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, "");
444
445    defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2')
446
447    # This has it's own function because Rd ops don't always have two parameters
448    def defineMicroRegOpRd(mnemonic, code):
449        Name = mnemonic
450        name = mnemonic.lower()
451
452        class RegOpChild(RegOp):
453            def __init__(self, dest, src1 = "NUM_INTREGS"):
454                super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", False)
455                self.className = Name
456                self.mnemonic = name
457
458        setUpMicroRegOp(name, Name, "RegOp", code, RegOpChild, "");
459
460    defineMicroRegOpRd('Rdip', 'DestReg = RIP')
461
462    def defineMicroRegOpImm(mnemonic, code):
463        Name = mnemonic
464        name = mnemonic.lower()
465
466        class RegOpChild(RegOpImm):
467            def __init__(self, dest, src1, src2):
468                super(RegOpChild, self).__init__(dest, src1, src2, False)
469                self.className = Name
470                self.mnemonic = name
471
472        setUpMicroRegOp(name, Name, "RegOpImm", code, RegOpChild, "");
473
474    defineMicroRegOpImm('Sext', '''
475            IntReg val = SrcReg1;
476            int sign_bit = bits(val, imm8-1, imm8-1);
477            val = sign_bit ? (val | ~mask(imm8)) : val;
478            DestReg = merge(DestReg, val, dataSize);''')
479}};
480