ldstop.isa revision 10184:bbfa3152bdea
16691Stjones1@inf.ed.ac.uk// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
26691Stjones1@inf.ed.ac.uk// All rights reserved.
36691Stjones1@inf.ed.ac.uk//
46691Stjones1@inf.ed.ac.uk// The license below extends only to copyright in the software and shall
56691Stjones1@inf.ed.ac.uk// not be construed as granting a license to any other intellectual
66691Stjones1@inf.ed.ac.uk// property including but not limited to intellectual property relating
76691Stjones1@inf.ed.ac.uk// to a hardware implementation of the functionality of the software
86691Stjones1@inf.ed.ac.uk// licensed hereunder.  You may use the software subject to the license
96691Stjones1@inf.ed.ac.uk// terms below provided that you ensure that this notice is replicated
106691Stjones1@inf.ed.ac.uk// unmodified and in its entirety in all distributions of the software,
116691Stjones1@inf.ed.ac.uk// modified or unmodified, in source code or in binary form.
126691Stjones1@inf.ed.ac.uk//
136691Stjones1@inf.ed.ac.uk// Copyright (c) 2008 The Regents of The University of Michigan
146691Stjones1@inf.ed.ac.uk// All rights reserved.
156691Stjones1@inf.ed.ac.uk//
166691Stjones1@inf.ed.ac.uk// Redistribution and use in source and binary forms, with or without
176691Stjones1@inf.ed.ac.uk// modification, are permitted provided that the following conditions are
186691Stjones1@inf.ed.ac.uk// met: redistributions of source code must retain the above copyright
196691Stjones1@inf.ed.ac.uk// notice, this list of conditions and the following disclaimer;
206691Stjones1@inf.ed.ac.uk// redistributions in binary form must reproduce the above copyright
216691Stjones1@inf.ed.ac.uk// notice, this list of conditions and the following disclaimer in the
226691Stjones1@inf.ed.ac.uk// documentation and/or other materials provided with the distribution;
236691Stjones1@inf.ed.ac.uk// neither the name of the copyright holders nor the names of its
246691Stjones1@inf.ed.ac.uk// contributors may be used to endorse or promote products derived from
256691Stjones1@inf.ed.ac.uk// this software without specific prior written permission.
266691Stjones1@inf.ed.ac.uk//
276691Stjones1@inf.ed.ac.uk// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
286691Stjones1@inf.ed.ac.uk// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
296691Stjones1@inf.ed.ac.uk// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
306691Stjones1@inf.ed.ac.uk// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
316691Stjones1@inf.ed.ac.uk// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
326691Stjones1@inf.ed.ac.uk// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
336691Stjones1@inf.ed.ac.uk// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
346691Stjones1@inf.ed.ac.uk// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
356691Stjones1@inf.ed.ac.uk// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
366691Stjones1@inf.ed.ac.uk// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
376691Stjones1@inf.ed.ac.uk// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
386691Stjones1@inf.ed.ac.uk//
396691Stjones1@inf.ed.ac.uk// Authors: Gabe Black
406691Stjones1@inf.ed.ac.uk
416691Stjones1@inf.ed.ac.uk//////////////////////////////////////////////////////////////////////////
426691Stjones1@inf.ed.ac.uk//
436691Stjones1@inf.ed.ac.uk// LdStOp Microop templates
446691Stjones1@inf.ed.ac.uk//
456691Stjones1@inf.ed.ac.uk//////////////////////////////////////////////////////////////////////////
466691Stjones1@inf.ed.ac.uk
476691Stjones1@inf.ed.ac.uk// LEA template
486691Stjones1@inf.ed.ac.uk
496691Stjones1@inf.ed.ac.ukdef template MicroLeaExecute {{
506691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
516691Stjones1@inf.ed.ac.uk          Trace::InstRecord *traceData) const
526691Stjones1@inf.ed.ac.uk    {
536691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
546691Stjones1@inf.ed.ac.uk        Addr EA;
556691Stjones1@inf.ed.ac.uk
566691Stjones1@inf.ed.ac.uk        %(op_decl)s;
576691Stjones1@inf.ed.ac.uk        %(op_rd)s;
586691Stjones1@inf.ed.ac.uk        %(ea_code)s;
596691Stjones1@inf.ed.ac.uk        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
606691Stjones1@inf.ed.ac.uk
616691Stjones1@inf.ed.ac.uk        %(code)s;
626691Stjones1@inf.ed.ac.uk        if(fault == NoFault)
636691Stjones1@inf.ed.ac.uk        {
646691Stjones1@inf.ed.ac.uk            %(op_wb)s;
656691Stjones1@inf.ed.ac.uk        }
666691Stjones1@inf.ed.ac.uk
676691Stjones1@inf.ed.ac.uk        return fault;
686691Stjones1@inf.ed.ac.uk    }
696691Stjones1@inf.ed.ac.uk}};
706691Stjones1@inf.ed.ac.uk
716691Stjones1@inf.ed.ac.ukdef template MicroLeaDeclare {{
726691Stjones1@inf.ed.ac.uk    class %(class_name)s : public %(base_class)s
736691Stjones1@inf.ed.ac.uk    {
746691Stjones1@inf.ed.ac.uk      public:
756691Stjones1@inf.ed.ac.uk        %(class_name)s(ExtMachInst _machInst,
766691Stjones1@inf.ed.ac.uk                const char * instMnem, uint64_t setFlags,
776691Stjones1@inf.ed.ac.uk                uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
786691Stjones1@inf.ed.ac.uk                uint64_t _disp, InstRegIndex _segment,
796691Stjones1@inf.ed.ac.uk                InstRegIndex _data,
806691Stjones1@inf.ed.ac.uk                uint8_t _dataSize, uint8_t _addressSize,
816691Stjones1@inf.ed.ac.uk                Request::FlagsType _memFlags);
826691Stjones1@inf.ed.ac.uk
836691Stjones1@inf.ed.ac.uk        %(BasicExecDeclare)s
846691Stjones1@inf.ed.ac.uk    };
856691Stjones1@inf.ed.ac.uk}};
866691Stjones1@inf.ed.ac.uk
876691Stjones1@inf.ed.ac.uk// Load templates
886691Stjones1@inf.ed.ac.uk
896691Stjones1@inf.ed.ac.ukdef template MicroLoadExecute {{
906691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
916691Stjones1@inf.ed.ac.uk          Trace::InstRecord *traceData) const
926691Stjones1@inf.ed.ac.uk    {
936691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
946691Stjones1@inf.ed.ac.uk        Addr EA;
956691Stjones1@inf.ed.ac.uk
966691Stjones1@inf.ed.ac.uk        %(op_decl)s;
976691Stjones1@inf.ed.ac.uk        %(op_rd)s;
986691Stjones1@inf.ed.ac.uk        %(ea_code)s;
996691Stjones1@inf.ed.ac.uk        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
1006691Stjones1@inf.ed.ac.uk
1016691Stjones1@inf.ed.ac.uk        fault = readMemAtomic(xc, traceData, EA, Mem, dataSize, memFlags);
1026691Stjones1@inf.ed.ac.uk
1036691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1046691Stjones1@inf.ed.ac.uk            %(code)s;
1056691Stjones1@inf.ed.ac.uk        } else if (memFlags & Request::PREFETCH) {
1066691Stjones1@inf.ed.ac.uk            // For prefetches, ignore any faults/exceptions.
1076691Stjones1@inf.ed.ac.uk            return NoFault;
1086691Stjones1@inf.ed.ac.uk        }
1096691Stjones1@inf.ed.ac.uk        if(fault == NoFault)
1106691Stjones1@inf.ed.ac.uk        {
1116691Stjones1@inf.ed.ac.uk            %(op_wb)s;
1126691Stjones1@inf.ed.ac.uk        }
1136691Stjones1@inf.ed.ac.uk
1146691Stjones1@inf.ed.ac.uk        return fault;
1156691Stjones1@inf.ed.ac.uk    }
1166691Stjones1@inf.ed.ac.uk}};
1176691Stjones1@inf.ed.ac.uk
1186691Stjones1@inf.ed.ac.ukdef template MicroLoadInitiateAcc {{
1196691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
1206691Stjones1@inf.ed.ac.uk            Trace::InstRecord * traceData) const
1216691Stjones1@inf.ed.ac.uk    {
1226691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1236691Stjones1@inf.ed.ac.uk        Addr EA;
1246691Stjones1@inf.ed.ac.uk
1256691Stjones1@inf.ed.ac.uk        %(op_decl)s;
1266691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1276691Stjones1@inf.ed.ac.uk        %(ea_code)s;
1286691Stjones1@inf.ed.ac.uk        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
1296691Stjones1@inf.ed.ac.uk
1306691Stjones1@inf.ed.ac.uk        fault = readMemTiming(xc, traceData, EA, Mem, dataSize, memFlags);
1316691Stjones1@inf.ed.ac.uk
1326691Stjones1@inf.ed.ac.uk        return fault;
1336691Stjones1@inf.ed.ac.uk    }
1346691Stjones1@inf.ed.ac.uk}};
1356691Stjones1@inf.ed.ac.uk
1366691Stjones1@inf.ed.ac.ukdef template MicroLoadCompleteAcc {{
1376691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::completeAcc(PacketPtr pkt,
1386691Stjones1@inf.ed.ac.uk            %(CPU_exec_context)s * xc,
1396691Stjones1@inf.ed.ac.uk            Trace::InstRecord * traceData) const
1406691Stjones1@inf.ed.ac.uk    {
1416691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1426691Stjones1@inf.ed.ac.uk
1436691Stjones1@inf.ed.ac.uk        %(op_decl)s;
1446691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1456691Stjones1@inf.ed.ac.uk
1466691Stjones1@inf.ed.ac.uk        Mem = getMem(pkt, dataSize, traceData);
1476691Stjones1@inf.ed.ac.uk
1486691Stjones1@inf.ed.ac.uk        %(code)s;
1496691Stjones1@inf.ed.ac.uk
1506691Stjones1@inf.ed.ac.uk        if(fault == NoFault)
1516691Stjones1@inf.ed.ac.uk        {
1526691Stjones1@inf.ed.ac.uk            %(op_wb)s;
1536691Stjones1@inf.ed.ac.uk        }
1546691Stjones1@inf.ed.ac.uk
1556691Stjones1@inf.ed.ac.uk        return fault;
1566691Stjones1@inf.ed.ac.uk    }
1576691Stjones1@inf.ed.ac.uk}};
1586691Stjones1@inf.ed.ac.uk
1596691Stjones1@inf.ed.ac.uk// Store templates
1606691Stjones1@inf.ed.ac.uk
1616691Stjones1@inf.ed.ac.ukdef template MicroStoreExecute {{
1626691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
1636691Stjones1@inf.ed.ac.uk            Trace::InstRecord *traceData) const
1646691Stjones1@inf.ed.ac.uk    {
1656691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1666691Stjones1@inf.ed.ac.uk
1676691Stjones1@inf.ed.ac.uk        Addr EA;
1686691Stjones1@inf.ed.ac.uk        %(op_decl)s;
1696691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1706691Stjones1@inf.ed.ac.uk        %(ea_code)s;
1716691Stjones1@inf.ed.ac.uk        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
1726691Stjones1@inf.ed.ac.uk
1736691Stjones1@inf.ed.ac.uk        %(code)s;
1746691Stjones1@inf.ed.ac.uk
1756691Stjones1@inf.ed.ac.uk        if(fault == NoFault)
1766691Stjones1@inf.ed.ac.uk        {
1776691Stjones1@inf.ed.ac.uk            fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA,
1786691Stjones1@inf.ed.ac.uk                    memFlags, NULL);
1796691Stjones1@inf.ed.ac.uk            if(fault == NoFault)
1806691Stjones1@inf.ed.ac.uk            {
1816691Stjones1@inf.ed.ac.uk                %(op_wb)s;
1826691Stjones1@inf.ed.ac.uk            }
1836691Stjones1@inf.ed.ac.uk        }
1846691Stjones1@inf.ed.ac.uk
1856691Stjones1@inf.ed.ac.uk        return fault;
1866691Stjones1@inf.ed.ac.uk    }
1876691Stjones1@inf.ed.ac.uk}};
1886691Stjones1@inf.ed.ac.uk
1896691Stjones1@inf.ed.ac.ukdef template MicroStoreInitiateAcc {{
1906691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
1916691Stjones1@inf.ed.ac.uk            Trace::InstRecord * traceData) const
1926691Stjones1@inf.ed.ac.uk    {
1936691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1946691Stjones1@inf.ed.ac.uk
1956691Stjones1@inf.ed.ac.uk        Addr EA;
1966691Stjones1@inf.ed.ac.uk        %(op_decl)s;
1976691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1986691Stjones1@inf.ed.ac.uk        %(ea_code)s;
1996691Stjones1@inf.ed.ac.uk        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
2006691Stjones1@inf.ed.ac.uk
2016691Stjones1@inf.ed.ac.uk        %(code)s;
2026691Stjones1@inf.ed.ac.uk
2036691Stjones1@inf.ed.ac.uk        if(fault == NoFault)
2046691Stjones1@inf.ed.ac.uk        {
2056691Stjones1@inf.ed.ac.uk            fault = writeMemTiming(xc, traceData, Mem, dataSize, EA,
2066691Stjones1@inf.ed.ac.uk                    memFlags, NULL);
2076691Stjones1@inf.ed.ac.uk        }
2086691Stjones1@inf.ed.ac.uk        return fault;
2096691Stjones1@inf.ed.ac.uk    }
2106691Stjones1@inf.ed.ac.uk}};
2116691Stjones1@inf.ed.ac.uk
2126691Stjones1@inf.ed.ac.ukdef template MicroStoreCompleteAcc {{
2136691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::completeAcc(PacketPtr pkt,
2146691Stjones1@inf.ed.ac.uk            %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const
2156691Stjones1@inf.ed.ac.uk    {
2166691Stjones1@inf.ed.ac.uk        %(op_decl)s;
2176691Stjones1@inf.ed.ac.uk        %(op_rd)s;
2186691Stjones1@inf.ed.ac.uk        %(complete_code)s;
2196691Stjones1@inf.ed.ac.uk        %(op_wb)s;
2206691Stjones1@inf.ed.ac.uk        return NoFault;
2216691Stjones1@inf.ed.ac.uk    }
2226691Stjones1@inf.ed.ac.uk}};
2236691Stjones1@inf.ed.ac.uk
2246691Stjones1@inf.ed.ac.uk// Common templates
2256691Stjones1@inf.ed.ac.uk
2266691Stjones1@inf.ed.ac.uk//This delcares the initiateAcc function in memory operations
2276691Stjones1@inf.ed.ac.ukdef template InitiateAccDeclare {{
2286691Stjones1@inf.ed.ac.uk    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
2296691Stjones1@inf.ed.ac.uk}};
2306691Stjones1@inf.ed.ac.uk
2316691Stjones1@inf.ed.ac.uk//This declares the completeAcc function in memory operations
2326691Stjones1@inf.ed.ac.ukdef template CompleteAccDeclare {{
2336691Stjones1@inf.ed.ac.uk    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
2346691Stjones1@inf.ed.ac.uk}};
2356691Stjones1@inf.ed.ac.uk
2366691Stjones1@inf.ed.ac.ukdef template MicroLdStOpDeclare {{
2376691Stjones1@inf.ed.ac.uk    class %(class_name)s : public %(base_class)s
2386691Stjones1@inf.ed.ac.uk    {
2396691Stjones1@inf.ed.ac.uk      public:
2406691Stjones1@inf.ed.ac.uk        %(class_name)s(ExtMachInst _machInst,
2416691Stjones1@inf.ed.ac.uk                const char * instMnem, uint64_t setFlags,
2426691Stjones1@inf.ed.ac.uk                uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
2436691Stjones1@inf.ed.ac.uk                uint64_t _disp, InstRegIndex _segment,
2446691Stjones1@inf.ed.ac.uk                InstRegIndex _data,
2456691Stjones1@inf.ed.ac.uk                uint8_t _dataSize, uint8_t _addressSize,
2466691Stjones1@inf.ed.ac.uk                Request::FlagsType _memFlags);
2476691Stjones1@inf.ed.ac.uk
2486691Stjones1@inf.ed.ac.uk        %(BasicExecDeclare)s
2496691Stjones1@inf.ed.ac.uk
2506691Stjones1@inf.ed.ac.uk        %(InitiateAccDeclare)s
2516691Stjones1@inf.ed.ac.uk
2526691Stjones1@inf.ed.ac.uk        %(CompleteAccDeclare)s
2536691Stjones1@inf.ed.ac.uk    };
2546691Stjones1@inf.ed.ac.uk}};
2556691Stjones1@inf.ed.ac.uk
2566691Stjones1@inf.ed.ac.ukdef template MicroLdStOpConstructor {{
2576691Stjones1@inf.ed.ac.uk    %(class_name)s::%(class_name)s(
2586691Stjones1@inf.ed.ac.uk            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
2596691Stjones1@inf.ed.ac.uk            uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
2606691Stjones1@inf.ed.ac.uk            uint64_t _disp, InstRegIndex _segment,
2616691Stjones1@inf.ed.ac.uk            InstRegIndex _data,
2626691Stjones1@inf.ed.ac.uk            uint8_t _dataSize, uint8_t _addressSize,
2636691Stjones1@inf.ed.ac.uk            Request::FlagsType _memFlags) :
2646691Stjones1@inf.ed.ac.uk        %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
2656691Stjones1@inf.ed.ac.uk                _scale, _index, _base,
2666691Stjones1@inf.ed.ac.uk                _disp, _segment, _data,
2676691Stjones1@inf.ed.ac.uk                _dataSize, _addressSize, _memFlags, %(op_class)s)
2686691Stjones1@inf.ed.ac.uk    {
2696701Sgblack@eecs.umich.edu        %(constructor)s;
2706691Stjones1@inf.ed.ac.uk    }
2716691Stjones1@inf.ed.ac.uk}};
2726701Sgblack@eecs.umich.edu
2736691Stjones1@inf.ed.ac.uklet {{
2746691Stjones1@inf.ed.ac.uk    class LdStOp(X86Microop):
2756691Stjones1@inf.ed.ac.uk        def __init__(self, data, segment, addr, disp,
2766691Stjones1@inf.ed.ac.uk                dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec):
2776691Stjones1@inf.ed.ac.uk            self.data = data
2786691Stjones1@inf.ed.ac.uk            [self.scale, self.index, self.base] = addr
2796691Stjones1@inf.ed.ac.uk            self.disp = disp
2806691Stjones1@inf.ed.ac.uk            self.segment = segment
2816691Stjones1@inf.ed.ac.uk            self.dataSize = dataSize
2826691Stjones1@inf.ed.ac.uk            self.addressSize = addressSize
2836691Stjones1@inf.ed.ac.uk            self.memFlags = baseFlags
2846691Stjones1@inf.ed.ac.uk            if atCPL0:
2856691Stjones1@inf.ed.ac.uk                self.memFlags += " | (CPL0FlagBit << FlagShift)"
2866691Stjones1@inf.ed.ac.uk            self.instFlags = ""
2876691Stjones1@inf.ed.ac.uk            if prefetch:
2886691Stjones1@inf.ed.ac.uk                self.memFlags += " | Request::PREFETCH"
289                self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
290            if nonSpec:
291                self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
292            self.memFlags += " | (machInst.legacy.addr ? " + \
293                             "(AddrSizeFlagBit << FlagShift) : 0)"
294
295        def getAllocator(self, microFlags):
296            allocator = '''new %(class_name)s(machInst, macrocodeBlock,
297                    %(flags)s, %(scale)s, %(index)s, %(base)s,
298                    %(disp)s, %(segment)s, %(data)s,
299                    %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
300                "class_name" : self.className,
301                "flags" : self.microFlagsText(microFlags) + self.instFlags,
302                "scale" : self.scale, "index" : self.index,
303                "base" : self.base,
304                "disp" : self.disp,
305                "segment" : self.segment, "data" : self.data,
306                "dataSize" : self.dataSize, "addressSize" : self.addressSize,
307                "memFlags" : self.memFlags}
308            return allocator
309
310    class BigLdStOp(X86Microop):
311        def __init__(self, data, segment, addr, disp,
312                dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec):
313            self.data = data
314            [self.scale, self.index, self.base] = addr
315            self.disp = disp
316            self.segment = segment
317            self.dataSize = dataSize
318            self.addressSize = addressSize
319            self.memFlags = baseFlags
320            if atCPL0:
321                self.memFlags += " | (CPL0FlagBit << FlagShift)"
322            self.instFlags = ""
323            if prefetch:
324                self.memFlags += " | Request::PREFETCH"
325                self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
326            if nonSpec:
327                self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
328            self.memFlags += " | (machInst.legacy.addr ? " + \
329                             "(AddrSizeFlagBit << FlagShift) : 0)"
330
331        def getAllocator(self, microFlags):
332            allocString = '''
333                (%(dataSize)s >= 4) ?
334                    (StaticInstPtr)(new %(class_name)sBig(machInst,
335                        macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
336                        %(base)s, %(disp)s, %(segment)s, %(data)s,
337                        %(dataSize)s, %(addressSize)s, %(memFlags)s)) :
338                    (StaticInstPtr)(new %(class_name)s(machInst,
339                        macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
340                        %(base)s, %(disp)s, %(segment)s, %(data)s,
341                        %(dataSize)s, %(addressSize)s, %(memFlags)s))
342            '''
343            allocator = allocString % {
344                "class_name" : self.className,
345                "flags" : self.microFlagsText(microFlags) + self.instFlags,
346                "scale" : self.scale, "index" : self.index,
347                "base" : self.base,
348                "disp" : self.disp,
349                "segment" : self.segment, "data" : self.data,
350                "dataSize" : self.dataSize, "addressSize" : self.addressSize,
351                "memFlags" : self.memFlags}
352            return allocator
353}};
354
355let {{
356
357    # Make these empty strings so that concatenating onto
358    # them will always work.
359    header_output = ""
360    decoder_output = ""
361    exec_output = ""
362
363    calculateEA = '''
364    EA = SegBase + bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
365    '''
366
367    def defineMicroLoadOp(mnemonic, code, bigCode='',
368                          mem_flags="0", big=True):
369        global header_output
370        global decoder_output
371        global exec_output
372        global microopClasses
373        Name = mnemonic
374        name = mnemonic.lower()
375
376        # Build up the all register version of this micro op
377        iops = [InstObjParams(name, Name, 'X86ISA::LdStOp',
378                {"code": code, "ea_code": calculateEA})]
379        if big:
380            iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp',
381                     {"code": bigCode, "ea_code": calculateEA})]
382        for iop in iops:
383            header_output += MicroLdStOpDeclare.subst(iop)
384            decoder_output += MicroLdStOpConstructor.subst(iop)
385            exec_output += MicroLoadExecute.subst(iop)
386            exec_output += MicroLoadInitiateAcc.subst(iop)
387            exec_output += MicroLoadCompleteAcc.subst(iop)
388
389        base = LdStOp
390        if big:
391            base = BigLdStOp
392        class LoadOp(base):
393            def __init__(self, data, segment, addr, disp = 0,
394                    dataSize="env.dataSize",
395                    addressSize="env.addressSize",
396                    atCPL0=False, prefetch=False, nonSpec=False):
397                super(LoadOp, self).__init__(data, segment, addr,
398                        disp, dataSize, addressSize, mem_flags,
399                        atCPL0, prefetch, nonSpec)
400                self.className = Name
401                self.mnemonic = name
402
403        microopClasses[name] = LoadOp
404
405    defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);',
406                            'Data = Mem & mask(dataSize * 8);')
407    defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
408                              'Data = Mem & mask(dataSize * 8);',
409                      '(StoreCheck << FlagShift)')
410    defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);',
411                               'Data = Mem & mask(dataSize * 8);',
412                      '(StoreCheck << FlagShift) | Request::LOCKED')
413
414    defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big = False)
415
416    defineMicroLoadOp('Ldfp87', code='''
417        switch (dataSize)
418        {
419          case 4:
420            FpData_df = *(float *)&Mem;
421            break;
422          case 8:
423            FpData_df = *(double *)&Mem;
424            break;
425          default:
426            panic("Unhandled data size in LdFp87.\\n");
427        }
428    ''', big = False)
429
430    def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"):
431        global header_output
432        global decoder_output
433        global exec_output
434        global microopClasses
435        Name = mnemonic
436        name = mnemonic.lower()
437
438        # Build up the all register version of this micro op
439        iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
440                {"code": code,
441                 "complete_code": completeCode,
442                 "ea_code": calculateEA})
443        header_output += MicroLdStOpDeclare.subst(iop)
444        decoder_output += MicroLdStOpConstructor.subst(iop)
445        exec_output += MicroStoreExecute.subst(iop)
446        exec_output += MicroStoreInitiateAcc.subst(iop)
447        exec_output += MicroStoreCompleteAcc.subst(iop)
448
449        class StoreOp(LdStOp):
450            def __init__(self, data, segment, addr, disp = 0,
451                    dataSize="env.dataSize",
452                    addressSize="env.addressSize",
453                    atCPL0=False, nonSpec=False):
454                super(StoreOp, self).__init__(data, segment, addr, disp,
455                        dataSize, addressSize, mem_flags, atCPL0, False,
456                        nonSpec)
457                self.className = Name
458                self.mnemonic = name
459
460        microopClasses[name] = StoreOp
461
462    defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
463    defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
464            mem_flags="Request::LOCKED")
465
466    defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;')
467
468    defineMicroStoreOp('Stfp87', code='''
469        switch (dataSize)
470        {
471          case 4: {
472            float single(FpData_df);
473            Mem = *(uint32_t *)&single;
474          } break;
475          case 8:
476            Mem = *(uint64_t *)&FpData_df;
477            break;
478          default:
479            panic("Unhandled data size in StFp87.\\n");
480        }
481    ''')
482
483    defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
484
485    iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
486            {"code": "Data = merge(Data, EA, dataSize);",
487             "ea_code": '''
488             EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
489             '''})
490    header_output += MicroLeaDeclare.subst(iop)
491    decoder_output += MicroLdStOpConstructor.subst(iop)
492    exec_output += MicroLeaExecute.subst(iop)
493
494    class LeaOp(LdStOp):
495        def __init__(self, data, segment, addr, disp = 0,
496                dataSize="env.dataSize", addressSize="env.addressSize"):
497            super(LeaOp, self).__init__(data, segment, addr, disp,
498                    dataSize, addressSize, "0", False, False, False)
499            self.className = "Lea"
500            self.mnemonic = "lea"
501
502    microopClasses["lea"] = LeaOp
503
504
505    iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
506            {"code": "xc->demapPage(EA, 0);",
507             "ea_code": calculateEA})
508    header_output += MicroLeaDeclare.subst(iop)
509    decoder_output += MicroLdStOpConstructor.subst(iop)
510    exec_output += MicroLeaExecute.subst(iop)
511
512    class TiaOp(LdStOp):
513        def __init__(self, segment, addr, disp = 0,
514                dataSize="env.dataSize",
515                addressSize="env.addressSize"):
516            super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
517                    addr, disp, dataSize, addressSize, "0", False, False,
518                    False)
519            self.className = "Tia"
520            self.mnemonic = "tia"
521
522    microopClasses["tia"] = TiaOp
523
524    class CdaOp(LdStOp):
525        def __init__(self, segment, addr, disp = 0,
526                dataSize="env.dataSize",
527                addressSize="env.addressSize", atCPL0=False):
528            super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
529                    addr, disp, dataSize, addressSize, "Request::NO_ACCESS",
530                    atCPL0, False, False)
531            self.className = "Cda"
532            self.mnemonic = "cda"
533
534    microopClasses["cda"] = CdaOp
535}};
536
537