branch.isa (7290:ea9189fbb84f) branch.isa (7316:bb190cb8ee69)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 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// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Control transfer instructions
46//
47
48def format ArmBBlxImm() {{
49 decode_block = '''
50 if (machInst.condCode == 0xF) {
51 int32_t imm = (sext<26>(bits(machInst, 23, 0) << 2)) |
52 (bits(machInst, 24) << 1);
53 return new BlxImm(machInst, imm);
54 } else {
55 return new B(machInst, sext<26>(bits(machInst, 23, 0) << 2),
56 (ConditionCode)(uint32_t)machInst.condCode);
57 }
58 '''
59}};
60
61def format ArmBlBlxImm() {{
62 decode_block = '''
63 if (machInst.condCode == 0xF) {
64 int32_t imm = (sext<26>(bits(machInst, 23, 0) << 2)) |
65 (bits(machInst, 24) << 1);
66 return new BlxImm(machInst, imm);
67 } else {
68 return new Bl(machInst, sext<26>(bits(machInst, 23, 0) << 2),
69 (ConditionCode)(uint32_t)machInst.condCode);
70 }
71 '''
72}};
73
74def format ArmBxClz() {{
75 decode_block = '''
76 {
77 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
78 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
79 if (OPCODE == 0x9) {
80 return new BxReg(machInst, rm,
81 (ConditionCode)(uint32_t)machInst.condCode);
82 } else if (OPCODE == 0xb) {
83 return new Clz(machInst, rd, rm);
84 } else {
85 return new Unknown(machInst);
86 }
87 }
88 '''
89}};
90
91def format ArmBlxReg() {{
92 decode_block = '''
93 return new BlxReg(machInst, (IntRegIndex)(uint32_t)bits(machInst, 3, 0),
94 (ConditionCode)(uint32_t)machInst.condCode);
95 '''
96}};
97
98def format Thumb16CondBranchAndSvc() {{
99 decode_block = '''
100 if (bits(machInst, 11, 9) != 0x7) {
101 return new B(machInst, sext<9>(bits(machInst, 7, 0) << 1),
102 (ConditionCode)(uint32_t)bits(machInst, 11, 8));
103 } else if (bits(machInst, 8)) {
104 return new Svc(machInst);
105 } else {
106 // This space will not be allocated in the future.
107 return new Unknown(machInst);
108 }
109 '''
110}};
111
112def format Thumb16UncondBranch() {{
113 decode_block = '''
114 return new B(machInst, sext<12>(bits(machInst, 10, 0) << 1), COND_UC);
115 '''
116}};
117
118def format Thumb32BranchesAndMiscCtrl() {{
119 decode_block = '''
120 {
121 const uint32_t op = bits(machInst, 26, 20);
122 const uint32_t op1 = bits(machInst, 14, 12);
123 switch (op1 & 0x5) {
124 case 0x0:
125 if (op == 127) {
126 if (op1 & 0x2) {
127 // Permanently undefined.
128 return new Unknown(machInst);
129 } else {
130 return new WarnUnimplemented("smc", machInst);
131 }
132 } else if ((op & 0x38) != 0x38) {
133 const uint32_t s = bits(machInst, 26);
134 const uint32_t j1 = bits(machInst, 13);
135 const uint32_t j2 = bits(machInst, 11);
136 const uint32_t imm6 = bits(machInst, 21, 16);
137 const uint32_t imm11 = bits(machInst, 10, 0);
138 const int32_t imm = sext<21>((s << 20) |
139 (j2 << 19) | (j1 << 18) |
140 (imm6 << 12) | (imm11 << 1));
141 return new B(machInst, imm,
142 (ConditionCode)(uint32_t)bits(machInst, 25, 22));
143 } else {
144 switch (op) {
145 case 0x38:
146 {
147 const IntRegIndex rn =
148 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
149 const uint8_t byteMask = bits(machInst, 11, 8);
150 return new MsrCpsrReg(machInst, rn, byteMask);
151 }
152 case 0x39:
153 {
154 const IntRegIndex rn =
155 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
156 const uint8_t byteMask = bits(machInst, 11, 8);
157 return new MsrSpsrReg(machInst, rn, byteMask);
158 }
159 case 0x3a:
160 {
161 const uint32_t op1 = bits(machInst, 10, 8);
162 const uint32_t op2 = bits(machInst, 7, 0);
163 if (op1 != 0) {
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 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// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Control transfer instructions
46//
47
48def format ArmBBlxImm() {{
49 decode_block = '''
50 if (machInst.condCode == 0xF) {
51 int32_t imm = (sext<26>(bits(machInst, 23, 0) << 2)) |
52 (bits(machInst, 24) << 1);
53 return new BlxImm(machInst, imm);
54 } else {
55 return new B(machInst, sext<26>(bits(machInst, 23, 0) << 2),
56 (ConditionCode)(uint32_t)machInst.condCode);
57 }
58 '''
59}};
60
61def format ArmBlBlxImm() {{
62 decode_block = '''
63 if (machInst.condCode == 0xF) {
64 int32_t imm = (sext<26>(bits(machInst, 23, 0) << 2)) |
65 (bits(machInst, 24) << 1);
66 return new BlxImm(machInst, imm);
67 } else {
68 return new Bl(machInst, sext<26>(bits(machInst, 23, 0) << 2),
69 (ConditionCode)(uint32_t)machInst.condCode);
70 }
71 '''
72}};
73
74def format ArmBxClz() {{
75 decode_block = '''
76 {
77 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
78 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
79 if (OPCODE == 0x9) {
80 return new BxReg(machInst, rm,
81 (ConditionCode)(uint32_t)machInst.condCode);
82 } else if (OPCODE == 0xb) {
83 return new Clz(machInst, rd, rm);
84 } else {
85 return new Unknown(machInst);
86 }
87 }
88 '''
89}};
90
91def format ArmBlxReg() {{
92 decode_block = '''
93 return new BlxReg(machInst, (IntRegIndex)(uint32_t)bits(machInst, 3, 0),
94 (ConditionCode)(uint32_t)machInst.condCode);
95 '''
96}};
97
98def format Thumb16CondBranchAndSvc() {{
99 decode_block = '''
100 if (bits(machInst, 11, 9) != 0x7) {
101 return new B(machInst, sext<9>(bits(machInst, 7, 0) << 1),
102 (ConditionCode)(uint32_t)bits(machInst, 11, 8));
103 } else if (bits(machInst, 8)) {
104 return new Svc(machInst);
105 } else {
106 // This space will not be allocated in the future.
107 return new Unknown(machInst);
108 }
109 '''
110}};
111
112def format Thumb16UncondBranch() {{
113 decode_block = '''
114 return new B(machInst, sext<12>(bits(machInst, 10, 0) << 1), COND_UC);
115 '''
116}};
117
118def format Thumb32BranchesAndMiscCtrl() {{
119 decode_block = '''
120 {
121 const uint32_t op = bits(machInst, 26, 20);
122 const uint32_t op1 = bits(machInst, 14, 12);
123 switch (op1 & 0x5) {
124 case 0x0:
125 if (op == 127) {
126 if (op1 & 0x2) {
127 // Permanently undefined.
128 return new Unknown(machInst);
129 } else {
130 return new WarnUnimplemented("smc", machInst);
131 }
132 } else if ((op & 0x38) != 0x38) {
133 const uint32_t s = bits(machInst, 26);
134 const uint32_t j1 = bits(machInst, 13);
135 const uint32_t j2 = bits(machInst, 11);
136 const uint32_t imm6 = bits(machInst, 21, 16);
137 const uint32_t imm11 = bits(machInst, 10, 0);
138 const int32_t imm = sext<21>((s << 20) |
139 (j2 << 19) | (j1 << 18) |
140 (imm6 << 12) | (imm11 << 1));
141 return new B(machInst, imm,
142 (ConditionCode)(uint32_t)bits(machInst, 25, 22));
143 } else {
144 switch (op) {
145 case 0x38:
146 {
147 const IntRegIndex rn =
148 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
149 const uint8_t byteMask = bits(machInst, 11, 8);
150 return new MsrCpsrReg(machInst, rn, byteMask);
151 }
152 case 0x39:
153 {
154 const IntRegIndex rn =
155 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
156 const uint8_t byteMask = bits(machInst, 11, 8);
157 return new MsrSpsrReg(machInst, rn, byteMask);
158 }
159 case 0x3a:
160 {
161 const uint32_t op1 = bits(machInst, 10, 8);
162 const uint32_t op2 = bits(machInst, 7, 0);
163 if (op1 != 0) {
164 return new WarnUnimplemented("cps", machInst);
164 const bool enable = bits(machInst, 10, 9) == 0x2;
165 const uint32_t mods = bits(machInst, 8, 0) |
166 ((enable ? 1 : 0) << 9);
167 return new Cps(machInst, mods);
165 } else if ((op2 & 0xf0) == 0xf0) {
166 return new WarnUnimplemented("dbg", machInst);
167 } else {
168 switch (op2) {
169 case 0x0:
170 return new NopInst(machInst);
171 case 0x1:
172 return new WarnUnimplemented("yield", machInst);
173 case 0x2:
174 return new WarnUnimplemented("wfe", machInst);
175 case 0x3:
176 return new WarnUnimplemented("wfi", machInst);
177 case 0x4:
178 return new WarnUnimplemented("sev", machInst);
179 default:
180 break;
181 }
182 }
183 break;
184 }
185 case 0x3b:
186 {
187 const uint32_t op = bits(machInst, 7, 4);
188 switch (op) {
189 case 0x0:
190 return new Leavex(machInst);
191 case 0x1:
192 return new Enterx(machInst);
193 case 0x2:
194 return new WarnUnimplemented("clrex", machInst);
195 case 0x4:
196 return new WarnUnimplemented("dsb", machInst);
197 case 0x5:
198 return new WarnUnimplemented("dmb", machInst);
199 case 0x6:
200 return new WarnUnimplemented("isb", machInst);
201 default:
202 break;
203 }
204 break;
205 }
206 case 0x3c:
207 return new WarnUnimplemented("bxj", machInst);
208 case 0x3d:
209 {
210 const uint32_t imm32 = bits(machInst, 7, 0);
211 return new SubsImmPclr(machInst, INTREG_PC, INTREG_LR,
212 imm32, false);
213 }
214 case 0x3e:
215 {
216 const IntRegIndex rd =
217 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
218 return new MrsCpsr(machInst, rd);
219 }
220 case 0x3f:
221 {
222 const IntRegIndex rd =
223 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
224 return new MrsSpsr(machInst, rd);
225 }
226 }
227 break;
228 }
229 case 0x1:
230 {
231 const uint32_t s = bits(machInst, 26);
232 const uint32_t i1 = !(bits(machInst, 13) ^ s);
233 const uint32_t i2 = !(bits(machInst, 11) ^ s);
234 const uint32_t imm10 = bits(machInst, 25, 16);
235 const uint32_t imm11 = bits(machInst, 10, 0);
236 const int32_t imm = sext<25>((s << 24) |
237 (i1 << 23) | (i2 << 22) |
238 (imm10 << 12) | (imm11 << 1));
239 return new B(machInst, imm, COND_UC);
240 }
241 case 0x4:
242 {
243 if (bits(machInst, 0) == 1) {
244 return new Unknown(machInst);
245 }
246 const uint32_t s = bits(machInst, 26);
247 const uint32_t i1 = !(bits(machInst, 13) ^ s);
248 const uint32_t i2 = !(bits(machInst, 11) ^ s);
249 const uint32_t imm10h = bits(machInst, 25, 16);
250 const uint32_t imm10l = bits(machInst, 10, 1);
251 const int32_t imm = sext<25>((s << 24) |
252 (i1 << 23) | (i2 << 22) |
253 (imm10h << 12) | (imm10l << 2));
254 return new BlxImm(machInst, imm);
255 }
256 case 0x5:
257 {
258 const uint32_t s = bits(machInst, 26);
259 const uint32_t i1 = !(bits(machInst, 13) ^ s);
260 const uint32_t i2 = !(bits(machInst, 11) ^ s);
261 const uint32_t imm10 = bits(machInst, 25, 16);
262 const uint32_t imm11 = bits(machInst, 10, 0);
263 const int32_t imm = sext<25>((s << 24) |
264 (i1 << 23) | (i2 << 22) |
265 (imm10 << 12) | (imm11 << 1));
266 return new Bl(machInst, imm, COND_UC);
267 }
268 default:
269 break;
270 }
271 return new Unknown(machInst);
272 }
273 '''
274}};
168 } else if ((op2 & 0xf0) == 0xf0) {
169 return new WarnUnimplemented("dbg", machInst);
170 } else {
171 switch (op2) {
172 case 0x0:
173 return new NopInst(machInst);
174 case 0x1:
175 return new WarnUnimplemented("yield", machInst);
176 case 0x2:
177 return new WarnUnimplemented("wfe", machInst);
178 case 0x3:
179 return new WarnUnimplemented("wfi", machInst);
180 case 0x4:
181 return new WarnUnimplemented("sev", machInst);
182 default:
183 break;
184 }
185 }
186 break;
187 }
188 case 0x3b:
189 {
190 const uint32_t op = bits(machInst, 7, 4);
191 switch (op) {
192 case 0x0:
193 return new Leavex(machInst);
194 case 0x1:
195 return new Enterx(machInst);
196 case 0x2:
197 return new WarnUnimplemented("clrex", machInst);
198 case 0x4:
199 return new WarnUnimplemented("dsb", machInst);
200 case 0x5:
201 return new WarnUnimplemented("dmb", machInst);
202 case 0x6:
203 return new WarnUnimplemented("isb", machInst);
204 default:
205 break;
206 }
207 break;
208 }
209 case 0x3c:
210 return new WarnUnimplemented("bxj", machInst);
211 case 0x3d:
212 {
213 const uint32_t imm32 = bits(machInst, 7, 0);
214 return new SubsImmPclr(machInst, INTREG_PC, INTREG_LR,
215 imm32, false);
216 }
217 case 0x3e:
218 {
219 const IntRegIndex rd =
220 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
221 return new MrsCpsr(machInst, rd);
222 }
223 case 0x3f:
224 {
225 const IntRegIndex rd =
226 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
227 return new MrsSpsr(machInst, rd);
228 }
229 }
230 break;
231 }
232 case 0x1:
233 {
234 const uint32_t s = bits(machInst, 26);
235 const uint32_t i1 = !(bits(machInst, 13) ^ s);
236 const uint32_t i2 = !(bits(machInst, 11) ^ s);
237 const uint32_t imm10 = bits(machInst, 25, 16);
238 const uint32_t imm11 = bits(machInst, 10, 0);
239 const int32_t imm = sext<25>((s << 24) |
240 (i1 << 23) | (i2 << 22) |
241 (imm10 << 12) | (imm11 << 1));
242 return new B(machInst, imm, COND_UC);
243 }
244 case 0x4:
245 {
246 if (bits(machInst, 0) == 1) {
247 return new Unknown(machInst);
248 }
249 const uint32_t s = bits(machInst, 26);
250 const uint32_t i1 = !(bits(machInst, 13) ^ s);
251 const uint32_t i2 = !(bits(machInst, 11) ^ s);
252 const uint32_t imm10h = bits(machInst, 25, 16);
253 const uint32_t imm10l = bits(machInst, 10, 1);
254 const int32_t imm = sext<25>((s << 24) |
255 (i1 << 23) | (i2 << 22) |
256 (imm10h << 12) | (imm10l << 2));
257 return new BlxImm(machInst, imm);
258 }
259 case 0x5:
260 {
261 const uint32_t s = bits(machInst, 26);
262 const uint32_t i1 = !(bits(machInst, 13) ^ s);
263 const uint32_t i2 = !(bits(machInst, 11) ^ s);
264 const uint32_t imm10 = bits(machInst, 25, 16);
265 const uint32_t imm11 = bits(machInst, 10, 0);
266 const int32_t imm = sext<25>((s << 24) |
267 (i1 << 23) | (i2 << 22) |
268 (imm10 << 12) | (imm11 << 1));
269 return new Bl(machInst, imm, COND_UC);
270 }
271 default:
272 break;
273 }
274 return new Unknown(machInst);
275 }
276 '''
277}};