3 // Copyright (c) 2010 ARM Limited
6 // The license below extends only to copyright in the software and shall
7 // not be construed as granting a license to any other intellectual
8 // property including but not limited to intellectual property relating
9 // to a hardware implementation of the functionality of the software
10 // licensed hereunder. You may use the software subject to the license
11 // terms below provided that you ensure that this notice is replicated
12 // unmodified and in its entirety in all distributions of the software,
13 // modified or unmodified, in source code or in binary form.
15 // Redistribution and use in source and binary forms, with or without
16 // modification, are permitted provided that the following conditions are
17 // met: redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer;
19 // redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution;
22 // neither the name of the copyright holders nor the names of its
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
26 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 // Authors: Gabe Black
47 for (mnem, link) in (("b", False), ("bl", True)):
49 NPC = (uint32_t)(PC + imm);
51 br_tgt_code = '''pcs.instNPC(branchPC.instPC() + imm);'''
52 instFlags = ["IsDirectControl"]
60 instFlags += ["IsCall"]
63 bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond",
64 {"code": bCode, "predicate_test": predicateTest,
65 "brTgtCode" : br_tgt_code}, instFlags)
66 header_output += BranchImmCondDeclare.subst(bIop)
67 decoder_output += BranchImmCondConstructor.subst(bIop) + \
68 BranchTarget.subst(bIop)
69 exec_output += PredOpExecute.subst(bIop)
78 blxList = (("blx", True, True),
82 for (mnem, imm, link) in blxList:
83 Name = mnem.capitalize()
87 # Since we're switching ISAs, the target ISA will be the opposite
88 # of the current ISA. Thumb is whether the target is ARM.
89 newPC = '(Thumb ? (roundDown(PC, 4) + imm) : (PC + imm))'
91 pcs.instNPC((branchPC.thumb() ? (roundDown(branchPC.instPC(),4) + imm) :
92 (branchPC.instPC() + imm)));
94 base = "BranchImmCond"
95 declare = BranchImmCondDeclare
96 constructor = BranchImmCondConstructor
97 instFlags = ["IsDirectControl"]
102 base = "BranchRegCond"
103 declare = BranchRegCondDeclare
104 constructor = BranchRegCondConstructor
105 instFlags = ["IsIndirectControl"]
108 // The immediate version of the blx thumb instruction
109 // is 32 bits wide, but "next pc" doesn't reflect that
110 // so we don't want to substract 2 from it at this point
116 instFlags += ["IsCall"]
124 instFlags += ["IsCall"]
127 isRasPop = "op1 == INTREG_LR"
129 if imm and link: #blx with imm
134 br_tgt_code = '''pcs.nextThumb(!branchPC.thumb());\n''' + \
137 branchStr = "IWNPC = %(newPC)s;"
138 branchStr = branchStr % { "newPC" : newPC }
140 code = blxCode % {"link": linkStr,
143 blxIop = InstObjParams(mnem, Name, base,
144 {"code": code, "brTgtCode" : br_tgt_code,
145 "predicate_test": predicateTest,
146 "is_ras_pop" : isRasPop }, instFlags)
147 header_output += declare.subst(blxIop)
148 decoder_output += constructor.subst(blxIop)
149 exec_output += PredOpExecute.subst(blxIop)
151 decoder_output += BranchTarget.subst(blxIop)
155 #CBNZ, CBZ. These are always unconditional as far as predicates
156 for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")):
157 code = 'NPC = (uint32_t)(PC + imm);\n'
158 predTest = "Op1 %(test)s 0" % {"test": test}
159 iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg",
160 {"code": code, "predicate_test": predTest},
161 ["IsIndirectControl"])
162 header_output += BranchImmRegDeclare.subst(iop)
163 decoder_output += BranchImmRegConstructor.subst(iop)
164 exec_output += PredOpExecute.subst(iop)
170 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned |
171 ArmISA::TLB::AlignHalfWord |
172 ArmISA::TLB::MustBeOne;
175 accCode = 'NPC = PC + 2 * (Mem_uh);\n'
179 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned |
180 ArmISA::TLB::AlignByte |
181 ArmISA::TLB::MustBeOne;
184 accCode = 'NPC = PC + 2 * (Mem_ub)'
186 iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg",
188 'memacc_code': accCode,
189 'predicate_test': predicateTest},
190 ["IsIndirectControl"])
191 header_output += BranchTableDeclare.subst(iop)
192 decoder_output += BranchRegRegConstructor.subst(iop)
193 exec_output += LoadExecute.subst(iop) + \
194 LoadInitiateAcc.subst(iop) + \
195 LoadCompleteAcc.subst(iop)