branch.isa revision 2632
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 /** 722516SN/A * Base class for branches with 19 bit displacements. 732516SN/A */ 742516SN/A class Branch19 : public BranchDisp 752516SN/A { 762516SN/A protected: 772516SN/A // Constructor 782516SN/A Branch19(const char *mnem, MachInst _machInst, 792516SN/A OpClass __opClass) : 802516SN/A BranchDisp(mnem, _machInst, __opClass) 812516SN/A { 822516SN/A disp = sign_ext(DISP19 << 2, 21); 832516SN/A } 842516SN/A }; 852516SN/A 862516SN/A /** 872516SN/A * Base class for branches with 22 bit displacements. 882516SN/A */ 892516SN/A class Branch22 : public BranchDisp 902516SN/A { 912516SN/A protected: 922516SN/A // Constructor 932516SN/A Branch22(const char *mnem, MachInst _machInst, 942516SN/A OpClass __opClass) : 952516SN/A BranchDisp(mnem, _machInst, __opClass) 962516SN/A { 972516SN/A disp = sign_ext(DISP22 << 2, 24); 982516SN/A } 992516SN/A }; 1002516SN/A 1012516SN/A /** 1022516SN/A * Base class for branches with 30 bit displacements. 1032516SN/A */ 1042516SN/A class Branch30 : public BranchDisp 1052516SN/A { 1062516SN/A protected: 1072516SN/A // Constructor 1082516SN/A Branch30(const char *mnem, MachInst _machInst, 1092516SN/A OpClass __opClass) : 1102516SN/A BranchDisp(mnem, _machInst, __opClass) 1112516SN/A { 1122516SN/A disp = sign_ext(DISP30 << 2, 32); 1132516SN/A } 1142516SN/A }; 1152516SN/A 1162516SN/A /** 1172516SN/A * Base class for 16bit split displacements. 1182516SN/A */ 1192516SN/A class BranchSplit : public BranchDisp 1202516SN/A { 1212516SN/A protected: 1222516SN/A // Constructor 1232516SN/A BranchSplit(const char *mnem, MachInst _machInst, 1242516SN/A OpClass __opClass) : 1252516SN/A BranchDisp(mnem, _machInst, __opClass) 1262516SN/A { 1272516SN/A disp = sign_ext((D16HI << 16) | (D16LO << 2), 18); 1282516SN/A } 1292516SN/A }; 1302516SN/A 1312516SN/A /** 1322516SN/A * Base class for branches that use an immediate and a register to 1332516SN/A * compute their displacements. 1342516SN/A */ 1352516SN/A class BranchImm13 : public Branch 1362516SN/A { 1372516SN/A protected: 1382516SN/A // Constructor 1392516SN/A BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) : 1402516SN/A Branch(mnem, _machInst, __opClass), imm(sign_ext(SIMM13, 13)) 1412516SN/A { 1422516SN/A } 1432516SN/A 1442516SN/A std::string generateDisassembly(Addr pc, 1452516SN/A const SymbolTable *symtab) const; 1462516SN/A 1472516SN/A int32_t imm; 1482516SN/A }; 1492022SN/A}}; 1502022SN/A 1512022SN/Aoutput decoder {{ 1522516SN/A std::string Branch::generateDisassembly(Addr pc, 1532516SN/A const SymbolTable *symtab) const 1542022SN/A { 1552516SN/A std::stringstream response; 1562516SN/A 1572516SN/A printMnemonic(response, mnemonic); 1582516SN/A 1592516SN/A if (_numSrcRegs > 0) 1602516SN/A { 1612516SN/A printReg(response, _srcRegIdx[0]); 1622516SN/A for(int x = 1; x < _numSrcRegs; x++) 1632516SN/A { 1642516SN/A response << ", "; 1652516SN/A printReg(response, _srcRegIdx[x]); 1662516SN/A } 1672516SN/A } 1682516SN/A 1692516SN/A if (_numDestRegs > 0) 1702516SN/A { 1712516SN/A if(_numSrcRegs > 0) 1722516SN/A response << ", "; 1732516SN/A printReg(response, _destRegIdx[0]); 1742516SN/A } 1752516SN/A 1762516SN/A return response.str(); 1772516SN/A } 1782516SN/A 1792516SN/A std::string BranchImm13::generateDisassembly(Addr pc, 1802516SN/A const SymbolTable *symtab) const 1812516SN/A { 1822516SN/A std::stringstream response; 1832516SN/A 1842516SN/A printMnemonic(response, mnemonic); 1852516SN/A 1862516SN/A if (_numSrcRegs > 0) 1872516SN/A { 1882516SN/A printReg(response, _srcRegIdx[0]); 1892516SN/A for(int x = 1; x < _numSrcRegs; x++) 1902516SN/A { 1912516SN/A response << ", "; 1922516SN/A printReg(response, _srcRegIdx[x]); 1932516SN/A } 1942516SN/A } 1952516SN/A 1962516SN/A if(_numSrcRegs > 0) 1972516SN/A response << ", "; 1982516SN/A 1992516SN/A ccprintf(response, "0x%x", imm); 2002516SN/A 2012516SN/A if (_numDestRegs > 0) 2022516SN/A { 2032516SN/A response << ", "; 2042516SN/A printReg(response, _destRegIdx[0]); 2052516SN/A } 2062516SN/A 2072516SN/A return response.str(); 2082516SN/A } 2092516SN/A 2102516SN/A std::string BranchDisp::generateDisassembly(Addr pc, 2112516SN/A const SymbolTable *symtab) const 2122516SN/A { 2132516SN/A std::stringstream response; 2142516SN/A std::string symbol; 2152516SN/A Addr symbolAddr; 2162516SN/A 2172516SN/A Addr target = disp + pc; 2182516SN/A 2192516SN/A printMnemonic(response, mnemonic); 2202516SN/A ccprintf(response, "0x%x", target); 2212516SN/A 2222516SN/A if(symtab->findNearestSymbol(target, symbol, symbolAddr)) 2232516SN/A { 2242516SN/A ccprintf(response, " <%s", symbol); 2252516SN/A if(symbolAddr != target) 2262580SN/A ccprintf(response, "+%d>", target - symbolAddr); 2272516SN/A else 2282516SN/A ccprintf(response, ">"); 2292516SN/A } 2302516SN/A 2312516SN/A return response.str(); 2322022SN/A } 2332022SN/A}}; 2342022SN/A 2352022SN/Adef template BranchExecute {{ 2362224SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2372224SN/A Trace::InstRecord *traceData) const 2382022SN/A { 2392224SN/A //Attempt to execute the instruction 2402224SN/A Fault fault = NoFault; 2412022SN/A 2422224SN/A %(op_decl)s; 2432224SN/A %(op_rd)s; 2442516SN/A 2452516SN/A NNPC = xc->readNextNPC(); 2462224SN/A %(code)s; 2472022SN/A 2482224SN/A if(fault == NoFault) 2492224SN/A { 2502022SN/A //Write the resulting state to the execution context 2512022SN/A %(op_wb)s; 2522224SN/A } 2532022SN/A 2542224SN/A return fault; 2552022SN/A } 2562022SN/A}}; 2572022SN/A 2582580SN/Alet {{ 2592580SN/A handle_annul = ''' 2602580SN/A { 2612580SN/A if(A) 2622580SN/A { 2632580SN/A NPC = xc->readNextNPC(); 2642580SN/A NNPC = NPC + 4; 2652580SN/A } 2662580SN/A else 2672580SN/A { 2682580SN/A NPC = xc->readNextPC(); 2692580SN/A NNPC = xc->readNextNPC(); 2702580SN/A } 2712580SN/A }''' 2722580SN/A}}; 2732580SN/A 2742516SN/A// Primary format for branch instructions: 2752022SN/Adef format Branch(code, *opt_flags) {{ 2762580SN/A code = re.sub(r'handle_annul', handle_annul, code) 2772516SN/A (usesImm, code, immCode, 2782516SN/A rString, iString) = splitOutImm(code) 2792561SN/A iop = InstObjParams(name, Name, 'Branch', code, opt_flags) 2802022SN/A header_output = BasicDeclare.subst(iop) 2812022SN/A decoder_output = BasicConstructor.subst(iop) 2822516SN/A exec_output = BranchExecute.subst(iop) 2832516SN/A if usesImm: 2842516SN/A imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, 2852561SN/A immCode, opt_flags) 2862516SN/A header_output += BasicDeclare.subst(imm_iop) 2872516SN/A decoder_output += BasicConstructor.subst(imm_iop) 2882516SN/A exec_output += BranchExecute.subst(imm_iop) 2892516SN/A decode_block = ROrImmDecode.subst(iop) 2902516SN/A else: 2912516SN/A decode_block = BasicDecode.subst(iop) 2922516SN/A}}; 2932516SN/A 2942516SN/A// Primary format for branch instructions: 2952516SN/Adef format Branch19(code, *opt_flags) {{ 2962580SN/A code = re.sub(r'handle_annul', handle_annul, code) 2972516SN/A codeBlk = CodeBlock(code) 2982516SN/A iop = InstObjParams(name, Name, 'Branch19', codeBlk, opt_flags) 2992516SN/A header_output = BasicDeclare.subst(iop) 3002516SN/A decoder_output = BasicConstructor.subst(iop) 3012516SN/A exec_output = BranchExecute.subst(iop) 3022469SN/A decode_block = BasicDecode.subst(iop) 3032516SN/A}}; 3042516SN/A 3052516SN/A// Primary format for branch instructions: 3062516SN/Adef format Branch22(code, *opt_flags) {{ 3072580SN/A code = re.sub(r'handle_annul', handle_annul, code) 3082516SN/A codeBlk = CodeBlock(code) 3092516SN/A iop = InstObjParams(name, Name, 'Branch22', codeBlk, opt_flags) 3102516SN/A header_output = BasicDeclare.subst(iop) 3112516SN/A decoder_output = BasicConstructor.subst(iop) 3122022SN/A exec_output = BranchExecute.subst(iop) 3132516SN/A decode_block = BasicDecode.subst(iop) 3142022SN/A}}; 3152516SN/A 3162516SN/A// Primary format for branch instructions: 3172516SN/Adef format Branch30(code, *opt_flags) {{ 3182580SN/A code = re.sub(r'handle_annul', handle_annul, code) 3192516SN/A codeBlk = CodeBlock(code) 3202516SN/A iop = InstObjParams(name, Name, 'Branch30', codeBlk, opt_flags) 3212516SN/A header_output = BasicDeclare.subst(iop) 3222516SN/A decoder_output = BasicConstructor.subst(iop) 3232516SN/A exec_output = BranchExecute.subst(iop) 3242516SN/A decode_block = BasicDecode.subst(iop) 3252516SN/A}}; 3262516SN/A 3272516SN/A// Primary format for branch instructions: 3282516SN/Adef format BranchSplit(code, *opt_flags) {{ 3292580SN/A code = re.sub(r'handle_annul', handle_annul, code) 3302516SN/A codeBlk = CodeBlock(code) 3312516SN/A iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags) 3322516SN/A header_output = BasicDeclare.subst(iop) 3332516SN/A decoder_output = BasicConstructor.subst(iop) 3342516SN/A exec_output = BranchExecute.subst(iop) 3352516SN/A decode_block = BasicDecode.subst(iop) 3362516SN/A}}; 3372516SN/A 338