branch.isa revision 7692:8173327c9c65
12023SN/A// -*- mode:c++ -*-
22023SN/A
32023SN/A// Copyright (c) 2010 ARM Limited
42023SN/A// All rights reserved
52023SN/A//
62023SN/A// The license below extends only to copyright in the software and shall
72023SN/A// not be construed as granting a license to any other intellectual
82023SN/A// property including but not limited to intellectual property relating
92023SN/A// to a hardware implementation of the functionality of the software
102023SN/A// licensed hereunder.  You may use the software subject to the license
112023SN/A// terms below provided that you ensure that this notice is replicated
122023SN/A// unmodified and in its entirety in all distributions of the software,
132023SN/A// modified or unmodified, in source code or in binary form.
142023SN/A//
152023SN/A// Redistribution and use in source and binary forms, with or without
162023SN/A// modification, are permitted provided that the following conditions are
172023SN/A// met: redistributions of source code must retain the above copyright
182023SN/A// notice, this list of conditions and the following disclaimer;
192023SN/A// redistributions in binary form must reproduce the above copyright
202023SN/A// notice, this list of conditions and the following disclaimer in the
212023SN/A// documentation and/or other materials provided with the distribution;
222023SN/A// neither the name of the copyright holders nor the names of its
232023SN/A// contributors may be used to endorse or promote products derived from
242023SN/A// this software without specific prior written permission.
252023SN/A//
262023SN/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
282972Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
293804Ssaidi@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
302023SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
312023SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
322023SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
332023SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
342023SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
352972Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
363752Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
372225SN/A//
383809Sgblack@eecs.umich.edu// Authors: Gabe Black
392225SN/A
402225SN/Alet {{
412023SN/A
422458SN/A    header_output = ""
432023SN/A    decoder_output = ""
442458SN/A    exec_output = ""
452458SN/A
462972Sgblack@eecs.umich.edu    # B, BL
472972Sgblack@eecs.umich.edu    for (mnem, link) in (("b", False), ("bl", True)):
483809Sgblack@eecs.umich.edu        bCode = '''
493809Sgblack@eecs.umich.edu        Addr curPc = readPC(xc);
502972Sgblack@eecs.umich.edu        NPC = ((curPc + imm) & mask(32)) | (curPc & ~mask(32));
512972Sgblack@eecs.umich.edu        '''
522972Sgblack@eecs.umich.edu        if (link):
533437Sgblack@eecs.umich.edu            bCode += '''
543093Sksewell@umich.edu                if (!isThumb(curPc))
553093Sksewell@umich.edu                    LR = curPc - 4;
563414Sgblack@eecs.umich.edu                else
573414Sgblack@eecs.umich.edu                    LR = curPc | 1;
582972Sgblack@eecs.umich.edu            '''
592469SN/A
602469SN/A        bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond",
613761Sgblack@eecs.umich.edu                             {"code": bCode,
623980Sgblack@eecs.umich.edu                              "predicate_test": predicateTest})
632469SN/A        header_output += BranchImmCondDeclare.subst(bIop)
642469SN/A        decoder_output += BranchImmCondConstructor.subst(bIop)
652458SN/A        exec_output += PredOpExecute.subst(bIop)
662458SN/A
672458SN/A    # BX, BLX
682458SN/A    blxCode = '''
692458SN/A    Addr curPc M5_VAR_USED = readPC(xc);
702458SN/A    %(link)s
712458SN/A    // Switch modes
722458SN/A    %(branch)s
732458SN/A    '''
742458SN/A
752458SN/A    blxList = (("blx", True, True),
762458SN/A               ("blx", False, True),
772458SN/A               ("bx", False, False))
782510SN/A
792458SN/A    for (mnem, imm, link) in blxList:
802458SN/A        Name = mnem.capitalize()
812458SN/A        if imm:
822525SN/A            Name += "Imm"
832561SN/A            # Since we're switching ISAs, the target ISA will be the opposite
842458SN/A            # of the current ISA. !arm is whether the target is ARM.
852458SN/A            newPC = '(isThumb(curPc) ? (roundDown(curPc, 4) + imm) : (curPc + imm))'
862458SN/A            base = "BranchImmCond"
872458SN/A            declare = BranchImmCondDeclare
882458SN/A            constructor = BranchImmCondConstructor
892458SN/A        else:
902458SN/A            Name += "Reg"
912458SN/A            newPC = 'Op1'
923756Sgblack@eecs.umich.edu            base = "BranchRegCond"
932458SN/A            declare = BranchRegCondDeclare
942458SN/A            constructor = BranchRegCondConstructor
952458SN/A        if link and imm:
962469SN/A            linkStr = '''
972458SN/A                // The immediate version of the blx thumb instruction
983804Ssaidi@eecs.umich.edu                // is 32 bits wide, but "next pc" doesn't reflect that
993804Ssaidi@eecs.umich.edu                // so we don't want to substract 2 from it at this point
1003804Ssaidi@eecs.umich.edu                if (!isThumb(curPc))
1013804Ssaidi@eecs.umich.edu                    LR = curPc - 4;
1023804Ssaidi@eecs.umich.edu                else
1033804Ssaidi@eecs.umich.edu                    LR = curPc  | 1;
1043804Ssaidi@eecs.umich.edu            '''
1053804Ssaidi@eecs.umich.edu        elif link:
1063804Ssaidi@eecs.umich.edu            linkStr = '''
1073804Ssaidi@eecs.umich.edu                if (!isThumb(curPc))
1083804Ssaidi@eecs.umich.edu                    LR = curPc - 4;
1093804Ssaidi@eecs.umich.edu                else
1103804Ssaidi@eecs.umich.edu                    LR = (curPc - 2) | 1;
1113804Ssaidi@eecs.umich.edu            '''
1122458SN/A        else:
1132458SN/A            linkStr = ""
1142023SN/A
115        if imm and link: #blx with imm
116            branchStr = '''
117                Addr tempPc = ((%(newPC)s) & mask(32)) | (curPc & ~mask(32));
118                FNPC = tempPc ^ PcTBit;
119            '''
120        else:
121            branchStr = "IWNPC = %(newPC)s;"
122        branchStr = branchStr % { "newPC" : newPC }
123
124        code = blxCode % {"link": linkStr,
125                          "newPC": newPC,
126                          "branch": branchStr}
127        blxIop = InstObjParams(mnem, Name, base,
128                               {"code": code,
129                                "predicate_test": predicateTest})
130        header_output += declare.subst(blxIop)
131        decoder_output += constructor.subst(blxIop)
132        exec_output += PredOpExecute.subst(blxIop)
133
134    #Ignore BXJ for now
135
136    #CBNZ, CBZ. These are always unconditional as far as predicates
137    for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")):
138        code = '''
139        Addr curPc = readPC(xc);
140        NPC = ((curPc + imm) & mask(32)) | (curPc & ~mask(32));
141        '''
142        predTest = "Op1 %(test)s 0" % {"test": test}
143        iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg",
144                            {"code": code, "predicate_test": predTest})
145        header_output += BranchImmRegDeclare.subst(iop)
146        decoder_output += BranchImmRegConstructor.subst(iop)
147        exec_output += PredOpExecute.subst(iop)
148
149    #TBB, TBH
150    for isTbh in (0, 1):
151        if isTbh:
152            eaCode = '''
153            unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned |
154                                      ArmISA::TLB::AlignHalfWord |
155                                      ArmISA::TLB::MustBeOne;
156            EA = Op1 + Op2 * 2
157            '''
158            accCode = "NPC = readPC(xc) + 2 * (Mem.uh);"
159            mnem = "tbh"
160        else:
161            eaCode = '''
162            unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned |
163                                      ArmISA::TLB::AlignByte |
164                                      ArmISA::TLB::MustBeOne;
165            EA = Op1 + Op2
166            '''
167            accCode = "NPC = readPC(xc) + 2 * (Mem.ub);"
168            mnem = "tbb"
169        iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg",
170                            {'ea_code': eaCode,
171                             'memacc_code': accCode,
172                             'predicate_test': predicateTest})
173        header_output += BranchTableDeclare.subst(iop)
174        decoder_output += BranchRegRegConstructor.subst(iop)
175        exec_output += LoadExecute.subst(iop) + \
176                       LoadInitiateAcc.subst(iop) + \
177                       LoadCompleteAcc.subst(iop)
178}};
179