data.isa (7316:bb190cb8ee69) data.isa (7408:ee6949c5bb5b)
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
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 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, 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 }
856 case 0x1: // lsr
860 case 0x1: // lsr
857 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, 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 }
858 case 0x2: // asr
866 case 0x2: // asr
859 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, 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 }
860 case 0x3:
861 switch (bits(machInst, 10, 9)) {
862 case 0x0:
872 case 0x3:
873 switch (bits(machInst, 10, 9)) {
874 case 0x0:
863 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
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 }
864 case 0x1:
880 case 0x1:
865 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
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 }
866 case 0x2:
886 case 0x2:
867 return new AddImmCc(machInst, rd, rn, imm3, true);
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 }
868 case 0x3:
892 case 0x3:
869 return new SubImmCc(machInst, rd, rn, imm3, true);
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 }
870 }
871 case 0x4:
898 }
899 case 0x4:
872 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
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 }
873 case 0x5:
874 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
875 case 0x6:
905 case 0x5:
906 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
907 case 0x6:
876 return new AddImmCc(machInst, rd8, rd8, imm8, true);
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 }
877 case 0x7:
913 case 0x7:
878 return new SubImmCc(machInst, rd8, rd8, imm8, true);
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 }
879 }
880 }
881 '''
882}};
883
884def format Thumb16DataProcessing() {{
885 decode_block = '''
886 {
887 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
888 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
889 switch (bits(machInst, 9, 6)) {
890 case 0x0:
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:
891 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
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 }
892 case 0x1:
936 case 0x1:
893 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
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 }
894 case 0x2: //lsl
942 case 0x2: //lsl
895 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, 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 }
896 case 0x3: //lsr
950 case 0x3: //lsr
897 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, 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 }
898 case 0x4: //asr
958 case 0x4: //asr
899 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, 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 }
900 case 0x5:
966 case 0x5:
901 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
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 }
902 case 0x6:
972 case 0x6:
903 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
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 }
904 case 0x7: // ror
978 case 0x7: // ror
905 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, 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 }
906 case 0x8:
907 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
908 case 0x9:
986 case 0x8:
987 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
988 case 0x9:
909 return new RsbImmCc(machInst, rdn, rm, 0, true);
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 }
910 case 0xa:
911 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
912 case 0xb:
913 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
914 case 0xc:
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:
915 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
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 }
916 case 0xd:
1004 case 0xd:
917 return new MulCc(machInst, rdn, rm, rdn);
1005 if (machInst.itstateMask) {
1006 return new Mul(machInst, rdn, rm, rdn);
1007 } else {
1008 return new MulCc(machInst, rdn, rm, rdn);
1009 }
918 case 0xe:
1010 case 0xe:
919 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
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 }
920 case 0xf:
1016 case 0xf:
921 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
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 }
922 }
923 }
924 '''
925}};
926
927def format Thumb16SpecDataAndBx() {{
928 decode_block = '''
929 {
930 const IntRegIndex rdn =
931 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
932 (bits(machInst, 7) << 3));
933 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
934 switch (bits(machInst, 9, 8)) {
935 case 0x0:
936 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
937 case 0x1:
938 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
939 case 0x2:
940 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
941 case 0x3:
942 if (bits(machInst, 7) == 0) {
943 return new BxReg(machInst,
944 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
945 COND_UC);
946 } else {
947 return new BlxReg(machInst,
948 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
949 COND_UC);
950 }
951 }
952 }
953 '''
954}};
955
956def format Thumb16Adr() {{
957 decode_block = '''
958 {
959 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
960 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
961 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
962 }
963 '''
964}};
965
966def format Thumb16AddSp() {{
967 decode_block = '''
968 {
969 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
970 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
971 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
972 }
973 '''
974}};
975
976def format Thumb16Misc() {{
977 decode_block = '''
978 {
979 switch (bits(machInst, 11, 8)) {
980 case 0x0:
981 if (bits(machInst, 7)) {
982 return new SubImm(machInst, INTREG_SP, INTREG_SP,
983 bits(machInst, 6, 0) << 2, true);
984 } else {
985 return new AddImm(machInst, INTREG_SP, INTREG_SP,
986 bits(machInst, 6, 0) << 2, true);
987 }
988 case 0x1:
989 return new Cbz(machInst,
990 (bits(machInst, 9) << 6) |
991 (bits(machInst, 7, 3) << 1),
992 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
993 case 0x2:
994 {
995 const IntRegIndex rd =
996 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
997 const IntRegIndex rm =
998 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
999 switch (bits(machInst, 7, 6)) {
1000 case 0x0:
1001 return new Sxth(machInst, rd, 0, rm);
1002 case 0x1:
1003 return new Sxtb(machInst, rd, 0, rm);
1004 case 0x2:
1005 return new Uxth(machInst, rd, 0, rm);
1006 case 0x3:
1007 return new Uxtb(machInst, rd, 0, rm);
1008 }
1009 }
1010 case 0x3:
1011 return new Cbz(machInst,
1012 (bits(machInst, 9) << 6) |
1013 (bits(machInst, 7, 3) << 1),
1014 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1015 case 0x4:
1016 case 0x5:
1017 {
1018 const uint32_t m = bits(machInst, 8);
1019 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
1020 return new LdmStm(machInst, INTREG_SP, false, false, false,
1021 true, false, regList);
1022 }
1023 case 0x6:
1024 {
1025 const uint32_t opBits = bits(machInst, 7, 5);
1026 if (opBits == 2) {
1027 return new Setend(machInst, bits(machInst, 3));
1028 } else if (opBits == 3) {
1029 const bool enable = (bits(machInst, 4) == 0);
1030 const uint32_t mods = (bits(machInst, 2, 0) << 5) |
1031 ((enable ? 1 : 0) << 9);
1032 return new Cps(machInst, mods);
1033 }
1034 }
1035 case 0x9:
1036 return new Cbnz(machInst,
1037 (bits(machInst, 9) << 6) |
1038 (bits(machInst, 7, 3) << 1),
1039 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1040 case 0xa:
1041 {
1042 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1043 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1044 switch (bits(machInst, 7, 6)) {
1045 case 0x0:
1046 return new Rev(machInst, rd, rm);
1047 case 0x1:
1048 return new Rev16(machInst, rd, rm);
1049 case 0x3:
1050 return new Revsh(machInst, rd, rm);
1051 default:
1052 break;
1053 }
1054 }
1055 break;
1056 case 0xb:
1057 return new Cbnz(machInst,
1058 (bits(machInst, 9) << 6) |
1059 (bits(machInst, 7, 3) << 1),
1060 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1061 case 0xc:
1062 case 0xd:
1063 {
1064 const uint32_t p = bits(machInst, 8);
1065 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1066 return new LdmStm(machInst, INTREG_SP, true, true, false,
1067 true, true, regList);
1068 }
1069 case 0xe:
1070 return new WarnUnimplemented("bkpt", machInst);
1071 case 0xf:
1072 if (bits(machInst, 3, 0) != 0)
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 Thumb16Misc() {{
1077 decode_block = '''
1078 {
1079 switch (bits(machInst, 11, 8)) {
1080 case 0x0:
1081 if (bits(machInst, 7)) {
1082 return new SubImm(machInst, INTREG_SP, INTREG_SP,
1083 bits(machInst, 6, 0) << 2, true);
1084 } else {
1085 return new AddImm(machInst, INTREG_SP, INTREG_SP,
1086 bits(machInst, 6, 0) << 2, true);
1087 }
1088 case 0x1:
1089 return new Cbz(machInst,
1090 (bits(machInst, 9) << 6) |
1091 (bits(machInst, 7, 3) << 1),
1092 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1093 case 0x2:
1094 {
1095 const IntRegIndex rd =
1096 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1097 const IntRegIndex rm =
1098 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1099 switch (bits(machInst, 7, 6)) {
1100 case 0x0:
1101 return new Sxth(machInst, rd, 0, rm);
1102 case 0x1:
1103 return new Sxtb(machInst, rd, 0, rm);
1104 case 0x2:
1105 return new Uxth(machInst, rd, 0, rm);
1106 case 0x3:
1107 return new Uxtb(machInst, rd, 0, rm);
1108 }
1109 }
1110 case 0x3:
1111 return new Cbz(machInst,
1112 (bits(machInst, 9) << 6) |
1113 (bits(machInst, 7, 3) << 1),
1114 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1115 case 0x4:
1116 case 0x5:
1117 {
1118 const uint32_t m = bits(machInst, 8);
1119 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
1120 return new LdmStm(machInst, INTREG_SP, false, false, false,
1121 true, false, regList);
1122 }
1123 case 0x6:
1124 {
1125 const uint32_t opBits = bits(machInst, 7, 5);
1126 if (opBits == 2) {
1127 return new Setend(machInst, bits(machInst, 3));
1128 } else if (opBits == 3) {
1129 const bool enable = (bits(machInst, 4) == 0);
1130 const uint32_t mods = (bits(machInst, 2, 0) << 5) |
1131 ((enable ? 1 : 0) << 9);
1132 return new Cps(machInst, mods);
1133 }
1134 }
1135 case 0x9:
1136 return new Cbnz(machInst,
1137 (bits(machInst, 9) << 6) |
1138 (bits(machInst, 7, 3) << 1),
1139 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1140 case 0xa:
1141 {
1142 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1143 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1144 switch (bits(machInst, 7, 6)) {
1145 case 0x0:
1146 return new Rev(machInst, rd, rm);
1147 case 0x1:
1148 return new Rev16(machInst, rd, rm);
1149 case 0x3:
1150 return new Revsh(machInst, rd, rm);
1151 default:
1152 break;
1153 }
1154 }
1155 break;
1156 case 0xb:
1157 return new Cbnz(machInst,
1158 (bits(machInst, 9) << 6) |
1159 (bits(machInst, 7, 3) << 1),
1160 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1161 case 0xc:
1162 case 0xd:
1163 {
1164 const uint32_t p = bits(machInst, 8);
1165 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1166 return new LdmStm(machInst, INTREG_SP, true, true, false,
1167 true, true, regList);
1168 }
1169 case 0xe:
1170 return new WarnUnimplemented("bkpt", machInst);
1171 case 0xf:
1172 if (bits(machInst, 3, 0) != 0)
1073 return new WarnUnimplemented("it", machInst);
1173 return new ItInst(machInst);
1074 switch (bits(machInst, 7, 4)) {
1075 case 0x0:
1076 return new NopInst(machInst);
1077 case 0x1:
1078 return new WarnUnimplemented("yield", machInst);
1079 case 0x2:
1080 return new WarnUnimplemented("wfe", machInst);
1081 case 0x3:
1082 return new WarnUnimplemented("wfi", machInst);
1083 case 0x4:
1084 return new WarnUnimplemented("sev", machInst);
1085 default:
1086 return new WarnUnimplemented("unallocated_hint", machInst);
1087 }
1088 default:
1089 break;
1090 }
1091 return new Unknown(machInst);
1092 }
1093 '''
1094}};
1095
1096def format Thumb32DataProcModImm() {{
1097
1098 def decInst(mnem, dest="rd", op1="rn"):
1099 return '''
1100 if (s) {
1101 return new %(mnem)sImmCc(machInst, %(dest)s,
1102 %(op1)s, imm, rotC);
1103 } else {
1104 return new %(mnem)sImm(machInst, %(dest)s,
1105 %(op1)s, imm, rotC);
1106 }
1107 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1108
1109 decode_block = '''
1110 {
1111 const uint32_t op = bits(machInst, 24, 21);
1112 const bool s = (bits(machInst, 20) == 1);
1113 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1114 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1115 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1116 bits(machInst, 14, 12);
1117 const bool rotC = ctrlImm > 3;
1118 const uint32_t dataImm = bits(machInst, 7, 0);
1119 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1120 switch (op) {
1121 case 0x0:
1122 if (rd == INTREG_PC) {
1123 %(tst)s
1124 } else {
1125 %(and)s
1126 }
1127 case 0x1:
1128 %(bic)s
1129 case 0x2:
1130 if (rn == INTREG_PC) {
1131 %(mov)s
1132 } else {
1133 %(orr)s
1134 }
1135 case 0x3:
1136 if (rn == INTREG_PC) {
1137 %(mvn)s
1138 } else {
1139 %(orn)s
1140 }
1141 case 0x4:
1142 if (rd == INTREG_PC) {
1143 %(teq)s
1144 } else {
1145 %(eor)s
1146 }
1147 case 0x8:
1148 if (rd == INTREG_PC) {
1149 %(cmn)s
1150 } else {
1151 %(add)s
1152 }
1153 case 0xa:
1154 %(adc)s
1155 case 0xb:
1156 %(sbc)s
1157 case 0xd:
1158 if (rd == INTREG_PC) {
1159 %(cmp)s
1160 } else {
1161 %(sub)s
1162 }
1163 case 0xe:
1164 %(rsb)s
1165 default:
1166 return new Unknown(machInst);
1167 }
1168 }
1169 ''' % {
1170 "tst" : decInst("Tst", "INTREG_ZERO"),
1171 "and" : decInst("And"),
1172 "bic" : decInst("Bic"),
1173 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1174 "orr" : decInst("Orr"),
1175 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1176 "orn" : decInst("Orn"),
1177 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1178 "eor" : decInst("Eor"),
1179 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1180 "add" : decInst("Add"),
1181 "adc" : decInst("Adc"),
1182 "sbc" : decInst("Sbc"),
1183 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1184 "sub" : decInst("Sub"),
1185 "rsb" : decInst("Rsb")
1186 }
1187}};
1188
1189def format Thumb32DataProcPlainBin() {{
1190 decode_block = '''
1191 {
1192 const uint32_t op = bits(machInst, 24, 20);
1193 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1194 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1195 switch (op) {
1196 case 0x0:
1197 {
1198 const uint32_t imm = bits(machInst, 7, 0) |
1199 (bits(machInst, 14, 12) << 8) |
1200 (bits(machInst, 26) << 11);
1201 if (rn == 0xf) {
1202 return new AdrImm(machInst, rd, (IntRegIndex)1,
1203 imm, false);
1204 } else {
1205 return new AddImm(machInst, rd, rn, imm, true);
1206 }
1207 }
1208 case 0x4:
1209 {
1210 const uint32_t imm = bits(machInst, 7, 0) |
1211 (bits(machInst, 14, 12) << 8) |
1212 (bits(machInst, 26) << 11) |
1213 (bits(machInst, 19, 16) << 12);
1214 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1215 }
1216 case 0xa:
1217 {
1218 const uint32_t imm = bits(machInst, 7, 0) |
1219 (bits(machInst, 14, 12) << 8) |
1220 (bits(machInst, 26) << 11);
1221 if (rn == 0xf) {
1222 return new AdrImm(machInst, rd, (IntRegIndex)0,
1223 imm, false);
1224 } else {
1225 return new SubImm(machInst, rd, rn, imm, true);
1226 }
1227 }
1228 case 0xc:
1229 {
1230 const uint32_t imm = bits(machInst, 7, 0) |
1231 (bits(machInst, 14, 12) << 8) |
1232 (bits(machInst, 26) << 11) |
1233 (bits(machInst, 19, 16) << 12);
1234 return new MovtImm(machInst, rd, rd, imm, true);
1235 }
1236 case 0x12:
1237 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1238 const uint32_t satImm = bits(machInst, 4, 0);
1239 return new Ssat16(machInst, rd, satImm + 1, rn);
1240 }
1241 // Fall through on purpose...
1242 case 0x10:
1243 {
1244 const uint32_t satImm = bits(machInst, 4, 0);
1245 const uint32_t imm = bits(machInst, 7, 6) |
1246 (bits(machInst, 14, 12) << 2);
1247 const ArmShiftType type =
1248 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1249 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1250 }
1251 case 0x14:
1252 {
1253 const uint32_t lsb = bits(machInst, 7, 6) |
1254 (bits(machInst, 14, 12) << 2);
1255 const uint32_t msb = lsb + bits(machInst, 4, 0);
1256 return new Sbfx(machInst, rd, rn, lsb, msb);
1257 }
1258 case 0x16:
1259 {
1260 const uint32_t lsb = bits(machInst, 7, 6) |
1261 (bits(machInst, 14, 12) << 2);
1262 const uint32_t msb = bits(machInst, 4, 0);
1263 if (rn == 0xf) {
1264 return new Bfc(machInst, rd, rd, lsb, msb);
1265 } else {
1266 return new Bfi(machInst, rd, rn, lsb, msb);
1267 }
1268 }
1269 case 0x1a:
1270 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1271 const uint32_t satImm = bits(machInst, 4, 0);
1272 return new Usat16(machInst, rd, satImm, rn);
1273 }
1274 // Fall through on purpose...
1275 case 0x18:
1276 {
1277 const uint32_t satImm = bits(machInst, 4, 0);
1278 const uint32_t imm = bits(machInst, 7, 6) |
1279 (bits(machInst, 14, 12) << 2);
1280 const ArmShiftType type =
1281 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1282 return new Usat(machInst, rd, satImm, rn, imm, type);
1283 }
1284 case 0x1c:
1285 {
1286 const uint32_t lsb = bits(machInst, 7, 6) |
1287 (bits(machInst, 14, 12) << 2);
1288 const uint32_t msb = lsb + bits(machInst, 4, 0);
1289 return new Ubfx(machInst, rd, rn, lsb, msb);
1290 }
1291 default:
1292 return new Unknown(machInst);
1293 }
1294 }
1295 '''
1296}};
1297
1298def format Thumb32DataProcShiftReg() {{
1299
1300 def decInst(mnem, dest="rd", op1="rn"):
1301 return '''
1302 if (s) {
1303 return new %(mnem)sRegCc(machInst, %(dest)s,
1304 %(op1)s, rm, amt, type);
1305 } else {
1306 return new %(mnem)sReg(machInst, %(dest)s,
1307 %(op1)s, rm, amt, type);
1308 }
1309 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1310
1311 decode_block = '''
1312 {
1313 const uint32_t op = bits(machInst, 24, 21);
1314 const bool s = (bits(machInst, 20) == 1);
1315 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1316 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1317 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1318 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1319 bits(machInst, 7, 6);
1320 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1321 switch (op) {
1322 case 0x0:
1323 if (rd == INTREG_PC) {
1324 %(tst)s
1325 } else {
1326 %(and)s
1327 }
1328 case 0x1:
1329 %(bic)s
1330 case 0x2:
1331 if (rn == INTREG_PC) {
1332 %(mov)s
1333 } else {
1334 %(orr)s
1335 }
1336 case 0x3:
1337 if (rn == INTREG_PC) {
1338 %(mvn)s
1339 } else {
1340 %(orn)s
1341 }
1342 case 0x4:
1343 if (rd == INTREG_PC) {
1344 %(teq)s
1345 } else {
1346 %(eor)s
1347 }
1348 case 0x6:
1349 if (type) {
1350 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1351 } else {
1352 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1353 }
1354 case 0x8:
1355 if (rd == INTREG_PC) {
1356 %(cmn)s
1357 } else {
1358 %(add)s
1359 }
1360 case 0xa:
1361 %(adc)s
1362 case 0xb:
1363 %(sbc)s
1364 case 0xd:
1365 if (rd == INTREG_PC) {
1366 %(cmp)s
1367 } else {
1368 %(sub)s
1369 }
1370 case 0xe:
1371 %(rsb)s
1372 default:
1373 return new Unknown(machInst);
1374 }
1375 }
1376 ''' % {
1377 "tst" : decInst("Tst", "INTREG_ZERO"),
1378 "and" : decInst("And"),
1379 "bic" : decInst("Bic"),
1380 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1381 "orr" : decInst("Orr"),
1382 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1383 "orn" : decInst("Orn"),
1384 "teq" : decInst("Teq", "INTREG_ZERO"),
1385 "eor" : decInst("Eor"),
1386 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1387 "add" : decInst("Add"),
1388 "adc" : decInst("Adc"),
1389 "sbc" : decInst("Sbc"),
1390 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1391 "sub" : decInst("Sub"),
1392 "rsb" : decInst("Rsb")
1393 }
1394}};
1174 switch (bits(machInst, 7, 4)) {
1175 case 0x0:
1176 return new NopInst(machInst);
1177 case 0x1:
1178 return new WarnUnimplemented("yield", machInst);
1179 case 0x2:
1180 return new WarnUnimplemented("wfe", machInst);
1181 case 0x3:
1182 return new WarnUnimplemented("wfi", machInst);
1183 case 0x4:
1184 return new WarnUnimplemented("sev", machInst);
1185 default:
1186 return new WarnUnimplemented("unallocated_hint", machInst);
1187 }
1188 default:
1189 break;
1190 }
1191 return new Unknown(machInst);
1192 }
1193 '''
1194}};
1195
1196def format Thumb32DataProcModImm() {{
1197
1198 def decInst(mnem, dest="rd", op1="rn"):
1199 return '''
1200 if (s) {
1201 return new %(mnem)sImmCc(machInst, %(dest)s,
1202 %(op1)s, imm, rotC);
1203 } else {
1204 return new %(mnem)sImm(machInst, %(dest)s,
1205 %(op1)s, imm, rotC);
1206 }
1207 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1208
1209 decode_block = '''
1210 {
1211 const uint32_t op = bits(machInst, 24, 21);
1212 const bool s = (bits(machInst, 20) == 1);
1213 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1214 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1215 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1216 bits(machInst, 14, 12);
1217 const bool rotC = ctrlImm > 3;
1218 const uint32_t dataImm = bits(machInst, 7, 0);
1219 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1220 switch (op) {
1221 case 0x0:
1222 if (rd == INTREG_PC) {
1223 %(tst)s
1224 } else {
1225 %(and)s
1226 }
1227 case 0x1:
1228 %(bic)s
1229 case 0x2:
1230 if (rn == INTREG_PC) {
1231 %(mov)s
1232 } else {
1233 %(orr)s
1234 }
1235 case 0x3:
1236 if (rn == INTREG_PC) {
1237 %(mvn)s
1238 } else {
1239 %(orn)s
1240 }
1241 case 0x4:
1242 if (rd == INTREG_PC) {
1243 %(teq)s
1244 } else {
1245 %(eor)s
1246 }
1247 case 0x8:
1248 if (rd == INTREG_PC) {
1249 %(cmn)s
1250 } else {
1251 %(add)s
1252 }
1253 case 0xa:
1254 %(adc)s
1255 case 0xb:
1256 %(sbc)s
1257 case 0xd:
1258 if (rd == INTREG_PC) {
1259 %(cmp)s
1260 } else {
1261 %(sub)s
1262 }
1263 case 0xe:
1264 %(rsb)s
1265 default:
1266 return new Unknown(machInst);
1267 }
1268 }
1269 ''' % {
1270 "tst" : decInst("Tst", "INTREG_ZERO"),
1271 "and" : decInst("And"),
1272 "bic" : decInst("Bic"),
1273 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1274 "orr" : decInst("Orr"),
1275 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1276 "orn" : decInst("Orn"),
1277 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1278 "eor" : decInst("Eor"),
1279 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1280 "add" : decInst("Add"),
1281 "adc" : decInst("Adc"),
1282 "sbc" : decInst("Sbc"),
1283 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1284 "sub" : decInst("Sub"),
1285 "rsb" : decInst("Rsb")
1286 }
1287}};
1288
1289def format Thumb32DataProcPlainBin() {{
1290 decode_block = '''
1291 {
1292 const uint32_t op = bits(machInst, 24, 20);
1293 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1294 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1295 switch (op) {
1296 case 0x0:
1297 {
1298 const uint32_t imm = bits(machInst, 7, 0) |
1299 (bits(machInst, 14, 12) << 8) |
1300 (bits(machInst, 26) << 11);
1301 if (rn == 0xf) {
1302 return new AdrImm(machInst, rd, (IntRegIndex)1,
1303 imm, false);
1304 } else {
1305 return new AddImm(machInst, rd, rn, imm, true);
1306 }
1307 }
1308 case 0x4:
1309 {
1310 const uint32_t imm = bits(machInst, 7, 0) |
1311 (bits(machInst, 14, 12) << 8) |
1312 (bits(machInst, 26) << 11) |
1313 (bits(machInst, 19, 16) << 12);
1314 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1315 }
1316 case 0xa:
1317 {
1318 const uint32_t imm = bits(machInst, 7, 0) |
1319 (bits(machInst, 14, 12) << 8) |
1320 (bits(machInst, 26) << 11);
1321 if (rn == 0xf) {
1322 return new AdrImm(machInst, rd, (IntRegIndex)0,
1323 imm, false);
1324 } else {
1325 return new SubImm(machInst, rd, rn, imm, true);
1326 }
1327 }
1328 case 0xc:
1329 {
1330 const uint32_t imm = bits(machInst, 7, 0) |
1331 (bits(machInst, 14, 12) << 8) |
1332 (bits(machInst, 26) << 11) |
1333 (bits(machInst, 19, 16) << 12);
1334 return new MovtImm(machInst, rd, rd, imm, true);
1335 }
1336 case 0x12:
1337 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1338 const uint32_t satImm = bits(machInst, 4, 0);
1339 return new Ssat16(machInst, rd, satImm + 1, rn);
1340 }
1341 // Fall through on purpose...
1342 case 0x10:
1343 {
1344 const uint32_t satImm = bits(machInst, 4, 0);
1345 const uint32_t imm = bits(machInst, 7, 6) |
1346 (bits(machInst, 14, 12) << 2);
1347 const ArmShiftType type =
1348 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1349 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1350 }
1351 case 0x14:
1352 {
1353 const uint32_t lsb = bits(machInst, 7, 6) |
1354 (bits(machInst, 14, 12) << 2);
1355 const uint32_t msb = lsb + bits(machInst, 4, 0);
1356 return new Sbfx(machInst, rd, rn, lsb, msb);
1357 }
1358 case 0x16:
1359 {
1360 const uint32_t lsb = bits(machInst, 7, 6) |
1361 (bits(machInst, 14, 12) << 2);
1362 const uint32_t msb = bits(machInst, 4, 0);
1363 if (rn == 0xf) {
1364 return new Bfc(machInst, rd, rd, lsb, msb);
1365 } else {
1366 return new Bfi(machInst, rd, rn, lsb, msb);
1367 }
1368 }
1369 case 0x1a:
1370 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1371 const uint32_t satImm = bits(machInst, 4, 0);
1372 return new Usat16(machInst, rd, satImm, rn);
1373 }
1374 // Fall through on purpose...
1375 case 0x18:
1376 {
1377 const uint32_t satImm = bits(machInst, 4, 0);
1378 const uint32_t imm = bits(machInst, 7, 6) |
1379 (bits(machInst, 14, 12) << 2);
1380 const ArmShiftType type =
1381 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1382 return new Usat(machInst, rd, satImm, rn, imm, type);
1383 }
1384 case 0x1c:
1385 {
1386 const uint32_t lsb = bits(machInst, 7, 6) |
1387 (bits(machInst, 14, 12) << 2);
1388 const uint32_t msb = lsb + bits(machInst, 4, 0);
1389 return new Ubfx(machInst, rd, rn, lsb, msb);
1390 }
1391 default:
1392 return new Unknown(machInst);
1393 }
1394 }
1395 '''
1396}};
1397
1398def format Thumb32DataProcShiftReg() {{
1399
1400 def decInst(mnem, dest="rd", op1="rn"):
1401 return '''
1402 if (s) {
1403 return new %(mnem)sRegCc(machInst, %(dest)s,
1404 %(op1)s, rm, amt, type);
1405 } else {
1406 return new %(mnem)sReg(machInst, %(dest)s,
1407 %(op1)s, rm, amt, type);
1408 }
1409 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1410
1411 decode_block = '''
1412 {
1413 const uint32_t op = bits(machInst, 24, 21);
1414 const bool s = (bits(machInst, 20) == 1);
1415 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1416 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1417 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1418 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1419 bits(machInst, 7, 6);
1420 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1421 switch (op) {
1422 case 0x0:
1423 if (rd == INTREG_PC) {
1424 %(tst)s
1425 } else {
1426 %(and)s
1427 }
1428 case 0x1:
1429 %(bic)s
1430 case 0x2:
1431 if (rn == INTREG_PC) {
1432 %(mov)s
1433 } else {
1434 %(orr)s
1435 }
1436 case 0x3:
1437 if (rn == INTREG_PC) {
1438 %(mvn)s
1439 } else {
1440 %(orn)s
1441 }
1442 case 0x4:
1443 if (rd == INTREG_PC) {
1444 %(teq)s
1445 } else {
1446 %(eor)s
1447 }
1448 case 0x6:
1449 if (type) {
1450 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1451 } else {
1452 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1453 }
1454 case 0x8:
1455 if (rd == INTREG_PC) {
1456 %(cmn)s
1457 } else {
1458 %(add)s
1459 }
1460 case 0xa:
1461 %(adc)s
1462 case 0xb:
1463 %(sbc)s
1464 case 0xd:
1465 if (rd == INTREG_PC) {
1466 %(cmp)s
1467 } else {
1468 %(sub)s
1469 }
1470 case 0xe:
1471 %(rsb)s
1472 default:
1473 return new Unknown(machInst);
1474 }
1475 }
1476 ''' % {
1477 "tst" : decInst("Tst", "INTREG_ZERO"),
1478 "and" : decInst("And"),
1479 "bic" : decInst("Bic"),
1480 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1481 "orr" : decInst("Orr"),
1482 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1483 "orn" : decInst("Orn"),
1484 "teq" : decInst("Teq", "INTREG_ZERO"),
1485 "eor" : decInst("Eor"),
1486 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1487 "add" : decInst("Add"),
1488 "adc" : decInst("Adc"),
1489 "sbc" : decInst("Sbc"),
1490 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1491 "sub" : decInst("Sub"),
1492 "rsb" : decInst("Rsb")
1493 }
1494}};