util.isa revision 3391
13388Sgblack@eecs.umich.edu// Copyright (c) 2006 The Regents of The University of Michigan 23388Sgblack@eecs.umich.edu// All rights reserved. 33388Sgblack@eecs.umich.edu// 43388Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 53388Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 63388Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 73388Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 83388Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 93388Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 103388Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 113388Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 123388Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 133388Sgblack@eecs.umich.edu// this software without specific prior written permission. 143388Sgblack@eecs.umich.edu// 153388Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163388Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173388Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 183388Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 193388Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 203388Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 213388Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 223388Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 233388Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 243388Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 253388Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 263388Sgblack@eecs.umich.edu// 273388Sgblack@eecs.umich.edu// Authors: Ali Saidi 283388Sgblack@eecs.umich.edu// Gabe Black 293388Sgblack@eecs.umich.edu// Steve Reinhardt 303388Sgblack@eecs.umich.edu 313388Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////// 323388Sgblack@eecs.umich.edu// 333388Sgblack@eecs.umich.edu// Mem utility templates and functions 343388Sgblack@eecs.umich.edu// 353388Sgblack@eecs.umich.edu 363388Sgblack@eecs.umich.edu//This template provides the execute functions for a load 373388Sgblack@eecs.umich.edudef template LoadExecute {{ 383388Sgblack@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 393388Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 403388Sgblack@eecs.umich.edu { 413388Sgblack@eecs.umich.edu Fault fault = NoFault; 423388Sgblack@eecs.umich.edu Addr EA; 433388Sgblack@eecs.umich.edu %(op_decl)s; 443388Sgblack@eecs.umich.edu %(op_rd)s; 453388Sgblack@eecs.umich.edu %(ea_code)s; 463388Sgblack@eecs.umich.edu DPRINTF(Sparc, "The address is 0x%x\n", EA); 473391Sgblack@eecs.umich.edu %(fault_check)s; 483391Sgblack@eecs.umich.edu if(fault == NoFault) 493391Sgblack@eecs.umich.edu { 503391Sgblack@eecs.umich.edu fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); 513391Sgblack@eecs.umich.edu } 523391Sgblack@eecs.umich.edu if(fault == NoFault) 533391Sgblack@eecs.umich.edu { 543391Sgblack@eecs.umich.edu %(code)s; 553391Sgblack@eecs.umich.edu } 563388Sgblack@eecs.umich.edu if(fault == NoFault) 573388Sgblack@eecs.umich.edu { 583388Sgblack@eecs.umich.edu //Write the resulting state to the execution context 593388Sgblack@eecs.umich.edu %(op_wb)s; 603388Sgblack@eecs.umich.edu } 613388Sgblack@eecs.umich.edu 623388Sgblack@eecs.umich.edu return fault; 633388Sgblack@eecs.umich.edu } 643388Sgblack@eecs.umich.edu 653388Sgblack@eecs.umich.edu Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 663388Sgblack@eecs.umich.edu Trace::InstRecord * traceData) const 673388Sgblack@eecs.umich.edu { 683388Sgblack@eecs.umich.edu Fault fault = NoFault; 693388Sgblack@eecs.umich.edu Addr EA; 703388Sgblack@eecs.umich.edu uint%(mem_acc_size)s_t Mem; 713388Sgblack@eecs.umich.edu %(ea_decl)s; 723388Sgblack@eecs.umich.edu %(ea_rd)s; 733388Sgblack@eecs.umich.edu %(ea_code)s; 743391Sgblack@eecs.umich.edu %(fault_check)s; 753391Sgblack@eecs.umich.edu if(fault == NoFault) 763391Sgblack@eecs.umich.edu { 773391Sgblack@eecs.umich.edu fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); 783391Sgblack@eecs.umich.edu } 793388Sgblack@eecs.umich.edu return fault; 803388Sgblack@eecs.umich.edu } 813388Sgblack@eecs.umich.edu 823388Sgblack@eecs.umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, 833388Sgblack@eecs.umich.edu Trace::InstRecord * traceData) const 843388Sgblack@eecs.umich.edu { 853388Sgblack@eecs.umich.edu Fault fault = NoFault; 863388Sgblack@eecs.umich.edu %(code_decl)s; 873388Sgblack@eecs.umich.edu %(code_rd)s; 883388Sgblack@eecs.umich.edu Mem = pkt->get<typeof(Mem)>(); 893388Sgblack@eecs.umich.edu %(code)s; 903388Sgblack@eecs.umich.edu if(fault == NoFault) 913388Sgblack@eecs.umich.edu { 923388Sgblack@eecs.umich.edu %(code_wb)s; 933388Sgblack@eecs.umich.edu } 943388Sgblack@eecs.umich.edu return fault; 953388Sgblack@eecs.umich.edu } 963388Sgblack@eecs.umich.edu}}; 973388Sgblack@eecs.umich.edu 983388Sgblack@eecs.umich.edu//This template provides the execute functions for a store 993388Sgblack@eecs.umich.edudef template StoreExecute {{ 1003388Sgblack@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1013388Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 1023388Sgblack@eecs.umich.edu { 1033388Sgblack@eecs.umich.edu Fault fault = NoFault; 1043388Sgblack@eecs.umich.edu uint64_t write_result = 0; 1053388Sgblack@eecs.umich.edu Addr EA; 1063388Sgblack@eecs.umich.edu %(op_decl)s; 1073388Sgblack@eecs.umich.edu %(op_rd)s; 1083388Sgblack@eecs.umich.edu %(ea_code)s; 1093388Sgblack@eecs.umich.edu DPRINTF(Sparc, "The address is 0x%x\n", EA); 1103391Sgblack@eecs.umich.edu %(fault_check)s; 1113391Sgblack@eecs.umich.edu if(fault == NoFault) 1123391Sgblack@eecs.umich.edu { 1133391Sgblack@eecs.umich.edu %(code)s; 1143391Sgblack@eecs.umich.edu } 1153388Sgblack@eecs.umich.edu if(fault == NoFault) 1163388Sgblack@eecs.umich.edu { 1173388Sgblack@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); 1183388Sgblack@eecs.umich.edu } 1193388Sgblack@eecs.umich.edu if(fault == NoFault) 1203388Sgblack@eecs.umich.edu { 1213388Sgblack@eecs.umich.edu //Write the resulting state to the execution context 1223388Sgblack@eecs.umich.edu %(op_wb)s; 1233388Sgblack@eecs.umich.edu } 1243388Sgblack@eecs.umich.edu 1253388Sgblack@eecs.umich.edu return fault; 1263388Sgblack@eecs.umich.edu } 1273388Sgblack@eecs.umich.edu 1283388Sgblack@eecs.umich.edu Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 1293388Sgblack@eecs.umich.edu Trace::InstRecord * traceData) const 1303388Sgblack@eecs.umich.edu { 1313388Sgblack@eecs.umich.edu Fault fault = NoFault; 1323388Sgblack@eecs.umich.edu uint64_t write_result = 0; 1333388Sgblack@eecs.umich.edu Addr EA; 1343388Sgblack@eecs.umich.edu %(op_decl)s; 1353388Sgblack@eecs.umich.edu %(op_rd)s; 1363388Sgblack@eecs.umich.edu %(ea_code)s; 1373388Sgblack@eecs.umich.edu DPRINTF(Sparc, "The address is 0x%x\n", EA); 1383391Sgblack@eecs.umich.edu %(fault_check)s; 1393391Sgblack@eecs.umich.edu if(fault == NoFault) 1403391Sgblack@eecs.umich.edu { 1413391Sgblack@eecs.umich.edu %(code)s; 1423391Sgblack@eecs.umich.edu } 1433388Sgblack@eecs.umich.edu if(fault == NoFault) 1443388Sgblack@eecs.umich.edu { 1453388Sgblack@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); 1463388Sgblack@eecs.umich.edu } 1473388Sgblack@eecs.umich.edu if(fault == NoFault) 1483388Sgblack@eecs.umich.edu { 1493388Sgblack@eecs.umich.edu //Write the resulting state to the execution context 1503388Sgblack@eecs.umich.edu %(op_wb)s; 1513388Sgblack@eecs.umich.edu } 1523388Sgblack@eecs.umich.edu return fault; 1533388Sgblack@eecs.umich.edu } 1543388Sgblack@eecs.umich.edu 1553388Sgblack@eecs.umich.edu Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, 1563388Sgblack@eecs.umich.edu Trace::InstRecord * traceData) const 1573388Sgblack@eecs.umich.edu { 1583388Sgblack@eecs.umich.edu return NoFault; 1593388Sgblack@eecs.umich.edu } 1603388Sgblack@eecs.umich.edu}}; 1613388Sgblack@eecs.umich.edu 1623388Sgblack@eecs.umich.edu//This delcares the initiateAcc function in memory operations 1633388Sgblack@eecs.umich.edudef template InitiateAccDeclare {{ 1643388Sgblack@eecs.umich.edu Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1653388Sgblack@eecs.umich.edu}}; 1663388Sgblack@eecs.umich.edu 1673388Sgblack@eecs.umich.edu//This declares the completeAcc function in memory operations 1683388Sgblack@eecs.umich.edudef template CompleteAccDeclare {{ 1693388Sgblack@eecs.umich.edu Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 1703388Sgblack@eecs.umich.edu}}; 1713388Sgblack@eecs.umich.edu 1723391Sgblack@eecs.umich.edu//Here are some code snippets which check for various fault conditions 1733391Sgblack@eecs.umich.edulet {{ 1743391Sgblack@eecs.umich.edu # The LSB can be zero, since it's really the MSB in doubles and quads 1753391Sgblack@eecs.umich.edu # and we're dealing with doubles 1763391Sgblack@eecs.umich.edu BlockAlignmentFaultCheck = ''' 1773391Sgblack@eecs.umich.edu if(RD & 0xe) 1783391Sgblack@eecs.umich.edu fault = new IllegalInstruction; 1793391Sgblack@eecs.umich.edu else if(EA & 0x3f) 1803391Sgblack@eecs.umich.edu fault = new MemAddressNotAligned; 1813391Sgblack@eecs.umich.edu ''' 1823391Sgblack@eecs.umich.edu # XXX Need to take care of pstate.hpriv as well. The lower ASIs 1833391Sgblack@eecs.umich.edu # are split into ones that are available in priv and hpriv, and 1843391Sgblack@eecs.umich.edu # those that are only available in hpriv 1853391Sgblack@eecs.umich.edu AlternateASIPrivFaultCheck = ''' 1863391Sgblack@eecs.umich.edu if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0) 1873391Sgblack@eecs.umich.edu fault = new PrivilegedAction; 1883391Sgblack@eecs.umich.edu else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) 1893391Sgblack@eecs.umich.edu fault = new PrivilegedAction; 1903391Sgblack@eecs.umich.edu ''' 1913391Sgblack@eecs.umich.edu 1923391Sgblack@eecs.umich.edu}}; 1933391Sgblack@eecs.umich.edu 1943391Sgblack@eecs.umich.edu//A simple function to generate the name of the macro op of a certain 1953391Sgblack@eecs.umich.edu//instruction at a certain micropc 1963391Sgblack@eecs.umich.edulet {{ 1973391Sgblack@eecs.umich.edu def makeMicroName(name, microPc): 1983391Sgblack@eecs.umich.edu return name + "::" + name + "_" + str(microPc) 1993391Sgblack@eecs.umich.edu}}; 2003391Sgblack@eecs.umich.edu 2013388Sgblack@eecs.umich.edu//This function properly generates the execute functions for one of the 2023388Sgblack@eecs.umich.edu//templates above. This is needed because in one case, ea computation, 2033391Sgblack@eecs.umich.edu//fault checks and the actual code all occur in the same function, 2043388Sgblack@eecs.umich.edu//and in the other they're distributed across two. Also note that for 2053388Sgblack@eecs.umich.edu//execute functions, the name of the base class doesn't matter. 2063388Sgblack@eecs.umich.edulet {{ 2073388Sgblack@eecs.umich.edu def doSplitExecute(code, eaRegCode, eaImmCode, execute, 2083391Sgblack@eecs.umich.edu faultCode, nameReg, nameImm, NameReg, NameImm, opt_flags): 2093388Sgblack@eecs.umich.edu codeIop = InstObjParams(nameReg, NameReg, '', code, opt_flags) 2103388Sgblack@eecs.umich.edu executeCode = '' 2113388Sgblack@eecs.umich.edu for (eaCode, name, Name) in ( 2123388Sgblack@eecs.umich.edu (eaRegCode, nameReg, NameReg), 2133388Sgblack@eecs.umich.edu (eaImmCode, nameImm, NameImm)): 2143388Sgblack@eecs.umich.edu eaIop = InstObjParams(name, Name, '', eaCode, 2153391Sgblack@eecs.umich.edu opt_flags, {"fault_check": faultCode}) 2163388Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, '', code, opt_flags, 2173391Sgblack@eecs.umich.edu {"fault_check": faultCode, "ea_code" : eaCode}) 2183388Sgblack@eecs.umich.edu (iop.ea_decl, 2193388Sgblack@eecs.umich.edu iop.ea_rd, 2203388Sgblack@eecs.umich.edu iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb) 2213388Sgblack@eecs.umich.edu (iop.code_decl, 2223388Sgblack@eecs.umich.edu iop.code_rd, 2233388Sgblack@eecs.umich.edu iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb) 2243388Sgblack@eecs.umich.edu executeCode += execute.subst(iop) 2253388Sgblack@eecs.umich.edu return executeCode 2263388Sgblack@eecs.umich.edu}}; 227