branch.isa revision 7294:fda2c00880db
112787Sgabeblack@google.com// -*- mode:c++ -*- 212787Sgabeblack@google.com 312787Sgabeblack@google.com// Copyright (c) 2010 ARM Limited 412787Sgabeblack@google.com// All rights reserved 512787Sgabeblack@google.com// 612787Sgabeblack@google.com// The license below extends only to copyright in the software and shall 712787Sgabeblack@google.com// not be construed as granting a license to any other intellectual 812787Sgabeblack@google.com// property including but not limited to intellectual property relating 912787Sgabeblack@google.com// to a hardware implementation of the functionality of the software 1012787Sgabeblack@google.com// licensed hereunder. You may use the software subject to the license 1112787Sgabeblack@google.com// terms below provided that you ensure that this notice is replicated 1212787Sgabeblack@google.com// unmodified and in its entirety in all distributions of the software, 1312787Sgabeblack@google.com// modified or unmodified, in source code or in binary form. 1412787Sgabeblack@google.com// 1512787Sgabeblack@google.com// Redistribution and use in source and binary forms, with or without 1612787Sgabeblack@google.com// modification, are permitted provided that the following conditions are 1712787Sgabeblack@google.com// met: redistributions of source code must retain the above copyright 1812787Sgabeblack@google.com// notice, this list of conditions and the following disclaimer; 1912787Sgabeblack@google.com// redistributions in binary form must reproduce the above copyright 2012787Sgabeblack@google.com// notice, this list of conditions and the following disclaimer in the 2112787Sgabeblack@google.com// documentation and/or other materials provided with the distribution; 2212787Sgabeblack@google.com// neither the name of the copyright holders nor the names of its 2312787Sgabeblack@google.com// contributors may be used to endorse or promote products derived from 2412787Sgabeblack@google.com// this software without specific prior written permission. 2512787Sgabeblack@google.com// 2612787Sgabeblack@google.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2712787Sgabeblack@google.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2812787Sgabeblack@google.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2912787Sgabeblack@google.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3012787Sgabeblack@google.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3112787Sgabeblack@google.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3212787Sgabeblack@google.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3312787Sgabeblack@google.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3412787Sgabeblack@google.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3512787Sgabeblack@google.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3612787Sgabeblack@google.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3712787Sgabeblack@google.com// 3812787Sgabeblack@google.com// Authors: Gabe Black 3912787Sgabeblack@google.com 4012787Sgabeblack@google.comlet {{ 4112787Sgabeblack@google.com 4212787Sgabeblack@google.com header_output = "" 4312787Sgabeblack@google.com decoder_output = "" 4412787Sgabeblack@google.com exec_output = "" 4512787Sgabeblack@google.com 4612787Sgabeblack@google.com # B, BL 4712787Sgabeblack@google.com for (mnem, link) in (("b", False), ("bl", True)): 4812787Sgabeblack@google.com bCode = ''' 4912787Sgabeblack@google.com Addr PC = readPC(xc); 5012787Sgabeblack@google.com NPC = ((PC + imm) & mask(32)) | (PC & ~mask(32)); 5112787Sgabeblack@google.com ''' 5212787Sgabeblack@google.com if (link): 5312787Sgabeblack@google.com bCode += ''' 5412787Sgabeblack@google.com Addr tBit = PC & (ULL(1) << PcTBitShift); 5512787Sgabeblack@google.com if (!tBit) 5612787Sgabeblack@google.com LR = PC - 4; 5712787Sgabeblack@google.com else 5812787Sgabeblack@google.com LR = PC | 1; 5912787Sgabeblack@google.com ''' 6012787Sgabeblack@google.com 6112787Sgabeblack@google.com bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond", 6212787Sgabeblack@google.com {"code": bCode, 6312787Sgabeblack@google.com "predicate_test": predicateTest}) 6412787Sgabeblack@google.com header_output += BranchImmCondDeclare.subst(bIop) 6512787Sgabeblack@google.com decoder_output += BranchImmCondConstructor.subst(bIop) 6612787Sgabeblack@google.com exec_output += PredOpExecute.subst(bIop) 6712787Sgabeblack@google.com 6812787Sgabeblack@google.com # BX, BLX 6912787Sgabeblack@google.com blxCode = ''' 7012787Sgabeblack@google.com Addr PC = readPC(xc); 7112787Sgabeblack@google.com Addr tBit = PC & (ULL(1) << PcTBitShift); 7212787Sgabeblack@google.com bool arm = !tBit; 7312787Sgabeblack@google.com arm = arm; // In case it's not used otherwise. 7412787Sgabeblack@google.com %(link)s 7512787Sgabeblack@google.com // Switch modes 7612787Sgabeblack@google.com %(branch)s 7712787Sgabeblack@google.com ''' 7812787Sgabeblack@google.com 7912787Sgabeblack@google.com blxList = (("blx", True, True), 8012787Sgabeblack@google.com ("blx", False, True), 8112787Sgabeblack@google.com ("bx", False, False)) 8212787Sgabeblack@google.com 8312787Sgabeblack@google.com for (mnem, imm, link) in blxList: 8412787Sgabeblack@google.com Name = mnem.capitalize() 8512787Sgabeblack@google.com if imm: 8612787Sgabeblack@google.com Name += "Imm" 8712787Sgabeblack@google.com # Since we're switching ISAs, the target ISA will be the opposite 8812787Sgabeblack@google.com # of the current ISA. !arm is whether the target is ARM. 8912787Sgabeblack@google.com newPC = '(!arm ? (roundDown(PC, 4) + imm) : (PC + imm))' 9012787Sgabeblack@google.com base = "BranchImm" 9112787Sgabeblack@google.com declare = BranchImmDeclare 9212787Sgabeblack@google.com constructor = BranchImmConstructor 9312787Sgabeblack@google.com else: 9412787Sgabeblack@google.com Name += "Reg" 9512787Sgabeblack@google.com newPC = 'Op1' 9612787Sgabeblack@google.com base = "BranchRegCond" 9712787Sgabeblack@google.com declare = BranchRegCondDeclare 9812787Sgabeblack@google.com constructor = BranchRegCondConstructor 9912787Sgabeblack@google.com if link and imm: 10012787Sgabeblack@google.com linkStr = ''' 10112787Sgabeblack@google.com // The immediate version of the blx thumb instruction 10212787Sgabeblack@google.com // is 32 bits wide, but "next pc" doesn't reflect that 10312787Sgabeblack@google.com // so we don't want to substract 2 from it at this point 10412787Sgabeblack@google.com if (arm) 10512787Sgabeblack@google.com LR = PC - 4; 10612787Sgabeblack@google.com else 10712787Sgabeblack@google.com LR = PC | 1; 10812787Sgabeblack@google.com ''' 10912787Sgabeblack@google.com elif link: 11012787Sgabeblack@google.com linkStr = ''' 11112787Sgabeblack@google.com if (arm) 11212787Sgabeblack@google.com LR = PC - 4; 11312787Sgabeblack@google.com else 11412787Sgabeblack@google.com LR = (PC - 2) | 1; 11512787Sgabeblack@google.com ''' 11612787Sgabeblack@google.com else: 11712787Sgabeblack@google.com linkStr = "" 11812787Sgabeblack@google.com 11912787Sgabeblack@google.com if imm and link: #blx with imm 12012787Sgabeblack@google.com branchStr = ''' 12112787Sgabeblack@google.com Addr tempPc = ((%(newPC)s) & mask(32)) | (PC & ~mask(32)); 12212787Sgabeblack@google.com FNPC = tempPc ^ (ULL(1) << PcTBitShift); 12312787Sgabeblack@google.com ''' 12412787Sgabeblack@google.com else: 12512787Sgabeblack@google.com branchStr = "IWNPC = %(newPC)s;" 12612787Sgabeblack@google.com branchStr = branchStr % { "newPC" : newPC } 12712787Sgabeblack@google.com 12812787Sgabeblack@google.com code = blxCode % {"link": linkStr, 12912787Sgabeblack@google.com "newPC": newPC, 13012787Sgabeblack@google.com "branch": branchStr} 13112787Sgabeblack@google.com blxIop = InstObjParams(mnem, Name, base, 13212787Sgabeblack@google.com {"code": code, 13312787Sgabeblack@google.com "predicate_test": predicateTest}) 13412787Sgabeblack@google.com header_output += declare.subst(blxIop) 13512787Sgabeblack@google.com decoder_output += constructor.subst(blxIop) 13612787Sgabeblack@google.com exec_output += PredOpExecute.subst(blxIop) 13712787Sgabeblack@google.com 13812787Sgabeblack@google.com #Ignore BXJ for now 13912787Sgabeblack@google.com 14012787Sgabeblack@google.com #CBNZ, CBZ. These are always unconditional as far as predicates 14112787Sgabeblack@google.com for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")): 14212787Sgabeblack@google.com code = ''' 14312787Sgabeblack@google.com Addr PC = readPC(xc); 14412787Sgabeblack@google.com NPC = ((PC + imm) & mask(32)) | (PC & ~mask(32)); 14512787Sgabeblack@google.com ''' 14612787Sgabeblack@google.com predTest = "Op1 %(test)s 0" % {"test": test} 14712787Sgabeblack@google.com iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg", 14812787Sgabeblack@google.com {"code": code, "predicate_test": predTest}) 149 header_output += BranchImmRegDeclare.subst(iop) 150 decoder_output += BranchImmRegConstructor.subst(iop) 151 exec_output += PredOpExecute.subst(iop) 152 153 #TBB, TBH 154 for isTbh in (0, 1): 155 if isTbh: 156 eaCode = ''' 157 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned | 158 ArmISA::TLB::AlignHalfWord | 159 ArmISA::TLB::MustBeOne; 160 EA = Op1 + Op2 * 2 161 ''' 162 accCode = "NPC = readPC(xc) + 2 * (Mem.uh);" 163 mnem = "tbh" 164 else: 165 eaCode = ''' 166 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned | 167 ArmISA::TLB::AlignByte | 168 ArmISA::TLB::MustBeOne; 169 EA = Op1 + Op2 170 ''' 171 accCode = "NPC = readPC(xc) + 2 * (Mem.ub);" 172 mnem = "tbb" 173 iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg", 174 {'ea_code': eaCode, 175 'memacc_code': accCode, 176 'predicate_test': predicateTest}) 177 header_output += BranchTableDeclare.subst(iop) 178 decoder_output += BranchRegRegConstructor.subst(iop) 179 exec_output += LoadExecute.subst(iop) + \ 180 LoadInitiateAcc.subst(iop) + \ 181 LoadCompleteAcc.subst(iop) 182}}; 183