branch.isa revision 3985
12348SN/A// Copyright (c) 2006-2007 The Regents of The University of Michigan 22348SN/A// All rights reserved. 32348SN/A// 42348SN/A// Redistribution and use in source and binary forms, with or without 52348SN/A// modification, are permitted provided that the following conditions are 62348SN/A// met: redistributions of source code must retain the above copyright 72348SN/A// notice, this list of conditions and the following disclaimer; 82348SN/A// redistributions in binary form must reproduce the above copyright 92348SN/A// notice, this list of conditions and the following disclaimer in the 102348SN/A// documentation and/or other materials provided with the distribution; 112348SN/A// neither the name of the copyright holders nor the names of its 122348SN/A// contributors may be used to endorse or promote products derived from 132348SN/A// this software without specific prior written permission. 142348SN/A// 152348SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162348SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172348SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182348SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192348SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202348SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212348SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222348SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232348SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242348SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252348SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262348SN/A// 272689Sktlim@umich.edu// Authors: Gabe Black 282689Sktlim@umich.edu// Steve Reinhardt 292348SN/A 302325SN/A//////////////////////////////////////////////////////////////////// 315804Snate@binkert.org// 323918Ssaidi@eecs.umich.edu// Branch instructions 338229Snate@binkert.org// 347813Ssteve.reinhardt@amd.com 358232Snate@binkert.orgoutput header {{ 362325SN/A /** 375804Snate@binkert.org * Base class for branch operations. 385804Snate@binkert.org */ 395804Snate@binkert.org class Branch : public SparcStaticInst 405804Snate@binkert.org { 415804Snate@binkert.org protected: 425804Snate@binkert.org // Constructor 435804Snate@binkert.org Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : 442325SN/A SparcStaticInst(mnem, _machInst, __opClass) 452325SN/A { 463918Ssaidi@eecs.umich.edu } 472325SN/A 482325SN/A std::string generateDisassembly(Addr pc, 492325SN/A const SymbolTable *symtab) const; 502325SN/A }; 512325SN/A 522348SN/A /** 532348SN/A * Base class for branch operations with an immediate displacement. 542325SN/A */ 552325SN/A class BranchDisp : public Branch 562325SN/A { 572325SN/A protected: 582325SN/A // Constructor 592325SN/A BranchDisp(const char *mnem, MachInst _machInst, 602325SN/A OpClass __opClass) : 612325SN/A Branch(mnem, _machInst, __opClass) 622325SN/A { 632325SN/A } 642325SN/A 652325SN/A std::string generateDisassembly(Addr pc, 662325SN/A const SymbolTable *symtab) const; 672325SN/A 682348SN/A int32_t disp; 692348SN/A }; 702325SN/A 712325SN/A /** 722325SN/A * Base class for branches with n bit displacements. 732325SN/A */ 742325SN/A template<int bits> 752325SN/A class BranchNBits : public BranchDisp 762325SN/A { 772325SN/A protected: 782325SN/A // Constructor 792325SN/A BranchNBits(const char *mnem, MachInst _machInst, 802325SN/A OpClass __opClass) : 812325SN/A BranchDisp(mnem, _machInst, __opClass) 822325SN/A { 832325SN/A disp = sext<bits + 2>((_machInst & mask(bits)) << 2); 842325SN/A } 852325SN/A }; 862325SN/A 872325SN/A /** 882348SN/A * Base class for 16bit split displacements. 892325SN/A */ 902325SN/A class BranchSplit : public BranchDisp 912325SN/A { 922325SN/A protected: 932325SN/A // Constructor 942325SN/A BranchSplit(const char *mnem, MachInst _machInst, 952325SN/A OpClass __opClass) : 962325SN/A BranchDisp(mnem, _machInst, __opClass) 972325SN/A { 982325SN/A disp = sext<18>((D16HI << 16) | (D16LO << 2)); 992325SN/A } 1002325SN/A }; 1012325SN/A 1022325SN/A /** 1032325SN/A * Base class for branches that use an immediate and a register to 1042325SN/A * compute their displacements. 1052348SN/A */ 1062325SN/A class BranchImm13 : public Branch 1072325SN/A { 1082325SN/A protected: 1092325SN/A // Constructor 1102325SN/A BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) : 1112325SN/A Branch(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) 1122325SN/A { 1132325SN/A } 1142325SN/A 1152325SN/A std::string generateDisassembly(Addr pc, 1162325SN/A const SymbolTable *symtab) const; 1172325SN/A 1182325SN/A int32_t imm; 1192325SN/A }; 1202325SN/A}}; 1212325SN/A 1222325SN/Aoutput decoder {{ 1233918Ssaidi@eecs.umich.edu 1242325SN/A template class BranchNBits<19>; 1252325SN/A 1262325SN/A template class BranchNBits<22>; 1272325SN/A 1282325SN/A template class BranchNBits<30>; 1292325SN/A 1302325SN/A std::string Branch::generateDisassembly(Addr pc, 1312325SN/A const SymbolTable *symtab) const 1322325SN/A { 1332325SN/A std::stringstream response; 1342325SN/A 1352325SN/A printMnemonic(response, mnemonic); 1362325SN/A printRegArray(response, _srcRegIdx, _numSrcRegs); 1372325SN/A if(_numDestRegs && _numSrcRegs) 1382325SN/A response << ", "; 1392325SN/A printDestReg(response, 0); 1402325SN/A 1412325SN/A return response.str(); 1422325SN/A } 1432325SN/A 1442325SN/A std::string BranchImm13::generateDisassembly(Addr pc, 1452325SN/A const SymbolTable *symtab) const 1462325SN/A { 1472325SN/A std::stringstream response; 1482325SN/A 1492325SN/A printMnemonic(response, mnemonic); 1502325SN/A printRegArray(response, _srcRegIdx, _numSrcRegs); 1512325SN/A if(_numSrcRegs > 0) 1522325SN/A response << ", "; 1532325SN/A ccprintf(response, "0x%x", imm); 1542325SN/A if (_numDestRegs > 0) 1552325SN/A response << ", "; 1562325SN/A printDestReg(response, 0); 1572325SN/A 1582325SN/A return response.str(); 1592325SN/A } 1602325SN/A 1612325SN/A std::string BranchDisp::generateDisassembly(Addr pc, 1622325SN/A const SymbolTable *symtab) const 1632325SN/A { 164 std::stringstream response; 165 std::string symbol; 166 Addr symbolAddr; 167 168 Addr target = disp + pc; 169 170 printMnemonic(response, mnemonic); 171 ccprintf(response, "0x%x", target); 172 173 if(symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) 174 { 175 ccprintf(response, " <%s", symbol); 176 if(symbolAddr != target) 177 ccprintf(response, "+%d>", target - symbolAddr); 178 else 179 ccprintf(response, ">"); 180 } 181 182 return response.str(); 183 } 184}}; 185 186def template BranchExecute {{ 187 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 188 Trace::InstRecord *traceData) const 189 { 190 //Attempt to execute the instruction 191 Fault fault = NoFault; 192 193 %(op_decl)s; 194 %(op_rd)s; 195 196 NNPC = xc->readNextNPC(); 197 %(code)s; 198 199 if(fault == NoFault) 200 { 201 //Write the resulting state to the execution context 202 %(op_wb)s; 203 } 204 205 return fault; 206 } 207}}; 208 209let {{ 210 handle_annul = ''' 211 { 212 if(A) 213 { 214 NPC = xc->readNextNPC(); 215 NNPC = NPC + 4; 216 } 217 else 218 { 219 NPC = xc->readNextPC(); 220 NNPC = xc->readNextNPC(); 221 } 222 }''' 223}}; 224 225// Primary format for branch instructions: 226def format Branch(code, *opt_flags) {{ 227 (usesImm, code, immCode, 228 rString, iString) = splitOutImm(code) 229 iop = InstObjParams(name, Name, 'Branch', code, opt_flags) 230 header_output = BasicDeclare.subst(iop) 231 decoder_output = BasicConstructor.subst(iop) 232 exec_output = BranchExecute.subst(iop) 233 if usesImm: 234 imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, 235 immCode, opt_flags) 236 header_output += BasicDeclare.subst(imm_iop) 237 decoder_output += BasicConstructor.subst(imm_iop) 238 exec_output += BranchExecute.subst(imm_iop) 239 decode_block = ROrImmDecode.subst(iop) 240 else: 241 decode_block = BasicDecode.subst(iop) 242}}; 243 244// Primary format for branch instructions: 245def format BranchN(bits, code, *opt_flags) {{ 246 code = re.sub(r'handle_annul', handle_annul, code) 247 new_opt_flags = [] 248 for flag in opt_flags: 249 if flag == ',a': 250 name += ',a' 251 Name += 'Annul' 252 else: 253 new_opt_flags += flag 254 iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags) 255 header_output = BasicDeclare.subst(iop) 256 decoder_output = BasicConstructor.subst(iop) 257 exec_output = BranchExecute.subst(iop) 258 decode_block = BasicDecode.subst(iop) 259}}; 260 261// Primary format for branch instructions: 262def format BranchSplit(code, *opt_flags) {{ 263 code = re.sub(r'handle_annul', handle_annul, code) 264 iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags) 265 header_output = BasicDeclare.subst(iop) 266 decoder_output = BasicConstructor.subst(iop) 267 exec_output = BranchExecute.subst(iop) 268 decode_block = BasicDecode.subst(iop) 269}}; 270 271