13985Sgblack@eecs.umich.edu// Copyright (c) 2006-2007 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 355091Sgblack@eecs.umich.edudef template JumpExecute {{ 3612234Sgabeblack@google.com Fault %(class_name)s::execute(ExecContext *xc, 372224SN/A Trace::InstRecord *traceData) const 382022SN/A { 397741Sgblack@eecs.umich.edu // Attempt to execute the instruction 402224SN/A Fault fault = NoFault; 412022SN/A 422224SN/A %(op_decl)s; 432224SN/A %(op_rd)s; 442516SN/A 452224SN/A %(code)s; 462022SN/A 477741Sgblack@eecs.umich.edu if (fault == NoFault) { 487741Sgblack@eecs.umich.edu // Write the resulting state to the execution context 492022SN/A %(op_wb)s; 502224SN/A } 512022SN/A 522224SN/A return fault; 532022SN/A } 542022SN/A}}; 552022SN/A 565091Sgblack@eecs.umich.edudef template BranchExecute {{ 577741Sgblack@eecs.umich.edu Fault 5812234Sgabeblack@google.com %(class_name)s::execute(ExecContext *xc, 595091Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 602580SN/A { 617741Sgblack@eecs.umich.edu // Attempt to execute the instruction 625091Sgblack@eecs.umich.edu Fault fault = NoFault; 635091Sgblack@eecs.umich.edu 645091Sgblack@eecs.umich.edu %(op_decl)s; 655091Sgblack@eecs.umich.edu %(op_rd)s; 665091Sgblack@eecs.umich.edu 675091Sgblack@eecs.umich.edu if (%(cond)s) { 685091Sgblack@eecs.umich.edu %(code)s; 695091Sgblack@eecs.umich.edu } else { 705091Sgblack@eecs.umich.edu %(fail)s; 715091Sgblack@eecs.umich.edu } 725091Sgblack@eecs.umich.edu 737741Sgblack@eecs.umich.edu if (fault == NoFault) { 747741Sgblack@eecs.umich.edu // Write the resulting state to the execution context 755091Sgblack@eecs.umich.edu %(op_wb)s; 765091Sgblack@eecs.umich.edu } 775091Sgblack@eecs.umich.edu 785091Sgblack@eecs.umich.edu return fault; 792580SN/A } 805091Sgblack@eecs.umich.edu}}; 815091Sgblack@eecs.umich.edu 825091Sgblack@eecs.umich.edudef template BranchDecode {{ 835091Sgblack@eecs.umich.edu if (A) 845091Sgblack@eecs.umich.edu return new %(class_name)sAnnul("%(mnemonic)s,a", machInst); 855091Sgblack@eecs.umich.edu else 865091Sgblack@eecs.umich.edu return new %(class_name)s("%(mnemonic)s", machInst); 872580SN/A}}; 882580SN/A 892516SN/A// Primary format for branch instructions: 902022SN/Adef format Branch(code, *opt_flags) {{ 917790Sgblack@eecs.umich.edu code = 'NNPC = NNPC;\n' + code 925091Sgblack@eecs.umich.edu (usesImm, code, immCode, 935091Sgblack@eecs.umich.edu rString, iString) = splitOutImm(code) 945091Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, 'Branch', code, opt_flags) 955091Sgblack@eecs.umich.edu header_output = BasicDeclare.subst(iop) 965091Sgblack@eecs.umich.edu decoder_output = BasicConstructor.subst(iop) 975091Sgblack@eecs.umich.edu exec_output = JumpExecute.subst(iop) 985091Sgblack@eecs.umich.edu if usesImm: 995091Sgblack@eecs.umich.edu imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, 1005091Sgblack@eecs.umich.edu immCode, opt_flags) 1015091Sgblack@eecs.umich.edu header_output += BasicDeclare.subst(imm_iop) 1025091Sgblack@eecs.umich.edu decoder_output += BasicConstructor.subst(imm_iop) 1035091Sgblack@eecs.umich.edu exec_output += JumpExecute.subst(imm_iop) 1045091Sgblack@eecs.umich.edu decode_block = ROrImmDecode.subst(iop) 1055091Sgblack@eecs.umich.edu else: 1062516SN/A decode_block = BasicDecode.subst(iop) 1072516SN/A}}; 1082516SN/A 1095091Sgblack@eecs.umich.edulet {{ 1105091Sgblack@eecs.umich.edu def doBranch(name, Name, base, cond, 1115091Sgblack@eecs.umich.edu code, annul_code, fail, annul_fail, opt_flags): 1128345Sksewell@umich.edu #@todo: add flags and branchTarget() for DirectCntrl branches 1138345Sksewell@umich.edu # the o3 model can take advantage of this annotation if 1148345Sksewell@umich.edu # done correctly 1158342Sksewell@umich.edu 1165091Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, base, 1175091Sgblack@eecs.umich.edu {"code": code, 1185091Sgblack@eecs.umich.edu "fail": fail, 1195091Sgblack@eecs.umich.edu "cond": cond 1205091Sgblack@eecs.umich.edu }, 1215091Sgblack@eecs.umich.edu opt_flags) 1225091Sgblack@eecs.umich.edu header_output = BasicDeclareWithMnemonic.subst(iop) 1235091Sgblack@eecs.umich.edu decoder_output = BasicConstructorWithMnemonic.subst(iop) 1242516SN/A exec_output = BranchExecute.subst(iop) 1255091Sgblack@eecs.umich.edu if annul_code == "None": 1265091Sgblack@eecs.umich.edu decode_block = BasicDecodeWithMnemonic.subst(iop) 1275091Sgblack@eecs.umich.edu else: 1285091Sgblack@eecs.umich.edu decode_block = BranchDecode.subst(iop) 1295091Sgblack@eecs.umich.edu 1305091Sgblack@eecs.umich.edu if annul_code != "None": 1315091Sgblack@eecs.umich.edu iop = InstObjParams(name + ',a', Name + 'Annul', base, 1325091Sgblack@eecs.umich.edu {"code": annul_code, 1335091Sgblack@eecs.umich.edu "fail": annul_fail, 1345091Sgblack@eecs.umich.edu "cond": cond 1355091Sgblack@eecs.umich.edu }, 1365091Sgblack@eecs.umich.edu opt_flags) 1375091Sgblack@eecs.umich.edu header_output += BasicDeclareWithMnemonic.subst(iop) 1385091Sgblack@eecs.umich.edu decoder_output += BasicConstructorWithMnemonic.subst(iop) 1395091Sgblack@eecs.umich.edu exec_output += BranchExecute.subst(iop) 1405091Sgblack@eecs.umich.edu return (header_output, decoder_output, exec_output, decode_block) 1415091Sgblack@eecs.umich.edu 1425091Sgblack@eecs.umich.edu def doCondBranch(name, Name, base, cond, code, opt_flags): 1438342Sksewell@umich.edu opt_flags += ('IsCondControl', ) 1445091Sgblack@eecs.umich.edu return doBranch(name, Name, base, cond, code, code, 1457790Sgblack@eecs.umich.edu 'NNPC = NNPC; NPC = NPC;\n', 1467790Sgblack@eecs.umich.edu 'NNPC = NPC + 8; NPC = NPC + 4;\n', 1475091Sgblack@eecs.umich.edu opt_flags) 1485091Sgblack@eecs.umich.edu 1495091Sgblack@eecs.umich.edu def doUncondBranch(name, Name, base, code, annul_code, opt_flags): 1508342Sksewell@umich.edu opt_flags += ('IsUncondControl', ) 1515091Sgblack@eecs.umich.edu return doBranch(name, Name, base, "true", code, annul_code, 1525091Sgblack@eecs.umich.edu ";", ";", opt_flags) 1535091Sgblack@eecs.umich.edu 1547790Sgblack@eecs.umich.edu default_branch_code = 'NNPC = PC + disp;\n' 1552516SN/A}}; 1562516SN/A 1575091Sgblack@eecs.umich.edu// Format for branch instructions with n bit displacements: 1585091Sgblack@eecs.umich.edudef format BranchN(bits, code=default_branch_code, 1595091Sgblack@eecs.umich.edu test=None, annul_code=None, *opt_flags) {{ 1605091Sgblack@eecs.umich.edu if code == "default_branch_code": 1615091Sgblack@eecs.umich.edu code = default_branch_code 1625091Sgblack@eecs.umich.edu if test != "None": 1635091Sgblack@eecs.umich.edu (header_output, 1645091Sgblack@eecs.umich.edu decoder_output, 1655091Sgblack@eecs.umich.edu exec_output, 1665091Sgblack@eecs.umich.edu decode_block) = doCondBranch(name, Name, 1675091Sgblack@eecs.umich.edu "BranchNBits<%d>" % bits, test, code, opt_flags) 1685091Sgblack@eecs.umich.edu else: 1695091Sgblack@eecs.umich.edu (header_output, 1705091Sgblack@eecs.umich.edu decoder_output, 1715091Sgblack@eecs.umich.edu exec_output, 1725091Sgblack@eecs.umich.edu decode_block) = doUncondBranch(name, Name, 1735091Sgblack@eecs.umich.edu "BranchNBits<%d>" % bits, code, annul_code, opt_flags) 1745091Sgblack@eecs.umich.edu}}; 1755091Sgblack@eecs.umich.edu 1765091Sgblack@eecs.umich.edu// Format for branch instructions with split displacements: 1775091Sgblack@eecs.umich.edudef format BranchSplit(code=default_branch_code, 1785091Sgblack@eecs.umich.edu test=None, annul_code=None, *opt_flags) {{ 1795091Sgblack@eecs.umich.edu if code == "default_branch_code": 1805091Sgblack@eecs.umich.edu code = default_branch_code 1815091Sgblack@eecs.umich.edu if test != "None": 1825091Sgblack@eecs.umich.edu (header_output, 1835091Sgblack@eecs.umich.edu decoder_output, 1845091Sgblack@eecs.umich.edu exec_output, 1855091Sgblack@eecs.umich.edu decode_block) = doCondBranch(name, Name, 1865091Sgblack@eecs.umich.edu "BranchSplit", test, code, opt_flags) 1875091Sgblack@eecs.umich.edu else: 1885091Sgblack@eecs.umich.edu (header_output, 1895091Sgblack@eecs.umich.edu decoder_output, 1905091Sgblack@eecs.umich.edu exec_output, 1915091Sgblack@eecs.umich.edu decode_block) = doUncondBranch(name, Name, 1925091Sgblack@eecs.umich.edu "BranchSplit", code, annul_code, opt_flags) 1935091Sgblack@eecs.umich.edu}}; 1945091Sgblack@eecs.umich.edu 195