ldstop.isa revision 4587:2c9a2534a489
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
63// Load templates
64
65output header {{
66    /**
67     * Base class for load and store ops
68     */
69    class LdStOp : public X86MicroopBase
70    {
71      protected:
72        const uint8_t scale;
73        const RegIndex index;
74        const RegIndex base;
75        const uint64_t disp;
76        const uint8_t segment;
77        const RegIndex data;
78        const uint8_t dataSize;
79        const uint8_t addressSize;
80
81        //Constructor
82        LdStOp(ExtMachInst _machInst,
83                const char * mnem, const char * _instMnem,
84                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
85                uint8_t _scale, RegIndex _index, RegIndex _base,
86                uint64_t _disp, uint8_t _segment,
87                RegIndex _data,
88                uint8_t _dataSize, uint8_t _addressSize,
89                OpClass __opClass) :
90        X86MicroopBase(machInst, mnem, _instMnem,
91                isMicro, isDelayed, isFirst, isLast, __opClass),
92                scale(_scale), index(_index), base(_base),
93                disp(_disp), segment(_segment),
94                data(_data),
95                dataSize(_dataSize), addressSize(_addressSize)
96        {}
97
98        std::string generateDisassembly(Addr pc,
99            const SymbolTable *symtab) const;
100    };
101}};
102
103output decoder {{
104    std::string LdStOp::generateDisassembly(Addr pc,
105            const SymbolTable *symtab) const
106    {
107        std::stringstream response;
108
109        printMnemonic(response, instMnem, mnemonic);
110        printReg(response, data);
111        response << ", ";
112        printSegment(response, segment);
113        ccprintf(response, ":[%d*", scale);
114        printReg(response, index);
115        response << " + ";
116        printReg(response, base);
117        ccprintf(response, " + %#x]", disp);
118        return response.str();
119    }
120}};
121
122def template MicroLoadExecute {{
123    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
124          Trace::InstRecord *traceData) const
125    {
126        Fault fault = NoFault;
127        Addr EA;
128
129        %(op_decl)s;
130        %(op_rd)s;
131        %(ea_code)s;
132        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
133
134        fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
135        if(fault == NoFault)
136        {
137            %(code)s;
138        }
139        if(fault == NoFault)
140        {
141            %(op_wb)s;
142        }
143
144        return fault;
145    }
146}};
147
148def template MicroLoadInitiateAcc {{
149    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
150            Trace::InstRecord * traceData) const
151    {
152        Fault fault = NoFault;
153        Addr EA;
154
155        %(op_decl)s;
156        %(op_rd)s;
157        %(ea_code)s;
158        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
159
160        fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
161
162        return fault;
163    }
164}};
165
166def template MicroLoadCompleteAcc {{
167    Fault %(class_name)s::completeAcc(PacketPtr pkt,
168            %(CPU_exec_context)s * xc,
169            Trace::InstRecord * traceData) const
170    {
171        Fault fault = NoFault;
172
173        %(op_decl)s;
174        %(op_rd)s;
175
176        Mem = pkt->get<typeof(Mem)>();
177        %(code)s;
178
179        if(fault == NoFault)
180        {
181            %(op_wb)s;
182        }
183
184        return fault;
185    }
186}};
187
188// Store templates
189
190def template MicroStoreExecute {{
191    Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
192            Trace::InstRecord *traceData) const
193    {
194        Fault fault = NoFault;
195
196        Addr EA;
197        %(op_decl)s;
198        %(op_rd)s;
199        %(ea_code)s;
200        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
201
202        %(code)s;
203
204        if(fault == NoFault)
205        {
206            fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
207                    EA, 0, 0);
208        }
209        if(fault == NoFault)
210        {
211            %(op_wb)s;
212        }
213
214        return fault;
215    }
216}};
217
218def template MicroStoreInitiateAcc {{
219    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
220            Trace::InstRecord * traceData) const
221    {
222        Fault fault = NoFault;
223
224        Addr EA;
225        %(op_decl)s;
226        %(op_rd)s;
227        %(ea_code)s;
228        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
229
230        %(code)s;
231
232        if(fault == NoFault)
233        {
234            fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
235                    EA, 0, 0);
236        }
237        if(fault == NoFault)
238        {
239            %(op_wb)s;
240        }
241        return fault;
242    }
243}};
244
245def template MicroStoreCompleteAcc {{
246    Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
247            Trace::InstRecord * traceData) const
248    {
249        return NoFault;
250    }
251}};
252
253// Common templates
254
255//This delcares the initiateAcc function in memory operations
256def template InitiateAccDeclare {{
257    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
258}};
259
260//This declares the completeAcc function in memory operations
261def template CompleteAccDeclare {{
262    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
263}};
264
265def template MicroLdStOpDeclare {{
266    class %(class_name)s : public %(base_class)s
267    {
268      protected:
269        void buildMe();
270
271      public:
272        %(class_name)s(ExtMachInst _machInst,
273                const char * instMnem,
274                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
275                uint8_t _scale, RegIndex _index, RegIndex _base,
276                uint64_t _disp, uint8_t _segment,
277                RegIndex _data,
278                uint8_t _dataSize, uint8_t _addressSize);
279
280        %(class_name)s(ExtMachInst _machInst,
281                const char * instMnem,
282                uint8_t _scale, RegIndex _index, RegIndex _base,
283                uint64_t _disp, uint8_t _segment,
284                RegIndex _data,
285                uint8_t _dataSize, uint8_t _addressSize);
286
287        %(BasicExecDeclare)s
288
289        %(InitiateAccDeclare)s
290
291        %(CompleteAccDeclare)s
292    };
293}};
294
295def template MicroLdStOpConstructor {{
296
297    inline void %(class_name)s::buildMe()
298    {
299        %(constructor)s;
300    }
301
302    inline %(class_name)s::%(class_name)s(
303            ExtMachInst machInst, const char * instMnem,
304            uint8_t _scale, RegIndex _index, RegIndex _base,
305            uint64_t _disp, uint8_t _segment,
306            RegIndex _data,
307            uint8_t _dataSize, uint8_t _addressSize) :
308        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
309                false, false, false, false,
310                _scale, _index, _base,
311                _disp, _segment, _data,
312                _dataSize, _addressSize, %(op_class)s)
313    {
314        buildMe();
315    }
316
317    inline %(class_name)s::%(class_name)s(
318            ExtMachInst machInst, const char * instMnem,
319            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
320            uint8_t _scale, RegIndex _index, RegIndex _base,
321            uint64_t _disp, uint8_t _segment,
322            RegIndex _data,
323            uint8_t _dataSize, uint8_t _addressSize) :
324        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
325                isMicro, isDelayed, isFirst, isLast,
326                _scale, _index, _base,
327                _disp, _segment, _data,
328                _dataSize, _addressSize, %(op_class)s)
329    {
330        buildMe();
331    }
332}};
333
334let {{
335    class LdStOp(X86Microop):
336        def __init__(self, data, segment, addr, disp):
337            self.data = data
338            [self.scale, self.index, self.base] = addr
339            self.disp = disp
340            self.segment = segment
341            self.dataSize = "env.dataSize"
342            self.addressSize = "env.addressSize"
343
344        def getAllocator(self, *microFlags):
345            allocator = '''new %(class_name)s(machInst, mnemonic
346                    %(flags)s, %(scale)s, %(index)s, %(base)s,
347                    %(disp)s, %(segment)s, %(data)s,
348                    %(dataSize)s, %(addressSize)s)''' % {
349                "class_name" : self.className,
350                "flags" : self.microFlagsText(microFlags),
351                "scale" : self.scale, "index" : self.index,
352                "base" : self.base,
353                "disp" : self.disp,
354                "segment" : self.segment, "data" : self.data,
355                "dataSize" : self.dataSize, "addressSize" : self.addressSize}
356            return allocator
357}};
358
359let {{
360
361    # Make these empty strings so that concatenating onto
362    # them will always work.
363    header_output = ""
364    decoder_output = ""
365    exec_output = ""
366
367    calculateEA = "EA = scale * Index + Base + disp;"
368
369    def defineMicroLoadOp(mnemonic, code):
370        global header_output
371        global decoder_output
372        global exec_output
373        global microopClasses
374        Name = mnemonic
375        name = mnemonic.lower()
376
377        # Build up the all register version of this micro op
378        iop = InstObjParams(name, Name, 'LdStOp',
379                {"code": code, "ea_code": calculateEA})
380        header_output += MicroLdStOpDeclare.subst(iop)
381        decoder_output += MicroLdStOpConstructor.subst(iop)
382        exec_output += MicroLoadExecute.subst(iop)
383        exec_output += MicroLoadInitiateAcc.subst(iop)
384        exec_output += MicroLoadCompleteAcc.subst(iop)
385
386        class LoadOp(LdStOp):
387            def __init__(self, data, segment, addr, disp = 0):
388                super(LoadOp, self).__init__(data, segment, addr, disp)
389                self.className = Name
390                self.mnemonic = name
391
392        microopClasses[name] = LoadOp
393
394    defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
395
396    def defineMicroStoreOp(mnemonic, code):
397        global header_output
398        global decoder_output
399        global exec_output
400        global microopClasses
401        Name = mnemonic
402        name = mnemonic.lower()
403
404        # Build up the all register version of this micro op
405        iop = InstObjParams(name, Name, 'LdStOp',
406                {"code": code, "ea_code": calculateEA})
407        header_output += MicroLdStOpDeclare.subst(iop)
408        decoder_output += MicroLdStOpConstructor.subst(iop)
409        exec_output += MicroStoreExecute.subst(iop)
410        exec_output += MicroStoreInitiateAcc.subst(iop)
411        exec_output += MicroStoreCompleteAcc.subst(iop)
412
413        class StoreOp(LdStOp):
414            def __init__(self, data, addr, segment):
415                super(LoadOp, self).__init__(data, addr, segment)
416                self.className = Name
417                self.mnemonic = name
418
419        microopClasses[name] = StoreOp
420
421    defineMicroLoadOp('St', 'Mem = Data;')
422}};
423
424