Deleted Added
sdiff udiff text old ( 7195:ccd270981263 ) new ( 7201:253d16049184 )
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 ArmParallelAddSubtract() {{
128 decode_block='''
129 {
130 const uint32_t op1 = bits(machInst, 21, 20);
131 const uint32_t op2 = bits(machInst, 7, 5);
132 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
133 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
134 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
135 if (bits(machInst, 22) == 0) {
136 switch (op1) {
137 case 0x1:
138 switch (op2) {
139 case 0x0:
140 return new WarnUnimplemented("sadd16", machInst);
141 case 0x1:
142 return new WarnUnimplemented("sasx", machInst);
143 case 0x2:
144 return new WarnUnimplemented("ssax", machInst);
145 case 0x3:
146 return new WarnUnimplemented("ssub16", machInst);
147 case 0x4:
148 return new WarnUnimplemented("sadd8", machInst);
149 case 0x7:
150 return new WarnUnimplemented("ssub8", machInst);
151 }
152 break;
153 case 0x2:
154 switch (op2) {
155 case 0x0:
156 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
157 case 0x1:
158 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
159 case 0x2:
160 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
161 case 0x3:
162 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
163 case 0x4:
164 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
165 case 0x7:
166 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
167 }
168 break;
169 case 0x3:
170 switch (op2) {
171 case 0x0:
172 return new WarnUnimplemented("shadd16", machInst);
173 case 0x1:
174 return new WarnUnimplemented("shasx", machInst);
175 case 0x2:
176 return new WarnUnimplemented("shsax", machInst);
177 case 0x3:
178 return new WarnUnimplemented("shsub16", machInst);
179 case 0x4:
180 return new WarnUnimplemented("shadd8", machInst);
181 case 0x7:
182 return new WarnUnimplemented("shsub8", machInst);
183 }
184 break;
185 }
186 } else {
187 switch (op1) {
188 case 0x1:
189 switch (op2) {
190 case 0x0:
191 return new WarnUnimplemented("uadd16", machInst);
192 case 0x1:
193 return new WarnUnimplemented("uasx", machInst);
194 case 0x2:
195 return new WarnUnimplemented("usax", machInst);
196 case 0x3:
197 return new WarnUnimplemented("usub16", machInst);
198 case 0x4:
199 return new WarnUnimplemented("uadd8", machInst);
200 case 0x7:
201 return new WarnUnimplemented("usub8", machInst);
202 }
203 break;
204 case 0x2:
205 switch (op2) {
206 case 0x0:
207 return new WarnUnimplemented("uqadd16", machInst);
208 case 0x1:
209 return new WarnUnimplemented("uqasx", machInst);
210 case 0x2:
211 return new WarnUnimplemented("uqsax", machInst);
212 case 0x3:
213 return new WarnUnimplemented("uqsub16", machInst);
214 case 0x4:
215 return new WarnUnimplemented("uqadd8", machInst);
216 case 0x7:
217 return new WarnUnimplemented("uqsub8", machInst);
218 }
219 break;
220 case 0x3:
221 switch (op2) {
222 case 0x0:
223 return new WarnUnimplemented("uhadd16", machInst);
224 case 0x1:
225 return new WarnUnimplemented("uhasx", machInst);
226 case 0x2:
227 return new WarnUnimplemented("uhsax", machInst);
228 case 0x3:
229 return new WarnUnimplemented("uhsub16", machInst);
230 case 0x4:
231 return new WarnUnimplemented("uhadd8", machInst);
232 case 0x7:
233 return new WarnUnimplemented("uhsub8", machInst);
234 }
235 break;
236 }
237 }
238 return new Unknown(machInst);
239 }
240 '''
241}};
242
243def format ArmDataProcImm() {{
244 pclr = '''
245 return new %(className)ssImmPclr(machInst, %(dest)s,
246 %(op1)s, imm, false);
247 '''
248 adr = '''
249 return new AdrImm(machInst, %(dest)s, %(add)s,
250 imm, false);
251 '''
252 instDecode = '''
253 case %(opcode)#x:
254 if (setCc) {
255 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
256 %(pclr)s
257 } else {
258 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
259 imm, rotC);
260 }
261 } else {
262 if (%(adrInst)s && %(op1)s == INTREG_PC) {
263 %(adr)s
264 } else {
265 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
266 imm, rotC);
267 }
268 }
269 break;
270 '''
271
272 def instCode(opcode, mnem, useDest = True, useOp1 = True):
273 global instDecode, pclr, adr
274 if useDest:
275 dest = "rd"
276 else:
277 dest = "INTREG_ZERO"
278 if useOp1:
279 op1 = "rn"
280 else:
281 op1 = "INTREG_ZERO"
282 substDict = { "className": mnem.capitalize(),
283 "opcode": opcode,
284 "dest": dest,
285 "op1": op1,
286 "adr": "",
287 "adrInst": "false" }
288 if useDest:
289 substDict["pclrInst"] = "true"
290 substDict["pclr"] = pclr % substDict
291 else:
292 substDict["pclrInst"] = "false"
293 substDict["pclr"] = ""
294 return instDecode % substDict
295
296 def adrCode(opcode, mnem, add="1"):
297 global instDecode, pclr, adr
298 substDict = { "className": mnem.capitalize(),
299 "opcode": opcode,
300 "dest": "rd",
301 "op1": "rn",
302 "add": add,
303 "pclrInst": "true",
304 "adrInst": "true" }
305 substDict["pclr"] = pclr % substDict
306 substDict["adr"] = adr % substDict
307 return instDecode % substDict
308
309 decode_block = '''
310 {
311 const bool setCc = (bits(machInst, 20) == 1);
312 const uint32_t unrotated = bits(machInst, 7, 0);
313 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
314 const bool rotC = (rotation != 0);
315 const uint32_t imm = rotate_imm(unrotated, rotation);
316 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
317 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
318 switch (OPCODE) {
319 '''
320 decode_block += instCode(0x0, "and")
321 decode_block += instCode(0x1, "eor")
322 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
323 decode_block += instCode(0x3, "rsb")
324 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
325 decode_block += instCode(0x5, "adc")
326 decode_block += instCode(0x6, "sbc")
327 decode_block += instCode(0x7, "rsc")
328 decode_block += instCode(0x8, "tst", useDest = False)
329 decode_block += instCode(0x9, "teq", useDest = False)
330 decode_block += instCode(0xa, "cmp", useDest = False)
331 decode_block += instCode(0xb, "cmn", useDest = False)
332 decode_block += instCode(0xc, "orr")
333 decode_block += instCode(0xd, "mov", useOp1 = False)
334 decode_block += instCode(0xe, "bic")
335 decode_block += instCode(0xf, "mvn", useOp1 = False)
336 decode_block += '''
337 default:
338 return new Unknown(machInst);
339 }
340 }
341 '''
342}};
343
344def format ArmSatAddSub() {{
345 decode_block = '''
346 {
347 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
348 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
349 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
350 switch (OPCODE) {
351 case 0x8:
352 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
353 case 0x9:
354 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
355 case 0xa:
356 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
357 case 0xb:
358 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
359 default:
360 return new Unknown(machInst);
361 }
362 }
363 '''
364}};
365
366def format Thumb16ShiftAddSubMoveCmp() {{
367 decode_block = '''
368 {
369 const uint32_t imm5 = bits(machInst, 10, 6);
370 const uint32_t imm3 = bits(machInst, 8, 6);
371 const uint32_t imm8 = bits(machInst, 7, 0);
372 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
373 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
374 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
375 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
376 switch (bits(machInst, 13, 11)) {
377 case 0x0: // lsl
378 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
379 case 0x1: // lsr
380 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
381 case 0x2: // asr
382 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
383 case 0x3:
384 switch (bits(machInst, 10, 9)) {
385 case 0x0:
386 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
387 case 0x1:
388 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
389 case 0x2:
390 return new AddImmCc(machInst, rd, rn, imm3, true);
391 case 0x3:
392 return new SubImmCc(machInst, rd, rn, imm3, true);
393 }
394 case 0x4:
395 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
396 case 0x5:
397 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
398 case 0x6:
399 return new AddImmCc(machInst, rd8, rd8, imm8, true);
400 case 0x7:
401 return new SubImmCc(machInst, rd8, rd8, imm8, true);
402 }
403 }
404 '''
405}};
406
407def format Thumb16DataProcessing() {{
408 decode_block = '''
409 {
410 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
411 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
412 switch (bits(machInst, 9, 6)) {
413 case 0x0:
414 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
415 case 0x1:
416 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
417 case 0x2: //lsl
418 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
419 case 0x3: //lsr
420 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
421 case 0x4: //asr
422 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
423 case 0x5:
424 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
425 case 0x6:
426 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
427 case 0x7: // ror
428 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
429 case 0x8:
430 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
431 case 0x9:
432 return new RsbImmCc(machInst, rdn, rm, 0, true);
433 case 0xa:
434 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
435 case 0xb:
436 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
437 case 0xc:
438 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
439 case 0xd:
440 return new MulCc(machInst, rdn, rm, rdn);
441 case 0xe:
442 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
443 case 0xf:
444 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
445 }
446 }
447 '''
448}};
449
450def format Thumb16SpecDataAndBx() {{
451 decode_block = '''
452 {
453 const IntRegIndex rdn =
454 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
455 (bits(machInst, 7) << 3));
456 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
457 switch (bits(machInst, 9, 8)) {
458 case 0x0:
459 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
460 case 0x1:
461 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
462 case 0x2:
463 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
464 case 0x3:
465 if (bits(machInst, 7) == 0) {
466 return new BxReg(machInst,
467 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
468 COND_UC);
469 } else {
470 return new BlxReg(machInst,
471 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
472 COND_UC);
473 }
474 }
475 }
476 '''
477}};
478
479def format Thumb16Adr() {{
480 decode_block = '''
481 {
482 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
483 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
484 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
485 }
486 '''
487}};
488
489def format Thumb16AddSp() {{
490 decode_block = '''
491 {
492 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
493 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
494 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
495 }
496 '''
497}};
498
499def format Thumb16Misc() {{
500 decode_block = '''
501 {
502 switch (bits(machInst, 11, 8)) {
503 case 0x0:
504 if (bits(machInst, 7)) {
505 return new SubImm(machInst, INTREG_SP, INTREG_SP,
506 bits(machInst, 6, 0) << 2, true);
507 } else {
508 return new AddImm(machInst, INTREG_SP, INTREG_SP,
509 bits(machInst, 6, 0) << 2, true);
510 }
511 case 0x1:
512 return new Cbz(machInst,
513 (bits(machInst, 9) << 6) |
514 (bits(machInst, 7, 3) << 1),
515 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
516 case 0x2:
517 switch (bits(machInst, 7, 6)) {
518 case 0x0:
519 return new WarnUnimplemented("sxth", machInst);
520 case 0x1:
521 return new WarnUnimplemented("sxtb", machInst);
522 case 0x2:
523 return new WarnUnimplemented("uxth", machInst);
524 case 0x3:
525 return new WarnUnimplemented("uxtb", machInst);
526 }
527 case 0x3:
528 return new Cbz(machInst,
529 (bits(machInst, 9) << 6) |
530 (bits(machInst, 7, 3) << 1),
531 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
532 case 0x4:
533 case 0x5:
534 return new WarnUnimplemented("push", machInst);
535 case 0x6:
536 {
537 const uint32_t opBits = bits(machInst, 7, 5);
538 if (opBits == 2) {
539 return new WarnUnimplemented("setend", machInst);
540 } else if (opBits == 3) {
541 return new WarnUnimplemented("cps", machInst);
542 }
543 }
544 case 0x9:
545 return new Cbnz(machInst,
546 (bits(machInst, 9) << 6) |
547 (bits(machInst, 7, 3) << 1),
548 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
549 case 0xa:
550 switch (bits(machInst, 7, 5)) {
551 case 0x0:
552 return new WarnUnimplemented("rev", machInst);
553 case 0x1:
554 return new WarnUnimplemented("rev16", machInst);
555 case 0x3:
556 return new WarnUnimplemented("revsh", machInst);
557 default:
558 break;
559 }
560 break;
561 case 0xb:
562 return new Cbnz(machInst,
563 (bits(machInst, 9) << 6) |
564 (bits(machInst, 7, 3) << 1),
565 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
566 case 0xc:
567 case 0xd:
568 return new WarnUnimplemented("pop", machInst);
569 case 0xe:
570 return new WarnUnimplemented("bkpt", machInst);
571 case 0xf:
572 if (bits(machInst, 3, 0) != 0)
573 return new WarnUnimplemented("it", machInst);
574 switch (bits(machInst, 7, 4)) {
575 case 0x0:
576 return new WarnUnimplemented("nop", machInst);
577 case 0x1:
578 return new WarnUnimplemented("yield", machInst);
579 case 0x2:
580 return new WarnUnimplemented("wfe", machInst);
581 case 0x3:
582 return new WarnUnimplemented("wfi", machInst);
583 case 0x4:
584 return new WarnUnimplemented("sev", machInst);
585 default:
586 return new WarnUnimplemented("unallocated_hint", machInst);
587 }
588 default:
589 break;
590 }
591 return new Unknown(machInst);
592 }
593 '''
594}};
595
596def format Thumb32DataProcModImm() {{
597
598 def decInst(mnem, dest="rd", op1="rn"):
599 return '''
600 if (s) {
601 return new %(mnem)sImmCc(machInst, %(dest)s,
602 %(op1)s, imm, rotC);
603 } else {
604 return new %(mnem)sImm(machInst, %(dest)s,
605 %(op1)s, imm, rotC);
606 }
607 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
608
609 decode_block = '''
610 {
611 const uint32_t op = bits(machInst, 24, 21);
612 const bool s = (bits(machInst, 20) == 1);
613 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
614 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
615 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
616 bits(machInst, 14, 12);
617 const bool rotC = ctrlImm > 3;
618 const uint32_t dataImm = bits(machInst, 7, 0);
619 const uint32_t imm = modified_imm(ctrlImm, dataImm);
620 switch (op) {
621 case 0x0:
622 if (rd == INTREG_PC) {
623 %(tst)s
624 } else {
625 %(and)s
626 }
627 case 0x1:
628 %(bic)s
629 case 0x2:
630 if (rn == INTREG_PC) {
631 %(mov)s
632 } else {
633 %(orr)s
634 }
635 case 0x3:
636 if (rn == INTREG_PC) {
637 %(mvn)s
638 } else {
639 %(orn)s
640 }
641 case 0x4:
642 if (rd == INTREG_PC) {
643 %(teq)s
644 } else {
645 %(eor)s
646 }
647 case 0x8:
648 if (rd == INTREG_PC) {
649 %(cmn)s
650 } else {
651 %(add)s
652 }
653 case 0xa:
654 %(adc)s
655 case 0xb:
656 %(sbc)s
657 case 0xd:
658 if (rd == INTREG_PC) {
659 %(cmp)s
660 } else {
661 %(sub)s
662 }
663 case 0xe:
664 %(rsb)s
665 default:
666 return new Unknown(machInst);
667 }
668 }
669 ''' % {
670 "tst" : decInst("Tst", "INTREG_ZERO"),
671 "and" : decInst("And"),
672 "bic" : decInst("Bic"),
673 "mov" : decInst("Mov", op1="INTREG_ZERO"),
674 "orr" : decInst("Orr"),
675 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
676 "orn" : decInst("Orn"),
677 "teq" : decInst("Teq", dest="INTREG_ZERO"),
678 "eor" : decInst("Eor"),
679 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
680 "add" : decInst("Add"),
681 "adc" : decInst("Adc"),
682 "sbc" : decInst("Sbc"),
683 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
684 "sub" : decInst("Sub"),
685 "rsb" : decInst("Rsb")
686 }
687}};
688
689def format Thumb32DataProcPlainBin() {{
690 decode_block = '''
691 {
692 const uint32_t op = bits(machInst, 24, 20);
693 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
694 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
695 switch (op) {
696 case 0x0:
697 {
698 const uint32_t imm = bits(machInst, 7, 0) |
699 (bits(machInst, 14, 12) << 8) |
700 (bits(machInst, 26) << 11);
701 if (rn == 0xf) {
702 return new AdrImm(machInst, rd, (IntRegIndex)1,
703 imm, false);
704 } else {
705 return new AddImm(machInst, rd, rn, imm, true);
706 }
707 }
708 case 0x4:
709 {
710 const uint32_t imm = bits(machInst, 7, 0) |
711 (bits(machInst, 14, 12) << 8) |
712 (bits(machInst, 26) << 11) |
713 (bits(machInst, 19, 16) << 12);
714 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
715 }
716 case 0xa:
717 {
718 const uint32_t imm = bits(machInst, 7, 0) |
719 (bits(machInst, 14, 12) << 8) |
720 (bits(machInst, 26) << 11);
721 if (rn == 0xf) {
722 return new AdrImm(machInst, rd, (IntRegIndex)0,
723 imm, false);
724 } else {
725 return new SubImm(machInst, rd, rn, imm, true);
726 }
727 }
728 case 0xc:
729 {
730 const uint32_t imm = bits(machInst, 7, 0) |
731 (bits(machInst, 14, 12) << 8) |
732 (bits(machInst, 26) << 11) |
733 (bits(machInst, 19, 16) << 12);
734 return new MovtImm(machInst, rd, rd, imm, true);
735 }
736 case 0x12:
737 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
738 return new WarnUnimplemented("ssat16", machInst);
739 }
740 // Fall through on purpose...
741 case 0x10:
742 return new WarnUnimplemented("ssat", machInst);
743 case 0x14:
744 return new WarnUnimplemented("sbfx", machInst);
745 case 0x16:
746 if (rn == 0xf) {
747 return new WarnUnimplemented("bfc", machInst);
748 } else {
749 return new WarnUnimplemented("bfi", machInst);
750 }
751 case 0x1a:
752 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
753 return new WarnUnimplemented("usat16", machInst);
754 }
755 // Fall through on purpose...
756 case 0x18:
757 return new WarnUnimplemented("usat", machInst);
758 case 0x1c:
759 return new WarnUnimplemented("ubfx", machInst);
760 default:
761 return new Unknown(machInst);
762 }
763 }
764 '''
765}};
766
767def format Thumb32DataProcShiftReg() {{
768
769 def decInst(mnem, dest="rd", op1="rn"):
770 return '''
771 if (s) {
772 return new %(mnem)sRegCc(machInst, %(dest)s,
773 %(op1)s, rm, amt, type);
774 } else {
775 return new %(mnem)sReg(machInst, %(dest)s,
776 %(op1)s, rm, amt, type);
777 }
778 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
779
780 decode_block = '''
781 {
782 const uint32_t op = bits(machInst, 24, 21);
783 const bool s = (bits(machInst, 20) == 1);
784 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
785 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
786 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
787 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
788 bits(machInst, 7, 6);
789 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
790 switch (op) {
791 case 0x0:
792 if (rd == INTREG_PC) {
793 %(tst)s
794 } else {
795 %(and)s
796 }
797 case 0x1:
798 %(bic)s
799 case 0x2:
800 if (rn == INTREG_PC) {
801 %(mov)s
802 } else {
803 %(orr)s
804 }
805 case 0x3:
806 if (rn == INTREG_PC) {
807 %(mvn)s
808 } else {
809 %(orn)s
810 }
811 case 0x4:
812 if (rd == INTREG_PC) {
813 %(teq)s
814 } else {
815 %(eor)s
816 }
817 case 0x6:
818 return new WarnUnimplemented("pkh", machInst);
819 case 0x8:
820 if (rd == INTREG_PC) {
821 %(cmn)s
822 } else {
823 %(add)s
824 }
825 case 0xa:
826 %(adc)s
827 case 0xb:
828 %(sbc)s
829 case 0xd:
830 if (rd == INTREG_PC) {
831 %(cmp)s
832 } else {
833 %(sub)s
834 }
835 case 0xe:
836 %(rsb)s
837 default:
838 return new Unknown(machInst);
839 }
840 }
841 ''' % {
842 "tst" : decInst("Tst", "INTREG_ZERO"),
843 "and" : decInst("And"),
844 "bic" : decInst("Bic"),
845 "mov" : decInst("Mov", op1="INTREG_ZERO"),
846 "orr" : decInst("Orr"),
847 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
848 "orn" : decInst("Orn"),
849 "teq" : decInst("Teq", "INTREG_ZERO"),
850 "eor" : decInst("Eor"),
851 "cmn" : decInst("Cmn", "INTREG_ZERO"),
852 "add" : decInst("Add"),
853 "adc" : decInst("Adc"),
854 "sbc" : decInst("Sbc"),
855 "cmp" : decInst("Cmp", "INTREG_ZERO"),
856 "sub" : decInst("Sub"),
857 "rsb" : decInst("Rsb")
858 }
859}};