pal.isa revision 6181
12810SN/A// -*- mode:c++ -*-
212724Snikos.nikoleris@arm.com
38856Sandreas.hansson@arm.com// Copyright (c) 2003-2005 The Regents of The University of Michigan
48856Sandreas.hansson@arm.com// All rights reserved.
58856Sandreas.hansson@arm.com//
68856Sandreas.hansson@arm.com// Redistribution and use in source and binary forms, with or without
78856Sandreas.hansson@arm.com// modification, are permitted provided that the following conditions are
88856Sandreas.hansson@arm.com// met: redistributions of source code must retain the above copyright
98856Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer;
108856Sandreas.hansson@arm.com// redistributions in binary form must reproduce the above copyright
118856Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer in the
128856Sandreas.hansson@arm.com// documentation and/or other materials provided with the distribution;
138856Sandreas.hansson@arm.com// neither the name of the copyright holders nor the names of its
142810SN/A// contributors may be used to endorse or promote products derived from
152810SN/A// this software without specific prior written permission.
162810SN/A//
172810SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182810SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192810SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202810SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212810SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222810SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232810SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242810SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252810SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262810SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272810SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282810SN/A//
292810SN/A// Authors: Steve Reinhardt
302810SN/A
312810SN/A////////////////////////////////////////////////////////////////////
322810SN/A//
332810SN/A// PAL calls & PAL-specific instructions
342810SN/A//
352810SN/A
362810SN/Aoutput header {{
372810SN/A    /**
382810SN/A     * Base class for emulated call_pal calls (used only in
392810SN/A     * non-full-system mode).
402810SN/A     */
414458SN/A    class EmulatedCallPal : public AlphaStaticInst
424458SN/A    {
4312724Snikos.nikoleris@arm.com      protected:
4412724Snikos.nikoleris@arm.com
452810SN/A        /// Constructor.
462810SN/A        EmulatedCallPal(const char *mnem, ExtMachInst _machInst,
472810SN/A                        OpClass __opClass)
482810SN/A            : AlphaStaticInst(mnem, _machInst, __opClass)
492810SN/A        {
502810SN/A        }
512810SN/A
5211051Sandreas.hansson@arm.com        std::string
5311051Sandreas.hansson@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
542810SN/A    };
5512724Snikos.nikoleris@arm.com}};
5612724Snikos.nikoleris@arm.com
577676Snate@binkert.orgoutput decoder {{
582810SN/A    std::string
5912724Snikos.nikoleris@arm.com    EmulatedCallPal::generateDisassembly(Addr pc,
602810SN/A                                         const SymbolTable *symtab) const
612810SN/A    {
626215Snate@binkert.org#ifdef SS_COMPATIBLE_DISASSEMBLY
638232Snate@binkert.org        return csprintf("%s %s", "call_pal", mnemonic);
648232Snate@binkert.org#else
6512724Snikos.nikoleris@arm.com        return csprintf("%-10s %s", "call_pal", mnemonic);
6612724Snikos.nikoleris@arm.com#endif
675338Sstever@gmail.com    }
6812724Snikos.nikoleris@arm.com}};
6911375Sandreas.hansson@arm.com
7012724Snikos.nikoleris@arm.comdef format EmulatedCallPal(code, *flags) {{
712810SN/A    iop = InstObjParams(name, Name, 'EmulatedCallPal', code, flags)
722810SN/A    header_output = BasicDeclare.subst(iop)
7312724Snikos.nikoleris@arm.com    decoder_output = BasicConstructor.subst(iop)
748914Sandreas.hansson@arm.com    decode_block = BasicDecode.subst(iop)
758229Snate@binkert.org    exec_output = BasicExecute.subst(iop)
762811SN/A}};
7712724Snikos.nikoleris@arm.com
784626SN/Aoutput header {{
798833Sdam.sunwoo@arm.com    /**
802810SN/A     * Base class for full-system-mode call_pal instructions.
8112724Snikos.nikoleris@arm.com     * Probably could turn this into a leaf class and get rid of the
8212724Snikos.nikoleris@arm.com     * parser template.
8312724Snikos.nikoleris@arm.com     */
8412724Snikos.nikoleris@arm.com    class CallPalBase : public AlphaStaticInst
8512724Snikos.nikoleris@arm.com    {
8612724Snikos.nikoleris@arm.com      protected:
8712724Snikos.nikoleris@arm.com        int palFunc;	///< Function code part of instruction
8812724Snikos.nikoleris@arm.com        int palOffset;	///< Target PC, offset from IPR_PAL_BASE
892810SN/A        bool palValid;	///< is the function code valid?
902810SN/A        bool palPriv;	///< is this call privileged?
912810SN/A
922810SN/A        /// Constructor.
932810SN/A        CallPalBase(const char *mnem, ExtMachInst _machInst,
9411375Sandreas.hansson@arm.com                    OpClass __opClass);
954628SN/A
964628SN/A        std::string
974628SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
984628SN/A    };
994628SN/A}};
1004628SN/A
1014628SN/Aoutput decoder {{
1024628SN/A    inline
1038737Skoansin.tan@gmail.com    CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst,
1044628SN/A                             OpClass __opClass)
1054628SN/A        : AlphaStaticInst(mnem, _machInst, __opClass),
1064628SN/A        palFunc(PALFUNC)
1074628SN/A    {
1084628SN/A        // From the 21164 HRM (paraphrased):
1094628SN/A        // Bit 7 of the function code (mask 0x80) indicates
1104628SN/A        // whether the call is privileged (bit 7 == 0) or
1114628SN/A        // unprivileged (bit 7 == 1).  The privileged call table
1124628SN/A        // starts at 0x2000, the unprivielged call table starts at
1134628SN/A        // 0x3000.  Bits 5-0 (mask 0x3f) are used to calculate the
1148737Skoansin.tan@gmail.com        // offset.
1154628SN/A        const int palPrivMask = 0x80;
1168856Sandreas.hansson@arm.com        const int palOffsetMask = 0x3f;
1178856Sandreas.hansson@arm.com
1188856Sandreas.hansson@arm.com        // Pal call is invalid unless all other bits are 0
1198856Sandreas.hansson@arm.com        palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0);
1208856Sandreas.hansson@arm.com        palPriv = ((machInst & palPrivMask) == 0);
12110942Sandreas.hansson@arm.com        int shortPalFunc = (machInst & palOffsetMask);
1228856Sandreas.hansson@arm.com        // Add 1 to base to set pal-mode bit
1238856Sandreas.hansson@arm.com        palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6);
1248856Sandreas.hansson@arm.com    }
1258922Swilliam.wang@arm.com
1262810SN/A    std::string
1278856Sandreas.hansson@arm.com    CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1282844SN/A    {
1298856Sandreas.hansson@arm.com        return csprintf("%-10s %#x", "call_pal", palFunc);
1308856Sandreas.hansson@arm.com    }
1318856Sandreas.hansson@arm.com}};
13210713Sandreas.hansson@arm.com
1338856Sandreas.hansson@arm.comdef format CallPal(code, *flags) {{
13410942Sandreas.hansson@arm.com    iop = InstObjParams(name, Name, 'CallPalBase', code, flags)
1358856Sandreas.hansson@arm.com    header_output = BasicDeclare.subst(iop)
13610942Sandreas.hansson@arm.com    decoder_output = BasicConstructor.subst(iop)
13710713Sandreas.hansson@arm.com    decode_block = BasicDecode.subst(iop)
1388856Sandreas.hansson@arm.com    exec_output = BasicExecute.subst(iop)
1398856Sandreas.hansson@arm.com}};
1403738SN/A
1414458SN/A////////////////////////////////////////////////////////////////////
1428856Sandreas.hansson@arm.com//
14310713Sandreas.hansson@arm.com// hw_ld, hw_st
14410713Sandreas.hansson@arm.com//
14510713Sandreas.hansson@arm.com
1468914Sandreas.hansson@arm.comoutput header {{
1472810SN/A    /**
1488856Sandreas.hansson@arm.com     * Base class for hw_ld and hw_st.
1498856Sandreas.hansson@arm.com     */
1508856Sandreas.hansson@arm.com    class HwLoadStore : public Memory
1518914Sandreas.hansson@arm.com    {
1528856Sandreas.hansson@arm.com      protected:
1538922Swilliam.wang@arm.com
1548856Sandreas.hansson@arm.com        /// Displacement for EA calculation (signed).
1553013SN/A        int16_t disp;
1568856Sandreas.hansson@arm.com
15712724Snikos.nikoleris@arm.com        /// Constructor
15812724Snikos.nikoleris@arm.com        HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass);
15912724Snikos.nikoleris@arm.com
16012724Snikos.nikoleris@arm.com        std::string
16112724Snikos.nikoleris@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
16212724Snikos.nikoleris@arm.com    };
16312724Snikos.nikoleris@arm.com}};
16412724Snikos.nikoleris@arm.com
16512724Snikos.nikoleris@arm.com
16612724Snikos.nikoleris@arm.comoutput decoder {{
16712724Snikos.nikoleris@arm.com    inline
16812724Snikos.nikoleris@arm.com    HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst,
16912724Snikos.nikoleris@arm.com                             OpClass __opClass)
17012724Snikos.nikoleris@arm.com        : Memory(mnem, _machInst, __opClass), disp(HW_LDST_DISP)
17112724Snikos.nikoleris@arm.com    {
17212724Snikos.nikoleris@arm.com        memAccessFlags.clear();
17312724Snikos.nikoleris@arm.com        if (HW_LDST_PHYS) memAccessFlags.set(Request::PHYSICAL);
17412724Snikos.nikoleris@arm.com        if (HW_LDST_ALT)  memAccessFlags.set(Request::ALTMODE);
17512724Snikos.nikoleris@arm.com        if (HW_LDST_VPTE) memAccessFlags.set(Request::VPTE);
17612724Snikos.nikoleris@arm.com        if (HW_LDST_LOCK) memAccessFlags.set(Request::LLSC);
17712724Snikos.nikoleris@arm.com    }
17812724Snikos.nikoleris@arm.com
17912724Snikos.nikoleris@arm.com    std::string
18012724Snikos.nikoleris@arm.com    HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const
18112724Snikos.nikoleris@arm.com    {
18212724Snikos.nikoleris@arm.com#ifdef SS_COMPATIBLE_DISASSEMBLY
18312724Snikos.nikoleris@arm.com        return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB);
18412724Snikos.nikoleris@arm.com#else
18512724Snikos.nikoleris@arm.com        // HW_LDST_LOCK and HW_LDST_COND are the same bit.
18612724Snikos.nikoleris@arm.com        const char *lock_str =
18712724Snikos.nikoleris@arm.com            (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : "";
18812724Snikos.nikoleris@arm.com
18912724Snikos.nikoleris@arm.com        return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s",
19012724Snikos.nikoleris@arm.com                        mnemonic, RA, disp, RB,
19112724Snikos.nikoleris@arm.com                        HW_LDST_PHYS ? ",PHYS" : "",
19212724Snikos.nikoleris@arm.com                        HW_LDST_ALT ? ",ALT" : "",
19312724Snikos.nikoleris@arm.com                        HW_LDST_QUAD ? ",QUAD" : "",
19412724Snikos.nikoleris@arm.com                        HW_LDST_VPTE ? ",VPTE" : "",
19512724Snikos.nikoleris@arm.com                        lock_str);
19612724Snikos.nikoleris@arm.com#endif
19712724Snikos.nikoleris@arm.com    }
19812724Snikos.nikoleris@arm.com}};
19912724Snikos.nikoleris@arm.com
20012724Snikos.nikoleris@arm.comdef format HwLoad(ea_code, memacc_code, class_ext, *flags) {{
20112724Snikos.nikoleris@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
20212724Snikos.nikoleris@arm.com        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
20312724Snikos.nikoleris@arm.com                      mem_flags = [], inst_flags = flags,
20412724Snikos.nikoleris@arm.com                      base_class = 'HwLoadStore', exec_template_base = 'Load')
20512724Snikos.nikoleris@arm.com}};
20612724Snikos.nikoleris@arm.com
20712724Snikos.nikoleris@arm.com
20812724Snikos.nikoleris@arm.comdef format HwStore(ea_code, memacc_code, class_ext, *flags) {{
20912724Snikos.nikoleris@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
21012724Snikos.nikoleris@arm.com        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
21112724Snikos.nikoleris@arm.com                      mem_flags = [], inst_flags = flags,
21212724Snikos.nikoleris@arm.com                      base_class = 'HwLoadStore', exec_template_base = 'Store')
21312724Snikos.nikoleris@arm.com}};
21412724Snikos.nikoleris@arm.com
21512724Snikos.nikoleris@arm.com
21612724Snikos.nikoleris@arm.comdef format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext,
21712724Snikos.nikoleris@arm.com                       *flags) {{
21812724Snikos.nikoleris@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
21912724Snikos.nikoleris@arm.com        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
22012724Snikos.nikoleris@arm.com                      postacc_code, mem_flags = [], inst_flags = flags,
22112724Snikos.nikoleris@arm.com                      base_class = 'HwLoadStore')
22212724Snikos.nikoleris@arm.com}};
22312724Snikos.nikoleris@arm.com
22412724Snikos.nikoleris@arm.com
22512724Snikos.nikoleris@arm.comoutput header {{
22612724Snikos.nikoleris@arm.com    /**
22712724Snikos.nikoleris@arm.com     * Base class for hw_mfpr and hw_mtpr.
22812724Snikos.nikoleris@arm.com     */
22912724Snikos.nikoleris@arm.com    class HwMoveIPR : public AlphaStaticInst
23012724Snikos.nikoleris@arm.com    {
23112724Snikos.nikoleris@arm.com      protected:
23212724Snikos.nikoleris@arm.com        /// Index of internal processor register.
23312724Snikos.nikoleris@arm.com        int ipr_index;
23412724Snikos.nikoleris@arm.com
23512724Snikos.nikoleris@arm.com        /// Constructor
23612724Snikos.nikoleris@arm.com        HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
23712724Snikos.nikoleris@arm.com            : AlphaStaticInst(mnem, _machInst, __opClass),
2388856Sandreas.hansson@arm.com              ipr_index(HW_IPR_IDX)
2398856Sandreas.hansson@arm.com        {
2408856Sandreas.hansson@arm.com        }
2418856Sandreas.hansson@arm.com
2428856Sandreas.hansson@arm.com        std::string
2438856Sandreas.hansson@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
2448856Sandreas.hansson@arm.com    };
2458922Swilliam.wang@arm.com}};
2468856Sandreas.hansson@arm.com
2475314SN/Aoutput decoder {{
2482811SN/A    std::string
2498856Sandreas.hansson@arm.com    HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
2508856Sandreas.hansson@arm.com    {
2512810SN/A        if (_numSrcRegs > 0) {
2522810SN/A            // must be mtpr
2538856Sandreas.hansson@arm.com            return csprintf("%-10s r%d,IPR(%#x)",
2542810SN/A                            mnemonic, RA, ipr_index);
2552810SN/A        }
25610345SCurtis.Dunham@arm.com        else {
25710345SCurtis.Dunham@arm.com            // must be mfpr
2588856Sandreas.hansson@arm.com            return csprintf("%-10s IPR(%#x),r%d",
2598856Sandreas.hansson@arm.com                            mnemonic, ipr_index, RA);
2608856Sandreas.hansson@arm.com        }
2618856Sandreas.hansson@arm.com    }
2623606SN/A}};
2638914Sandreas.hansson@arm.com
26410713Sandreas.hansson@arm.comdef format HwMoveIPR(code, *flags) {{
2658914Sandreas.hansson@arm.com    all_flags = ['IprAccessOp']
2662810SN/A    all_flags += flags
2672810SN/A    iop = InstObjParams(name, Name, 'HwMoveIPR', code, all_flags)
2682897SN/A    header_output = BasicDeclare.subst(iop)
2692897SN/A    decoder_output = BasicConstructor.subst(iop)
2708856Sandreas.hansson@arm.com    decode_block = BasicDecode.subst(iop)
2714458SN/A    exec_output = BasicExecute.subst(iop)
27210344Sandreas.hansson@arm.com}};
27310344Sandreas.hansson@arm.com
27412084Sspwilson2@wisc.edu
2758856Sandreas.hansson@arm.com