pal.isa revision 6076
12068SN/A// -*- mode:c++ -*- 22068SN/A 32068SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan 42068SN/A// All rights reserved. 52068SN/A// 62068SN/A// Redistribution and use in source and binary forms, with or without 72068SN/A// modification, are permitted provided that the following conditions are 82068SN/A// met: redistributions of source code must retain the above copyright 92068SN/A// notice, this list of conditions and the following disclaimer; 102068SN/A// redistributions in binary form must reproduce the above copyright 112068SN/A// notice, this list of conditions and the following disclaimer in the 122068SN/A// documentation and/or other materials provided with the distribution; 132068SN/A// neither the name of the copyright holders nor the names of its 142068SN/A// contributors may be used to endorse or promote products derived from 152068SN/A// this software without specific prior written permission. 162068SN/A// 172068SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182068SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192068SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202068SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212068SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222068SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232068SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242068SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252068SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262068SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272068SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu// 292665Ssaidi@eecs.umich.edu// Authors: Steve Reinhardt 302068SN/A 312649Ssaidi@eecs.umich.edu//////////////////////////////////////////////////////////////////// 322649Ssaidi@eecs.umich.edu// 332649Ssaidi@eecs.umich.edu// PAL calls & PAL-specific instructions 342649Ssaidi@eecs.umich.edu// 352649Ssaidi@eecs.umich.edu 362068SN/Aoutput header {{ 372068SN/A /** 382068SN/A * Base class for emulated call_pal calls (used only in 392068SN/A * non-full-system mode). 402068SN/A */ 412068SN/A class EmulatedCallPal : public AlphaStaticInst 422068SN/A { 432068SN/A protected: 442068SN/A 452068SN/A /// Constructor. 462227SN/A EmulatedCallPal(const char *mnem, ExtMachInst _machInst, 472068SN/A OpClass __opClass) 482068SN/A : AlphaStaticInst(mnem, _machInst, __opClass) 492068SN/A { 502068SN/A } 512068SN/A 522068SN/A std::string 532068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 542068SN/A }; 552068SN/A}}; 562068SN/A 572068SN/Aoutput decoder {{ 582068SN/A std::string 592068SN/A EmulatedCallPal::generateDisassembly(Addr pc, 602068SN/A const SymbolTable *symtab) const 612068SN/A { 622068SN/A#ifdef SS_COMPATIBLE_DISASSEMBLY 632068SN/A return csprintf("%s %s", "call_pal", mnemonic); 642068SN/A#else 652068SN/A return csprintf("%-10s %s", "call_pal", mnemonic); 662068SN/A#endif 672068SN/A } 682068SN/A}}; 692068SN/A 702068SN/Adef format EmulatedCallPal(code, *flags) {{ 713953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, 'EmulatedCallPal', code, flags) 722068SN/A header_output = BasicDeclare.subst(iop) 732068SN/A decoder_output = BasicConstructor.subst(iop) 742068SN/A decode_block = BasicDecode.subst(iop) 752068SN/A exec_output = BasicExecute.subst(iop) 762068SN/A}}; 772068SN/A 782068SN/Aoutput header {{ 792068SN/A /** 802068SN/A * Base class for full-system-mode call_pal instructions. 812068SN/A * Probably could turn this into a leaf class and get rid of the 822068SN/A * parser template. 832068SN/A */ 842068SN/A class CallPalBase : public AlphaStaticInst 852068SN/A { 862068SN/A protected: 872068SN/A int palFunc; ///< Function code part of instruction 882068SN/A int palOffset; ///< Target PC, offset from IPR_PAL_BASE 892068SN/A bool palValid; ///< is the function code valid? 902068SN/A bool palPriv; ///< is this call privileged? 912068SN/A 922068SN/A /// Constructor. 932227SN/A CallPalBase(const char *mnem, ExtMachInst _machInst, 942068SN/A OpClass __opClass); 952068SN/A 962068SN/A std::string 972068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 982068SN/A }; 992068SN/A}}; 1002068SN/A 1012068SN/Aoutput decoder {{ 1022068SN/A inline 1032227SN/A CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst, 1042068SN/A OpClass __opClass) 1052068SN/A : AlphaStaticInst(mnem, _machInst, __opClass), 1062068SN/A palFunc(PALFUNC) 1072068SN/A { 1082068SN/A // From the 21164 HRM (paraphrased): 1092068SN/A // Bit 7 of the function code (mask 0x80) indicates 1102068SN/A // whether the call is privileged (bit 7 == 0) or 1112068SN/A // unprivileged (bit 7 == 1). The privileged call table 1122068SN/A // starts at 0x2000, the unprivielged call table starts at 1132068SN/A // 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the 1142068SN/A // offset. 1152068SN/A const int palPrivMask = 0x80; 1162068SN/A const int palOffsetMask = 0x3f; 1172068SN/A 1182068SN/A // Pal call is invalid unless all other bits are 0 1192068SN/A palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0); 1202068SN/A palPriv = ((machInst & palPrivMask) == 0); 1212068SN/A int shortPalFunc = (machInst & palOffsetMask); 1222068SN/A // Add 1 to base to set pal-mode bit 1232068SN/A palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6); 1242068SN/A } 1252068SN/A 1262068SN/A std::string 1272068SN/A CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1282068SN/A { 1292068SN/A return csprintf("%-10s %#x", "call_pal", palFunc); 1302068SN/A } 1312068SN/A}}; 1322068SN/A 1332068SN/Adef format CallPal(code, *flags) {{ 1343953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, 'CallPalBase', code, flags) 1352068SN/A header_output = BasicDeclare.subst(iop) 1362068SN/A decoder_output = BasicConstructor.subst(iop) 1372068SN/A decode_block = BasicDecode.subst(iop) 1382068SN/A exec_output = BasicExecute.subst(iop) 1392068SN/A}}; 1402068SN/A 1412068SN/A//////////////////////////////////////////////////////////////////// 1422068SN/A// 1432068SN/A// hw_ld, hw_st 1442068SN/A// 1452068SN/A 1462068SN/Aoutput header {{ 1472068SN/A /** 1482068SN/A * Base class for hw_ld and hw_st. 1492068SN/A */ 1502068SN/A class HwLoadStore : public Memory 1512068SN/A { 1522068SN/A protected: 1532068SN/A 1542068SN/A /// Displacement for EA calculation (signed). 1552068SN/A int16_t disp; 1562068SN/A 1572068SN/A /// Constructor 1582227SN/A HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 1592107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 1602107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr); 1612068SN/A 1622068SN/A std::string 1632068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1642068SN/A }; 1652068SN/A}}; 1662068SN/A 1672068SN/A 1682068SN/Aoutput decoder {{ 1692068SN/A inline 1702227SN/A HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst, 1712068SN/A OpClass __opClass, 1722107SN/A StaticInstPtr _eaCompPtr, 1732107SN/A StaticInstPtr _memAccPtr) 1742068SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 1752068SN/A disp(HW_LDST_DISP) 1762068SN/A { 1775736Snate@binkert.org memAccessFlags.clear(); 1785736Snate@binkert.org if (HW_LDST_PHYS) memAccessFlags.set(Request::PHYSICAL); 1795736Snate@binkert.org if (HW_LDST_ALT) memAccessFlags.set(Request::ALTMODE); 1805736Snate@binkert.org if (HW_LDST_VPTE) memAccessFlags.set(Request::VPTE); 1816076Sgblack@eecs.umich.edu if (HW_LDST_LOCK) memAccessFlags.set(Request::LLSC); 1822068SN/A } 1832068SN/A 1842068SN/A std::string 1852068SN/A HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1862068SN/A { 1872068SN/A#ifdef SS_COMPATIBLE_DISASSEMBLY 1882068SN/A return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB); 1892068SN/A#else 1902068SN/A // HW_LDST_LOCK and HW_LDST_COND are the same bit. 1912068SN/A const char *lock_str = 1922068SN/A (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : ""; 1932068SN/A 1942068SN/A return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s", 1952068SN/A mnemonic, RA, disp, RB, 1962068SN/A HW_LDST_PHYS ? ",PHYS" : "", 1972068SN/A HW_LDST_ALT ? ",ALT" : "", 1982068SN/A HW_LDST_QUAD ? ",QUAD" : "", 1992068SN/A HW_LDST_VPTE ? ",VPTE" : "", 2002068SN/A lock_str); 2012068SN/A#endif 2022068SN/A } 2032068SN/A}}; 2042068SN/A 2052069SN/Adef format HwLoad(ea_code, memacc_code, class_ext, *flags) {{ 2062068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 2072068SN/A LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 2082075SN/A mem_flags = [], inst_flags = flags, 2092075SN/A base_class = 'HwLoadStore', exec_template_base = 'Load') 2102069SN/A}}; 2112069SN/A 2122069SN/A 2132069SN/Adef format HwStore(ea_code, memacc_code, class_ext, *flags) {{ 2142069SN/A (header_output, decoder_output, decode_block, exec_output) = \ 2152069SN/A LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 2162075SN/A mem_flags = [], inst_flags = flags, 2172075SN/A base_class = 'HwLoadStore', exec_template_base = 'Store') 2182068SN/A}}; 2192068SN/A 2202068SN/A 2212075SN/Adef format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, 2222075SN/A *flags) {{ 2232068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 2242068SN/A LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 2252075SN/A postacc_code, mem_flags = [], inst_flags = flags, 2262075SN/A base_class = 'HwLoadStore') 2272068SN/A}}; 2282068SN/A 2292068SN/A 2302068SN/Aoutput header {{ 2312068SN/A /** 2322068SN/A * Base class for hw_mfpr and hw_mtpr. 2332068SN/A */ 2342068SN/A class HwMoveIPR : public AlphaStaticInst 2352068SN/A { 2362068SN/A protected: 2372068SN/A /// Index of internal processor register. 2382068SN/A int ipr_index; 2392068SN/A 2402068SN/A /// Constructor 2412227SN/A HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 2422068SN/A : AlphaStaticInst(mnem, _machInst, __opClass), 2432068SN/A ipr_index(HW_IPR_IDX) 2442068SN/A { 2452068SN/A } 2462068SN/A 2472068SN/A std::string 2482068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 2492068SN/A }; 2502068SN/A}}; 2512068SN/A 2522068SN/Aoutput decoder {{ 2532068SN/A std::string 2542068SN/A HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 2552068SN/A { 2562068SN/A if (_numSrcRegs > 0) { 2572068SN/A // must be mtpr 2582068SN/A return csprintf("%-10s r%d,IPR(%#x)", 2592068SN/A mnemonic, RA, ipr_index); 2602068SN/A } 2612068SN/A else { 2622068SN/A // must be mfpr 2632068SN/A return csprintf("%-10s IPR(%#x),r%d", 2642068SN/A mnemonic, ipr_index, RA); 2652068SN/A } 2662068SN/A } 2672068SN/A}}; 2682068SN/A 2692292SN/Adef format HwMoveIPR(code, *flags) {{ 2702292SN/A all_flags = ['IprAccessOp'] 2712292SN/A all_flags += flags 2723953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, 'HwMoveIPR', code, all_flags) 2732068SN/A header_output = BasicDeclare.subst(iop) 2742068SN/A decoder_output = BasicConstructor.subst(iop) 2752068SN/A decode_block = BasicDecode.subst(iop) 2762068SN/A exec_output = BasicExecute.subst(iop) 2772068SN/A}}; 2782068SN/A 2792068SN/A 280