limmop.isa revision 7087:fb8d5786ff30
1// Copyright (c) 2007 The Hewlett-Packard Development Company
2// All rights reserved.
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder.  You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Gabe Black
37
38//////////////////////////////////////////////////////////////////////////
39//
40// LIMMOp Microop templates
41//
42//////////////////////////////////////////////////////////////////////////
43
44def template MicroLimmOpExecute {{
45        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
46                Trace::InstRecord *traceData) const
47        {
48            %(op_decl)s;
49            %(op_rd)s;
50            %(code)s;
51            %(op_wb)s;
52            return NoFault;
53        }
54}};
55
56def template MicroLimmOpDeclare {{
57    class %(class_name)s : public X86ISA::X86MicroopBase
58    {
59      protected:
60        const RegIndex dest;
61        const uint64_t imm;
62        const uint8_t dataSize;
63        RegIndex foldOBit;
64        void buildMe();
65
66        std::string generateDisassembly(Addr pc,
67            const SymbolTable *symtab) const;
68
69      public:
70        %(class_name)s(ExtMachInst _machInst,
71                const char * instMnem,
72                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
73                InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize);
74
75        %(class_name)s(ExtMachInst _machInst,
76                const char * instMnem,
77                InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize);
78
79        %(BasicExecDeclare)s
80    };
81}};
82
83def template MicroLimmOpDisassembly {{
84    std::string %(class_name)s::generateDisassembly(Addr pc,
85            const SymbolTable *symtab) const
86    {
87        std::stringstream response;
88
89        printMnemonic(response, instMnem, mnemonic);
90        printDestReg(response, 0, dataSize);
91        response << ", ";
92        ccprintf(response, "%#x", imm);
93        return response.str();
94    }
95}};
96
97def template MicroLimmOpConstructor {{
98
99    inline void %(class_name)s::buildMe()
100    {
101        foldOBit = (dataSize == 1 && !machInst.rex.present) ? 1 << 6 : 0;
102        %(constructor)s;
103    }
104
105    inline %(class_name)s::%(class_name)s(
106            ExtMachInst machInst, const char * instMnem,
107            InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
108        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
109                false, false, false, false, %(op_class)s),
110                dest(_dest.idx), imm(_imm), dataSize(_dataSize)
111    {
112        buildMe();
113    }
114
115    inline %(class_name)s::%(class_name)s(
116            ExtMachInst machInst, const char * instMnem,
117            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
118            InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
119        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
120                isMicro, isDelayed, isFirst, isLast, %(op_class)s),
121                dest(_dest.idx), imm(_imm), dataSize(_dataSize)
122    {
123        buildMe();
124    }
125}};
126
127let {{
128    class LimmOp(X86Microop):
129        def __init__(self, dest, imm, dataSize="env.dataSize"):
130            self.className = "Limm"
131            self.mnemonic = "limm"
132            self.dest = dest
133            if isinstance(imm, (int, long)):
134                imm = "ULL(%d)" % imm
135            self.imm = imm
136            self.dataSize = dataSize
137
138        def getAllocator(self, *microFlags):
139            allocator = '''new %(class_name)s(machInst, macrocodeBlock
140                    %(flags)s, %(dest)s, %(imm)s, %(dataSize)s)''' % {
141                "class_name" : self.className,
142                "mnemonic" : self.mnemonic,
143                "flags" : self.microFlagsText(microFlags),
144                "dest" : self.dest, "imm" : self.imm,
145                "dataSize" : self.dataSize}
146            return allocator
147
148    microopClasses["limm"] = LimmOp
149
150    class LfpimmOp(X86Microop):
151        def __init__(self, dest, imm, dataSize="env.dataSize"):
152            self.className = "Lfpimm"
153            self.mnemonic = "lfpimm"
154            self.dest = dest
155            if isinstance(imm, (int, long)):
156                imm = "ULL(%d)" % imm
157            if isinstance(imm, float):
158                imm = "reinterpret_cast<uint64_t>((double)(%d))"
159            self.imm = imm
160            self.dataSize = dataSize
161
162        def getAllocator(self, *microFlags):
163            allocator = '''new %(class_name)s(machInst, macrocodeBlock
164                    %(flags)s, %(dest)s, %(imm)s, %(dataSize)s)''' % {
165                "class_name" : self.className,
166                "mnemonic" : self.mnemonic,
167                "flags" : self.microFlagsText(microFlags),
168                "dest" : self.dest, "imm" : self.imm,
169                "dataSize" : self.dataSize}
170            return allocator
171
172    microopClasses["lfpimm"] = LfpimmOp
173}};
174
175let {{
176    # Build up the all register version of this micro op
177    iop = InstObjParams("limm", "Limm", 'X86MicroopBase',
178            {"code" : "DestReg = merge(DestReg, imm, dataSize);"})
179    header_output += MicroLimmOpDeclare.subst(iop)
180    decoder_output += MicroLimmOpConstructor.subst(iop)
181    decoder_output += MicroLimmOpDisassembly.subst(iop)
182    exec_output += MicroLimmOpExecute.subst(iop)
183
184    iop = InstObjParams("lfpimm", "Lfpimm", 'X86MicroopBase',
185            {"code" : "FpDestReg.uqw = imm"})
186    header_output += MicroLimmOpDeclare.subst(iop)
187    decoder_output += MicroLimmOpConstructor.subst(iop)
188    decoder_output += MicroLimmOpDisassembly.subst(iop)
189    exec_output += MicroLimmOpExecute.subst(iop)
190}};
191