branch.isa revision 3273
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 1732516SN/A if(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 } 1812516SN/A 1822516SN/A return response.str(); 1832022SN/A } 1842022SN/A}}; 1852022SN/A 1862022SN/Adef template BranchExecute {{ 1872224SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1882224SN/A Trace::InstRecord *traceData) const 1892022SN/A { 1902224SN/A //Attempt to execute the instruction 1912224SN/A Fault fault = NoFault; 1922022SN/A 1932224SN/A %(op_decl)s; 1942224SN/A %(op_rd)s; 1952516SN/A 1962516SN/A NNPC = xc->readNextNPC(); 1972224SN/A %(code)s; 1982022SN/A 1992224SN/A if(fault == NoFault) 2002224SN/A { 2012022SN/A //Write the resulting state to the execution context 2022022SN/A %(op_wb)s; 2032224SN/A } 2042022SN/A 2052224SN/A return fault; 2062022SN/A } 2072022SN/A}}; 2082022SN/A 2092580SN/Alet {{ 2102580SN/A handle_annul = ''' 2112580SN/A { 2122580SN/A if(A) 2132580SN/A { 2142580SN/A NPC = xc->readNextNPC(); 2152580SN/A NNPC = NPC + 4; 2162580SN/A } 2172580SN/A else 2182580SN/A { 2192580SN/A NPC = xc->readNextPC(); 2202580SN/A NNPC = xc->readNextNPC(); 2212580SN/A } 2222580SN/A }''' 2232580SN/A}}; 2242580SN/A 2252516SN/A// Primary format for branch instructions: 2262022SN/Adef format Branch(code, *opt_flags) {{ 2272516SN/A (usesImm, code, immCode, 2282516SN/A rString, iString) = splitOutImm(code) 2292561SN/A iop = InstObjParams(name, Name, 'Branch', code, opt_flags) 2302022SN/A header_output = BasicDeclare.subst(iop) 2312022SN/A decoder_output = BasicConstructor.subst(iop) 2322516SN/A exec_output = BranchExecute.subst(iop) 2332516SN/A if usesImm: 2342516SN/A imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, 2352561SN/A immCode, opt_flags) 2362516SN/A header_output += BasicDeclare.subst(imm_iop) 2372516SN/A decoder_output += BasicConstructor.subst(imm_iop) 2382516SN/A exec_output += BranchExecute.subst(imm_iop) 2392516SN/A decode_block = ROrImmDecode.subst(iop) 2402516SN/A else: 2412516SN/A decode_block = BasicDecode.subst(iop) 2422516SN/A}}; 2432516SN/A 2442516SN/A// Primary format for branch instructions: 2452944Sgblack@eecs.umich.edudef format BranchN(bits, code, *opt_flags) {{ 2462580SN/A code = re.sub(r'handle_annul', handle_annul, code) 2472516SN/A codeBlk = CodeBlock(code) 2483056Sgblack@eecs.umich.edu new_opt_flags = [] 2493056Sgblack@eecs.umich.edu for flag in opt_flags: 2503056Sgblack@eecs.umich.edu if flag == ',a': 2513056Sgblack@eecs.umich.edu name += ',a' 2523056Sgblack@eecs.umich.edu Name += 'Annul' 2533056Sgblack@eecs.umich.edu else: 2543056Sgblack@eecs.umich.edu new_opt_flags += flag 2553056Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, new_opt_flags) 2562516SN/A header_output = BasicDeclare.subst(iop) 2572516SN/A decoder_output = BasicConstructor.subst(iop) 2582516SN/A exec_output = BranchExecute.subst(iop) 2592516SN/A decode_block = BasicDecode.subst(iop) 2602516SN/A}}; 2612516SN/A 2622516SN/A// Primary format for branch instructions: 2632516SN/Adef format BranchSplit(code, *opt_flags) {{ 2642580SN/A code = re.sub(r'handle_annul', handle_annul, code) 2652516SN/A codeBlk = CodeBlock(code) 2662516SN/A iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags) 2672516SN/A header_output = BasicDeclare.subst(iop) 2682516SN/A decoder_output = BasicConstructor.subst(iop) 2692516SN/A exec_output = BranchExecute.subst(iop) 2702516SN/A decode_block = BasicDecode.subst(iop) 2712516SN/A}}; 2722516SN/A 273