pal.isa revision 2649
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. 282068SN/A 292649Ssaidi@eecs.umich.edu//////////////////////////////////////////////////////////////////// 302649Ssaidi@eecs.umich.edu// 312649Ssaidi@eecs.umich.edu// PAL calls & PAL-specific instructions 322649Ssaidi@eecs.umich.edu// 332649Ssaidi@eecs.umich.edu 342068SN/Aoutput header {{ 352068SN/A /** 362068SN/A * Base class for emulated call_pal calls (used only in 372068SN/A * non-full-system mode). 382068SN/A */ 392068SN/A class EmulatedCallPal : public AlphaStaticInst 402068SN/A { 412068SN/A protected: 422068SN/A 432068SN/A /// Constructor. 442227SN/A EmulatedCallPal(const char *mnem, ExtMachInst _machInst, 452068SN/A OpClass __opClass) 462068SN/A : AlphaStaticInst(mnem, _machInst, __opClass) 472068SN/A { 482068SN/A } 492068SN/A 502068SN/A std::string 512068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 522068SN/A }; 532068SN/A}}; 542068SN/A 552068SN/Aoutput decoder {{ 562068SN/A std::string 572068SN/A EmulatedCallPal::generateDisassembly(Addr pc, 582068SN/A const SymbolTable *symtab) const 592068SN/A { 602068SN/A#ifdef SS_COMPATIBLE_DISASSEMBLY 612068SN/A return csprintf("%s %s", "call_pal", mnemonic); 622068SN/A#else 632068SN/A return csprintf("%-10s %s", "call_pal", mnemonic); 642068SN/A#endif 652068SN/A } 662068SN/A}}; 672068SN/A 682068SN/Adef format EmulatedCallPal(code, *flags) {{ 692068SN/A iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags) 702068SN/A header_output = BasicDeclare.subst(iop) 712068SN/A decoder_output = BasicConstructor.subst(iop) 722068SN/A decode_block = BasicDecode.subst(iop) 732068SN/A exec_output = BasicExecute.subst(iop) 742068SN/A}}; 752068SN/A 762068SN/Aoutput header {{ 772068SN/A /** 782068SN/A * Base class for full-system-mode call_pal instructions. 792068SN/A * Probably could turn this into a leaf class and get rid of the 802068SN/A * parser template. 812068SN/A */ 822068SN/A class CallPalBase : public AlphaStaticInst 832068SN/A { 842068SN/A protected: 852068SN/A int palFunc; ///< Function code part of instruction 862068SN/A int palOffset; ///< Target PC, offset from IPR_PAL_BASE 872068SN/A bool palValid; ///< is the function code valid? 882068SN/A bool palPriv; ///< is this call privileged? 892068SN/A 902068SN/A /// Constructor. 912227SN/A CallPalBase(const char *mnem, ExtMachInst _machInst, 922068SN/A OpClass __opClass); 932068SN/A 942068SN/A std::string 952068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 962068SN/A }; 972068SN/A}}; 982068SN/A 992068SN/Aoutput decoder {{ 1002068SN/A inline 1012227SN/A CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst, 1022068SN/A OpClass __opClass) 1032068SN/A : AlphaStaticInst(mnem, _machInst, __opClass), 1042068SN/A palFunc(PALFUNC) 1052068SN/A { 1062068SN/A // From the 21164 HRM (paraphrased): 1072068SN/A // Bit 7 of the function code (mask 0x80) indicates 1082068SN/A // whether the call is privileged (bit 7 == 0) or 1092068SN/A // unprivileged (bit 7 == 1). The privileged call table 1102068SN/A // starts at 0x2000, the unprivielged call table starts at 1112068SN/A // 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the 1122068SN/A // offset. 1132068SN/A const int palPrivMask = 0x80; 1142068SN/A const int palOffsetMask = 0x3f; 1152068SN/A 1162068SN/A // Pal call is invalid unless all other bits are 0 1172068SN/A palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0); 1182068SN/A palPriv = ((machInst & palPrivMask) == 0); 1192068SN/A int shortPalFunc = (machInst & palOffsetMask); 1202068SN/A // Add 1 to base to set pal-mode bit 1212068SN/A palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6); 1222068SN/A } 1232068SN/A 1242068SN/A std::string 1252068SN/A CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1262068SN/A { 1272068SN/A return csprintf("%-10s %#x", "call_pal", palFunc); 1282068SN/A } 1292068SN/A}}; 1302068SN/A 1312068SN/Adef format CallPal(code, *flags) {{ 1322068SN/A iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags) 1332068SN/A header_output = BasicDeclare.subst(iop) 1342068SN/A decoder_output = BasicConstructor.subst(iop) 1352068SN/A decode_block = BasicDecode.subst(iop) 1362068SN/A exec_output = BasicExecute.subst(iop) 1372068SN/A}}; 1382068SN/A 1392068SN/A//////////////////////////////////////////////////////////////////// 1402068SN/A// 1412068SN/A// hw_ld, hw_st 1422068SN/A// 1432068SN/A 1442068SN/Aoutput header {{ 1452068SN/A /** 1462068SN/A * Base class for hw_ld and hw_st. 1472068SN/A */ 1482068SN/A class HwLoadStore : public Memory 1492068SN/A { 1502068SN/A protected: 1512068SN/A 1522068SN/A /// Displacement for EA calculation (signed). 1532068SN/A int16_t disp; 1542068SN/A 1552068SN/A /// Constructor 1562227SN/A HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 1572107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 1582107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr); 1592068SN/A 1602068SN/A std::string 1612068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1622068SN/A }; 1632068SN/A}}; 1642068SN/A 1652068SN/A 1662068SN/Aoutput decoder {{ 1672068SN/A inline 1682227SN/A HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst, 1692068SN/A OpClass __opClass, 1702107SN/A StaticInstPtr _eaCompPtr, 1712107SN/A StaticInstPtr _memAccPtr) 1722068SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 1732068SN/A disp(HW_LDST_DISP) 1742068SN/A { 1752068SN/A memAccessFlags = 0; 1762068SN/A if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL; 1772068SN/A if (HW_LDST_ALT) memAccessFlags |= ALTMODE; 1782068SN/A if (HW_LDST_VPTE) memAccessFlags |= VPTE; 1792068SN/A if (HW_LDST_LOCK) memAccessFlags |= LOCKED; 1802068SN/A } 1812068SN/A 1822068SN/A std::string 1832068SN/A HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1842068SN/A { 1852068SN/A#ifdef SS_COMPATIBLE_DISASSEMBLY 1862068SN/A return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB); 1872068SN/A#else 1882068SN/A // HW_LDST_LOCK and HW_LDST_COND are the same bit. 1892068SN/A const char *lock_str = 1902068SN/A (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : ""; 1912068SN/A 1922068SN/A return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s", 1932068SN/A mnemonic, RA, disp, RB, 1942068SN/A HW_LDST_PHYS ? ",PHYS" : "", 1952068SN/A HW_LDST_ALT ? ",ALT" : "", 1962068SN/A HW_LDST_QUAD ? ",QUAD" : "", 1972068SN/A HW_LDST_VPTE ? ",VPTE" : "", 1982068SN/A lock_str); 1992068SN/A#endif 2002068SN/A } 2012068SN/A}}; 2022068SN/A 2032069SN/Adef format HwLoad(ea_code, memacc_code, class_ext, *flags) {{ 2042068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 2052068SN/A LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 2062075SN/A mem_flags = [], inst_flags = flags, 2072075SN/A base_class = 'HwLoadStore', exec_template_base = 'Load') 2082069SN/A}}; 2092069SN/A 2102069SN/A 2112069SN/Adef format HwStore(ea_code, memacc_code, class_ext, *flags) {{ 2122069SN/A (header_output, decoder_output, decode_block, exec_output) = \ 2132069SN/A LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 2142075SN/A mem_flags = [], inst_flags = flags, 2152075SN/A base_class = 'HwLoadStore', exec_template_base = 'Store') 2162068SN/A}}; 2172068SN/A 2182068SN/A 2192075SN/Adef format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, 2202075SN/A *flags) {{ 2212068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 2222068SN/A LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 2232075SN/A postacc_code, mem_flags = [], inst_flags = flags, 2242075SN/A base_class = 'HwLoadStore') 2252068SN/A}}; 2262068SN/A 2272068SN/A 2282068SN/Aoutput header {{ 2292068SN/A /** 2302068SN/A * Base class for hw_mfpr and hw_mtpr. 2312068SN/A */ 2322068SN/A class HwMoveIPR : public AlphaStaticInst 2332068SN/A { 2342068SN/A protected: 2352068SN/A /// Index of internal processor register. 2362068SN/A int ipr_index; 2372068SN/A 2382068SN/A /// Constructor 2392227SN/A HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 2402068SN/A : AlphaStaticInst(mnem, _machInst, __opClass), 2412068SN/A ipr_index(HW_IPR_IDX) 2422068SN/A { 2432068SN/A } 2442068SN/A 2452068SN/A std::string 2462068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 2472068SN/A }; 2482068SN/A}}; 2492068SN/A 2502068SN/Aoutput decoder {{ 2512068SN/A std::string 2522068SN/A HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 2532068SN/A { 2542068SN/A if (_numSrcRegs > 0) { 2552068SN/A // must be mtpr 2562068SN/A return csprintf("%-10s r%d,IPR(%#x)", 2572068SN/A mnemonic, RA, ipr_index); 2582068SN/A } 2592068SN/A else { 2602068SN/A // must be mfpr 2612068SN/A return csprintf("%-10s IPR(%#x),r%d", 2622068SN/A mnemonic, ipr_index, RA); 2632068SN/A } 2642068SN/A } 2652068SN/A}}; 2662068SN/A 2672068SN/Adef format HwMoveIPR(code) {{ 2682068SN/A iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code), 2692068SN/A ['IprAccessOp']) 2702068SN/A header_output = BasicDeclare.subst(iop) 2712068SN/A decoder_output = BasicConstructor.subst(iop) 2722068SN/A decode_block = BasicDecode.subst(iop) 2732068SN/A exec_output = BasicExecute.subst(iop) 2742068SN/A}}; 2752068SN/A 2762068SN/A 277