util.isa revision 4040
12SN/A// Copyright (c) 2006-2007 The Regents of The University of Michigan 21762SN/A// All rights reserved. 32SN/A// 42SN/A// Redistribution and use in source and binary forms, with or without 52SN/A// modification, are permitted provided that the following conditions are 62SN/A// met: redistributions of source code must retain the above copyright 72SN/A// notice, this list of conditions and the following disclaimer; 82SN/A// redistributions in binary form must reproduce the above copyright 92SN/A// notice, this list of conditions and the following disclaimer in the 102SN/A// documentation and/or other materials provided with the distribution; 112SN/A// neither the name of the copyright holders nor the names of its 122SN/A// contributors may be used to endorse or promote products derived from 132SN/A// this software without specific prior written permission. 142SN/A// 152SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262SN/A// 272665Ssaidi@eecs.umich.edu// Authors: Ali Saidi 282665Ssaidi@eecs.umich.edu// Gabe Black 292665Ssaidi@eecs.umich.edu// Steve Reinhardt 302SN/A 312SN/A//////////////////////////////////////////////////////////////////// 322SN/A// 332SN/A// Mem utility templates and functions 342SN/A// 352SN/A 361354SN/Aoutput header {{ 371354SN/A /** 382SN/A * Base class for memory operations. 392SN/A */ 405501Snate@binkert.org class Mem : public SparcStaticInst 415546Snate@binkert.org { 427004Snate@binkert.org protected: 432SN/A 442SN/A // Constructor 455769Snate@binkert.org Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 462361SN/A SparcStaticInst(mnem, _machInst, __opClass) 476216Snate@binkert.org { 488232Snate@binkert.org } 4956SN/A 502SN/A std::string generateDisassembly(Addr pc, 515543Ssaidi@eecs.umich.edu const SymbolTable *symtab) const; 522SN/A }; 531354SN/A 541354SN/A /** 552SN/A * Class for memory operations which use an immediate offset. 562SN/A */ 572SN/A class MemImm : public Mem 582SN/A { 595501Snate@binkert.org protected: 605501Snate@binkert.org 612SN/A // Constructor 629044SAli.Saidi@ARM.com MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 632SN/A Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) 642SN/A {} 652SN/A 665769Snate@binkert.org std::string generateDisassembly(Addr pc, 678902Sandreas.hansson@arm.com const SymbolTable *symtab) const; 685769Snate@binkert.org 695769Snate@binkert.org const int32_t imm; 707059Snate@binkert.org }; 717059Snate@binkert.org}}; 727059Snate@binkert.org 737059Snate@binkert.orgoutput decoder {{ 747059Snate@binkert.org std::string Mem::generateDisassembly(Addr pc, 757059Snate@binkert.org const SymbolTable *symtab) const 767059Snate@binkert.org { 777059Snate@binkert.org std::stringstream response; 787059Snate@binkert.org bool load = flags[IsLoad]; 797059Snate@binkert.org bool store = flags[IsStore]; 807059Snate@binkert.org 817059Snate@binkert.org printMnemonic(response, mnemonic); 827059Snate@binkert.org if(store) 837059Snate@binkert.org { 847059Snate@binkert.org printReg(response, _srcRegIdx[0]); 857059Snate@binkert.org ccprintf(response, ", "); 865769Snate@binkert.org } 877058Snate@binkert.org ccprintf(response, "["); 887058Snate@binkert.org if(_srcRegIdx[!store ? 0 : 1] != 0) 897058Snate@binkert.org { 902SN/A printSrcReg(response, !store ? 0 : 1); 915502Snate@binkert.org ccprintf(response, " + "); 925502Snate@binkert.org } 935502Snate@binkert.org printSrcReg(response, !store ? 1 : 2); 945503Snate@binkert.org ccprintf(response, "]"); 955503Snate@binkert.org if(load) 965502Snate@binkert.org { 975502Snate@binkert.org ccprintf(response, ", "); 985502Snate@binkert.org printReg(response, _destRegIdx[0]); 995502Snate@binkert.org } 1005502Snate@binkert.org 1015502Snate@binkert.org return response.str(); 1025502Snate@binkert.org } 1035602Snate@binkert.org 1045602Snate@binkert.org std::string MemImm::generateDisassembly(Addr pc, 1055501Snate@binkert.org const SymbolTable *symtab) const 1065543Ssaidi@eecs.umich.edu { 1077058Snate@binkert.org std::stringstream response; 1085769Snate@binkert.org bool load = flags[IsLoad]; 1094016Sstever@eecs.umich.edu bool save = flags[IsStore]; 1104016Sstever@eecs.umich.edu 1114016Sstever@eecs.umich.edu printMnemonic(response, mnemonic); 1124016Sstever@eecs.umich.edu if(save) 1134016Sstever@eecs.umich.edu { 1144016Sstever@eecs.umich.edu printReg(response, _srcRegIdx[0]); 1154016Sstever@eecs.umich.edu ccprintf(response, ", "); 1164016Sstever@eecs.umich.edu } 1174016Sstever@eecs.umich.edu ccprintf(response, "["); 1185501Snate@binkert.org if(_srcRegIdx[!save ? 0 : 1] != 0) 1195605Snate@binkert.org { 1205605Snate@binkert.org printReg(response, _srcRegIdx[!save ? 0 : 1]); 1215605Snate@binkert.org ccprintf(response, " + "); 1225605Snate@binkert.org } 1235501Snate@binkert.org if(imm >= 0) 1244016Sstever@eecs.umich.edu ccprintf(response, "0x%x]", imm); 1255577SSteve.Reinhardt@amd.com else 1265501Snate@binkert.org ccprintf(response, "-0x%x]", -imm); 1275501Snate@binkert.org if(load) 1285501Snate@binkert.org { 1295502Snate@binkert.org ccprintf(response, ", "); 1305502Snate@binkert.org printReg(response, _destRegIdx[0]); 1315605Snate@binkert.org } 1325502Snate@binkert.org 1335502Snate@binkert.org return response.str(); 1345605Snate@binkert.org } 1355605Snate@binkert.org}}; 1365605Snate@binkert.org 1375577SSteve.Reinhardt@amd.com//This template provides the execute functions for a load 1387823Ssteve.reinhardt@amd.comdef template LoadExecute {{ 1395502Snate@binkert.org Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1405502Snate@binkert.org Trace::InstRecord *traceData) const 1415502Snate@binkert.org { 1422SN/A Fault fault = NoFault; 1435769Snate@binkert.org Addr EA; 1445769Snate@binkert.org %(fp_enable_check)s; 1455769Snate@binkert.org %(op_decl)s; 1465769Snate@binkert.org %(op_rd)s; 1475769Snate@binkert.org %(ea_code)s; 1485769Snate@binkert.org DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); 1492SN/A %(fault_check)s; 1508581Ssteve.reinhardt@amd.com if(fault == NoFault) 1518581Ssteve.reinhardt@amd.com { 1525769Snate@binkert.org fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s); 1537059Snate@binkert.org } 1545769Snate@binkert.org if(fault == NoFault) 1555769Snate@binkert.org { 1562SN/A %(code)s; 1575769Snate@binkert.org } 1585769Snate@binkert.org if(fault == NoFault) 1595769Snate@binkert.org { 1605769Snate@binkert.org //Write the resulting state to the execution context 1615769Snate@binkert.org %(op_wb)s; 1625769Snate@binkert.org } 1635769Snate@binkert.org 1645769Snate@binkert.org return fault; 1655769Snate@binkert.org } 1665769Snate@binkert.org}}; 1675769Snate@binkert.org 1685769Snate@binkert.orgdef template LoadInitiateAcc {{ 1695769Snate@binkert.org Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 1705769Snate@binkert.org Trace::InstRecord * traceData) const 1715769Snate@binkert.org { 1725769Snate@binkert.org Fault fault = NoFault; 1735769Snate@binkert.org Addr EA; 1745769Snate@binkert.org %(fp_enable_check)s; 1755769Snate@binkert.org %(op_decl)s; 1765769Snate@binkert.org %(op_rd)s; 1775769Snate@binkert.org %(ea_code)s; 1785501Snate@binkert.org DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); 1795543Ssaidi@eecs.umich.edu %(fault_check)s; 1802SN/A if(fault == NoFault) 1812SN/A { 182396SN/A fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s); 183396SN/A } 184396SN/A return fault; 185396SN/A } 1865501Snate@binkert.org}}; 1877058Snate@binkert.org 1887058Snate@binkert.orgdef template LoadCompleteAcc {{ 1893329Sstever@eecs.umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, 1907058Snate@binkert.org Trace::InstRecord * traceData) const 1917058Snate@binkert.org { 1927058Snate@binkert.org Fault fault = NoFault; 1937058Snate@binkert.org %(op_decl)s; 194396SN/A %(op_rd)s; 1957058Snate@binkert.org Mem = pkt->get<typeof(Mem)>(); 1967058Snate@binkert.org %(code)s; 1977058Snate@binkert.org if(fault == NoFault) 1987058Snate@binkert.org { 1993329Sstever@eecs.umich.edu %(op_wb)s; 2007058Snate@binkert.org } 2017058Snate@binkert.org return fault; 2027058Snate@binkert.org } 2037058Snate@binkert.org}}; 2047058Snate@binkert.org 205396SN/A//This template provides the execute functions for a store 2067058Snate@binkert.orgdef template StoreExecute {{ 2077058Snate@binkert.org Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2087058Snate@binkert.org Trace::InstRecord *traceData) const 2097058Snate@binkert.org { 210396SN/A Fault fault = NoFault; 2117058Snate@binkert.org //This is to support the conditional store in cas instructions. 2127058Snate@binkert.org //It should be optomized out in all the others 213396SN/A bool storeCond = true; 2147058Snate@binkert.org Addr EA; 2157058Snate@binkert.org %(fp_enable_check)s; 2167058Snate@binkert.org %(op_decl)s; 2177058Snate@binkert.org %(op_rd)s; 218396SN/A %(ea_code)s; 2197058Snate@binkert.org DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); 2207058Snate@binkert.org %(fault_check)s; 2217058Snate@binkert.org if(fault == NoFault) 222396SN/A { 2237058Snate@binkert.org %(code)s; 2247058Snate@binkert.org } 2257058Snate@binkert.org if(storeCond && fault == NoFault) 2264075Sbinkertn@umich.edu { 2277058Snate@binkert.org fault = xc->write((uint%(mem_acc_size)s_t)Mem, 2287058Snate@binkert.org EA, %(asi_val)s, 0); 2295501Snate@binkert.org } 2307058Snate@binkert.org if(fault == NoFault) 2317058Snate@binkert.org { 2327058Snate@binkert.org //Write the resulting state to the execution context 2337058Snate@binkert.org %(op_wb)s; 2347058Snate@binkert.org } 2357058Snate@binkert.org 236396SN/A return fault; 2372SN/A } 2382SN/A}}; 2392SN/A 2402SN/Adef template StoreInitiateAcc {{ 2418581Ssteve.reinhardt@amd.com Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 2428581Ssteve.reinhardt@amd.com Trace::InstRecord * traceData) const 2438581Ssteve.reinhardt@amd.com { 244224SN/A Fault fault = NoFault; 2458581Ssteve.reinhardt@amd.com bool storeCond = true; 2464016Sstever@eecs.umich.edu Addr EA; 2475501Snate@binkert.org %(fp_enable_check)s; 2485605Snate@binkert.org %(op_decl)s; 2495501Snate@binkert.org 2505501Snate@binkert.org %(op_rd)s; 2517823Ssteve.reinhardt@amd.com %(ea_code)s; 2525501Snate@binkert.org DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); 2534016Sstever@eecs.umich.edu %(fault_check)s; 254224SN/A if(fault == NoFault) 255224SN/A { 2565768Snate@binkert.org %(code)s; 2575768Snate@binkert.org } 258265SN/A if(storeCond && fault == NoFault) 2595501Snate@binkert.org { 2605501Snate@binkert.org fault = xc->write((uint%(mem_acc_size)s_t)Mem, 2615501Snate@binkert.org EA, %(asi_val)s, 0); 2625501Snate@binkert.org } 2635501Snate@binkert.org if(fault == NoFault) 2645501Snate@binkert.org { 2655501Snate@binkert.org //Write the resulting state to the execution context 2665501Snate@binkert.org %(op_wb)s; 2675501Snate@binkert.org } 2685501Snate@binkert.org return fault; 2695501Snate@binkert.org } 2705501Snate@binkert.org}}; 2715501Snate@binkert.org 2725501Snate@binkert.orgdef template StoreCompleteAcc {{ 2735501Snate@binkert.org Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, 2745501Snate@binkert.org Trace::InstRecord * traceData) const 2755501Snate@binkert.org { 2765501Snate@binkert.org return NoFault; 2775501Snate@binkert.org } 2785501Snate@binkert.org}}; 2795501Snate@binkert.org 2802SN/A//This delcares the initiateAcc function in memory operations 2815769Snate@binkert.orgdef template InitiateAccDeclare {{ 2822SN/A Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 2832SN/A}}; 2845769Snate@binkert.org 2852SN/A//This declares the completeAcc function in memory operations 2862SN/Adef template CompleteAccDeclare {{ 2875769Snate@binkert.org Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 2882SN/A}}; 2892667Sstever@eecs.umich.edu 2905769Snate@binkert.org//Here are some code snippets which check for various fault conditions 2912667Sstever@eecs.umich.edulet {{ 2922SN/A LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc] 2932SN/A StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc] 2942SN/A 2952SN/A # The LSB can be zero, since it's really the MSB in doubles and quads 2967058Snate@binkert.org # and we're dealing with doubles 2972SN/A BlockAlignmentFaultCheck = ''' 2985605Snate@binkert.org if(RD & 0xe) 2995501Snate@binkert.org fault = new IllegalInstruction; 3005501Snate@binkert.org else if(EA & 0x3f) 3012SN/A fault = new MemAddressNotAligned; 3025501Snate@binkert.org ''' 3035501Snate@binkert.org TwinAlignmentFaultCheck = ''' 3045501Snate@binkert.org if(RD & 0x1) 3052SN/A fault = new IllegalInstruction; 3062SN/A else if(EA & 0xf) 3072SN/A fault = new MemAddressNotAligned; 308224SN/A ''' 309224SN/A # XXX Need to take care of pstate.hpriv as well. The lower ASIs 310237SN/A # are split into ones that are available in priv and hpriv, and 3115605Snate@binkert.org # those that are only available in hpriv 312571SN/A AlternateASIPrivFaultCheck = ''' 313571SN/A if(!bits(Pstate,2,2) && !bits(Hpstate,2,2) && !AsiIsUnPriv((ASI)EXT_ASI) || 3147005Snate@binkert.org !bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI)) 3157005Snate@binkert.org fault = new PrivilegedAction; 3167005Snate@binkert.org else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) 3177005Snate@binkert.org fault = new PrivilegedAction; 3187005Snate@binkert.org ''' 3197005Snate@binkert.org 3207005Snate@binkert.org}}; 3217005Snate@binkert.org 3227005Snate@binkert.org//A simple function to generate the name of the macro op of a certain 3237005Snate@binkert.org//instruction at a certain micropc 3247005Snate@binkert.orglet {{ 3257005Snate@binkert.org def makeMicroName(name, microPc): 3267005Snate@binkert.org return name + "::" + name + "_" + str(microPc) 3277005Snate@binkert.org}}; 3287005Snate@binkert.org 3297005Snate@binkert.org//This function properly generates the execute functions for one of the 3307005Snate@binkert.org//templates above. This is needed because in one case, ea computation, 3317005Snate@binkert.org//fault checks and the actual code all occur in the same function, 3327005Snate@binkert.org//and in the other they're distributed across two. Also note that for 3337005Snate@binkert.org//execute functions, the name of the base class doesn't matter. 3347005Snate@binkert.orglet {{ 3357005Snate@binkert.org def doSplitExecute(execute, name, Name, asi, opt_flags, microParam): 3367005Snate@binkert.org microParam["asi_val"] = asi; 3377005Snate@binkert.org iop = InstObjParams(name, Name, '', microParam, opt_flags) 3387005Snate@binkert.org (execf, initf, compf) = execute 3397005Snate@binkert.org return execf.subst(iop) + initf.subst(iop) + compf.subst(iop) 3407005Snate@binkert.org 3417005Snate@binkert.org 3427005Snate@binkert.org def doDualSplitExecute(code, postacc_code, eaRegCode, eaImmCode, execute, 3437005Snate@binkert.org faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags): 3447005Snate@binkert.org executeCode = '' 3457005Snate@binkert.org for (eaCode, name, Name) in ( 3467005Snate@binkert.org (eaRegCode, nameReg, NameReg), 3477005Snate@binkert.org (eaImmCode, nameImm, NameImm)): 3487005Snate@binkert.org microParams = {"code": code, "postacc_code" : postacc_code, 3497005Snate@binkert.org "ea_code": eaCode, "fault_check": faultCode} 3507005Snate@binkert.org executeCode += doSplitExecute(execute, name, Name, 3517005Snate@binkert.org asi, opt_flags, microParams) 3527005Snate@binkert.org return executeCode 3537005Snate@binkert.org}}; 3547005Snate@binkert.org