Deleted Added
sdiff udiff text old ( 7212:746657ee59a2 ) new ( 7213:beadb1dc1be6 )
full compact
1// Copyright (c) 2010 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder. You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Gabe Black
37
38def format ArmDataProcReg() {{
39 pclr = '''
40 return new %(className)ssRegPclr(machInst, %(dest)s,
41 %(op1)s, rm, imm5,
42 type);
43 '''
44 instDecode = '''
45 case %(opcode)#x:
46 if (immShift) {
47 if (setCc) {
48 if (%(dest)s == INTREG_PC) {
49 %(pclr)s
50 } else {
51 return new %(className)sRegCc(machInst, %(dest)s,
52 %(op1)s, rm, imm5, type);
53 }
54 } else {
55 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
56 rm, imm5, type);
57 }
58 } else {
59 if (setCc) {
60 return new %(className)sRegRegCc(machInst, %(dest)s,
61 %(op1)s, rm, rs, type);
62 } else {
63 return new %(className)sRegReg(machInst, %(dest)s,
64 %(op1)s, rm, rs, type);
65 }
66 }
67 break;
68 '''
69
70 def instCode(opcode, mnem, useDest = True, useOp1 = True):
71 global pclr
72 if useDest:
73 dest = "rd"
74 else:
75 dest = "INTREG_ZERO"
76 if useOp1:
77 op1 = "rn"
78 else:
79 op1 = "INTREG_ZERO"
80 global instDecode, pclrCode
81 substDict = { "className": mnem.capitalize(),
82 "opcode": opcode,
83 "dest": dest,
84 "op1": op1 }
85 if useDest:
86 substDict["pclr"] = pclr % substDict
87 else:
88 substDict["pclr"] = ""
89 return instDecode % substDict
90
91 decode_block = '''
92 {
93 const bool immShift = (bits(machInst, 4) == 0);
94 const bool setCc = (bits(machInst, 20) == 1);
95 const uint32_t imm5 = bits(machInst, 11, 7);
96 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
97 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
98 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
99 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
100 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
101 switch (OPCODE) {
102 '''
103 decode_block += instCode(0x0, "and")
104 decode_block += instCode(0x1, "eor")
105 decode_block += instCode(0x2, "sub")
106 decode_block += instCode(0x3, "rsb")
107 decode_block += instCode(0x4, "add")
108 decode_block += instCode(0x5, "adc")
109 decode_block += instCode(0x6, "sbc")
110 decode_block += instCode(0x7, "rsc")
111 decode_block += instCode(0x8, "tst", useDest = False)
112 decode_block += instCode(0x9, "teq", useDest = False)
113 decode_block += instCode(0xa, "cmp", useDest = False)
114 decode_block += instCode(0xb, "cmn", useDest = False)
115 decode_block += instCode(0xc, "orr")
116 decode_block += instCode(0xd, "mov", useOp1 = False)
117 decode_block += instCode(0xe, "bic")
118 decode_block += instCode(0xf, "mvn", useOp1 = False)
119 decode_block += '''
120 default:
121 return new Unknown(machInst);
122 }
123 }
124 '''
125}};
126
127def format ArmPackUnpackSatReverse() {{
128 decode_block = '''
129 {
130 const uint32_t op1 = bits(machInst, 22, 20);
131 const uint32_t a = bits(machInst, 19, 16);
132 const uint32_t op2 = bits(machInst, 7, 5);
133 if (bits(op2, 0) == 0) {
134 if (op1 == 0) {
135 return new WarnUnimplemented("pkh", machInst);
136 } else if (bits(op1, 2, 1) == 1) {
137 return new WarnUnimplemented("ssat", machInst);
138 } else if (bits(op1, 2, 1) == 3) {
139 return new WarnUnimplemented("usat", machInst);
140 }
141 return new Unknown(machInst);
142 }
143 switch (op1) {
144 case 0x0:
145 if (op2 == 0x3) {
146 if (a == 0xf) {
147 return new WarnUnimplemented("sxtb16", machInst);
148 } else {
149 return new WarnUnimplemented("sxtab16", machInst);
150 }
151 } else if (op2 == 0x5) {
152 return new WarnUnimplemented("sel", machInst);
153 }
154 break;
155 case 0x2:
156 if (op2 == 0x1) {
157 return new WarnUnimplemented("ssat16", machInst);
158 } else if (op2 == 0x3) {
159 if (a == 0xf) {
160 return new WarnUnimplemented("sxtb", machInst);
161 } else {
162 return new WarnUnimplemented("sxtab", machInst);
163 }
164 }
165 break;
166 case 0x3:
167 if (op2 == 0x1) {
168 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
169 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
170 return new Rev(machInst, rd, rm);
171 } else if (op2 == 0x3) {
172 if (a == 0xf) {
173 return new WarnUnimplemented("sxth", machInst);
174 } else {
175 return new WarnUnimplemented("sxtah", machInst);
176 }
177 } else if (op2 == 0x5) {
178 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
179 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
180 return new Rev16(machInst, rd, rm);
181 }
182 break;
183 case 0x4:
184 if (op2 == 0x3) {
185 if (a == 0xf) {
186 return new WarnUnimplemented("uxtb16", machInst);
187 } else {
188 return new WarnUnimplemented("uxtab16", machInst);
189 }
190 }
191 break;
192 case 0x6:
193 if (op2 == 0x1) {
194 return new WarnUnimplemented("usat16", machInst);
195 } else if (op2 == 0x3) {
196 if (a == 0xf) {
197 return new WarnUnimplemented("uxtb", machInst);
198 } else {
199 return new WarnUnimplemented("uxtab", machInst);
200 }
201 }
202 break;
203 case 0x7:
204 if (op2 == 0x1) {
205 return new WarnUnimplemented("rbit", machInst);
206 } else if (op2 == 0x3) {
207 if (a == 0xf) {
208 return new WarnUnimplemented("uxth", machInst);
209 } else {
210 return new WarnUnimplemented("uxtah", machInst);
211 }
212 } else if (op2 == 0x5) {
213 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
214 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
215 return new Revsh(machInst, rd, rm);
216 }
217 break;
218 }
219 return new Unknown(machInst);
220 }
221 '''
222}};
223
224def format ArmParallelAddSubtract() {{
225 decode_block='''
226 {
227 const uint32_t op1 = bits(machInst, 21, 20);
228 const uint32_t op2 = bits(machInst, 7, 5);
229 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
230 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
231 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
232 if (bits(machInst, 22) == 0) {
233 switch (op1) {
234 case 0x1:
235 switch (op2) {
236 case 0x0:
237 return new WarnUnimplemented("sadd16", machInst);
238 case 0x1:
239 return new WarnUnimplemented("sasx", machInst);
240 case 0x2:
241 return new WarnUnimplemented("ssax", machInst);
242 case 0x3:
243 return new WarnUnimplemented("ssub16", machInst);
244 case 0x4:
245 return new WarnUnimplemented("sadd8", machInst);
246 case 0x7:
247 return new WarnUnimplemented("ssub8", machInst);
248 }
249 break;
250 case 0x2:
251 switch (op2) {
252 case 0x0:
253 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
254 case 0x1:
255 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
256 case 0x2:
257 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
258 case 0x3:
259 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
260 case 0x4:
261 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
262 case 0x7:
263 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
264 }
265 break;
266 case 0x3:
267 switch (op2) {
268 case 0x0:
269 return new WarnUnimplemented("shadd16", machInst);
270 case 0x1:
271 return new WarnUnimplemented("shasx", machInst);
272 case 0x2:
273 return new WarnUnimplemented("shsax", machInst);
274 case 0x3:
275 return new WarnUnimplemented("shsub16", machInst);
276 case 0x4:
277 return new WarnUnimplemented("shadd8", machInst);
278 case 0x7:
279 return new WarnUnimplemented("shsub8", machInst);
280 }
281 break;
282 }
283 } else {
284 switch (op1) {
285 case 0x1:
286 switch (op2) {
287 case 0x0:
288 return new WarnUnimplemented("uadd16", machInst);
289 case 0x1:
290 return new WarnUnimplemented("uasx", machInst);
291 case 0x2:
292 return new WarnUnimplemented("usax", machInst);
293 case 0x3:
294 return new WarnUnimplemented("usub16", machInst);
295 case 0x4:
296 return new WarnUnimplemented("uadd8", machInst);
297 case 0x7:
298 return new WarnUnimplemented("usub8", machInst);
299 }
300 break;
301 case 0x2:
302 switch (op2) {
303 case 0x0:
304 return new WarnUnimplemented("uqadd16", machInst);
305 case 0x1:
306 return new WarnUnimplemented("uqasx", machInst);
307 case 0x2:
308 return new WarnUnimplemented("uqsax", machInst);
309 case 0x3:
310 return new WarnUnimplemented("uqsub16", machInst);
311 case 0x4:
312 return new WarnUnimplemented("uqadd8", machInst);
313 case 0x7:
314 return new WarnUnimplemented("uqsub8", machInst);
315 }
316 break;
317 case 0x3:
318 switch (op2) {
319 case 0x0:
320 return new WarnUnimplemented("uhadd16", machInst);
321 case 0x1:
322 return new WarnUnimplemented("uhasx", machInst);
323 case 0x2:
324 return new WarnUnimplemented("uhsax", machInst);
325 case 0x3:
326 return new WarnUnimplemented("uhsub16", machInst);
327 case 0x4:
328 return new WarnUnimplemented("uhadd8", machInst);
329 case 0x7:
330 return new WarnUnimplemented("uhsub8", machInst);
331 }
332 break;
333 }
334 }
335 return new Unknown(machInst);
336 }
337 '''
338}};
339
340def format ArmDataProcImm() {{
341 pclr = '''
342 return new %(className)ssImmPclr(machInst, %(dest)s,
343 %(op1)s, imm, false);
344 '''
345 adr = '''
346 return new AdrImm(machInst, %(dest)s, %(add)s,
347 imm, false);
348 '''
349 instDecode = '''
350 case %(opcode)#x:
351 if (setCc) {
352 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
353 %(pclr)s
354 } else {
355 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
356 imm, rotC);
357 }
358 } else {
359 if (%(adrInst)s && %(op1)s == INTREG_PC) {
360 %(adr)s
361 } else {
362 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
363 imm, rotC);
364 }
365 }
366 break;
367 '''
368
369 def instCode(opcode, mnem, useDest = True, useOp1 = True):
370 global instDecode, pclr, adr
371 if useDest:
372 dest = "rd"
373 else:
374 dest = "INTREG_ZERO"
375 if useOp1:
376 op1 = "rn"
377 else:
378 op1 = "INTREG_ZERO"
379 substDict = { "className": mnem.capitalize(),
380 "opcode": opcode,
381 "dest": dest,
382 "op1": op1,
383 "adr": "",
384 "adrInst": "false" }
385 if useDest:
386 substDict["pclrInst"] = "true"
387 substDict["pclr"] = pclr % substDict
388 else:
389 substDict["pclrInst"] = "false"
390 substDict["pclr"] = ""
391 return instDecode % substDict
392
393 def adrCode(opcode, mnem, add="1"):
394 global instDecode, pclr, adr
395 substDict = { "className": mnem.capitalize(),
396 "opcode": opcode,
397 "dest": "rd",
398 "op1": "rn",
399 "add": add,
400 "pclrInst": "true",
401 "adrInst": "true" }
402 substDict["pclr"] = pclr % substDict
403 substDict["adr"] = adr % substDict
404 return instDecode % substDict
405
406 decode_block = '''
407 {
408 const bool setCc = (bits(machInst, 20) == 1);
409 const uint32_t unrotated = bits(machInst, 7, 0);
410 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
411 const bool rotC = (rotation != 0);
412 const uint32_t imm = rotate_imm(unrotated, rotation);
413 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
414 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
415 switch (OPCODE) {
416 '''
417 decode_block += instCode(0x0, "and")
418 decode_block += instCode(0x1, "eor")
419 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
420 decode_block += instCode(0x3, "rsb")
421 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
422 decode_block += instCode(0x5, "adc")
423 decode_block += instCode(0x6, "sbc")
424 decode_block += instCode(0x7, "rsc")
425 decode_block += instCode(0x8, "tst", useDest = False)
426 decode_block += instCode(0x9, "teq", useDest = False)
427 decode_block += instCode(0xa, "cmp", useDest = False)
428 decode_block += instCode(0xb, "cmn", useDest = False)
429 decode_block += instCode(0xc, "orr")
430 decode_block += instCode(0xd, "mov", useOp1 = False)
431 decode_block += instCode(0xe, "bic")
432 decode_block += instCode(0xf, "mvn", useOp1 = False)
433 decode_block += '''
434 default:
435 return new Unknown(machInst);
436 }
437 }
438 '''
439}};
440
441def format ArmSatAddSub() {{
442 decode_block = '''
443 {
444 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
445 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
446 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
447 switch (OPCODE) {
448 case 0x8:
449 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
450 case 0x9:
451 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
452 case 0xa:
453 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
454 case 0xb:
455 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
456 default:
457 return new Unknown(machInst);
458 }
459 }
460 '''
461}};
462
463def format Thumb16ShiftAddSubMoveCmp() {{
464 decode_block = '''
465 {
466 const uint32_t imm5 = bits(machInst, 10, 6);
467 const uint32_t imm3 = bits(machInst, 8, 6);
468 const uint32_t imm8 = bits(machInst, 7, 0);
469 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
470 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
471 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
472 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
473 switch (bits(machInst, 13, 11)) {
474 case 0x0: // lsl
475 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
476 case 0x1: // lsr
477 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
478 case 0x2: // asr
479 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
480 case 0x3:
481 switch (bits(machInst, 10, 9)) {
482 case 0x0:
483 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
484 case 0x1:
485 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
486 case 0x2:
487 return new AddImmCc(machInst, rd, rn, imm3, true);
488 case 0x3:
489 return new SubImmCc(machInst, rd, rn, imm3, true);
490 }
491 case 0x4:
492 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
493 case 0x5:
494 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
495 case 0x6:
496 return new AddImmCc(machInst, rd8, rd8, imm8, true);
497 case 0x7:
498 return new SubImmCc(machInst, rd8, rd8, imm8, true);
499 }
500 }
501 '''
502}};
503
504def format Thumb16DataProcessing() {{
505 decode_block = '''
506 {
507 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
508 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
509 switch (bits(machInst, 9, 6)) {
510 case 0x0:
511 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
512 case 0x1:
513 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
514 case 0x2: //lsl
515 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
516 case 0x3: //lsr
517 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
518 case 0x4: //asr
519 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
520 case 0x5:
521 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
522 case 0x6:
523 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
524 case 0x7: // ror
525 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
526 case 0x8:
527 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
528 case 0x9:
529 return new RsbImmCc(machInst, rdn, rm, 0, true);
530 case 0xa:
531 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
532 case 0xb:
533 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
534 case 0xc:
535 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
536 case 0xd:
537 return new MulCc(machInst, rdn, rm, rdn);
538 case 0xe:
539 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
540 case 0xf:
541 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
542 }
543 }
544 '''
545}};
546
547def format Thumb16SpecDataAndBx() {{
548 decode_block = '''
549 {
550 const IntRegIndex rdn =
551 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
552 (bits(machInst, 7) << 3));
553 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
554 switch (bits(machInst, 9, 8)) {
555 case 0x0:
556 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
557 case 0x1:
558 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
559 case 0x2:
560 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
561 case 0x3:
562 if (bits(machInst, 7) == 0) {
563 return new BxReg(machInst,
564 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
565 COND_UC);
566 } else {
567 return new BlxReg(machInst,
568 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
569 COND_UC);
570 }
571 }
572 }
573 '''
574}};
575
576def format Thumb16Adr() {{
577 decode_block = '''
578 {
579 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
580 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
581 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
582 }
583 '''
584}};
585
586def format Thumb16AddSp() {{
587 decode_block = '''
588 {
589 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
590 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
591 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
592 }
593 '''
594}};
595
596def format Thumb16Misc() {{
597 decode_block = '''
598 {
599 switch (bits(machInst, 11, 8)) {
600 case 0x0:
601 if (bits(machInst, 7)) {
602 return new SubImm(machInst, INTREG_SP, INTREG_SP,
603 bits(machInst, 6, 0) << 2, true);
604 } else {
605 return new AddImm(machInst, INTREG_SP, INTREG_SP,
606 bits(machInst, 6, 0) << 2, true);
607 }
608 case 0x1:
609 return new Cbz(machInst,
610 (bits(machInst, 9) << 6) |
611 (bits(machInst, 7, 3) << 1),
612 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
613 case 0x2:
614 switch (bits(machInst, 7, 6)) {
615 case 0x0:
616 return new WarnUnimplemented("sxth", machInst);
617 case 0x1:
618 return new WarnUnimplemented("sxtb", machInst);
619 case 0x2:
620 return new WarnUnimplemented("uxth", machInst);
621 case 0x3:
622 return new WarnUnimplemented("uxtb", machInst);
623 }
624 case 0x3:
625 return new Cbz(machInst,
626 (bits(machInst, 9) << 6) |
627 (bits(machInst, 7, 3) << 1),
628 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
629 case 0x4:
630 case 0x5:
631 {
632 const uint32_t m = bits(machInst, 8);
633 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
634 return new LdmStm(machInst, INTREG_SP, false, false, false,
635 true, false, regList);
636 }
637 case 0x6:
638 {
639 const uint32_t opBits = bits(machInst, 7, 5);
640 if (opBits == 2) {
641 return new WarnUnimplemented("setend", machInst);
642 } else if (opBits == 3) {
643 return new WarnUnimplemented("cps", machInst);
644 }
645 }
646 case 0x9:
647 return new Cbnz(machInst,
648 (bits(machInst, 9) << 6) |
649 (bits(machInst, 7, 3) << 1),
650 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
651 case 0xa:
652 {
653 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
654 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
655 switch (bits(machInst, 7, 6)) {
656 case 0x0:
657 return new Rev(machInst, rd, rm);
658 case 0x1:
659 return new Rev16(machInst, rd, rm);
660 case 0x3:
661 return new Revsh(machInst, rd, rm);
662 default:
663 break;
664 }
665 }
666 break;
667 case 0xb:
668 return new Cbnz(machInst,
669 (bits(machInst, 9) << 6) |
670 (bits(machInst, 7, 3) << 1),
671 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
672 case 0xc:
673 case 0xd:
674 {
675 const uint32_t p = bits(machInst, 8);
676 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
677 return new LdmStm(machInst, INTREG_SP, true, true, false,
678 true, true, regList);
679 }
680 case 0xe:
681 return new WarnUnimplemented("bkpt", machInst);
682 case 0xf:
683 if (bits(machInst, 3, 0) != 0)
684 return new WarnUnimplemented("it", machInst);
685 switch (bits(machInst, 7, 4)) {
686 case 0x0:
687 return new WarnUnimplemented("nop", machInst);
688 case 0x1:
689 return new WarnUnimplemented("yield", machInst);
690 case 0x2:
691 return new WarnUnimplemented("wfe", machInst);
692 case 0x3:
693 return new WarnUnimplemented("wfi", machInst);
694 case 0x4:
695 return new WarnUnimplemented("sev", machInst);
696 default:
697 return new WarnUnimplemented("unallocated_hint", machInst);
698 }
699 default:
700 break;
701 }
702 return new Unknown(machInst);
703 }
704 '''
705}};
706
707def format Thumb32DataProcModImm() {{
708
709 def decInst(mnem, dest="rd", op1="rn"):
710 return '''
711 if (s) {
712 return new %(mnem)sImmCc(machInst, %(dest)s,
713 %(op1)s, imm, rotC);
714 } else {
715 return new %(mnem)sImm(machInst, %(dest)s,
716 %(op1)s, imm, rotC);
717 }
718 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
719
720 decode_block = '''
721 {
722 const uint32_t op = bits(machInst, 24, 21);
723 const bool s = (bits(machInst, 20) == 1);
724 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
725 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
726 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
727 bits(machInst, 14, 12);
728 const bool rotC = ctrlImm > 3;
729 const uint32_t dataImm = bits(machInst, 7, 0);
730 const uint32_t imm = modified_imm(ctrlImm, dataImm);
731 switch (op) {
732 case 0x0:
733 if (rd == INTREG_PC) {
734 %(tst)s
735 } else {
736 %(and)s
737 }
738 case 0x1:
739 %(bic)s
740 case 0x2:
741 if (rn == INTREG_PC) {
742 %(mov)s
743 } else {
744 %(orr)s
745 }
746 case 0x3:
747 if (rn == INTREG_PC) {
748 %(mvn)s
749 } else {
750 %(orn)s
751 }
752 case 0x4:
753 if (rd == INTREG_PC) {
754 %(teq)s
755 } else {
756 %(eor)s
757 }
758 case 0x8:
759 if (rd == INTREG_PC) {
760 %(cmn)s
761 } else {
762 %(add)s
763 }
764 case 0xa:
765 %(adc)s
766 case 0xb:
767 %(sbc)s
768 case 0xd:
769 if (rd == INTREG_PC) {
770 %(cmp)s
771 } else {
772 %(sub)s
773 }
774 case 0xe:
775 %(rsb)s
776 default:
777 return new Unknown(machInst);
778 }
779 }
780 ''' % {
781 "tst" : decInst("Tst", "INTREG_ZERO"),
782 "and" : decInst("And"),
783 "bic" : decInst("Bic"),
784 "mov" : decInst("Mov", op1="INTREG_ZERO"),
785 "orr" : decInst("Orr"),
786 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
787 "orn" : decInst("Orn"),
788 "teq" : decInst("Teq", dest="INTREG_ZERO"),
789 "eor" : decInst("Eor"),
790 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
791 "add" : decInst("Add"),
792 "adc" : decInst("Adc"),
793 "sbc" : decInst("Sbc"),
794 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
795 "sub" : decInst("Sub"),
796 "rsb" : decInst("Rsb")
797 }
798}};
799
800def format Thumb32DataProcPlainBin() {{
801 decode_block = '''
802 {
803 const uint32_t op = bits(machInst, 24, 20);
804 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
805 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
806 switch (op) {
807 case 0x0:
808 {
809 const uint32_t imm = bits(machInst, 7, 0) |
810 (bits(machInst, 14, 12) << 8) |
811 (bits(machInst, 26) << 11);
812 if (rn == 0xf) {
813 return new AdrImm(machInst, rd, (IntRegIndex)1,
814 imm, false);
815 } else {
816 return new AddImm(machInst, rd, rn, imm, true);
817 }
818 }
819 case 0x4:
820 {
821 const uint32_t imm = bits(machInst, 7, 0) |
822 (bits(machInst, 14, 12) << 8) |
823 (bits(machInst, 26) << 11) |
824 (bits(machInst, 19, 16) << 12);
825 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
826 }
827 case 0xa:
828 {
829 const uint32_t imm = bits(machInst, 7, 0) |
830 (bits(machInst, 14, 12) << 8) |
831 (bits(machInst, 26) << 11);
832 if (rn == 0xf) {
833 return new AdrImm(machInst, rd, (IntRegIndex)0,
834 imm, false);
835 } else {
836 return new SubImm(machInst, rd, rn, imm, true);
837 }
838 }
839 case 0xc:
840 {
841 const uint32_t imm = bits(machInst, 7, 0) |
842 (bits(machInst, 14, 12) << 8) |
843 (bits(machInst, 26) << 11) |
844 (bits(machInst, 19, 16) << 12);
845 return new MovtImm(machInst, rd, rd, imm, true);
846 }
847 case 0x12:
848 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
849 return new WarnUnimplemented("ssat16", machInst);
850 }
851 // Fall through on purpose...
852 case 0x10:
853 return new WarnUnimplemented("ssat", machInst);
854 case 0x14:
855 return new WarnUnimplemented("sbfx", machInst);
856 case 0x16:
857 if (rn == 0xf) {
858 return new WarnUnimplemented("bfc", machInst);
859 } else {
860 return new WarnUnimplemented("bfi", machInst);
861 }
862 case 0x1a:
863 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
864 return new WarnUnimplemented("usat16", machInst);
865 }
866 // Fall through on purpose...
867 case 0x18:
868 return new WarnUnimplemented("usat", machInst);
869 case 0x1c:
870 return new WarnUnimplemented("ubfx", machInst);
871 default:
872 return new Unknown(machInst);
873 }
874 }
875 '''
876}};
877
878def format Thumb32DataProcShiftReg() {{
879
880 def decInst(mnem, dest="rd", op1="rn"):
881 return '''
882 if (s) {
883 return new %(mnem)sRegCc(machInst, %(dest)s,
884 %(op1)s, rm, amt, type);
885 } else {
886 return new %(mnem)sReg(machInst, %(dest)s,
887 %(op1)s, rm, amt, type);
888 }
889 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
890
891 decode_block = '''
892 {
893 const uint32_t op = bits(machInst, 24, 21);
894 const bool s = (bits(machInst, 20) == 1);
895 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
896 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
897 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
898 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
899 bits(machInst, 7, 6);
900 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
901 switch (op) {
902 case 0x0:
903 if (rd == INTREG_PC) {
904 %(tst)s
905 } else {
906 %(and)s
907 }
908 case 0x1:
909 %(bic)s
910 case 0x2:
911 if (rn == INTREG_PC) {
912 %(mov)s
913 } else {
914 %(orr)s
915 }
916 case 0x3:
917 if (rn == INTREG_PC) {
918 %(mvn)s
919 } else {
920 %(orn)s
921 }
922 case 0x4:
923 if (rd == INTREG_PC) {
924 %(teq)s
925 } else {
926 %(eor)s
927 }
928 case 0x6:
929 return new WarnUnimplemented("pkh", machInst);
930 case 0x8:
931 if (rd == INTREG_PC) {
932 %(cmn)s
933 } else {
934 %(add)s
935 }
936 case 0xa:
937 %(adc)s
938 case 0xb:
939 %(sbc)s
940 case 0xd:
941 if (rd == INTREG_PC) {
942 %(cmp)s
943 } else {
944 %(sub)s
945 }
946 case 0xe:
947 %(rsb)s
948 default:
949 return new Unknown(machInst);
950 }
951 }
952 ''' % {
953 "tst" : decInst("Tst", "INTREG_ZERO"),
954 "and" : decInst("And"),
955 "bic" : decInst("Bic"),
956 "mov" : decInst("Mov", op1="INTREG_ZERO"),
957 "orr" : decInst("Orr"),
958 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
959 "orn" : decInst("Orn"),
960 "teq" : decInst("Teq", "INTREG_ZERO"),
961 "eor" : decInst("Eor"),
962 "cmn" : decInst("Cmn", "INTREG_ZERO"),
963 "add" : decInst("Add"),
964 "adc" : decInst("Adc"),
965 "sbc" : decInst("Sbc"),
966 "cmp" : decInst("Cmp", "INTREG_ZERO"),
967 "sub" : decInst("Sub"),
968 "rsb" : decInst("Rsb")
969 }
970}};