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