blockmem.isa revision 7741
13901Ssaidi@eecs.umich.edu// Copyright (c) 2006-2007 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 303270SN/A//////////////////////////////////////////////////////////////////// 313270SN/A// 323270SN/A// Block Memory instructions 333270SN/A// 343270SN/A 353270SN/Aoutput header {{ 363270SN/A 373270SN/A class BlockMem : public SparcMacroInst 383270SN/A { 393270SN/A protected: 403270SN/A 413270SN/A // Constructor 423270SN/A // We make the assumption that all block memory operations 433270SN/A // Will take 8 instructions to execute 443388Sgblack@eecs.umich.edu BlockMem(const char *mnem, ExtMachInst _machInst) : 453388Sgblack@eecs.umich.edu SparcMacroInst(mnem, _machInst, No_OpClass, 8) 463270SN/A {} 473270SN/A }; 483270SN/A 493270SN/A class BlockMemImm : public BlockMem 503270SN/A { 513270SN/A protected: 523270SN/A 533270SN/A // Constructor 543388Sgblack@eecs.umich.edu BlockMemImm(const char *mnem, ExtMachInst _machInst) : 553388Sgblack@eecs.umich.edu BlockMem(mnem, _machInst) 563270SN/A {} 573270SN/A }; 583270SN/A 593440Sgblack@eecs.umich.edu class BlockMemMicro : public SparcMicroInst 603270SN/A { 613270SN/A protected: 623270SN/A 633270SN/A // Constructor 643270SN/A BlockMemMicro(const char *mnem, ExtMachInst _machInst, 653270SN/A OpClass __opClass, int8_t _offset) : 663440Sgblack@eecs.umich.edu SparcMicroInst(mnem, _machInst, __opClass), 673270SN/A offset(_offset) 683270SN/A {} 693270SN/A 703270SN/A std::string generateDisassembly(Addr pc, 713270SN/A const SymbolTable *symtab) const; 723270SN/A 733270SN/A const int8_t offset; 743270SN/A }; 753270SN/A 763270SN/A class BlockMemImmMicro : public BlockMemMicro 773270SN/A { 783270SN/A protected: 793270SN/A 803270SN/A // Constructor 813270SN/A BlockMemImmMicro(const char *mnem, ExtMachInst _machInst, 823270SN/A OpClass __opClass, int8_t _offset) : 833270SN/A BlockMemMicro(mnem, _machInst, __opClass, _offset), 843270SN/A imm(sext<13>(SIMM13)) 853270SN/A {} 863270SN/A 873270SN/A std::string generateDisassembly(Addr pc, 883270SN/A const SymbolTable *symtab) const; 893270SN/A 903270SN/A const int32_t imm; 913270SN/A }; 923270SN/A}}; 933270SN/A 943270SN/Aoutput decoder {{ 953280SN/A std::string BlockMemMicro::generateDisassembly(Addr pc, 963270SN/A const SymbolTable *symtab) const 973270SN/A { 983270SN/A std::stringstream response; 993270SN/A bool load = flags[IsLoad]; 1003270SN/A bool save = flags[IsStore]; 1013270SN/A 1023270SN/A printMnemonic(response, mnemonic); 1037741Sgblack@eecs.umich.edu if (save) { 1043270SN/A printReg(response, _srcRegIdx[0]); 1053270SN/A ccprintf(response, ", "); 1063270SN/A } 1073270SN/A ccprintf(response, "[ "); 1083270SN/A printReg(response, _srcRegIdx[!save ? 0 : 1]); 1093270SN/A ccprintf(response, " + "); 1103270SN/A printReg(response, _srcRegIdx[!save ? 1 : 2]); 1113270SN/A ccprintf(response, " ]"); 1127741Sgblack@eecs.umich.edu if (load) { 1133270SN/A ccprintf(response, ", "); 1143270SN/A printReg(response, _destRegIdx[0]); 1153270SN/A } 1163270SN/A 1173270SN/A return response.str(); 1183270SN/A } 1193270SN/A 1203280SN/A std::string BlockMemImmMicro::generateDisassembly(Addr pc, 1213270SN/A const SymbolTable *symtab) const 1223270SN/A { 1233270SN/A std::stringstream response; 1243270SN/A bool load = flags[IsLoad]; 1253270SN/A bool save = flags[IsStore]; 1263270SN/A 1273270SN/A printMnemonic(response, mnemonic); 1287741Sgblack@eecs.umich.edu if (save) { 1293379SN/A printReg(response, _srcRegIdx[1]); 1303270SN/A ccprintf(response, ", "); 1313270SN/A } 1323270SN/A ccprintf(response, "[ "); 1333379SN/A printReg(response, _srcRegIdx[0]); 1347741Sgblack@eecs.umich.edu if (imm >= 0) 1353270SN/A ccprintf(response, " + 0x%x ]", imm); 1363270SN/A else 1373270SN/A ccprintf(response, " + -0x%x ]", -imm); 1387741Sgblack@eecs.umich.edu if (load) { 1393270SN/A ccprintf(response, ", "); 1403270SN/A printReg(response, _destRegIdx[0]); 1413270SN/A } 1423270SN/A 1433270SN/A return response.str(); 1443270SN/A } 1453270SN/A 1463270SN/A}}; 1473270SN/A 1483270SN/Adef template BlockMemDeclare {{ 1493270SN/A /** 1503270SN/A * Static instruction class for a block memory operation 1513270SN/A */ 1523270SN/A class %(class_name)s : public %(base_class)s 1533270SN/A { 1543270SN/A public: 1557741Sgblack@eecs.umich.edu // Constructor 1563280SN/A %(class_name)s(ExtMachInst machInst); 1573270SN/A 1583274SN/A protected: 1593270SN/A class %(class_name)s_0 : public %(base_class)sMicro 1603270SN/A { 1613274SN/A public: 1627741Sgblack@eecs.umich.edu // Constructor 1633280SN/A %(class_name)s_0(ExtMachInst machInst); 1643270SN/A %(BasicExecDeclare)s 1653391Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 1663391Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 1673270SN/A }; 1683270SN/A 1693270SN/A class %(class_name)s_1 : public %(base_class)sMicro 1703270SN/A { 1713274SN/A public: 1727741Sgblack@eecs.umich.edu // Constructor 1733280SN/A %(class_name)s_1(ExtMachInst machInst); 1743270SN/A %(BasicExecDeclare)s 1753391Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 1763391Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 1773270SN/A }; 1783270SN/A 1793270SN/A class %(class_name)s_2 : public %(base_class)sMicro 1803270SN/A { 1813274SN/A public: 1827741Sgblack@eecs.umich.edu // Constructor 1833280SN/A %(class_name)s_2(ExtMachInst machInst); 1843270SN/A %(BasicExecDeclare)s 1853391Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 1863391Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 1873270SN/A }; 1883270SN/A 1893270SN/A class %(class_name)s_3 : public %(base_class)sMicro 1903270SN/A { 1913274SN/A public: 1927741Sgblack@eecs.umich.edu // Constructor 1933280SN/A %(class_name)s_3(ExtMachInst machInst); 1943270SN/A %(BasicExecDeclare)s 1953391Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 1963391Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 1973270SN/A }; 1983270SN/A 1993270SN/A class %(class_name)s_4 : public %(base_class)sMicro 2003270SN/A { 2013274SN/A public: 2027741Sgblack@eecs.umich.edu // Constructor 2033280SN/A %(class_name)s_4(ExtMachInst machInst); 2043270SN/A %(BasicExecDeclare)s 2053391Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 2063391Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 2073270SN/A }; 2083270SN/A 2093270SN/A class %(class_name)s_5 : public %(base_class)sMicro 2103270SN/A { 2113274SN/A public: 2127741Sgblack@eecs.umich.edu // Constructor 2133280SN/A %(class_name)s_5(ExtMachInst machInst); 2143270SN/A %(BasicExecDeclare)s 2153391Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 2163391Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 2173270SN/A }; 2183270SN/A 2193270SN/A class %(class_name)s_6 : public %(base_class)sMicro 2203270SN/A { 2213274SN/A public: 2227741Sgblack@eecs.umich.edu // Constructor 2233280SN/A %(class_name)s_6(ExtMachInst machInst); 2243270SN/A %(BasicExecDeclare)s 2253391Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 2263391Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 2273270SN/A }; 2283270SN/A 2293270SN/A class %(class_name)s_7 : public %(base_class)sMicro 2303270SN/A { 2313274SN/A public: 2327741Sgblack@eecs.umich.edu // Constructor 2333280SN/A %(class_name)s_7(ExtMachInst machInst); 2343270SN/A %(BasicExecDeclare)s 2353391Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 2363391Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 2373270SN/A }; 2383270SN/A }; 2393270SN/A}}; 2403270SN/A 2413270SN/A// Basic instruction class constructor template. 2423270SN/Adef template BlockMemConstructor {{ 2433280SN/A inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 2443388Sgblack@eecs.umich.edu : %(base_class)s("%(mnemonic)s", machInst) 2453270SN/A { 2463270SN/A %(constructor)s; 2474539Sgblack@eecs.umich.edu microops[0] = new %(class_name)s_0(machInst); 2484539Sgblack@eecs.umich.edu microops[1] = new %(class_name)s_1(machInst); 2494539Sgblack@eecs.umich.edu microops[2] = new %(class_name)s_2(machInst); 2504539Sgblack@eecs.umich.edu microops[3] = new %(class_name)s_3(machInst); 2514539Sgblack@eecs.umich.edu microops[4] = new %(class_name)s_4(machInst); 2524539Sgblack@eecs.umich.edu microops[5] = new %(class_name)s_5(machInst); 2534539Sgblack@eecs.umich.edu microops[6] = new %(class_name)s_6(machInst); 2544539Sgblack@eecs.umich.edu microops[7] = new %(class_name)s_7(machInst); 2553270SN/A } 2563270SN/A}}; 2573270SN/A 2583280SN/Adef template BlockMemMicroConstructor {{ 2593280SN/A inline %(class_name)s:: 2603280SN/A %(class_name)s_%(micro_pc)s:: 2613280SN/A %(class_name)s_%(micro_pc)s(ExtMachInst machInst) : 2623280SN/A %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]", 2633280SN/A machInst, %(op_class)s, %(micro_pc)s * 8) 2643280SN/A { 2653280SN/A %(constructor)s; 2663280SN/A %(set_flags)s; 2673280SN/A } 2683280SN/A}}; 2693280SN/A 2703270SN/Alet {{ 2713270SN/A 2725096Sgblack@eecs.umich.edu def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags): 2733270SN/A # XXX Need to take care of pstate.hpriv as well. The lower ASIs 2743270SN/A # are split into ones that are available in priv and hpriv, and 2753270SN/A # those that are only available in hpriv 2763379SN/A addrCalcReg = 'EA = Rs1 + Rs2 + offset;' 2773379SN/A addrCalcImm = 'EA = Rs1 + imm + offset;' 2783274SN/A iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags) 2793274SN/A iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags) 2803270SN/A header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm) 2813270SN/A decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm) 2823270SN/A decode_block = ROrImmDecode.subst(iop) 2833274SN/A matcher = re.compile(r'Frd_N') 2843274SN/A exec_output = '' 2853391Sgblack@eecs.umich.edu for microPc in range(8): 2863280SN/A flag_code = '' 2873391Sgblack@eecs.umich.edu if (microPc == 7): 2884539Sgblack@eecs.umich.edu flag_code = "flags[IsLastMicroop] = true;" 2893901Ssaidi@eecs.umich.edu elif (microPc == 0): 2904539Sgblack@eecs.umich.edu flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroop] = true;" 2913440Sgblack@eecs.umich.edu else: 2923440Sgblack@eecs.umich.edu flag_code = "flags[IsDelayedCommit] = true;" 2933391Sgblack@eecs.umich.edu pcedCode = matcher.sub("Frd_%d" % microPc, code) 2943792Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, 'BlockMem', 2953792Sgblack@eecs.umich.edu {"code": pcedCode, "ea_code": addrCalcReg, 2963391Sgblack@eecs.umich.edu "fault_check": faultCode, "micro_pc": microPc, 2974648Sgblack@eecs.umich.edu "set_flags": flag_code, "EA_trunc" : TruncateEA}, 2984648Sgblack@eecs.umich.edu opt_flags) 2993792Sgblack@eecs.umich.edu iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', 3003792Sgblack@eecs.umich.edu {"code": pcedCode, "ea_code": addrCalcImm, 3013391Sgblack@eecs.umich.edu "fault_check": faultCode, "micro_pc": microPc, 3024648Sgblack@eecs.umich.edu "set_flags": flag_code, "EA_trunc" : TruncateEA}, 3034648Sgblack@eecs.umich.edu opt_flags) 3043280SN/A decoder_output += BlockMemMicroConstructor.subst(iop) 3053280SN/A decoder_output += BlockMemMicroConstructor.subst(iop_imm) 3063439Sgblack@eecs.umich.edu exec_output += doDualSplitExecute( 3074040Ssaidi@eecs.umich.edu pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode, 3083391Sgblack@eecs.umich.edu makeMicroName(name, microPc), 3093391Sgblack@eecs.umich.edu makeMicroName(name + "Imm", microPc), 3103391Sgblack@eecs.umich.edu makeMicroName(Name, microPc), 3113391Sgblack@eecs.umich.edu makeMicroName(Name + "Imm", microPc), 3125096Sgblack@eecs.umich.edu "EXT_ASI", opt_flags); 3133391Sgblack@eecs.umich.edu faultCode = '' 3143270SN/A return (header_output, decoder_output, exec_output, decode_block) 3153270SN/A}}; 3163270SN/A 3175096Sgblack@eecs.umich.edudef format BlockLoad(code, *opt_flags) {{ 3184362Sgblack@eecs.umich.edu code = filterDoubles(code) 3193391Sgblack@eecs.umich.edu # We need to make sure to check the highest priority fault last. 3203391Sgblack@eecs.umich.edu # That way, if other faults have been detected, they'll be overwritten 3213391Sgblack@eecs.umich.edu # rather than the other way around. 3223391Sgblack@eecs.umich.edu faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck 3233270SN/A (header_output, 3243270SN/A decoder_output, 3253270SN/A exec_output, 3263391Sgblack@eecs.umich.edu decode_block) = doBlockMemFormat(code, faultCode, 3275096Sgblack@eecs.umich.edu LoadFuncs, name, Name, opt_flags) 3283270SN/A}}; 3293270SN/A 3305096Sgblack@eecs.umich.edudef format BlockStore(code, *opt_flags) {{ 3314362Sgblack@eecs.umich.edu code = filterDoubles(code) 3323391Sgblack@eecs.umich.edu # We need to make sure to check the highest priority fault last. 3333391Sgblack@eecs.umich.edu # That way, if other faults have been detected, they'll be overwritten 3343391Sgblack@eecs.umich.edu # rather than the other way around. 3353391Sgblack@eecs.umich.edu faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck 3363270SN/A (header_output, 3373270SN/A decoder_output, 3383270SN/A exec_output, 3393391Sgblack@eecs.umich.edu decode_block) = doBlockMemFormat(code, faultCode, 3405096Sgblack@eecs.umich.edu StoreFuncs, name, Name, opt_flags) 3413270SN/A}}; 342