branch.isa revision 8146
17151Sgblack@eecs.umich.edu// -*- mode:c++ -*- 27151Sgblack@eecs.umich.edu 37151Sgblack@eecs.umich.edu// Copyright (c) 2010 ARM Limited 47151Sgblack@eecs.umich.edu// All rights reserved 57151Sgblack@eecs.umich.edu// 67151Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall 77151Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual 87151Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating 97151Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software 107151Sgblack@eecs.umich.edu// licensed hereunder. You may use the software subject to the license 117151Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated 127151Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software, 137151Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form. 147151Sgblack@eecs.umich.edu// 157151Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 167151Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 177151Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 187151Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 197151Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 207151Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 217151Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 227151Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 237151Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 247151Sgblack@eecs.umich.edu// this software without specific prior written permission. 257151Sgblack@eecs.umich.edu// 267151Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 277151Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 287151Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 297151Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 307151Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 317151Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 327151Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 337151Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 347151Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 357151Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 367151Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 377151Sgblack@eecs.umich.edu// 387151Sgblack@eecs.umich.edu// Authors: Gabe Black 397151Sgblack@eecs.umich.edu 407151Sgblack@eecs.umich.edulet {{ 417151Sgblack@eecs.umich.edu 427151Sgblack@eecs.umich.edu header_output = "" 437151Sgblack@eecs.umich.edu decoder_output = "" 447151Sgblack@eecs.umich.edu exec_output = "" 457151Sgblack@eecs.umich.edu 467151Sgblack@eecs.umich.edu # B, BL 477151Sgblack@eecs.umich.edu for (mnem, link) in (("b", False), ("bl", True)): 487151Sgblack@eecs.umich.edu bCode = ''' 497797Sgblack@eecs.umich.edu NPC = (uint32_t)(PC + imm); 507151Sgblack@eecs.umich.edu ''' 518146SAli.Saidi@ARM.com br_tgt_code = '''pcs.instNPC(branchPC.instPC() + imm);''' 528146SAli.Saidi@ARM.com instFlags = ["IsDirectControl"] 537151Sgblack@eecs.umich.edu if (link): 547151Sgblack@eecs.umich.edu bCode += ''' 557797Sgblack@eecs.umich.edu if (Thumb) 567797Sgblack@eecs.umich.edu LR = PC | 1; 577720Sgblack@eecs.umich.edu else 587797Sgblack@eecs.umich.edu LR = PC - 4; 597151Sgblack@eecs.umich.edu ''' 608146SAli.Saidi@ARM.com instFlags += ["IsCall"] 618146SAli.Saidi@ARM.com 627151Sgblack@eecs.umich.edu 637151Sgblack@eecs.umich.edu bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond", 648146SAli.Saidi@ARM.com {"code": bCode, "predicate_test": predicateTest, 658146SAli.Saidi@ARM.com "brTgtCode" : br_tgt_code}, instFlags) 667151Sgblack@eecs.umich.edu header_output += BranchImmCondDeclare.subst(bIop) 678146SAli.Saidi@ARM.com decoder_output += BranchImmCondConstructor.subst(bIop) + \ 688146SAli.Saidi@ARM.com BranchTarget.subst(bIop) 697151Sgblack@eecs.umich.edu exec_output += PredOpExecute.subst(bIop) 707151Sgblack@eecs.umich.edu 717151Sgblack@eecs.umich.edu # BX, BLX 727151Sgblack@eecs.umich.edu blxCode = ''' 737151Sgblack@eecs.umich.edu %(link)s 747151Sgblack@eecs.umich.edu // Switch modes 757151Sgblack@eecs.umich.edu %(branch)s 767151Sgblack@eecs.umich.edu ''' 777151Sgblack@eecs.umich.edu 787151Sgblack@eecs.umich.edu blxList = (("blx", True, True), 797151Sgblack@eecs.umich.edu ("blx", False, True), 807151Sgblack@eecs.umich.edu ("bx", False, False)) 817151Sgblack@eecs.umich.edu 827151Sgblack@eecs.umich.edu for (mnem, imm, link) in blxList: 837151Sgblack@eecs.umich.edu Name = mnem.capitalize() 847151Sgblack@eecs.umich.edu if imm: 857151Sgblack@eecs.umich.edu Name += "Imm" 867151Sgblack@eecs.umich.edu # Since we're switching ISAs, the target ISA will be the opposite 877797Sgblack@eecs.umich.edu # of the current ISA. Thumb is whether the target is ARM. 887797Sgblack@eecs.umich.edu newPC = '(Thumb ? (roundDown(PC, 4) + imm) : (PC + imm))' 898146SAli.Saidi@ARM.com br_tgt_code = ''' 908146SAli.Saidi@ARM.com pcs.instNPC((branchPC.thumb() ? (roundDown(branchPC.instPC(),4) + imm) : 918146SAli.Saidi@ARM.com (branchPC.instPC() + imm))); 928146SAli.Saidi@ARM.com ''' 937602SGene.Wu@arm.com base = "BranchImmCond" 947602SGene.Wu@arm.com declare = BranchImmCondDeclare 957602SGene.Wu@arm.com constructor = BranchImmCondConstructor 968146SAli.Saidi@ARM.com instFlags = ["IsDirectControl"] 977151Sgblack@eecs.umich.edu else: 987151Sgblack@eecs.umich.edu Name += "Reg" 997282Sgblack@eecs.umich.edu newPC = 'Op1' 1008146SAli.Saidi@ARM.com br_tgt_code = '' 1017151Sgblack@eecs.umich.edu base = "BranchRegCond" 1027151Sgblack@eecs.umich.edu declare = BranchRegCondDeclare 1037151Sgblack@eecs.umich.edu constructor = BranchRegCondConstructor 1048146SAli.Saidi@ARM.com instFlags = ["IsIndirectControl"] 1057151Sgblack@eecs.umich.edu if link and imm: 1067151Sgblack@eecs.umich.edu linkStr = ''' 1077151Sgblack@eecs.umich.edu // The immediate version of the blx thumb instruction 1087151Sgblack@eecs.umich.edu // is 32 bits wide, but "next pc" doesn't reflect that 1097151Sgblack@eecs.umich.edu // so we don't want to substract 2 from it at this point 1107797Sgblack@eecs.umich.edu if (Thumb) 1117797Sgblack@eecs.umich.edu LR = PC | 1; 1127720Sgblack@eecs.umich.edu else 1137797Sgblack@eecs.umich.edu LR = PC - 4; 1147151Sgblack@eecs.umich.edu ''' 1158146SAli.Saidi@ARM.com instFlags += ["IsCall"] 1167151Sgblack@eecs.umich.edu elif link: 1177151Sgblack@eecs.umich.edu linkStr = ''' 1187797Sgblack@eecs.umich.edu if (Thumb) 1197797Sgblack@eecs.umich.edu LR = (PC - 2) | 1; 1207720Sgblack@eecs.umich.edu else 1217797Sgblack@eecs.umich.edu LR = PC - 4; 1227151Sgblack@eecs.umich.edu ''' 1238146SAli.Saidi@ARM.com instFlags += ["IsCall"] 1247151Sgblack@eecs.umich.edu else: 1257151Sgblack@eecs.umich.edu linkStr = "" 1268146SAli.Saidi@ARM.com instFlags += ["IsReturn"] 1277282Sgblack@eecs.umich.edu 1287282Sgblack@eecs.umich.edu if imm and link: #blx with imm 1297282Sgblack@eecs.umich.edu branchStr = ''' 1307797Sgblack@eecs.umich.edu NextThumb = !Thumb; 1317797Sgblack@eecs.umich.edu NPC = %(newPC)s; 1327282Sgblack@eecs.umich.edu ''' 1338146SAli.Saidi@ARM.com br_tgt_code = '''pcs.nextThumb(!branchPC.thumb());\n''' + \ 1348146SAli.Saidi@ARM.com br_tgt_code 1357282Sgblack@eecs.umich.edu else: 1367797Sgblack@eecs.umich.edu branchStr = "IWNPC = %(newPC)s;" 1377282Sgblack@eecs.umich.edu branchStr = branchStr % { "newPC" : newPC } 1387282Sgblack@eecs.umich.edu 1397151Sgblack@eecs.umich.edu code = blxCode % {"link": linkStr, 1407151Sgblack@eecs.umich.edu "newPC": newPC, 1417151Sgblack@eecs.umich.edu "branch": branchStr} 1427151Sgblack@eecs.umich.edu blxIop = InstObjParams(mnem, Name, base, 1438146SAli.Saidi@ARM.com {"code": code, "brTgtCode" : br_tgt_code, 1448146SAli.Saidi@ARM.com "predicate_test": predicateTest}, instFlags) 1457151Sgblack@eecs.umich.edu header_output += declare.subst(blxIop) 1467151Sgblack@eecs.umich.edu decoder_output += constructor.subst(blxIop) 1477151Sgblack@eecs.umich.edu exec_output += PredOpExecute.subst(blxIop) 1488146SAli.Saidi@ARM.com if imm: 1498146SAli.Saidi@ARM.com decoder_output += BranchTarget.subst(blxIop) 1507151Sgblack@eecs.umich.edu 1517151Sgblack@eecs.umich.edu #Ignore BXJ for now 1527151Sgblack@eecs.umich.edu 1537151Sgblack@eecs.umich.edu #CBNZ, CBZ. These are always unconditional as far as predicates 1547151Sgblack@eecs.umich.edu for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")): 1557797Sgblack@eecs.umich.edu code = 'NPC = (uint32_t)(PC + imm);\n' 1567151Sgblack@eecs.umich.edu predTest = "Op1 %(test)s 0" % {"test": test} 1577151Sgblack@eecs.umich.edu iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg", 1588146SAli.Saidi@ARM.com {"code": code, "predicate_test": predTest}, 1598146SAli.Saidi@ARM.com ["IsIndirectControl"]) 1607151Sgblack@eecs.umich.edu header_output += BranchImmRegDeclare.subst(iop) 1617151Sgblack@eecs.umich.edu decoder_output += BranchImmRegConstructor.subst(iop) 1627151Sgblack@eecs.umich.edu exec_output += PredOpExecute.subst(iop) 1637151Sgblack@eecs.umich.edu 1647151Sgblack@eecs.umich.edu #TBB, TBH 1657151Sgblack@eecs.umich.edu for isTbh in (0, 1): 1667151Sgblack@eecs.umich.edu if isTbh: 1677294Sgblack@eecs.umich.edu eaCode = ''' 1687294Sgblack@eecs.umich.edu unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned | 1697294Sgblack@eecs.umich.edu ArmISA::TLB::AlignHalfWord | 1707294Sgblack@eecs.umich.edu ArmISA::TLB::MustBeOne; 1717294Sgblack@eecs.umich.edu EA = Op1 + Op2 * 2 1727294Sgblack@eecs.umich.edu ''' 1737797Sgblack@eecs.umich.edu accCode = 'NPC = PC + 2 * (Mem.uh);\n' 1747151Sgblack@eecs.umich.edu mnem = "tbh" 1757151Sgblack@eecs.umich.edu else: 1767294Sgblack@eecs.umich.edu eaCode = ''' 1777294Sgblack@eecs.umich.edu unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned | 1787294Sgblack@eecs.umich.edu ArmISA::TLB::AlignByte | 1797294Sgblack@eecs.umich.edu ArmISA::TLB::MustBeOne; 1807294Sgblack@eecs.umich.edu EA = Op1 + Op2 1817294Sgblack@eecs.umich.edu ''' 1827797Sgblack@eecs.umich.edu accCode = 'NPC = PC + 2 * (Mem.ub)' 1837151Sgblack@eecs.umich.edu mnem = "tbb" 1847151Sgblack@eecs.umich.edu iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg", 1857151Sgblack@eecs.umich.edu {'ea_code': eaCode, 1867151Sgblack@eecs.umich.edu 'memacc_code': accCode, 1878146SAli.Saidi@ARM.com 'predicate_test': predicateTest}, 1888146SAli.Saidi@ARM.com ["IsIndirectControl"]) 1897151Sgblack@eecs.umich.edu header_output += BranchTableDeclare.subst(iop) 1907151Sgblack@eecs.umich.edu decoder_output += BranchRegRegConstructor.subst(iop) 1917151Sgblack@eecs.umich.edu exec_output += LoadExecute.subst(iop) + \ 1927151Sgblack@eecs.umich.edu LoadInitiateAcc.subst(iop) + \ 1937151Sgblack@eecs.umich.edu LoadCompleteAcc.subst(iop) 1947151Sgblack@eecs.umich.edu}}; 195