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