branch.isa revision 7692:8173327c9c65
11689SN/A// -*- mode:c++ -*- 22326SN/A 31689SN/A// Copyright (c) 2010 ARM Limited 41689SN/A// All rights reserved 51689SN/A// 61689SN/A// The license below extends only to copyright in the software and shall 71689SN/A// not be construed as granting a license to any other intellectual 81689SN/A// property including but not limited to intellectual property relating 91689SN/A// to a hardware implementation of the functionality of the software 101689SN/A// licensed hereunder. You may use the software subject to the license 111689SN/A// terms below provided that you ensure that this notice is replicated 121689SN/A// unmodified and in its entirety in all distributions of the software, 131689SN/A// modified or unmodified, in source code or in binary form. 141689SN/A// 151689SN/A// Redistribution and use in source and binary forms, with or without 161689SN/A// modification, are permitted provided that the following conditions are 171689SN/A// met: redistributions of source code must retain the above copyright 181689SN/A// notice, this list of conditions and the following disclaimer; 191689SN/A// redistributions in binary form must reproduce the above copyright 201689SN/A// notice, this list of conditions and the following disclaimer in the 211689SN/A// documentation and/or other materials provided with the distribution; 221689SN/A// neither the name of the copyright holders nor the names of its 231689SN/A// contributors may be used to endorse or promote products derived from 241689SN/A// this software without specific prior written permission. 251689SN/A// 261689SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 272665Ssaidi@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 282665Ssaidi@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 291689SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 301689SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 312292SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 322292SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 331060SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 341060SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 351060SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 361461SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 371060SN/A// 386221Snate@binkert.org// Authors: Gabe Black 391717SN/A 402292SN/Alet {{ 412292SN/A 421060SN/A header_output = "" 435529Snate@binkert.org decoder_output = "" 442292SN/A exec_output = "" 452292SN/A 462292SN/A # B, BL 472326SN/A for (mnem, link) in (("b", False), ("bl", True)): 482326SN/A bCode = ''' 492326SN/A Addr curPc = readPC(xc); 502326SN/A NPC = ((curPc + imm) & mask(32)) | (curPc & ~mask(32)); 512326SN/A ''' 522292SN/A if (link): 532326SN/A bCode += ''' 542326SN/A if (!isThumb(curPc)) 552326SN/A LR = curPc - 4; 562326SN/A else 572326SN/A LR = curPc | 1; 582326SN/A ''' 592326SN/A 602326SN/A bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond", 612326SN/A {"code": bCode, 622326SN/A "predicate_test": predicateTest}) 632326SN/A header_output += BranchImmCondDeclare.subst(bIop) 642292SN/A decoder_output += BranchImmCondConstructor.subst(bIop) 651681SN/A exec_output += PredOpExecute.subst(bIop) 662292SN/A 671060SN/A # BX, BLX 681060SN/A blxCode = ''' 691060SN/A Addr curPc M5_VAR_USED = readPC(xc); 701061SN/A %(link)s 711061SN/A // Switch modes 722733Sktlim@umich.edu %(branch)s 731060SN/A ''' 741681SN/A 751061SN/A blxList = (("blx", True, True), 762292SN/A ("blx", False, True), 771060SN/A ("bx", False, False)) 781061SN/A 791061SN/A for (mnem, imm, link) in blxList: 801061SN/A Name = mnem.capitalize() 811061SN/A if imm: 821060SN/A Name += "Imm" 832733Sktlim@umich.edu # Since we're switching ISAs, the target ISA will be the opposite 842292SN/A # of the current ISA. !arm is whether the target is ARM. 852292SN/A newPC = '(isThumb(curPc) ? (roundDown(curPc, 4) + imm) : (curPc + imm))' 861060SN/A base = "BranchImmCond" 872292SN/A declare = BranchImmCondDeclare 882292SN/A constructor = BranchImmCondConstructor 892292SN/A else: 901060SN/A Name += "Reg" 912292SN/A newPC = 'Op1' 922292SN/A base = "BranchRegCond" 932292SN/A declare = BranchRegCondDeclare 942292SN/A constructor = BranchRegCondConstructor 952292SN/A if link and imm: 962292SN/A linkStr = ''' 971060SN/A // The immediate version of the blx thumb instruction 981060SN/A // is 32 bits wide, but "next pc" doesn't reflect that 991060SN/A // so we don't want to substract 2 from it at this point 1002292SN/A if (!isThumb(curPc)) 1011060SN/A LR = curPc - 4; 1021060SN/A else 1031060SN/A LR = curPc | 1; 1041060SN/A ''' 1051060SN/A elif link: 1062292SN/A linkStr = ''' 1071060SN/A if (!isThumb(curPc)) 1082292SN/A LR = curPc - 4; 1092292SN/A else 1102292SN/A LR = (curPc - 2) | 1; 1112292SN/A ''' 1122292SN/A else: 1132292SN/A linkStr = "" 1141060SN/A 1151060SN/A if imm and link: #blx with imm 1162292SN/A branchStr = ''' 1175529Snate@binkert.org Addr tempPc = ((%(newPC)s) & mask(32)) | (curPc & ~mask(32)); 1181060SN/A FNPC = tempPc ^ PcTBit; 1192292SN/A ''' 1202292SN/A else: 1211062SN/A branchStr = "IWNPC = %(newPC)s;" 1222292SN/A branchStr = branchStr % { "newPC" : newPC } 1232632Sstever@eecs.umich.edu 1242632Sstever@eecs.umich.edu code = blxCode % {"link": linkStr, 1252292SN/A "newPC": newPC, 1262292SN/A "branch": branchStr} 1272292SN/A blxIop = InstObjParams(mnem, Name, base, 1282871Sktlim@umich.edu {"code": code, 1292871Sktlim@umich.edu "predicate_test": predicateTest}) 1302871Sktlim@umich.edu header_output += declare.subst(blxIop) 1312292SN/A decoder_output += constructor.subst(blxIop) 1322632Sstever@eecs.umich.edu exec_output += PredOpExecute.subst(blxIop) 1332632Sstever@eecs.umich.edu 1342292SN/A #Ignore BXJ for now 1352632Sstever@eecs.umich.edu 1362632Sstever@eecs.umich.edu #CBNZ, CBZ. These are always unconditional as far as predicates 1372292SN/A for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")): 1382632Sstever@eecs.umich.edu code = ''' 1392632Sstever@eecs.umich.edu Addr curPc = readPC(xc); 1402292SN/A NPC = ((curPc + imm) & mask(32)) | (curPc & ~mask(32)); 1416221Snate@binkert.org ''' 1422632Sstever@eecs.umich.edu predTest = "Op1 %(test)s 0" % {"test": test} 1432292SN/A iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg", 1442292SN/A {"code": code, "predicate_test": predTest}) 1452632Sstever@eecs.umich.edu header_output += BranchImmRegDeclare.subst(iop) 1462843Sktlim@umich.edu decoder_output += BranchImmRegConstructor.subst(iop) 1472863Sktlim@umich.edu exec_output += PredOpExecute.subst(iop) 1482843Sktlim@umich.edu 1492843Sktlim@umich.edu #TBB, TBH 1502843Sktlim@umich.edu for isTbh in (0, 1): 1512632Sstever@eecs.umich.edu if isTbh: 1522348SN/A eaCode = ''' 1532843Sktlim@umich.edu unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned | 1542632Sstever@eecs.umich.edu ArmISA::TLB::AlignHalfWord | 1552348SN/A ArmISA::TLB::MustBeOne; 1562307SN/A EA = Op1 + Op2 * 2 1572632Sstever@eecs.umich.edu ''' 1582348SN/A accCode = "NPC = readPC(xc) + 2 * (Mem.uh);" 1592307SN/A mnem = "tbh" 1602632Sstever@eecs.umich.edu else: 1612292SN/A eaCode = ''' 1626221Snate@binkert.org unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned | 1632107SN/A ArmISA::TLB::AlignByte | 1642292SN/A ArmISA::TLB::MustBeOne; 1652632Sstever@eecs.umich.edu EA = Op1 + Op2 1662632Sstever@eecs.umich.edu ''' 1672292SN/A accCode = "NPC = readPC(xc) + 2 * (Mem.ub);" 1682292SN/A mnem = "tbb" 1692292SN/A iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg", 1702292SN/A {'ea_code': eaCode, 1712292SN/A 'memacc_code': accCode, 1722292SN/A 'predicate_test': predicateTest}) 1732292SN/A header_output += BranchTableDeclare.subst(iop) 1742292SN/A decoder_output += BranchRegRegConstructor.subst(iop) 1752292SN/A exec_output += LoadExecute.subst(iop) + \ 1762632Sstever@eecs.umich.edu LoadInitiateAcc.subst(iop) + \ 1772632Sstever@eecs.umich.edu LoadCompleteAcc.subst(iop) 1782292SN/A}}; 1796221Snate@binkert.org