data.isa (7224:7d22b6d6093f) data.isa (7227:6f435f54b1fb)
1// Copyright (c) 2010 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder. You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Gabe Black
37
38def format ArmDataProcReg() {{
39 pclr = '''
40 return new %(className)ssRegPclr(machInst, %(dest)s,
41 %(op1)s, rm, imm5,
42 type);
43 '''
44 instDecode = '''
45 case %(opcode)#x:
46 if (immShift) {
47 if (setCc) {
48 if (%(dest)s == INTREG_PC) {
49 %(pclr)s
50 } else {
51 return new %(className)sRegCc(machInst, %(dest)s,
52 %(op1)s, rm, imm5, type);
53 }
54 } else {
55 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
56 rm, imm5, type);
57 }
58 } else {
59 if (setCc) {
60 return new %(className)sRegRegCc(machInst, %(dest)s,
61 %(op1)s, rm, rs, type);
62 } else {
63 return new %(className)sRegReg(machInst, %(dest)s,
64 %(op1)s, rm, rs, type);
65 }
66 }
67 break;
68 '''
69
70 def instCode(opcode, mnem, useDest = True, useOp1 = True):
71 global pclr
72 if useDest:
73 dest = "rd"
74 else:
75 dest = "INTREG_ZERO"
76 if useOp1:
77 op1 = "rn"
78 else:
79 op1 = "INTREG_ZERO"
80 global instDecode, pclrCode
81 substDict = { "className": mnem.capitalize(),
82 "opcode": opcode,
83 "dest": dest,
84 "op1": op1 }
85 if useDest:
86 substDict["pclr"] = pclr % substDict
87 else:
88 substDict["pclr"] = ""
89 return instDecode % substDict
90
91 decode_block = '''
92 {
93 const bool immShift = (bits(machInst, 4) == 0);
94 const bool setCc = (bits(machInst, 20) == 1);
95 const uint32_t imm5 = bits(machInst, 11, 7);
96 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
97 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
98 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
99 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
100 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
101 switch (OPCODE) {
102 '''
103 decode_block += instCode(0x0, "and")
104 decode_block += instCode(0x1, "eor")
105 decode_block += instCode(0x2, "sub")
106 decode_block += instCode(0x3, "rsb")
107 decode_block += instCode(0x4, "add")
108 decode_block += instCode(0x5, "adc")
109 decode_block += instCode(0x6, "sbc")
110 decode_block += instCode(0x7, "rsc")
111 decode_block += instCode(0x8, "tst", useDest = False)
112 decode_block += instCode(0x9, "teq", useDest = False)
113 decode_block += instCode(0xa, "cmp", useDest = False)
114 decode_block += instCode(0xb, "cmn", useDest = False)
115 decode_block += instCode(0xc, "orr")
116 decode_block += instCode(0xd, "mov", useOp1 = False)
117 decode_block += instCode(0xe, "bic")
118 decode_block += instCode(0xf, "mvn", useOp1 = False)
119 decode_block += '''
120 default:
121 return new Unknown(machInst);
122 }
123 }
124 '''
125}};
126
127def format ArmPackUnpackSatReverse() {{
128 decode_block = '''
129 {
130 const uint32_t op1 = bits(machInst, 22, 20);
131 const uint32_t a = bits(machInst, 19, 16);
132 const uint32_t op2 = bits(machInst, 7, 5);
133 if (bits(op2, 0) == 0) {
1// Copyright (c) 2010 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder. You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Gabe Black
37
38def format ArmDataProcReg() {{
39 pclr = '''
40 return new %(className)ssRegPclr(machInst, %(dest)s,
41 %(op1)s, rm, imm5,
42 type);
43 '''
44 instDecode = '''
45 case %(opcode)#x:
46 if (immShift) {
47 if (setCc) {
48 if (%(dest)s == INTREG_PC) {
49 %(pclr)s
50 } else {
51 return new %(className)sRegCc(machInst, %(dest)s,
52 %(op1)s, rm, imm5, type);
53 }
54 } else {
55 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
56 rm, imm5, type);
57 }
58 } else {
59 if (setCc) {
60 return new %(className)sRegRegCc(machInst, %(dest)s,
61 %(op1)s, rm, rs, type);
62 } else {
63 return new %(className)sRegReg(machInst, %(dest)s,
64 %(op1)s, rm, rs, type);
65 }
66 }
67 break;
68 '''
69
70 def instCode(opcode, mnem, useDest = True, useOp1 = True):
71 global pclr
72 if useDest:
73 dest = "rd"
74 else:
75 dest = "INTREG_ZERO"
76 if useOp1:
77 op1 = "rn"
78 else:
79 op1 = "INTREG_ZERO"
80 global instDecode, pclrCode
81 substDict = { "className": mnem.capitalize(),
82 "opcode": opcode,
83 "dest": dest,
84 "op1": op1 }
85 if useDest:
86 substDict["pclr"] = pclr % substDict
87 else:
88 substDict["pclr"] = ""
89 return instDecode % substDict
90
91 decode_block = '''
92 {
93 const bool immShift = (bits(machInst, 4) == 0);
94 const bool setCc = (bits(machInst, 20) == 1);
95 const uint32_t imm5 = bits(machInst, 11, 7);
96 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
97 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
98 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
99 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
100 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
101 switch (OPCODE) {
102 '''
103 decode_block += instCode(0x0, "and")
104 decode_block += instCode(0x1, "eor")
105 decode_block += instCode(0x2, "sub")
106 decode_block += instCode(0x3, "rsb")
107 decode_block += instCode(0x4, "add")
108 decode_block += instCode(0x5, "adc")
109 decode_block += instCode(0x6, "sbc")
110 decode_block += instCode(0x7, "rsc")
111 decode_block += instCode(0x8, "tst", useDest = False)
112 decode_block += instCode(0x9, "teq", useDest = False)
113 decode_block += instCode(0xa, "cmp", useDest = False)
114 decode_block += instCode(0xb, "cmn", useDest = False)
115 decode_block += instCode(0xc, "orr")
116 decode_block += instCode(0xd, "mov", useOp1 = False)
117 decode_block += instCode(0xe, "bic")
118 decode_block += instCode(0xf, "mvn", useOp1 = False)
119 decode_block += '''
120 default:
121 return new Unknown(machInst);
122 }
123 }
124 '''
125}};
126
127def format ArmPackUnpackSatReverse() {{
128 decode_block = '''
129 {
130 const uint32_t op1 = bits(machInst, 22, 20);
131 const uint32_t a = bits(machInst, 19, 16);
132 const uint32_t op2 = bits(machInst, 7, 5);
133 if (bits(op2, 0) == 0) {
134 const IntRegIndex rn =
135 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
136 const IntRegIndex rd =
137 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
138 const uint32_t satImm = bits(machInst, 20, 16);
139 const uint32_t imm = bits(machInst, 11, 7);
140 const ArmShiftType type =
141 (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
134 if (op1 == 0) {
135 return new WarnUnimplemented("pkh", machInst);
136 } else if (bits(op1, 2, 1) == 1) {
142 if (op1 == 0) {
143 return new WarnUnimplemented("pkh", machInst);
144 } else if (bits(op1, 2, 1) == 1) {
137 return new WarnUnimplemented("ssat", machInst);
145 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
138 } else if (bits(op1, 2, 1) == 3) {
146 } else if (bits(op1, 2, 1) == 3) {
139 return new WarnUnimplemented("usat", machInst);
147 return new Usat(machInst, rd, satImm, rn, imm, type);
140 }
141 return new Unknown(machInst);
142 }
143 switch (op1) {
144 case 0x0:
145 if (op2 == 0x3) {
146 if (a == 0xf) {
147 return new WarnUnimplemented("sxtb16", machInst);
148 } else {
149 return new WarnUnimplemented("sxtab16", machInst);
150 }
151 } else if (op2 == 0x5) {
152 return new WarnUnimplemented("sel", machInst);
153 }
154 break;
155 case 0x2:
156 if (op2 == 0x1) {
148 }
149 return new Unknown(machInst);
150 }
151 switch (op1) {
152 case 0x0:
153 if (op2 == 0x3) {
154 if (a == 0xf) {
155 return new WarnUnimplemented("sxtb16", machInst);
156 } else {
157 return new WarnUnimplemented("sxtab16", machInst);
158 }
159 } else if (op2 == 0x5) {
160 return new WarnUnimplemented("sel", machInst);
161 }
162 break;
163 case 0x2:
164 if (op2 == 0x1) {
157 return new WarnUnimplemented("ssat16", machInst);
165 const IntRegIndex rn =
166 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
167 const IntRegIndex rd =
168 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
169 const uint32_t satImm = bits(machInst, 20, 16);
170 return new Ssat16(machInst, rd, satImm + 1, rn);
158 } else if (op2 == 0x3) {
159 if (a == 0xf) {
160 return new WarnUnimplemented("sxtb", machInst);
161 } else {
162 return new WarnUnimplemented("sxtab", machInst);
163 }
164 }
165 break;
166 case 0x3:
167 if (op2 == 0x1) {
168 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
169 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
170 return new Rev(machInst, rd, rm);
171 } else if (op2 == 0x3) {
172 if (a == 0xf) {
173 return new WarnUnimplemented("sxth", machInst);
174 } else {
175 return new WarnUnimplemented("sxtah", machInst);
176 }
177 } else if (op2 == 0x5) {
178 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
179 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
180 return new Rev16(machInst, rd, rm);
181 }
182 break;
183 case 0x4:
184 if (op2 == 0x3) {
185 if (a == 0xf) {
186 return new WarnUnimplemented("uxtb16", machInst);
187 } else {
188 return new WarnUnimplemented("uxtab16", machInst);
189 }
190 }
191 break;
192 case 0x6:
193 if (op2 == 0x1) {
171 } else if (op2 == 0x3) {
172 if (a == 0xf) {
173 return new WarnUnimplemented("sxtb", machInst);
174 } else {
175 return new WarnUnimplemented("sxtab", machInst);
176 }
177 }
178 break;
179 case 0x3:
180 if (op2 == 0x1) {
181 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
182 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
183 return new Rev(machInst, rd, rm);
184 } else if (op2 == 0x3) {
185 if (a == 0xf) {
186 return new WarnUnimplemented("sxth", machInst);
187 } else {
188 return new WarnUnimplemented("sxtah", machInst);
189 }
190 } else if (op2 == 0x5) {
191 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
192 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
193 return new Rev16(machInst, rd, rm);
194 }
195 break;
196 case 0x4:
197 if (op2 == 0x3) {
198 if (a == 0xf) {
199 return new WarnUnimplemented("uxtb16", machInst);
200 } else {
201 return new WarnUnimplemented("uxtab16", machInst);
202 }
203 }
204 break;
205 case 0x6:
206 if (op2 == 0x1) {
194 return new WarnUnimplemented("usat16", machInst);
207 const IntRegIndex rn =
208 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
209 const IntRegIndex rd =
210 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
211 const uint32_t satImm = bits(machInst, 20, 16);
212 return new Usat16(machInst, rd, satImm, rn);
195 } else if (op2 == 0x3) {
196 if (a == 0xf) {
197 return new WarnUnimplemented("uxtb", machInst);
198 } else {
199 return new WarnUnimplemented("uxtab", machInst);
200 }
201 }
202 break;
203 case 0x7:
204 if (op2 == 0x1) {
205 return new WarnUnimplemented("rbit", machInst);
206 } else if (op2 == 0x3) {
207 if (a == 0xf) {
208 return new WarnUnimplemented("uxth", machInst);
209 } else {
210 return new WarnUnimplemented("uxtah", machInst);
211 }
212 } else if (op2 == 0x5) {
213 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
214 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
215 return new Revsh(machInst, rd, rm);
216 }
217 break;
218 }
219 return new Unknown(machInst);
220 }
221 '''
222}};
223
224def format ArmParallelAddSubtract() {{
225 decode_block='''
226 {
227 const uint32_t op1 = bits(machInst, 21, 20);
228 const uint32_t op2 = bits(machInst, 7, 5);
229 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
230 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
231 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
232 if (bits(machInst, 22) == 0) {
233 switch (op1) {
234 case 0x1:
235 switch (op2) {
236 case 0x0:
237 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
238 case 0x1:
239 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
240 case 0x2:
241 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
242 case 0x3:
243 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
244 case 0x4:
245 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
246 case 0x7:
247 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
248 }
249 break;
250 case 0x2:
251 switch (op2) {
252 case 0x0:
253 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
254 case 0x1:
255 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
256 case 0x2:
257 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
258 case 0x3:
259 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
260 case 0x4:
261 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
262 case 0x7:
263 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
264 }
265 break;
266 case 0x3:
267 switch (op2) {
268 case 0x0:
269 return new WarnUnimplemented("shadd16", machInst);
270 case 0x1:
271 return new WarnUnimplemented("shasx", machInst);
272 case 0x2:
273 return new WarnUnimplemented("shsax", machInst);
274 case 0x3:
275 return new WarnUnimplemented("shsub16", machInst);
276 case 0x4:
277 return new WarnUnimplemented("shadd8", machInst);
278 case 0x7:
279 return new WarnUnimplemented("shsub8", machInst);
280 }
281 break;
282 }
283 } else {
284 switch (op1) {
285 case 0x1:
286 switch (op2) {
287 case 0x0:
288 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
289 case 0x1:
290 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
291 case 0x2:
292 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
293 case 0x3:
294 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
295 case 0x4:
296 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
297 case 0x7:
298 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
299 }
300 break;
301 case 0x2:
302 switch (op2) {
303 case 0x0:
304 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
305 case 0x1:
306 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
307 case 0x2:
308 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
309 case 0x3:
310 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
311 case 0x4:
312 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
313 case 0x7:
314 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
315 }
316 break;
317 case 0x3:
318 switch (op2) {
319 case 0x0:
320 return new WarnUnimplemented("uhadd16", machInst);
321 case 0x1:
322 return new WarnUnimplemented("uhasx", machInst);
323 case 0x2:
324 return new WarnUnimplemented("uhsax", machInst);
325 case 0x3:
326 return new WarnUnimplemented("uhsub16", machInst);
327 case 0x4:
328 return new WarnUnimplemented("uhadd8", machInst);
329 case 0x7:
330 return new WarnUnimplemented("uhsub8", machInst);
331 }
332 break;
333 }
334 }
335 return new Unknown(machInst);
336 }
337 '''
338}};
339
340def format ArmDataProcImm() {{
341 pclr = '''
342 return new %(className)ssImmPclr(machInst, %(dest)s,
343 %(op1)s, imm, false);
344 '''
345 adr = '''
346 return new AdrImm(machInst, %(dest)s, %(add)s,
347 imm, false);
348 '''
349 instDecode = '''
350 case %(opcode)#x:
351 if (setCc) {
352 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
353 %(pclr)s
354 } else {
355 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
356 imm, rotC);
357 }
358 } else {
359 if (%(adrInst)s && %(op1)s == INTREG_PC) {
360 %(adr)s
361 } else {
362 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
363 imm, rotC);
364 }
365 }
366 break;
367 '''
368
369 def instCode(opcode, mnem, useDest = True, useOp1 = True):
370 global instDecode, pclr, adr
371 if useDest:
372 dest = "rd"
373 else:
374 dest = "INTREG_ZERO"
375 if useOp1:
376 op1 = "rn"
377 else:
378 op1 = "INTREG_ZERO"
379 substDict = { "className": mnem.capitalize(),
380 "opcode": opcode,
381 "dest": dest,
382 "op1": op1,
383 "adr": "",
384 "adrInst": "false" }
385 if useDest:
386 substDict["pclrInst"] = "true"
387 substDict["pclr"] = pclr % substDict
388 else:
389 substDict["pclrInst"] = "false"
390 substDict["pclr"] = ""
391 return instDecode % substDict
392
393 def adrCode(opcode, mnem, add="1"):
394 global instDecode, pclr, adr
395 substDict = { "className": mnem.capitalize(),
396 "opcode": opcode,
397 "dest": "rd",
398 "op1": "rn",
399 "add": add,
400 "pclrInst": "true",
401 "adrInst": "true" }
402 substDict["pclr"] = pclr % substDict
403 substDict["adr"] = adr % substDict
404 return instDecode % substDict
405
406 decode_block = '''
407 {
408 const bool setCc = (bits(machInst, 20) == 1);
409 const uint32_t unrotated = bits(machInst, 7, 0);
410 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
411 const bool rotC = (rotation != 0);
412 const uint32_t imm = rotate_imm(unrotated, rotation);
413 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
414 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
415 switch (OPCODE) {
416 '''
417 decode_block += instCode(0x0, "and")
418 decode_block += instCode(0x1, "eor")
419 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
420 decode_block += instCode(0x3, "rsb")
421 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
422 decode_block += instCode(0x5, "adc")
423 decode_block += instCode(0x6, "sbc")
424 decode_block += instCode(0x7, "rsc")
425 decode_block += instCode(0x8, "tst", useDest = False)
426 decode_block += instCode(0x9, "teq", useDest = False)
427 decode_block += instCode(0xa, "cmp", useDest = False)
428 decode_block += instCode(0xb, "cmn", useDest = False)
429 decode_block += instCode(0xc, "orr")
430 decode_block += instCode(0xd, "mov", useOp1 = False)
431 decode_block += instCode(0xe, "bic")
432 decode_block += instCode(0xf, "mvn", useOp1 = False)
433 decode_block += '''
434 default:
435 return new Unknown(machInst);
436 }
437 }
438 '''
439}};
440
441def format ArmSatAddSub() {{
442 decode_block = '''
443 {
444 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
445 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
446 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
447 switch (OPCODE) {
448 case 0x8:
449 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
450 case 0x9:
451 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
452 case 0xa:
453 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
454 case 0xb:
455 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
456 default:
457 return new Unknown(machInst);
458 }
459 }
460 '''
461}};
462
463def format Thumb32DataProcReg() {{
464 decode_block = '''
465 {
466 const uint32_t op1 = bits(machInst, 23, 20);
467 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
468 const uint32_t op2 = bits(machInst, 7, 4);
469 if (bits(op1, 3) != 1) {
470 if (op2 == 0) {
471 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
472 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
473 switch (bits(op1, 2, 0)) {
474 case 0x0:
475 return new MovRegReg(machInst, rd,
476 INTREG_ZERO, rn, rm, LSL);
477 case 0x1:
478 return new MovRegRegCc(machInst, rd,
479 INTREG_ZERO, rn, rm, LSL);
480 case 0x2:
481 return new MovRegReg(machInst, rd,
482 INTREG_ZERO, rn, rm, LSR);
483 case 0x3:
484 return new MovRegRegCc(machInst, rd,
485 INTREG_ZERO, rn, rm, LSR);
486 case 0x4:
487 return new MovRegReg(machInst, rd,
488 INTREG_ZERO, rn, rm, ASR);
489 case 0x5:
490 return new MovRegRegCc(machInst, rd,
491 INTREG_ZERO, rn, rm, ASR);
492 case 0x6:
493 return new MovRegReg(machInst, rd,
494 INTREG_ZERO, rn, rm, ROR);
495 case 0x7:
496 return new MovRegRegCc(machInst, rd,
497 INTREG_ZERO, rn, rm, ROR);
498 }
499 }
500 switch (bits(op1, 2, 0)) {
501 case 0x0:
502 if (rn == 0xf) {
503 return new WarnUnimplemented("sxth", machInst);
504 } else {
505 return new WarnUnimplemented("sxtah", machInst);
506 }
507 case 0x1:
508 if (rn == 0xf) {
509 return new WarnUnimplemented("uxth", machInst);
510 } else {
511 return new WarnUnimplemented("uxtah", machInst);
512 }
513 case 0x2:
514 if (rn == 0xf) {
515 return new WarnUnimplemented("sxtb16", machInst);
516 } else {
517 return new WarnUnimplemented("sxtab16", machInst);
518 }
519 case 0x3:
520 if (rn == 0xf) {
521 return new WarnUnimplemented("uxtb16", machInst);
522 } else {
523 return new WarnUnimplemented("uxtab16", machInst);
524 }
525 case 0x4:
526 if (rn == 0xf) {
527 return new WarnUnimplemented("sxtb", machInst);
528 } else {
529 return new WarnUnimplemented("sxtab", machInst);
530 }
531 case 0x5:
532 if (rn == 0xf) {
533 return new WarnUnimplemented("uxtb", machInst);
534 } else {
535 return new WarnUnimplemented("uxtab", machInst);
536 }
537 default:
538 return new Unknown(machInst);
539 }
540 } else {
541 if (bits(op2, 3) == 0) {
542 const IntRegIndex rd =
543 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
544 const IntRegIndex rm =
545 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
546 if (bits(op2, 2) == 0x0) {
547 const uint32_t op1 = bits(machInst, 22, 20);
548 const uint32_t op2 = bits(machInst, 5, 4);
549 switch (op2) {
550 case 0x0:
551 switch (op1) {
552 case 0x1:
553 return new Sadd16RegCc(machInst, rd,
554 rn, rm, 0, LSL);
555 case 0x2:
556 return new SasxRegCc(machInst, rd,
557 rn, rm, 0, LSL);
558 case 0x6:
559 return new SsaxRegCc(machInst, rd,
560 rn, rm, 0, LSL);
561 case 0x5:
562 return new Ssub16RegCc(machInst, rd,
563 rn, rm, 0, LSL);
564 case 0x0:
565 return new Sadd8RegCc(machInst, rd,
566 rn, rm, 0, LSL);
567 case 0x4:
568 return new Ssub8RegCc(machInst, rd,
569 rn, rm, 0, LSL);
570 }
571 break;
572 case 0x1:
573 switch (op1) {
574 case 0x1:
575 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
576 case 0x2:
577 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
578 case 0x6:
579 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
580 case 0x5:
581 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
582 case 0x0:
583 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
584 case 0x4:
585 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
586 }
587 break;
588 case 0x2:
589 switch (op1) {
590 case 0x1:
591 return new WarnUnimplemented("shadd16", machInst);
592 case 0x2:
593 return new WarnUnimplemented("shasx", machInst);
594 case 0x6:
595 return new WarnUnimplemented("shsax", machInst);
596 case 0x5:
597 return new WarnUnimplemented("shsub16", machInst);
598 case 0x0:
599 return new WarnUnimplemented("shadd8", machInst);
600 case 0x4:
601 return new WarnUnimplemented("shsub8", machInst);
602 }
603 break;
604 }
605 } else {
606 const uint32_t op1 = bits(machInst, 22, 20);
607 const uint32_t op2 = bits(machInst, 5, 4);
608 switch (op2) {
609 case 0x0:
610 switch (op1) {
611 case 0x1:
612 return new Uadd16RegCc(machInst, rd,
613 rn, rm, 0, LSL);
614 case 0x2:
615 return new UasxRegCc(machInst, rd,
616 rn, rm, 0, LSL);
617 case 0x6:
618 return new UsaxRegCc(machInst, rd,
619 rn, rm, 0, LSL);
620 case 0x5:
621 return new Usub16RegCc(machInst, rd,
622 rn, rm, 0, LSL);
623 case 0x0:
624 return new Uadd8RegCc(machInst, rd,
625 rn, rm, 0, LSL);
626 case 0x4:
627 return new Usub8RegCc(machInst, rd,
628 rn, rm, 0, LSL);
629 }
630 break;
631 case 0x1:
632 switch (op1) {
633 case 0x1:
634 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
635 case 0x2:
636 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
637 case 0x6:
638 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
639 case 0x5:
640 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
641 case 0x0:
642 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
643 case 0x4:
644 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
645 }
646 break;
647 case 0x2:
648 switch (op1) {
649 case 0x1:
650 return new WarnUnimplemented("uhadd16", machInst);
651 case 0x2:
652 return new WarnUnimplemented("uhasx", machInst);
653 case 0x6:
654 return new WarnUnimplemented("uhsax", machInst);
655 case 0x5:
656 return new WarnUnimplemented("uhsub16", machInst);
657 case 0x0:
658 return new WarnUnimplemented("uhadd8", machInst);
659 case 0x4:
660 return new WarnUnimplemented("uhsub8", machInst);
661 }
662 break;
663 }
664 }
665 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
666 const uint32_t op1 = bits(machInst, 21, 20);
667 const uint32_t op2 = bits(machInst, 5, 4);
668 switch (op1) {
669 case 0x0:
670 {
671 IntRegIndex rd =
672 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
673 IntRegIndex rm =
674 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
675 switch (op2) {
676 case 0x0:
677 return new QaddRegCc(machInst, rd,
678 rm, rn, 0, LSL);
679 case 0x1:
680 return new QdaddRegCc(machInst, rd,
681 rm, rn, 0, LSL);
682 case 0x2:
683 return new QsubRegCc(machInst, rd,
684 rm, rn, 0, LSL);
685 case 0x3:
686 return new QdsubRegCc(machInst, rd,
687 rm, rn, 0, LSL);
688 }
689 }
690 break;
691 case 0x1:
692 {
693 IntRegIndex rd =
694 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
695 IntRegIndex rm = rn;
696 switch (op2) {
697 case 0x0:
698 return new Rev(machInst, rd, rm);
699 case 0x1:
700 return new Rev16(machInst, rd, rm);
701 case 0x2:
702 return new WarnUnimplemented("rbit", machInst);
703 case 0x3:
704 return new Revsh(machInst, rd, rm);
705 }
706 }
707 break;
708 case 0x2:
709 if (op2 == 0) {
710 return new WarnUnimplemented("sel", machInst);
711 }
712 break;
713 case 0x3:
714 if (op2 == 0) {
715 return new WarnUnimplemented("clz", machInst);
716 }
717 }
718 }
719 return new Unknown(machInst);
720 }
721 }
722 '''
723}};
724
725def format Thumb16ShiftAddSubMoveCmp() {{
726 decode_block = '''
727 {
728 const uint32_t imm5 = bits(machInst, 10, 6);
729 const uint32_t imm3 = bits(machInst, 8, 6);
730 const uint32_t imm8 = bits(machInst, 7, 0);
731 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
732 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
733 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
734 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
735 switch (bits(machInst, 13, 11)) {
736 case 0x0: // lsl
737 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
738 case 0x1: // lsr
739 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
740 case 0x2: // asr
741 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
742 case 0x3:
743 switch (bits(machInst, 10, 9)) {
744 case 0x0:
745 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
746 case 0x1:
747 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
748 case 0x2:
749 return new AddImmCc(machInst, rd, rn, imm3, true);
750 case 0x3:
751 return new SubImmCc(machInst, rd, rn, imm3, true);
752 }
753 case 0x4:
754 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
755 case 0x5:
756 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
757 case 0x6:
758 return new AddImmCc(machInst, rd8, rd8, imm8, true);
759 case 0x7:
760 return new SubImmCc(machInst, rd8, rd8, imm8, true);
761 }
762 }
763 '''
764}};
765
766def format Thumb16DataProcessing() {{
767 decode_block = '''
768 {
769 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
770 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
771 switch (bits(machInst, 9, 6)) {
772 case 0x0:
773 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
774 case 0x1:
775 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
776 case 0x2: //lsl
777 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
778 case 0x3: //lsr
779 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
780 case 0x4: //asr
781 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
782 case 0x5:
783 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
784 case 0x6:
785 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
786 case 0x7: // ror
787 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
788 case 0x8:
789 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
790 case 0x9:
791 return new RsbImmCc(machInst, rdn, rm, 0, true);
792 case 0xa:
793 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
794 case 0xb:
795 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
796 case 0xc:
797 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
798 case 0xd:
799 return new MulCc(machInst, rdn, rm, rdn);
800 case 0xe:
801 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
802 case 0xf:
803 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
804 }
805 }
806 '''
807}};
808
809def format Thumb16SpecDataAndBx() {{
810 decode_block = '''
811 {
812 const IntRegIndex rdn =
813 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
814 (bits(machInst, 7) << 3));
815 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
816 switch (bits(machInst, 9, 8)) {
817 case 0x0:
818 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
819 case 0x1:
820 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
821 case 0x2:
822 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
823 case 0x3:
824 if (bits(machInst, 7) == 0) {
825 return new BxReg(machInst,
826 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
827 COND_UC);
828 } else {
829 return new BlxReg(machInst,
830 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
831 COND_UC);
832 }
833 }
834 }
835 '''
836}};
837
838def format Thumb16Adr() {{
839 decode_block = '''
840 {
841 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
842 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
843 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
844 }
845 '''
846}};
847
848def format Thumb16AddSp() {{
849 decode_block = '''
850 {
851 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
852 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
853 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
854 }
855 '''
856}};
857
858def format Thumb16Misc() {{
859 decode_block = '''
860 {
861 switch (bits(machInst, 11, 8)) {
862 case 0x0:
863 if (bits(machInst, 7)) {
864 return new SubImm(machInst, INTREG_SP, INTREG_SP,
865 bits(machInst, 6, 0) << 2, true);
866 } else {
867 return new AddImm(machInst, INTREG_SP, INTREG_SP,
868 bits(machInst, 6, 0) << 2, true);
869 }
870 case 0x1:
871 return new Cbz(machInst,
872 (bits(machInst, 9) << 6) |
873 (bits(machInst, 7, 3) << 1),
874 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
875 case 0x2:
876 switch (bits(machInst, 7, 6)) {
877 case 0x0:
878 return new WarnUnimplemented("sxth", machInst);
879 case 0x1:
880 return new WarnUnimplemented("sxtb", machInst);
881 case 0x2:
882 return new WarnUnimplemented("uxth", machInst);
883 case 0x3:
884 return new WarnUnimplemented("uxtb", machInst);
885 }
886 case 0x3:
887 return new Cbz(machInst,
888 (bits(machInst, 9) << 6) |
889 (bits(machInst, 7, 3) << 1),
890 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
891 case 0x4:
892 case 0x5:
893 {
894 const uint32_t m = bits(machInst, 8);
895 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
896 return new LdmStm(machInst, INTREG_SP, false, false, false,
897 true, false, regList);
898 }
899 case 0x6:
900 {
901 const uint32_t opBits = bits(machInst, 7, 5);
902 if (opBits == 2) {
903 return new WarnUnimplemented("setend", machInst);
904 } else if (opBits == 3) {
905 return new WarnUnimplemented("cps", machInst);
906 }
907 }
908 case 0x9:
909 return new Cbnz(machInst,
910 (bits(machInst, 9) << 6) |
911 (bits(machInst, 7, 3) << 1),
912 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
913 case 0xa:
914 {
915 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
916 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
917 switch (bits(machInst, 7, 6)) {
918 case 0x0:
919 return new Rev(machInst, rd, rm);
920 case 0x1:
921 return new Rev16(machInst, rd, rm);
922 case 0x3:
923 return new Revsh(machInst, rd, rm);
924 default:
925 break;
926 }
927 }
928 break;
929 case 0xb:
930 return new Cbnz(machInst,
931 (bits(machInst, 9) << 6) |
932 (bits(machInst, 7, 3) << 1),
933 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
934 case 0xc:
935 case 0xd:
936 {
937 const uint32_t p = bits(machInst, 8);
938 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
939 return new LdmStm(machInst, INTREG_SP, true, true, false,
940 true, true, regList);
941 }
942 case 0xe:
943 return new WarnUnimplemented("bkpt", machInst);
944 case 0xf:
945 if (bits(machInst, 3, 0) != 0)
946 return new WarnUnimplemented("it", machInst);
947 switch (bits(machInst, 7, 4)) {
948 case 0x0:
949 return new WarnUnimplemented("nop", machInst);
950 case 0x1:
951 return new WarnUnimplemented("yield", machInst);
952 case 0x2:
953 return new WarnUnimplemented("wfe", machInst);
954 case 0x3:
955 return new WarnUnimplemented("wfi", machInst);
956 case 0x4:
957 return new WarnUnimplemented("sev", machInst);
958 default:
959 return new WarnUnimplemented("unallocated_hint", machInst);
960 }
961 default:
962 break;
963 }
964 return new Unknown(machInst);
965 }
966 '''
967}};
968
969def format Thumb32DataProcModImm() {{
970
971 def decInst(mnem, dest="rd", op1="rn"):
972 return '''
973 if (s) {
974 return new %(mnem)sImmCc(machInst, %(dest)s,
975 %(op1)s, imm, rotC);
976 } else {
977 return new %(mnem)sImm(machInst, %(dest)s,
978 %(op1)s, imm, rotC);
979 }
980 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
981
982 decode_block = '''
983 {
984 const uint32_t op = bits(machInst, 24, 21);
985 const bool s = (bits(machInst, 20) == 1);
986 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
987 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
988 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
989 bits(machInst, 14, 12);
990 const bool rotC = ctrlImm > 3;
991 const uint32_t dataImm = bits(machInst, 7, 0);
992 const uint32_t imm = modified_imm(ctrlImm, dataImm);
993 switch (op) {
994 case 0x0:
995 if (rd == INTREG_PC) {
996 %(tst)s
997 } else {
998 %(and)s
999 }
1000 case 0x1:
1001 %(bic)s
1002 case 0x2:
1003 if (rn == INTREG_PC) {
1004 %(mov)s
1005 } else {
1006 %(orr)s
1007 }
1008 case 0x3:
1009 if (rn == INTREG_PC) {
1010 %(mvn)s
1011 } else {
1012 %(orn)s
1013 }
1014 case 0x4:
1015 if (rd == INTREG_PC) {
1016 %(teq)s
1017 } else {
1018 %(eor)s
1019 }
1020 case 0x8:
1021 if (rd == INTREG_PC) {
1022 %(cmn)s
1023 } else {
1024 %(add)s
1025 }
1026 case 0xa:
1027 %(adc)s
1028 case 0xb:
1029 %(sbc)s
1030 case 0xd:
1031 if (rd == INTREG_PC) {
1032 %(cmp)s
1033 } else {
1034 %(sub)s
1035 }
1036 case 0xe:
1037 %(rsb)s
1038 default:
1039 return new Unknown(machInst);
1040 }
1041 }
1042 ''' % {
1043 "tst" : decInst("Tst", "INTREG_ZERO"),
1044 "and" : decInst("And"),
1045 "bic" : decInst("Bic"),
1046 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1047 "orr" : decInst("Orr"),
1048 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1049 "orn" : decInst("Orn"),
1050 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1051 "eor" : decInst("Eor"),
1052 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1053 "add" : decInst("Add"),
1054 "adc" : decInst("Adc"),
1055 "sbc" : decInst("Sbc"),
1056 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1057 "sub" : decInst("Sub"),
1058 "rsb" : decInst("Rsb")
1059 }
1060}};
1061
1062def format Thumb32DataProcPlainBin() {{
1063 decode_block = '''
1064 {
1065 const uint32_t op = bits(machInst, 24, 20);
1066 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1067 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1068 switch (op) {
1069 case 0x0:
1070 {
1071 const uint32_t imm = bits(machInst, 7, 0) |
1072 (bits(machInst, 14, 12) << 8) |
1073 (bits(machInst, 26) << 11);
1074 if (rn == 0xf) {
1075 return new AdrImm(machInst, rd, (IntRegIndex)1,
1076 imm, false);
1077 } else {
1078 return new AddImm(machInst, rd, rn, imm, true);
1079 }
1080 }
1081 case 0x4:
1082 {
1083 const uint32_t imm = bits(machInst, 7, 0) |
1084 (bits(machInst, 14, 12) << 8) |
1085 (bits(machInst, 26) << 11) |
1086 (bits(machInst, 19, 16) << 12);
1087 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1088 }
1089 case 0xa:
1090 {
1091 const uint32_t imm = bits(machInst, 7, 0) |
1092 (bits(machInst, 14, 12) << 8) |
1093 (bits(machInst, 26) << 11);
1094 if (rn == 0xf) {
1095 return new AdrImm(machInst, rd, (IntRegIndex)0,
1096 imm, false);
1097 } else {
1098 return new SubImm(machInst, rd, rn, imm, true);
1099 }
1100 }
1101 case 0xc:
1102 {
1103 const uint32_t imm = bits(machInst, 7, 0) |
1104 (bits(machInst, 14, 12) << 8) |
1105 (bits(machInst, 26) << 11) |
1106 (bits(machInst, 19, 16) << 12);
1107 return new MovtImm(machInst, rd, rd, imm, true);
1108 }
1109 case 0x12:
1110 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
213 } else if (op2 == 0x3) {
214 if (a == 0xf) {
215 return new WarnUnimplemented("uxtb", machInst);
216 } else {
217 return new WarnUnimplemented("uxtab", machInst);
218 }
219 }
220 break;
221 case 0x7:
222 if (op2 == 0x1) {
223 return new WarnUnimplemented("rbit", machInst);
224 } else if (op2 == 0x3) {
225 if (a == 0xf) {
226 return new WarnUnimplemented("uxth", machInst);
227 } else {
228 return new WarnUnimplemented("uxtah", machInst);
229 }
230 } else if (op2 == 0x5) {
231 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
232 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
233 return new Revsh(machInst, rd, rm);
234 }
235 break;
236 }
237 return new Unknown(machInst);
238 }
239 '''
240}};
241
242def format ArmParallelAddSubtract() {{
243 decode_block='''
244 {
245 const uint32_t op1 = bits(machInst, 21, 20);
246 const uint32_t op2 = bits(machInst, 7, 5);
247 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
248 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
249 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
250 if (bits(machInst, 22) == 0) {
251 switch (op1) {
252 case 0x1:
253 switch (op2) {
254 case 0x0:
255 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
256 case 0x1:
257 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
258 case 0x2:
259 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
260 case 0x3:
261 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
262 case 0x4:
263 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
264 case 0x7:
265 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
266 }
267 break;
268 case 0x2:
269 switch (op2) {
270 case 0x0:
271 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
272 case 0x1:
273 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
274 case 0x2:
275 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
276 case 0x3:
277 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
278 case 0x4:
279 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
280 case 0x7:
281 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
282 }
283 break;
284 case 0x3:
285 switch (op2) {
286 case 0x0:
287 return new WarnUnimplemented("shadd16", machInst);
288 case 0x1:
289 return new WarnUnimplemented("shasx", machInst);
290 case 0x2:
291 return new WarnUnimplemented("shsax", machInst);
292 case 0x3:
293 return new WarnUnimplemented("shsub16", machInst);
294 case 0x4:
295 return new WarnUnimplemented("shadd8", machInst);
296 case 0x7:
297 return new WarnUnimplemented("shsub8", machInst);
298 }
299 break;
300 }
301 } else {
302 switch (op1) {
303 case 0x1:
304 switch (op2) {
305 case 0x0:
306 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
307 case 0x1:
308 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
309 case 0x2:
310 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
311 case 0x3:
312 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
313 case 0x4:
314 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
315 case 0x7:
316 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
317 }
318 break;
319 case 0x2:
320 switch (op2) {
321 case 0x0:
322 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
323 case 0x1:
324 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
325 case 0x2:
326 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
327 case 0x3:
328 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
329 case 0x4:
330 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
331 case 0x7:
332 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
333 }
334 break;
335 case 0x3:
336 switch (op2) {
337 case 0x0:
338 return new WarnUnimplemented("uhadd16", machInst);
339 case 0x1:
340 return new WarnUnimplemented("uhasx", machInst);
341 case 0x2:
342 return new WarnUnimplemented("uhsax", machInst);
343 case 0x3:
344 return new WarnUnimplemented("uhsub16", machInst);
345 case 0x4:
346 return new WarnUnimplemented("uhadd8", machInst);
347 case 0x7:
348 return new WarnUnimplemented("uhsub8", machInst);
349 }
350 break;
351 }
352 }
353 return new Unknown(machInst);
354 }
355 '''
356}};
357
358def format ArmDataProcImm() {{
359 pclr = '''
360 return new %(className)ssImmPclr(machInst, %(dest)s,
361 %(op1)s, imm, false);
362 '''
363 adr = '''
364 return new AdrImm(machInst, %(dest)s, %(add)s,
365 imm, false);
366 '''
367 instDecode = '''
368 case %(opcode)#x:
369 if (setCc) {
370 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
371 %(pclr)s
372 } else {
373 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
374 imm, rotC);
375 }
376 } else {
377 if (%(adrInst)s && %(op1)s == INTREG_PC) {
378 %(adr)s
379 } else {
380 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
381 imm, rotC);
382 }
383 }
384 break;
385 '''
386
387 def instCode(opcode, mnem, useDest = True, useOp1 = True):
388 global instDecode, pclr, adr
389 if useDest:
390 dest = "rd"
391 else:
392 dest = "INTREG_ZERO"
393 if useOp1:
394 op1 = "rn"
395 else:
396 op1 = "INTREG_ZERO"
397 substDict = { "className": mnem.capitalize(),
398 "opcode": opcode,
399 "dest": dest,
400 "op1": op1,
401 "adr": "",
402 "adrInst": "false" }
403 if useDest:
404 substDict["pclrInst"] = "true"
405 substDict["pclr"] = pclr % substDict
406 else:
407 substDict["pclrInst"] = "false"
408 substDict["pclr"] = ""
409 return instDecode % substDict
410
411 def adrCode(opcode, mnem, add="1"):
412 global instDecode, pclr, adr
413 substDict = { "className": mnem.capitalize(),
414 "opcode": opcode,
415 "dest": "rd",
416 "op1": "rn",
417 "add": add,
418 "pclrInst": "true",
419 "adrInst": "true" }
420 substDict["pclr"] = pclr % substDict
421 substDict["adr"] = adr % substDict
422 return instDecode % substDict
423
424 decode_block = '''
425 {
426 const bool setCc = (bits(machInst, 20) == 1);
427 const uint32_t unrotated = bits(machInst, 7, 0);
428 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
429 const bool rotC = (rotation != 0);
430 const uint32_t imm = rotate_imm(unrotated, rotation);
431 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
432 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
433 switch (OPCODE) {
434 '''
435 decode_block += instCode(0x0, "and")
436 decode_block += instCode(0x1, "eor")
437 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
438 decode_block += instCode(0x3, "rsb")
439 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
440 decode_block += instCode(0x5, "adc")
441 decode_block += instCode(0x6, "sbc")
442 decode_block += instCode(0x7, "rsc")
443 decode_block += instCode(0x8, "tst", useDest = False)
444 decode_block += instCode(0x9, "teq", useDest = False)
445 decode_block += instCode(0xa, "cmp", useDest = False)
446 decode_block += instCode(0xb, "cmn", useDest = False)
447 decode_block += instCode(0xc, "orr")
448 decode_block += instCode(0xd, "mov", useOp1 = False)
449 decode_block += instCode(0xe, "bic")
450 decode_block += instCode(0xf, "mvn", useOp1 = False)
451 decode_block += '''
452 default:
453 return new Unknown(machInst);
454 }
455 }
456 '''
457}};
458
459def format ArmSatAddSub() {{
460 decode_block = '''
461 {
462 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
463 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
464 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
465 switch (OPCODE) {
466 case 0x8:
467 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
468 case 0x9:
469 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
470 case 0xa:
471 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
472 case 0xb:
473 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
474 default:
475 return new Unknown(machInst);
476 }
477 }
478 '''
479}};
480
481def format Thumb32DataProcReg() {{
482 decode_block = '''
483 {
484 const uint32_t op1 = bits(machInst, 23, 20);
485 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
486 const uint32_t op2 = bits(machInst, 7, 4);
487 if (bits(op1, 3) != 1) {
488 if (op2 == 0) {
489 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
490 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
491 switch (bits(op1, 2, 0)) {
492 case 0x0:
493 return new MovRegReg(machInst, rd,
494 INTREG_ZERO, rn, rm, LSL);
495 case 0x1:
496 return new MovRegRegCc(machInst, rd,
497 INTREG_ZERO, rn, rm, LSL);
498 case 0x2:
499 return new MovRegReg(machInst, rd,
500 INTREG_ZERO, rn, rm, LSR);
501 case 0x3:
502 return new MovRegRegCc(machInst, rd,
503 INTREG_ZERO, rn, rm, LSR);
504 case 0x4:
505 return new MovRegReg(machInst, rd,
506 INTREG_ZERO, rn, rm, ASR);
507 case 0x5:
508 return new MovRegRegCc(machInst, rd,
509 INTREG_ZERO, rn, rm, ASR);
510 case 0x6:
511 return new MovRegReg(machInst, rd,
512 INTREG_ZERO, rn, rm, ROR);
513 case 0x7:
514 return new MovRegRegCc(machInst, rd,
515 INTREG_ZERO, rn, rm, ROR);
516 }
517 }
518 switch (bits(op1, 2, 0)) {
519 case 0x0:
520 if (rn == 0xf) {
521 return new WarnUnimplemented("sxth", machInst);
522 } else {
523 return new WarnUnimplemented("sxtah", machInst);
524 }
525 case 0x1:
526 if (rn == 0xf) {
527 return new WarnUnimplemented("uxth", machInst);
528 } else {
529 return new WarnUnimplemented("uxtah", machInst);
530 }
531 case 0x2:
532 if (rn == 0xf) {
533 return new WarnUnimplemented("sxtb16", machInst);
534 } else {
535 return new WarnUnimplemented("sxtab16", machInst);
536 }
537 case 0x3:
538 if (rn == 0xf) {
539 return new WarnUnimplemented("uxtb16", machInst);
540 } else {
541 return new WarnUnimplemented("uxtab16", machInst);
542 }
543 case 0x4:
544 if (rn == 0xf) {
545 return new WarnUnimplemented("sxtb", machInst);
546 } else {
547 return new WarnUnimplemented("sxtab", machInst);
548 }
549 case 0x5:
550 if (rn == 0xf) {
551 return new WarnUnimplemented("uxtb", machInst);
552 } else {
553 return new WarnUnimplemented("uxtab", machInst);
554 }
555 default:
556 return new Unknown(machInst);
557 }
558 } else {
559 if (bits(op2, 3) == 0) {
560 const IntRegIndex rd =
561 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
562 const IntRegIndex rm =
563 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
564 if (bits(op2, 2) == 0x0) {
565 const uint32_t op1 = bits(machInst, 22, 20);
566 const uint32_t op2 = bits(machInst, 5, 4);
567 switch (op2) {
568 case 0x0:
569 switch (op1) {
570 case 0x1:
571 return new Sadd16RegCc(machInst, rd,
572 rn, rm, 0, LSL);
573 case 0x2:
574 return new SasxRegCc(machInst, rd,
575 rn, rm, 0, LSL);
576 case 0x6:
577 return new SsaxRegCc(machInst, rd,
578 rn, rm, 0, LSL);
579 case 0x5:
580 return new Ssub16RegCc(machInst, rd,
581 rn, rm, 0, LSL);
582 case 0x0:
583 return new Sadd8RegCc(machInst, rd,
584 rn, rm, 0, LSL);
585 case 0x4:
586 return new Ssub8RegCc(machInst, rd,
587 rn, rm, 0, LSL);
588 }
589 break;
590 case 0x1:
591 switch (op1) {
592 case 0x1:
593 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
594 case 0x2:
595 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
596 case 0x6:
597 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
598 case 0x5:
599 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
600 case 0x0:
601 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
602 case 0x4:
603 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
604 }
605 break;
606 case 0x2:
607 switch (op1) {
608 case 0x1:
609 return new WarnUnimplemented("shadd16", machInst);
610 case 0x2:
611 return new WarnUnimplemented("shasx", machInst);
612 case 0x6:
613 return new WarnUnimplemented("shsax", machInst);
614 case 0x5:
615 return new WarnUnimplemented("shsub16", machInst);
616 case 0x0:
617 return new WarnUnimplemented("shadd8", machInst);
618 case 0x4:
619 return new WarnUnimplemented("shsub8", machInst);
620 }
621 break;
622 }
623 } else {
624 const uint32_t op1 = bits(machInst, 22, 20);
625 const uint32_t op2 = bits(machInst, 5, 4);
626 switch (op2) {
627 case 0x0:
628 switch (op1) {
629 case 0x1:
630 return new Uadd16RegCc(machInst, rd,
631 rn, rm, 0, LSL);
632 case 0x2:
633 return new UasxRegCc(machInst, rd,
634 rn, rm, 0, LSL);
635 case 0x6:
636 return new UsaxRegCc(machInst, rd,
637 rn, rm, 0, LSL);
638 case 0x5:
639 return new Usub16RegCc(machInst, rd,
640 rn, rm, 0, LSL);
641 case 0x0:
642 return new Uadd8RegCc(machInst, rd,
643 rn, rm, 0, LSL);
644 case 0x4:
645 return new Usub8RegCc(machInst, rd,
646 rn, rm, 0, LSL);
647 }
648 break;
649 case 0x1:
650 switch (op1) {
651 case 0x1:
652 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
653 case 0x2:
654 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
655 case 0x6:
656 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
657 case 0x5:
658 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
659 case 0x0:
660 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
661 case 0x4:
662 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
663 }
664 break;
665 case 0x2:
666 switch (op1) {
667 case 0x1:
668 return new WarnUnimplemented("uhadd16", machInst);
669 case 0x2:
670 return new WarnUnimplemented("uhasx", machInst);
671 case 0x6:
672 return new WarnUnimplemented("uhsax", machInst);
673 case 0x5:
674 return new WarnUnimplemented("uhsub16", machInst);
675 case 0x0:
676 return new WarnUnimplemented("uhadd8", machInst);
677 case 0x4:
678 return new WarnUnimplemented("uhsub8", machInst);
679 }
680 break;
681 }
682 }
683 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
684 const uint32_t op1 = bits(machInst, 21, 20);
685 const uint32_t op2 = bits(machInst, 5, 4);
686 switch (op1) {
687 case 0x0:
688 {
689 IntRegIndex rd =
690 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
691 IntRegIndex rm =
692 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
693 switch (op2) {
694 case 0x0:
695 return new QaddRegCc(machInst, rd,
696 rm, rn, 0, LSL);
697 case 0x1:
698 return new QdaddRegCc(machInst, rd,
699 rm, rn, 0, LSL);
700 case 0x2:
701 return new QsubRegCc(machInst, rd,
702 rm, rn, 0, LSL);
703 case 0x3:
704 return new QdsubRegCc(machInst, rd,
705 rm, rn, 0, LSL);
706 }
707 }
708 break;
709 case 0x1:
710 {
711 IntRegIndex rd =
712 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
713 IntRegIndex rm = rn;
714 switch (op2) {
715 case 0x0:
716 return new Rev(machInst, rd, rm);
717 case 0x1:
718 return new Rev16(machInst, rd, rm);
719 case 0x2:
720 return new WarnUnimplemented("rbit", machInst);
721 case 0x3:
722 return new Revsh(machInst, rd, rm);
723 }
724 }
725 break;
726 case 0x2:
727 if (op2 == 0) {
728 return new WarnUnimplemented("sel", machInst);
729 }
730 break;
731 case 0x3:
732 if (op2 == 0) {
733 return new WarnUnimplemented("clz", machInst);
734 }
735 }
736 }
737 return new Unknown(machInst);
738 }
739 }
740 '''
741}};
742
743def format Thumb16ShiftAddSubMoveCmp() {{
744 decode_block = '''
745 {
746 const uint32_t imm5 = bits(machInst, 10, 6);
747 const uint32_t imm3 = bits(machInst, 8, 6);
748 const uint32_t imm8 = bits(machInst, 7, 0);
749 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
750 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
751 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
752 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
753 switch (bits(machInst, 13, 11)) {
754 case 0x0: // lsl
755 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
756 case 0x1: // lsr
757 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
758 case 0x2: // asr
759 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
760 case 0x3:
761 switch (bits(machInst, 10, 9)) {
762 case 0x0:
763 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
764 case 0x1:
765 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
766 case 0x2:
767 return new AddImmCc(machInst, rd, rn, imm3, true);
768 case 0x3:
769 return new SubImmCc(machInst, rd, rn, imm3, true);
770 }
771 case 0x4:
772 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
773 case 0x5:
774 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
775 case 0x6:
776 return new AddImmCc(machInst, rd8, rd8, imm8, true);
777 case 0x7:
778 return new SubImmCc(machInst, rd8, rd8, imm8, true);
779 }
780 }
781 '''
782}};
783
784def format Thumb16DataProcessing() {{
785 decode_block = '''
786 {
787 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
788 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
789 switch (bits(machInst, 9, 6)) {
790 case 0x0:
791 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
792 case 0x1:
793 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
794 case 0x2: //lsl
795 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
796 case 0x3: //lsr
797 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
798 case 0x4: //asr
799 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
800 case 0x5:
801 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
802 case 0x6:
803 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
804 case 0x7: // ror
805 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
806 case 0x8:
807 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
808 case 0x9:
809 return new RsbImmCc(machInst, rdn, rm, 0, true);
810 case 0xa:
811 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
812 case 0xb:
813 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
814 case 0xc:
815 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
816 case 0xd:
817 return new MulCc(machInst, rdn, rm, rdn);
818 case 0xe:
819 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
820 case 0xf:
821 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
822 }
823 }
824 '''
825}};
826
827def format Thumb16SpecDataAndBx() {{
828 decode_block = '''
829 {
830 const IntRegIndex rdn =
831 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
832 (bits(machInst, 7) << 3));
833 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
834 switch (bits(machInst, 9, 8)) {
835 case 0x0:
836 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
837 case 0x1:
838 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
839 case 0x2:
840 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
841 case 0x3:
842 if (bits(machInst, 7) == 0) {
843 return new BxReg(machInst,
844 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
845 COND_UC);
846 } else {
847 return new BlxReg(machInst,
848 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
849 COND_UC);
850 }
851 }
852 }
853 '''
854}};
855
856def format Thumb16Adr() {{
857 decode_block = '''
858 {
859 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
860 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
861 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
862 }
863 '''
864}};
865
866def format Thumb16AddSp() {{
867 decode_block = '''
868 {
869 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
870 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
871 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
872 }
873 '''
874}};
875
876def format Thumb16Misc() {{
877 decode_block = '''
878 {
879 switch (bits(machInst, 11, 8)) {
880 case 0x0:
881 if (bits(machInst, 7)) {
882 return new SubImm(machInst, INTREG_SP, INTREG_SP,
883 bits(machInst, 6, 0) << 2, true);
884 } else {
885 return new AddImm(machInst, INTREG_SP, INTREG_SP,
886 bits(machInst, 6, 0) << 2, true);
887 }
888 case 0x1:
889 return new Cbz(machInst,
890 (bits(machInst, 9) << 6) |
891 (bits(machInst, 7, 3) << 1),
892 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
893 case 0x2:
894 switch (bits(machInst, 7, 6)) {
895 case 0x0:
896 return new WarnUnimplemented("sxth", machInst);
897 case 0x1:
898 return new WarnUnimplemented("sxtb", machInst);
899 case 0x2:
900 return new WarnUnimplemented("uxth", machInst);
901 case 0x3:
902 return new WarnUnimplemented("uxtb", machInst);
903 }
904 case 0x3:
905 return new Cbz(machInst,
906 (bits(machInst, 9) << 6) |
907 (bits(machInst, 7, 3) << 1),
908 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
909 case 0x4:
910 case 0x5:
911 {
912 const uint32_t m = bits(machInst, 8);
913 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
914 return new LdmStm(machInst, INTREG_SP, false, false, false,
915 true, false, regList);
916 }
917 case 0x6:
918 {
919 const uint32_t opBits = bits(machInst, 7, 5);
920 if (opBits == 2) {
921 return new WarnUnimplemented("setend", machInst);
922 } else if (opBits == 3) {
923 return new WarnUnimplemented("cps", machInst);
924 }
925 }
926 case 0x9:
927 return new Cbnz(machInst,
928 (bits(machInst, 9) << 6) |
929 (bits(machInst, 7, 3) << 1),
930 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
931 case 0xa:
932 {
933 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
934 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
935 switch (bits(machInst, 7, 6)) {
936 case 0x0:
937 return new Rev(machInst, rd, rm);
938 case 0x1:
939 return new Rev16(machInst, rd, rm);
940 case 0x3:
941 return new Revsh(machInst, rd, rm);
942 default:
943 break;
944 }
945 }
946 break;
947 case 0xb:
948 return new Cbnz(machInst,
949 (bits(machInst, 9) << 6) |
950 (bits(machInst, 7, 3) << 1),
951 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
952 case 0xc:
953 case 0xd:
954 {
955 const uint32_t p = bits(machInst, 8);
956 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
957 return new LdmStm(machInst, INTREG_SP, true, true, false,
958 true, true, regList);
959 }
960 case 0xe:
961 return new WarnUnimplemented("bkpt", machInst);
962 case 0xf:
963 if (bits(machInst, 3, 0) != 0)
964 return new WarnUnimplemented("it", machInst);
965 switch (bits(machInst, 7, 4)) {
966 case 0x0:
967 return new WarnUnimplemented("nop", machInst);
968 case 0x1:
969 return new WarnUnimplemented("yield", machInst);
970 case 0x2:
971 return new WarnUnimplemented("wfe", machInst);
972 case 0x3:
973 return new WarnUnimplemented("wfi", machInst);
974 case 0x4:
975 return new WarnUnimplemented("sev", machInst);
976 default:
977 return new WarnUnimplemented("unallocated_hint", machInst);
978 }
979 default:
980 break;
981 }
982 return new Unknown(machInst);
983 }
984 '''
985}};
986
987def format Thumb32DataProcModImm() {{
988
989 def decInst(mnem, dest="rd", op1="rn"):
990 return '''
991 if (s) {
992 return new %(mnem)sImmCc(machInst, %(dest)s,
993 %(op1)s, imm, rotC);
994 } else {
995 return new %(mnem)sImm(machInst, %(dest)s,
996 %(op1)s, imm, rotC);
997 }
998 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
999
1000 decode_block = '''
1001 {
1002 const uint32_t op = bits(machInst, 24, 21);
1003 const bool s = (bits(machInst, 20) == 1);
1004 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1005 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1006 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1007 bits(machInst, 14, 12);
1008 const bool rotC = ctrlImm > 3;
1009 const uint32_t dataImm = bits(machInst, 7, 0);
1010 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1011 switch (op) {
1012 case 0x0:
1013 if (rd == INTREG_PC) {
1014 %(tst)s
1015 } else {
1016 %(and)s
1017 }
1018 case 0x1:
1019 %(bic)s
1020 case 0x2:
1021 if (rn == INTREG_PC) {
1022 %(mov)s
1023 } else {
1024 %(orr)s
1025 }
1026 case 0x3:
1027 if (rn == INTREG_PC) {
1028 %(mvn)s
1029 } else {
1030 %(orn)s
1031 }
1032 case 0x4:
1033 if (rd == INTREG_PC) {
1034 %(teq)s
1035 } else {
1036 %(eor)s
1037 }
1038 case 0x8:
1039 if (rd == INTREG_PC) {
1040 %(cmn)s
1041 } else {
1042 %(add)s
1043 }
1044 case 0xa:
1045 %(adc)s
1046 case 0xb:
1047 %(sbc)s
1048 case 0xd:
1049 if (rd == INTREG_PC) {
1050 %(cmp)s
1051 } else {
1052 %(sub)s
1053 }
1054 case 0xe:
1055 %(rsb)s
1056 default:
1057 return new Unknown(machInst);
1058 }
1059 }
1060 ''' % {
1061 "tst" : decInst("Tst", "INTREG_ZERO"),
1062 "and" : decInst("And"),
1063 "bic" : decInst("Bic"),
1064 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1065 "orr" : decInst("Orr"),
1066 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1067 "orn" : decInst("Orn"),
1068 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1069 "eor" : decInst("Eor"),
1070 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1071 "add" : decInst("Add"),
1072 "adc" : decInst("Adc"),
1073 "sbc" : decInst("Sbc"),
1074 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1075 "sub" : decInst("Sub"),
1076 "rsb" : decInst("Rsb")
1077 }
1078}};
1079
1080def format Thumb32DataProcPlainBin() {{
1081 decode_block = '''
1082 {
1083 const uint32_t op = bits(machInst, 24, 20);
1084 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1085 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1086 switch (op) {
1087 case 0x0:
1088 {
1089 const uint32_t imm = bits(machInst, 7, 0) |
1090 (bits(machInst, 14, 12) << 8) |
1091 (bits(machInst, 26) << 11);
1092 if (rn == 0xf) {
1093 return new AdrImm(machInst, rd, (IntRegIndex)1,
1094 imm, false);
1095 } else {
1096 return new AddImm(machInst, rd, rn, imm, true);
1097 }
1098 }
1099 case 0x4:
1100 {
1101 const uint32_t imm = bits(machInst, 7, 0) |
1102 (bits(machInst, 14, 12) << 8) |
1103 (bits(machInst, 26) << 11) |
1104 (bits(machInst, 19, 16) << 12);
1105 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1106 }
1107 case 0xa:
1108 {
1109 const uint32_t imm = bits(machInst, 7, 0) |
1110 (bits(machInst, 14, 12) << 8) |
1111 (bits(machInst, 26) << 11);
1112 if (rn == 0xf) {
1113 return new AdrImm(machInst, rd, (IntRegIndex)0,
1114 imm, false);
1115 } else {
1116 return new SubImm(machInst, rd, rn, imm, true);
1117 }
1118 }
1119 case 0xc:
1120 {
1121 const uint32_t imm = bits(machInst, 7, 0) |
1122 (bits(machInst, 14, 12) << 8) |
1123 (bits(machInst, 26) << 11) |
1124 (bits(machInst, 19, 16) << 12);
1125 return new MovtImm(machInst, rd, rd, imm, true);
1126 }
1127 case 0x12:
1128 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1111 return new WarnUnimplemented("ssat16", machInst);
1129 const uint32_t satImm = bits(machInst, 4, 0);
1130 return new Ssat16(machInst, rd, satImm + 1, rn);
1112 }
1113 // Fall through on purpose...
1114 case 0x10:
1131 }
1132 // Fall through on purpose...
1133 case 0x10:
1115 return new WarnUnimplemented("ssat", machInst);
1134 {
1135 const uint32_t satImm = bits(machInst, 4, 0);
1136 const uint32_t imm = bits(machInst, 7, 6) |
1137 (bits(machInst, 14, 12) << 2);
1138 const ArmShiftType type =
1139 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1140 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1141 }
1116 case 0x14:
1117 return new WarnUnimplemented("sbfx", machInst);
1118 case 0x16:
1119 if (rn == 0xf) {
1120 return new WarnUnimplemented("bfc", machInst);
1121 } else {
1122 return new WarnUnimplemented("bfi", machInst);
1123 }
1124 case 0x1a:
1125 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1142 case 0x14:
1143 return new WarnUnimplemented("sbfx", machInst);
1144 case 0x16:
1145 if (rn == 0xf) {
1146 return new WarnUnimplemented("bfc", machInst);
1147 } else {
1148 return new WarnUnimplemented("bfi", machInst);
1149 }
1150 case 0x1a:
1151 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1126 return new WarnUnimplemented("usat16", machInst);
1152 const uint32_t satImm = bits(machInst, 4, 0);
1153 return new Usat16(machInst, rd, satImm, rn);
1127 }
1128 // Fall through on purpose...
1129 case 0x18:
1154 }
1155 // Fall through on purpose...
1156 case 0x18:
1130 return new WarnUnimplemented("usat", machInst);
1157 {
1158 const uint32_t satImm = bits(machInst, 4, 0);
1159 const uint32_t imm = bits(machInst, 7, 6) |
1160 (bits(machInst, 14, 12) << 2);
1161 const ArmShiftType type =
1162 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1163 return new Usat(machInst, rd, satImm, rn, imm, type);
1164 }
1131 case 0x1c:
1132 return new WarnUnimplemented("ubfx", machInst);
1133 default:
1134 return new Unknown(machInst);
1135 }
1136 }
1137 '''
1138}};
1139
1140def format Thumb32DataProcShiftReg() {{
1141
1142 def decInst(mnem, dest="rd", op1="rn"):
1143 return '''
1144 if (s) {
1145 return new %(mnem)sRegCc(machInst, %(dest)s,
1146 %(op1)s, rm, amt, type);
1147 } else {
1148 return new %(mnem)sReg(machInst, %(dest)s,
1149 %(op1)s, rm, amt, type);
1150 }
1151 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1152
1153 decode_block = '''
1154 {
1155 const uint32_t op = bits(machInst, 24, 21);
1156 const bool s = (bits(machInst, 20) == 1);
1157 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1158 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1159 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1160 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1161 bits(machInst, 7, 6);
1162 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1163 switch (op) {
1164 case 0x0:
1165 if (rd == INTREG_PC) {
1166 %(tst)s
1167 } else {
1168 %(and)s
1169 }
1170 case 0x1:
1171 %(bic)s
1172 case 0x2:
1173 if (rn == INTREG_PC) {
1174 %(mov)s
1175 } else {
1176 %(orr)s
1177 }
1178 case 0x3:
1179 if (rn == INTREG_PC) {
1180 %(mvn)s
1181 } else {
1182 %(orn)s
1183 }
1184 case 0x4:
1185 if (rd == INTREG_PC) {
1186 %(teq)s
1187 } else {
1188 %(eor)s
1189 }
1190 case 0x6:
1191 return new WarnUnimplemented("pkh", machInst);
1192 case 0x8:
1193 if (rd == INTREG_PC) {
1194 %(cmn)s
1195 } else {
1196 %(add)s
1197 }
1198 case 0xa:
1199 %(adc)s
1200 case 0xb:
1201 %(sbc)s
1202 case 0xd:
1203 if (rd == INTREG_PC) {
1204 %(cmp)s
1205 } else {
1206 %(sub)s
1207 }
1208 case 0xe:
1209 %(rsb)s
1210 default:
1211 return new Unknown(machInst);
1212 }
1213 }
1214 ''' % {
1215 "tst" : decInst("Tst", "INTREG_ZERO"),
1216 "and" : decInst("And"),
1217 "bic" : decInst("Bic"),
1218 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1219 "orr" : decInst("Orr"),
1220 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1221 "orn" : decInst("Orn"),
1222 "teq" : decInst("Teq", "INTREG_ZERO"),
1223 "eor" : decInst("Eor"),
1224 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1225 "add" : decInst("Add"),
1226 "adc" : decInst("Adc"),
1227 "sbc" : decInst("Sbc"),
1228 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1229 "sub" : decInst("Sub"),
1230 "rsb" : decInst("Rsb")
1231 }
1232}};
1165 case 0x1c:
1166 return new WarnUnimplemented("ubfx", machInst);
1167 default:
1168 return new Unknown(machInst);
1169 }
1170 }
1171 '''
1172}};
1173
1174def format Thumb32DataProcShiftReg() {{
1175
1176 def decInst(mnem, dest="rd", op1="rn"):
1177 return '''
1178 if (s) {
1179 return new %(mnem)sRegCc(machInst, %(dest)s,
1180 %(op1)s, rm, amt, type);
1181 } else {
1182 return new %(mnem)sReg(machInst, %(dest)s,
1183 %(op1)s, rm, amt, type);
1184 }
1185 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1186
1187 decode_block = '''
1188 {
1189 const uint32_t op = bits(machInst, 24, 21);
1190 const bool s = (bits(machInst, 20) == 1);
1191 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1192 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1193 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1194 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1195 bits(machInst, 7, 6);
1196 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1197 switch (op) {
1198 case 0x0:
1199 if (rd == INTREG_PC) {
1200 %(tst)s
1201 } else {
1202 %(and)s
1203 }
1204 case 0x1:
1205 %(bic)s
1206 case 0x2:
1207 if (rn == INTREG_PC) {
1208 %(mov)s
1209 } else {
1210 %(orr)s
1211 }
1212 case 0x3:
1213 if (rn == INTREG_PC) {
1214 %(mvn)s
1215 } else {
1216 %(orn)s
1217 }
1218 case 0x4:
1219 if (rd == INTREG_PC) {
1220 %(teq)s
1221 } else {
1222 %(eor)s
1223 }
1224 case 0x6:
1225 return new WarnUnimplemented("pkh", machInst);
1226 case 0x8:
1227 if (rd == INTREG_PC) {
1228 %(cmn)s
1229 } else {
1230 %(add)s
1231 }
1232 case 0xa:
1233 %(adc)s
1234 case 0xb:
1235 %(sbc)s
1236 case 0xd:
1237 if (rd == INTREG_PC) {
1238 %(cmp)s
1239 } else {
1240 %(sub)s
1241 }
1242 case 0xe:
1243 %(rsb)s
1244 default:
1245 return new Unknown(machInst);
1246 }
1247 }
1248 ''' % {
1249 "tst" : decInst("Tst", "INTREG_ZERO"),
1250 "and" : decInst("And"),
1251 "bic" : decInst("Bic"),
1252 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1253 "orr" : decInst("Orr"),
1254 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1255 "orn" : decInst("Orn"),
1256 "teq" : decInst("Teq", "INTREG_ZERO"),
1257 "eor" : decInst("Eor"),
1258 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1259 "add" : decInst("Add"),
1260 "adc" : decInst("Adc"),
1261 "sbc" : decInst("Sbc"),
1262 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1263 "sub" : decInst("Sub"),
1264 "rsb" : decInst("Rsb")
1265 }
1266}};