17087Snate@binkert.org// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
211329Salexandru.dutu@amd.com// Copyright (c) 2015 Advanced Micro Devices, Inc.
37087Snate@binkert.org// All rights reserved.
47087Snate@binkert.org//
57087Snate@binkert.org// The license below extends only to copyright in the software and shall
67087Snate@binkert.org// not be construed as granting a license to any other intellectual
77087Snate@binkert.org// property including but not limited to intellectual property relating
87087Snate@binkert.org// to a hardware implementation of the functionality of the software
97087Snate@binkert.org// licensed hereunder.  You may use the software subject to the license
107087Snate@binkert.org// terms below provided that you ensure that this notice is replicated
117087Snate@binkert.org// unmodified and in its entirety in all distributions of the software,
127087Snate@binkert.org// modified or unmodified, in source code or in binary form.
137087Snate@binkert.org//
145359Sgblack@eecs.umich.edu// Copyright (c) 2008 The Regents of The University of Michigan
155359Sgblack@eecs.umich.edu// All rights reserved.
165359Sgblack@eecs.umich.edu//
175359Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
185359Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
195359Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
205359Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
215359Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
225359Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
235359Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
245359Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
255359Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
265359Sgblack@eecs.umich.edu// this software without specific prior written permission.
275359Sgblack@eecs.umich.edu//
285359Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
295359Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
305359Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
315359Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
325359Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
335359Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
345359Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
355359Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
365359Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
375359Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
385359Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
395359Sgblack@eecs.umich.edu//
405359Sgblack@eecs.umich.edu// Authors: Gabe Black
415359Sgblack@eecs.umich.edu
424561Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////////////
434561Sgblack@eecs.umich.edu//
444561Sgblack@eecs.umich.edu// LdStOp Microop templates
454561Sgblack@eecs.umich.edu//
464561Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////////////
474561Sgblack@eecs.umich.edu
484601Sgblack@eecs.umich.edu// LEA template
494601Sgblack@eecs.umich.edu
504601Sgblack@eecs.umich.edudef template MicroLeaExecute {{
5112234Sgabeblack@google.com    Fault %(class_name)s::execute(ExecContext *xc,
524601Sgblack@eecs.umich.edu          Trace::InstRecord *traceData) const
534601Sgblack@eecs.umich.edu    {
544601Sgblack@eecs.umich.edu        Fault fault = NoFault;
554601Sgblack@eecs.umich.edu        Addr EA;
564601Sgblack@eecs.umich.edu
574601Sgblack@eecs.umich.edu        %(op_decl)s;
584601Sgblack@eecs.umich.edu        %(op_rd)s;
594601Sgblack@eecs.umich.edu        %(ea_code)s;
604601Sgblack@eecs.umich.edu        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
614601Sgblack@eecs.umich.edu
624601Sgblack@eecs.umich.edu        %(code)s;
634601Sgblack@eecs.umich.edu        if(fault == NoFault)
644601Sgblack@eecs.umich.edu        {
654601Sgblack@eecs.umich.edu            %(op_wb)s;
664601Sgblack@eecs.umich.edu        }
674601Sgblack@eecs.umich.edu
684601Sgblack@eecs.umich.edu        return fault;
694601Sgblack@eecs.umich.edu    }
704601Sgblack@eecs.umich.edu}};
714601Sgblack@eecs.umich.edu
724601Sgblack@eecs.umich.edudef template MicroLeaDeclare {{
734601Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
744601Sgblack@eecs.umich.edu    {
754601Sgblack@eecs.umich.edu      public:
764601Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
777620Sgblack@eecs.umich.edu                const char * instMnem, uint64_t setFlags,
786345Sgblack@eecs.umich.edu                uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
796345Sgblack@eecs.umich.edu                uint64_t _disp, InstRegIndex _segment,
806345Sgblack@eecs.umich.edu                InstRegIndex _data,
815912Sgblack@eecs.umich.edu                uint8_t _dataSize, uint8_t _addressSize,
825912Sgblack@eecs.umich.edu                Request::FlagsType _memFlags);
834601Sgblack@eecs.umich.edu
8412236Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
854601Sgblack@eecs.umich.edu    };
864601Sgblack@eecs.umich.edu}};
874601Sgblack@eecs.umich.edu
884601Sgblack@eecs.umich.edu// Load templates
894601Sgblack@eecs.umich.edu
904587Sgblack@eecs.umich.edudef template MicroLoadExecute {{
9112234Sgabeblack@google.com    Fault %(class_name)s::execute(ExecContext *xc,
924587Sgblack@eecs.umich.edu          Trace::InstRecord *traceData) const
934587Sgblack@eecs.umich.edu    {
944587Sgblack@eecs.umich.edu        Fault fault = NoFault;
954587Sgblack@eecs.umich.edu        Addr EA;
964587Sgblack@eecs.umich.edu
974587Sgblack@eecs.umich.edu        %(op_decl)s;
984587Sgblack@eecs.umich.edu        %(op_rd)s;
994587Sgblack@eecs.umich.edu        %(ea_code)s;
1004587Sgblack@eecs.umich.edu        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
1014587Sgblack@eecs.umich.edu
10212384Sgabeblack@google.com        fault = readMemAtomic(xc, traceData, EA, Mem, dataSize, memFlags);
1034720Sgblack@eecs.umich.edu
1045920Sgblack@eecs.umich.edu        if (fault == NoFault) {
1054587Sgblack@eecs.umich.edu            %(code)s;
1066736Sgblack@eecs.umich.edu        } else if (memFlags & Request::PREFETCH) {
1075920Sgblack@eecs.umich.edu            // For prefetches, ignore any faults/exceptions.
1085920Sgblack@eecs.umich.edu            return NoFault;
1094587Sgblack@eecs.umich.edu        }
1104587Sgblack@eecs.umich.edu        if(fault == NoFault)
1114587Sgblack@eecs.umich.edu        {
1124587Sgblack@eecs.umich.edu            %(op_wb)s;
1134587Sgblack@eecs.umich.edu        }
1144587Sgblack@eecs.umich.edu
1154587Sgblack@eecs.umich.edu        return fault;
1164587Sgblack@eecs.umich.edu    }
1174587Sgblack@eecs.umich.edu}};
1184587Sgblack@eecs.umich.edu
1194587Sgblack@eecs.umich.edudef template MicroLoadInitiateAcc {{
12012234Sgabeblack@google.com    Fault %(class_name)s::initiateAcc(ExecContext * xc,
1214587Sgblack@eecs.umich.edu            Trace::InstRecord * traceData) const
1224587Sgblack@eecs.umich.edu    {
1234587Sgblack@eecs.umich.edu        Fault fault = NoFault;
1244587Sgblack@eecs.umich.edu        Addr EA;
1254587Sgblack@eecs.umich.edu
1264587Sgblack@eecs.umich.edu        %(op_decl)s;
1274587Sgblack@eecs.umich.edu        %(op_rd)s;
1284587Sgblack@eecs.umich.edu        %(ea_code)s;
1294587Sgblack@eecs.umich.edu        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
1304587Sgblack@eecs.umich.edu
13111329Salexandru.dutu@amd.com        fault = initiateMemRead(xc, traceData, EA,
13211329Salexandru.dutu@amd.com                                %(memDataSize)s, memFlags);
1334587Sgblack@eecs.umich.edu
1344587Sgblack@eecs.umich.edu        return fault;
1354587Sgblack@eecs.umich.edu    }
1364587Sgblack@eecs.umich.edu}};
1374587Sgblack@eecs.umich.edu
1384587Sgblack@eecs.umich.edudef template MicroLoadCompleteAcc {{
13912234Sgabeblack@google.com    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext * xc,
14012234Sgabeblack@google.com                                      Trace::InstRecord * traceData) const
1414587Sgblack@eecs.umich.edu    {
1424587Sgblack@eecs.umich.edu        Fault fault = NoFault;
1434587Sgblack@eecs.umich.edu
1444587Sgblack@eecs.umich.edu        %(op_decl)s;
1454587Sgblack@eecs.umich.edu        %(op_rd)s;
1464587Sgblack@eecs.umich.edu
14712384Sgabeblack@google.com        getMem(pkt, Mem, dataSize, traceData);
1485002Sgblack@eecs.umich.edu
1494587Sgblack@eecs.umich.edu        %(code)s;
1504587Sgblack@eecs.umich.edu
1514587Sgblack@eecs.umich.edu        if(fault == NoFault)
1524587Sgblack@eecs.umich.edu        {
1534587Sgblack@eecs.umich.edu            %(op_wb)s;
1544587Sgblack@eecs.umich.edu        }
1554587Sgblack@eecs.umich.edu
1564587Sgblack@eecs.umich.edu        return fault;
1574587Sgblack@eecs.umich.edu    }
1584587Sgblack@eecs.umich.edu}};
1594587Sgblack@eecs.umich.edu
1604587Sgblack@eecs.umich.edu// Store templates
1614587Sgblack@eecs.umich.edu
1624587Sgblack@eecs.umich.edudef template MicroStoreExecute {{
16312234Sgabeblack@google.com    Fault %(class_name)s::execute(ExecContext * xc,
1644587Sgblack@eecs.umich.edu            Trace::InstRecord *traceData) const
1654587Sgblack@eecs.umich.edu    {
1664587Sgblack@eecs.umich.edu        Fault fault = NoFault;
1674587Sgblack@eecs.umich.edu
1684587Sgblack@eecs.umich.edu        Addr EA;
1694587Sgblack@eecs.umich.edu        %(op_decl)s;
1704587Sgblack@eecs.umich.edu        %(op_rd)s;
1714587Sgblack@eecs.umich.edu        %(ea_code)s;
1724587Sgblack@eecs.umich.edu        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
1734587Sgblack@eecs.umich.edu
1744587Sgblack@eecs.umich.edu        %(code)s;
1754587Sgblack@eecs.umich.edu
17612384Sgabeblack@google.com        if (fault == NoFault) {
17712384Sgabeblack@google.com            fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA,
17812384Sgabeblack@google.com                                   memFlags, NULL);
17912384Sgabeblack@google.com            if (fault == NoFault) {
1804767Sgblack@eecs.umich.edu                %(op_wb)s;
1814720Sgblack@eecs.umich.edu            }
1824587Sgblack@eecs.umich.edu        }
1834587Sgblack@eecs.umich.edu
1844587Sgblack@eecs.umich.edu        return fault;
1854587Sgblack@eecs.umich.edu    }
1864587Sgblack@eecs.umich.edu}};
1874587Sgblack@eecs.umich.edu
1884587Sgblack@eecs.umich.edudef template MicroStoreInitiateAcc {{
18912234Sgabeblack@google.com    Fault %(class_name)s::initiateAcc(ExecContext * xc,
1904587Sgblack@eecs.umich.edu            Trace::InstRecord * traceData) const
1914587Sgblack@eecs.umich.edu    {
1924587Sgblack@eecs.umich.edu        Fault fault = NoFault;
1934587Sgblack@eecs.umich.edu
1944587Sgblack@eecs.umich.edu        Addr EA;
1954587Sgblack@eecs.umich.edu        %(op_decl)s;
1964587Sgblack@eecs.umich.edu        %(op_rd)s;
1974587Sgblack@eecs.umich.edu        %(ea_code)s;
1984587Sgblack@eecs.umich.edu        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
1994587Sgblack@eecs.umich.edu
2004587Sgblack@eecs.umich.edu        %(code)s;
2014587Sgblack@eecs.umich.edu
20212384Sgabeblack@google.com        if (fault == NoFault) {
20312384Sgabeblack@google.com            fault = writeMemTiming(xc, traceData, Mem, dataSize, EA,
20412384Sgabeblack@google.com                                   memFlags, NULL);
2054587Sgblack@eecs.umich.edu        }
2064587Sgblack@eecs.umich.edu        return fault;
2074587Sgblack@eecs.umich.edu    }
2084587Sgblack@eecs.umich.edu}};
2094587Sgblack@eecs.umich.edu
2104587Sgblack@eecs.umich.edudef template MicroStoreCompleteAcc {{
2115892Sgblack@eecs.umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
21212234Sgabeblack@google.com            ExecContext * xc, Trace::InstRecord * traceData) const
2134587Sgblack@eecs.umich.edu    {
2145892Sgblack@eecs.umich.edu        %(op_decl)s;
2155892Sgblack@eecs.umich.edu        %(op_rd)s;
2165892Sgblack@eecs.umich.edu        %(complete_code)s;
2175892Sgblack@eecs.umich.edu        %(op_wb)s;
2184587Sgblack@eecs.umich.edu        return NoFault;
2194587Sgblack@eecs.umich.edu    }
2204587Sgblack@eecs.umich.edu}};
2214587Sgblack@eecs.umich.edu
2224587Sgblack@eecs.umich.edudef template MicroLdStOpDeclare {{
2234587Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
2244587Sgblack@eecs.umich.edu    {
2254561Sgblack@eecs.umich.edu      public:
2264561Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst _machInst,
2277620Sgblack@eecs.umich.edu                const char * instMnem, uint64_t setFlags,
2286345Sgblack@eecs.umich.edu                uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
2296345Sgblack@eecs.umich.edu                uint64_t _disp, InstRegIndex _segment,
2306345Sgblack@eecs.umich.edu                InstRegIndex _data,
2315912Sgblack@eecs.umich.edu                uint8_t _dataSize, uint8_t _addressSize,
2325912Sgblack@eecs.umich.edu                Request::FlagsType _memFlags);
2334561Sgblack@eecs.umich.edu
23412236Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
23512236Sgabeblack@google.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
23612236Sgabeblack@google.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
2374561Sgblack@eecs.umich.edu    };
2384561Sgblack@eecs.umich.edu}};
2394561Sgblack@eecs.umich.edu
24011329Salexandru.dutu@amd.com// LdStSplitOp is a load or store that uses a pair of regs as the
24111329Salexandru.dutu@amd.com// source or destination.  Used for cmpxchg{8,16}b.
24211329Salexandru.dutu@amd.comdef template MicroLdStSplitOpDeclare {{
24311329Salexandru.dutu@amd.com    class %(class_name)s : public %(base_class)s
24411329Salexandru.dutu@amd.com    {
24511329Salexandru.dutu@amd.com      public:
24611329Salexandru.dutu@amd.com        %(class_name)s(ExtMachInst _machInst,
24711329Salexandru.dutu@amd.com                const char * instMnem, uint64_t setFlags,
24811329Salexandru.dutu@amd.com                uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
24911329Salexandru.dutu@amd.com                uint64_t _disp, InstRegIndex _segment,
25011329Salexandru.dutu@amd.com                InstRegIndex _dataLow, InstRegIndex _dataHi,
25111329Salexandru.dutu@amd.com                uint8_t _dataSize, uint8_t _addressSize,
25211329Salexandru.dutu@amd.com                Request::FlagsType _memFlags);
25311329Salexandru.dutu@amd.com
25412236Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
25512236Sgabeblack@google.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
25612236Sgabeblack@google.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
25711329Salexandru.dutu@amd.com    };
25811329Salexandru.dutu@amd.com}};
25911329Salexandru.dutu@amd.com
2604561Sgblack@eecs.umich.edudef template MicroLdStOpConstructor {{
26110184SCurtis.Dunham@arm.com    %(class_name)s::%(class_name)s(
2627620Sgblack@eecs.umich.edu            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
2636345Sgblack@eecs.umich.edu            uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
2646345Sgblack@eecs.umich.edu            uint64_t _disp, InstRegIndex _segment,
2656345Sgblack@eecs.umich.edu            InstRegIndex _data,
2665912Sgblack@eecs.umich.edu            uint8_t _dataSize, uint8_t _addressSize,
2675912Sgblack@eecs.umich.edu            Request::FlagsType _memFlags) :
2687620Sgblack@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
2694587Sgblack@eecs.umich.edu                _scale, _index, _base,
2704587Sgblack@eecs.umich.edu                _disp, _segment, _data,
2715912Sgblack@eecs.umich.edu                _dataSize, _addressSize, _memFlags, %(op_class)s)
2724561Sgblack@eecs.umich.edu    {
2737626Sgblack@eecs.umich.edu        %(constructor)s;
2744561Sgblack@eecs.umich.edu    }
2754561Sgblack@eecs.umich.edu}};
2764561Sgblack@eecs.umich.edu
27711329Salexandru.dutu@amd.comdef template MicroLdStSplitOpConstructor {{
27811329Salexandru.dutu@amd.com    %(class_name)s::%(class_name)s(
27911329Salexandru.dutu@amd.com            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
28011329Salexandru.dutu@amd.com            uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
28111329Salexandru.dutu@amd.com            uint64_t _disp, InstRegIndex _segment,
28211329Salexandru.dutu@amd.com            InstRegIndex _dataLow, InstRegIndex _dataHi,
28311329Salexandru.dutu@amd.com            uint8_t _dataSize, uint8_t _addressSize,
28411329Salexandru.dutu@amd.com            Request::FlagsType _memFlags) :
28511329Salexandru.dutu@amd.com        %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
28611329Salexandru.dutu@amd.com                _scale, _index, _base,
28711329Salexandru.dutu@amd.com                _disp, _segment, _dataLow, _dataHi,
28811329Salexandru.dutu@amd.com                _dataSize, _addressSize, _memFlags, %(op_class)s)
28911329Salexandru.dutu@amd.com    {
29011329Salexandru.dutu@amd.com        %(constructor)s;
29111329Salexandru.dutu@amd.com    }
29211329Salexandru.dutu@amd.com}};
29311329Salexandru.dutu@amd.com
2944587Sgblack@eecs.umich.edulet {{
2954587Sgblack@eecs.umich.edu    class LdStOp(X86Microop):
2965912Sgblack@eecs.umich.edu        def __init__(self, data, segment, addr, disp,
29711829Sjason@lowepower.com                dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
29812682Sgabeblack@google.com                implicitStack, uncacheable):
2994587Sgblack@eecs.umich.edu            self.data = data
3004587Sgblack@eecs.umich.edu            [self.scale, self.index, self.base] = addr
3014587Sgblack@eecs.umich.edu            self.disp = disp
3024587Sgblack@eecs.umich.edu            self.segment = segment
3034712Sgblack@eecs.umich.edu            self.dataSize = dataSize
3045149Sgblack@eecs.umich.edu            self.addressSize = addressSize
3055912Sgblack@eecs.umich.edu            self.memFlags = baseFlags
3065912Sgblack@eecs.umich.edu            if atCPL0:
3075912Sgblack@eecs.umich.edu                self.memFlags += " | (CPL0FlagBit << FlagShift)"
3088102Sgblack@eecs.umich.edu            self.instFlags = ""
3095920Sgblack@eecs.umich.edu            if prefetch:
3106736Sgblack@eecs.umich.edu                self.memFlags += " | Request::PREFETCH"
3118103Sgblack@eecs.umich.edu                self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
3128103Sgblack@eecs.umich.edu            if nonSpec:
3138103Sgblack@eecs.umich.edu                self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
31412682Sgabeblack@google.com            if uncacheable:
31512682Sgabeblack@google.com                self.instFlags += " | (Request::UNCACHEABLE)"
31611829Sjason@lowepower.com            # For implicit stack operations, we should use *not* use the
31711829Sjason@lowepower.com            # alternative addressing mode for loads/stores if the prefix is set
31811829Sjason@lowepower.com            if not implicitStack:
31911829Sjason@lowepower.com                self.memFlags += " | (machInst.legacy.addr ? " + \
32011829Sjason@lowepower.com                                 "(AddrSizeFlagBit << FlagShift) : 0)"
3214587Sgblack@eecs.umich.edu
3227620Sgblack@eecs.umich.edu        def getAllocator(self, microFlags):
3237620Sgblack@eecs.umich.edu            allocator = '''new %(class_name)s(machInst, macrocodeBlock,
3244587Sgblack@eecs.umich.edu                    %(flags)s, %(scale)s, %(index)s, %(base)s,
3254587Sgblack@eecs.umich.edu                    %(disp)s, %(segment)s, %(data)s,
3265912Sgblack@eecs.umich.edu                    %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
3274587Sgblack@eecs.umich.edu                "class_name" : self.className,
3288102Sgblack@eecs.umich.edu                "flags" : self.microFlagsText(microFlags) + self.instFlags,
3294587Sgblack@eecs.umich.edu                "scale" : self.scale, "index" : self.index,
3304587Sgblack@eecs.umich.edu                "base" : self.base,
3314587Sgblack@eecs.umich.edu                "disp" : self.disp,
3324587Sgblack@eecs.umich.edu                "segment" : self.segment, "data" : self.data,
3335912Sgblack@eecs.umich.edu                "dataSize" : self.dataSize, "addressSize" : self.addressSize,
3345912Sgblack@eecs.umich.edu                "memFlags" : self.memFlags}
3354587Sgblack@eecs.umich.edu            return allocator
3367967Sgblack@eecs.umich.edu
3377967Sgblack@eecs.umich.edu    class BigLdStOp(X86Microop):
3387967Sgblack@eecs.umich.edu        def __init__(self, data, segment, addr, disp,
33911829Sjason@lowepower.com                dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
34012682Sgabeblack@google.com                implicitStack, uncacheable):
3417967Sgblack@eecs.umich.edu            self.data = data
3427967Sgblack@eecs.umich.edu            [self.scale, self.index, self.base] = addr
3437967Sgblack@eecs.umich.edu            self.disp = disp
3447967Sgblack@eecs.umich.edu            self.segment = segment
3457967Sgblack@eecs.umich.edu            self.dataSize = dataSize
3467967Sgblack@eecs.umich.edu            self.addressSize = addressSize
3477967Sgblack@eecs.umich.edu            self.memFlags = baseFlags
3487967Sgblack@eecs.umich.edu            if atCPL0:
3497967Sgblack@eecs.umich.edu                self.memFlags += " | (CPL0FlagBit << FlagShift)"
3508103Sgblack@eecs.umich.edu            self.instFlags = ""
3517967Sgblack@eecs.umich.edu            if prefetch:
3527967Sgblack@eecs.umich.edu                self.memFlags += " | Request::PREFETCH"
3538103Sgblack@eecs.umich.edu                self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
3548103Sgblack@eecs.umich.edu            if nonSpec:
3558103Sgblack@eecs.umich.edu                self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
35612682Sgabeblack@google.com            if uncacheable:
35712682Sgabeblack@google.com                self.instFlags += " | (Request::UNCACHEABLE)"
35811829Sjason@lowepower.com            # For implicit stack operations, we should use *not* use the
35911829Sjason@lowepower.com            # alternative addressing mode for loads/stores if the prefix is set
36011829Sjason@lowepower.com            if not implicitStack:
36111829Sjason@lowepower.com                self.memFlags += " | (machInst.legacy.addr ? " + \
36211829Sjason@lowepower.com                                 "(AddrSizeFlagBit << FlagShift) : 0)"
3637967Sgblack@eecs.umich.edu
3647967Sgblack@eecs.umich.edu        def getAllocator(self, microFlags):
3657967Sgblack@eecs.umich.edu            allocString = '''
3667967Sgblack@eecs.umich.edu                (%(dataSize)s >= 4) ?
3677967Sgblack@eecs.umich.edu                    (StaticInstPtr)(new %(class_name)sBig(machInst,
3687967Sgblack@eecs.umich.edu                        macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
3697967Sgblack@eecs.umich.edu                        %(base)s, %(disp)s, %(segment)s, %(data)s,
3707967Sgblack@eecs.umich.edu                        %(dataSize)s, %(addressSize)s, %(memFlags)s)) :
3717967Sgblack@eecs.umich.edu                    (StaticInstPtr)(new %(class_name)s(machInst,
3727967Sgblack@eecs.umich.edu                        macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
3737967Sgblack@eecs.umich.edu                        %(base)s, %(disp)s, %(segment)s, %(data)s,
3747967Sgblack@eecs.umich.edu                        %(dataSize)s, %(addressSize)s, %(memFlags)s))
3757967Sgblack@eecs.umich.edu            '''
3767967Sgblack@eecs.umich.edu            allocator = allocString % {
3777967Sgblack@eecs.umich.edu                "class_name" : self.className,
3788103Sgblack@eecs.umich.edu                "flags" : self.microFlagsText(microFlags) + self.instFlags,
3797967Sgblack@eecs.umich.edu                "scale" : self.scale, "index" : self.index,
3807967Sgblack@eecs.umich.edu                "base" : self.base,
3817967Sgblack@eecs.umich.edu                "disp" : self.disp,
3827967Sgblack@eecs.umich.edu                "segment" : self.segment, "data" : self.data,
3837967Sgblack@eecs.umich.edu                "dataSize" : self.dataSize, "addressSize" : self.addressSize,
3847967Sgblack@eecs.umich.edu                "memFlags" : self.memFlags}
3857967Sgblack@eecs.umich.edu            return allocator
38611329Salexandru.dutu@amd.com
38711329Salexandru.dutu@amd.com    class LdStSplitOp(LdStOp):
38811329Salexandru.dutu@amd.com        def __init__(self, data, segment, addr, disp,
38911829Sjason@lowepower.com                dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
39012682Sgabeblack@google.com                implicitStack, uncacheable):
39111329Salexandru.dutu@amd.com            super(LdStSplitOp, self).__init__(0, segment, addr, disp,
39211829Sjason@lowepower.com                dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
39312682Sgabeblack@google.com                implicitStack, uncacheable)
39411329Salexandru.dutu@amd.com            (self.dataLow, self.dataHi) = data
39511329Salexandru.dutu@amd.com
39611329Salexandru.dutu@amd.com        def getAllocator(self, microFlags):
39711329Salexandru.dutu@amd.com            allocString = '''(StaticInstPtr)(new %(class_name)s(machInst,
39811329Salexandru.dutu@amd.com                        macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
39911329Salexandru.dutu@amd.com                        %(base)s, %(disp)s, %(segment)s,
40011329Salexandru.dutu@amd.com                        %(dataLow)s, %(dataHi)s,
40111329Salexandru.dutu@amd.com                        %(dataSize)s, %(addressSize)s, %(memFlags)s))
40211329Salexandru.dutu@amd.com            '''
40311329Salexandru.dutu@amd.com            allocator = allocString % {
40411329Salexandru.dutu@amd.com                "class_name" : self.className,
40511329Salexandru.dutu@amd.com                "flags" : self.microFlagsText(microFlags) + self.instFlags,
40611329Salexandru.dutu@amd.com                "scale" : self.scale, "index" : self.index,
40711329Salexandru.dutu@amd.com                "base" : self.base,
40811329Salexandru.dutu@amd.com                "disp" : self.disp,
40911329Salexandru.dutu@amd.com                "segment" : self.segment,
41011329Salexandru.dutu@amd.com                "dataLow" : self.dataLow, "dataHi" : self.dataHi,
41111329Salexandru.dutu@amd.com                "dataSize" : self.dataSize, "addressSize" : self.addressSize,
41211329Salexandru.dutu@amd.com                "memFlags" : self.memFlags}
41311329Salexandru.dutu@amd.com            return allocator
41411329Salexandru.dutu@amd.com
4154587Sgblack@eecs.umich.edu}};
4164587Sgblack@eecs.umich.edu
4174587Sgblack@eecs.umich.edulet {{
4184587Sgblack@eecs.umich.edu
4194587Sgblack@eecs.umich.edu    # Make these empty strings so that concatenating onto
4204587Sgblack@eecs.umich.edu    # them will always work.
4214587Sgblack@eecs.umich.edu    header_output = ""
4224587Sgblack@eecs.umich.edu    decoder_output = ""
4234587Sgblack@eecs.umich.edu    exec_output = ""
4244587Sgblack@eecs.umich.edu
42511329Salexandru.dutu@amd.com    segmentEAExpr = \
42611329Salexandru.dutu@amd.com        'bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);'
42711329Salexandru.dutu@amd.com
42811329Salexandru.dutu@amd.com    calculateEA = 'EA = SegBase + ' + segmentEAExpr
4294587Sgblack@eecs.umich.edu
4307967Sgblack@eecs.umich.edu    def defineMicroLoadOp(mnemonic, code, bigCode='',
43111829Sjason@lowepower.com                          mem_flags="0", big=True, nonSpec=False,
43211829Sjason@lowepower.com                          implicitStack=False):
4334587Sgblack@eecs.umich.edu        global header_output
4344587Sgblack@eecs.umich.edu        global decoder_output
4354587Sgblack@eecs.umich.edu        global exec_output
4364587Sgblack@eecs.umich.edu        global microopClasses
4374587Sgblack@eecs.umich.edu        Name = mnemonic
4384587Sgblack@eecs.umich.edu        name = mnemonic.lower()
4394587Sgblack@eecs.umich.edu
4404587Sgblack@eecs.umich.edu        # Build up the all register version of this micro op
4417967Sgblack@eecs.umich.edu        iops = [InstObjParams(name, Name, 'X86ISA::LdStOp',
44211329Salexandru.dutu@amd.com                              { "code": code,
44311329Salexandru.dutu@amd.com                                "ea_code": calculateEA,
44411329Salexandru.dutu@amd.com                                "memDataSize": "dataSize" })]
4457967Sgblack@eecs.umich.edu        if big:
4467967Sgblack@eecs.umich.edu            iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp',
44711329Salexandru.dutu@amd.com                                   { "code": bigCode,
44811329Salexandru.dutu@amd.com                                     "ea_code": calculateEA,
44911329Salexandru.dutu@amd.com                                     "memDataSize": "dataSize" })]
4507967Sgblack@eecs.umich.edu        for iop in iops:
4517967Sgblack@eecs.umich.edu            header_output += MicroLdStOpDeclare.subst(iop)
4527967Sgblack@eecs.umich.edu            decoder_output += MicroLdStOpConstructor.subst(iop)
4537967Sgblack@eecs.umich.edu            exec_output += MicroLoadExecute.subst(iop)
4547967Sgblack@eecs.umich.edu            exec_output += MicroLoadInitiateAcc.subst(iop)
4557967Sgblack@eecs.umich.edu            exec_output += MicroLoadCompleteAcc.subst(iop)
4564587Sgblack@eecs.umich.edu
45711829Sjason@lowepower.com        if implicitStack:
45811829Sjason@lowepower.com            # For instructions that implicitly access the stack, the address
45911829Sjason@lowepower.com            # size is the same as the stack segment pointer size, not the
46011829Sjason@lowepower.com            # address size if specified by the instruction prefix
46111829Sjason@lowepower.com            addressSize = "env.stackSize"
46211829Sjason@lowepower.com        else:
46311829Sjason@lowepower.com            addressSize = "env.addressSize"
46411829Sjason@lowepower.com
4657967Sgblack@eecs.umich.edu        base = LdStOp
4667967Sgblack@eecs.umich.edu        if big:
4677967Sgblack@eecs.umich.edu            base = BigLdStOp
4687967Sgblack@eecs.umich.edu        class LoadOp(base):
4695149Sgblack@eecs.umich.edu            def __init__(self, data, segment, addr, disp = 0,
4705912Sgblack@eecs.umich.edu                    dataSize="env.dataSize",
47111829Sjason@lowepower.com                    addressSize=addressSize,
47211829Sjason@lowepower.com                    atCPL0=False, prefetch=False, nonSpec=nonSpec,
47312682Sgabeblack@google.com                    implicitStack=implicitStack, uncacheable=False):
4745912Sgblack@eecs.umich.edu                super(LoadOp, self).__init__(data, segment, addr,
4755920Sgblack@eecs.umich.edu                        disp, dataSize, addressSize, mem_flags,
47612682Sgabeblack@google.com                        atCPL0, prefetch, nonSpec, implicitStack, uncacheable)
4774587Sgblack@eecs.umich.edu                self.className = Name
4784587Sgblack@eecs.umich.edu                self.mnemonic = name
4794587Sgblack@eecs.umich.edu
4804587Sgblack@eecs.umich.edu        microopClasses[name] = LoadOp
4814587Sgblack@eecs.umich.edu
4827967Sgblack@eecs.umich.edu    defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);',
4837967Sgblack@eecs.umich.edu                            'Data = Mem & mask(dataSize * 8);')
48411829Sjason@lowepower.com    defineMicroLoadOp('Ldis', 'Data = merge(Data, Mem, dataSize);',
48511829Sjason@lowepower.com                              'Data = Mem & mask(dataSize * 8);',
48611829Sjason@lowepower.com                               implicitStack=True)
4875912Sgblack@eecs.umich.edu    defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
4887967Sgblack@eecs.umich.edu                              'Data = Mem & mask(dataSize * 8);',
4897967Sgblack@eecs.umich.edu                      '(StoreCheck << FlagShift)')
4906079Sgblack@eecs.umich.edu    defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);',
4917967Sgblack@eecs.umich.edu                               'Data = Mem & mask(dataSize * 8);',
49211329Salexandru.dutu@amd.com                      '(StoreCheck << FlagShift) | Request::LOCKED_RMW',
49311329Salexandru.dutu@amd.com                      nonSpec=True)
4949894Sandreas@sandberg.pp.se
4959894Sandreas@sandberg.pp.se    defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big = False)
4969894Sandreas@sandberg.pp.se
4979894Sandreas@sandberg.pp.se    defineMicroLoadOp('Ldfp87', code='''
4989894Sandreas@sandberg.pp.se        switch (dataSize)
4999894Sandreas@sandberg.pp.se        {
5009894Sandreas@sandberg.pp.se          case 4:
5019894Sandreas@sandberg.pp.se            FpData_df = *(float *)&Mem;
5029894Sandreas@sandberg.pp.se            break;
5039894Sandreas@sandberg.pp.se          case 8:
5049894Sandreas@sandberg.pp.se            FpData_df = *(double *)&Mem;
5059894Sandreas@sandberg.pp.se            break;
5069894Sandreas@sandberg.pp.se          default:
5079894Sandreas@sandberg.pp.se            panic("Unhandled data size in LdFp87.\\n");
5089894Sandreas@sandberg.pp.se        }
5099894Sandreas@sandberg.pp.se    ''', big = False)
5104587Sgblack@eecs.umich.edu
51111159Ssteve.reinhardt@amd.com    # Load integer from memory into x87 top-of-stack register.
51211159Ssteve.reinhardt@amd.com    # Used to implement fild instruction.
51311159Ssteve.reinhardt@amd.com    defineMicroLoadOp('Ldifp87', code='''
51411159Ssteve.reinhardt@amd.com        switch (dataSize)
51511159Ssteve.reinhardt@amd.com        {
51611159Ssteve.reinhardt@amd.com          case 2:
51711159Ssteve.reinhardt@amd.com            FpData_df = (int64_t)sext<16>(Mem);
51811159Ssteve.reinhardt@amd.com            break;
51911159Ssteve.reinhardt@amd.com          case 4:
52011159Ssteve.reinhardt@amd.com            FpData_df = (int64_t)sext<32>(Mem);
52111159Ssteve.reinhardt@amd.com            break;
52211159Ssteve.reinhardt@amd.com          case 8:
52311159Ssteve.reinhardt@amd.com            FpData_df = (int64_t)Mem;
52411159Ssteve.reinhardt@amd.com            break;
52511159Ssteve.reinhardt@amd.com          default:
52611159Ssteve.reinhardt@amd.com            panic("Unhandled data size in LdIFp87.\\n");
52711159Ssteve.reinhardt@amd.com        }
52811159Ssteve.reinhardt@amd.com    ''', big = False)
52911159Ssteve.reinhardt@amd.com
53011329Salexandru.dutu@amd.com    def defineMicroLoadSplitOp(mnemonic, code, mem_flags="0", nonSpec=False):
53111329Salexandru.dutu@amd.com        global header_output
53211329Salexandru.dutu@amd.com        global decoder_output
53311329Salexandru.dutu@amd.com        global exec_output
53411329Salexandru.dutu@amd.com        global microopClasses
53511329Salexandru.dutu@amd.com        Name = mnemonic
53611329Salexandru.dutu@amd.com        name = mnemonic.lower()
53711329Salexandru.dutu@amd.com
53811329Salexandru.dutu@amd.com        iop = InstObjParams(name, Name, 'X86ISA::LdStSplitOp',
53911329Salexandru.dutu@amd.com                            { "code": code,
54011329Salexandru.dutu@amd.com                              "ea_code": calculateEA,
54111329Salexandru.dutu@amd.com                              "memDataSize": "2 * dataSize" })
54211329Salexandru.dutu@amd.com
54311329Salexandru.dutu@amd.com        header_output += MicroLdStSplitOpDeclare.subst(iop)
54411329Salexandru.dutu@amd.com        decoder_output += MicroLdStSplitOpConstructor.subst(iop)
54511329Salexandru.dutu@amd.com        exec_output += MicroLoadExecute.subst(iop)
54611329Salexandru.dutu@amd.com        exec_output += MicroLoadInitiateAcc.subst(iop)
54711329Salexandru.dutu@amd.com        exec_output += MicroLoadCompleteAcc.subst(iop)
54811329Salexandru.dutu@amd.com
54911329Salexandru.dutu@amd.com        class LoadOp(LdStSplitOp):
55011329Salexandru.dutu@amd.com            def __init__(self, data, segment, addr, disp = 0,
55111329Salexandru.dutu@amd.com                    dataSize="env.dataSize",
55211329Salexandru.dutu@amd.com                    addressSize="env.addressSize",
55311829Sjason@lowepower.com                    atCPL0=False, prefetch=False, nonSpec=nonSpec,
55412682Sgabeblack@google.com                    implicitStack=False, uncacheable=False):
55511329Salexandru.dutu@amd.com                super(LoadOp, self).__init__(data, segment, addr,
55611329Salexandru.dutu@amd.com                        disp, dataSize, addressSize, mem_flags,
55712682Sgabeblack@google.com                        atCPL0, prefetch, nonSpec, implicitStack, uncacheable)
55811329Salexandru.dutu@amd.com                self.className = Name
55911329Salexandru.dutu@amd.com                self.mnemonic = name
56011329Salexandru.dutu@amd.com
56111329Salexandru.dutu@amd.com        microopClasses[name] = LoadOp
56211329Salexandru.dutu@amd.com
56311329Salexandru.dutu@amd.com    code = '''
56412384Sgabeblack@google.com        DataLow = Mem_u2qw[0];
56512384Sgabeblack@google.com        DataHi = Mem_u2qw[1];
56612384Sgabeblack@google.com    '''
56711329Salexandru.dutu@amd.com
56811329Salexandru.dutu@amd.com    defineMicroLoadSplitOp('LdSplit', code,
56911329Salexandru.dutu@amd.com                           '(StoreCheck << FlagShift)')
57011329Salexandru.dutu@amd.com
57111329Salexandru.dutu@amd.com    defineMicroLoadSplitOp('LdSplitl', code,
57211329Salexandru.dutu@amd.com                           '(StoreCheck << FlagShift) | Request::LOCKED_RMW',
57311329Salexandru.dutu@amd.com                           nonSpec=True)
57411329Salexandru.dutu@amd.com
57511829Sjason@lowepower.com    def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0",
57611829Sjason@lowepower.com                           implicitStack=False):
5774587Sgblack@eecs.umich.edu        global header_output
5784587Sgblack@eecs.umich.edu        global decoder_output
5794587Sgblack@eecs.umich.edu        global exec_output
5804587Sgblack@eecs.umich.edu        global microopClasses
5814587Sgblack@eecs.umich.edu        Name = mnemonic
5824587Sgblack@eecs.umich.edu        name = mnemonic.lower()
5834587Sgblack@eecs.umich.edu
5844587Sgblack@eecs.umich.edu        # Build up the all register version of this micro op
5854679Sgblack@eecs.umich.edu        iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
58611329Salexandru.dutu@amd.com                            { "code": code,
58711329Salexandru.dutu@amd.com                              "complete_code": completeCode,
58811329Salexandru.dutu@amd.com                              "ea_code": calculateEA,
58911329Salexandru.dutu@amd.com                              "memDataSize": "dataSize" })
5904587Sgblack@eecs.umich.edu        header_output += MicroLdStOpDeclare.subst(iop)
5914587Sgblack@eecs.umich.edu        decoder_output += MicroLdStOpConstructor.subst(iop)
5924587Sgblack@eecs.umich.edu        exec_output += MicroStoreExecute.subst(iop)
5934587Sgblack@eecs.umich.edu        exec_output += MicroStoreInitiateAcc.subst(iop)
5944587Sgblack@eecs.umich.edu        exec_output += MicroStoreCompleteAcc.subst(iop)
5954587Sgblack@eecs.umich.edu
59611829Sjason@lowepower.com        if implicitStack:
59711829Sjason@lowepower.com            # For instructions that implicitly access the stack, the address
59811829Sjason@lowepower.com            # size is the same as the stack segment pointer size, not the
59911829Sjason@lowepower.com            # address size if specified by the instruction prefix
60011829Sjason@lowepower.com            addressSize = "env.stackSize"
60111829Sjason@lowepower.com        else:
60211829Sjason@lowepower.com            addressSize = "env.addressSize"
60311829Sjason@lowepower.com
6044587Sgblack@eecs.umich.edu        class StoreOp(LdStOp):
6055149Sgblack@eecs.umich.edu            def __init__(self, data, segment, addr, disp = 0,
6065912Sgblack@eecs.umich.edu                    dataSize="env.dataSize",
60711829Sjason@lowepower.com                    addressSize=addressSize,
60812682Sgabeblack@google.com                    atCPL0=False, nonSpec=False, implicitStack=implicitStack,
60912682Sgabeblack@google.com                    uncacheable=False):
6108103Sgblack@eecs.umich.edu                super(StoreOp, self).__init__(data, segment, addr, disp,
6118103Sgblack@eecs.umich.edu                        dataSize, addressSize, mem_flags, atCPL0, False,
61212682Sgabeblack@google.com                        nonSpec, implicitStack, uncacheable)
6134587Sgblack@eecs.umich.edu                self.className = Name
6144587Sgblack@eecs.umich.edu                self.mnemonic = name
6154587Sgblack@eecs.umich.edu
6164587Sgblack@eecs.umich.edu        microopClasses[name] = StoreOp
6174587Sgblack@eecs.umich.edu
6185919Sgblack@eecs.umich.edu    defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
61911829Sjason@lowepower.com    defineMicroStoreOp('Stis', 'Mem = pick(Data, 2, dataSize);',
62011829Sjason@lowepower.com                       implicitStack=True)
6216080Sgblack@eecs.umich.edu    defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
62210760Ssteve.reinhardt@amd.com            mem_flags="Request::LOCKED_RMW")
6239894Sandreas@sandberg.pp.se
6249894Sandreas@sandberg.pp.se    defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;')
6259894Sandreas@sandberg.pp.se
6269894Sandreas@sandberg.pp.se    defineMicroStoreOp('Stfp87', code='''
6279894Sandreas@sandberg.pp.se        switch (dataSize)
6289894Sandreas@sandberg.pp.se        {
6299894Sandreas@sandberg.pp.se          case 4: {
6309894Sandreas@sandberg.pp.se            float single(FpData_df);
6319894Sandreas@sandberg.pp.se            Mem = *(uint32_t *)&single;
6329894Sandreas@sandberg.pp.se          } break;
6339894Sandreas@sandberg.pp.se          case 8:
6349894Sandreas@sandberg.pp.se            Mem = *(uint64_t *)&FpData_df;
6359894Sandreas@sandberg.pp.se            break;
6369894Sandreas@sandberg.pp.se          default:
6379894Sandreas@sandberg.pp.se            panic("Unhandled data size in StFp87.\\n");
6389894Sandreas@sandberg.pp.se        }
6399894Sandreas@sandberg.pp.se    ''')
6409894Sandreas@sandberg.pp.se
6415892Sgblack@eecs.umich.edu    defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
64212463Sswapnilster@gmail.com    defineMicroStoreOp('Clflushopt', 'Mem = 0;',
64312463Sswapnilster@gmail.com                       mem_flags="Request::CLEAN | Request::INVALIDATE" +
64412463Sswapnilster@gmail.com                       " | Request::DST_POC")
64512463Sswapnilster@gmail.com    defineMicroStoreOp('Clwb', 'Mem = 0;',
64612463Sswapnilster@gmail.com                       mem_flags="Request::CLEAN | Request::DST_POC")
6474601Sgblack@eecs.umich.edu
64811329Salexandru.dutu@amd.com    def defineMicroStoreSplitOp(mnemonic, code,
64911329Salexandru.dutu@amd.com                                completeCode="", mem_flags="0"):
65011329Salexandru.dutu@amd.com        global header_output
65111329Salexandru.dutu@amd.com        global decoder_output
65211329Salexandru.dutu@amd.com        global exec_output
65311329Salexandru.dutu@amd.com        global microopClasses
65411329Salexandru.dutu@amd.com        Name = mnemonic
65511329Salexandru.dutu@amd.com        name = mnemonic.lower()
65611329Salexandru.dutu@amd.com
65711329Salexandru.dutu@amd.com        iop = InstObjParams(name, Name, 'X86ISA::LdStSplitOp',
65811329Salexandru.dutu@amd.com                            { "code": code,
65911329Salexandru.dutu@amd.com                              "complete_code": completeCode,
66011329Salexandru.dutu@amd.com                              "ea_code": calculateEA,
66111329Salexandru.dutu@amd.com                              "memDataSize": "2 * dataSize" })
66211329Salexandru.dutu@amd.com
66311329Salexandru.dutu@amd.com        header_output += MicroLdStSplitOpDeclare.subst(iop)
66411329Salexandru.dutu@amd.com        decoder_output += MicroLdStSplitOpConstructor.subst(iop)
66511329Salexandru.dutu@amd.com        exec_output += MicroStoreExecute.subst(iop)
66611329Salexandru.dutu@amd.com        exec_output += MicroStoreInitiateAcc.subst(iop)
66711329Salexandru.dutu@amd.com        exec_output += MicroStoreCompleteAcc.subst(iop)
66811329Salexandru.dutu@amd.com
66911329Salexandru.dutu@amd.com        class StoreOp(LdStSplitOp):
67011329Salexandru.dutu@amd.com            def __init__(self, data, segment, addr, disp = 0,
67111329Salexandru.dutu@amd.com                    dataSize="env.dataSize",
67211329Salexandru.dutu@amd.com                    addressSize="env.addressSize",
67312682Sgabeblack@google.com                    atCPL0=False, nonSpec=False, implicitStack=False,
67412682Sgabeblack@google.com                    uncacheable=False):
67511329Salexandru.dutu@amd.com                super(StoreOp, self).__init__(data, segment, addr, disp,
67611329Salexandru.dutu@amd.com                        dataSize, addressSize, mem_flags, atCPL0, False,
67712682Sgabeblack@google.com                        nonSpec, implicitStack, uncacheable)
67811329Salexandru.dutu@amd.com                self.className = Name
67911329Salexandru.dutu@amd.com                self.mnemonic = name
68011329Salexandru.dutu@amd.com
68111329Salexandru.dutu@amd.com        microopClasses[name] = StoreOp
68211329Salexandru.dutu@amd.com
68311329Salexandru.dutu@amd.com    code = '''
68412384Sgabeblack@google.com        Mem_u2qw[0] = DataLow;
68512384Sgabeblack@google.com        Mem_u2qw[1] = DataHi;
68612384Sgabeblack@google.com    '''
68711329Salexandru.dutu@amd.com
68811329Salexandru.dutu@amd.com    defineMicroStoreSplitOp('StSplit', code);
68911329Salexandru.dutu@amd.com
69011329Salexandru.dutu@amd.com    defineMicroStoreSplitOp('StSplitul', code,
69111329Salexandru.dutu@amd.com                            mem_flags='Request::LOCKED_RMW')
69211329Salexandru.dutu@amd.com
6934679Sgblack@eecs.umich.edu    iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
69411329Salexandru.dutu@amd.com                        { "code": "Data = merge(Data, EA, dataSize);",
69511329Salexandru.dutu@amd.com                          "ea_code": "EA = " + segmentEAExpr,
69611329Salexandru.dutu@amd.com                          "memDataSize": "dataSize" })
6974601Sgblack@eecs.umich.edu    header_output += MicroLeaDeclare.subst(iop)
6984601Sgblack@eecs.umich.edu    decoder_output += MicroLdStOpConstructor.subst(iop)
6994601Sgblack@eecs.umich.edu    exec_output += MicroLeaExecute.subst(iop)
7004601Sgblack@eecs.umich.edu
7014601Sgblack@eecs.umich.edu    class LeaOp(LdStOp):
7025149Sgblack@eecs.umich.edu        def __init__(self, data, segment, addr, disp = 0,
7035149Sgblack@eecs.umich.edu                dataSize="env.dataSize", addressSize="env.addressSize"):
7048103Sgblack@eecs.umich.edu            super(LeaOp, self).__init__(data, segment, addr, disp,
70512682Sgabeblack@google.com                    dataSize, addressSize, "0",
70612682Sgabeblack@google.com                    False, False, False, False, False)
7074601Sgblack@eecs.umich.edu            self.className = "Lea"
7084601Sgblack@eecs.umich.edu            self.mnemonic = "lea"
7094601Sgblack@eecs.umich.edu
7104601Sgblack@eecs.umich.edu    microopClasses["lea"] = LeaOp
7115178Sgblack@eecs.umich.edu
7125178Sgblack@eecs.umich.edu
7135359Sgblack@eecs.umich.edu    iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
71411329Salexandru.dutu@amd.com                        { "code": "xc->demapPage(EA, 0);",
71511329Salexandru.dutu@amd.com                          "ea_code": calculateEA,
71611329Salexandru.dutu@amd.com                          "memDataSize": "dataSize" })
7175359Sgblack@eecs.umich.edu    header_output += MicroLeaDeclare.subst(iop)
7185359Sgblack@eecs.umich.edu    decoder_output += MicroLdStOpConstructor.subst(iop)
7195359Sgblack@eecs.umich.edu    exec_output += MicroLeaExecute.subst(iop)
7205359Sgblack@eecs.umich.edu
7215359Sgblack@eecs.umich.edu    class TiaOp(LdStOp):
7225359Sgblack@eecs.umich.edu        def __init__(self, segment, addr, disp = 0,
7235912Sgblack@eecs.umich.edu                dataSize="env.dataSize",
7245912Sgblack@eecs.umich.edu                addressSize="env.addressSize"):
7256345Sgblack@eecs.umich.edu            super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
7268103Sgblack@eecs.umich.edu                    addr, disp, dataSize, addressSize, "0", False, False,
72712682Sgabeblack@google.com                    False, False, False)
7285359Sgblack@eecs.umich.edu            self.className = "Tia"
7295359Sgblack@eecs.umich.edu            self.mnemonic = "tia"
7305359Sgblack@eecs.umich.edu
7315359Sgblack@eecs.umich.edu    microopClasses["tia"] = TiaOp
7325359Sgblack@eecs.umich.edu
7335178Sgblack@eecs.umich.edu    class CdaOp(LdStOp):
7345178Sgblack@eecs.umich.edu        def __init__(self, segment, addr, disp = 0,
7355912Sgblack@eecs.umich.edu                dataSize="env.dataSize",
7365912Sgblack@eecs.umich.edu                addressSize="env.addressSize", atCPL0=False):
7376345Sgblack@eecs.umich.edu            super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
7386624Sgblack@eecs.umich.edu                    addr, disp, dataSize, addressSize, "Request::NO_ACCESS",
73912682Sgabeblack@google.com                    atCPL0, False, False, False, False)
7405178Sgblack@eecs.umich.edu            self.className = "Cda"
7415178Sgblack@eecs.umich.edu            self.mnemonic = "cda"
7425178Sgblack@eecs.umich.edu
7435178Sgblack@eecs.umich.edu    microopClasses["cda"] = CdaOp
7444587Sgblack@eecs.umich.edu}};
745