pal.isa revision 2665:a124942bacb8
12600SN/A// -*- mode:c++ -*-
22600SN/A
32600SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan
42600SN/A// All rights reserved.
52600SN/A//
62600SN/A// Redistribution and use in source and binary forms, with or without
72600SN/A// modification, are permitted provided that the following conditions are
82600SN/A// met: redistributions of source code must retain the above copyright
92600SN/A// notice, this list of conditions and the following disclaimer;
102600SN/A// redistributions in binary form must reproduce the above copyright
112600SN/A// notice, this list of conditions and the following disclaimer in the
122600SN/A// documentation and/or other materials provided with the distribution;
132600SN/A// neither the name of the copyright holders nor the names of its
142600SN/A// contributors may be used to endorse or promote products derived from
152600SN/A// this software without specific prior written permission.
162600SN/A//
172600SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182600SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192600SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202600SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212600SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222600SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232600SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242600SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252600SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262600SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272665Ssaidi@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu//
292600SN/A// Authors: Steve Reinhardt
302600SN/A
318229Snate@binkert.org////////////////////////////////////////////////////////////////////
3211793Sbrandon.potter@amd.com//
332600SN/A// PAL calls & PAL-specific instructions
346329Sgblack@eecs.umich.edu//
3513988Sgabeblack@google.com
362600SN/Aoutput header {{
372680Sktlim@umich.edu    /**
382600SN/A     * Base class for emulated call_pal calls (used only in
392600SN/A     * non-full-system mode).
4011794Sbrandon.potter@amd.com     */
412600SN/A    class EmulatedCallPal : public AlphaStaticInst
422600SN/A    {
432600SN/A      protected:
442600SN/A
452600SN/A        /// Constructor.
4613988Sgabeblack@google.com        EmulatedCallPal(const char *mnem, ExtMachInst _machInst,
4713988Sgabeblack@google.com                        OpClass __opClass)
4813988Sgabeblack@google.com            : AlphaStaticInst(mnem, _machInst, __opClass)
4913988Sgabeblack@google.com        {
5013988Sgabeblack@google.com        }
5113988Sgabeblack@google.com
5213988Sgabeblack@google.com        std::string
5313988Sgabeblack@google.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
5413988Sgabeblack@google.com    };
5513988Sgabeblack@google.com}};
5613988Sgabeblack@google.com
5713988Sgabeblack@google.comoutput decoder {{
5813988Sgabeblack@google.com    std::string
5913988Sgabeblack@google.com    EmulatedCallPal::generateDisassembly(Addr pc,
6013988Sgabeblack@google.com                                         const SymbolTable *symtab) const
6113988Sgabeblack@google.com    {
6213988Sgabeblack@google.com#ifdef SS_COMPATIBLE_DISASSEMBLY
6313988Sgabeblack@google.com        return csprintf("%s %s", "call_pal", mnemonic);
6413988Sgabeblack@google.com#else
6513988Sgabeblack@google.com        return csprintf("%-10s %s", "call_pal", mnemonic);
6613988Sgabeblack@google.com#endif
6713988Sgabeblack@google.com    }
6813988Sgabeblack@google.com}};
6913988Sgabeblack@google.com
7013988Sgabeblack@google.comdef format EmulatedCallPal(code, *flags) {{
7113988Sgabeblack@google.com    iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags)
722600SN/A    header_output = BasicDeclare.subst(iop)
732600SN/A    decoder_output = BasicConstructor.subst(iop)
742600SN/A    decode_block = BasicDecode.subst(iop)
7513995Sbrandon.potter@amd.com    exec_output = BasicExecute.subst(iop)
762600SN/A}};
776701Sgblack@eecs.umich.edu
7813995Sbrandon.potter@amd.comoutput header {{
796701Sgblack@eecs.umich.edu    /**
802600SN/A     * Base class for full-system-mode call_pal instructions.
812600SN/A     * Probably could turn this into a leaf class and get rid of the
822600SN/A     * parser template.
832600SN/A     */
842600SN/A    class CallPalBase : public AlphaStaticInst
852600SN/A    {
862600SN/A      protected:
878706Sandreas.hansson@arm.com        int palFunc;	///< Function code part of instruction
882600SN/A        int palOffset;	///< Target PC, offset from IPR_PAL_BASE
892600SN/A        bool palValid;	///< is the function code valid?
902600SN/A        bool palPriv;	///< is this call privileged?
912600SN/A
922600SN/A        /// Constructor.
932600SN/A        CallPalBase(const char *mnem, ExtMachInst _machInst,
942600SN/A                    OpClass __opClass);
952600SN/A
962600SN/A        std::string
9713570Sbrandon.potter@amd.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
9813570Sbrandon.potter@amd.com    };
992600SN/A}};
1002600SN/A
1012600SN/Aoutput decoder {{
1022600SN/A    inline
1032600SN/A    CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst,
1042600SN/A                             OpClass __opClass)
1052600SN/A        : AlphaStaticInst(mnem, _machInst, __opClass),
1062600SN/A        palFunc(PALFUNC)
1072600SN/A    {
1082600SN/A        // From the 21164 HRM (paraphrased):
1092600SN/A        // Bit 7 of the function code (mask 0x80) indicates
1102600SN/A        // whether the call is privileged (bit 7 == 0) or
1115748SSteve.Reinhardt@amd.com        // unprivileged (bit 7 == 1).  The privileged call table
1122600SN/A        // starts at 0x2000, the unprivielged call table starts at
1132600SN/A        // 0x3000.  Bits 5-0 (mask 0x3f) are used to calculate the
1142600SN/A        // offset.
1152600SN/A        const int palPrivMask = 0x80;
1162600SN/A        const int palOffsetMask = 0x3f;
1172600SN/A
1182600SN/A        // Pal call is invalid unless all other bits are 0
1192600SN/A        palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0);
1202600SN/A        palPriv = ((machInst & palPrivMask) == 0);
1212600SN/A        int shortPalFunc = (machInst & palOffsetMask);
1222600SN/A        // Add 1 to base to set pal-mode bit
1232600SN/A        palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6);
1242600SN/A    }
1252600SN/A
1262600SN/A    std::string
1272600SN/A    CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1282600SN/A    {
1292600SN/A        return csprintf("%-10s %#x", "call_pal", palFunc);
1302600SN/A    }
1312600SN/A}};
1322600SN/A
1332600SN/Adef format CallPal(code, *flags) {{
1342600SN/A    iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags)
1352600SN/A    header_output = BasicDeclare.subst(iop)
1362600SN/A    decoder_output = BasicConstructor.subst(iop)
1372600SN/A    decode_block = BasicDecode.subst(iop)
1382600SN/A    exec_output = BasicExecute.subst(iop)
1392600SN/A}};
1402600SN/A
1412600SN/A////////////////////////////////////////////////////////////////////
1422600SN/A//
1432600SN/A// hw_ld, hw_st
1442600SN/A//
1452600SN/A
1462600SN/Aoutput header {{
1472600SN/A    /**
1482600SN/A     * Base class for hw_ld and hw_st.
1492600SN/A     */
1502600SN/A    class HwLoadStore : public Memory
1512600SN/A    {
1522600SN/A      protected:
1532600SN/A
1545513SMichael.Adler@intel.com        /// Displacement for EA calculation (signed).
1552600SN/A        int16_t disp;
1562600SN/A
1572600SN/A        /// Constructor
1582600SN/A        HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
1592600SN/A                    StaticInstPtr _eaCompPtr = nullStaticInstPtr,
1602600SN/A                    StaticInstPtr _memAccPtr = nullStaticInstPtr);
1612600SN/A
1622600SN/A        std::string
1632600SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1642600SN/A    };
1652600SN/A}};
1662600SN/A
1672600SN/A
1682600SN/Aoutput decoder {{
1692600SN/A    inline
1702600SN/A    HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst,
1712600SN/A                             OpClass __opClass,
1722600SN/A                             StaticInstPtr _eaCompPtr,
1732600SN/A                             StaticInstPtr _memAccPtr)
1742600SN/A        : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
1752600SN/A        disp(HW_LDST_DISP)
1762600SN/A    {
1772600SN/A        memAccessFlags = 0;
1782600SN/A        if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL;
1792600SN/A        if (HW_LDST_ALT)  memAccessFlags |= ALTMODE;
1802600SN/A        if (HW_LDST_VPTE) memAccessFlags |= VPTE;
1812600SN/A        if (HW_LDST_LOCK) memAccessFlags |= LOCKED;
1822600SN/A    }
1832600SN/A
1845513SMichael.Adler@intel.com    std::string
1852600SN/A    HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1862600SN/A    {
1872600SN/A#ifdef SS_COMPATIBLE_DISASSEMBLY
1882600SN/A        return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB);
1892600SN/A#else
1902600SN/A        // HW_LDST_LOCK and HW_LDST_COND are the same bit.
1912600SN/A        const char *lock_str =
1922600SN/A            (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : "";
1932600SN/A
1942600SN/A        return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s",
1952600SN/A                        mnemonic, RA, disp, RB,
1962600SN/A                        HW_LDST_PHYS ? ",PHYS" : "",
1972600SN/A                        HW_LDST_ALT ? ",ALT" : "",
1982600SN/A                        HW_LDST_QUAD ? ",QUAD" : "",
1992600SN/A                        HW_LDST_VPTE ? ",VPTE" : "",
2002600SN/A                        lock_str);
2012600SN/A#endif
2022600SN/A    }
2032600SN/A}};
2042600SN/A
2052600SN/Adef format HwLoad(ea_code, memacc_code, class_ext, *flags) {{
2062600SN/A    (header_output, decoder_output, decode_block, exec_output) = \
2072600SN/A        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
2082600SN/A                      mem_flags = [], inst_flags = flags,
2092600SN/A                      base_class = 'HwLoadStore', exec_template_base = 'Load')
2102600SN/A}};
2112600SN/A
2122600SN/A
2132600SN/Adef format HwStore(ea_code, memacc_code, class_ext, *flags) {{
2142600SN/A    (header_output, decoder_output, decode_block, exec_output) = \
2152600SN/A        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
2162600SN/A                      mem_flags = [], inst_flags = flags,
2172600SN/A                      base_class = 'HwLoadStore', exec_template_base = 'Store')
2182600SN/A}};
2192600SN/A
2202600SN/A
2212600SN/Adef format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext,
2222600SN/A                       *flags) {{
2232600SN/A    (header_output, decoder_output, decode_block, exec_output) = \
2242600SN/A        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
2252600SN/A                      postacc_code, mem_flags = [], inst_flags = flags,
2262600SN/A                      base_class = 'HwLoadStore')
2272600SN/A}};
2282600SN/A
2292600SN/A
2302600SN/Aoutput header {{
2312600SN/A    /**
2322600SN/A     * Base class for hw_mfpr and hw_mtpr.
2332600SN/A     */
2342600SN/A    class HwMoveIPR : public AlphaStaticInst
2352600SN/A    {
2362600SN/A      protected:
2372600SN/A        /// Index of internal processor register.
2382600SN/A        int ipr_index;
2392600SN/A
2402600SN/A        /// Constructor
2412600SN/A        HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
2422600SN/A            : AlphaStaticInst(mnem, _machInst, __opClass),
2432600SN/A              ipr_index(HW_IPR_IDX)
2442600SN/A        {
2452600SN/A        }
2462600SN/A
2472600SN/A        std::string
2482600SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
2492600SN/A    };
2502600SN/A}};
2512600SN/A
2522600SN/Aoutput decoder {{
2532600SN/A    std::string
2542600SN/A    HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
2552600SN/A    {
2562600SN/A        if (_numSrcRegs > 0) {
2572600SN/A            // must be mtpr
2582600SN/A            return csprintf("%-10s r%d,IPR(%#x)",
2592600SN/A                            mnemonic, RA, ipr_index);
2602600SN/A        }
2612600SN/A        else {
2622600SN/A            // must be mfpr
2632600SN/A            return csprintf("%-10s IPR(%#x),r%d",
2642600SN/A                            mnemonic, ipr_index, RA);
2652600SN/A        }
2662600SN/A    }
2672600SN/A}};
2682600SN/A
2692600SN/Adef format HwMoveIPR(code) {{
2702600SN/A    iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code),
2712600SN/A                        ['IprAccessOp'])
2722600SN/A    header_output = BasicDeclare.subst(iop)
2732600SN/A    decoder_output = BasicConstructor.subst(iop)
2742600SN/A    decode_block = BasicDecode.subst(iop)
2752600SN/A    exec_output = BasicExecute.subst(iop)
2762600SN/A}};
2772600SN/A
2782600SN/A
2792600SN/A