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 {
535 const uint32_t m = bits(machInst, 8);
536 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
537 return new LdmStm(machInst, INTREG_SP, false, false, false,
538 true, false, regList);
539 }
540 case 0x6:
541 {
542 const uint32_t opBits = bits(machInst, 7, 5);
543 if (opBits == 2) {
544 return new WarnUnimplemented("setend", machInst);
545 } else if (opBits == 3) {
546 return new WarnUnimplemented("cps", machInst);
547 }
548 }
549 case 0x9:
550 return new Cbnz(machInst,
551 (bits(machInst, 9) << 6) |
552 (bits(machInst, 7, 3) << 1),
553 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
554 case 0xa:
555 switch (bits(machInst, 7, 5)) {
556 case 0x0:
557 return new WarnUnimplemented("rev", machInst);
558 case 0x1:
559 return new WarnUnimplemented("rev16", machInst);
560 case 0x3:
561 return new WarnUnimplemented("revsh", machInst);
562 default:
563 break;
564 }
565 break;
566 case 0xb:
567 return new Cbnz(machInst,
568 (bits(machInst, 9) << 6) |
569 (bits(machInst, 7, 3) << 1),
570 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
571 case 0xc:
572 case 0xd:
573 {
574 const uint32_t p = bits(machInst, 8);
575 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
576 return new LdmStm(machInst, INTREG_SP, true, true, false,
577 true, true, regList);
578 }
579 case 0xe:
580 return new WarnUnimplemented("bkpt", machInst);
581 case 0xf:
582 if (bits(machInst, 3, 0) != 0)
583 return new WarnUnimplemented("it", machInst);
584 switch (bits(machInst, 7, 4)) {
585 case 0x0:
586 return new WarnUnimplemented("nop", machInst);
587 case 0x1:
588 return new WarnUnimplemented("yield", machInst);
589 case 0x2:
590 return new WarnUnimplemented("wfe", machInst);
591 case 0x3:
592 return new WarnUnimplemented("wfi", machInst);
593 case 0x4:
594 return new WarnUnimplemented("sev", machInst);
595 default:
596 return new WarnUnimplemented("unallocated_hint", machInst);
597 }
598 default:
599 break;
600 }
601 return new Unknown(machInst);
602 }
603 '''
604}};
605
606def format Thumb32DataProcModImm() {{
607
608 def decInst(mnem, dest="rd", op1="rn"):
609 return '''
610 if (s) {
611 return new %(mnem)sImmCc(machInst, %(dest)s,
612 %(op1)s, imm, rotC);
613 } else {
614 return new %(mnem)sImm(machInst, %(dest)s,
615 %(op1)s, imm, rotC);
616 }
617 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
618
619 decode_block = '''
620 {
621 const uint32_t op = bits(machInst, 24, 21);
622 const bool s = (bits(machInst, 20) == 1);
623 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
624 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
625 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
626 bits(machInst, 14, 12);
627 const bool rotC = ctrlImm > 3;
628 const uint32_t dataImm = bits(machInst, 7, 0);
629 const uint32_t imm = modified_imm(ctrlImm, dataImm);
630 switch (op) {
631 case 0x0:
632 if (rd == INTREG_PC) {
633 %(tst)s
634 } else {
635 %(and)s
636 }
637 case 0x1:
638 %(bic)s
639 case 0x2:
640 if (rn == INTREG_PC) {
641 %(mov)s
642 } else {
643 %(orr)s
644 }
645 case 0x3:
646 if (rn == INTREG_PC) {
647 %(mvn)s
648 } else {
649 %(orn)s
650 }
651 case 0x4:
652 if (rd == INTREG_PC) {
653 %(teq)s
654 } else {
655 %(eor)s
656 }
657 case 0x8:
658 if (rd == INTREG_PC) {
659 %(cmn)s
660 } else {
661 %(add)s
662 }
663 case 0xa:
664 %(adc)s
665 case 0xb:
666 %(sbc)s
667 case 0xd:
668 if (rd == INTREG_PC) {
669 %(cmp)s
670 } else {
671 %(sub)s
672 }
673 case 0xe:
674 %(rsb)s
675 default:
676 return new Unknown(machInst);
677 }
678 }
679 ''' % {
680 "tst" : decInst("Tst", "INTREG_ZERO"),
681 "and" : decInst("And"),
682 "bic" : decInst("Bic"),
683 "mov" : decInst("Mov", op1="INTREG_ZERO"),
684 "orr" : decInst("Orr"),
685 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
686 "orn" : decInst("Orn"),
687 "teq" : decInst("Teq", dest="INTREG_ZERO"),
688 "eor" : decInst("Eor"),
689 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
690 "add" : decInst("Add"),
691 "adc" : decInst("Adc"),
692 "sbc" : decInst("Sbc"),
693 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
694 "sub" : decInst("Sub"),
695 "rsb" : decInst("Rsb")
696 }
697}};
698
699def format Thumb32DataProcPlainBin() {{
700 decode_block = '''
701 {
702 const uint32_t op = bits(machInst, 24, 20);
703 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
704 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
705 switch (op) {
706 case 0x0:
707 {
708 const uint32_t imm = bits(machInst, 7, 0) |
709 (bits(machInst, 14, 12) << 8) |
710 (bits(machInst, 26) << 11);
711 if (rn == 0xf) {
712 return new AdrImm(machInst, rd, (IntRegIndex)1,
713 imm, false);
714 } else {
715 return new AddImm(machInst, rd, rn, imm, true);
716 }
717 }
718 case 0x4:
719 {
720 const uint32_t imm = bits(machInst, 7, 0) |
721 (bits(machInst, 14, 12) << 8) |
722 (bits(machInst, 26) << 11) |
723 (bits(machInst, 19, 16) << 12);
724 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
725 }
726 case 0xa:
727 {
728 const uint32_t imm = bits(machInst, 7, 0) |
729 (bits(machInst, 14, 12) << 8) |
730 (bits(machInst, 26) << 11);
731 if (rn == 0xf) {
732 return new AdrImm(machInst, rd, (IntRegIndex)0,
733 imm, false);
734 } else {
735 return new SubImm(machInst, rd, rn, imm, true);
736 }
737 }
738 case 0xc:
739 {
740 const uint32_t imm = bits(machInst, 7, 0) |
741 (bits(machInst, 14, 12) << 8) |
742 (bits(machInst, 26) << 11) |
743 (bits(machInst, 19, 16) << 12);
744 return new MovtImm(machInst, rd, rd, imm, true);
745 }
746 case 0x12:
747 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
748 return new WarnUnimplemented("ssat16", machInst);
749 }
750 // Fall through on purpose...
751 case 0x10:
752 return new WarnUnimplemented("ssat", machInst);
753 case 0x14:
754 return new WarnUnimplemented("sbfx", machInst);
755 case 0x16:
756 if (rn == 0xf) {
757 return new WarnUnimplemented("bfc", machInst);
758 } else {
759 return new WarnUnimplemented("bfi", machInst);
760 }
761 case 0x1a:
762 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
763 return new WarnUnimplemented("usat16", machInst);
764 }
765 // Fall through on purpose...
766 case 0x18:
767 return new WarnUnimplemented("usat", machInst);
768 case 0x1c:
769 return new WarnUnimplemented("ubfx", machInst);
770 default:
771 return new Unknown(machInst);
772 }
773 }
774 '''
775}};
776
777def format Thumb32DataProcShiftReg() {{
778
779 def decInst(mnem, dest="rd", op1="rn"):
780 return '''
781 if (s) {
782 return new %(mnem)sRegCc(machInst, %(dest)s,
783 %(op1)s, rm, amt, type);
784 } else {
785 return new %(mnem)sReg(machInst, %(dest)s,
786 %(op1)s, rm, amt, type);
787 }
788 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
789
790 decode_block = '''
791 {
792 const uint32_t op = bits(machInst, 24, 21);
793 const bool s = (bits(machInst, 20) == 1);
794 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
795 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
796 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
797 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
798 bits(machInst, 7, 6);
799 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
800 switch (op) {
801 case 0x0:
802 if (rd == INTREG_PC) {
803 %(tst)s
804 } else {
805 %(and)s
806 }
807 case 0x1:
808 %(bic)s
809 case 0x2:
810 if (rn == INTREG_PC) {
811 %(mov)s
812 } else {
813 %(orr)s
814 }
815 case 0x3:
816 if (rn == INTREG_PC) {
817 %(mvn)s
818 } else {
819 %(orn)s
820 }
821 case 0x4:
822 if (rd == INTREG_PC) {
823 %(teq)s
824 } else {
825 %(eor)s
826 }
827 case 0x6:
828 return new WarnUnimplemented("pkh", machInst);
829 case 0x8:
830 if (rd == INTREG_PC) {
831 %(cmn)s
832 } else {
833 %(add)s
834 }
835 case 0xa:
836 %(adc)s
837 case 0xb:
838 %(sbc)s
839 case 0xd:
840 if (rd == INTREG_PC) {
841 %(cmp)s
842 } else {
843 %(sub)s
844 }
845 case 0xe:
846 %(rsb)s
847 default:
848 return new Unknown(machInst);
849 }
850 }
851 ''' % {
852 "tst" : decInst("Tst", "INTREG_ZERO"),
853 "and" : decInst("And"),
854 "bic" : decInst("Bic"),
855 "mov" : decInst("Mov", op1="INTREG_ZERO"),
856 "orr" : decInst("Orr"),
857 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
858 "orn" : decInst("Orn"),
859 "teq" : decInst("Teq", "INTREG_ZERO"),
860 "eor" : decInst("Eor"),
861 "cmn" : decInst("Cmn", "INTREG_ZERO"),
862 "add" : decInst("Add"),
863 "adc" : decInst("Adc"),
864 "sbc" : decInst("Sbc"),
865 "cmp" : decInst("Cmp", "INTREG_ZERO"),
866 "sub" : decInst("Sub"),
867 "rsb" : decInst("Rsb")
868 }
869}};