branch.isa revision 3273:5aa5cc05fff9
1298SN/A// Copyright (c) 2006 The Regents of The University of Michigan 211270Sandreas.sandberg@arm.com// All rights reserved. 38142SAli.Saidi@ARM.com// 48142SAli.Saidi@ARM.com// Redistribution and use in source and binary forms, with or without 58142SAli.Saidi@ARM.com// modification, are permitted provided that the following conditions are 68142SAli.Saidi@ARM.com// met: redistributions of source code must retain the above copyright 78142SAli.Saidi@ARM.com// notice, this list of conditions and the following disclaimer; 88142SAli.Saidi@ARM.com// redistributions in binary form must reproduce the above copyright 98142SAli.Saidi@ARM.com// notice, this list of conditions and the following disclaimer in the 108142SAli.Saidi@ARM.com// documentation and/or other materials provided with the distribution; 118142SAli.Saidi@ARM.com// neither the name of the copyright holders nor the names of its 128142SAli.Saidi@ARM.com// contributors may be used to endorse or promote products derived from 138142SAli.Saidi@ARM.com// this software without specific prior written permission. 148580Ssteve.reinhardt@amd.com// 152188SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16298SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17298SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18298SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19298SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20298SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21298SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22298SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23298SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24298SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25298SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26298SN/A// 27298SN/A// Authors: Gabe Black 28298SN/A// Steve Reinhardt 29298SN/A 30298SN/A//////////////////////////////////////////////////////////////////// 31298SN/A// 32298SN/A// Branch instructions 33298SN/A// 34298SN/A 35298SN/Aoutput header {{ 36298SN/A /** 37298SN/A * Base class for branch operations. 38298SN/A */ 39298SN/A class Branch : public SparcStaticInst 402665Ssaidi@eecs.umich.edu { 412665Ssaidi@eecs.umich.edu protected: 42298SN/A // Constructor 43298SN/A Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : 44954SN/A SparcStaticInst(mnem, _machInst, __opClass) 45956SN/A { 46956SN/A } 478229Snate@binkert.org 484078Sbinkertn@umich.edu std::string generateDisassembly(Addr pc, 49299SN/A const SymbolTable *symtab) const; 509659SAndreas.Sandberg@ARM.com }; 51299SN/A 528777Sgblack@eecs.umich.edu /** 539659SAndreas.Sandberg@ARM.com * Base class for branch operations with an immediate displacement. 542170SN/A */ 5510553Salexandru.dutu@amd.com class BranchDisp : public Branch 565882Snate@binkert.org { 578734Sdam.sunwoo@arm.com protected: 586658Snate@binkert.org // Constructor 591717SN/A BranchDisp(const char *mnem, MachInst _machInst, 608229Snate@binkert.org OpClass __opClass) : 612680Sktlim@umich.edu Branch(mnem, _machInst, __opClass) 628232Snate@binkert.org { 639733Sandreas@sandberg.pp.se } 648232Snate@binkert.org 658232Snate@binkert.org std::string generateDisassembly(Addr pc, 6611290Sgabor.dozsa@arm.com const SymbolTable *symtab) const; 675529Snate@binkert.org 688784Sgblack@eecs.umich.edu int32_t disp; 6911290Sgabor.dozsa@arm.com }; 7010553Salexandru.dutu@amd.com 713565Sgblack@eecs.umich.edu /** 72298SN/A * Base class for branches with n bit displacements. 735606Snate@binkert.org */ 74298SN/A template<int bits> 75695SN/A class BranchNBits : public BranchDisp 76695SN/A { 77954SN/A protected: 782080SN/A // Constructor 79298SN/A BranchNBits(const char *mnem, MachInst _machInst, 80299SN/A OpClass __opClass) : 811052SN/A BranchDisp(mnem, _machInst, __opClass) 82729SN/A { 832107SN/A disp = sext<bits + 2>((_machInst & mask(bits)) << 2); 84298SN/A } 855504Snate@binkert.org }; 865504Snate@binkert.org 878784Sgblack@eecs.umich.edu /** 888784Sgblack@eecs.umich.edu * Base class for 16bit split displacements. 898784Sgblack@eecs.umich.edu */ 908784Sgblack@eecs.umich.edu class BranchSplit : public BranchDisp 918784Sgblack@eecs.umich.edu { 925780Ssteve.reinhardt@amd.com protected: 939659SAndreas.Sandberg@ARM.com // Constructor 949659SAndreas.Sandberg@ARM.com BranchSplit(const char *mnem, MachInst _machInst, 959659SAndreas.Sandberg@ARM.com OpClass __opClass) : 969659SAndreas.Sandberg@ARM.com BranchDisp(mnem, _machInst, __opClass) 979659SAndreas.Sandberg@ARM.com { 989733Sandreas@sandberg.pp.se disp = sext<18>((D16HI << 16) | (D16LO << 2)); 999733Sandreas@sandberg.pp.se } 1009659SAndreas.Sandberg@ARM.com }; 1019659SAndreas.Sandberg@ARM.com 1029659SAndreas.Sandberg@ARM.com /** 1039659SAndreas.Sandberg@ARM.com * Base class for branches that use an immediate and a register to 1049659SAndreas.Sandberg@ARM.com * compute their displacements. 1059879Sandreas@sandberg.pp.se */ 1069879Sandreas@sandberg.pp.se class BranchImm13 : public Branch 1079879Sandreas@sandberg.pp.se { 1089879Sandreas@sandberg.pp.se protected: 1099659SAndreas.Sandberg@ARM.com // Constructor 1109659SAndreas.Sandberg@ARM.com BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) : 1119659SAndreas.Sandberg@ARM.com Branch(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) 1129659SAndreas.Sandberg@ARM.com { 1139659SAndreas.Sandberg@ARM.com } 1149659SAndreas.Sandberg@ARM.com 1159659SAndreas.Sandberg@ARM.com std::string generateDisassembly(Addr pc, 1169659SAndreas.Sandberg@ARM.com const SymbolTable *symtab) const; 1179659SAndreas.Sandberg@ARM.com 1189659SAndreas.Sandberg@ARM.com int32_t imm; 1199659SAndreas.Sandberg@ARM.com }; 1209659SAndreas.Sandberg@ARM.com}}; 1219659SAndreas.Sandberg@ARM.com 1229659SAndreas.Sandberg@ARM.comoutput decoder {{ 1239659SAndreas.Sandberg@ARM.com 1249659SAndreas.Sandberg@ARM.com template class BranchNBits<19>; 1259659SAndreas.Sandberg@ARM.com 1269659SAndreas.Sandberg@ARM.com template class BranchNBits<22>; 1279659SAndreas.Sandberg@ARM.com 1289659SAndreas.Sandberg@ARM.com template class BranchNBits<30>; 1299659SAndreas.Sandberg@ARM.com 1309659SAndreas.Sandberg@ARM.com std::string Branch::generateDisassembly(Addr pc, 1319659SAndreas.Sandberg@ARM.com const SymbolTable *symtab) const 1329659SAndreas.Sandberg@ARM.com { 1339659SAndreas.Sandberg@ARM.com std::stringstream response; 1349659SAndreas.Sandberg@ARM.com 1359659SAndreas.Sandberg@ARM.com printMnemonic(response, mnemonic); 1369659SAndreas.Sandberg@ARM.com printRegArray(response, _srcRegIdx, _numSrcRegs); 1379659SAndreas.Sandberg@ARM.com if(_numDestRegs && _numSrcRegs) 1389659SAndreas.Sandberg@ARM.com response << ", "; 1399659SAndreas.Sandberg@ARM.com printDestReg(response, 0); 1409659SAndreas.Sandberg@ARM.com 1419681Sandreas@sandberg.pp.se return response.str(); 1429681Sandreas@sandberg.pp.se } 1439681Sandreas@sandberg.pp.se 1449681Sandreas@sandberg.pp.se std::string BranchImm13::generateDisassembly(Addr pc, 1459659SAndreas.Sandberg@ARM.com const SymbolTable *symtab) const 14611289Sgabor.dozsa@arm.com { 1479659SAndreas.Sandberg@ARM.com std::stringstream response; 1489659SAndreas.Sandberg@ARM.com 1499659SAndreas.Sandberg@ARM.com printMnemonic(response, mnemonic); 1509659SAndreas.Sandberg@ARM.com printRegArray(response, _srcRegIdx, _numSrcRegs); 1519659SAndreas.Sandberg@ARM.com if(_numSrcRegs > 0) 1529659SAndreas.Sandberg@ARM.com response << ", "; 1539659SAndreas.Sandberg@ARM.com ccprintf(response, "0x%x", imm); 1549659SAndreas.Sandberg@ARM.com if (_numDestRegs > 0) 1559659SAndreas.Sandberg@ARM.com response << ", "; 1569659SAndreas.Sandberg@ARM.com printDestReg(response, 0); 1579659SAndreas.Sandberg@ARM.com 1589659SAndreas.Sandberg@ARM.com return response.str(); 1599659SAndreas.Sandberg@ARM.com } 1609659SAndreas.Sandberg@ARM.com 1619659SAndreas.Sandberg@ARM.com std::string BranchDisp::generateDisassembly(Addr pc, 1629659SAndreas.Sandberg@ARM.com const SymbolTable *symtab) const 1639659SAndreas.Sandberg@ARM.com { 1649659SAndreas.Sandberg@ARM.com std::stringstream response; 1659659SAndreas.Sandberg@ARM.com std::string symbol; 1669659SAndreas.Sandberg@ARM.com Addr symbolAddr; 1679659SAndreas.Sandberg@ARM.com 1689659SAndreas.Sandberg@ARM.com Addr target = disp + pc; 1699659SAndreas.Sandberg@ARM.com 1709659SAndreas.Sandberg@ARM.com printMnemonic(response, mnemonic); 1719659SAndreas.Sandberg@ARM.com ccprintf(response, "0x%x", target); 1729659SAndreas.Sandberg@ARM.com 1739659SAndreas.Sandberg@ARM.com if(symtab->findNearestSymbol(target, symbol, symbolAddr)) 1749659SAndreas.Sandberg@ARM.com { 1759659SAndreas.Sandberg@ARM.com ccprintf(response, " <%s", symbol); 1769659SAndreas.Sandberg@ARM.com if(symbolAddr != target) 1779659SAndreas.Sandberg@ARM.com ccprintf(response, "+%d>", target - symbolAddr); 1789659SAndreas.Sandberg@ARM.com else 1799659SAndreas.Sandberg@ARM.com ccprintf(response, ">"); 1809659SAndreas.Sandberg@ARM.com } 1819659SAndreas.Sandberg@ARM.com 1829659SAndreas.Sandberg@ARM.com return response.str(); 1839659SAndreas.Sandberg@ARM.com } 1849659SAndreas.Sandberg@ARM.com}}; 1859659SAndreas.Sandberg@ARM.com 1869659SAndreas.Sandberg@ARM.comdef template BranchExecute {{ 1879659SAndreas.Sandberg@ARM.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1889659SAndreas.Sandberg@ARM.com Trace::InstRecord *traceData) const 1899659SAndreas.Sandberg@ARM.com { 1909659SAndreas.Sandberg@ARM.com //Attempt to execute the instruction 1919659SAndreas.Sandberg@ARM.com Fault fault = NoFault; 1929659SAndreas.Sandberg@ARM.com 1939659SAndreas.Sandberg@ARM.com %(op_decl)s; 1949659SAndreas.Sandberg@ARM.com %(op_rd)s; 1959659SAndreas.Sandberg@ARM.com 1969659SAndreas.Sandberg@ARM.com NNPC = xc->readNextNPC(); 1979659SAndreas.Sandberg@ARM.com %(code)s; 1989659SAndreas.Sandberg@ARM.com 1999659SAndreas.Sandberg@ARM.com if(fault == NoFault) 2009659SAndreas.Sandberg@ARM.com { 2019659SAndreas.Sandberg@ARM.com //Write the resulting state to the execution context 2029659SAndreas.Sandberg@ARM.com %(op_wb)s; 2039659SAndreas.Sandberg@ARM.com } 2049659SAndreas.Sandberg@ARM.com 20510553Salexandru.dutu@amd.com return fault; 20610553Salexandru.dutu@amd.com } 20710553Salexandru.dutu@amd.com}}; 20810553Salexandru.dutu@amd.com 20910553Salexandru.dutu@amd.comlet {{ 21010553Salexandru.dutu@amd.com handle_annul = ''' 21110553Salexandru.dutu@amd.com { 21210553Salexandru.dutu@amd.com if(A) 21310553Salexandru.dutu@amd.com { 2149659SAndreas.Sandberg@ARM.com NPC = xc->readNextNPC(); 2159659SAndreas.Sandberg@ARM.com NNPC = NPC + 4; 2169659SAndreas.Sandberg@ARM.com } 2179659SAndreas.Sandberg@ARM.com else 2189659SAndreas.Sandberg@ARM.com { 2199659SAndreas.Sandberg@ARM.com NPC = xc->readNextPC(); 2209659SAndreas.Sandberg@ARM.com NNPC = xc->readNextNPC(); 2219659SAndreas.Sandberg@ARM.com } 2225504Snate@binkert.org }''' 2235504Snate@binkert.org}}; 224298SN/A 2259733Sandreas@sandberg.pp.se// Primary format for branch instructions: 2268806Sgblack@eecs.umich.edudef format Branch(code, *opt_flags) {{ 2278784Sgblack@eecs.umich.edu (usesImm, code, immCode, 2288806Sgblack@eecs.umich.edu rString, iString) = splitOutImm(code) 2295504Snate@binkert.org iop = InstObjParams(name, Name, 'Branch', code, opt_flags) 2305504Snate@binkert.org header_output = BasicDeclare.subst(iop) 2315504Snate@binkert.org decoder_output = BasicConstructor.subst(iop) 2325504Snate@binkert.org exec_output = BranchExecute.subst(iop) 2335504Snate@binkert.org if usesImm: 2345504Snate@binkert.org imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, 2355504Snate@binkert.org immCode, opt_flags) 2369733Sandreas@sandberg.pp.se header_output += BasicDeclare.subst(imm_iop) 2378806Sgblack@eecs.umich.edu decoder_output += BasicConstructor.subst(imm_iop) 2388806Sgblack@eecs.umich.edu exec_output += BranchExecute.subst(imm_iop) 2398666SPrakash.Ramrakhyani@arm.com decode_block = ROrImmDecode.subst(iop) 2405529Snate@binkert.org else: 2415504Snate@binkert.org decode_block = BasicDecode.subst(iop) 2425504Snate@binkert.org}}; 2435504Snate@binkert.org 2445504Snate@binkert.org// Primary format for branch instructions: 2455504Snate@binkert.orgdef format BranchN(bits, code, *opt_flags) {{ 2465504Snate@binkert.org code = re.sub(r'handle_annul', handle_annul, code) 2475504Snate@binkert.org codeBlk = CodeBlock(code) 2485504Snate@binkert.org new_opt_flags = [] 2495504Snate@binkert.org for flag in opt_flags: 2505504Snate@binkert.org if flag == ',a': 2518142SAli.Saidi@ARM.com name += ',a' 2528142SAli.Saidi@ARM.com Name += 'Annul' 2539733Sandreas@sandberg.pp.se else: 2548806Sgblack@eecs.umich.edu new_opt_flags += flag 2558806Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, new_opt_flags) 2568666SPrakash.Ramrakhyani@arm.com header_output = BasicDeclare.subst(iop) 2578142SAli.Saidi@ARM.com decoder_output = BasicConstructor.subst(iop) 2588142SAli.Saidi@ARM.com exec_output = BranchExecute.subst(iop) 2598142SAli.Saidi@ARM.com decode_block = BasicDecode.subst(iop) 2608142SAli.Saidi@ARM.com}}; 2618142SAli.Saidi@ARM.com 2628142SAli.Saidi@ARM.com// Primary format for branch instructions: 2638142SAli.Saidi@ARM.comdef format BranchSplit(code, *opt_flags) {{ 2648142SAli.Saidi@ARM.com code = re.sub(r'handle_annul', handle_annul, code) 2658142SAli.Saidi@ARM.com codeBlk = CodeBlock(code) 2668142SAli.Saidi@ARM.com iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags) 2678142SAli.Saidi@ARM.com header_output = BasicDeclare.subst(iop) 2688142SAli.Saidi@ARM.com decoder_output = BasicConstructor.subst(iop) 2698142SAli.Saidi@ARM.com exec_output = BranchExecute.subst(iop) 2708142SAli.Saidi@ARM.com decode_block = BasicDecode.subst(iop) 2718142SAli.Saidi@ARM.com}}; 2728142SAli.Saidi@ARM.com 2738142SAli.Saidi@ARM.com