arm: Delete authors lists from the arm files.
[gem5.git] / src / arch / arm / isa / insts / branch.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2010-2012, 2014 ARM Limited
4 // All rights reserved
5 //
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.
14 //
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.
25 //
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.
37
38 let {{
39
40 header_output = ""
41 decoder_output = ""
42 exec_output = ""
43
44 # B, BL
45 for (mnem, link) in (("b", False), ("bl", True)):
46 bCode = '''
47 NPC = (uint32_t)(PC + imm);
48 '''
49 br_tgt_code = '''pcs.instNPC((uint32_t)(branchPC.instPC() + imm));'''
50 instFlags = ["IsDirectControl"]
51 if (link):
52 bCode += '''
53 if (Thumb)
54 LR = PC | 1;
55 else
56 LR = PC - 4;
57 '''
58 instFlags += ["IsCall"]
59
60
61 bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond",
62 {"code": bCode, "predicate_test": predicateTest,
63 "brTgtCode" : br_tgt_code}, instFlags)
64 header_output += BranchImmCondDeclare.subst(bIop)
65 decoder_output += BranchImmCondConstructor.subst(bIop) + \
66 BranchTarget.subst(bIop)
67 exec_output += PredOpExecute.subst(bIop)
68
69 # BX, BLX
70 blxCode = '''
71 %(link)s
72 // Switch modes
73 %(branch)s
74 '''
75
76 blxList = (("blx", True, True),
77 ("blx", False, True),
78 ("bx", False, False))
79
80 for (mnem, imm, link) in blxList:
81 Name = mnem.capitalize()
82 isRasPop = 0
83 if imm:
84 Name += "Imm"
85 # Since we're switching ISAs, the target ISA will be the opposite
86 # of the current ISA. Thumb is whether the target is ARM.
87 newPC = '(uint32_t)(Thumb ? (roundDown(PC, 4) + imm) : (PC + imm))'
88 br_tgt_code = '''
89 pcs.instNPC((uint32_t)(branchPC.thumb() ? (roundDown(branchPC.instPC(),4) + imm) :
90 (branchPC.instPC() + imm)));
91 '''
92 base = "BranchImmCond"
93 declare = BranchImmCondDeclare
94 constructor = BranchImmCondConstructor
95 instFlags = ["IsDirectControl"]
96 else:
97 Name += "Reg"
98 newPC = 'Op1'
99 br_tgt_code = ''
100 base = "BranchRegCond"
101 declare = BranchRegCondDeclare
102 constructor = BranchRegCondConstructor
103 instFlags = ["IsIndirectControl"]
104 if link and imm:
105 linkStr = '''
106 // The immediate version of the blx thumb instruction
107 // is 32 bits wide, but "next pc" doesn't reflect that
108 // so we don't want to substract 2 from it at this point
109 if (Thumb)
110 LR = PC | 1;
111 else
112 LR = PC - 4;
113 '''
114 instFlags += ["IsCall"]
115 elif link:
116 linkStr = '''
117 if (Thumb)
118 LR = (PC - 2) | 1;
119 else
120 LR = PC - 4;
121 '''
122 instFlags += ["IsCall"]
123 else:
124 linkStr = ""
125 isRasPop = "op1 == INTREG_LR"
126
127 if imm and link: #blx with imm
128 branchStr = '''
129 NextThumb = !Thumb;
130 NPC = %(newPC)s;
131 '''
132 br_tgt_code = '''pcs.nextThumb(!branchPC.thumb());\n''' + \
133 br_tgt_code
134 else:
135 branchStr = "IWNPC = %(newPC)s;"
136 branchStr = branchStr % { "newPC" : newPC }
137
138 code = blxCode % {"link": linkStr,
139 "newPC": newPC,
140 "branch": branchStr}
141 blxIop = InstObjParams(mnem, Name, base,
142 {"code": code, "brTgtCode" : br_tgt_code,
143 "predicate_test": predicateTest,
144 "is_ras_pop" : isRasPop }, instFlags)
145 header_output += declare.subst(blxIop)
146 decoder_output += constructor.subst(blxIop)
147 exec_output += PredOpExecute.subst(blxIop)
148 if imm:
149 decoder_output += BranchTarget.subst(blxIop)
150
151 bxjcode = '''
152 HSTR hstr = Hstr;
153 CPSR cpsr = Cpsr;
154 SCR scr = Scr;
155
156 if (ArmSystem::haveVirtualization(xc->tcBase()) && hstr.tjdbx &&
157 !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
158 fault = std::make_shared<HypervisorTrap>(machInst, op1, EC_TRAPPED_BXJ);
159 }
160 IWNPC = Op1;
161 '''
162
163 bxjIop = InstObjParams("bxj", "BxjReg", "BranchRegCond",
164 {"code": bxjcode,
165 "predicate_test": predicateTest,
166 "is_ras_pop": "op1 == INTREG_LR" },
167 ["IsIndirectControl"])
168 header_output += BranchRegCondDeclare.subst(bxjIop)
169 decoder_output += BranchRegCondConstructor.subst(bxjIop)
170 exec_output += PredOpExecute.subst(bxjIop)
171
172 #CBNZ, CBZ. These are always unconditional as far as predicates
173 for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")):
174 code = 'NPC = (uint32_t)(PC + imm);\n'
175 br_tgt_code = '''pcs.instNPC((uint32_t)(branchPC.instPC() + imm));'''
176 predTest = "Op1 %(test)s 0" % {"test": test}
177 iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg",
178 {"code": code, "predicate_test": predTest,
179 "brTgtCode" : br_tgt_code},
180 ["IsDirectControl"])
181 header_output += BranchImmRegDeclare.subst(iop)
182 decoder_output += BranchImmRegConstructor.subst(iop) + \
183 BranchTarget.subst(iop)
184 exec_output += PredOpExecute.subst(iop)
185
186 #TBB, TBH
187 for isTbh in (0, 1):
188 if isTbh:
189 eaCode = '''
190 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned |
191 ArmISA::TLB::AlignHalfWord |
192 ArmISA::TLB::MustBeOne;
193 EA = Op1 + Op2 * 2
194 '''
195 accCode = 'NPC = PC + 2 * (Mem_uh);\n'
196 mnem = "tbh"
197 else:
198 eaCode = '''
199 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned |
200 ArmISA::TLB::AlignByte |
201 ArmISA::TLB::MustBeOne;
202 EA = Op1 + Op2
203 '''
204 accCode = 'NPC = PC + 2 * (Mem_ub)'
205 mnem = "tbb"
206 iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg",
207 {'ea_code': eaCode,
208 'memacc_code': accCode,
209 'predicate_test': predicateTest},
210 ["IsIndirectControl"])
211 header_output += BranchTableDeclare.subst(iop)
212 decoder_output += BranchRegRegConstructor.subst(iop)
213 exec_output += LoadExecute.subst(iop) + \
214 LoadInitiateAcc.subst(iop) + \
215 LoadCompleteAcc.subst(iop)
216 }};