1// -*- mode:c++ -*- 2 3// Copyright (c) 2003-2005 The Regents of The University of Michigan 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Steve Reinhardt 30 31//////////////////////////////////////////////////////////////////// 32// 33// PAL calls & PAL-specific instructions 34// 35 36output header {{ 37 /** 38 * Base class for emulated call_pal calls (used only in 39 * non-full-system mode). 40 */ 41 class EmulatedCallPal : public AlphaStaticInst 42 { 43 protected: 44 45 /// Constructor. 46 EmulatedCallPal(const char *mnem, ExtMachInst _machInst, 47 OpClass __opClass) 48 : AlphaStaticInst(mnem, _machInst, __opClass) 49 { 50 } 51 52 std::string generateDisassembly( 53 Addr pc, const SymbolTable *symtab) const override; 54 }; 55}}; 56 57output decoder {{ 58 std::string 59 EmulatedCallPal::generateDisassembly(Addr pc, 60 const SymbolTable *symtab) const 61 { 62#ifdef SS_COMPATIBLE_DISASSEMBLY 63 return csprintf("%s %s", "call_pal", mnemonic); 64#else 65 return csprintf("%-10s %s", "call_pal", mnemonic); 66#endif 67 } 68}}; 69 70def format EmulatedCallPal(code, *flags) {{ 71 iop = InstObjParams(name, Name, 'EmulatedCallPal', code, flags) 72 header_output = BasicDeclare.subst(iop) 73 decoder_output = BasicConstructor.subst(iop) 74 decode_block = BasicDecode.subst(iop) 75 exec_output = BasicExecute.subst(iop) 76}}; 77 78output header {{ 79 /** 80 * Base class for full-system-mode call_pal instructions. 81 * Probably could turn this into a leaf class and get rid of the 82 * parser template. 83 */ 84 class CallPalBase : public AlphaStaticInst 85 { 86 protected: 87 int palFunc; ///< Function code part of instruction 88 int palOffset; ///< Target PC, offset from IPR_PAL_BASE 89 bool palValid; ///< is the function code valid? 90 bool palPriv; ///< is this call privileged? 91 92 /// Constructor. 93 CallPalBase(const char *mnem, ExtMachInst _machInst, 94 OpClass __opClass); 95 96 std::string generateDisassembly( 97 Addr pc, const SymbolTable *symtab) const override; 98 }; 99}}; 100 101output decoder {{ 102 inline 103 CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst, 104 OpClass __opClass) 105 : AlphaStaticInst(mnem, _machInst, __opClass), 106 palFunc(PALFUNC) 107 { 108 // From the 21164 HRM (paraphrased): 109 // Bit 7 of the function code (mask 0x80) indicates 110 // whether the call is privileged (bit 7 == 0) or 111 // unprivileged (bit 7 == 1). The privileged call table 112 // starts at 0x2000, the unprivielged call table starts at 113 // 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the 114 // offset. 115 const int palPrivMask = 0x80; 116 const int palOffsetMask = 0x3f; 117 118 // Pal call is invalid unless all other bits are 0 119 palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0); 120 palPriv = ((machInst & palPrivMask) == 0); 121 int shortPalFunc = (machInst & palOffsetMask); 122 // Add 1 to base to set pal-mode bit 123 palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6); 124 } 125 126 std::string 127 CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const 128 { 129 return csprintf("%-10s %#x", "call_pal", palFunc); 130 } 131}}; 132 133def format CallPal(code, *flags) {{ 134 iop = InstObjParams(name, Name, 'CallPalBase', code, flags) 135 header_output = BasicDeclare.subst(iop) 136 decoder_output = BasicConstructor.subst(iop) 137 decode_block = BasicDecode.subst(iop) 138 exec_output = BasicExecute.subst(iop) 139}}; 140 141//////////////////////////////////////////////////////////////////// 142// 143// hw_ld, hw_st 144// 145 146output header {{ 147 /** 148 * Base class for hw_ld and hw_st. 149 */ 150 class HwLoadStore : public Memory 151 { 152 protected: 153 154 /// Displacement for EA calculation (signed). 155 int16_t disp; 156 157 /// Constructor 158 HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass); 159 160 std::string generateDisassembly( 161 Addr pc, const SymbolTable *symtab) const override; 162 }; 163}}; 164 165 166output decoder {{ 167 inline 168 HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst, 169 OpClass __opClass) 170 : Memory(mnem, _machInst, __opClass), disp(HW_LDST_DISP) 171 { 172 memAccessFlags.clear(); 173 if (HW_LDST_PHYS) memAccessFlags.set(Request::PHYSICAL); 174 if (HW_LDST_ALT) memAccessFlags.set(AlphaRequestFlags::ALTMODE); 175 if (HW_LDST_VPTE) memAccessFlags.set(AlphaRequestFlags::VPTE); 176 if (HW_LDST_LOCK) memAccessFlags.set(Request::LLSC); 177 } 178 179 std::string 180 HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const 181 { 182#ifdef SS_COMPATIBLE_DISASSEMBLY 183 return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB); 184#else 185 // HW_LDST_LOCK and HW_LDST_COND are the same bit. 186 const char *lock_str = 187 (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : ""; 188 189 return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s", 190 mnemonic, RA, disp, RB, 191 HW_LDST_PHYS ? ",PHYS" : "", 192 HW_LDST_ALT ? ",ALT" : "", 193 HW_LDST_QUAD ? ",QUAD" : "", 194 HW_LDST_VPTE ? ",VPTE" : "", 195 lock_str); 196#endif 197 } 198}}; 199 200def format HwLoad(ea_code, memacc_code, class_ext, *flags) {{ 201 (header_output, decoder_output, decode_block, exec_output) = \ 202 LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 203 mem_flags = [], inst_flags = flags, 204 base_class = 'HwLoadStore', exec_template_base = 'Load') 205}}; 206 207 208def format HwStore(ea_code, memacc_code, class_ext, *flags) {{ 209 (header_output, decoder_output, decode_block, exec_output) = \ 210 LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 211 mem_flags = [], inst_flags = flags, 212 base_class = 'HwLoadStore', exec_template_base = 'Store') 213}}; 214 215 216def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, 217 *flags) {{ 218 (header_output, decoder_output, decode_block, exec_output) = \ 219 LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, 220 postacc_code, mem_flags = [], inst_flags = flags, 221 base_class = 'HwLoadStore') 222}}; 223 224 225output header {{ 226 /** 227 * Base class for hw_mfpr and hw_mtpr. 228 */ 229 class HwMoveIPR : public AlphaStaticInst 230 { 231 protected: 232 /// Index of internal processor register. 233 int ipr_index; 234 235 /// Constructor 236 HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 237 : AlphaStaticInst(mnem, _machInst, __opClass), 238 ipr_index(HW_IPR_IDX) 239 { 240 } 241 242 std::string generateDisassembly( 243 Addr pc, const SymbolTable *symtab) const override; 244 }; 245}}; 246 247output decoder {{ 248 std::string 249 HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const 250 { 251 if (_numSrcRegs > 0) { 252 // must be mtpr 253 return csprintf("%-10s r%d,IPR(%#x)", 254 mnemonic, RA, ipr_index); 255 } 256 else { 257 // must be mfpr 258 return csprintf("%-10s IPR(%#x),r%d", 259 mnemonic, ipr_index, RA); 260 } 261 } 262}}; 263 264def format HwMoveIPR(code, *flags) {{ 265 all_flags = ['IprAccessOp'] 266 all_flags += flags 267 iop = InstObjParams(name, Name, 'HwMoveIPR', code, all_flags) 268 header_output = BasicDeclare.subst(iop) 269 decoder_output = BasicConstructor.subst(iop) 270 decode_block = BasicDecode.subst(iop) 271 exec_output = BasicExecute.subst(iop) 272}}; 273 274 275