branch.isa revision 3792
12632Sstever@eecs.umich.edu// Copyright (c) 2006 The Regents of The University of Michigan 22632Sstever@eecs.umich.edu// All rights reserved. 32632Sstever@eecs.umich.edu// 42632Sstever@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 52632Sstever@eecs.umich.edu// modification, are permitted provided that the following conditions are 62632Sstever@eecs.umich.edu// met: redistributions of source code must retain the above copyright 72632Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 82632Sstever@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 92632Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 102632Sstever@eecs.umich.edu// documentation and/or other materials provided with the distribution; 112632Sstever@eecs.umich.edu// neither the name of the copyright holders nor the names of its 122632Sstever@eecs.umich.edu// contributors may be used to endorse or promote products derived from 132632Sstever@eecs.umich.edu// this software without specific prior written permission. 142632Sstever@eecs.umich.edu// 152632Sstever@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162632Sstever@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172632Sstever@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182632Sstever@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192632Sstever@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202632Sstever@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212632Sstever@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222632Sstever@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232632Sstever@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242632Sstever@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252632Sstever@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262632Sstever@eecs.umich.edu// 272632Sstever@eecs.umich.edu// Authors: Gabe Black 282632Sstever@eecs.umich.edu// Steve Reinhardt 292632Sstever@eecs.umich.edu 302022SN/A//////////////////////////////////////////////////////////////////// 312022SN/A// 322022SN/A// Branch instructions 332022SN/A// 342022SN/A 352022SN/Aoutput header {{ 362022SN/A /** 372516SN/A * Base class for branch operations. 382022SN/A */ 392022SN/A class Branch : public SparcStaticInst 402022SN/A { 412224SN/A protected: 422224SN/A // Constructor 432224SN/A Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : 442224SN/A SparcStaticInst(mnem, _machInst, __opClass) 452224SN/A { 462224SN/A } 472022SN/A 482224SN/A std::string generateDisassembly(Addr pc, 492224SN/A const SymbolTable *symtab) const; 502022SN/A }; 512516SN/A 522516SN/A /** 532516SN/A * Base class for branch operations with an immediate displacement. 542516SN/A */ 552516SN/A class BranchDisp : public Branch 562516SN/A { 572516SN/A protected: 582516SN/A // Constructor 592516SN/A BranchDisp(const char *mnem, MachInst _machInst, 602516SN/A OpClass __opClass) : 612516SN/A Branch(mnem, _machInst, __opClass) 622516SN/A { 632516SN/A } 642516SN/A 652516SN/A std::string generateDisassembly(Addr pc, 662516SN/A const SymbolTable *symtab) const; 672516SN/A 682516SN/A int32_t disp; 692516SN/A }; 702516SN/A 712516SN/A /** 722944Sgblack@eecs.umich.edu * Base class for branches with n bit displacements. 732516SN/A */ 742944Sgblack@eecs.umich.edu template<int bits> 752944Sgblack@eecs.umich.edu class BranchNBits : public BranchDisp 762516SN/A { 772516SN/A protected: 782516SN/A // Constructor 792944Sgblack@eecs.umich.edu BranchNBits(const char *mnem, MachInst _machInst, 802516SN/A OpClass __opClass) : 812516SN/A BranchDisp(mnem, _machInst, __opClass) 822516SN/A { 833273Sgblack@eecs.umich.edu disp = sext<bits + 2>((_machInst & mask(bits)) << 2); 842516SN/A } 852516SN/A }; 862516SN/A 872516SN/A /** 882516SN/A * Base class for 16bit split displacements. 892516SN/A */ 902516SN/A class BranchSplit : public BranchDisp 912516SN/A { 922516SN/A protected: 932516SN/A // Constructor 942516SN/A BranchSplit(const char *mnem, MachInst _machInst, 952516SN/A OpClass __opClass) : 962516SN/A BranchDisp(mnem, _machInst, __opClass) 972516SN/A { 983273Sgblack@eecs.umich.edu disp = sext<18>((D16HI << 16) | (D16LO << 2)); 992516SN/A } 1002516SN/A }; 1012516SN/A 1022516SN/A /** 1032516SN/A * Base class for branches that use an immediate and a register to 1042516SN/A * compute their displacements. 1052516SN/A */ 1062516SN/A class BranchImm13 : public Branch 1072516SN/A { 1082516SN/A protected: 1092516SN/A // Constructor 1102516SN/A BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) : 1113273Sgblack@eecs.umich.edu Branch(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) 1122516SN/A { 1132516SN/A } 1142516SN/A 1152516SN/A std::string generateDisassembly(Addr pc, 1162516SN/A const SymbolTable *symtab) const; 1172516SN/A 1182516SN/A int32_t imm; 1192516SN/A }; 1202022SN/A}}; 1212022SN/A 1222022SN/Aoutput decoder {{ 1232944Sgblack@eecs.umich.edu 1242944Sgblack@eecs.umich.edu template class BranchNBits<19>; 1252944Sgblack@eecs.umich.edu 1262944Sgblack@eecs.umich.edu template class BranchNBits<22>; 1272944Sgblack@eecs.umich.edu 1282944Sgblack@eecs.umich.edu template class BranchNBits<30>; 1292944Sgblack@eecs.umich.edu 1302516SN/A std::string Branch::generateDisassembly(Addr pc, 1312516SN/A const SymbolTable *symtab) const 1322022SN/A { 1332516SN/A std::stringstream response; 1342516SN/A 1352516SN/A printMnemonic(response, mnemonic); 1362944Sgblack@eecs.umich.edu printRegArray(response, _srcRegIdx, _numSrcRegs); 1372944Sgblack@eecs.umich.edu if(_numDestRegs && _numSrcRegs) 1382516SN/A response << ", "; 1392944Sgblack@eecs.umich.edu printDestReg(response, 0); 1402516SN/A 1412516SN/A return response.str(); 1422516SN/A } 1432516SN/A 1442516SN/A std::string BranchImm13::generateDisassembly(Addr pc, 1452516SN/A const SymbolTable *symtab) const 1462516SN/A { 1472516SN/A std::stringstream response; 1482516SN/A 1492516SN/A printMnemonic(response, mnemonic); 1502944Sgblack@eecs.umich.edu printRegArray(response, _srcRegIdx, _numSrcRegs); 1512516SN/A if(_numSrcRegs > 0) 1522516SN/A response << ", "; 1532516SN/A ccprintf(response, "0x%x", imm); 1542516SN/A if (_numDestRegs > 0) 1552516SN/A response << ", "; 1562944Sgblack@eecs.umich.edu printDestReg(response, 0); 1572516SN/A 1582516SN/A return response.str(); 1592516SN/A } 1602516SN/A 1612516SN/A std::string BranchDisp::generateDisassembly(Addr pc, 1622516SN/A const SymbolTable *symtab) const 1632516SN/A { 1642516SN/A std::stringstream response; 1652516SN/A std::string symbol; 1662516SN/A Addr symbolAddr; 1672516SN/A 1682516SN/A Addr target = disp + pc; 1692516SN/A 1702516SN/A printMnemonic(response, mnemonic); 1712516SN/A ccprintf(response, "0x%x", target); 1722516SN/A 1733787Sgblack@eecs.umich.edu if(symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) 1742516SN/A { 1752516SN/A ccprintf(response, " <%s", symbol); 1762516SN/A if(symbolAddr != target) 1772580SN/A ccprintf(response, "+%d>", target - symbolAddr); 1782516SN/A else 1792516SN/A ccprintf(response, ">"); 1802516SN/A } 1813787Sgblack@eecs.umich.edu else 1823787Sgblack@eecs.umich.edu { 1833787Sgblack@eecs.umich.edu ccprintf(response, "<%d>", target); 1843787Sgblack@eecs.umich.edu } 1852516SN/A 1862516SN/A return response.str(); 1872022SN/A } 1882022SN/A}}; 1892022SN/A 1902022SN/Adef template BranchExecute {{ 1912224SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1922224SN/A Trace::InstRecord *traceData) const 1932022SN/A { 1942224SN/A //Attempt to execute the instruction 1952224SN/A Fault fault = NoFault; 1962022SN/A 1972224SN/A %(op_decl)s; 1982224SN/A %(op_rd)s; 1992516SN/A 2002516SN/A NNPC = xc->readNextNPC(); 2012224SN/A %(code)s; 2022022SN/A 2032224SN/A if(fault == NoFault) 2042224SN/A { 2052022SN/A //Write the resulting state to the execution context 2062022SN/A %(op_wb)s; 2072224SN/A } 2082022SN/A 2092224SN/A return fault; 2102022SN/A } 2112022SN/A}}; 2122022SN/A 2132580SN/Alet {{ 2142580SN/A handle_annul = ''' 2152580SN/A { 2162580SN/A if(A) 2172580SN/A { 2182580SN/A NPC = xc->readNextNPC(); 2192580SN/A NNPC = NPC + 4; 2202580SN/A } 2212580SN/A else 2222580SN/A { 2232580SN/A NPC = xc->readNextPC(); 2242580SN/A NNPC = xc->readNextNPC(); 2252580SN/A } 2262580SN/A }''' 2272580SN/A}}; 2282580SN/A 2292516SN/A// Primary format for branch instructions: 2302022SN/Adef format Branch(code, *opt_flags) {{ 2312516SN/A (usesImm, code, immCode, 2322516SN/A rString, iString) = splitOutImm(code) 2332561SN/A iop = InstObjParams(name, Name, 'Branch', code, opt_flags) 2342022SN/A header_output = BasicDeclare.subst(iop) 2352022SN/A decoder_output = BasicConstructor.subst(iop) 2362516SN/A exec_output = BranchExecute.subst(iop) 2372516SN/A if usesImm: 2382516SN/A imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, 2392561SN/A immCode, opt_flags) 2402516SN/A header_output += BasicDeclare.subst(imm_iop) 2412516SN/A decoder_output += BasicConstructor.subst(imm_iop) 2422516SN/A exec_output += BranchExecute.subst(imm_iop) 2432516SN/A decode_block = ROrImmDecode.subst(iop) 2442516SN/A else: 2452516SN/A decode_block = BasicDecode.subst(iop) 2462516SN/A}}; 2472516SN/A 2482516SN/A// Primary format for branch instructions: 2492944Sgblack@eecs.umich.edudef format BranchN(bits, code, *opt_flags) {{ 2502580SN/A code = re.sub(r'handle_annul', handle_annul, code) 2513056Sgblack@eecs.umich.edu new_opt_flags = [] 2523056Sgblack@eecs.umich.edu for flag in opt_flags: 2533056Sgblack@eecs.umich.edu if flag == ',a': 2543056Sgblack@eecs.umich.edu name += ',a' 2553056Sgblack@eecs.umich.edu Name += 'Annul' 2563056Sgblack@eecs.umich.edu else: 2573056Sgblack@eecs.umich.edu new_opt_flags += flag 2583792Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags) 2592516SN/A header_output = BasicDeclare.subst(iop) 2602516SN/A decoder_output = BasicConstructor.subst(iop) 2612516SN/A exec_output = BranchExecute.subst(iop) 2622516SN/A decode_block = BasicDecode.subst(iop) 2632516SN/A}}; 2642516SN/A 2652516SN/A// Primary format for branch instructions: 2662516SN/Adef format BranchSplit(code, *opt_flags) {{ 2672580SN/A code = re.sub(r'handle_annul', handle_annul, code) 2683792Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags) 2692516SN/A header_output = BasicDeclare.subst(iop) 2702516SN/A decoder_output = BasicConstructor.subst(iop) 2712516SN/A exec_output = BranchExecute.subst(iop) 2722516SN/A decode_block = BasicDecode.subst(iop) 2732516SN/A}}; 2742516SN/A 275