data.isa (7419:10e7f0f18461) data.isa (7432:7501a6d33e3e)
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 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);
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 }
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#if FULL_SYSTEM
1095 case 0x1:
1096 return new YieldInst(machInst);
1097 case 0x2:
1098 return new WfeInst(machInst);
1099 case 0x3:
1100 return new WfiInst(machInst);
1101 case 0x4:
1102 return new SevInst(machInst);
1103#endif
1104 default:
1105 return new Unknown(machInst);
1106 }
1107 } else {
1108 return new MsrCpsrImm(machInst, imm, byteMask);
1109 }
1110 case 0xa:
1111 {
1112 const uint32_t timm = (bits(machInst, 19, 16) << 12) |
1113 bits(machInst, 11, 0);
1114 return new MovtImm(machInst, (IntRegIndex)(uint32_t)RD,
1115 (IntRegIndex)(uint32_t)RD, timm, true);
1116 }
1117 case 0xb:
1118 return new MsrSpsrImm(machInst, imm, byteMask);
1119 default:
1120 return new Unknown(machInst);
1121 }
1122 }
1123 '''
1124}};
1125
1126def format Thumb16Misc() {{
1127 decode_block = '''
1128 {
1129 switch (bits(machInst, 11, 8)) {
1130 case 0x0:
1131 if (bits(machInst, 7)) {
1132 return new SubImm(machInst, INTREG_SP, INTREG_SP,
1133 bits(machInst, 6, 0) << 2, true);
1134 } else {
1135 return new AddImm(machInst, INTREG_SP, INTREG_SP,
1136 bits(machInst, 6, 0) << 2, true);
1137 }
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 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);
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 }
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#if FULL_SYSTEM
1095 case 0x1:
1096 return new YieldInst(machInst);
1097 case 0x2:
1098 return new WfeInst(machInst);
1099 case 0x3:
1100 return new WfiInst(machInst);
1101 case 0x4:
1102 return new SevInst(machInst);
1103#endif
1104 default:
1105 return new Unknown(machInst);
1106 }
1107 } else {
1108 return new MsrCpsrImm(machInst, imm, byteMask);
1109 }
1110 case 0xa:
1111 {
1112 const uint32_t timm = (bits(machInst, 19, 16) << 12) |
1113 bits(machInst, 11, 0);
1114 return new MovtImm(machInst, (IntRegIndex)(uint32_t)RD,
1115 (IntRegIndex)(uint32_t)RD, timm, true);
1116 }
1117 case 0xb:
1118 return new MsrSpsrImm(machInst, imm, byteMask);
1119 default:
1120 return new Unknown(machInst);
1121 }
1122 }
1123 '''
1124}};
1125
1126def format Thumb16Misc() {{
1127 decode_block = '''
1128 {
1129 switch (bits(machInst, 11, 8)) {
1130 case 0x0:
1131 if (bits(machInst, 7)) {
1132 return new SubImm(machInst, INTREG_SP, INTREG_SP,
1133 bits(machInst, 6, 0) << 2, true);
1134 } else {
1135 return new AddImm(machInst, INTREG_SP, INTREG_SP,
1136 bits(machInst, 6, 0) << 2, true);
1137 }
1138 case 0x1:
1139 return new Cbz(machInst,
1140 (bits(machInst, 9) << 6) |
1141 (bits(machInst, 7, 3) << 1),
1142 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1143 case 0x2:
1144 {
1145 const IntRegIndex rd =
1146 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1147 const IntRegIndex rm =
1148 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1149 switch (bits(machInst, 7, 6)) {
1150 case 0x0:
1151 return new Sxth(machInst, rd, 0, rm);
1152 case 0x1:
1153 return new Sxtb(machInst, rd, 0, rm);
1154 case 0x2:
1155 return new Uxth(machInst, rd, 0, rm);
1156 case 0x3:
1157 return new Uxtb(machInst, rd, 0, rm);
1158 }
1159 }
1138 case 0x2:
1139 {
1140 const IntRegIndex rd =
1141 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1142 const IntRegIndex rm =
1143 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1144 switch (bits(machInst, 7, 6)) {
1145 case 0x0:
1146 return new Sxth(machInst, rd, 0, rm);
1147 case 0x1:
1148 return new Sxtb(machInst, rd, 0, rm);
1149 case 0x2:
1150 return new Uxth(machInst, rd, 0, rm);
1151 case 0x3:
1152 return new Uxtb(machInst, rd, 0, rm);
1153 }
1154 }
1155 case 0x1:
1160 case 0x3:
1161 return new Cbz(machInst,
1162 (bits(machInst, 9) << 6) |
1163 (bits(machInst, 7, 3) << 1),
1164 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1165 case 0x4:
1166 case 0x5:
1167 {
1168 const uint32_t m = bits(machInst, 8);
1169 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
1170 return new LdmStm(machInst, INTREG_SP, false, false, false,
1171 true, false, regList);
1172 }
1173 case 0x6:
1174 {
1175 const uint32_t opBits = bits(machInst, 7, 5);
1176 if (opBits == 2) {
1177 return new Setend(machInst, bits(machInst, 3));
1178 } else if (opBits == 3) {
1179 const bool enable = (bits(machInst, 4) == 0);
1180 const uint32_t mods = (bits(machInst, 2, 0) << 5) |
1181 ((enable ? 1 : 0) << 9);
1182 return new Cps(machInst, mods);
1183 }
1184 }
1156 case 0x3:
1157 return new Cbz(machInst,
1158 (bits(machInst, 9) << 6) |
1159 (bits(machInst, 7, 3) << 1),
1160 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1161 case 0x4:
1162 case 0x5:
1163 {
1164 const uint32_t m = bits(machInst, 8);
1165 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
1166 return new LdmStm(machInst, INTREG_SP, false, false, false,
1167 true, false, regList);
1168 }
1169 case 0x6:
1170 {
1171 const uint32_t opBits = bits(machInst, 7, 5);
1172 if (opBits == 2) {
1173 return new Setend(machInst, bits(machInst, 3));
1174 } else if (opBits == 3) {
1175 const bool enable = (bits(machInst, 4) == 0);
1176 const uint32_t mods = (bits(machInst, 2, 0) << 5) |
1177 ((enable ? 1 : 0) << 9);
1178 return new Cps(machInst, mods);
1179 }
1180 }
1185 case 0x9:
1186 return new Cbnz(machInst,
1187 (bits(machInst, 9) << 6) |
1188 (bits(machInst, 7, 3) << 1),
1189 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1190 case 0xa:
1191 {
1192 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1193 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1194 switch (bits(machInst, 7, 6)) {
1195 case 0x0:
1196 return new Rev(machInst, rd, rm);
1197 case 0x1:
1198 return new Rev16(machInst, rd, rm);
1199 case 0x3:
1200 return new Revsh(machInst, rd, rm);
1201 default:
1202 break;
1203 }
1204 }
1205 break;
1181 case 0xa:
1182 {
1183 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1184 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1185 switch (bits(machInst, 7, 6)) {
1186 case 0x0:
1187 return new Rev(machInst, rd, rm);
1188 case 0x1:
1189 return new Rev16(machInst, rd, rm);
1190 case 0x3:
1191 return new Revsh(machInst, rd, rm);
1192 default:
1193 break;
1194 }
1195 }
1196 break;
1197 case 0x9:
1206 case 0xb:
1207 return new Cbnz(machInst,
1208 (bits(machInst, 9) << 6) |
1209 (bits(machInst, 7, 3) << 1),
1210 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1211 case 0xc:
1212 case 0xd:
1213 {
1214 const uint32_t p = bits(machInst, 8);
1215 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1216 return new LdmStm(machInst, INTREG_SP, true, true, false,
1217 true, true, regList);
1218 }
1219 case 0xe:
1220 return new BkptInst(machInst);
1221 case 0xf:
1222 if (bits(machInst, 3, 0) != 0)
1223 return new ItInst(machInst);
1224 switch (bits(machInst, 7, 4)) {
1225 case 0x0:
1226 return new NopInst(machInst);
1227 case 0x1:
1228 return new YieldInst(machInst);
1229 case 0x2:
1230 return new WfeInst(machInst);
1231 case 0x3:
1232 return new WfiInst(machInst);
1233 case 0x4:
1234 return new SevInst(machInst);
1235 default:
1236 return new WarnUnimplemented("unallocated_hint", machInst);
1237 }
1238 default:
1239 break;
1240 }
1241 return new Unknown(machInst);
1242 }
1243 '''
1244}};
1245
1246def format Thumb32DataProcModImm() {{
1247
1248 def decInst(mnem, dest="rd", op1="rn"):
1249 return '''
1250 if (s) {
1251 return new %(mnem)sImmCc(machInst, %(dest)s,
1252 %(op1)s, imm, rotC);
1253 } else {
1254 return new %(mnem)sImm(machInst, %(dest)s,
1255 %(op1)s, imm, rotC);
1256 }
1257 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1258
1259 decode_block = '''
1260 {
1261 const uint32_t op = bits(machInst, 24, 21);
1262 const bool s = (bits(machInst, 20) == 1);
1263 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1264 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1265 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1266 bits(machInst, 14, 12);
1267 const bool rotC = ctrlImm > 3;
1268 const uint32_t dataImm = bits(machInst, 7, 0);
1269 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1270 switch (op) {
1271 case 0x0:
1272 if (rd == INTREG_PC) {
1273 %(tst)s
1274 } else {
1275 %(and)s
1276 }
1277 case 0x1:
1278 %(bic)s
1279 case 0x2:
1280 if (rn == INTREG_PC) {
1281 %(mov)s
1282 } else {
1283 %(orr)s
1284 }
1285 case 0x3:
1286 if (rn == INTREG_PC) {
1287 %(mvn)s
1288 } else {
1289 %(orn)s
1290 }
1291 case 0x4:
1292 if (rd == INTREG_PC) {
1293 %(teq)s
1294 } else {
1295 %(eor)s
1296 }
1297 case 0x8:
1298 if (rd == INTREG_PC) {
1299 %(cmn)s
1300 } else {
1301 %(add)s
1302 }
1303 case 0xa:
1304 %(adc)s
1305 case 0xb:
1306 %(sbc)s
1307 case 0xd:
1308 if (rd == INTREG_PC) {
1309 %(cmp)s
1310 } else {
1311 %(sub)s
1312 }
1313 case 0xe:
1314 %(rsb)s
1315 default:
1316 return new Unknown(machInst);
1317 }
1318 }
1319 ''' % {
1320 "tst" : decInst("Tst", "INTREG_ZERO"),
1321 "and" : decInst("And"),
1322 "bic" : decInst("Bic"),
1323 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1324 "orr" : decInst("Orr"),
1325 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1326 "orn" : decInst("Orn"),
1327 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1328 "eor" : decInst("Eor"),
1329 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1330 "add" : decInst("Add"),
1331 "adc" : decInst("Adc"),
1332 "sbc" : decInst("Sbc"),
1333 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1334 "sub" : decInst("Sub"),
1335 "rsb" : decInst("Rsb")
1336 }
1337}};
1338
1339def format Thumb32DataProcPlainBin() {{
1340 decode_block = '''
1341 {
1342 const uint32_t op = bits(machInst, 24, 20);
1343 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1344 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1345 switch (op) {
1346 case 0x0:
1347 {
1348 const uint32_t imm = bits(machInst, 7, 0) |
1349 (bits(machInst, 14, 12) << 8) |
1350 (bits(machInst, 26) << 11);
1351 if (rn == 0xf) {
1352 return new AdrImm(machInst, rd, (IntRegIndex)1,
1353 imm, false);
1354 } else {
1355 return new AddImm(machInst, rd, rn, imm, true);
1356 }
1357 }
1358 case 0x4:
1359 {
1360 const uint32_t imm = bits(machInst, 7, 0) |
1361 (bits(machInst, 14, 12) << 8) |
1362 (bits(machInst, 26) << 11) |
1363 (bits(machInst, 19, 16) << 12);
1364 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1365 }
1366 case 0xa:
1367 {
1368 const uint32_t imm = bits(machInst, 7, 0) |
1369 (bits(machInst, 14, 12) << 8) |
1370 (bits(machInst, 26) << 11);
1371 if (rn == 0xf) {
1372 return new AdrImm(machInst, rd, (IntRegIndex)0,
1373 imm, false);
1374 } else {
1375 return new SubImm(machInst, rd, rn, imm, true);
1376 }
1377 }
1378 case 0xc:
1379 {
1380 const uint32_t imm = bits(machInst, 7, 0) |
1381 (bits(machInst, 14, 12) << 8) |
1382 (bits(machInst, 26) << 11) |
1383 (bits(machInst, 19, 16) << 12);
1384 return new MovtImm(machInst, rd, rd, imm, true);
1385 }
1386 case 0x12:
1387 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1388 const uint32_t satImm = bits(machInst, 4, 0);
1389 return new Ssat16(machInst, rd, satImm + 1, rn);
1390 }
1391 // Fall through on purpose...
1392 case 0x10:
1393 {
1394 const uint32_t satImm = bits(machInst, 4, 0);
1395 const uint32_t imm = bits(machInst, 7, 6) |
1396 (bits(machInst, 14, 12) << 2);
1397 const ArmShiftType type =
1398 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1399 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1400 }
1401 case 0x14:
1402 {
1403 const uint32_t lsb = bits(machInst, 7, 6) |
1404 (bits(machInst, 14, 12) << 2);
1405 const uint32_t msb = lsb + bits(machInst, 4, 0);
1406 return new Sbfx(machInst, rd, rn, lsb, msb);
1407 }
1408 case 0x16:
1409 {
1410 const uint32_t lsb = bits(machInst, 7, 6) |
1411 (bits(machInst, 14, 12) << 2);
1412 const uint32_t msb = bits(machInst, 4, 0);
1413 if (rn == 0xf) {
1414 return new Bfc(machInst, rd, rd, lsb, msb);
1415 } else {
1416 return new Bfi(machInst, rd, rn, lsb, msb);
1417 }
1418 }
1419 case 0x1a:
1420 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1421 const uint32_t satImm = bits(machInst, 4, 0);
1422 return new Usat16(machInst, rd, satImm, rn);
1423 }
1424 // Fall through on purpose...
1425 case 0x18:
1426 {
1427 const uint32_t satImm = bits(machInst, 4, 0);
1428 const uint32_t imm = bits(machInst, 7, 6) |
1429 (bits(machInst, 14, 12) << 2);
1430 const ArmShiftType type =
1431 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1432 return new Usat(machInst, rd, satImm, rn, imm, type);
1433 }
1434 case 0x1c:
1435 {
1436 const uint32_t lsb = bits(machInst, 7, 6) |
1437 (bits(machInst, 14, 12) << 2);
1438 const uint32_t msb = lsb + bits(machInst, 4, 0);
1439 return new Ubfx(machInst, rd, rn, lsb, msb);
1440 }
1441 default:
1442 return new Unknown(machInst);
1443 }
1444 }
1445 '''
1446}};
1447
1448def format Thumb32DataProcShiftReg() {{
1449
1450 def decInst(mnem, dest="rd", op1="rn"):
1451 return '''
1452 if (s) {
1453 return new %(mnem)sRegCc(machInst, %(dest)s,
1454 %(op1)s, rm, amt, type);
1455 } else {
1456 return new %(mnem)sReg(machInst, %(dest)s,
1457 %(op1)s, rm, amt, type);
1458 }
1459 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1460
1461 decode_block = '''
1462 {
1463 const uint32_t op = bits(machInst, 24, 21);
1464 const bool s = (bits(machInst, 20) == 1);
1465 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1466 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1467 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1468 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1469 bits(machInst, 7, 6);
1470 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1471 switch (op) {
1472 case 0x0:
1473 if (rd == INTREG_PC) {
1474 %(tst)s
1475 } else {
1476 %(and)s
1477 }
1478 case 0x1:
1479 %(bic)s
1480 case 0x2:
1481 if (rn == INTREG_PC) {
1482 %(mov)s
1483 } else {
1484 %(orr)s
1485 }
1486 case 0x3:
1487 if (rn == INTREG_PC) {
1488 %(mvn)s
1489 } else {
1490 %(orn)s
1491 }
1492 case 0x4:
1493 if (rd == INTREG_PC) {
1494 %(teq)s
1495 } else {
1496 %(eor)s
1497 }
1498 case 0x6:
1499 if (type) {
1500 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1501 } else {
1502 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1503 }
1504 case 0x8:
1505 if (rd == INTREG_PC) {
1506 %(cmn)s
1507 } else {
1508 %(add)s
1509 }
1510 case 0xa:
1511 %(adc)s
1512 case 0xb:
1513 %(sbc)s
1514 case 0xd:
1515 if (rd == INTREG_PC) {
1516 %(cmp)s
1517 } else {
1518 %(sub)s
1519 }
1520 case 0xe:
1521 %(rsb)s
1522 default:
1523 return new Unknown(machInst);
1524 }
1525 }
1526 ''' % {
1527 "tst" : decInst("Tst", "INTREG_ZERO"),
1528 "and" : decInst("And"),
1529 "bic" : decInst("Bic"),
1530 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1531 "orr" : decInst("Orr"),
1532 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1533 "orn" : decInst("Orn"),
1534 "teq" : decInst("Teq", "INTREG_ZERO"),
1535 "eor" : decInst("Eor"),
1536 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1537 "add" : decInst("Add"),
1538 "adc" : decInst("Adc"),
1539 "sbc" : decInst("Sbc"),
1540 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1541 "sub" : decInst("Sub"),
1542 "rsb" : decInst("Rsb")
1543 }
1544}};
1198 case 0xb:
1199 return new Cbnz(machInst,
1200 (bits(machInst, 9) << 6) |
1201 (bits(machInst, 7, 3) << 1),
1202 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1203 case 0xc:
1204 case 0xd:
1205 {
1206 const uint32_t p = bits(machInst, 8);
1207 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1208 return new LdmStm(machInst, INTREG_SP, true, true, false,
1209 true, true, regList);
1210 }
1211 case 0xe:
1212 return new BkptInst(machInst);
1213 case 0xf:
1214 if (bits(machInst, 3, 0) != 0)
1215 return new ItInst(machInst);
1216 switch (bits(machInst, 7, 4)) {
1217 case 0x0:
1218 return new NopInst(machInst);
1219 case 0x1:
1220 return new YieldInst(machInst);
1221 case 0x2:
1222 return new WfeInst(machInst);
1223 case 0x3:
1224 return new WfiInst(machInst);
1225 case 0x4:
1226 return new SevInst(machInst);
1227 default:
1228 return new WarnUnimplemented("unallocated_hint", machInst);
1229 }
1230 default:
1231 break;
1232 }
1233 return new Unknown(machInst);
1234 }
1235 '''
1236}};
1237
1238def format Thumb32DataProcModImm() {{
1239
1240 def decInst(mnem, dest="rd", op1="rn"):
1241 return '''
1242 if (s) {
1243 return new %(mnem)sImmCc(machInst, %(dest)s,
1244 %(op1)s, imm, rotC);
1245 } else {
1246 return new %(mnem)sImm(machInst, %(dest)s,
1247 %(op1)s, imm, rotC);
1248 }
1249 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1250
1251 decode_block = '''
1252 {
1253 const uint32_t op = bits(machInst, 24, 21);
1254 const bool s = (bits(machInst, 20) == 1);
1255 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1256 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1257 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1258 bits(machInst, 14, 12);
1259 const bool rotC = ctrlImm > 3;
1260 const uint32_t dataImm = bits(machInst, 7, 0);
1261 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1262 switch (op) {
1263 case 0x0:
1264 if (rd == INTREG_PC) {
1265 %(tst)s
1266 } else {
1267 %(and)s
1268 }
1269 case 0x1:
1270 %(bic)s
1271 case 0x2:
1272 if (rn == INTREG_PC) {
1273 %(mov)s
1274 } else {
1275 %(orr)s
1276 }
1277 case 0x3:
1278 if (rn == INTREG_PC) {
1279 %(mvn)s
1280 } else {
1281 %(orn)s
1282 }
1283 case 0x4:
1284 if (rd == INTREG_PC) {
1285 %(teq)s
1286 } else {
1287 %(eor)s
1288 }
1289 case 0x8:
1290 if (rd == INTREG_PC) {
1291 %(cmn)s
1292 } else {
1293 %(add)s
1294 }
1295 case 0xa:
1296 %(adc)s
1297 case 0xb:
1298 %(sbc)s
1299 case 0xd:
1300 if (rd == INTREG_PC) {
1301 %(cmp)s
1302 } else {
1303 %(sub)s
1304 }
1305 case 0xe:
1306 %(rsb)s
1307 default:
1308 return new Unknown(machInst);
1309 }
1310 }
1311 ''' % {
1312 "tst" : decInst("Tst", "INTREG_ZERO"),
1313 "and" : decInst("And"),
1314 "bic" : decInst("Bic"),
1315 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1316 "orr" : decInst("Orr"),
1317 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1318 "orn" : decInst("Orn"),
1319 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1320 "eor" : decInst("Eor"),
1321 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1322 "add" : decInst("Add"),
1323 "adc" : decInst("Adc"),
1324 "sbc" : decInst("Sbc"),
1325 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1326 "sub" : decInst("Sub"),
1327 "rsb" : decInst("Rsb")
1328 }
1329}};
1330
1331def format Thumb32DataProcPlainBin() {{
1332 decode_block = '''
1333 {
1334 const uint32_t op = bits(machInst, 24, 20);
1335 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1336 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1337 switch (op) {
1338 case 0x0:
1339 {
1340 const uint32_t imm = bits(machInst, 7, 0) |
1341 (bits(machInst, 14, 12) << 8) |
1342 (bits(machInst, 26) << 11);
1343 if (rn == 0xf) {
1344 return new AdrImm(machInst, rd, (IntRegIndex)1,
1345 imm, false);
1346 } else {
1347 return new AddImm(machInst, rd, rn, imm, true);
1348 }
1349 }
1350 case 0x4:
1351 {
1352 const uint32_t imm = bits(machInst, 7, 0) |
1353 (bits(machInst, 14, 12) << 8) |
1354 (bits(machInst, 26) << 11) |
1355 (bits(machInst, 19, 16) << 12);
1356 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1357 }
1358 case 0xa:
1359 {
1360 const uint32_t imm = bits(machInst, 7, 0) |
1361 (bits(machInst, 14, 12) << 8) |
1362 (bits(machInst, 26) << 11);
1363 if (rn == 0xf) {
1364 return new AdrImm(machInst, rd, (IntRegIndex)0,
1365 imm, false);
1366 } else {
1367 return new SubImm(machInst, rd, rn, imm, true);
1368 }
1369 }
1370 case 0xc:
1371 {
1372 const uint32_t imm = bits(machInst, 7, 0) |
1373 (bits(machInst, 14, 12) << 8) |
1374 (bits(machInst, 26) << 11) |
1375 (bits(machInst, 19, 16) << 12);
1376 return new MovtImm(machInst, rd, rd, imm, true);
1377 }
1378 case 0x12:
1379 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1380 const uint32_t satImm = bits(machInst, 4, 0);
1381 return new Ssat16(machInst, rd, satImm + 1, rn);
1382 }
1383 // Fall through on purpose...
1384 case 0x10:
1385 {
1386 const uint32_t satImm = bits(machInst, 4, 0);
1387 const uint32_t imm = bits(machInst, 7, 6) |
1388 (bits(machInst, 14, 12) << 2);
1389 const ArmShiftType type =
1390 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1391 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1392 }
1393 case 0x14:
1394 {
1395 const uint32_t lsb = bits(machInst, 7, 6) |
1396 (bits(machInst, 14, 12) << 2);
1397 const uint32_t msb = lsb + bits(machInst, 4, 0);
1398 return new Sbfx(machInst, rd, rn, lsb, msb);
1399 }
1400 case 0x16:
1401 {
1402 const uint32_t lsb = bits(machInst, 7, 6) |
1403 (bits(machInst, 14, 12) << 2);
1404 const uint32_t msb = bits(machInst, 4, 0);
1405 if (rn == 0xf) {
1406 return new Bfc(machInst, rd, rd, lsb, msb);
1407 } else {
1408 return new Bfi(machInst, rd, rn, lsb, msb);
1409 }
1410 }
1411 case 0x1a:
1412 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1413 const uint32_t satImm = bits(machInst, 4, 0);
1414 return new Usat16(machInst, rd, satImm, rn);
1415 }
1416 // Fall through on purpose...
1417 case 0x18:
1418 {
1419 const uint32_t satImm = bits(machInst, 4, 0);
1420 const uint32_t imm = bits(machInst, 7, 6) |
1421 (bits(machInst, 14, 12) << 2);
1422 const ArmShiftType type =
1423 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1424 return new Usat(machInst, rd, satImm, rn, imm, type);
1425 }
1426 case 0x1c:
1427 {
1428 const uint32_t lsb = bits(machInst, 7, 6) |
1429 (bits(machInst, 14, 12) << 2);
1430 const uint32_t msb = lsb + bits(machInst, 4, 0);
1431 return new Ubfx(machInst, rd, rn, lsb, msb);
1432 }
1433 default:
1434 return new Unknown(machInst);
1435 }
1436 }
1437 '''
1438}};
1439
1440def format Thumb32DataProcShiftReg() {{
1441
1442 def decInst(mnem, dest="rd", op1="rn"):
1443 return '''
1444 if (s) {
1445 return new %(mnem)sRegCc(machInst, %(dest)s,
1446 %(op1)s, rm, amt, type);
1447 } else {
1448 return new %(mnem)sReg(machInst, %(dest)s,
1449 %(op1)s, rm, amt, type);
1450 }
1451 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1452
1453 decode_block = '''
1454 {
1455 const uint32_t op = bits(machInst, 24, 21);
1456 const bool s = (bits(machInst, 20) == 1);
1457 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1458 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1459 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1460 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1461 bits(machInst, 7, 6);
1462 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1463 switch (op) {
1464 case 0x0:
1465 if (rd == INTREG_PC) {
1466 %(tst)s
1467 } else {
1468 %(and)s
1469 }
1470 case 0x1:
1471 %(bic)s
1472 case 0x2:
1473 if (rn == INTREG_PC) {
1474 %(mov)s
1475 } else {
1476 %(orr)s
1477 }
1478 case 0x3:
1479 if (rn == INTREG_PC) {
1480 %(mvn)s
1481 } else {
1482 %(orn)s
1483 }
1484 case 0x4:
1485 if (rd == INTREG_PC) {
1486 %(teq)s
1487 } else {
1488 %(eor)s
1489 }
1490 case 0x6:
1491 if (type) {
1492 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1493 } else {
1494 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1495 }
1496 case 0x8:
1497 if (rd == INTREG_PC) {
1498 %(cmn)s
1499 } else {
1500 %(add)s
1501 }
1502 case 0xa:
1503 %(adc)s
1504 case 0xb:
1505 %(sbc)s
1506 case 0xd:
1507 if (rd == INTREG_PC) {
1508 %(cmp)s
1509 } else {
1510 %(sub)s
1511 }
1512 case 0xe:
1513 %(rsb)s
1514 default:
1515 return new Unknown(machInst);
1516 }
1517 }
1518 ''' % {
1519 "tst" : decInst("Tst", "INTREG_ZERO"),
1520 "and" : decInst("And"),
1521 "bic" : decInst("Bic"),
1522 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1523 "orr" : decInst("Orr"),
1524 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1525 "orn" : decInst("Orn"),
1526 "teq" : decInst("Teq", "INTREG_ZERO"),
1527 "eor" : decInst("Eor"),
1528 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1529 "add" : decInst("Add"),
1530 "adc" : decInst("Adc"),
1531 "sbc" : decInst("Sbc"),
1532 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1533 "sub" : decInst("Sub"),
1534 "rsb" : decInst("Rsb")
1535 }
1536}};