branch.isa revision 8203
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() 848203SAli.Saidi@ARM.com isRasPop = 0 857151Sgblack@eecs.umich.edu if imm: 867151Sgblack@eecs.umich.edu Name += "Imm" 877151Sgblack@eecs.umich.edu # Since we're switching ISAs, the target ISA will be the opposite 887797Sgblack@eecs.umich.edu # of the current ISA. Thumb is whether the target is ARM. 897797Sgblack@eecs.umich.edu newPC = '(Thumb ? (roundDown(PC, 4) + imm) : (PC + imm))' 908146SAli.Saidi@ARM.com br_tgt_code = ''' 918146SAli.Saidi@ARM.com pcs.instNPC((branchPC.thumb() ? (roundDown(branchPC.instPC(),4) + imm) : 928146SAli.Saidi@ARM.com (branchPC.instPC() + imm))); 938146SAli.Saidi@ARM.com ''' 947602SGene.Wu@arm.com base = "BranchImmCond" 957602SGene.Wu@arm.com declare = BranchImmCondDeclare 967602SGene.Wu@arm.com constructor = BranchImmCondConstructor 978146SAli.Saidi@ARM.com instFlags = ["IsDirectControl"] 987151Sgblack@eecs.umich.edu else: 997151Sgblack@eecs.umich.edu Name += "Reg" 1007282Sgblack@eecs.umich.edu newPC = 'Op1' 1018146SAli.Saidi@ARM.com br_tgt_code = '' 1027151Sgblack@eecs.umich.edu base = "BranchRegCond" 1037151Sgblack@eecs.umich.edu declare = BranchRegCondDeclare 1047151Sgblack@eecs.umich.edu constructor = BranchRegCondConstructor 1058146SAli.Saidi@ARM.com instFlags = ["IsIndirectControl"] 1067151Sgblack@eecs.umich.edu if link and imm: 1077151Sgblack@eecs.umich.edu linkStr = ''' 1087151Sgblack@eecs.umich.edu // The immediate version of the blx thumb instruction 1097151Sgblack@eecs.umich.edu // is 32 bits wide, but "next pc" doesn't reflect that 1107151Sgblack@eecs.umich.edu // so we don't want to substract 2 from it at this point 1117797Sgblack@eecs.umich.edu if (Thumb) 1127797Sgblack@eecs.umich.edu LR = PC | 1; 1137720Sgblack@eecs.umich.edu else 1147797Sgblack@eecs.umich.edu LR = PC - 4; 1157151Sgblack@eecs.umich.edu ''' 1168146SAli.Saidi@ARM.com instFlags += ["IsCall"] 1177151Sgblack@eecs.umich.edu elif link: 1187151Sgblack@eecs.umich.edu linkStr = ''' 1197797Sgblack@eecs.umich.edu if (Thumb) 1207797Sgblack@eecs.umich.edu LR = (PC - 2) | 1; 1217720Sgblack@eecs.umich.edu else 1227797Sgblack@eecs.umich.edu LR = PC - 4; 1237151Sgblack@eecs.umich.edu ''' 1248146SAli.Saidi@ARM.com instFlags += ["IsCall"] 1257151Sgblack@eecs.umich.edu else: 1267151Sgblack@eecs.umich.edu linkStr = "" 1278203SAli.Saidi@ARM.com isRasPop = "op1 == INTREG_LR" 1287282Sgblack@eecs.umich.edu 1297282Sgblack@eecs.umich.edu if imm and link: #blx with imm 1307282Sgblack@eecs.umich.edu branchStr = ''' 1317797Sgblack@eecs.umich.edu NextThumb = !Thumb; 1327797Sgblack@eecs.umich.edu NPC = %(newPC)s; 1337282Sgblack@eecs.umich.edu ''' 1348146SAli.Saidi@ARM.com br_tgt_code = '''pcs.nextThumb(!branchPC.thumb());\n''' + \ 1358146SAli.Saidi@ARM.com br_tgt_code 1367282Sgblack@eecs.umich.edu else: 1377797Sgblack@eecs.umich.edu branchStr = "IWNPC = %(newPC)s;" 1387282Sgblack@eecs.umich.edu branchStr = branchStr % { "newPC" : newPC } 1397282Sgblack@eecs.umich.edu 1407151Sgblack@eecs.umich.edu code = blxCode % {"link": linkStr, 1417151Sgblack@eecs.umich.edu "newPC": newPC, 1427151Sgblack@eecs.umich.edu "branch": branchStr} 1437151Sgblack@eecs.umich.edu blxIop = InstObjParams(mnem, Name, base, 1448146SAli.Saidi@ARM.com {"code": code, "brTgtCode" : br_tgt_code, 1458203SAli.Saidi@ARM.com "predicate_test": predicateTest, 1468203SAli.Saidi@ARM.com "is_ras_pop" : isRasPop }, instFlags) 1477151Sgblack@eecs.umich.edu header_output += declare.subst(blxIop) 1487151Sgblack@eecs.umich.edu decoder_output += constructor.subst(blxIop) 1497151Sgblack@eecs.umich.edu exec_output += PredOpExecute.subst(blxIop) 1508146SAli.Saidi@ARM.com if imm: 1518146SAli.Saidi@ARM.com decoder_output += BranchTarget.subst(blxIop) 1527151Sgblack@eecs.umich.edu 1537151Sgblack@eecs.umich.edu #Ignore BXJ for now 1547151Sgblack@eecs.umich.edu 1557151Sgblack@eecs.umich.edu #CBNZ, CBZ. These are always unconditional as far as predicates 1567151Sgblack@eecs.umich.edu for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")): 1577797Sgblack@eecs.umich.edu code = 'NPC = (uint32_t)(PC + imm);\n' 1587151Sgblack@eecs.umich.edu predTest = "Op1 %(test)s 0" % {"test": test} 1597151Sgblack@eecs.umich.edu iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg", 1608146SAli.Saidi@ARM.com {"code": code, "predicate_test": predTest}, 1618146SAli.Saidi@ARM.com ["IsIndirectControl"]) 1627151Sgblack@eecs.umich.edu header_output += BranchImmRegDeclare.subst(iop) 1637151Sgblack@eecs.umich.edu decoder_output += BranchImmRegConstructor.subst(iop) 1647151Sgblack@eecs.umich.edu exec_output += PredOpExecute.subst(iop) 1657151Sgblack@eecs.umich.edu 1667151Sgblack@eecs.umich.edu #TBB, TBH 1677151Sgblack@eecs.umich.edu for isTbh in (0, 1): 1687151Sgblack@eecs.umich.edu if isTbh: 1697294Sgblack@eecs.umich.edu eaCode = ''' 1707294Sgblack@eecs.umich.edu unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned | 1717294Sgblack@eecs.umich.edu ArmISA::TLB::AlignHalfWord | 1727294Sgblack@eecs.umich.edu ArmISA::TLB::MustBeOne; 1737294Sgblack@eecs.umich.edu EA = Op1 + Op2 * 2 1747294Sgblack@eecs.umich.edu ''' 1757797Sgblack@eecs.umich.edu accCode = 'NPC = PC + 2 * (Mem.uh);\n' 1767151Sgblack@eecs.umich.edu mnem = "tbh" 1777151Sgblack@eecs.umich.edu else: 1787294Sgblack@eecs.umich.edu eaCode = ''' 1797294Sgblack@eecs.umich.edu unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned | 1807294Sgblack@eecs.umich.edu ArmISA::TLB::AlignByte | 1817294Sgblack@eecs.umich.edu ArmISA::TLB::MustBeOne; 1827294Sgblack@eecs.umich.edu EA = Op1 + Op2 1837294Sgblack@eecs.umich.edu ''' 1847797Sgblack@eecs.umich.edu accCode = 'NPC = PC + 2 * (Mem.ub)' 1857151Sgblack@eecs.umich.edu mnem = "tbb" 1867151Sgblack@eecs.umich.edu iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg", 1877151Sgblack@eecs.umich.edu {'ea_code': eaCode, 1887151Sgblack@eecs.umich.edu 'memacc_code': accCode, 1898146SAli.Saidi@ARM.com 'predicate_test': predicateTest}, 1908146SAli.Saidi@ARM.com ["IsIndirectControl"]) 1917151Sgblack@eecs.umich.edu header_output += BranchTableDeclare.subst(iop) 1927151Sgblack@eecs.umich.edu decoder_output += BranchRegRegConstructor.subst(iop) 1937151Sgblack@eecs.umich.edu exec_output += LoadExecute.subst(iop) + \ 1947151Sgblack@eecs.umich.edu LoadInitiateAcc.subst(iop) + \ 1957151Sgblack@eecs.umich.edu LoadCompleteAcc.subst(iop) 1967151Sgblack@eecs.umich.edu}}; 197