data.isa (8909:7fa0a081f12f) data.isa (12258:08990d24fe41)
1// Copyright (c) 2010 ARM Limited
1// Copyright (c) 2010,2017 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 ArmMiscMedia() {{
39 decode_block = '''
40 {
41 const uint32_t op1 = bits(machInst, 22, 20);
42 const uint32_t op2 = bits(machInst, 7, 5);
43 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
44 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
45 if (op1 == 0 && op2 == 0) {
46 const IntRegIndex rd =
47 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
48 const IntRegIndex rm =
49 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
50 if (ra == 0xf) {
51 return new Usad8(machInst, rd, rn, rm);
52 } else {
53 return new Usada8(machInst, rd, rn, rm, ra);
54 }
55 } else if (bits(op2, 1, 0) == 0x2) {
56 const uint32_t lsb = bits(machInst, 11, 7);
57 const uint32_t msb = lsb + bits(machInst, 20, 16);
58 if (bits(op1, 2, 1) == 0x3) {
59 return new Ubfx(machInst, ra, rn, lsb, msb);
60 } else if (bits(op1, 2, 1) == 0x1) {
61 return new Sbfx(machInst, ra, rn, lsb, msb);
62 }
63 } else if (bits(op2, 1, 0) == 0x0 && bits(op1, 2, 1) == 0x2) {
64 const uint32_t lsb = bits(machInst, 11, 7);
65 const uint32_t msb = bits(machInst, 20, 16);
66 if (rn == 0xf) {
67 return new Bfc(machInst, ra, ra, lsb, msb);
68 } else {
69 return new Bfi(machInst, ra, rn, lsb, msb);
70 }
71 }
72 return new Unknown(machInst);
73 }
74 '''
75}};
76
77def format ArmDataProcReg() {{
78 pclr = '''
79 return new %(className)ssRegPclr(machInst, %(dest)s,
80 %(op1)s, rm, imm5,
81 type);
82 '''
83 instDecode = '''
84 case %(opcode)#x:
85 if (immShift) {
86 if (setCc) {
87 if (%(dest)s == INTREG_PC) {
88 %(pclr)s
89 } else {
90 return new %(className)sRegCc(machInst, %(dest)s,
91 %(op1)s, rm, imm5, type);
92 }
93 } else {
94 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
95 rm, imm5, type);
96 }
97 } else {
98 if (setCc) {
99 return new %(className)sRegRegCc(machInst, %(dest)s,
100 %(op1)s, rm, rs, type);
101 } else {
102 return new %(className)sRegReg(machInst, %(dest)s,
103 %(op1)s, rm, rs, type);
104 }
105 }
106 break;
107 '''
108
109 def instCode(opcode, mnem, useDest = True, useOp1 = True):
110 global pclr
111 if useDest:
112 dest = "rd"
113 else:
114 dest = "INTREG_ZERO"
115 if useOp1:
116 op1 = "rn"
117 else:
118 op1 = "INTREG_ZERO"
119 global instDecode, pclrCode
120 substDict = { "className": mnem.capitalize(),
121 "opcode": opcode,
122 "dest": dest,
123 "op1": op1 }
124 if useDest:
125 substDict["pclr"] = pclr % substDict
126 else:
127 substDict["pclr"] = ""
128 return instDecode % substDict
129
130 decode_block = '''
131 {
132 const bool immShift = (bits(machInst, 4) == 0);
133 const bool setCc = (bits(machInst, 20) == 1);
134 const uint32_t imm5 = bits(machInst, 11, 7);
135 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
136 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
137 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
138 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
139 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
140 switch (OPCODE) {
141 '''
142 decode_block += instCode(0x0, "and")
143 decode_block += instCode(0x1, "eor")
144 decode_block += instCode(0x2, "sub")
145 decode_block += instCode(0x3, "rsb")
146 decode_block += instCode(0x4, "add")
147 decode_block += instCode(0x5, "adc")
148 decode_block += instCode(0x6, "sbc")
149 decode_block += instCode(0x7, "rsc")
150 decode_block += instCode(0x8, "tst", useDest = False)
151 decode_block += instCode(0x9, "teq", useDest = False)
152 decode_block += instCode(0xa, "cmp", useDest = False)
153 decode_block += instCode(0xb, "cmn", useDest = False)
154 decode_block += instCode(0xc, "orr")
155 decode_block += instCode(0xd, "mov", useOp1 = False)
156 decode_block += instCode(0xe, "bic")
157 decode_block += instCode(0xf, "mvn", useOp1 = False)
158 decode_block += '''
159 default:
160 return new Unknown(machInst);
161 }
162 }
163 '''
164}};
165
166def format ArmPackUnpackSatReverse() {{
167 decode_block = '''
168 {
169 const uint32_t op1 = bits(machInst, 22, 20);
170 const uint32_t a = bits(machInst, 19, 16);
171 const uint32_t op2 = bits(machInst, 7, 5);
172 if (bits(op2, 0) == 0) {
173 const IntRegIndex rn =
174 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
175 const IntRegIndex rd =
176 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
177 const uint32_t satImm = bits(machInst, 20, 16);
178 const uint32_t imm = bits(machInst, 11, 7);
179 const ArmShiftType type =
180 (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
181 if (op1 == 0) {
182 if (type) {
183 return new PkhtbReg(machInst, rd, (IntRegIndex)a,
184 rn, imm, type);
185 } else {
186 return new PkhbtReg(machInst, rd, (IntRegIndex)a,
187 rn, imm, type);
188 }
189 } else if (bits(op1, 2, 1) == 1) {
190 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
191 } else if (bits(op1, 2, 1) == 3) {
192 return new Usat(machInst, rd, satImm, rn, imm, type);
193 }
194 return new Unknown(machInst);
195 }
196 switch (op1) {
197 case 0x0:
198 {
199 const IntRegIndex rn =
200 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
201 const IntRegIndex rd =
202 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
203 const IntRegIndex rm =
204 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
205 if (op2 == 0x3) {
206 const uint32_t rotation =
207 (uint32_t)bits(machInst, 11, 10) << 3;
208 if (a == 0xf) {
209 return new Sxtb16(machInst, rd, rotation, rm);
210 } else {
211 return new Sxtab16(machInst, rd, rn, rm, rotation);
212 }
213 } else if (op2 == 0x5) {
214 return new Sel(machInst, rd, rn, rm);
215 }
216 }
217 break;
218 case 0x2:
219 if (op2 == 0x1) {
220 const IntRegIndex rn =
221 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
222 const IntRegIndex rd =
223 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
224 const uint32_t satImm = bits(machInst, 20, 16);
225 return new Ssat16(machInst, rd, satImm + 1, rn);
226 } else if (op2 == 0x3) {
227 const IntRegIndex rn =
228 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
229 const IntRegIndex rd =
230 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
231 const IntRegIndex rm =
232 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
233 const uint32_t rotation =
234 (uint32_t)bits(machInst, 11, 10) << 3;
235 if (a == 0xf) {
236 return new Sxtb(machInst, rd, rotation, rm);
237 } else {
238 return new Sxtab(machInst, rd, rn, rm, rotation);
239 }
240 }
241 break;
242 case 0x3:
243 if (op2 == 0x1) {
244 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
245 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
246 return new Rev(machInst, rd, rm);
247 } else if (op2 == 0x3) {
248 const IntRegIndex rn =
249 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
250 const IntRegIndex rd =
251 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
252 const IntRegIndex rm =
253 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
254 const uint32_t rotation =
255 (uint32_t)bits(machInst, 11, 10) << 3;
256 if (a == 0xf) {
257 return new Sxth(machInst, rd, rotation, rm);
258 } else {
259 return new Sxtah(machInst, rd, rn, rm, rotation);
260 }
261 } else if (op2 == 0x5) {
262 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
263 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
264 return new Rev16(machInst, rd, rm);
265 }
266 break;
267 case 0x4:
268 if (op2 == 0x3) {
269 const IntRegIndex rn =
270 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
271 const IntRegIndex rd =
272 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
273 const IntRegIndex rm =
274 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
275 const uint32_t rotation =
276 (uint32_t)bits(machInst, 11, 10) << 3;
277 if (a == 0xf) {
278 return new Uxtb16(machInst, rd, rotation, rm);
279 } else {
280 return new Uxtab16(machInst, rd, rn, rm, rotation);
281 }
282 }
283 break;
284 case 0x6:
285 if (op2 == 0x1) {
286 const IntRegIndex rn =
287 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
288 const IntRegIndex rd =
289 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
290 const uint32_t satImm = bits(machInst, 20, 16);
291 return new Usat16(machInst, rd, satImm, rn);
292 } else if (op2 == 0x3) {
293 const IntRegIndex rn =
294 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
295 const IntRegIndex rd =
296 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
297 const IntRegIndex rm =
298 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
299 const uint32_t rotation =
300 (uint32_t)bits(machInst, 11, 10) << 3;
301 if (a == 0xf) {
302 return new Uxtb(machInst, rd, rotation, rm);
303 } else {
304 return new Uxtab(machInst, rd, rn, rm, rotation);
305 }
306 }
307 break;
308 case 0x7:
309 {
310 const IntRegIndex rn =
311 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
312 const IntRegIndex rd =
313 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
314 const IntRegIndex rm =
315 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
316 if (op2 == 0x1) {
317 return new Rbit(machInst, rd, rm);
318 } else if (op2 == 0x3) {
319 const uint32_t rotation =
320 (uint32_t)bits(machInst, 11, 10) << 3;
321 if (a == 0xf) {
322 return new Uxth(machInst, rd, rotation, rm);
323 } else {
324 return new Uxtah(machInst, rd, rn, rm, rotation);
325 }
326 } else if (op2 == 0x5) {
327 return new Revsh(machInst, rd, rm);
328 }
329 }
330 break;
331 }
332 return new Unknown(machInst);
333 }
334 '''
335}};
336
337def format ArmParallelAddSubtract() {{
338 decode_block='''
339 {
340 const uint32_t op1 = bits(machInst, 21, 20);
341 const uint32_t op2 = bits(machInst, 7, 5);
342 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
343 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
344 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
345 if (bits(machInst, 22) == 0) {
346 switch (op1) {
347 case 0x1:
348 switch (op2) {
349 case 0x0:
350 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
351 case 0x1:
352 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
353 case 0x2:
354 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
355 case 0x3:
356 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
357 case 0x4:
358 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
359 case 0x7:
360 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
361 }
362 break;
363 case 0x2:
364 switch (op2) {
365 case 0x0:
366 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
367 case 0x1:
368 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
369 case 0x2:
370 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
371 case 0x3:
372 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
373 case 0x4:
374 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
375 case 0x7:
376 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
377 }
378 break;
379 case 0x3:
380 switch (op2) {
381 case 0x0:
382 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
383 case 0x1:
384 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
385 case 0x2:
386 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
387 case 0x3:
388 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
389 case 0x4:
390 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
391 case 0x7:
392 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
393 }
394 break;
395 }
396 } else {
397 switch (op1) {
398 case 0x1:
399 switch (op2) {
400 case 0x0:
401 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
402 case 0x1:
403 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
404 case 0x2:
405 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
406 case 0x3:
407 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
408 case 0x4:
409 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
410 case 0x7:
411 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
412 }
413 break;
414 case 0x2:
415 switch (op2) {
416 case 0x0:
417 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
418 case 0x1:
419 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
420 case 0x2:
421 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
422 case 0x3:
423 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
424 case 0x4:
425 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
426 case 0x7:
427 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
428 }
429 break;
430 case 0x3:
431 switch (op2) {
432 case 0x0:
433 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
434 case 0x1:
435 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
436 case 0x2:
437 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
438 case 0x3:
439 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
440 case 0x4:
441 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
442 case 0x7:
443 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
444 }
445 break;
446 }
447 }
448 return new Unknown(machInst);
449 }
450 '''
451}};
452
453def format ArmDataProcImm() {{
454 pclr = '''
455 return new %(className)ssImmPclr(machInst, %(dest)s,
456 %(op1)s, imm, false);
457 '''
458 adr = '''
459 return new AdrImm(machInst, %(dest)s, %(add)s,
460 imm, false);
461 '''
462 instDecode = '''
463 case %(opcode)#x:
464 if (setCc) {
465 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
466 %(pclr)s
467 } else {
468 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
469 imm, rotC);
470 }
471 } else {
472 if (%(adrInst)s && %(op1)s == INTREG_PC) {
473 %(adr)s
474 } else {
475 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
476 imm, rotC);
477 }
478 }
479 break;
480 '''
481
482 def instCode(opcode, mnem, useDest = True, useOp1 = True):
483 global instDecode, pclr, adr
484 if useDest:
485 dest = "rd"
486 else:
487 dest = "INTREG_ZERO"
488 if useOp1:
489 op1 = "rn"
490 else:
491 op1 = "INTREG_ZERO"
492 substDict = { "className": mnem.capitalize(),
493 "opcode": opcode,
494 "dest": dest,
495 "op1": op1,
496 "adr": "",
497 "adrInst": "false" }
498 if useDest:
499 substDict["pclrInst"] = "true"
500 substDict["pclr"] = pclr % substDict
501 else:
502 substDict["pclrInst"] = "false"
503 substDict["pclr"] = ""
504 return instDecode % substDict
505
506 def adrCode(opcode, mnem, add="1"):
507 global instDecode, pclr, adr
508 substDict = { "className": mnem.capitalize(),
509 "opcode": opcode,
510 "dest": "rd",
511 "op1": "rn",
512 "add": add,
513 "pclrInst": "true",
514 "adrInst": "true" }
515 substDict["pclr"] = pclr % substDict
516 substDict["adr"] = adr % substDict
517 return instDecode % substDict
518
519 decode_block = '''
520 {
521 const bool setCc = (bits(machInst, 20) == 1);
522 const uint32_t unrotated = bits(machInst, 7, 0);
523 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
524 const bool rotC = (rotation != 0);
525 const uint32_t imm = rotate_imm(unrotated, rotation);
526 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
527 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
528 switch (OPCODE) {
529 '''
530 decode_block += instCode(0x0, "and")
531 decode_block += instCode(0x1, "eor")
532 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
533 decode_block += instCode(0x3, "rsb")
534 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
535 decode_block += instCode(0x5, "adc")
536 decode_block += instCode(0x6, "sbc")
537 decode_block += instCode(0x7, "rsc")
538 decode_block += instCode(0x8, "tst", useDest = False)
539 decode_block += instCode(0x9, "teq", useDest = False)
540 decode_block += instCode(0xa, "cmp", useDest = False)
541 decode_block += instCode(0xb, "cmn", useDest = False)
542 decode_block += instCode(0xc, "orr")
543 decode_block += instCode(0xd, "mov", useOp1 = False)
544 decode_block += instCode(0xe, "bic")
545 decode_block += instCode(0xf, "mvn", useOp1 = False)
546 decode_block += '''
547 default:
548 return new Unknown(machInst);
549 }
550 }
551 '''
552}};
553
554def format ArmSatAddSub() {{
555 decode_block = '''
556 {
557 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
558 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
559 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
560 switch (OPCODE) {
561 case 0x8:
562 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
563 case 0x9:
564 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
565 case 0xa:
566 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
567 case 0xb:
568 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
569 default:
570 return new Unknown(machInst);
571 }
572 }
573 '''
574}};
575
576def format Thumb32DataProcReg() {{
577 decode_block = '''
578 {
579 const uint32_t op1 = bits(machInst, 23, 20);
580 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
581 const uint32_t op2 = bits(machInst, 7, 4);
582 if (bits(machInst, 15, 12) != 0xf) {
583 return new Unknown(machInst);
584 }
585 if (bits(op1, 3) != 1) {
586 if (op2 == 0) {
587 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
588 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
589 switch (bits(op1, 2, 0)) {
590 case 0x0:
591 return new MovRegReg(machInst, rd,
592 INTREG_ZERO, rn, rm, LSL);
593 case 0x1:
594 return new MovRegRegCc(machInst, rd,
595 INTREG_ZERO, rn, rm, LSL);
596 case 0x2:
597 return new MovRegReg(machInst, rd,
598 INTREG_ZERO, rn, rm, LSR);
599 case 0x3:
600 return new MovRegRegCc(machInst, rd,
601 INTREG_ZERO, rn, rm, LSR);
602 case 0x4:
603 return new MovRegReg(machInst, rd,
604 INTREG_ZERO, rn, rm, ASR);
605 case 0x5:
606 return new MovRegRegCc(machInst, rd,
607 INTREG_ZERO, rn, rm, ASR);
608 case 0x6:
609 return new MovRegReg(machInst, rd,
610 INTREG_ZERO, rn, rm, ROR);
611 case 0x7:
612 return new MovRegRegCc(machInst, rd,
613 INTREG_ZERO, rn, rm, ROR);
614 }
615 } else if (bits(op2, 3) == 0) {
616 return new Unknown(machInst);
617 } else {
618 const IntRegIndex rd =
619 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
620 const IntRegIndex rm =
621 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
622 const uint32_t rotation =
623 (uint32_t)bits(machInst, 5, 4) << 3;
624 switch (bits(op1, 2, 0)) {
625 case 0x0:
626 if (rn == 0xf) {
627 return new Sxth(machInst, rd, rotation, rm);
628 } else {
629 return new Sxtah(machInst, rd, rn, rm, rotation);
630 }
631 case 0x1:
632 if (rn == 0xf) {
633 return new Uxth(machInst, rd, rotation, rm);
634 } else {
635 return new Uxtah(machInst, rd, rn, rm, rotation);
636 }
637 case 0x2:
638 if (rn == 0xf) {
639 return new Sxtb16(machInst, rd, rotation, rm);
640 } else {
641 return new Sxtab16(machInst, rd, rn, rm, rotation);
642 }
643 case 0x3:
644 if (rn == 0xf) {
645 return new Uxtb16(machInst, rd, rotation, rm);
646 } else {
647 return new Uxtab16(machInst, rd, rn, rm, rotation);
648 }
649 case 0x4:
650 if (rn == 0xf) {
651 return new Sxtb(machInst, rd, rotation, rm);
652 } else {
653 return new Sxtab(machInst, rd, rn, rm, rotation);
654 }
655 case 0x5:
656 if (rn == 0xf) {
657 return new Uxtb(machInst, rd, rotation, rm);
658 } else {
659 return new Uxtab(machInst, rd, rn, rm, rotation);
660 }
661 default:
662 return new Unknown(machInst);
663 }
664 }
665 } else {
666 if (bits(op2, 3) == 0) {
667 const IntRegIndex rd =
668 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
669 const IntRegIndex rm =
670 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
671 if (bits(op2, 2) == 0x0) {
672 const uint32_t op1 = bits(machInst, 22, 20);
673 const uint32_t op2 = bits(machInst, 5, 4);
674 switch (op2) {
675 case 0x0:
676 switch (op1) {
677 case 0x1:
678 return new Sadd16RegCc(machInst, rd,
679 rn, rm, 0, LSL);
680 case 0x2:
681 return new SasxRegCc(machInst, rd,
682 rn, rm, 0, LSL);
683 case 0x6:
684 return new SsaxRegCc(machInst, rd,
685 rn, rm, 0, LSL);
686 case 0x5:
687 return new Ssub16RegCc(machInst, rd,
688 rn, rm, 0, LSL);
689 case 0x0:
690 return new Sadd8RegCc(machInst, rd,
691 rn, rm, 0, LSL);
692 case 0x4:
693 return new Ssub8RegCc(machInst, rd,
694 rn, rm, 0, LSL);
695 }
696 break;
697 case 0x1:
698 switch (op1) {
699 case 0x1:
700 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
701 case 0x2:
702 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
703 case 0x6:
704 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
705 case 0x5:
706 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
707 case 0x0:
708 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
709 case 0x4:
710 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
711 }
712 break;
713 case 0x2:
714 switch (op1) {
715 case 0x1:
716 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
717 case 0x2:
718 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
719 case 0x6:
720 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
721 case 0x5:
722 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
723 case 0x0:
724 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
725 case 0x4:
726 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
727 }
728 break;
729 }
730 } else {
731 const uint32_t op1 = bits(machInst, 22, 20);
732 const uint32_t op2 = bits(machInst, 5, 4);
733 switch (op2) {
734 case 0x0:
735 switch (op1) {
736 case 0x1:
737 return new Uadd16RegCc(machInst, rd,
738 rn, rm, 0, LSL);
739 case 0x2:
740 return new UasxRegCc(machInst, rd,
741 rn, rm, 0, LSL);
742 case 0x6:
743 return new UsaxRegCc(machInst, rd,
744 rn, rm, 0, LSL);
745 case 0x5:
746 return new Usub16RegCc(machInst, rd,
747 rn, rm, 0, LSL);
748 case 0x0:
749 return new Uadd8RegCc(machInst, rd,
750 rn, rm, 0, LSL);
751 case 0x4:
752 return new Usub8RegCc(machInst, rd,
753 rn, rm, 0, LSL);
754 }
755 break;
756 case 0x1:
757 switch (op1) {
758 case 0x1:
759 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
760 case 0x2:
761 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
762 case 0x6:
763 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
764 case 0x5:
765 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
766 case 0x0:
767 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
768 case 0x4:
769 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
770 }
771 break;
772 case 0x2:
773 switch (op1) {
774 case 0x1:
775 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
776 case 0x2:
777 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
778 case 0x6:
779 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
780 case 0x5:
781 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
782 case 0x0:
783 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
784 case 0x4:
785 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
786 }
787 break;
788 }
789 }
790 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
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 ArmMiscMedia() {{
39 decode_block = '''
40 {
41 const uint32_t op1 = bits(machInst, 22, 20);
42 const uint32_t op2 = bits(machInst, 7, 5);
43 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
44 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
45 if (op1 == 0 && op2 == 0) {
46 const IntRegIndex rd =
47 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
48 const IntRegIndex rm =
49 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
50 if (ra == 0xf) {
51 return new Usad8(machInst, rd, rn, rm);
52 } else {
53 return new Usada8(machInst, rd, rn, rm, ra);
54 }
55 } else if (bits(op2, 1, 0) == 0x2) {
56 const uint32_t lsb = bits(machInst, 11, 7);
57 const uint32_t msb = lsb + bits(machInst, 20, 16);
58 if (bits(op1, 2, 1) == 0x3) {
59 return new Ubfx(machInst, ra, rn, lsb, msb);
60 } else if (bits(op1, 2, 1) == 0x1) {
61 return new Sbfx(machInst, ra, rn, lsb, msb);
62 }
63 } else if (bits(op2, 1, 0) == 0x0 && bits(op1, 2, 1) == 0x2) {
64 const uint32_t lsb = bits(machInst, 11, 7);
65 const uint32_t msb = bits(machInst, 20, 16);
66 if (rn == 0xf) {
67 return new Bfc(machInst, ra, ra, lsb, msb);
68 } else {
69 return new Bfi(machInst, ra, rn, lsb, msb);
70 }
71 }
72 return new Unknown(machInst);
73 }
74 '''
75}};
76
77def format ArmDataProcReg() {{
78 pclr = '''
79 return new %(className)ssRegPclr(machInst, %(dest)s,
80 %(op1)s, rm, imm5,
81 type);
82 '''
83 instDecode = '''
84 case %(opcode)#x:
85 if (immShift) {
86 if (setCc) {
87 if (%(dest)s == INTREG_PC) {
88 %(pclr)s
89 } else {
90 return new %(className)sRegCc(machInst, %(dest)s,
91 %(op1)s, rm, imm5, type);
92 }
93 } else {
94 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
95 rm, imm5, type);
96 }
97 } else {
98 if (setCc) {
99 return new %(className)sRegRegCc(machInst, %(dest)s,
100 %(op1)s, rm, rs, type);
101 } else {
102 return new %(className)sRegReg(machInst, %(dest)s,
103 %(op1)s, rm, rs, type);
104 }
105 }
106 break;
107 '''
108
109 def instCode(opcode, mnem, useDest = True, useOp1 = True):
110 global pclr
111 if useDest:
112 dest = "rd"
113 else:
114 dest = "INTREG_ZERO"
115 if useOp1:
116 op1 = "rn"
117 else:
118 op1 = "INTREG_ZERO"
119 global instDecode, pclrCode
120 substDict = { "className": mnem.capitalize(),
121 "opcode": opcode,
122 "dest": dest,
123 "op1": op1 }
124 if useDest:
125 substDict["pclr"] = pclr % substDict
126 else:
127 substDict["pclr"] = ""
128 return instDecode % substDict
129
130 decode_block = '''
131 {
132 const bool immShift = (bits(machInst, 4) == 0);
133 const bool setCc = (bits(machInst, 20) == 1);
134 const uint32_t imm5 = bits(machInst, 11, 7);
135 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
136 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
137 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
138 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
139 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
140 switch (OPCODE) {
141 '''
142 decode_block += instCode(0x0, "and")
143 decode_block += instCode(0x1, "eor")
144 decode_block += instCode(0x2, "sub")
145 decode_block += instCode(0x3, "rsb")
146 decode_block += instCode(0x4, "add")
147 decode_block += instCode(0x5, "adc")
148 decode_block += instCode(0x6, "sbc")
149 decode_block += instCode(0x7, "rsc")
150 decode_block += instCode(0x8, "tst", useDest = False)
151 decode_block += instCode(0x9, "teq", useDest = False)
152 decode_block += instCode(0xa, "cmp", useDest = False)
153 decode_block += instCode(0xb, "cmn", useDest = False)
154 decode_block += instCode(0xc, "orr")
155 decode_block += instCode(0xd, "mov", useOp1 = False)
156 decode_block += instCode(0xe, "bic")
157 decode_block += instCode(0xf, "mvn", useOp1 = False)
158 decode_block += '''
159 default:
160 return new Unknown(machInst);
161 }
162 }
163 '''
164}};
165
166def format ArmPackUnpackSatReverse() {{
167 decode_block = '''
168 {
169 const uint32_t op1 = bits(machInst, 22, 20);
170 const uint32_t a = bits(machInst, 19, 16);
171 const uint32_t op2 = bits(machInst, 7, 5);
172 if (bits(op2, 0) == 0) {
173 const IntRegIndex rn =
174 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
175 const IntRegIndex rd =
176 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
177 const uint32_t satImm = bits(machInst, 20, 16);
178 const uint32_t imm = bits(machInst, 11, 7);
179 const ArmShiftType type =
180 (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
181 if (op1 == 0) {
182 if (type) {
183 return new PkhtbReg(machInst, rd, (IntRegIndex)a,
184 rn, imm, type);
185 } else {
186 return new PkhbtReg(machInst, rd, (IntRegIndex)a,
187 rn, imm, type);
188 }
189 } else if (bits(op1, 2, 1) == 1) {
190 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
191 } else if (bits(op1, 2, 1) == 3) {
192 return new Usat(machInst, rd, satImm, rn, imm, type);
193 }
194 return new Unknown(machInst);
195 }
196 switch (op1) {
197 case 0x0:
198 {
199 const IntRegIndex rn =
200 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
201 const IntRegIndex rd =
202 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
203 const IntRegIndex rm =
204 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
205 if (op2 == 0x3) {
206 const uint32_t rotation =
207 (uint32_t)bits(machInst, 11, 10) << 3;
208 if (a == 0xf) {
209 return new Sxtb16(machInst, rd, rotation, rm);
210 } else {
211 return new Sxtab16(machInst, rd, rn, rm, rotation);
212 }
213 } else if (op2 == 0x5) {
214 return new Sel(machInst, rd, rn, rm);
215 }
216 }
217 break;
218 case 0x2:
219 if (op2 == 0x1) {
220 const IntRegIndex rn =
221 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
222 const IntRegIndex rd =
223 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
224 const uint32_t satImm = bits(machInst, 20, 16);
225 return new Ssat16(machInst, rd, satImm + 1, rn);
226 } else if (op2 == 0x3) {
227 const IntRegIndex rn =
228 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
229 const IntRegIndex rd =
230 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
231 const IntRegIndex rm =
232 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
233 const uint32_t rotation =
234 (uint32_t)bits(machInst, 11, 10) << 3;
235 if (a == 0xf) {
236 return new Sxtb(machInst, rd, rotation, rm);
237 } else {
238 return new Sxtab(machInst, rd, rn, rm, rotation);
239 }
240 }
241 break;
242 case 0x3:
243 if (op2 == 0x1) {
244 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
245 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
246 return new Rev(machInst, rd, rm);
247 } else if (op2 == 0x3) {
248 const IntRegIndex rn =
249 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
250 const IntRegIndex rd =
251 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
252 const IntRegIndex rm =
253 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
254 const uint32_t rotation =
255 (uint32_t)bits(machInst, 11, 10) << 3;
256 if (a == 0xf) {
257 return new Sxth(machInst, rd, rotation, rm);
258 } else {
259 return new Sxtah(machInst, rd, rn, rm, rotation);
260 }
261 } else if (op2 == 0x5) {
262 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
263 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
264 return new Rev16(machInst, rd, rm);
265 }
266 break;
267 case 0x4:
268 if (op2 == 0x3) {
269 const IntRegIndex rn =
270 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
271 const IntRegIndex rd =
272 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
273 const IntRegIndex rm =
274 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
275 const uint32_t rotation =
276 (uint32_t)bits(machInst, 11, 10) << 3;
277 if (a == 0xf) {
278 return new Uxtb16(machInst, rd, rotation, rm);
279 } else {
280 return new Uxtab16(machInst, rd, rn, rm, rotation);
281 }
282 }
283 break;
284 case 0x6:
285 if (op2 == 0x1) {
286 const IntRegIndex rn =
287 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
288 const IntRegIndex rd =
289 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
290 const uint32_t satImm = bits(machInst, 20, 16);
291 return new Usat16(machInst, rd, satImm, rn);
292 } else if (op2 == 0x3) {
293 const IntRegIndex rn =
294 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
295 const IntRegIndex rd =
296 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
297 const IntRegIndex rm =
298 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
299 const uint32_t rotation =
300 (uint32_t)bits(machInst, 11, 10) << 3;
301 if (a == 0xf) {
302 return new Uxtb(machInst, rd, rotation, rm);
303 } else {
304 return new Uxtab(machInst, rd, rn, rm, rotation);
305 }
306 }
307 break;
308 case 0x7:
309 {
310 const IntRegIndex rn =
311 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
312 const IntRegIndex rd =
313 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
314 const IntRegIndex rm =
315 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
316 if (op2 == 0x1) {
317 return new Rbit(machInst, rd, rm);
318 } else if (op2 == 0x3) {
319 const uint32_t rotation =
320 (uint32_t)bits(machInst, 11, 10) << 3;
321 if (a == 0xf) {
322 return new Uxth(machInst, rd, rotation, rm);
323 } else {
324 return new Uxtah(machInst, rd, rn, rm, rotation);
325 }
326 } else if (op2 == 0x5) {
327 return new Revsh(machInst, rd, rm);
328 }
329 }
330 break;
331 }
332 return new Unknown(machInst);
333 }
334 '''
335}};
336
337def format ArmParallelAddSubtract() {{
338 decode_block='''
339 {
340 const uint32_t op1 = bits(machInst, 21, 20);
341 const uint32_t op2 = bits(machInst, 7, 5);
342 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
343 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
344 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
345 if (bits(machInst, 22) == 0) {
346 switch (op1) {
347 case 0x1:
348 switch (op2) {
349 case 0x0:
350 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
351 case 0x1:
352 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
353 case 0x2:
354 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
355 case 0x3:
356 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
357 case 0x4:
358 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
359 case 0x7:
360 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
361 }
362 break;
363 case 0x2:
364 switch (op2) {
365 case 0x0:
366 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
367 case 0x1:
368 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
369 case 0x2:
370 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
371 case 0x3:
372 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
373 case 0x4:
374 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
375 case 0x7:
376 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
377 }
378 break;
379 case 0x3:
380 switch (op2) {
381 case 0x0:
382 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
383 case 0x1:
384 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
385 case 0x2:
386 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
387 case 0x3:
388 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
389 case 0x4:
390 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
391 case 0x7:
392 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
393 }
394 break;
395 }
396 } else {
397 switch (op1) {
398 case 0x1:
399 switch (op2) {
400 case 0x0:
401 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
402 case 0x1:
403 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
404 case 0x2:
405 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
406 case 0x3:
407 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
408 case 0x4:
409 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
410 case 0x7:
411 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
412 }
413 break;
414 case 0x2:
415 switch (op2) {
416 case 0x0:
417 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
418 case 0x1:
419 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
420 case 0x2:
421 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
422 case 0x3:
423 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
424 case 0x4:
425 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
426 case 0x7:
427 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
428 }
429 break;
430 case 0x3:
431 switch (op2) {
432 case 0x0:
433 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
434 case 0x1:
435 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
436 case 0x2:
437 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
438 case 0x3:
439 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
440 case 0x4:
441 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
442 case 0x7:
443 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
444 }
445 break;
446 }
447 }
448 return new Unknown(machInst);
449 }
450 '''
451}};
452
453def format ArmDataProcImm() {{
454 pclr = '''
455 return new %(className)ssImmPclr(machInst, %(dest)s,
456 %(op1)s, imm, false);
457 '''
458 adr = '''
459 return new AdrImm(machInst, %(dest)s, %(add)s,
460 imm, false);
461 '''
462 instDecode = '''
463 case %(opcode)#x:
464 if (setCc) {
465 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
466 %(pclr)s
467 } else {
468 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
469 imm, rotC);
470 }
471 } else {
472 if (%(adrInst)s && %(op1)s == INTREG_PC) {
473 %(adr)s
474 } else {
475 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
476 imm, rotC);
477 }
478 }
479 break;
480 '''
481
482 def instCode(opcode, mnem, useDest = True, useOp1 = True):
483 global instDecode, pclr, adr
484 if useDest:
485 dest = "rd"
486 else:
487 dest = "INTREG_ZERO"
488 if useOp1:
489 op1 = "rn"
490 else:
491 op1 = "INTREG_ZERO"
492 substDict = { "className": mnem.capitalize(),
493 "opcode": opcode,
494 "dest": dest,
495 "op1": op1,
496 "adr": "",
497 "adrInst": "false" }
498 if useDest:
499 substDict["pclrInst"] = "true"
500 substDict["pclr"] = pclr % substDict
501 else:
502 substDict["pclrInst"] = "false"
503 substDict["pclr"] = ""
504 return instDecode % substDict
505
506 def adrCode(opcode, mnem, add="1"):
507 global instDecode, pclr, adr
508 substDict = { "className": mnem.capitalize(),
509 "opcode": opcode,
510 "dest": "rd",
511 "op1": "rn",
512 "add": add,
513 "pclrInst": "true",
514 "adrInst": "true" }
515 substDict["pclr"] = pclr % substDict
516 substDict["adr"] = adr % substDict
517 return instDecode % substDict
518
519 decode_block = '''
520 {
521 const bool setCc = (bits(machInst, 20) == 1);
522 const uint32_t unrotated = bits(machInst, 7, 0);
523 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
524 const bool rotC = (rotation != 0);
525 const uint32_t imm = rotate_imm(unrotated, rotation);
526 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
527 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
528 switch (OPCODE) {
529 '''
530 decode_block += instCode(0x0, "and")
531 decode_block += instCode(0x1, "eor")
532 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
533 decode_block += instCode(0x3, "rsb")
534 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
535 decode_block += instCode(0x5, "adc")
536 decode_block += instCode(0x6, "sbc")
537 decode_block += instCode(0x7, "rsc")
538 decode_block += instCode(0x8, "tst", useDest = False)
539 decode_block += instCode(0x9, "teq", useDest = False)
540 decode_block += instCode(0xa, "cmp", useDest = False)
541 decode_block += instCode(0xb, "cmn", useDest = False)
542 decode_block += instCode(0xc, "orr")
543 decode_block += instCode(0xd, "mov", useOp1 = False)
544 decode_block += instCode(0xe, "bic")
545 decode_block += instCode(0xf, "mvn", useOp1 = False)
546 decode_block += '''
547 default:
548 return new Unknown(machInst);
549 }
550 }
551 '''
552}};
553
554def format ArmSatAddSub() {{
555 decode_block = '''
556 {
557 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
558 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
559 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
560 switch (OPCODE) {
561 case 0x8:
562 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
563 case 0x9:
564 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
565 case 0xa:
566 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
567 case 0xb:
568 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
569 default:
570 return new Unknown(machInst);
571 }
572 }
573 '''
574}};
575
576def format Thumb32DataProcReg() {{
577 decode_block = '''
578 {
579 const uint32_t op1 = bits(machInst, 23, 20);
580 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
581 const uint32_t op2 = bits(machInst, 7, 4);
582 if (bits(machInst, 15, 12) != 0xf) {
583 return new Unknown(machInst);
584 }
585 if (bits(op1, 3) != 1) {
586 if (op2 == 0) {
587 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
588 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
589 switch (bits(op1, 2, 0)) {
590 case 0x0:
591 return new MovRegReg(machInst, rd,
592 INTREG_ZERO, rn, rm, LSL);
593 case 0x1:
594 return new MovRegRegCc(machInst, rd,
595 INTREG_ZERO, rn, rm, LSL);
596 case 0x2:
597 return new MovRegReg(machInst, rd,
598 INTREG_ZERO, rn, rm, LSR);
599 case 0x3:
600 return new MovRegRegCc(machInst, rd,
601 INTREG_ZERO, rn, rm, LSR);
602 case 0x4:
603 return new MovRegReg(machInst, rd,
604 INTREG_ZERO, rn, rm, ASR);
605 case 0x5:
606 return new MovRegRegCc(machInst, rd,
607 INTREG_ZERO, rn, rm, ASR);
608 case 0x6:
609 return new MovRegReg(machInst, rd,
610 INTREG_ZERO, rn, rm, ROR);
611 case 0x7:
612 return new MovRegRegCc(machInst, rd,
613 INTREG_ZERO, rn, rm, ROR);
614 }
615 } else if (bits(op2, 3) == 0) {
616 return new Unknown(machInst);
617 } else {
618 const IntRegIndex rd =
619 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
620 const IntRegIndex rm =
621 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
622 const uint32_t rotation =
623 (uint32_t)bits(machInst, 5, 4) << 3;
624 switch (bits(op1, 2, 0)) {
625 case 0x0:
626 if (rn == 0xf) {
627 return new Sxth(machInst, rd, rotation, rm);
628 } else {
629 return new Sxtah(machInst, rd, rn, rm, rotation);
630 }
631 case 0x1:
632 if (rn == 0xf) {
633 return new Uxth(machInst, rd, rotation, rm);
634 } else {
635 return new Uxtah(machInst, rd, rn, rm, rotation);
636 }
637 case 0x2:
638 if (rn == 0xf) {
639 return new Sxtb16(machInst, rd, rotation, rm);
640 } else {
641 return new Sxtab16(machInst, rd, rn, rm, rotation);
642 }
643 case 0x3:
644 if (rn == 0xf) {
645 return new Uxtb16(machInst, rd, rotation, rm);
646 } else {
647 return new Uxtab16(machInst, rd, rn, rm, rotation);
648 }
649 case 0x4:
650 if (rn == 0xf) {
651 return new Sxtb(machInst, rd, rotation, rm);
652 } else {
653 return new Sxtab(machInst, rd, rn, rm, rotation);
654 }
655 case 0x5:
656 if (rn == 0xf) {
657 return new Uxtb(machInst, rd, rotation, rm);
658 } else {
659 return new Uxtab(machInst, rd, rn, rm, rotation);
660 }
661 default:
662 return new Unknown(machInst);
663 }
664 }
665 } else {
666 if (bits(op2, 3) == 0) {
667 const IntRegIndex rd =
668 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
669 const IntRegIndex rm =
670 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
671 if (bits(op2, 2) == 0x0) {
672 const uint32_t op1 = bits(machInst, 22, 20);
673 const uint32_t op2 = bits(machInst, 5, 4);
674 switch (op2) {
675 case 0x0:
676 switch (op1) {
677 case 0x1:
678 return new Sadd16RegCc(machInst, rd,
679 rn, rm, 0, LSL);
680 case 0x2:
681 return new SasxRegCc(machInst, rd,
682 rn, rm, 0, LSL);
683 case 0x6:
684 return new SsaxRegCc(machInst, rd,
685 rn, rm, 0, LSL);
686 case 0x5:
687 return new Ssub16RegCc(machInst, rd,
688 rn, rm, 0, LSL);
689 case 0x0:
690 return new Sadd8RegCc(machInst, rd,
691 rn, rm, 0, LSL);
692 case 0x4:
693 return new Ssub8RegCc(machInst, rd,
694 rn, rm, 0, LSL);
695 }
696 break;
697 case 0x1:
698 switch (op1) {
699 case 0x1:
700 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
701 case 0x2:
702 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
703 case 0x6:
704 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
705 case 0x5:
706 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
707 case 0x0:
708 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
709 case 0x4:
710 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
711 }
712 break;
713 case 0x2:
714 switch (op1) {
715 case 0x1:
716 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
717 case 0x2:
718 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
719 case 0x6:
720 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
721 case 0x5:
722 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
723 case 0x0:
724 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
725 case 0x4:
726 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
727 }
728 break;
729 }
730 } else {
731 const uint32_t op1 = bits(machInst, 22, 20);
732 const uint32_t op2 = bits(machInst, 5, 4);
733 switch (op2) {
734 case 0x0:
735 switch (op1) {
736 case 0x1:
737 return new Uadd16RegCc(machInst, rd,
738 rn, rm, 0, LSL);
739 case 0x2:
740 return new UasxRegCc(machInst, rd,
741 rn, rm, 0, LSL);
742 case 0x6:
743 return new UsaxRegCc(machInst, rd,
744 rn, rm, 0, LSL);
745 case 0x5:
746 return new Usub16RegCc(machInst, rd,
747 rn, rm, 0, LSL);
748 case 0x0:
749 return new Uadd8RegCc(machInst, rd,
750 rn, rm, 0, LSL);
751 case 0x4:
752 return new Usub8RegCc(machInst, rd,
753 rn, rm, 0, LSL);
754 }
755 break;
756 case 0x1:
757 switch (op1) {
758 case 0x1:
759 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
760 case 0x2:
761 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
762 case 0x6:
763 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
764 case 0x5:
765 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
766 case 0x0:
767 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
768 case 0x4:
769 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
770 }
771 break;
772 case 0x2:
773 switch (op1) {
774 case 0x1:
775 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
776 case 0x2:
777 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
778 case 0x6:
779 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
780 case 0x5:
781 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
782 case 0x0:
783 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
784 case 0x4:
785 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
786 }
787 break;
788 }
789 }
790 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
791 const uint32_t op1 = bits(machInst, 21, 20);
791 const uint32_t op1 = bits(machInst, 22, 20);
792 const uint32_t op2 = bits(machInst, 5, 4);
793 const IntRegIndex rd =
794 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
795 const IntRegIndex rm =
796 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
797 switch (op1) {
798 case 0x0:
799 switch (op2) {
800 case 0x0:
801 return new QaddRegCc(machInst, rd,
802 rm, rn, 0, LSL);
803 case 0x1:
804 return new QdaddRegCc(machInst, rd,
805 rm, rn, 0, LSL);
806 case 0x2:
807 return new QsubRegCc(machInst, rd,
808 rm, rn, 0, LSL);
809 case 0x3:
810 return new QdsubRegCc(machInst, rd,
811 rm, rn, 0, LSL);
812 }
813 break;
814 case 0x1:
815 switch (op2) {
816 case 0x0:
817 return new Rev(machInst, rd, rn);
818 case 0x1:
819 return new Rev16(machInst, rd, rn);
820 case 0x2:
821 return new Rbit(machInst, rd, rm);
822 case 0x3:
823 return new Revsh(machInst, rd, rn);
824 }
825 break;
826 case 0x2:
827 if (op2 == 0) {
828 return new Sel(machInst, rd, rn, rm);
829 }
830 break;
831 case 0x3:
832 if (op2 == 0) {
833 return new Clz(machInst, rd, rm);
834 }
792 const uint32_t op2 = bits(machInst, 5, 4);
793 const IntRegIndex rd =
794 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
795 const IntRegIndex rm =
796 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
797 switch (op1) {
798 case 0x0:
799 switch (op2) {
800 case 0x0:
801 return new QaddRegCc(machInst, rd,
802 rm, rn, 0, LSL);
803 case 0x1:
804 return new QdaddRegCc(machInst, rd,
805 rm, rn, 0, LSL);
806 case 0x2:
807 return new QsubRegCc(machInst, rd,
808 rm, rn, 0, LSL);
809 case 0x3:
810 return new QdsubRegCc(machInst, rd,
811 rm, rn, 0, LSL);
812 }
813 break;
814 case 0x1:
815 switch (op2) {
816 case 0x0:
817 return new Rev(machInst, rd, rn);
818 case 0x1:
819 return new Rev16(machInst, rd, rn);
820 case 0x2:
821 return new Rbit(machInst, rd, rm);
822 case 0x3:
823 return new Revsh(machInst, rd, rn);
824 }
825 break;
826 case 0x2:
827 if (op2 == 0) {
828 return new Sel(machInst, rd, rn, rm);
829 }
830 break;
831 case 0x3:
832 if (op2 == 0) {
833 return new Clz(machInst, rd, rm);
834 }
835 break;
836 case 0x4:
837 switch (op2) {
838 case 0x0:
839 return new Crc32b(machInst, rd, rn, rm);
840 case 0x1:
841 return new Crc32h(machInst, rd, rn, rm);
842 case 0x2:
843 return new Crc32w(machInst, rd, rn, rm);
844 }
845 break;
846 case 0x5:
847 switch (op2) {
848 case 0x0:
849 return new Crc32cb(machInst, rd, rn, rm);
850 case 0x1:
851 return new Crc32ch(machInst, rd, rn, rm);
852 case 0x2:
853 return new Crc32cw(machInst, rd, rn, rm);
854 }
855 break;
835 }
836 }
837 return new Unknown(machInst);
838 }
839 }
840 '''
841}};
842
843def format Thumb16ShiftAddSubMoveCmp() {{
844 decode_block = '''
845 {
846 const uint32_t imm5 = bits(machInst, 10, 6);
847 const uint32_t imm3 = bits(machInst, 8, 6);
848 const uint32_t imm8 = bits(machInst, 7, 0);
849 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
850 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
851 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
852 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
853 switch (bits(machInst, 13, 11)) {
854 case 0x0: // lsl
855 if (machInst.itstateMask) {
856 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
857 } else {
858 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
859 }
860 case 0x1: // lsr
861 if (machInst.itstateMask) {
862 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
863 } else {
864 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
865 }
866 case 0x2: // asr
867 if (machInst.itstateMask) {
868 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
869 } else {
870 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
871 }
872 case 0x3:
873 switch (bits(machInst, 10, 9)) {
874 case 0x0:
875 if (machInst.itstateMask) {
876 return new AddReg(machInst, rd, rn, rm, 0, LSL);
877 } else {
878 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
879 }
880 case 0x1:
881 if (machInst.itstateMask) {
882 return new SubReg(machInst, rd, rn, rm, 0, LSL);
883 } else {
884 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
885 }
886 case 0x2:
887 if (machInst.itstateMask) {
888 return new AddImm(machInst, rd, rn, imm3, true);
889 } else {
890 return new AddImmCc(machInst, rd, rn, imm3, true);
891 }
892 case 0x3:
893 if (machInst.itstateMask) {
894 return new SubImm(machInst, rd, rn, imm3, true);
895 } else {
896 return new SubImmCc(machInst, rd, rn, imm3, true);
897 }
898 }
899 case 0x4:
900 if (machInst.itstateMask) {
901 return new MovImm(machInst, rd8, INTREG_ZERO, imm8, false);
902 } else {
903 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
904 }
905 case 0x5:
906 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
907 case 0x6:
908 if (machInst.itstateMask) {
909 return new AddImm(machInst, rd8, rd8, imm8, true);
910 } else {
911 return new AddImmCc(machInst, rd8, rd8, imm8, true);
912 }
913 case 0x7:
914 if (machInst.itstateMask) {
915 return new SubImm(machInst, rd8, rd8, imm8, true);
916 } else {
917 return new SubImmCc(machInst, rd8, rd8, imm8, true);
918 }
919 }
920 }
921 '''
922}};
923
924def format Thumb16DataProcessing() {{
925 decode_block = '''
926 {
927 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
928 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
929 switch (bits(machInst, 9, 6)) {
930 case 0x0:
931 if (machInst.itstateMask) {
932 return new AndReg(machInst, rdn, rdn, rm, 0, LSL);
933 } else {
934 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
935 }
936 case 0x1:
937 if (machInst.itstateMask) {
938 return new EorReg(machInst, rdn, rdn, rm, 0, LSL);
939 } else {
940 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
941 }
942 case 0x2: //lsl
943 if (machInst.itstateMask) {
944 return new MovRegReg(machInst, rdn,
945 INTREG_ZERO, rdn, rm, LSL);
946 } else {
947 return new MovRegRegCc(machInst, rdn,
948 INTREG_ZERO, rdn, rm, LSL);
949 }
950 case 0x3: //lsr
951 if (machInst.itstateMask) {
952 return new MovRegReg(machInst, rdn,
953 INTREG_ZERO, rdn, rm, LSR);
954 } else {
955 return new MovRegRegCc(machInst, rdn,
956 INTREG_ZERO, rdn, rm, LSR);
957 }
958 case 0x4: //asr
959 if (machInst.itstateMask) {
960 return new MovRegReg(machInst, rdn,
961 INTREG_ZERO, rdn, rm, ASR);
962 } else {
963 return new MovRegRegCc(machInst, rdn,
964 INTREG_ZERO, rdn, rm, ASR);
965 }
966 case 0x5:
967 if (machInst.itstateMask) {
968 return new AdcReg(machInst, rdn, rdn, rm, 0, LSL);
969 } else {
970 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
971 }
972 case 0x6:
973 if (machInst.itstateMask) {
974 return new SbcReg(machInst, rdn, rdn, rm, 0, LSL);
975 } else {
976 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
977 }
978 case 0x7: // ror
979 if (machInst.itstateMask) {
980 return new MovRegReg(machInst, rdn,
981 INTREG_ZERO, rdn, rm, ROR);
982 } else {
983 return new MovRegRegCc(machInst, rdn,
984 INTREG_ZERO, rdn, rm, ROR);
985 }
986 case 0x8:
987 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
988 case 0x9:
989 if (machInst.itstateMask) {
990 return new RsbImm(machInst, rdn, rm, 0, true);
991 } else {
992 return new RsbImmCc(machInst, rdn, rm, 0, true);
993 }
994 case 0xa:
995 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
996 case 0xb:
997 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
998 case 0xc:
999 if (machInst.itstateMask) {
1000 return new OrrReg(machInst, rdn, rdn, rm, 0, LSL);
1001 } else {
1002 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
1003 }
1004 case 0xd:
1005 if (machInst.itstateMask) {
1006 return new Mul(machInst, rdn, rm, rdn);
1007 } else {
1008 return new MulCc(machInst, rdn, rm, rdn);
1009 }
1010 case 0xe:
1011 if (machInst.itstateMask) {
1012 return new BicReg(machInst, rdn, rdn, rm, 0, LSL);
1013 } else {
1014 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
1015 }
1016 case 0xf:
1017 if (machInst.itstateMask) {
1018 return new MvnReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1019 } else {
1020 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1021 }
1022 }
1023 }
1024 '''
1025}};
1026
1027def format Thumb16SpecDataAndBx() {{
1028 decode_block = '''
1029 {
1030 const IntRegIndex rdn =
1031 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
1032 (bits(machInst, 7) << 3));
1033 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
1034 switch (bits(machInst, 9, 8)) {
1035 case 0x0:
1036 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
1037 case 0x1:
1038 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1039 case 0x2:
1040 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1041 case 0x3:
1042 if (bits(machInst, 7) == 0) {
1043 return new BxReg(machInst,
1044 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1045 COND_UC);
1046 } else {
1047 return new BlxReg(machInst,
1048 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1049 COND_UC);
1050 }
1051 }
1052 }
1053 '''
1054}};
1055
1056def format Thumb16Adr() {{
1057 decode_block = '''
1058 {
1059 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1060 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1061 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
1062 }
1063 '''
1064}};
1065
1066def format Thumb16AddSp() {{
1067 decode_block = '''
1068 {
1069 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1070 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1071 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
1072 }
1073 '''
1074}};
1075
1076def format ArmMisc() {{
1077 decode_block = '''
1078 {
1079 const uint32_t unrotated = bits(machInst, 7, 0);
1080 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
1081 const uint32_t imm = rotate_imm(unrotated, rotation);
1082 const uint8_t byteMask = bits(machInst, 19, 16);
1083 switch (OPCODE) {
1084 case 0x8:
1085 return new MovImm(machInst, (IntRegIndex)(uint32_t)RD,
1086 (IntRegIndex)INTREG_ZERO,
1087 bits(machInst, 11, 0) | (bits(machInst, 19, 16) << 12),
1088 false);
1089 case 0x9:
1090 if (RN == 0) {
1091 switch (IMM) {
1092 case 0x0:
1093 return new NopInst(machInst);
1094 case 0x1:
1095 return new YieldInst(machInst);
1096 case 0x2:
1097 return new WfeInst(machInst);
1098 case 0x3:
1099 return new WfiInst(machInst);
1100 case 0x4:
1101 return new SevInst(machInst);
1102 default:
1103 return new Unknown(machInst);
1104 }
1105 } else {
1106 return new MsrCpsrImm(machInst, imm, byteMask);
1107 }
1108 case 0xa:
1109 {
1110 const uint32_t timm = (bits(machInst, 19, 16) << 12) |
1111 bits(machInst, 11, 0);
1112 return new MovtImm(machInst, (IntRegIndex)(uint32_t)RD,
1113 (IntRegIndex)(uint32_t)RD, timm, true);
1114 }
1115 case 0xb:
1116 return new MsrSpsrImm(machInst, imm, byteMask);
1117 default:
1118 return new Unknown(machInst);
1119 }
1120 }
1121 '''
1122}};
1123
1124def format Thumb16Misc() {{
1125 decode_block = '''
1126 {
1127 switch (bits(machInst, 11, 8)) {
1128 case 0x0:
1129 if (bits(machInst, 7)) {
1130 return new SubImm(machInst, INTREG_SP, INTREG_SP,
1131 bits(machInst, 6, 0) << 2, true);
1132 } else {
1133 return new AddImm(machInst, INTREG_SP, INTREG_SP,
1134 bits(machInst, 6, 0) << 2, true);
1135 }
1136 case 0x2:
1137 {
1138 const IntRegIndex rd =
1139 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1140 const IntRegIndex rm =
1141 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1142 switch (bits(machInst, 7, 6)) {
1143 case 0x0:
1144 return new Sxth(machInst, rd, 0, rm);
1145 case 0x1:
1146 return new Sxtb(machInst, rd, 0, rm);
1147 case 0x2:
1148 return new Uxth(machInst, rd, 0, rm);
1149 case 0x3:
1150 return new Uxtb(machInst, rd, 0, rm);
1151 }
1152 }
1153 case 0x1:
1154 case 0x3:
1155 return new Cbz(machInst,
1156 (bits(machInst, 9) << 6) |
1157 (bits(machInst, 7, 3) << 1),
1158 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1159 case 0x4:
1160 case 0x5:
1161 {
1162 const uint32_t m = bits(machInst, 8);
1163 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
1164 return new LdmStm(machInst, INTREG_SP, false, false, false,
1165 true, false, regList);
1166 }
1167 case 0x6:
1168 {
1169 const uint32_t opBits = bits(machInst, 7, 5);
1170 if (opBits == 2) {
1171 return new Setend(machInst, bits(machInst, 3));
1172 } else if (opBits == 3) {
1173 const bool enable = (bits(machInst, 4) == 0);
1174 const uint32_t mods = (bits(machInst, 2, 0) << 5) |
1175 ((enable ? 1 : 0) << 9);
1176 return new Cps(machInst, mods);
1177 }
1178 }
1179 case 0xa:
1180 {
1181 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1182 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1183 switch (bits(machInst, 7, 6)) {
1184 case 0x0:
1185 return new Rev(machInst, rd, rm);
1186 case 0x1:
1187 return new Rev16(machInst, rd, rm);
1188 case 0x3:
1189 return new Revsh(machInst, rd, rm);
1190 default:
1191 break;
1192 }
1193 }
1194 break;
1195 case 0x9:
1196 case 0xb:
1197 return new Cbnz(machInst,
1198 (bits(machInst, 9) << 6) |
1199 (bits(machInst, 7, 3) << 1),
1200 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1201 case 0xc:
1202 case 0xd:
1203 {
1204 const uint32_t p = bits(machInst, 8);
1205 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1206 return new LdmStm(machInst, INTREG_SP, true, true, false,
1207 true, true, regList);
1208 }
1209 case 0xe:
1210 return new BkptInst(machInst);
1211 case 0xf:
1212 if (bits(machInst, 3, 0) != 0)
1213 return new ItInst(machInst);
1214 switch (bits(machInst, 7, 4)) {
1215 case 0x0:
1216 return new NopInst(machInst);
1217 case 0x1:
1218 return new YieldInst(machInst);
1219 case 0x2:
1220 return new WfeInst(machInst);
1221 case 0x3:
1222 return new WfiInst(machInst);
1223 case 0x4:
1224 return new SevInst(machInst);
1225 default:
1226 return new WarnUnimplemented("unallocated_hint", machInst);
1227 }
1228 default:
1229 break;
1230 }
1231 return new Unknown(machInst);
1232 }
1233 '''
1234}};
1235
1236def format Thumb32DataProcModImm() {{
1237
1238 def decInst(mnem, dest="rd", op1="rn"):
1239 return '''
1240 if (s) {
1241 return new %(mnem)sImmCc(machInst, %(dest)s,
1242 %(op1)s, imm, rotC);
1243 } else {
1244 return new %(mnem)sImm(machInst, %(dest)s,
1245 %(op1)s, imm, rotC);
1246 }
1247 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1248
1249 decode_block = '''
1250 {
1251 const uint32_t op = bits(machInst, 24, 21);
1252 const bool s = (bits(machInst, 20) == 1);
1253 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1254 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1255 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1256 bits(machInst, 14, 12);
1257 const bool rotC = ctrlImm > 3;
1258 const uint32_t dataImm = bits(machInst, 7, 0);
1259 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1260 switch (op) {
1261 case 0x0:
1262 if (rd == INTREG_PC) {
1263 %(tst)s
1264 } else {
1265 %(and)s
1266 }
1267 case 0x1:
1268 %(bic)s
1269 case 0x2:
1270 if (rn == INTREG_PC) {
1271 %(mov)s
1272 } else {
1273 %(orr)s
1274 }
1275 case 0x3:
1276 if (rn == INTREG_PC) {
1277 %(mvn)s
1278 } else {
1279 %(orn)s
1280 }
1281 case 0x4:
1282 if (rd == INTREG_PC) {
1283 %(teq)s
1284 } else {
1285 %(eor)s
1286 }
1287 case 0x8:
1288 if (rd == INTREG_PC) {
1289 %(cmn)s
1290 } else {
1291 %(add)s
1292 }
1293 case 0xa:
1294 %(adc)s
1295 case 0xb:
1296 %(sbc)s
1297 case 0xd:
1298 if (rd == INTREG_PC) {
1299 %(cmp)s
1300 } else {
1301 %(sub)s
1302 }
1303 case 0xe:
1304 %(rsb)s
1305 default:
1306 return new Unknown(machInst);
1307 }
1308 }
1309 ''' % {
1310 "tst" : decInst("Tst", "INTREG_ZERO"),
1311 "and" : decInst("And"),
1312 "bic" : decInst("Bic"),
1313 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1314 "orr" : decInst("Orr"),
1315 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1316 "orn" : decInst("Orn"),
1317 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1318 "eor" : decInst("Eor"),
1319 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1320 "add" : decInst("Add"),
1321 "adc" : decInst("Adc"),
1322 "sbc" : decInst("Sbc"),
1323 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1324 "sub" : decInst("Sub"),
1325 "rsb" : decInst("Rsb")
1326 }
1327}};
1328
1329def format Thumb32DataProcPlainBin() {{
1330 decode_block = '''
1331 {
1332 const uint32_t op = bits(machInst, 24, 20);
1333 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1334 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1335 switch (op) {
1336 case 0x0:
1337 {
1338 const uint32_t imm = bits(machInst, 7, 0) |
1339 (bits(machInst, 14, 12) << 8) |
1340 (bits(machInst, 26) << 11);
1341 if (rn == 0xf) {
1342 return new AdrImm(machInst, rd, (IntRegIndex)1,
1343 imm, false);
1344 } else {
1345 return new AddImm(machInst, rd, rn, imm, true);
1346 }
1347 }
1348 case 0x4:
1349 {
1350 const uint32_t imm = bits(machInst, 7, 0) |
1351 (bits(machInst, 14, 12) << 8) |
1352 (bits(machInst, 26) << 11) |
1353 (bits(machInst, 19, 16) << 12);
1354 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1355 }
1356 case 0xa:
1357 {
1358 const uint32_t imm = bits(machInst, 7, 0) |
1359 (bits(machInst, 14, 12) << 8) |
1360 (bits(machInst, 26) << 11);
1361 if (rn == 0xf) {
1362 return new AdrImm(machInst, rd, (IntRegIndex)0,
1363 imm, false);
1364 } else {
1365 return new SubImm(machInst, rd, rn, imm, true);
1366 }
1367 }
1368 case 0xc:
1369 {
1370 const uint32_t imm = bits(machInst, 7, 0) |
1371 (bits(machInst, 14, 12) << 8) |
1372 (bits(machInst, 26) << 11) |
1373 (bits(machInst, 19, 16) << 12);
1374 return new MovtImm(machInst, rd, rd, imm, true);
1375 }
1376 case 0x12:
1377 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1378 const uint32_t satImm = bits(machInst, 4, 0);
1379 return new Ssat16(machInst, rd, satImm + 1, rn);
1380 }
1381 // Fall through on purpose...
1382 case 0x10:
1383 {
1384 const uint32_t satImm = bits(machInst, 4, 0);
1385 const uint32_t imm = bits(machInst, 7, 6) |
1386 (bits(machInst, 14, 12) << 2);
1387 const ArmShiftType type =
1388 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1389 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1390 }
1391 case 0x14:
1392 {
1393 const uint32_t lsb = bits(machInst, 7, 6) |
1394 (bits(machInst, 14, 12) << 2);
1395 const uint32_t msb = lsb + bits(machInst, 4, 0);
1396 return new Sbfx(machInst, rd, rn, lsb, msb);
1397 }
1398 case 0x16:
1399 {
1400 const uint32_t lsb = bits(machInst, 7, 6) |
1401 (bits(machInst, 14, 12) << 2);
1402 const uint32_t msb = bits(machInst, 4, 0);
1403 if (rn == 0xf) {
1404 return new Bfc(machInst, rd, rd, lsb, msb);
1405 } else {
1406 return new Bfi(machInst, rd, rn, lsb, msb);
1407 }
1408 }
1409 case 0x1a:
1410 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1411 const uint32_t satImm = bits(machInst, 4, 0);
1412 return new Usat16(machInst, rd, satImm, rn);
1413 }
1414 // Fall through on purpose...
1415 case 0x18:
1416 {
1417 const uint32_t satImm = bits(machInst, 4, 0);
1418 const uint32_t imm = bits(machInst, 7, 6) |
1419 (bits(machInst, 14, 12) << 2);
1420 const ArmShiftType type =
1421 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1422 return new Usat(machInst, rd, satImm, rn, imm, type);
1423 }
1424 case 0x1c:
1425 {
1426 const uint32_t lsb = bits(machInst, 7, 6) |
1427 (bits(machInst, 14, 12) << 2);
1428 const uint32_t msb = lsb + bits(machInst, 4, 0);
1429 return new Ubfx(machInst, rd, rn, lsb, msb);
1430 }
1431 default:
1432 return new Unknown(machInst);
1433 }
1434 }
1435 '''
1436}};
1437
1438def format Thumb32DataProcShiftReg() {{
1439
1440 def decInst(mnem, dest="rd", op1="rn"):
1441 return '''
1442 if (s) {
1443 return new %(mnem)sRegCc(machInst, %(dest)s,
1444 %(op1)s, rm, amt, type);
1445 } else {
1446 return new %(mnem)sReg(machInst, %(dest)s,
1447 %(op1)s, rm, amt, type);
1448 }
1449 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1450
1451 decode_block = '''
1452 {
1453 const uint32_t op = bits(machInst, 24, 21);
1454 const bool s = (bits(machInst, 20) == 1);
1455 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1456 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1457 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1458 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1459 bits(machInst, 7, 6);
1460 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1461 switch (op) {
1462 case 0x0:
1463 if (rd == INTREG_PC) {
1464 %(tst)s
1465 } else {
1466 %(and)s
1467 }
1468 case 0x1:
1469 %(bic)s
1470 case 0x2:
1471 if (rn == INTREG_PC) {
1472 %(mov)s
1473 } else {
1474 %(orr)s
1475 }
1476 case 0x3:
1477 if (rn == INTREG_PC) {
1478 %(mvn)s
1479 } else {
1480 %(orn)s
1481 }
1482 case 0x4:
1483 if (rd == INTREG_PC) {
1484 %(teq)s
1485 } else {
1486 %(eor)s
1487 }
1488 case 0x6:
1489 if (type) {
1490 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1491 } else {
1492 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1493 }
1494 case 0x8:
1495 if (rd == INTREG_PC) {
1496 %(cmn)s
1497 } else {
1498 %(add)s
1499 }
1500 case 0xa:
1501 %(adc)s
1502 case 0xb:
1503 %(sbc)s
1504 case 0xd:
1505 if (rd == INTREG_PC) {
1506 %(cmp)s
1507 } else {
1508 %(sub)s
1509 }
1510 case 0xe:
1511 %(rsb)s
1512 default:
1513 return new Unknown(machInst);
1514 }
1515 }
1516 ''' % {
1517 "tst" : decInst("Tst", "INTREG_ZERO"),
1518 "and" : decInst("And"),
1519 "bic" : decInst("Bic"),
1520 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1521 "orr" : decInst("Orr"),
1522 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1523 "orn" : decInst("Orn"),
1524 "teq" : decInst("Teq", "INTREG_ZERO"),
1525 "eor" : decInst("Eor"),
1526 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1527 "add" : decInst("Add"),
1528 "adc" : decInst("Adc"),
1529 "sbc" : decInst("Sbc"),
1530 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1531 "sub" : decInst("Sub"),
1532 "rsb" : decInst("Rsb")
1533 }
1534}};
856 }
857 }
858 return new Unknown(machInst);
859 }
860 }
861 '''
862}};
863
864def format Thumb16ShiftAddSubMoveCmp() {{
865 decode_block = '''
866 {
867 const uint32_t imm5 = bits(machInst, 10, 6);
868 const uint32_t imm3 = bits(machInst, 8, 6);
869 const uint32_t imm8 = bits(machInst, 7, 0);
870 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
871 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
872 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
873 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
874 switch (bits(machInst, 13, 11)) {
875 case 0x0: // lsl
876 if (machInst.itstateMask) {
877 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
878 } else {
879 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
880 }
881 case 0x1: // lsr
882 if (machInst.itstateMask) {
883 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
884 } else {
885 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
886 }
887 case 0x2: // asr
888 if (machInst.itstateMask) {
889 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
890 } else {
891 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
892 }
893 case 0x3:
894 switch (bits(machInst, 10, 9)) {
895 case 0x0:
896 if (machInst.itstateMask) {
897 return new AddReg(machInst, rd, rn, rm, 0, LSL);
898 } else {
899 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
900 }
901 case 0x1:
902 if (machInst.itstateMask) {
903 return new SubReg(machInst, rd, rn, rm, 0, LSL);
904 } else {
905 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
906 }
907 case 0x2:
908 if (machInst.itstateMask) {
909 return new AddImm(machInst, rd, rn, imm3, true);
910 } else {
911 return new AddImmCc(machInst, rd, rn, imm3, true);
912 }
913 case 0x3:
914 if (machInst.itstateMask) {
915 return new SubImm(machInst, rd, rn, imm3, true);
916 } else {
917 return new SubImmCc(machInst, rd, rn, imm3, true);
918 }
919 }
920 case 0x4:
921 if (machInst.itstateMask) {
922 return new MovImm(machInst, rd8, INTREG_ZERO, imm8, false);
923 } else {
924 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
925 }
926 case 0x5:
927 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
928 case 0x6:
929 if (machInst.itstateMask) {
930 return new AddImm(machInst, rd8, rd8, imm8, true);
931 } else {
932 return new AddImmCc(machInst, rd8, rd8, imm8, true);
933 }
934 case 0x7:
935 if (machInst.itstateMask) {
936 return new SubImm(machInst, rd8, rd8, imm8, true);
937 } else {
938 return new SubImmCc(machInst, rd8, rd8, imm8, true);
939 }
940 }
941 }
942 '''
943}};
944
945def format Thumb16DataProcessing() {{
946 decode_block = '''
947 {
948 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
949 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
950 switch (bits(machInst, 9, 6)) {
951 case 0x0:
952 if (machInst.itstateMask) {
953 return new AndReg(machInst, rdn, rdn, rm, 0, LSL);
954 } else {
955 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
956 }
957 case 0x1:
958 if (machInst.itstateMask) {
959 return new EorReg(machInst, rdn, rdn, rm, 0, LSL);
960 } else {
961 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
962 }
963 case 0x2: //lsl
964 if (machInst.itstateMask) {
965 return new MovRegReg(machInst, rdn,
966 INTREG_ZERO, rdn, rm, LSL);
967 } else {
968 return new MovRegRegCc(machInst, rdn,
969 INTREG_ZERO, rdn, rm, LSL);
970 }
971 case 0x3: //lsr
972 if (machInst.itstateMask) {
973 return new MovRegReg(machInst, rdn,
974 INTREG_ZERO, rdn, rm, LSR);
975 } else {
976 return new MovRegRegCc(machInst, rdn,
977 INTREG_ZERO, rdn, rm, LSR);
978 }
979 case 0x4: //asr
980 if (machInst.itstateMask) {
981 return new MovRegReg(machInst, rdn,
982 INTREG_ZERO, rdn, rm, ASR);
983 } else {
984 return new MovRegRegCc(machInst, rdn,
985 INTREG_ZERO, rdn, rm, ASR);
986 }
987 case 0x5:
988 if (machInst.itstateMask) {
989 return new AdcReg(machInst, rdn, rdn, rm, 0, LSL);
990 } else {
991 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
992 }
993 case 0x6:
994 if (machInst.itstateMask) {
995 return new SbcReg(machInst, rdn, rdn, rm, 0, LSL);
996 } else {
997 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
998 }
999 case 0x7: // ror
1000 if (machInst.itstateMask) {
1001 return new MovRegReg(machInst, rdn,
1002 INTREG_ZERO, rdn, rm, ROR);
1003 } else {
1004 return new MovRegRegCc(machInst, rdn,
1005 INTREG_ZERO, rdn, rm, ROR);
1006 }
1007 case 0x8:
1008 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1009 case 0x9:
1010 if (machInst.itstateMask) {
1011 return new RsbImm(machInst, rdn, rm, 0, true);
1012 } else {
1013 return new RsbImmCc(machInst, rdn, rm, 0, true);
1014 }
1015 case 0xa:
1016 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1017 case 0xb:
1018 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1019 case 0xc:
1020 if (machInst.itstateMask) {
1021 return new OrrReg(machInst, rdn, rdn, rm, 0, LSL);
1022 } else {
1023 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
1024 }
1025 case 0xd:
1026 if (machInst.itstateMask) {
1027 return new Mul(machInst, rdn, rm, rdn);
1028 } else {
1029 return new MulCc(machInst, rdn, rm, rdn);
1030 }
1031 case 0xe:
1032 if (machInst.itstateMask) {
1033 return new BicReg(machInst, rdn, rdn, rm, 0, LSL);
1034 } else {
1035 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
1036 }
1037 case 0xf:
1038 if (machInst.itstateMask) {
1039 return new MvnReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1040 } else {
1041 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1042 }
1043 }
1044 }
1045 '''
1046}};
1047
1048def format Thumb16SpecDataAndBx() {{
1049 decode_block = '''
1050 {
1051 const IntRegIndex rdn =
1052 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
1053 (bits(machInst, 7) << 3));
1054 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
1055 switch (bits(machInst, 9, 8)) {
1056 case 0x0:
1057 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
1058 case 0x1:
1059 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1060 case 0x2:
1061 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1062 case 0x3:
1063 if (bits(machInst, 7) == 0) {
1064 return new BxReg(machInst,
1065 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1066 COND_UC);
1067 } else {
1068 return new BlxReg(machInst,
1069 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1070 COND_UC);
1071 }
1072 }
1073 }
1074 '''
1075}};
1076
1077def format Thumb16Adr() {{
1078 decode_block = '''
1079 {
1080 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1081 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1082 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
1083 }
1084 '''
1085}};
1086
1087def format Thumb16AddSp() {{
1088 decode_block = '''
1089 {
1090 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1091 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1092 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
1093 }
1094 '''
1095}};
1096
1097def format ArmMisc() {{
1098 decode_block = '''
1099 {
1100 const uint32_t unrotated = bits(machInst, 7, 0);
1101 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
1102 const uint32_t imm = rotate_imm(unrotated, rotation);
1103 const uint8_t byteMask = bits(machInst, 19, 16);
1104 switch (OPCODE) {
1105 case 0x8:
1106 return new MovImm(machInst, (IntRegIndex)(uint32_t)RD,
1107 (IntRegIndex)INTREG_ZERO,
1108 bits(machInst, 11, 0) | (bits(machInst, 19, 16) << 12),
1109 false);
1110 case 0x9:
1111 if (RN == 0) {
1112 switch (IMM) {
1113 case 0x0:
1114 return new NopInst(machInst);
1115 case 0x1:
1116 return new YieldInst(machInst);
1117 case 0x2:
1118 return new WfeInst(machInst);
1119 case 0x3:
1120 return new WfiInst(machInst);
1121 case 0x4:
1122 return new SevInst(machInst);
1123 default:
1124 return new Unknown(machInst);
1125 }
1126 } else {
1127 return new MsrCpsrImm(machInst, imm, byteMask);
1128 }
1129 case 0xa:
1130 {
1131 const uint32_t timm = (bits(machInst, 19, 16) << 12) |
1132 bits(machInst, 11, 0);
1133 return new MovtImm(machInst, (IntRegIndex)(uint32_t)RD,
1134 (IntRegIndex)(uint32_t)RD, timm, true);
1135 }
1136 case 0xb:
1137 return new MsrSpsrImm(machInst, imm, byteMask);
1138 default:
1139 return new Unknown(machInst);
1140 }
1141 }
1142 '''
1143}};
1144
1145def format Thumb16Misc() {{
1146 decode_block = '''
1147 {
1148 switch (bits(machInst, 11, 8)) {
1149 case 0x0:
1150 if (bits(machInst, 7)) {
1151 return new SubImm(machInst, INTREG_SP, INTREG_SP,
1152 bits(machInst, 6, 0) << 2, true);
1153 } else {
1154 return new AddImm(machInst, INTREG_SP, INTREG_SP,
1155 bits(machInst, 6, 0) << 2, true);
1156 }
1157 case 0x2:
1158 {
1159 const IntRegIndex rd =
1160 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1161 const IntRegIndex rm =
1162 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1163 switch (bits(machInst, 7, 6)) {
1164 case 0x0:
1165 return new Sxth(machInst, rd, 0, rm);
1166 case 0x1:
1167 return new Sxtb(machInst, rd, 0, rm);
1168 case 0x2:
1169 return new Uxth(machInst, rd, 0, rm);
1170 case 0x3:
1171 return new Uxtb(machInst, rd, 0, rm);
1172 }
1173 }
1174 case 0x1:
1175 case 0x3:
1176 return new Cbz(machInst,
1177 (bits(machInst, 9) << 6) |
1178 (bits(machInst, 7, 3) << 1),
1179 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1180 case 0x4:
1181 case 0x5:
1182 {
1183 const uint32_t m = bits(machInst, 8);
1184 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
1185 return new LdmStm(machInst, INTREG_SP, false, false, false,
1186 true, false, regList);
1187 }
1188 case 0x6:
1189 {
1190 const uint32_t opBits = bits(machInst, 7, 5);
1191 if (opBits == 2) {
1192 return new Setend(machInst, bits(machInst, 3));
1193 } else if (opBits == 3) {
1194 const bool enable = (bits(machInst, 4) == 0);
1195 const uint32_t mods = (bits(machInst, 2, 0) << 5) |
1196 ((enable ? 1 : 0) << 9);
1197 return new Cps(machInst, mods);
1198 }
1199 }
1200 case 0xa:
1201 {
1202 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1203 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1204 switch (bits(machInst, 7, 6)) {
1205 case 0x0:
1206 return new Rev(machInst, rd, rm);
1207 case 0x1:
1208 return new Rev16(machInst, rd, rm);
1209 case 0x3:
1210 return new Revsh(machInst, rd, rm);
1211 default:
1212 break;
1213 }
1214 }
1215 break;
1216 case 0x9:
1217 case 0xb:
1218 return new Cbnz(machInst,
1219 (bits(machInst, 9) << 6) |
1220 (bits(machInst, 7, 3) << 1),
1221 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1222 case 0xc:
1223 case 0xd:
1224 {
1225 const uint32_t p = bits(machInst, 8);
1226 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1227 return new LdmStm(machInst, INTREG_SP, true, true, false,
1228 true, true, regList);
1229 }
1230 case 0xe:
1231 return new BkptInst(machInst);
1232 case 0xf:
1233 if (bits(machInst, 3, 0) != 0)
1234 return new ItInst(machInst);
1235 switch (bits(machInst, 7, 4)) {
1236 case 0x0:
1237 return new NopInst(machInst);
1238 case 0x1:
1239 return new YieldInst(machInst);
1240 case 0x2:
1241 return new WfeInst(machInst);
1242 case 0x3:
1243 return new WfiInst(machInst);
1244 case 0x4:
1245 return new SevInst(machInst);
1246 default:
1247 return new WarnUnimplemented("unallocated_hint", machInst);
1248 }
1249 default:
1250 break;
1251 }
1252 return new Unknown(machInst);
1253 }
1254 '''
1255}};
1256
1257def format Thumb32DataProcModImm() {{
1258
1259 def decInst(mnem, dest="rd", op1="rn"):
1260 return '''
1261 if (s) {
1262 return new %(mnem)sImmCc(machInst, %(dest)s,
1263 %(op1)s, imm, rotC);
1264 } else {
1265 return new %(mnem)sImm(machInst, %(dest)s,
1266 %(op1)s, imm, rotC);
1267 }
1268 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1269
1270 decode_block = '''
1271 {
1272 const uint32_t op = bits(machInst, 24, 21);
1273 const bool s = (bits(machInst, 20) == 1);
1274 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1275 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1276 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1277 bits(machInst, 14, 12);
1278 const bool rotC = ctrlImm > 3;
1279 const uint32_t dataImm = bits(machInst, 7, 0);
1280 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1281 switch (op) {
1282 case 0x0:
1283 if (rd == INTREG_PC) {
1284 %(tst)s
1285 } else {
1286 %(and)s
1287 }
1288 case 0x1:
1289 %(bic)s
1290 case 0x2:
1291 if (rn == INTREG_PC) {
1292 %(mov)s
1293 } else {
1294 %(orr)s
1295 }
1296 case 0x3:
1297 if (rn == INTREG_PC) {
1298 %(mvn)s
1299 } else {
1300 %(orn)s
1301 }
1302 case 0x4:
1303 if (rd == INTREG_PC) {
1304 %(teq)s
1305 } else {
1306 %(eor)s
1307 }
1308 case 0x8:
1309 if (rd == INTREG_PC) {
1310 %(cmn)s
1311 } else {
1312 %(add)s
1313 }
1314 case 0xa:
1315 %(adc)s
1316 case 0xb:
1317 %(sbc)s
1318 case 0xd:
1319 if (rd == INTREG_PC) {
1320 %(cmp)s
1321 } else {
1322 %(sub)s
1323 }
1324 case 0xe:
1325 %(rsb)s
1326 default:
1327 return new Unknown(machInst);
1328 }
1329 }
1330 ''' % {
1331 "tst" : decInst("Tst", "INTREG_ZERO"),
1332 "and" : decInst("And"),
1333 "bic" : decInst("Bic"),
1334 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1335 "orr" : decInst("Orr"),
1336 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1337 "orn" : decInst("Orn"),
1338 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1339 "eor" : decInst("Eor"),
1340 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1341 "add" : decInst("Add"),
1342 "adc" : decInst("Adc"),
1343 "sbc" : decInst("Sbc"),
1344 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1345 "sub" : decInst("Sub"),
1346 "rsb" : decInst("Rsb")
1347 }
1348}};
1349
1350def format Thumb32DataProcPlainBin() {{
1351 decode_block = '''
1352 {
1353 const uint32_t op = bits(machInst, 24, 20);
1354 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1355 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1356 switch (op) {
1357 case 0x0:
1358 {
1359 const uint32_t imm = bits(machInst, 7, 0) |
1360 (bits(machInst, 14, 12) << 8) |
1361 (bits(machInst, 26) << 11);
1362 if (rn == 0xf) {
1363 return new AdrImm(machInst, rd, (IntRegIndex)1,
1364 imm, false);
1365 } else {
1366 return new AddImm(machInst, rd, rn, imm, true);
1367 }
1368 }
1369 case 0x4:
1370 {
1371 const uint32_t imm = bits(machInst, 7, 0) |
1372 (bits(machInst, 14, 12) << 8) |
1373 (bits(machInst, 26) << 11) |
1374 (bits(machInst, 19, 16) << 12);
1375 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1376 }
1377 case 0xa:
1378 {
1379 const uint32_t imm = bits(machInst, 7, 0) |
1380 (bits(machInst, 14, 12) << 8) |
1381 (bits(machInst, 26) << 11);
1382 if (rn == 0xf) {
1383 return new AdrImm(machInst, rd, (IntRegIndex)0,
1384 imm, false);
1385 } else {
1386 return new SubImm(machInst, rd, rn, imm, true);
1387 }
1388 }
1389 case 0xc:
1390 {
1391 const uint32_t imm = bits(machInst, 7, 0) |
1392 (bits(machInst, 14, 12) << 8) |
1393 (bits(machInst, 26) << 11) |
1394 (bits(machInst, 19, 16) << 12);
1395 return new MovtImm(machInst, rd, rd, imm, true);
1396 }
1397 case 0x12:
1398 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1399 const uint32_t satImm = bits(machInst, 4, 0);
1400 return new Ssat16(machInst, rd, satImm + 1, rn);
1401 }
1402 // Fall through on purpose...
1403 case 0x10:
1404 {
1405 const uint32_t satImm = bits(machInst, 4, 0);
1406 const uint32_t imm = bits(machInst, 7, 6) |
1407 (bits(machInst, 14, 12) << 2);
1408 const ArmShiftType type =
1409 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1410 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1411 }
1412 case 0x14:
1413 {
1414 const uint32_t lsb = bits(machInst, 7, 6) |
1415 (bits(machInst, 14, 12) << 2);
1416 const uint32_t msb = lsb + bits(machInst, 4, 0);
1417 return new Sbfx(machInst, rd, rn, lsb, msb);
1418 }
1419 case 0x16:
1420 {
1421 const uint32_t lsb = bits(machInst, 7, 6) |
1422 (bits(machInst, 14, 12) << 2);
1423 const uint32_t msb = bits(machInst, 4, 0);
1424 if (rn == 0xf) {
1425 return new Bfc(machInst, rd, rd, lsb, msb);
1426 } else {
1427 return new Bfi(machInst, rd, rn, lsb, msb);
1428 }
1429 }
1430 case 0x1a:
1431 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1432 const uint32_t satImm = bits(machInst, 4, 0);
1433 return new Usat16(machInst, rd, satImm, rn);
1434 }
1435 // Fall through on purpose...
1436 case 0x18:
1437 {
1438 const uint32_t satImm = bits(machInst, 4, 0);
1439 const uint32_t imm = bits(machInst, 7, 6) |
1440 (bits(machInst, 14, 12) << 2);
1441 const ArmShiftType type =
1442 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1443 return new Usat(machInst, rd, satImm, rn, imm, type);
1444 }
1445 case 0x1c:
1446 {
1447 const uint32_t lsb = bits(machInst, 7, 6) |
1448 (bits(machInst, 14, 12) << 2);
1449 const uint32_t msb = lsb + bits(machInst, 4, 0);
1450 return new Ubfx(machInst, rd, rn, lsb, msb);
1451 }
1452 default:
1453 return new Unknown(machInst);
1454 }
1455 }
1456 '''
1457}};
1458
1459def format Thumb32DataProcShiftReg() {{
1460
1461 def decInst(mnem, dest="rd", op1="rn"):
1462 return '''
1463 if (s) {
1464 return new %(mnem)sRegCc(machInst, %(dest)s,
1465 %(op1)s, rm, amt, type);
1466 } else {
1467 return new %(mnem)sReg(machInst, %(dest)s,
1468 %(op1)s, rm, amt, type);
1469 }
1470 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1471
1472 decode_block = '''
1473 {
1474 const uint32_t op = bits(machInst, 24, 21);
1475 const bool s = (bits(machInst, 20) == 1);
1476 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1477 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1478 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1479 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1480 bits(machInst, 7, 6);
1481 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1482 switch (op) {
1483 case 0x0:
1484 if (rd == INTREG_PC) {
1485 %(tst)s
1486 } else {
1487 %(and)s
1488 }
1489 case 0x1:
1490 %(bic)s
1491 case 0x2:
1492 if (rn == INTREG_PC) {
1493 %(mov)s
1494 } else {
1495 %(orr)s
1496 }
1497 case 0x3:
1498 if (rn == INTREG_PC) {
1499 %(mvn)s
1500 } else {
1501 %(orn)s
1502 }
1503 case 0x4:
1504 if (rd == INTREG_PC) {
1505 %(teq)s
1506 } else {
1507 %(eor)s
1508 }
1509 case 0x6:
1510 if (type) {
1511 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1512 } else {
1513 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1514 }
1515 case 0x8:
1516 if (rd == INTREG_PC) {
1517 %(cmn)s
1518 } else {
1519 %(add)s
1520 }
1521 case 0xa:
1522 %(adc)s
1523 case 0xb:
1524 %(sbc)s
1525 case 0xd:
1526 if (rd == INTREG_PC) {
1527 %(cmp)s
1528 } else {
1529 %(sub)s
1530 }
1531 case 0xe:
1532 %(rsb)s
1533 default:
1534 return new Unknown(machInst);
1535 }
1536 }
1537 ''' % {
1538 "tst" : decInst("Tst", "INTREG_ZERO"),
1539 "and" : decInst("And"),
1540 "bic" : decInst("Bic"),
1541 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1542 "orr" : decInst("Orr"),
1543 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1544 "orn" : decInst("Orn"),
1545 "teq" : decInst("Teq", "INTREG_ZERO"),
1546 "eor" : decInst("Eor"),
1547 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1548 "add" : decInst("Add"),
1549 "adc" : decInst("Adc"),
1550 "sbc" : decInst("Sbc"),
1551 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1552 "sub" : decInst("Sub"),
1553 "rsb" : decInst("Rsb")
1554 }
1555}};