data.isa (7250:40b0a5327df8) data.isa (7252:bba68021edca)
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 ArmUsad() {{
39 decode_block = '''
40 {
41 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
42 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
43 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
44 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
45 if (ra == 0xf) {
46 return new Usad8(machInst, rd, rn, rm);
47 } else {
48 return new Usada8(machInst, rd, rn, rm, ra);
49 }
50 }
51 '''
52}};
53
54def format ArmDataProcReg() {{
55 pclr = '''
56 return new %(className)ssRegPclr(machInst, %(dest)s,
57 %(op1)s, rm, imm5,
58 type);
59 '''
60 instDecode = '''
61 case %(opcode)#x:
62 if (immShift) {
63 if (setCc) {
64 if (%(dest)s == INTREG_PC) {
65 %(pclr)s
66 } else {
67 return new %(className)sRegCc(machInst, %(dest)s,
68 %(op1)s, rm, imm5, type);
69 }
70 } else {
71 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
72 rm, imm5, type);
73 }
74 } else {
75 if (setCc) {
76 return new %(className)sRegRegCc(machInst, %(dest)s,
77 %(op1)s, rm, rs, type);
78 } else {
79 return new %(className)sRegReg(machInst, %(dest)s,
80 %(op1)s, rm, rs, type);
81 }
82 }
83 break;
84 '''
85
86 def instCode(opcode, mnem, useDest = True, useOp1 = True):
87 global pclr
88 if useDest:
89 dest = "rd"
90 else:
91 dest = "INTREG_ZERO"
92 if useOp1:
93 op1 = "rn"
94 else:
95 op1 = "INTREG_ZERO"
96 global instDecode, pclrCode
97 substDict = { "className": mnem.capitalize(),
98 "opcode": opcode,
99 "dest": dest,
100 "op1": op1 }
101 if useDest:
102 substDict["pclr"] = pclr % substDict
103 else:
104 substDict["pclr"] = ""
105 return instDecode % substDict
106
107 decode_block = '''
108 {
109 const bool immShift = (bits(machInst, 4) == 0);
110 const bool setCc = (bits(machInst, 20) == 1);
111 const uint32_t imm5 = bits(machInst, 11, 7);
112 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
113 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
114 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
115 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
116 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
117 switch (OPCODE) {
118 '''
119 decode_block += instCode(0x0, "and")
120 decode_block += instCode(0x1, "eor")
121 decode_block += instCode(0x2, "sub")
122 decode_block += instCode(0x3, "rsb")
123 decode_block += instCode(0x4, "add")
124 decode_block += instCode(0x5, "adc")
125 decode_block += instCode(0x6, "sbc")
126 decode_block += instCode(0x7, "rsc")
127 decode_block += instCode(0x8, "tst", useDest = False)
128 decode_block += instCode(0x9, "teq", useDest = False)
129 decode_block += instCode(0xa, "cmp", useDest = False)
130 decode_block += instCode(0xb, "cmn", useDest = False)
131 decode_block += instCode(0xc, "orr")
132 decode_block += instCode(0xd, "mov", useOp1 = False)
133 decode_block += instCode(0xe, "bic")
134 decode_block += instCode(0xf, "mvn", useOp1 = False)
135 decode_block += '''
136 default:
137 return new Unknown(machInst);
138 }
139 }
140 '''
141}};
142
143def format ArmPackUnpackSatReverse() {{
144 decode_block = '''
145 {
146 const uint32_t op1 = bits(machInst, 22, 20);
147 const uint32_t a = bits(machInst, 19, 16);
148 const uint32_t op2 = bits(machInst, 7, 5);
149 if (bits(op2, 0) == 0) {
150 const IntRegIndex rn =
151 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
152 const IntRegIndex rd =
153 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
154 const uint32_t satImm = bits(machInst, 20, 16);
155 const uint32_t imm = bits(machInst, 11, 7);
156 const ArmShiftType type =
157 (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
158 if (op1 == 0) {
159 if (type) {
160 return new PkhtbReg(machInst, rd, (IntRegIndex)a,
161 rn, imm, type);
162 } else {
163 return new PkhbtReg(machInst, rd, (IntRegIndex)a,
164 rn, imm, type);
165 }
166 } else if (bits(op1, 2, 1) == 1) {
167 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
168 } else if (bits(op1, 2, 1) == 3) {
169 return new Usat(machInst, rd, satImm, rn, imm, type);
170 }
171 return new Unknown(machInst);
172 }
173 switch (op1) {
174 case 0x0:
175 {
176 const IntRegIndex rn =
177 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
178 const IntRegIndex rd =
179 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
180 const IntRegIndex rm =
181 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
182 if (op2 == 0x3) {
183 const uint32_t rotation =
184 (uint32_t)bits(machInst, 11, 10) << 3;
185 if (a == 0xf) {
186 return new Sxtb16(machInst, rd, rotation, rm);
187 } else {
188 return new Sxtab16(machInst, rd, rn, rm, rotation);
189 }
190 } else if (op2 == 0x5) {
191 return new Sel(machInst, rd, rn, rm);
192 }
193 }
194 break;
195 case 0x2:
196 if (op2 == 0x1) {
197 const IntRegIndex rn =
198 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
199 const IntRegIndex rd =
200 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
201 const uint32_t satImm = bits(machInst, 20, 16);
202 return new Ssat16(machInst, rd, satImm + 1, rn);
203 } else if (op2 == 0x3) {
204 const IntRegIndex rn =
205 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
206 const IntRegIndex rd =
207 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
208 const IntRegIndex rm =
209 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
210 const uint32_t rotation =
211 (uint32_t)bits(machInst, 11, 10) << 3;
212 if (a == 0xf) {
213 return new Sxtb(machInst, rd, rotation, rm);
214 } else {
215 return new Sxtab(machInst, rd, rn, rm, rotation);
216 }
217 }
218 break;
219 case 0x3:
220 if (op2 == 0x1) {
221 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
222 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
223 return new Rev(machInst, rd, rm);
224 } else if (op2 == 0x3) {
225 const IntRegIndex rn =
226 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
227 const IntRegIndex rd =
228 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
229 const IntRegIndex rm =
230 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
231 const uint32_t rotation =
232 (uint32_t)bits(machInst, 11, 10) << 3;
233 if (a == 0xf) {
234 return new Sxth(machInst, rd, rotation, rm);
235 } else {
236 return new Sxtah(machInst, rd, rn, rm, rotation);
237 }
238 } else if (op2 == 0x5) {
239 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
240 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
241 return new Rev16(machInst, rd, rm);
242 }
243 break;
244 case 0x4:
245 if (op2 == 0x3) {
246 const IntRegIndex rn =
247 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
248 const IntRegIndex rd =
249 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
250 const IntRegIndex rm =
251 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
252 const uint32_t rotation =
253 (uint32_t)bits(machInst, 11, 10) << 3;
254 if (a == 0xf) {
255 return new Uxtb16(machInst, rd, rotation, rm);
256 } else {
257 return new Uxtab16(machInst, rd, rn, rm, rotation);
258 }
259 }
260 break;
261 case 0x6:
262 if (op2 == 0x1) {
263 const IntRegIndex rn =
264 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
265 const IntRegIndex rd =
266 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
267 const uint32_t satImm = bits(machInst, 20, 16);
268 return new Usat16(machInst, rd, satImm, rn);
269 } else if (op2 == 0x3) {
270 const IntRegIndex rn =
271 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
272 const IntRegIndex rd =
273 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
274 const IntRegIndex rm =
275 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
276 const uint32_t rotation =
277 (uint32_t)bits(machInst, 11, 10) << 3;
278 if (a == 0xf) {
279 return new Uxtb(machInst, rd, rotation, rm);
280 } else {
281 return new Uxtab(machInst, rd, rn, rm, rotation);
282 }
283 }
284 break;
285 case 0x7:
286 {
287 const IntRegIndex rn =
288 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
289 const IntRegIndex rd =
290 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
291 const IntRegIndex rm =
292 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
293 if (op2 == 0x1) {
294 return new Rbit(machInst, rd, rm);
295 } else if (op2 == 0x3) {
296 const uint32_t rotation =
297 (uint32_t)bits(machInst, 11, 10) << 3;
298 if (a == 0xf) {
299 return new Uxth(machInst, rd, rotation, rm);
300 } else {
301 return new Uxtah(machInst, rd, rn, rm, rotation);
302 }
303 } else if (op2 == 0x5) {
304 return new Revsh(machInst, rd, rm);
305 }
306 }
307 break;
308 }
309 return new Unknown(machInst);
310 }
311 '''
312}};
313
314def format ArmParallelAddSubtract() {{
315 decode_block='''
316 {
317 const uint32_t op1 = bits(machInst, 21, 20);
318 const uint32_t op2 = bits(machInst, 7, 5);
319 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
320 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
321 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
322 if (bits(machInst, 22) == 0) {
323 switch (op1) {
324 case 0x1:
325 switch (op2) {
326 case 0x0:
327 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
328 case 0x1:
329 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
330 case 0x2:
331 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
332 case 0x3:
333 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
334 case 0x4:
335 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
336 case 0x7:
337 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
338 }
339 break;
340 case 0x2:
341 switch (op2) {
342 case 0x0:
343 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
344 case 0x1:
345 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
346 case 0x2:
347 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
348 case 0x3:
349 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
350 case 0x4:
351 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
352 case 0x7:
353 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
354 }
355 break;
356 case 0x3:
357 switch (op2) {
358 case 0x0:
359 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
360 case 0x1:
361 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
362 case 0x2:
363 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
364 case 0x3:
365 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
366 case 0x4:
367 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
368 case 0x7:
369 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
370 }
371 break;
372 }
373 } else {
374 switch (op1) {
375 case 0x1:
376 switch (op2) {
377 case 0x0:
378 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
379 case 0x1:
380 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
381 case 0x2:
382 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
383 case 0x3:
384 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
385 case 0x4:
386 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
387 case 0x7:
388 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
389 }
390 break;
391 case 0x2:
392 switch (op2) {
393 case 0x0:
394 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
395 case 0x1:
396 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
397 case 0x2:
398 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
399 case 0x3:
400 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
401 case 0x4:
402 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
403 case 0x7:
404 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
405 }
406 break;
407 case 0x3:
408 switch (op2) {
409 case 0x0:
410 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
411 case 0x1:
412 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
413 case 0x2:
414 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
415 case 0x3:
416 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
417 case 0x4:
418 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
419 case 0x7:
420 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
421 }
422 break;
423 }
424 }
425 return new Unknown(machInst);
426 }
427 '''
428}};
429
430def format ArmDataProcImm() {{
431 pclr = '''
432 return new %(className)ssImmPclr(machInst, %(dest)s,
433 %(op1)s, imm, false);
434 '''
435 adr = '''
436 return new AdrImm(machInst, %(dest)s, %(add)s,
437 imm, false);
438 '''
439 instDecode = '''
440 case %(opcode)#x:
441 if (setCc) {
442 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
443 %(pclr)s
444 } else {
445 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
446 imm, rotC);
447 }
448 } else {
449 if (%(adrInst)s && %(op1)s == INTREG_PC) {
450 %(adr)s
451 } else {
452 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
453 imm, rotC);
454 }
455 }
456 break;
457 '''
458
459 def instCode(opcode, mnem, useDest = True, useOp1 = True):
460 global instDecode, pclr, adr
461 if useDest:
462 dest = "rd"
463 else:
464 dest = "INTREG_ZERO"
465 if useOp1:
466 op1 = "rn"
467 else:
468 op1 = "INTREG_ZERO"
469 substDict = { "className": mnem.capitalize(),
470 "opcode": opcode,
471 "dest": dest,
472 "op1": op1,
473 "adr": "",
474 "adrInst": "false" }
475 if useDest:
476 substDict["pclrInst"] = "true"
477 substDict["pclr"] = pclr % substDict
478 else:
479 substDict["pclrInst"] = "false"
480 substDict["pclr"] = ""
481 return instDecode % substDict
482
483 def adrCode(opcode, mnem, add="1"):
484 global instDecode, pclr, adr
485 substDict = { "className": mnem.capitalize(),
486 "opcode": opcode,
487 "dest": "rd",
488 "op1": "rn",
489 "add": add,
490 "pclrInst": "true",
491 "adrInst": "true" }
492 substDict["pclr"] = pclr % substDict
493 substDict["adr"] = adr % substDict
494 return instDecode % substDict
495
496 decode_block = '''
497 {
498 const bool setCc = (bits(machInst, 20) == 1);
499 const uint32_t unrotated = bits(machInst, 7, 0);
500 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
501 const bool rotC = (rotation != 0);
502 const uint32_t imm = rotate_imm(unrotated, rotation);
503 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
504 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
505 switch (OPCODE) {
506 '''
507 decode_block += instCode(0x0, "and")
508 decode_block += instCode(0x1, "eor")
509 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
510 decode_block += instCode(0x3, "rsb")
511 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
512 decode_block += instCode(0x5, "adc")
513 decode_block += instCode(0x6, "sbc")
514 decode_block += instCode(0x7, "rsc")
515 decode_block += instCode(0x8, "tst", useDest = False)
516 decode_block += instCode(0x9, "teq", useDest = False)
517 decode_block += instCode(0xa, "cmp", useDest = False)
518 decode_block += instCode(0xb, "cmn", useDest = False)
519 decode_block += instCode(0xc, "orr")
520 decode_block += instCode(0xd, "mov", useOp1 = False)
521 decode_block += instCode(0xe, "bic")
522 decode_block += instCode(0xf, "mvn", useOp1 = False)
523 decode_block += '''
524 default:
525 return new Unknown(machInst);
526 }
527 }
528 '''
529}};
530
531def format ArmSatAddSub() {{
532 decode_block = '''
533 {
534 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
535 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
536 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
537 switch (OPCODE) {
538 case 0x8:
539 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
540 case 0x9:
541 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
542 case 0xa:
543 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
544 case 0xb:
545 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
546 default:
547 return new Unknown(machInst);
548 }
549 }
550 '''
551}};
552
553def format Thumb32DataProcReg() {{
554 decode_block = '''
555 {
556 const uint32_t op1 = bits(machInst, 23, 20);
557 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
558 const uint32_t op2 = bits(machInst, 7, 4);
559 if (bits(op1, 3) != 1) {
560 if (op2 == 0) {
561 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
562 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
563 switch (bits(op1, 2, 0)) {
564 case 0x0:
565 return new MovRegReg(machInst, rd,
566 INTREG_ZERO, rn, rm, LSL);
567 case 0x1:
568 return new MovRegRegCc(machInst, rd,
569 INTREG_ZERO, rn, rm, LSL);
570 case 0x2:
571 return new MovRegReg(machInst, rd,
572 INTREG_ZERO, rn, rm, LSR);
573 case 0x3:
574 return new MovRegRegCc(machInst, rd,
575 INTREG_ZERO, rn, rm, LSR);
576 case 0x4:
577 return new MovRegReg(machInst, rd,
578 INTREG_ZERO, rn, rm, ASR);
579 case 0x5:
580 return new MovRegRegCc(machInst, rd,
581 INTREG_ZERO, rn, rm, ASR);
582 case 0x6:
583 return new MovRegReg(machInst, rd,
584 INTREG_ZERO, rn, rm, ROR);
585 case 0x7:
586 return new MovRegRegCc(machInst, rd,
587 INTREG_ZERO, rn, rm, ROR);
588 }
589 }
590 {
591 const IntRegIndex rd =
592 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
593 const IntRegIndex rm =
594 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
595 const uint32_t rotation =
596 (uint32_t)bits(machInst, 5, 4) << 3;
597 switch (bits(op1, 2, 0)) {
598 case 0x0:
599 if (rn == 0xf) {
600 return new Sxth(machInst, rd, rotation, rm);
601 } else {
602 return new Sxtah(machInst, rd, rn, rm, rotation);
603 }
604 case 0x1:
605 if (rn == 0xf) {
606 return new Uxth(machInst, rd, rotation, rm);
607 } else {
608 return new Uxtah(machInst, rd, rn, rm, rotation);
609 }
610 case 0x2:
611 if (rn == 0xf) {
612 return new Sxtb16(machInst, rd, rotation, rm);
613 } else {
614 return new Sxtab16(machInst, rd, rn, rm, rotation);
615 }
616 case 0x3:
617 if (rn == 0xf) {
618 return new Uxtb16(machInst, rd, rotation, rm);
619 } else {
620 return new Uxtab16(machInst, rd, rn, rm, rotation);
621 }
622 case 0x4:
623 if (rn == 0xf) {
624 return new Sxtb(machInst, rd, rotation, rm);
625 } else {
626 return new Sxtab(machInst, rd, rn, rm, rotation);
627 }
628 case 0x5:
629 if (rn == 0xf) {
630 return new Uxtb(machInst, rd, rotation, rm);
631 } else {
632 return new Uxtab(machInst, rd, rn, rm, rotation);
633 }
634 default:
635 return new Unknown(machInst);
636 }
637 }
638 } else {
639 if (bits(op2, 3) == 0) {
640 const IntRegIndex rd =
641 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
642 const IntRegIndex rm =
643 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
644 if (bits(op2, 2) == 0x0) {
645 const uint32_t op1 = bits(machInst, 22, 20);
646 const uint32_t op2 = bits(machInst, 5, 4);
647 switch (op2) {
648 case 0x0:
649 switch (op1) {
650 case 0x1:
651 return new Sadd16RegCc(machInst, rd,
652 rn, rm, 0, LSL);
653 case 0x2:
654 return new SasxRegCc(machInst, rd,
655 rn, rm, 0, LSL);
656 case 0x6:
657 return new SsaxRegCc(machInst, rd,
658 rn, rm, 0, LSL);
659 case 0x5:
660 return new Ssub16RegCc(machInst, rd,
661 rn, rm, 0, LSL);
662 case 0x0:
663 return new Sadd8RegCc(machInst, rd,
664 rn, rm, 0, LSL);
665 case 0x4:
666 return new Ssub8RegCc(machInst, rd,
667 rn, rm, 0, LSL);
668 }
669 break;
670 case 0x1:
671 switch (op1) {
672 case 0x1:
673 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
674 case 0x2:
675 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
676 case 0x6:
677 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
678 case 0x5:
679 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
680 case 0x0:
681 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
682 case 0x4:
683 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
684 }
685 break;
686 case 0x2:
687 switch (op1) {
688 case 0x1:
689 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
690 case 0x2:
691 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
692 case 0x6:
693 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
694 case 0x5:
695 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
696 case 0x0:
697 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
698 case 0x4:
699 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
700 }
701 break;
702 }
703 } else {
704 const uint32_t op1 = bits(machInst, 22, 20);
705 const uint32_t op2 = bits(machInst, 5, 4);
706 switch (op2) {
707 case 0x0:
708 switch (op1) {
709 case 0x1:
710 return new Uadd16RegCc(machInst, rd,
711 rn, rm, 0, LSL);
712 case 0x2:
713 return new UasxRegCc(machInst, rd,
714 rn, rm, 0, LSL);
715 case 0x6:
716 return new UsaxRegCc(machInst, rd,
717 rn, rm, 0, LSL);
718 case 0x5:
719 return new Usub16RegCc(machInst, rd,
720 rn, rm, 0, LSL);
721 case 0x0:
722 return new Uadd8RegCc(machInst, rd,
723 rn, rm, 0, LSL);
724 case 0x4:
725 return new Usub8RegCc(machInst, rd,
726 rn, rm, 0, LSL);
727 }
728 break;
729 case 0x1:
730 switch (op1) {
731 case 0x1:
732 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
733 case 0x2:
734 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
735 case 0x6:
736 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
737 case 0x5:
738 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
739 case 0x0:
740 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
741 case 0x4:
742 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
743 }
744 break;
745 case 0x2:
746 switch (op1) {
747 case 0x1:
748 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
749 case 0x2:
750 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
751 case 0x6:
752 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
753 case 0x5:
754 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
755 case 0x0:
756 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
757 case 0x4:
758 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
759 }
760 break;
761 }
762 }
763 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
764 const uint32_t op1 = bits(machInst, 21, 20);
765 const uint32_t op2 = bits(machInst, 5, 4);
766 const IntRegIndex rd =
767 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
768 const IntRegIndex rm =
769 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
770 switch (op1) {
771 case 0x0:
772 switch (op2) {
773 case 0x0:
774 return new QaddRegCc(machInst, rd,
775 rm, rn, 0, LSL);
776 case 0x1:
777 return new QdaddRegCc(machInst, rd,
778 rm, rn, 0, LSL);
779 case 0x2:
780 return new QsubRegCc(machInst, rd,
781 rm, rn, 0, LSL);
782 case 0x3:
783 return new QdsubRegCc(machInst, rd,
784 rm, rn, 0, LSL);
785 }
786 break;
787 case 0x1:
788 switch (op2) {
789 case 0x0:
790 return new Rev(machInst, rd, rn);
791 case 0x1:
792 return new Rev16(machInst, rd, rn);
793 case 0x2:
794 return new Rbit(machInst, rd, rm);
795 case 0x3:
796 return new Revsh(machInst, rd, rn);
797 }
798 break;
799 case 0x2:
800 if (op2 == 0) {
801 return new Sel(machInst, rd, rn, rm);
802 }
803 break;
804 case 0x3:
805 if (op2 == 0) {
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 ArmUsad() {{
39 decode_block = '''
40 {
41 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
42 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
43 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
44 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
45 if (ra == 0xf) {
46 return new Usad8(machInst, rd, rn, rm);
47 } else {
48 return new Usada8(machInst, rd, rn, rm, ra);
49 }
50 }
51 '''
52}};
53
54def format ArmDataProcReg() {{
55 pclr = '''
56 return new %(className)ssRegPclr(machInst, %(dest)s,
57 %(op1)s, rm, imm5,
58 type);
59 '''
60 instDecode = '''
61 case %(opcode)#x:
62 if (immShift) {
63 if (setCc) {
64 if (%(dest)s == INTREG_PC) {
65 %(pclr)s
66 } else {
67 return new %(className)sRegCc(machInst, %(dest)s,
68 %(op1)s, rm, imm5, type);
69 }
70 } else {
71 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
72 rm, imm5, type);
73 }
74 } else {
75 if (setCc) {
76 return new %(className)sRegRegCc(machInst, %(dest)s,
77 %(op1)s, rm, rs, type);
78 } else {
79 return new %(className)sRegReg(machInst, %(dest)s,
80 %(op1)s, rm, rs, type);
81 }
82 }
83 break;
84 '''
85
86 def instCode(opcode, mnem, useDest = True, useOp1 = True):
87 global pclr
88 if useDest:
89 dest = "rd"
90 else:
91 dest = "INTREG_ZERO"
92 if useOp1:
93 op1 = "rn"
94 else:
95 op1 = "INTREG_ZERO"
96 global instDecode, pclrCode
97 substDict = { "className": mnem.capitalize(),
98 "opcode": opcode,
99 "dest": dest,
100 "op1": op1 }
101 if useDest:
102 substDict["pclr"] = pclr % substDict
103 else:
104 substDict["pclr"] = ""
105 return instDecode % substDict
106
107 decode_block = '''
108 {
109 const bool immShift = (bits(machInst, 4) == 0);
110 const bool setCc = (bits(machInst, 20) == 1);
111 const uint32_t imm5 = bits(machInst, 11, 7);
112 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
113 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
114 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
115 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
116 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
117 switch (OPCODE) {
118 '''
119 decode_block += instCode(0x0, "and")
120 decode_block += instCode(0x1, "eor")
121 decode_block += instCode(0x2, "sub")
122 decode_block += instCode(0x3, "rsb")
123 decode_block += instCode(0x4, "add")
124 decode_block += instCode(0x5, "adc")
125 decode_block += instCode(0x6, "sbc")
126 decode_block += instCode(0x7, "rsc")
127 decode_block += instCode(0x8, "tst", useDest = False)
128 decode_block += instCode(0x9, "teq", useDest = False)
129 decode_block += instCode(0xa, "cmp", useDest = False)
130 decode_block += instCode(0xb, "cmn", useDest = False)
131 decode_block += instCode(0xc, "orr")
132 decode_block += instCode(0xd, "mov", useOp1 = False)
133 decode_block += instCode(0xe, "bic")
134 decode_block += instCode(0xf, "mvn", useOp1 = False)
135 decode_block += '''
136 default:
137 return new Unknown(machInst);
138 }
139 }
140 '''
141}};
142
143def format ArmPackUnpackSatReverse() {{
144 decode_block = '''
145 {
146 const uint32_t op1 = bits(machInst, 22, 20);
147 const uint32_t a = bits(machInst, 19, 16);
148 const uint32_t op2 = bits(machInst, 7, 5);
149 if (bits(op2, 0) == 0) {
150 const IntRegIndex rn =
151 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
152 const IntRegIndex rd =
153 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
154 const uint32_t satImm = bits(machInst, 20, 16);
155 const uint32_t imm = bits(machInst, 11, 7);
156 const ArmShiftType type =
157 (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
158 if (op1 == 0) {
159 if (type) {
160 return new PkhtbReg(machInst, rd, (IntRegIndex)a,
161 rn, imm, type);
162 } else {
163 return new PkhbtReg(machInst, rd, (IntRegIndex)a,
164 rn, imm, type);
165 }
166 } else if (bits(op1, 2, 1) == 1) {
167 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
168 } else if (bits(op1, 2, 1) == 3) {
169 return new Usat(machInst, rd, satImm, rn, imm, type);
170 }
171 return new Unknown(machInst);
172 }
173 switch (op1) {
174 case 0x0:
175 {
176 const IntRegIndex rn =
177 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
178 const IntRegIndex rd =
179 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
180 const IntRegIndex rm =
181 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
182 if (op2 == 0x3) {
183 const uint32_t rotation =
184 (uint32_t)bits(machInst, 11, 10) << 3;
185 if (a == 0xf) {
186 return new Sxtb16(machInst, rd, rotation, rm);
187 } else {
188 return new Sxtab16(machInst, rd, rn, rm, rotation);
189 }
190 } else if (op2 == 0x5) {
191 return new Sel(machInst, rd, rn, rm);
192 }
193 }
194 break;
195 case 0x2:
196 if (op2 == 0x1) {
197 const IntRegIndex rn =
198 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
199 const IntRegIndex rd =
200 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
201 const uint32_t satImm = bits(machInst, 20, 16);
202 return new Ssat16(machInst, rd, satImm + 1, rn);
203 } else if (op2 == 0x3) {
204 const IntRegIndex rn =
205 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
206 const IntRegIndex rd =
207 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
208 const IntRegIndex rm =
209 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
210 const uint32_t rotation =
211 (uint32_t)bits(machInst, 11, 10) << 3;
212 if (a == 0xf) {
213 return new Sxtb(machInst, rd, rotation, rm);
214 } else {
215 return new Sxtab(machInst, rd, rn, rm, rotation);
216 }
217 }
218 break;
219 case 0x3:
220 if (op2 == 0x1) {
221 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
222 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
223 return new Rev(machInst, rd, rm);
224 } else if (op2 == 0x3) {
225 const IntRegIndex rn =
226 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
227 const IntRegIndex rd =
228 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
229 const IntRegIndex rm =
230 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
231 const uint32_t rotation =
232 (uint32_t)bits(machInst, 11, 10) << 3;
233 if (a == 0xf) {
234 return new Sxth(machInst, rd, rotation, rm);
235 } else {
236 return new Sxtah(machInst, rd, rn, rm, rotation);
237 }
238 } else if (op2 == 0x5) {
239 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
240 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
241 return new Rev16(machInst, rd, rm);
242 }
243 break;
244 case 0x4:
245 if (op2 == 0x3) {
246 const IntRegIndex rn =
247 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
248 const IntRegIndex rd =
249 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
250 const IntRegIndex rm =
251 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
252 const uint32_t rotation =
253 (uint32_t)bits(machInst, 11, 10) << 3;
254 if (a == 0xf) {
255 return new Uxtb16(machInst, rd, rotation, rm);
256 } else {
257 return new Uxtab16(machInst, rd, rn, rm, rotation);
258 }
259 }
260 break;
261 case 0x6:
262 if (op2 == 0x1) {
263 const IntRegIndex rn =
264 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
265 const IntRegIndex rd =
266 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
267 const uint32_t satImm = bits(machInst, 20, 16);
268 return new Usat16(machInst, rd, satImm, rn);
269 } else if (op2 == 0x3) {
270 const IntRegIndex rn =
271 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
272 const IntRegIndex rd =
273 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
274 const IntRegIndex rm =
275 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
276 const uint32_t rotation =
277 (uint32_t)bits(machInst, 11, 10) << 3;
278 if (a == 0xf) {
279 return new Uxtb(machInst, rd, rotation, rm);
280 } else {
281 return new Uxtab(machInst, rd, rn, rm, rotation);
282 }
283 }
284 break;
285 case 0x7:
286 {
287 const IntRegIndex rn =
288 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
289 const IntRegIndex rd =
290 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
291 const IntRegIndex rm =
292 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
293 if (op2 == 0x1) {
294 return new Rbit(machInst, rd, rm);
295 } else if (op2 == 0x3) {
296 const uint32_t rotation =
297 (uint32_t)bits(machInst, 11, 10) << 3;
298 if (a == 0xf) {
299 return new Uxth(machInst, rd, rotation, rm);
300 } else {
301 return new Uxtah(machInst, rd, rn, rm, rotation);
302 }
303 } else if (op2 == 0x5) {
304 return new Revsh(machInst, rd, rm);
305 }
306 }
307 break;
308 }
309 return new Unknown(machInst);
310 }
311 '''
312}};
313
314def format ArmParallelAddSubtract() {{
315 decode_block='''
316 {
317 const uint32_t op1 = bits(machInst, 21, 20);
318 const uint32_t op2 = bits(machInst, 7, 5);
319 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
320 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
321 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
322 if (bits(machInst, 22) == 0) {
323 switch (op1) {
324 case 0x1:
325 switch (op2) {
326 case 0x0:
327 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
328 case 0x1:
329 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
330 case 0x2:
331 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
332 case 0x3:
333 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
334 case 0x4:
335 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
336 case 0x7:
337 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
338 }
339 break;
340 case 0x2:
341 switch (op2) {
342 case 0x0:
343 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
344 case 0x1:
345 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
346 case 0x2:
347 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
348 case 0x3:
349 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
350 case 0x4:
351 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
352 case 0x7:
353 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
354 }
355 break;
356 case 0x3:
357 switch (op2) {
358 case 0x0:
359 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
360 case 0x1:
361 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
362 case 0x2:
363 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
364 case 0x3:
365 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
366 case 0x4:
367 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
368 case 0x7:
369 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
370 }
371 break;
372 }
373 } else {
374 switch (op1) {
375 case 0x1:
376 switch (op2) {
377 case 0x0:
378 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
379 case 0x1:
380 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
381 case 0x2:
382 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
383 case 0x3:
384 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
385 case 0x4:
386 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
387 case 0x7:
388 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
389 }
390 break;
391 case 0x2:
392 switch (op2) {
393 case 0x0:
394 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
395 case 0x1:
396 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
397 case 0x2:
398 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
399 case 0x3:
400 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
401 case 0x4:
402 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
403 case 0x7:
404 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
405 }
406 break;
407 case 0x3:
408 switch (op2) {
409 case 0x0:
410 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
411 case 0x1:
412 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
413 case 0x2:
414 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
415 case 0x3:
416 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
417 case 0x4:
418 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
419 case 0x7:
420 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
421 }
422 break;
423 }
424 }
425 return new Unknown(machInst);
426 }
427 '''
428}};
429
430def format ArmDataProcImm() {{
431 pclr = '''
432 return new %(className)ssImmPclr(machInst, %(dest)s,
433 %(op1)s, imm, false);
434 '''
435 adr = '''
436 return new AdrImm(machInst, %(dest)s, %(add)s,
437 imm, false);
438 '''
439 instDecode = '''
440 case %(opcode)#x:
441 if (setCc) {
442 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
443 %(pclr)s
444 } else {
445 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
446 imm, rotC);
447 }
448 } else {
449 if (%(adrInst)s && %(op1)s == INTREG_PC) {
450 %(adr)s
451 } else {
452 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
453 imm, rotC);
454 }
455 }
456 break;
457 '''
458
459 def instCode(opcode, mnem, useDest = True, useOp1 = True):
460 global instDecode, pclr, adr
461 if useDest:
462 dest = "rd"
463 else:
464 dest = "INTREG_ZERO"
465 if useOp1:
466 op1 = "rn"
467 else:
468 op1 = "INTREG_ZERO"
469 substDict = { "className": mnem.capitalize(),
470 "opcode": opcode,
471 "dest": dest,
472 "op1": op1,
473 "adr": "",
474 "adrInst": "false" }
475 if useDest:
476 substDict["pclrInst"] = "true"
477 substDict["pclr"] = pclr % substDict
478 else:
479 substDict["pclrInst"] = "false"
480 substDict["pclr"] = ""
481 return instDecode % substDict
482
483 def adrCode(opcode, mnem, add="1"):
484 global instDecode, pclr, adr
485 substDict = { "className": mnem.capitalize(),
486 "opcode": opcode,
487 "dest": "rd",
488 "op1": "rn",
489 "add": add,
490 "pclrInst": "true",
491 "adrInst": "true" }
492 substDict["pclr"] = pclr % substDict
493 substDict["adr"] = adr % substDict
494 return instDecode % substDict
495
496 decode_block = '''
497 {
498 const bool setCc = (bits(machInst, 20) == 1);
499 const uint32_t unrotated = bits(machInst, 7, 0);
500 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
501 const bool rotC = (rotation != 0);
502 const uint32_t imm = rotate_imm(unrotated, rotation);
503 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
504 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
505 switch (OPCODE) {
506 '''
507 decode_block += instCode(0x0, "and")
508 decode_block += instCode(0x1, "eor")
509 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
510 decode_block += instCode(0x3, "rsb")
511 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
512 decode_block += instCode(0x5, "adc")
513 decode_block += instCode(0x6, "sbc")
514 decode_block += instCode(0x7, "rsc")
515 decode_block += instCode(0x8, "tst", useDest = False)
516 decode_block += instCode(0x9, "teq", useDest = False)
517 decode_block += instCode(0xa, "cmp", useDest = False)
518 decode_block += instCode(0xb, "cmn", useDest = False)
519 decode_block += instCode(0xc, "orr")
520 decode_block += instCode(0xd, "mov", useOp1 = False)
521 decode_block += instCode(0xe, "bic")
522 decode_block += instCode(0xf, "mvn", useOp1 = False)
523 decode_block += '''
524 default:
525 return new Unknown(machInst);
526 }
527 }
528 '''
529}};
530
531def format ArmSatAddSub() {{
532 decode_block = '''
533 {
534 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
535 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
536 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
537 switch (OPCODE) {
538 case 0x8:
539 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
540 case 0x9:
541 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
542 case 0xa:
543 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
544 case 0xb:
545 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
546 default:
547 return new Unknown(machInst);
548 }
549 }
550 '''
551}};
552
553def format Thumb32DataProcReg() {{
554 decode_block = '''
555 {
556 const uint32_t op1 = bits(machInst, 23, 20);
557 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
558 const uint32_t op2 = bits(machInst, 7, 4);
559 if (bits(op1, 3) != 1) {
560 if (op2 == 0) {
561 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
562 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
563 switch (bits(op1, 2, 0)) {
564 case 0x0:
565 return new MovRegReg(machInst, rd,
566 INTREG_ZERO, rn, rm, LSL);
567 case 0x1:
568 return new MovRegRegCc(machInst, rd,
569 INTREG_ZERO, rn, rm, LSL);
570 case 0x2:
571 return new MovRegReg(machInst, rd,
572 INTREG_ZERO, rn, rm, LSR);
573 case 0x3:
574 return new MovRegRegCc(machInst, rd,
575 INTREG_ZERO, rn, rm, LSR);
576 case 0x4:
577 return new MovRegReg(machInst, rd,
578 INTREG_ZERO, rn, rm, ASR);
579 case 0x5:
580 return new MovRegRegCc(machInst, rd,
581 INTREG_ZERO, rn, rm, ASR);
582 case 0x6:
583 return new MovRegReg(machInst, rd,
584 INTREG_ZERO, rn, rm, ROR);
585 case 0x7:
586 return new MovRegRegCc(machInst, rd,
587 INTREG_ZERO, rn, rm, ROR);
588 }
589 }
590 {
591 const IntRegIndex rd =
592 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
593 const IntRegIndex rm =
594 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
595 const uint32_t rotation =
596 (uint32_t)bits(machInst, 5, 4) << 3;
597 switch (bits(op1, 2, 0)) {
598 case 0x0:
599 if (rn == 0xf) {
600 return new Sxth(machInst, rd, rotation, rm);
601 } else {
602 return new Sxtah(machInst, rd, rn, rm, rotation);
603 }
604 case 0x1:
605 if (rn == 0xf) {
606 return new Uxth(machInst, rd, rotation, rm);
607 } else {
608 return new Uxtah(machInst, rd, rn, rm, rotation);
609 }
610 case 0x2:
611 if (rn == 0xf) {
612 return new Sxtb16(machInst, rd, rotation, rm);
613 } else {
614 return new Sxtab16(machInst, rd, rn, rm, rotation);
615 }
616 case 0x3:
617 if (rn == 0xf) {
618 return new Uxtb16(machInst, rd, rotation, rm);
619 } else {
620 return new Uxtab16(machInst, rd, rn, rm, rotation);
621 }
622 case 0x4:
623 if (rn == 0xf) {
624 return new Sxtb(machInst, rd, rotation, rm);
625 } else {
626 return new Sxtab(machInst, rd, rn, rm, rotation);
627 }
628 case 0x5:
629 if (rn == 0xf) {
630 return new Uxtb(machInst, rd, rotation, rm);
631 } else {
632 return new Uxtab(machInst, rd, rn, rm, rotation);
633 }
634 default:
635 return new Unknown(machInst);
636 }
637 }
638 } else {
639 if (bits(op2, 3) == 0) {
640 const IntRegIndex rd =
641 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
642 const IntRegIndex rm =
643 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
644 if (bits(op2, 2) == 0x0) {
645 const uint32_t op1 = bits(machInst, 22, 20);
646 const uint32_t op2 = bits(machInst, 5, 4);
647 switch (op2) {
648 case 0x0:
649 switch (op1) {
650 case 0x1:
651 return new Sadd16RegCc(machInst, rd,
652 rn, rm, 0, LSL);
653 case 0x2:
654 return new SasxRegCc(machInst, rd,
655 rn, rm, 0, LSL);
656 case 0x6:
657 return new SsaxRegCc(machInst, rd,
658 rn, rm, 0, LSL);
659 case 0x5:
660 return new Ssub16RegCc(machInst, rd,
661 rn, rm, 0, LSL);
662 case 0x0:
663 return new Sadd8RegCc(machInst, rd,
664 rn, rm, 0, LSL);
665 case 0x4:
666 return new Ssub8RegCc(machInst, rd,
667 rn, rm, 0, LSL);
668 }
669 break;
670 case 0x1:
671 switch (op1) {
672 case 0x1:
673 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
674 case 0x2:
675 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
676 case 0x6:
677 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
678 case 0x5:
679 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
680 case 0x0:
681 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
682 case 0x4:
683 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
684 }
685 break;
686 case 0x2:
687 switch (op1) {
688 case 0x1:
689 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
690 case 0x2:
691 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
692 case 0x6:
693 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
694 case 0x5:
695 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
696 case 0x0:
697 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
698 case 0x4:
699 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
700 }
701 break;
702 }
703 } else {
704 const uint32_t op1 = bits(machInst, 22, 20);
705 const uint32_t op2 = bits(machInst, 5, 4);
706 switch (op2) {
707 case 0x0:
708 switch (op1) {
709 case 0x1:
710 return new Uadd16RegCc(machInst, rd,
711 rn, rm, 0, LSL);
712 case 0x2:
713 return new UasxRegCc(machInst, rd,
714 rn, rm, 0, LSL);
715 case 0x6:
716 return new UsaxRegCc(machInst, rd,
717 rn, rm, 0, LSL);
718 case 0x5:
719 return new Usub16RegCc(machInst, rd,
720 rn, rm, 0, LSL);
721 case 0x0:
722 return new Uadd8RegCc(machInst, rd,
723 rn, rm, 0, LSL);
724 case 0x4:
725 return new Usub8RegCc(machInst, rd,
726 rn, rm, 0, LSL);
727 }
728 break;
729 case 0x1:
730 switch (op1) {
731 case 0x1:
732 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
733 case 0x2:
734 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
735 case 0x6:
736 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
737 case 0x5:
738 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
739 case 0x0:
740 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
741 case 0x4:
742 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
743 }
744 break;
745 case 0x2:
746 switch (op1) {
747 case 0x1:
748 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
749 case 0x2:
750 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
751 case 0x6:
752 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
753 case 0x5:
754 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
755 case 0x0:
756 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
757 case 0x4:
758 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
759 }
760 break;
761 }
762 }
763 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
764 const uint32_t op1 = bits(machInst, 21, 20);
765 const uint32_t op2 = bits(machInst, 5, 4);
766 const IntRegIndex rd =
767 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
768 const IntRegIndex rm =
769 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
770 switch (op1) {
771 case 0x0:
772 switch (op2) {
773 case 0x0:
774 return new QaddRegCc(machInst, rd,
775 rm, rn, 0, LSL);
776 case 0x1:
777 return new QdaddRegCc(machInst, rd,
778 rm, rn, 0, LSL);
779 case 0x2:
780 return new QsubRegCc(machInst, rd,
781 rm, rn, 0, LSL);
782 case 0x3:
783 return new QdsubRegCc(machInst, rd,
784 rm, rn, 0, LSL);
785 }
786 break;
787 case 0x1:
788 switch (op2) {
789 case 0x0:
790 return new Rev(machInst, rd, rn);
791 case 0x1:
792 return new Rev16(machInst, rd, rn);
793 case 0x2:
794 return new Rbit(machInst, rd, rm);
795 case 0x3:
796 return new Revsh(machInst, rd, rn);
797 }
798 break;
799 case 0x2:
800 if (op2 == 0) {
801 return new Sel(machInst, rd, rn, rm);
802 }
803 break;
804 case 0x3:
805 if (op2 == 0) {
806 return new WarnUnimplemented("clz", machInst);
806 return new Clz(machInst, rd, rm);
807 }
808 }
809 }
810 return new Unknown(machInst);
811 }
812 }
813 '''
814}};
815
816def format Thumb16ShiftAddSubMoveCmp() {{
817 decode_block = '''
818 {
819 const uint32_t imm5 = bits(machInst, 10, 6);
820 const uint32_t imm3 = bits(machInst, 8, 6);
821 const uint32_t imm8 = bits(machInst, 7, 0);
822 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
823 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
824 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
825 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
826 switch (bits(machInst, 13, 11)) {
827 case 0x0: // lsl
828 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
829 case 0x1: // lsr
830 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
831 case 0x2: // asr
832 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
833 case 0x3:
834 switch (bits(machInst, 10, 9)) {
835 case 0x0:
836 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
837 case 0x1:
838 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
839 case 0x2:
840 return new AddImmCc(machInst, rd, rn, imm3, true);
841 case 0x3:
842 return new SubImmCc(machInst, rd, rn, imm3, true);
843 }
844 case 0x4:
845 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
846 case 0x5:
847 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
848 case 0x6:
849 return new AddImmCc(machInst, rd8, rd8, imm8, true);
850 case 0x7:
851 return new SubImmCc(machInst, rd8, rd8, imm8, true);
852 }
853 }
854 '''
855}};
856
857def format Thumb16DataProcessing() {{
858 decode_block = '''
859 {
860 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
861 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
862 switch (bits(machInst, 9, 6)) {
863 case 0x0:
864 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
865 case 0x1:
866 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
867 case 0x2: //lsl
868 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
869 case 0x3: //lsr
870 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
871 case 0x4: //asr
872 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
873 case 0x5:
874 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
875 case 0x6:
876 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
877 case 0x7: // ror
878 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
879 case 0x8:
880 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
881 case 0x9:
882 return new RsbImmCc(machInst, rdn, rm, 0, true);
883 case 0xa:
884 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
885 case 0xb:
886 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
887 case 0xc:
888 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
889 case 0xd:
890 return new MulCc(machInst, rdn, rm, rdn);
891 case 0xe:
892 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
893 case 0xf:
894 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
895 }
896 }
897 '''
898}};
899
900def format Thumb16SpecDataAndBx() {{
901 decode_block = '''
902 {
903 const IntRegIndex rdn =
904 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
905 (bits(machInst, 7) << 3));
906 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
907 switch (bits(machInst, 9, 8)) {
908 case 0x0:
909 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
910 case 0x1:
911 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
912 case 0x2:
913 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
914 case 0x3:
915 if (bits(machInst, 7) == 0) {
916 return new BxReg(machInst,
917 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
918 COND_UC);
919 } else {
920 return new BlxReg(machInst,
921 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
922 COND_UC);
923 }
924 }
925 }
926 '''
927}};
928
929def format Thumb16Adr() {{
930 decode_block = '''
931 {
932 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
933 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
934 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
935 }
936 '''
937}};
938
939def format Thumb16AddSp() {{
940 decode_block = '''
941 {
942 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
943 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
944 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
945 }
946 '''
947}};
948
949def format Thumb16Misc() {{
950 decode_block = '''
951 {
952 switch (bits(machInst, 11, 8)) {
953 case 0x0:
954 if (bits(machInst, 7)) {
955 return new SubImm(machInst, INTREG_SP, INTREG_SP,
956 bits(machInst, 6, 0) << 2, true);
957 } else {
958 return new AddImm(machInst, INTREG_SP, INTREG_SP,
959 bits(machInst, 6, 0) << 2, true);
960 }
961 case 0x1:
962 return new Cbz(machInst,
963 (bits(machInst, 9) << 6) |
964 (bits(machInst, 7, 3) << 1),
965 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
966 case 0x2:
967 {
968 const IntRegIndex rd =
969 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
970 const IntRegIndex rm =
971 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
972 switch (bits(machInst, 7, 6)) {
973 case 0x0:
974 return new Sxth(machInst, rd, 0, rm);
975 case 0x1:
976 return new Sxtb(machInst, rd, 0, rm);
977 case 0x2:
978 return new Uxth(machInst, rd, 0, rm);
979 case 0x3:
980 return new Uxtb(machInst, rd, 0, rm);
981 }
982 }
983 case 0x3:
984 return new Cbz(machInst,
985 (bits(machInst, 9) << 6) |
986 (bits(machInst, 7, 3) << 1),
987 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
988 case 0x4:
989 case 0x5:
990 {
991 const uint32_t m = bits(machInst, 8);
992 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
993 return new LdmStm(machInst, INTREG_SP, false, false, false,
994 true, false, regList);
995 }
996 case 0x6:
997 {
998 const uint32_t opBits = bits(machInst, 7, 5);
999 if (opBits == 2) {
1000 return new WarnUnimplemented("setend", machInst);
1001 } else if (opBits == 3) {
1002 return new WarnUnimplemented("cps", machInst);
1003 }
1004 }
1005 case 0x9:
1006 return new Cbnz(machInst,
1007 (bits(machInst, 9) << 6) |
1008 (bits(machInst, 7, 3) << 1),
1009 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1010 case 0xa:
1011 {
1012 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1013 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1014 switch (bits(machInst, 7, 6)) {
1015 case 0x0:
1016 return new Rev(machInst, rd, rm);
1017 case 0x1:
1018 return new Rev16(machInst, rd, rm);
1019 case 0x3:
1020 return new Revsh(machInst, rd, rm);
1021 default:
1022 break;
1023 }
1024 }
1025 break;
1026 case 0xb:
1027 return new Cbnz(machInst,
1028 (bits(machInst, 9) << 6) |
1029 (bits(machInst, 7, 3) << 1),
1030 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1031 case 0xc:
1032 case 0xd:
1033 {
1034 const uint32_t p = bits(machInst, 8);
1035 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1036 return new LdmStm(machInst, INTREG_SP, true, true, false,
1037 true, true, regList);
1038 }
1039 case 0xe:
1040 return new WarnUnimplemented("bkpt", machInst);
1041 case 0xf:
1042 if (bits(machInst, 3, 0) != 0)
1043 return new WarnUnimplemented("it", machInst);
1044 switch (bits(machInst, 7, 4)) {
1045 case 0x0:
1046 return new NopInst(machInst);
1047 case 0x1:
1048 return new WarnUnimplemented("yield", machInst);
1049 case 0x2:
1050 return new WarnUnimplemented("wfe", machInst);
1051 case 0x3:
1052 return new WarnUnimplemented("wfi", machInst);
1053 case 0x4:
1054 return new WarnUnimplemented("sev", machInst);
1055 default:
1056 return new WarnUnimplemented("unallocated_hint", machInst);
1057 }
1058 default:
1059 break;
1060 }
1061 return new Unknown(machInst);
1062 }
1063 '''
1064}};
1065
1066def format Thumb32DataProcModImm() {{
1067
1068 def decInst(mnem, dest="rd", op1="rn"):
1069 return '''
1070 if (s) {
1071 return new %(mnem)sImmCc(machInst, %(dest)s,
1072 %(op1)s, imm, rotC);
1073 } else {
1074 return new %(mnem)sImm(machInst, %(dest)s,
1075 %(op1)s, imm, rotC);
1076 }
1077 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1078
1079 decode_block = '''
1080 {
1081 const uint32_t op = bits(machInst, 24, 21);
1082 const bool s = (bits(machInst, 20) == 1);
1083 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1084 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1085 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1086 bits(machInst, 14, 12);
1087 const bool rotC = ctrlImm > 3;
1088 const uint32_t dataImm = bits(machInst, 7, 0);
1089 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1090 switch (op) {
1091 case 0x0:
1092 if (rd == INTREG_PC) {
1093 %(tst)s
1094 } else {
1095 %(and)s
1096 }
1097 case 0x1:
1098 %(bic)s
1099 case 0x2:
1100 if (rn == INTREG_PC) {
1101 %(mov)s
1102 } else {
1103 %(orr)s
1104 }
1105 case 0x3:
1106 if (rn == INTREG_PC) {
1107 %(mvn)s
1108 } else {
1109 %(orn)s
1110 }
1111 case 0x4:
1112 if (rd == INTREG_PC) {
1113 %(teq)s
1114 } else {
1115 %(eor)s
1116 }
1117 case 0x8:
1118 if (rd == INTREG_PC) {
1119 %(cmn)s
1120 } else {
1121 %(add)s
1122 }
1123 case 0xa:
1124 %(adc)s
1125 case 0xb:
1126 %(sbc)s
1127 case 0xd:
1128 if (rd == INTREG_PC) {
1129 %(cmp)s
1130 } else {
1131 %(sub)s
1132 }
1133 case 0xe:
1134 %(rsb)s
1135 default:
1136 return new Unknown(machInst);
1137 }
1138 }
1139 ''' % {
1140 "tst" : decInst("Tst", "INTREG_ZERO"),
1141 "and" : decInst("And"),
1142 "bic" : decInst("Bic"),
1143 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1144 "orr" : decInst("Orr"),
1145 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1146 "orn" : decInst("Orn"),
1147 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1148 "eor" : decInst("Eor"),
1149 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1150 "add" : decInst("Add"),
1151 "adc" : decInst("Adc"),
1152 "sbc" : decInst("Sbc"),
1153 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1154 "sub" : decInst("Sub"),
1155 "rsb" : decInst("Rsb")
1156 }
1157}};
1158
1159def format Thumb32DataProcPlainBin() {{
1160 decode_block = '''
1161 {
1162 const uint32_t op = bits(machInst, 24, 20);
1163 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1164 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1165 switch (op) {
1166 case 0x0:
1167 {
1168 const uint32_t imm = bits(machInst, 7, 0) |
1169 (bits(machInst, 14, 12) << 8) |
1170 (bits(machInst, 26) << 11);
1171 if (rn == 0xf) {
1172 return new AdrImm(machInst, rd, (IntRegIndex)1,
1173 imm, false);
1174 } else {
1175 return new AddImm(machInst, rd, rn, imm, true);
1176 }
1177 }
1178 case 0x4:
1179 {
1180 const uint32_t imm = bits(machInst, 7, 0) |
1181 (bits(machInst, 14, 12) << 8) |
1182 (bits(machInst, 26) << 11) |
1183 (bits(machInst, 19, 16) << 12);
1184 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1185 }
1186 case 0xa:
1187 {
1188 const uint32_t imm = bits(machInst, 7, 0) |
1189 (bits(machInst, 14, 12) << 8) |
1190 (bits(machInst, 26) << 11);
1191 if (rn == 0xf) {
1192 return new AdrImm(machInst, rd, (IntRegIndex)0,
1193 imm, false);
1194 } else {
1195 return new SubImm(machInst, rd, rn, imm, true);
1196 }
1197 }
1198 case 0xc:
1199 {
1200 const uint32_t imm = bits(machInst, 7, 0) |
1201 (bits(machInst, 14, 12) << 8) |
1202 (bits(machInst, 26) << 11) |
1203 (bits(machInst, 19, 16) << 12);
1204 return new MovtImm(machInst, rd, rd, imm, true);
1205 }
1206 case 0x12:
1207 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1208 const uint32_t satImm = bits(machInst, 4, 0);
1209 return new Ssat16(machInst, rd, satImm + 1, rn);
1210 }
1211 // Fall through on purpose...
1212 case 0x10:
1213 {
1214 const uint32_t satImm = bits(machInst, 4, 0);
1215 const uint32_t imm = bits(machInst, 7, 6) |
1216 (bits(machInst, 14, 12) << 2);
1217 const ArmShiftType type =
1218 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1219 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1220 }
1221 case 0x14:
1222 return new WarnUnimplemented("sbfx", machInst);
1223 case 0x16:
1224 if (rn == 0xf) {
1225 return new WarnUnimplemented("bfc", machInst);
1226 } else {
1227 return new WarnUnimplemented("bfi", machInst);
1228 }
1229 case 0x1a:
1230 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1231 const uint32_t satImm = bits(machInst, 4, 0);
1232 return new Usat16(machInst, rd, satImm, rn);
1233 }
1234 // Fall through on purpose...
1235 case 0x18:
1236 {
1237 const uint32_t satImm = bits(machInst, 4, 0);
1238 const uint32_t imm = bits(machInst, 7, 6) |
1239 (bits(machInst, 14, 12) << 2);
1240 const ArmShiftType type =
1241 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1242 return new Usat(machInst, rd, satImm, rn, imm, type);
1243 }
1244 case 0x1c:
1245 return new WarnUnimplemented("ubfx", machInst);
1246 default:
1247 return new Unknown(machInst);
1248 }
1249 }
1250 '''
1251}};
1252
1253def format Thumb32DataProcShiftReg() {{
1254
1255 def decInst(mnem, dest="rd", op1="rn"):
1256 return '''
1257 if (s) {
1258 return new %(mnem)sRegCc(machInst, %(dest)s,
1259 %(op1)s, rm, amt, type);
1260 } else {
1261 return new %(mnem)sReg(machInst, %(dest)s,
1262 %(op1)s, rm, amt, type);
1263 }
1264 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1265
1266 decode_block = '''
1267 {
1268 const uint32_t op = bits(machInst, 24, 21);
1269 const bool s = (bits(machInst, 20) == 1);
1270 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1271 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1272 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1273 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1274 bits(machInst, 7, 6);
1275 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1276 switch (op) {
1277 case 0x0:
1278 if (rd == INTREG_PC) {
1279 %(tst)s
1280 } else {
1281 %(and)s
1282 }
1283 case 0x1:
1284 %(bic)s
1285 case 0x2:
1286 if (rn == INTREG_PC) {
1287 %(mov)s
1288 } else {
1289 %(orr)s
1290 }
1291 case 0x3:
1292 if (rn == INTREG_PC) {
1293 %(mvn)s
1294 } else {
1295 %(orn)s
1296 }
1297 case 0x4:
1298 if (rd == INTREG_PC) {
1299 %(teq)s
1300 } else {
1301 %(eor)s
1302 }
1303 case 0x6:
1304 if (type) {
1305 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1306 } else {
1307 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1308 }
1309 case 0x8:
1310 if (rd == INTREG_PC) {
1311 %(cmn)s
1312 } else {
1313 %(add)s
1314 }
1315 case 0xa:
1316 %(adc)s
1317 case 0xb:
1318 %(sbc)s
1319 case 0xd:
1320 if (rd == INTREG_PC) {
1321 %(cmp)s
1322 } else {
1323 %(sub)s
1324 }
1325 case 0xe:
1326 %(rsb)s
1327 default:
1328 return new Unknown(machInst);
1329 }
1330 }
1331 ''' % {
1332 "tst" : decInst("Tst", "INTREG_ZERO"),
1333 "and" : decInst("And"),
1334 "bic" : decInst("Bic"),
1335 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1336 "orr" : decInst("Orr"),
1337 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1338 "orn" : decInst("Orn"),
1339 "teq" : decInst("Teq", "INTREG_ZERO"),
1340 "eor" : decInst("Eor"),
1341 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1342 "add" : decInst("Add"),
1343 "adc" : decInst("Adc"),
1344 "sbc" : decInst("Sbc"),
1345 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1346 "sub" : decInst("Sub"),
1347 "rsb" : decInst("Rsb")
1348 }
1349}};
807 }
808 }
809 }
810 return new Unknown(machInst);
811 }
812 }
813 '''
814}};
815
816def format Thumb16ShiftAddSubMoveCmp() {{
817 decode_block = '''
818 {
819 const uint32_t imm5 = bits(machInst, 10, 6);
820 const uint32_t imm3 = bits(machInst, 8, 6);
821 const uint32_t imm8 = bits(machInst, 7, 0);
822 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
823 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
824 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
825 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
826 switch (bits(machInst, 13, 11)) {
827 case 0x0: // lsl
828 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
829 case 0x1: // lsr
830 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
831 case 0x2: // asr
832 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
833 case 0x3:
834 switch (bits(machInst, 10, 9)) {
835 case 0x0:
836 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
837 case 0x1:
838 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
839 case 0x2:
840 return new AddImmCc(machInst, rd, rn, imm3, true);
841 case 0x3:
842 return new SubImmCc(machInst, rd, rn, imm3, true);
843 }
844 case 0x4:
845 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
846 case 0x5:
847 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
848 case 0x6:
849 return new AddImmCc(machInst, rd8, rd8, imm8, true);
850 case 0x7:
851 return new SubImmCc(machInst, rd8, rd8, imm8, true);
852 }
853 }
854 '''
855}};
856
857def format Thumb16DataProcessing() {{
858 decode_block = '''
859 {
860 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
861 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
862 switch (bits(machInst, 9, 6)) {
863 case 0x0:
864 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
865 case 0x1:
866 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
867 case 0x2: //lsl
868 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
869 case 0x3: //lsr
870 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
871 case 0x4: //asr
872 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
873 case 0x5:
874 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
875 case 0x6:
876 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
877 case 0x7: // ror
878 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
879 case 0x8:
880 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
881 case 0x9:
882 return new RsbImmCc(machInst, rdn, rm, 0, true);
883 case 0xa:
884 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
885 case 0xb:
886 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
887 case 0xc:
888 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
889 case 0xd:
890 return new MulCc(machInst, rdn, rm, rdn);
891 case 0xe:
892 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
893 case 0xf:
894 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
895 }
896 }
897 '''
898}};
899
900def format Thumb16SpecDataAndBx() {{
901 decode_block = '''
902 {
903 const IntRegIndex rdn =
904 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
905 (bits(machInst, 7) << 3));
906 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
907 switch (bits(machInst, 9, 8)) {
908 case 0x0:
909 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
910 case 0x1:
911 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
912 case 0x2:
913 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
914 case 0x3:
915 if (bits(machInst, 7) == 0) {
916 return new BxReg(machInst,
917 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
918 COND_UC);
919 } else {
920 return new BlxReg(machInst,
921 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
922 COND_UC);
923 }
924 }
925 }
926 '''
927}};
928
929def format Thumb16Adr() {{
930 decode_block = '''
931 {
932 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
933 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
934 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
935 }
936 '''
937}};
938
939def format Thumb16AddSp() {{
940 decode_block = '''
941 {
942 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
943 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
944 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
945 }
946 '''
947}};
948
949def format Thumb16Misc() {{
950 decode_block = '''
951 {
952 switch (bits(machInst, 11, 8)) {
953 case 0x0:
954 if (bits(machInst, 7)) {
955 return new SubImm(machInst, INTREG_SP, INTREG_SP,
956 bits(machInst, 6, 0) << 2, true);
957 } else {
958 return new AddImm(machInst, INTREG_SP, INTREG_SP,
959 bits(machInst, 6, 0) << 2, true);
960 }
961 case 0x1:
962 return new Cbz(machInst,
963 (bits(machInst, 9) << 6) |
964 (bits(machInst, 7, 3) << 1),
965 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
966 case 0x2:
967 {
968 const IntRegIndex rd =
969 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
970 const IntRegIndex rm =
971 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
972 switch (bits(machInst, 7, 6)) {
973 case 0x0:
974 return new Sxth(machInst, rd, 0, rm);
975 case 0x1:
976 return new Sxtb(machInst, rd, 0, rm);
977 case 0x2:
978 return new Uxth(machInst, rd, 0, rm);
979 case 0x3:
980 return new Uxtb(machInst, rd, 0, rm);
981 }
982 }
983 case 0x3:
984 return new Cbz(machInst,
985 (bits(machInst, 9) << 6) |
986 (bits(machInst, 7, 3) << 1),
987 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
988 case 0x4:
989 case 0x5:
990 {
991 const uint32_t m = bits(machInst, 8);
992 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
993 return new LdmStm(machInst, INTREG_SP, false, false, false,
994 true, false, regList);
995 }
996 case 0x6:
997 {
998 const uint32_t opBits = bits(machInst, 7, 5);
999 if (opBits == 2) {
1000 return new WarnUnimplemented("setend", machInst);
1001 } else if (opBits == 3) {
1002 return new WarnUnimplemented("cps", machInst);
1003 }
1004 }
1005 case 0x9:
1006 return new Cbnz(machInst,
1007 (bits(machInst, 9) << 6) |
1008 (bits(machInst, 7, 3) << 1),
1009 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1010 case 0xa:
1011 {
1012 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1013 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1014 switch (bits(machInst, 7, 6)) {
1015 case 0x0:
1016 return new Rev(machInst, rd, rm);
1017 case 0x1:
1018 return new Rev16(machInst, rd, rm);
1019 case 0x3:
1020 return new Revsh(machInst, rd, rm);
1021 default:
1022 break;
1023 }
1024 }
1025 break;
1026 case 0xb:
1027 return new Cbnz(machInst,
1028 (bits(machInst, 9) << 6) |
1029 (bits(machInst, 7, 3) << 1),
1030 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1031 case 0xc:
1032 case 0xd:
1033 {
1034 const uint32_t p = bits(machInst, 8);
1035 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1036 return new LdmStm(machInst, INTREG_SP, true, true, false,
1037 true, true, regList);
1038 }
1039 case 0xe:
1040 return new WarnUnimplemented("bkpt", machInst);
1041 case 0xf:
1042 if (bits(machInst, 3, 0) != 0)
1043 return new WarnUnimplemented("it", machInst);
1044 switch (bits(machInst, 7, 4)) {
1045 case 0x0:
1046 return new NopInst(machInst);
1047 case 0x1:
1048 return new WarnUnimplemented("yield", machInst);
1049 case 0x2:
1050 return new WarnUnimplemented("wfe", machInst);
1051 case 0x3:
1052 return new WarnUnimplemented("wfi", machInst);
1053 case 0x4:
1054 return new WarnUnimplemented("sev", machInst);
1055 default:
1056 return new WarnUnimplemented("unallocated_hint", machInst);
1057 }
1058 default:
1059 break;
1060 }
1061 return new Unknown(machInst);
1062 }
1063 '''
1064}};
1065
1066def format Thumb32DataProcModImm() {{
1067
1068 def decInst(mnem, dest="rd", op1="rn"):
1069 return '''
1070 if (s) {
1071 return new %(mnem)sImmCc(machInst, %(dest)s,
1072 %(op1)s, imm, rotC);
1073 } else {
1074 return new %(mnem)sImm(machInst, %(dest)s,
1075 %(op1)s, imm, rotC);
1076 }
1077 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1078
1079 decode_block = '''
1080 {
1081 const uint32_t op = bits(machInst, 24, 21);
1082 const bool s = (bits(machInst, 20) == 1);
1083 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1084 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1085 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1086 bits(machInst, 14, 12);
1087 const bool rotC = ctrlImm > 3;
1088 const uint32_t dataImm = bits(machInst, 7, 0);
1089 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1090 switch (op) {
1091 case 0x0:
1092 if (rd == INTREG_PC) {
1093 %(tst)s
1094 } else {
1095 %(and)s
1096 }
1097 case 0x1:
1098 %(bic)s
1099 case 0x2:
1100 if (rn == INTREG_PC) {
1101 %(mov)s
1102 } else {
1103 %(orr)s
1104 }
1105 case 0x3:
1106 if (rn == INTREG_PC) {
1107 %(mvn)s
1108 } else {
1109 %(orn)s
1110 }
1111 case 0x4:
1112 if (rd == INTREG_PC) {
1113 %(teq)s
1114 } else {
1115 %(eor)s
1116 }
1117 case 0x8:
1118 if (rd == INTREG_PC) {
1119 %(cmn)s
1120 } else {
1121 %(add)s
1122 }
1123 case 0xa:
1124 %(adc)s
1125 case 0xb:
1126 %(sbc)s
1127 case 0xd:
1128 if (rd == INTREG_PC) {
1129 %(cmp)s
1130 } else {
1131 %(sub)s
1132 }
1133 case 0xe:
1134 %(rsb)s
1135 default:
1136 return new Unknown(machInst);
1137 }
1138 }
1139 ''' % {
1140 "tst" : decInst("Tst", "INTREG_ZERO"),
1141 "and" : decInst("And"),
1142 "bic" : decInst("Bic"),
1143 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1144 "orr" : decInst("Orr"),
1145 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1146 "orn" : decInst("Orn"),
1147 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1148 "eor" : decInst("Eor"),
1149 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1150 "add" : decInst("Add"),
1151 "adc" : decInst("Adc"),
1152 "sbc" : decInst("Sbc"),
1153 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1154 "sub" : decInst("Sub"),
1155 "rsb" : decInst("Rsb")
1156 }
1157}};
1158
1159def format Thumb32DataProcPlainBin() {{
1160 decode_block = '''
1161 {
1162 const uint32_t op = bits(machInst, 24, 20);
1163 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1164 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1165 switch (op) {
1166 case 0x0:
1167 {
1168 const uint32_t imm = bits(machInst, 7, 0) |
1169 (bits(machInst, 14, 12) << 8) |
1170 (bits(machInst, 26) << 11);
1171 if (rn == 0xf) {
1172 return new AdrImm(machInst, rd, (IntRegIndex)1,
1173 imm, false);
1174 } else {
1175 return new AddImm(machInst, rd, rn, imm, true);
1176 }
1177 }
1178 case 0x4:
1179 {
1180 const uint32_t imm = bits(machInst, 7, 0) |
1181 (bits(machInst, 14, 12) << 8) |
1182 (bits(machInst, 26) << 11) |
1183 (bits(machInst, 19, 16) << 12);
1184 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1185 }
1186 case 0xa:
1187 {
1188 const uint32_t imm = bits(machInst, 7, 0) |
1189 (bits(machInst, 14, 12) << 8) |
1190 (bits(machInst, 26) << 11);
1191 if (rn == 0xf) {
1192 return new AdrImm(machInst, rd, (IntRegIndex)0,
1193 imm, false);
1194 } else {
1195 return new SubImm(machInst, rd, rn, imm, true);
1196 }
1197 }
1198 case 0xc:
1199 {
1200 const uint32_t imm = bits(machInst, 7, 0) |
1201 (bits(machInst, 14, 12) << 8) |
1202 (bits(machInst, 26) << 11) |
1203 (bits(machInst, 19, 16) << 12);
1204 return new MovtImm(machInst, rd, rd, imm, true);
1205 }
1206 case 0x12:
1207 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1208 const uint32_t satImm = bits(machInst, 4, 0);
1209 return new Ssat16(machInst, rd, satImm + 1, rn);
1210 }
1211 // Fall through on purpose...
1212 case 0x10:
1213 {
1214 const uint32_t satImm = bits(machInst, 4, 0);
1215 const uint32_t imm = bits(machInst, 7, 6) |
1216 (bits(machInst, 14, 12) << 2);
1217 const ArmShiftType type =
1218 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1219 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1220 }
1221 case 0x14:
1222 return new WarnUnimplemented("sbfx", machInst);
1223 case 0x16:
1224 if (rn == 0xf) {
1225 return new WarnUnimplemented("bfc", machInst);
1226 } else {
1227 return new WarnUnimplemented("bfi", machInst);
1228 }
1229 case 0x1a:
1230 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1231 const uint32_t satImm = bits(machInst, 4, 0);
1232 return new Usat16(machInst, rd, satImm, rn);
1233 }
1234 // Fall through on purpose...
1235 case 0x18:
1236 {
1237 const uint32_t satImm = bits(machInst, 4, 0);
1238 const uint32_t imm = bits(machInst, 7, 6) |
1239 (bits(machInst, 14, 12) << 2);
1240 const ArmShiftType type =
1241 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1242 return new Usat(machInst, rd, satImm, rn, imm, type);
1243 }
1244 case 0x1c:
1245 return new WarnUnimplemented("ubfx", machInst);
1246 default:
1247 return new Unknown(machInst);
1248 }
1249 }
1250 '''
1251}};
1252
1253def format Thumb32DataProcShiftReg() {{
1254
1255 def decInst(mnem, dest="rd", op1="rn"):
1256 return '''
1257 if (s) {
1258 return new %(mnem)sRegCc(machInst, %(dest)s,
1259 %(op1)s, rm, amt, type);
1260 } else {
1261 return new %(mnem)sReg(machInst, %(dest)s,
1262 %(op1)s, rm, amt, type);
1263 }
1264 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1265
1266 decode_block = '''
1267 {
1268 const uint32_t op = bits(machInst, 24, 21);
1269 const bool s = (bits(machInst, 20) == 1);
1270 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1271 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1272 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1273 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1274 bits(machInst, 7, 6);
1275 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1276 switch (op) {
1277 case 0x0:
1278 if (rd == INTREG_PC) {
1279 %(tst)s
1280 } else {
1281 %(and)s
1282 }
1283 case 0x1:
1284 %(bic)s
1285 case 0x2:
1286 if (rn == INTREG_PC) {
1287 %(mov)s
1288 } else {
1289 %(orr)s
1290 }
1291 case 0x3:
1292 if (rn == INTREG_PC) {
1293 %(mvn)s
1294 } else {
1295 %(orn)s
1296 }
1297 case 0x4:
1298 if (rd == INTREG_PC) {
1299 %(teq)s
1300 } else {
1301 %(eor)s
1302 }
1303 case 0x6:
1304 if (type) {
1305 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1306 } else {
1307 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1308 }
1309 case 0x8:
1310 if (rd == INTREG_PC) {
1311 %(cmn)s
1312 } else {
1313 %(add)s
1314 }
1315 case 0xa:
1316 %(adc)s
1317 case 0xb:
1318 %(sbc)s
1319 case 0xd:
1320 if (rd == INTREG_PC) {
1321 %(cmp)s
1322 } else {
1323 %(sub)s
1324 }
1325 case 0xe:
1326 %(rsb)s
1327 default:
1328 return new Unknown(machInst);
1329 }
1330 }
1331 ''' % {
1332 "tst" : decInst("Tst", "INTREG_ZERO"),
1333 "and" : decInst("And"),
1334 "bic" : decInst("Bic"),
1335 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1336 "orr" : decInst("Orr"),
1337 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1338 "orn" : decInst("Orn"),
1339 "teq" : decInst("Teq", "INTREG_ZERO"),
1340 "eor" : decInst("Eor"),
1341 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1342 "add" : decInst("Add"),
1343 "adc" : decInst("Adc"),
1344 "sbc" : decInst("Sbc"),
1345 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1346 "sub" : decInst("Sub"),
1347 "rsb" : decInst("Rsb")
1348 }
1349}};