pal.isa revision 6181
112853Sgabeblack@google.com// -*- mode:c++ -*- 212853Sgabeblack@google.com 312853Sgabeblack@google.com// Copyright (c) 2003-2005 The Regents of The University of Michigan 412853Sgabeblack@google.com// All rights reserved. 512853Sgabeblack@google.com// 612853Sgabeblack@google.com// Redistribution and use in source and binary forms, with or without 712853Sgabeblack@google.com// modification, are permitted provided that the following conditions are 812853Sgabeblack@google.com// met: redistributions of source code must retain the above copyright 912853Sgabeblack@google.com// notice, this list of conditions and the following disclaimer; 1012853Sgabeblack@google.com// redistributions in binary form must reproduce the above copyright 1112853Sgabeblack@google.com// notice, this list of conditions and the following disclaimer in the 1212853Sgabeblack@google.com// documentation and/or other materials provided with the distribution; 1312853Sgabeblack@google.com// neither the name of the copyright holders nor the names of its 1412853Sgabeblack@google.com// contributors may be used to endorse or promote products derived from 1512853Sgabeblack@google.com// this software without specific prior written permission. 1612853Sgabeblack@google.com// 1712853Sgabeblack@google.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1812853Sgabeblack@google.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1912853Sgabeblack@google.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2012853Sgabeblack@google.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2112853Sgabeblack@google.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2212853Sgabeblack@google.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2312853Sgabeblack@google.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2412853Sgabeblack@google.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2512853Sgabeblack@google.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2612853Sgabeblack@google.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2712853Sgabeblack@google.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2812853Sgabeblack@google.com// 2912853Sgabeblack@google.com// Authors: Steve Reinhardt 3012853Sgabeblack@google.com 3112853Sgabeblack@google.com//////////////////////////////////////////////////////////////////// 3212853Sgabeblack@google.com// 3312853Sgabeblack@google.com// PAL calls & PAL-specific instructions 3412853Sgabeblack@google.com// 3512853Sgabeblack@google.com 3612853Sgabeblack@google.comoutput header {{ 3712853Sgabeblack@google.com /** 3812853Sgabeblack@google.com * Base class for emulated call_pal calls (used only in 3912853Sgabeblack@google.com * non-full-system mode). 4012853Sgabeblack@google.com */ 4112853Sgabeblack@google.com class EmulatedCallPal : public AlphaStaticInst 4212853Sgabeblack@google.com { 4312853Sgabeblack@google.com protected: 4412853Sgabeblack@google.com 4512853Sgabeblack@google.com /// Constructor. 4612853Sgabeblack@google.com EmulatedCallPal(const char *mnem, ExtMachInst _machInst, 4712853Sgabeblack@google.com OpClass __opClass) 4812853Sgabeblack@google.com : AlphaStaticInst(mnem, _machInst, __opClass) 4912853Sgabeblack@google.com { 5012853Sgabeblack@google.com } 5112853Sgabeblack@google.com 5212853Sgabeblack@google.com std::string 5312853Sgabeblack@google.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 5412853Sgabeblack@google.com }; 5512853Sgabeblack@google.com}}; 5612853Sgabeblack@google.com 5712853Sgabeblack@google.comoutput decoder {{ 5812853Sgabeblack@google.com std::string 5912853Sgabeblack@google.com EmulatedCallPal::generateDisassembly(Addr pc, 6012853Sgabeblack@google.com const SymbolTable *symtab) const 6112853Sgabeblack@google.com { 6212853Sgabeblack@google.com#ifdef SS_COMPATIBLE_DISASSEMBLY 6312853Sgabeblack@google.com return csprintf("%s %s", "call_pal", mnemonic); 6412853Sgabeblack@google.com#else 6512853Sgabeblack@google.com return csprintf("%-10s %s", "call_pal", mnemonic); 6612853Sgabeblack@google.com#endif 6712853Sgabeblack@google.com } 6812853Sgabeblack@google.com}}; 6912853Sgabeblack@google.com 7012853Sgabeblack@google.comdef format EmulatedCallPal(code, *flags) {{ 7112853Sgabeblack@google.com iop = InstObjParams(name, Name, 'EmulatedCallPal', code, flags) 7212853Sgabeblack@google.com header_output = BasicDeclare.subst(iop) 7312853Sgabeblack@google.com decoder_output = BasicConstructor.subst(iop) 7412853Sgabeblack@google.com decode_block = BasicDecode.subst(iop) 7512853Sgabeblack@google.com exec_output = BasicExecute.subst(iop) 7612853Sgabeblack@google.com}}; 7712853Sgabeblack@google.com 7812853Sgabeblack@google.comoutput header {{ 7912853Sgabeblack@google.com /** 8012853Sgabeblack@google.com * Base class for full-system-mode call_pal instructions. 8112853Sgabeblack@google.com * Probably could turn this into a leaf class and get rid of the 8212853Sgabeblack@google.com * parser template. 8312853Sgabeblack@google.com */ 8412853Sgabeblack@google.com class CallPalBase : public AlphaStaticInst 8512853Sgabeblack@google.com { 8612853Sgabeblack@google.com protected: 8712853Sgabeblack@google.com int palFunc; ///< Function code part of instruction 8812853Sgabeblack@google.com int palOffset; ///< Target PC, offset from IPR_PAL_BASE 8912853Sgabeblack@google.com bool palValid; ///< is the function code valid? 9012853Sgabeblack@google.com bool palPriv; ///< is this call privileged? 9112853Sgabeblack@google.com 9212853Sgabeblack@google.com /// Constructor. 9312853Sgabeblack@google.com CallPalBase(const char *mnem, ExtMachInst _machInst, 9412853Sgabeblack@google.com OpClass __opClass); 9512853Sgabeblack@google.com 9612853Sgabeblack@google.com std::string 9712853Sgabeblack@google.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 9812853Sgabeblack@google.com }; 9912853Sgabeblack@google.com}}; 10012853Sgabeblack@google.com 10112853Sgabeblack@google.comoutput decoder {{ 10212853Sgabeblack@google.com inline 10312853Sgabeblack@google.com CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst, 10412853Sgabeblack@google.com OpClass __opClass) 10512853Sgabeblack@google.com : AlphaStaticInst(mnem, _machInst, __opClass), 10612853Sgabeblack@google.com palFunc(PALFUNC) 10712853Sgabeblack@google.com { 10812853Sgabeblack@google.com // From the 21164 HRM (paraphrased): 10912853Sgabeblack@google.com // Bit 7 of the function code (mask 0x80) indicates 11012853Sgabeblack@google.com // whether the call is privileged (bit 7 == 0) or 11112853Sgabeblack@google.com // unprivileged (bit 7 == 1). The privileged call table 11212853Sgabeblack@google.com // starts at 0x2000, the unprivielged call table starts at 11312853Sgabeblack@google.com // 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the 11412853Sgabeblack@google.com // offset. 11512853Sgabeblack@google.com const int palPrivMask = 0x80; 11612853Sgabeblack@google.com const int palOffsetMask = 0x3f; 11712853Sgabeblack@google.com 11812853Sgabeblack@google.com // Pal call is invalid unless all other bits are 0 11912853Sgabeblack@google.com palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0); 12012853Sgabeblack@google.com palPriv = ((machInst & palPrivMask) == 0); 12112853Sgabeblack@google.com int shortPalFunc = (machInst & palOffsetMask); 12212853Sgabeblack@google.com // Add 1 to base to set pal-mode bit 12312853Sgabeblack@google.com palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6); 12412853Sgabeblack@google.com } 12512853Sgabeblack@google.com 12612853Sgabeblack@google.com std::string 12712853Sgabeblack@google.com CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const 12812853Sgabeblack@google.com { 12912853Sgabeblack@google.com return csprintf("%-10s %#x", "call_pal", palFunc); 13012853Sgabeblack@google.com } 13112853Sgabeblack@google.com}}; 13212853Sgabeblack@google.com 13312853Sgabeblack@google.comdef format CallPal(code, *flags) {{ 13412853Sgabeblack@google.com iop = InstObjParams(name, Name, 'CallPalBase', code, flags) 13512853Sgabeblack@google.com header_output = BasicDeclare.subst(iop) 13612853Sgabeblack@google.com decoder_output = BasicConstructor.subst(iop) 13712853Sgabeblack@google.com decode_block = BasicDecode.subst(iop) 13812853Sgabeblack@google.com exec_output = BasicExecute.subst(iop) 13912853Sgabeblack@google.com}}; 14012853Sgabeblack@google.com 14112853Sgabeblack@google.com//////////////////////////////////////////////////////////////////// 14212853Sgabeblack@google.com// 14312853Sgabeblack@google.com// hw_ld, hw_st 14412853Sgabeblack@google.com// 14512853Sgabeblack@google.com 14612853Sgabeblack@google.comoutput header {{ 14712853Sgabeblack@google.com /** 14812853Sgabeblack@google.com * Base class for hw_ld and hw_st. 14912853Sgabeblack@google.com */ 15012853Sgabeblack@google.com class HwLoadStore : public Memory 15112853Sgabeblack@google.com { 15212853Sgabeblack@google.com protected: 15312853Sgabeblack@google.com 15412853Sgabeblack@google.com /// Displacement for EA calculation (signed). 15512853Sgabeblack@google.com int16_t disp; 15612853Sgabeblack@google.com 15712853Sgabeblack@google.com /// Constructor 15812853Sgabeblack@google.com HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass); 15912853Sgabeblack@google.com 16012853Sgabeblack@google.com std::string 16112853Sgabeblack@google.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 16212853Sgabeblack@google.com }; 16312853Sgabeblack@google.com}}; 16412853Sgabeblack@google.com 16512853Sgabeblack@google.com 16612853Sgabeblack@google.comoutput decoder {{ 16712853Sgabeblack@google.com inline 16812853Sgabeblack@google.com HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst, 16912853Sgabeblack@google.com OpClass __opClass) 17012853Sgabeblack@google.com : Memory(mnem, _machInst, __opClass), disp(HW_LDST_DISP) 17112853Sgabeblack@google.com { 17212853Sgabeblack@google.com memAccessFlags.clear(); 17312853Sgabeblack@google.com if (HW_LDST_PHYS) memAccessFlags.set(Request::PHYSICAL); 17412853Sgabeblack@google.com if (HW_LDST_ALT) memAccessFlags.set(Request::ALTMODE); 17512853Sgabeblack@google.com if (HW_LDST_VPTE) memAccessFlags.set(Request::VPTE); 17612853Sgabeblack@google.com if (HW_LDST_LOCK) memAccessFlags.set(Request::LLSC); 17712853Sgabeblack@google.com } 17812853Sgabeblack@google.com 17912853Sgabeblack@google.com std::string 18012853Sgabeblack@google.com HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const 18112853Sgabeblack@google.com { 18212853Sgabeblack@google.com#ifdef SS_COMPATIBLE_DISASSEMBLY 18312853Sgabeblack@google.com return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB); 18412853Sgabeblack@google.com#else 18512853Sgabeblack@google.com // HW_LDST_LOCK and HW_LDST_COND are the same bit. 18612853Sgabeblack@google.com const char *lock_str = 18712853Sgabeblack@google.com (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : ""; 18812853Sgabeblack@google.com 18912853Sgabeblack@google.com return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s", 19012853Sgabeblack@google.com mnemonic, RA, disp, RB, 19112853Sgabeblack@google.com HW_LDST_PHYS ? ",PHYS" : "", 19212853Sgabeblack@google.com HW_LDST_ALT ? ",ALT" : "", 19312853Sgabeblack@google.com HW_LDST_QUAD ? ",QUAD" : "", 19412853Sgabeblack@google.com HW_LDST_VPTE ? ",VPTE" : "", 19512853Sgabeblack@google.com lock_str); 19612853Sgabeblack@google.com#endif 19712853Sgabeblack@google.com } 19812853Sgabeblack@google.com}}; 19912853Sgabeblack@google.com 20012853Sgabeblack@google.comdef format HwLoad(ea_code, memacc_code, class_ext, *flags) {{ 20112853Sgabeblack@google.com (header_output, decoder_output, decode_block, exec_output) = \ 20212853Sgabeblack@google.com LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 20312853Sgabeblack@google.com mem_flags = [], inst_flags = flags, 20412853Sgabeblack@google.com base_class = 'HwLoadStore', exec_template_base = 'Load') 20512853Sgabeblack@google.com}}; 20612853Sgabeblack@google.com 20712853Sgabeblack@google.com 20812853Sgabeblack@google.comdef format HwStore(ea_code, memacc_code, class_ext, *flags) {{ 20912853Sgabeblack@google.com (header_output, decoder_output, decode_block, exec_output) = \ 21012853Sgabeblack@google.com LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 21112853Sgabeblack@google.com mem_flags = [], inst_flags = flags, 21212853Sgabeblack@google.com base_class = 'HwLoadStore', exec_template_base = 'Store') 21312853Sgabeblack@google.com}}; 21412853Sgabeblack@google.com 21512853Sgabeblack@google.com 21612853Sgabeblack@google.comdef format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, 21712853Sgabeblack@google.com *flags) {{ 21812853Sgabeblack@google.com (header_output, decoder_output, decode_block, exec_output) = \ 21912853Sgabeblack@google.com LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 22012853Sgabeblack@google.com postacc_code, mem_flags = [], inst_flags = flags, 22112853Sgabeblack@google.com base_class = 'HwLoadStore') 22212853Sgabeblack@google.com}}; 22312853Sgabeblack@google.com 22412853Sgabeblack@google.com 22512853Sgabeblack@google.comoutput header {{ 22612853Sgabeblack@google.com /** 22712853Sgabeblack@google.com * Base class for hw_mfpr and hw_mtpr. 22812853Sgabeblack@google.com */ 22912853Sgabeblack@google.com class HwMoveIPR : public AlphaStaticInst 23012853Sgabeblack@google.com { 23112853Sgabeblack@google.com protected: 23212853Sgabeblack@google.com /// Index of internal processor register. 23312853Sgabeblack@google.com int ipr_index; 23412853Sgabeblack@google.com 23512853Sgabeblack@google.com /// Constructor 23612853Sgabeblack@google.com HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 23712853Sgabeblack@google.com : AlphaStaticInst(mnem, _machInst, __opClass), 23812853Sgabeblack@google.com ipr_index(HW_IPR_IDX) 23912853Sgabeblack@google.com { 24012853Sgabeblack@google.com } 24112853Sgabeblack@google.com 24212853Sgabeblack@google.com std::string 24312853Sgabeblack@google.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 24412853Sgabeblack@google.com }; 24512853Sgabeblack@google.com}}; 24612853Sgabeblack@google.com 24712853Sgabeblack@google.comoutput decoder {{ 24812853Sgabeblack@google.com std::string 24912853Sgabeblack@google.com HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 25012853Sgabeblack@google.com { 25112853Sgabeblack@google.com if (_numSrcRegs > 0) { 25212853Sgabeblack@google.com // must be mtpr 25312853Sgabeblack@google.com return csprintf("%-10s r%d,IPR(%#x)", 25412853Sgabeblack@google.com mnemonic, RA, ipr_index); 25512853Sgabeblack@google.com } 25612853Sgabeblack@google.com else { 25712853Sgabeblack@google.com // must be mfpr 25812853Sgabeblack@google.com return csprintf("%-10s IPR(%#x),r%d", 25912853Sgabeblack@google.com mnemonic, ipr_index, RA); 26012853Sgabeblack@google.com } 26112853Sgabeblack@google.com } 26212853Sgabeblack@google.com}}; 26312853Sgabeblack@google.com 26412853Sgabeblack@google.comdef format HwMoveIPR(code, *flags) {{ 26512853Sgabeblack@google.com all_flags = ['IprAccessOp'] 26612853Sgabeblack@google.com all_flags += flags 26712853Sgabeblack@google.com iop = InstObjParams(name, Name, 'HwMoveIPR', code, all_flags) 26812853Sgabeblack@google.com header_output = BasicDeclare.subst(iop) 26912853Sgabeblack@google.com decoder_output = BasicConstructor.subst(iop) 27012853Sgabeblack@google.com decode_block = BasicDecode.subst(iop) 27112853Sgabeblack@google.com exec_output = BasicExecute.subst(iop) 27212853Sgabeblack@google.com}}; 27312853Sgabeblack@google.com 27412853Sgabeblack@google.com 27512853Sgabeblack@google.com