ldstop.isa revision 4679:0b39fa8f5eb8
1// Copyright (c) 2007 The Hewlett-Packard Development Company
2// All rights reserved.
3//
4// Redistribution and use of this software in source and binary forms,
5// with or without modification, are permitted provided that the
6// following conditions are met:
7//
8// The software must be used only for Non-Commercial Use which means any
9// use which is NOT directed to receiving any direct monetary
10// compensation for, or commercial advantage from such use.  Illustrative
11// examples of non-commercial use are academic research, personal study,
12// teaching, education and corporate research & development.
13// Illustrative examples of commercial use are distributing products for
14// commercial advantage and providing services using the software for
15// commercial advantage.
16//
17// If you wish to use this software or functionality therein that may be
18// covered by patents for commercial use, please contact:
19//     Director of Intellectual Property Licensing
20//     Office of Strategy and Technology
21//     Hewlett-Packard Company
22//     1501 Page Mill Road
23//     Palo Alto, California  94304
24//
25// Redistributions of source code must retain the above copyright notice,
26// this list of conditions and the following disclaimer.  Redistributions
27// in binary form must reproduce the above copyright notice, this list of
28// conditions and the following disclaimer in the documentation and/or
29// other materials provided with the distribution.  Neither the name of
30// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
31// contributors may be used to endorse or promote products derived from
32// this software without specific prior written permission.  No right of
33// sublicense is granted herewith.  Derivatives of the software and
34// output created using the software may be prepared, but only for
35// Non-Commercial Uses.  Derivatives of the software may be shared with
36// others provided: (i) the others agree to abide by the list of
37// conditions herein which includes the Non-Commercial Use restrictions;
38// and (ii) such Derivatives of the software include the above copyright
39// notice to acknowledge the contribution from this software where
40// applicable, this list of conditions and the disclaimer below.
41//
42// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53//
54// Authors: Gabe Black
55
56//////////////////////////////////////////////////////////////////////////
57//
58// LdStOp Microop templates
59//
60//////////////////////////////////////////////////////////////////////////
61
62// LEA template
63
64def template MicroLeaExecute {{
65    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
66          Trace::InstRecord *traceData) const
67    {
68        Fault fault = NoFault;
69        Addr EA;
70
71        %(op_decl)s;
72        %(op_rd)s;
73        %(ea_code)s;
74        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
75
76        %(code)s;
77        if(fault == NoFault)
78        {
79            %(op_wb)s;
80        }
81
82        return fault;
83    }
84}};
85
86def template MicroLeaDeclare {{
87    class %(class_name)s : public %(base_class)s
88    {
89      protected:
90        void buildMe();
91
92      public:
93        %(class_name)s(ExtMachInst _machInst,
94                const char * instMnem,
95                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
96                uint8_t _scale, RegIndex _index, RegIndex _base,
97                uint64_t _disp, uint8_t _segment,
98                RegIndex _data,
99                uint8_t _dataSize, uint8_t _addressSize);
100
101        %(class_name)s(ExtMachInst _machInst,
102                const char * instMnem,
103                uint8_t _scale, RegIndex _index, RegIndex _base,
104                uint64_t _disp, uint8_t _segment,
105                RegIndex _data,
106                uint8_t _dataSize, uint8_t _addressSize);
107
108        %(BasicExecDeclare)s
109    };
110}};
111
112// Load templates
113
114def template MicroLoadExecute {{
115    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
116          Trace::InstRecord *traceData) const
117    {
118        Fault fault = NoFault;
119        Addr EA;
120
121        %(op_decl)s;
122        %(op_rd)s;
123        %(ea_code)s;
124        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
125
126        fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
127        if(fault == NoFault)
128        {
129            %(code)s;
130        }
131        if(fault == NoFault)
132        {
133            %(op_wb)s;
134        }
135
136        return fault;
137    }
138}};
139
140def template MicroLoadInitiateAcc {{
141    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
142            Trace::InstRecord * traceData) const
143    {
144        Fault fault = NoFault;
145        Addr EA;
146
147        %(op_decl)s;
148        %(op_rd)s;
149        %(ea_code)s;
150        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
151
152        fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
153
154        return fault;
155    }
156}};
157
158def template MicroLoadCompleteAcc {{
159    Fault %(class_name)s::completeAcc(PacketPtr pkt,
160            %(CPU_exec_context)s * xc,
161            Trace::InstRecord * traceData) const
162    {
163        Fault fault = NoFault;
164
165        %(op_decl)s;
166        %(op_rd)s;
167
168        Mem = pkt->get<typeof(Mem)>();
169        %(code)s;
170
171        if(fault == NoFault)
172        {
173            %(op_wb)s;
174        }
175
176        return fault;
177    }
178}};
179
180// Store templates
181
182def template MicroStoreExecute {{
183    Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
184            Trace::InstRecord *traceData) const
185    {
186        Fault fault = NoFault;
187
188        Addr EA;
189        %(op_decl)s;
190        %(op_rd)s;
191        %(ea_code)s;
192        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
193
194        %(code)s;
195
196        if(fault == NoFault)
197        {
198            fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
199                    EA, 0, 0);
200        }
201        if(fault == NoFault)
202        {
203            %(op_wb)s;
204        }
205
206        return fault;
207    }
208}};
209
210def template MicroStoreInitiateAcc {{
211    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
212            Trace::InstRecord * traceData) const
213    {
214        Fault fault = NoFault;
215
216        Addr EA;
217        %(op_decl)s;
218        %(op_rd)s;
219        %(ea_code)s;
220        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
221
222        %(code)s;
223
224        if(fault == NoFault)
225        {
226            fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
227                    EA, 0, 0);
228        }
229        if(fault == NoFault)
230        {
231            %(op_wb)s;
232        }
233        return fault;
234    }
235}};
236
237def template MicroStoreCompleteAcc {{
238    Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
239            Trace::InstRecord * traceData) const
240    {
241        return NoFault;
242    }
243}};
244
245// Common templates
246
247//This delcares the initiateAcc function in memory operations
248def template InitiateAccDeclare {{
249    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
250}};
251
252//This declares the completeAcc function in memory operations
253def template CompleteAccDeclare {{
254    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
255}};
256
257def template MicroLdStOpDeclare {{
258    class %(class_name)s : public %(base_class)s
259    {
260      protected:
261        void buildMe();
262
263      public:
264        %(class_name)s(ExtMachInst _machInst,
265                const char * instMnem,
266                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
267                uint8_t _scale, RegIndex _index, RegIndex _base,
268                uint64_t _disp, uint8_t _segment,
269                RegIndex _data,
270                uint8_t _dataSize, uint8_t _addressSize);
271
272        %(class_name)s(ExtMachInst _machInst,
273                const char * instMnem,
274                uint8_t _scale, RegIndex _index, RegIndex _base,
275                uint64_t _disp, uint8_t _segment,
276                RegIndex _data,
277                uint8_t _dataSize, uint8_t _addressSize);
278
279        %(BasicExecDeclare)s
280
281        %(InitiateAccDeclare)s
282
283        %(CompleteAccDeclare)s
284    };
285}};
286
287def template MicroLdStOpConstructor {{
288
289    inline void %(class_name)s::buildMe()
290    {
291        %(constructor)s;
292    }
293
294    inline %(class_name)s::%(class_name)s(
295            ExtMachInst machInst, const char * instMnem,
296            uint8_t _scale, RegIndex _index, RegIndex _base,
297            uint64_t _disp, uint8_t _segment,
298            RegIndex _data,
299            uint8_t _dataSize, uint8_t _addressSize) :
300        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
301                false, false, false, false,
302                _scale, _index, _base,
303                _disp, _segment, _data,
304                _dataSize, _addressSize, %(op_class)s)
305    {
306        buildMe();
307    }
308
309    inline %(class_name)s::%(class_name)s(
310            ExtMachInst machInst, const char * instMnem,
311            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
312            uint8_t _scale, RegIndex _index, RegIndex _base,
313            uint64_t _disp, uint8_t _segment,
314            RegIndex _data,
315            uint8_t _dataSize, uint8_t _addressSize) :
316        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
317                isMicro, isDelayed, isFirst, isLast,
318                _scale, _index, _base,
319                _disp, _segment, _data,
320                _dataSize, _addressSize, %(op_class)s)
321    {
322        buildMe();
323    }
324}};
325
326let {{
327    class LdStOp(X86Microop):
328        def __init__(self, data, segment, addr, disp):
329            self.data = data
330            [self.scale, self.index, self.base] = addr
331            self.disp = disp
332            self.segment = segment
333            self.dataSize = "env.dataSize"
334            self.addressSize = "env.addressSize"
335
336        def getAllocator(self, *microFlags):
337            allocator = '''new %(class_name)s(machInst, mnemonic
338                    %(flags)s, %(scale)s, %(index)s, %(base)s,
339                    %(disp)s, %(segment)s, %(data)s,
340                    %(dataSize)s, %(addressSize)s)''' % {
341                "class_name" : self.className,
342                "flags" : self.microFlagsText(microFlags),
343                "scale" : self.scale, "index" : self.index,
344                "base" : self.base,
345                "disp" : self.disp,
346                "segment" : self.segment, "data" : self.data,
347                "dataSize" : self.dataSize, "addressSize" : self.addressSize}
348            return allocator
349}};
350
351let {{
352
353    # Make these empty strings so that concatenating onto
354    # them will always work.
355    header_output = ""
356    decoder_output = ""
357    exec_output = ""
358
359    calculateEA = "EA = scale * Index + Base + disp;"
360
361    def defineMicroLoadOp(mnemonic, code):
362        global header_output
363        global decoder_output
364        global exec_output
365        global microopClasses
366        Name = mnemonic
367        name = mnemonic.lower()
368
369        # Build up the all register version of this micro op
370        iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
371                {"code": code, "ea_code": calculateEA})
372        header_output += MicroLdStOpDeclare.subst(iop)
373        decoder_output += MicroLdStOpConstructor.subst(iop)
374        exec_output += MicroLoadExecute.subst(iop)
375        exec_output += MicroLoadInitiateAcc.subst(iop)
376        exec_output += MicroLoadCompleteAcc.subst(iop)
377
378        class LoadOp(LdStOp):
379            def __init__(self, data, segment, addr, disp = 0):
380                super(LoadOp, self).__init__(data, segment, addr, disp)
381                self.className = Name
382                self.mnemonic = name
383
384        microopClasses[name] = LoadOp
385
386    defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
387
388    def defineMicroStoreOp(mnemonic, code):
389        global header_output
390        global decoder_output
391        global exec_output
392        global microopClasses
393        Name = mnemonic
394        name = mnemonic.lower()
395
396        # Build up the all register version of this micro op
397        iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
398                {"code": code, "ea_code": calculateEA})
399        header_output += MicroLdStOpDeclare.subst(iop)
400        decoder_output += MicroLdStOpConstructor.subst(iop)
401        exec_output += MicroStoreExecute.subst(iop)
402        exec_output += MicroStoreInitiateAcc.subst(iop)
403        exec_output += MicroStoreCompleteAcc.subst(iop)
404
405        class StoreOp(LdStOp):
406            def __init__(self, data, segment, addr, disp = 0):
407                super(LoadOp, self).__init__(data, segment, addr, disp)
408                self.className = Name
409                self.mnemonic = name
410
411        microopClasses[name] = StoreOp
412
413    defineMicroLoadOp('St', 'Mem = Data;')
414
415    iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
416            {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA})
417    header_output += MicroLeaDeclare.subst(iop)
418    decoder_output += MicroLdStOpConstructor.subst(iop)
419    exec_output += MicroLeaExecute.subst(iop)
420
421    class LeaOp(LdStOp):
422        def __init__(self, data, segment, addr, disp = 0):
423            super(LeaOp, self).__init__(data, segment, addr, disp)
424            self.className = "Lea"
425            self.mnemonic = "lea"
426
427    microopClasses["lea"] = LeaOp
428}};
429
430