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