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 5212616Sgabeblack@google.com std::string generateDisassembly( 5312616Sgabeblack@google.com Addr pc, const SymbolTable *symtab) const override; 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: 877799Sgblack@eecs.umich.edu int palFunc; ///< Function code part of instruction 887799Sgblack@eecs.umich.edu int palOffset; ///< Target PC, offset from IPR_PAL_BASE 897799Sgblack@eecs.umich.edu bool palValid; ///< is the function code valid? 907799Sgblack@eecs.umich.edu 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 9612616Sgabeblack@google.com std::string generateDisassembly( 9712616Sgabeblack@google.com Addr pc, const SymbolTable *symtab) const override; 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 1586181Sksewell@umich.edu HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass); 1592068SN/A 16012616Sgabeblack@google.com std::string generateDisassembly( 16112616Sgabeblack@google.com Addr pc, const SymbolTable *symtab) const override; 1622068SN/A }; 1632068SN/A}}; 1642068SN/A 1652068SN/A 1662068SN/Aoutput decoder {{ 1672068SN/A inline 1682227SN/A HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst, 1696181Sksewell@umich.edu OpClass __opClass) 1706181Sksewell@umich.edu : Memory(mnem, _machInst, __opClass), disp(HW_LDST_DISP) 1712068SN/A { 1725736Snate@binkert.org memAccessFlags.clear(); 1735736Snate@binkert.org if (HW_LDST_PHYS) memAccessFlags.set(Request::PHYSICAL); 17410823SAndreas.Sandberg@ARM.com if (HW_LDST_ALT) memAccessFlags.set(AlphaRequestFlags::ALTMODE); 17510823SAndreas.Sandberg@ARM.com if (HW_LDST_VPTE) memAccessFlags.set(AlphaRequestFlags::VPTE); 1766076Sgblack@eecs.umich.edu if (HW_LDST_LOCK) memAccessFlags.set(Request::LLSC); 1772068SN/A } 1782068SN/A 1792068SN/A std::string 1802068SN/A HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1812068SN/A { 1822068SN/A#ifdef SS_COMPATIBLE_DISASSEMBLY 1832068SN/A return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB); 1842068SN/A#else 1852068SN/A // HW_LDST_LOCK and HW_LDST_COND are the same bit. 1862068SN/A const char *lock_str = 1872068SN/A (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : ""; 1882068SN/A 1892068SN/A return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s", 1902068SN/A mnemonic, RA, disp, RB, 1912068SN/A HW_LDST_PHYS ? ",PHYS" : "", 1922068SN/A HW_LDST_ALT ? ",ALT" : "", 1932068SN/A HW_LDST_QUAD ? ",QUAD" : "", 1942068SN/A HW_LDST_VPTE ? ",VPTE" : "", 1952068SN/A lock_str); 1962068SN/A#endif 1972068SN/A } 1982068SN/A}}; 1992068SN/A 2002069SN/Adef format HwLoad(ea_code, memacc_code, class_ext, *flags) {{ 2012068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 2022068SN/A LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 2032075SN/A mem_flags = [], inst_flags = flags, 2042075SN/A base_class = 'HwLoadStore', exec_template_base = 'Load') 2052069SN/A}}; 2062069SN/A 2072069SN/A 2082069SN/Adef format HwStore(ea_code, memacc_code, class_ext, *flags) {{ 2092069SN/A (header_output, decoder_output, decode_block, exec_output) = \ 2102069SN/A LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 2112075SN/A mem_flags = [], inst_flags = flags, 2122075SN/A base_class = 'HwLoadStore', exec_template_base = 'Store') 2132068SN/A}}; 2142068SN/A 2152068SN/A 2162075SN/Adef format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, 2172075SN/A *flags) {{ 2182068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 2192068SN/A LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 2202075SN/A postacc_code, mem_flags = [], inst_flags = flags, 2212075SN/A base_class = 'HwLoadStore') 2222068SN/A}}; 2232068SN/A 2242068SN/A 2252068SN/Aoutput header {{ 2262068SN/A /** 2272068SN/A * Base class for hw_mfpr and hw_mtpr. 2282068SN/A */ 2292068SN/A class HwMoveIPR : public AlphaStaticInst 2302068SN/A { 2312068SN/A protected: 2322068SN/A /// Index of internal processor register. 2332068SN/A int ipr_index; 2342068SN/A 2352068SN/A /// Constructor 2362227SN/A HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 2372068SN/A : AlphaStaticInst(mnem, _machInst, __opClass), 2382068SN/A ipr_index(HW_IPR_IDX) 2392068SN/A { 2402068SN/A } 2412068SN/A 24212616Sgabeblack@google.com std::string generateDisassembly( 24312616Sgabeblack@google.com Addr pc, const SymbolTable *symtab) const override; 2442068SN/A }; 2452068SN/A}}; 2462068SN/A 2472068SN/Aoutput decoder {{ 2482068SN/A std::string 2492068SN/A HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 2502068SN/A { 2512068SN/A if (_numSrcRegs > 0) { 2522068SN/A // must be mtpr 2532068SN/A return csprintf("%-10s r%d,IPR(%#x)", 2542068SN/A mnemonic, RA, ipr_index); 2552068SN/A } 2562068SN/A else { 2572068SN/A // must be mfpr 2582068SN/A return csprintf("%-10s IPR(%#x),r%d", 2592068SN/A mnemonic, ipr_index, RA); 2602068SN/A } 2612068SN/A } 2622068SN/A}}; 2632068SN/A 2642292SN/Adef format HwMoveIPR(code, *flags) {{ 2652292SN/A all_flags = ['IprAccessOp'] 2662292SN/A all_flags += flags 2673953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, 'HwMoveIPR', code, all_flags) 2682068SN/A header_output = BasicDeclare.subst(iop) 2692068SN/A decoder_output = BasicConstructor.subst(iop) 2702068SN/A decode_block = BasicDecode.subst(iop) 2712068SN/A exec_output = BasicExecute.subst(iop) 2722068SN/A}}; 2732068SN/A 2742068SN/A 275