data.isa (13354:c1bdac713ae5) data.isa (14031:7edee4296f90)
1// Copyright (c) 2010,2017-2018 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 if (%(dest)s == INTREG_PC) {
80 return new %(className)ssRegPclr(machInst, %(dest)s,
81 %(op1)s, rm, imm5,
82 type);
83 } else
84 '''
85 instDecode = '''
86 case %(opcode)#x:
87 if (immShift) {
88 if (setCc) {
89 %(pclr)s {
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 if (%(dest)s == INTREG_PC) {
456 return new %(className)ssImmPclr(machInst, %(dest)s,
457 %(op1)s, imm, false);
458 } else
459 '''
460 adr = '''
461 if (%(op1)s == INTREG_PC) {
462 return new AdrImm(machInst, %(dest)s, %(add)s,
463 imm, false);
464 } else
465 '''
466 instDecode = '''
467 case %(opcode)#x:
468 if (setCc) {
469 %(pclr)s {
470 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
471 imm, rotC);
472 }
473 } else {
474 %(adr)s {
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 if useDest:
498 substDict["pclr"] = pclr % substDict
499 else:
500 substDict["pclr"] = ""
501 return instDecode % substDict
502
503 def adrCode(opcode, mnem, add="1"):
504 global instDecode, pclr, adr
505 substDict = { "className": mnem.capitalize(),
506 "opcode": opcode,
507 "dest": "rd",
508 "op1": "rn",
509 "add": add }
510 substDict["pclr"] = pclr % substDict
511 substDict["adr"] = adr % substDict
512 return instDecode % substDict
513
514 decode_block = '''
515 {
516 const bool setCc = (bits(machInst, 20) == 1);
517 const uint32_t unrotated = bits(machInst, 7, 0);
518 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
519 const bool rotC = (rotation != 0);
520 const uint32_t imm = rotate_imm(unrotated, rotation);
521 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
522 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
523 switch (OPCODE) {
524 '''
525 decode_block += instCode(0x0, "and")
526 decode_block += instCode(0x1, "eor")
527 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
528 decode_block += instCode(0x3, "rsb")
529 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
530 decode_block += instCode(0x5, "adc")
531 decode_block += instCode(0x6, "sbc")
532 decode_block += instCode(0x7, "rsc")
533 decode_block += instCode(0x8, "tst", useDest = False)
534 decode_block += instCode(0x9, "teq", useDest = False)
535 decode_block += instCode(0xa, "cmp", useDest = False)
536 decode_block += instCode(0xb, "cmn", useDest = False)
537 decode_block += instCode(0xc, "orr")
538 decode_block += instCode(0xd, "mov", useOp1 = False)
539 decode_block += instCode(0xe, "bic")
540 decode_block += instCode(0xf, "mvn", useOp1 = False)
541 decode_block += '''
542 default:
543 return new Unknown(machInst);
544 }
545 }
546 '''
547}};
548
549def format ArmSatAddSub() {{
550 decode_block = '''
551 {
552 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
553 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
554 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
555 switch (OPCODE) {
556 case 0x8:
557 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
558 case 0x9:
559 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
560 case 0xa:
561 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
562 case 0xb:
563 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
564 default:
565 return new Unknown(machInst);
566 }
567 }
568 '''
569}};
570
571def format Thumb32DataProcReg() {{
572 decode_block = '''
573 {
574 const uint32_t op1 = bits(machInst, 23, 20);
575 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
576 const uint32_t op2 = bits(machInst, 7, 4);
577 if (bits(machInst, 15, 12) != 0xf) {
578 return new Unknown(machInst);
579 }
580 if (bits(op1, 3) != 1) {
581 if (op2 == 0) {
582 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
583 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
584 switch (bits(op1, 2, 0)) {
585 case 0x0:
586 return new MovRegReg(machInst, rd,
587 INTREG_ZERO, rn, rm, LSL);
588 case 0x1:
589 return new MovRegRegCc(machInst, rd,
590 INTREG_ZERO, rn, rm, LSL);
591 case 0x2:
592 return new MovRegReg(machInst, rd,
593 INTREG_ZERO, rn, rm, LSR);
594 case 0x3:
595 return new MovRegRegCc(machInst, rd,
596 INTREG_ZERO, rn, rm, LSR);
597 case 0x4:
598 return new MovRegReg(machInst, rd,
599 INTREG_ZERO, rn, rm, ASR);
600 case 0x5:
601 return new MovRegRegCc(machInst, rd,
602 INTREG_ZERO, rn, rm, ASR);
603 case 0x6:
604 return new MovRegReg(machInst, rd,
605 INTREG_ZERO, rn, rm, ROR);
606 case 0x7:
607 return new MovRegRegCc(machInst, rd,
608 INTREG_ZERO, rn, rm, ROR);
609 default:
610 M5_UNREACHABLE;
611 }
612 } else if (bits(op2, 3) == 0) {
613 return new Unknown(machInst);
614 } else {
615 const IntRegIndex rd =
616 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
617 const IntRegIndex rm =
618 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
619 const uint32_t rotation =
620 (uint32_t)bits(machInst, 5, 4) << 3;
621 switch (bits(op1, 2, 0)) {
622 case 0x0:
623 if (rn == 0xf) {
624 return new Sxth(machInst, rd, rotation, rm);
625 } else {
626 return new Sxtah(machInst, rd, rn, rm, rotation);
627 }
628 case 0x1:
629 if (rn == 0xf) {
630 return new Uxth(machInst, rd, rotation, rm);
631 } else {
632 return new Uxtah(machInst, rd, rn, rm, rotation);
633 }
634 case 0x2:
635 if (rn == 0xf) {
636 return new Sxtb16(machInst, rd, rotation, rm);
637 } else {
638 return new Sxtab16(machInst, rd, rn, rm, rotation);
639 }
640 case 0x3:
641 if (rn == 0xf) {
642 return new Uxtb16(machInst, rd, rotation, rm);
643 } else {
644 return new Uxtab16(machInst, rd, rn, rm, rotation);
645 }
646 case 0x4:
647 if (rn == 0xf) {
648 return new Sxtb(machInst, rd, rotation, rm);
649 } else {
650 return new Sxtab(machInst, rd, rn, rm, rotation);
651 }
652 case 0x5:
653 if (rn == 0xf) {
654 return new Uxtb(machInst, rd, rotation, rm);
655 } else {
656 return new Uxtab(machInst, rd, rn, rm, rotation);
657 }
658 default:
659 return new Unknown(machInst);
660 }
661 }
662 } else {
663 if (bits(op2, 3) == 0) {
664 const IntRegIndex rd =
665 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
666 const IntRegIndex rm =
667 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
668 if (bits(op2, 2) == 0x0) {
669 const uint32_t op1 = bits(machInst, 22, 20);
670 const uint32_t op2 = bits(machInst, 5, 4);
671 switch (op2) {
672 case 0x0:
673 switch (op1) {
674 case 0x1:
675 return new Sadd16RegCc(machInst, rd,
676 rn, rm, 0, LSL);
677 case 0x2:
678 return new SasxRegCc(machInst, rd,
679 rn, rm, 0, LSL);
680 case 0x6:
681 return new SsaxRegCc(machInst, rd,
682 rn, rm, 0, LSL);
683 case 0x5:
684 return new Ssub16RegCc(machInst, rd,
685 rn, rm, 0, LSL);
686 case 0x0:
687 return new Sadd8RegCc(machInst, rd,
688 rn, rm, 0, LSL);
689 case 0x4:
690 return new Ssub8RegCc(machInst, rd,
691 rn, rm, 0, LSL);
692 }
693 break;
694 case 0x1:
695 switch (op1) {
696 case 0x1:
697 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
698 case 0x2:
699 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
700 case 0x6:
701 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
702 case 0x5:
703 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
704 case 0x0:
705 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
706 case 0x4:
707 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
708 }
709 break;
710 case 0x2:
711 switch (op1) {
712 case 0x1:
713 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
714 case 0x2:
715 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
716 case 0x6:
717 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
718 case 0x5:
719 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
720 case 0x0:
721 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
722 case 0x4:
723 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
724 }
725 break;
726 }
727 } else {
728 const uint32_t op1 = bits(machInst, 22, 20);
729 const uint32_t op2 = bits(machInst, 5, 4);
730 switch (op2) {
731 case 0x0:
732 switch (op1) {
733 case 0x1:
734 return new Uadd16RegCc(machInst, rd,
735 rn, rm, 0, LSL);
736 case 0x2:
737 return new UasxRegCc(machInst, rd,
738 rn, rm, 0, LSL);
739 case 0x6:
740 return new UsaxRegCc(machInst, rd,
741 rn, rm, 0, LSL);
742 case 0x5:
743 return new Usub16RegCc(machInst, rd,
744 rn, rm, 0, LSL);
745 case 0x0:
746 return new Uadd8RegCc(machInst, rd,
747 rn, rm, 0, LSL);
748 case 0x4:
749 return new Usub8RegCc(machInst, rd,
750 rn, rm, 0, LSL);
751 }
752 break;
753 case 0x1:
754 switch (op1) {
755 case 0x1:
756 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
757 case 0x2:
758 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
759 case 0x6:
760 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
761 case 0x5:
762 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
763 case 0x0:
764 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
765 case 0x4:
766 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
767 }
768 break;
769 case 0x2:
770 switch (op1) {
771 case 0x1:
772 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
773 case 0x2:
774 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
775 case 0x6:
776 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
777 case 0x5:
778 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
779 case 0x0:
780 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
781 case 0x4:
782 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
783 }
784 break;
785 }
786 }
787 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
788 const uint32_t op1 = bits(machInst, 22, 20);
789 const uint32_t op2 = bits(machInst, 5, 4);
790 const IntRegIndex rd =
791 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
792 const IntRegIndex rm =
793 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
794 switch (op1) {
795 case 0x0:
796 switch (op2) {
797 case 0x0:
798 return new QaddRegCc(machInst, rd,
799 rm, rn, 0, LSL);
800 case 0x1:
801 return new QdaddRegCc(machInst, rd,
802 rm, rn, 0, LSL);
803 case 0x2:
804 return new QsubRegCc(machInst, rd,
805 rm, rn, 0, LSL);
806 case 0x3:
807 return new QdsubRegCc(machInst, rd,
808 rm, rn, 0, LSL);
809 }
810 break;
811 case 0x1:
812 switch (op2) {
813 case 0x0:
814 return new Rev(machInst, rd, rn);
815 case 0x1:
816 return new Rev16(machInst, rd, rn);
817 case 0x2:
818 return new Rbit(machInst, rd, rm);
819 case 0x3:
820 return new Revsh(machInst, rd, rn);
821 }
822 break;
823 case 0x2:
824 if (op2 == 0) {
825 return new Sel(machInst, rd, rn, rm);
826 }
827 break;
828 case 0x3:
829 if (op2 == 0) {
830 return new Clz(machInst, rd, rm);
831 }
832 break;
1// Copyright (c) 2010,2017-2018 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 if (%(dest)s == INTREG_PC) {
80 return new %(className)ssRegPclr(machInst, %(dest)s,
81 %(op1)s, rm, imm5,
82 type);
83 } else
84 '''
85 instDecode = '''
86 case %(opcode)#x:
87 if (immShift) {
88 if (setCc) {
89 %(pclr)s {
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 if (%(dest)s == INTREG_PC) {
456 return new %(className)ssImmPclr(machInst, %(dest)s,
457 %(op1)s, imm, false);
458 } else
459 '''
460 adr = '''
461 if (%(op1)s == INTREG_PC) {
462 return new AdrImm(machInst, %(dest)s, %(add)s,
463 imm, false);
464 } else
465 '''
466 instDecode = '''
467 case %(opcode)#x:
468 if (setCc) {
469 %(pclr)s {
470 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
471 imm, rotC);
472 }
473 } else {
474 %(adr)s {
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 if useDest:
498 substDict["pclr"] = pclr % substDict
499 else:
500 substDict["pclr"] = ""
501 return instDecode % substDict
502
503 def adrCode(opcode, mnem, add="1"):
504 global instDecode, pclr, adr
505 substDict = { "className": mnem.capitalize(),
506 "opcode": opcode,
507 "dest": "rd",
508 "op1": "rn",
509 "add": add }
510 substDict["pclr"] = pclr % substDict
511 substDict["adr"] = adr % substDict
512 return instDecode % substDict
513
514 decode_block = '''
515 {
516 const bool setCc = (bits(machInst, 20) == 1);
517 const uint32_t unrotated = bits(machInst, 7, 0);
518 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
519 const bool rotC = (rotation != 0);
520 const uint32_t imm = rotate_imm(unrotated, rotation);
521 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
522 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
523 switch (OPCODE) {
524 '''
525 decode_block += instCode(0x0, "and")
526 decode_block += instCode(0x1, "eor")
527 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
528 decode_block += instCode(0x3, "rsb")
529 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
530 decode_block += instCode(0x5, "adc")
531 decode_block += instCode(0x6, "sbc")
532 decode_block += instCode(0x7, "rsc")
533 decode_block += instCode(0x8, "tst", useDest = False)
534 decode_block += instCode(0x9, "teq", useDest = False)
535 decode_block += instCode(0xa, "cmp", useDest = False)
536 decode_block += instCode(0xb, "cmn", useDest = False)
537 decode_block += instCode(0xc, "orr")
538 decode_block += instCode(0xd, "mov", useOp1 = False)
539 decode_block += instCode(0xe, "bic")
540 decode_block += instCode(0xf, "mvn", useOp1 = False)
541 decode_block += '''
542 default:
543 return new Unknown(machInst);
544 }
545 }
546 '''
547}};
548
549def format ArmSatAddSub() {{
550 decode_block = '''
551 {
552 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
553 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
554 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
555 switch (OPCODE) {
556 case 0x8:
557 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
558 case 0x9:
559 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
560 case 0xa:
561 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
562 case 0xb:
563 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
564 default:
565 return new Unknown(machInst);
566 }
567 }
568 '''
569}};
570
571def format Thumb32DataProcReg() {{
572 decode_block = '''
573 {
574 const uint32_t op1 = bits(machInst, 23, 20);
575 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
576 const uint32_t op2 = bits(machInst, 7, 4);
577 if (bits(machInst, 15, 12) != 0xf) {
578 return new Unknown(machInst);
579 }
580 if (bits(op1, 3) != 1) {
581 if (op2 == 0) {
582 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
583 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
584 switch (bits(op1, 2, 0)) {
585 case 0x0:
586 return new MovRegReg(machInst, rd,
587 INTREG_ZERO, rn, rm, LSL);
588 case 0x1:
589 return new MovRegRegCc(machInst, rd,
590 INTREG_ZERO, rn, rm, LSL);
591 case 0x2:
592 return new MovRegReg(machInst, rd,
593 INTREG_ZERO, rn, rm, LSR);
594 case 0x3:
595 return new MovRegRegCc(machInst, rd,
596 INTREG_ZERO, rn, rm, LSR);
597 case 0x4:
598 return new MovRegReg(machInst, rd,
599 INTREG_ZERO, rn, rm, ASR);
600 case 0x5:
601 return new MovRegRegCc(machInst, rd,
602 INTREG_ZERO, rn, rm, ASR);
603 case 0x6:
604 return new MovRegReg(machInst, rd,
605 INTREG_ZERO, rn, rm, ROR);
606 case 0x7:
607 return new MovRegRegCc(machInst, rd,
608 INTREG_ZERO, rn, rm, ROR);
609 default:
610 M5_UNREACHABLE;
611 }
612 } else if (bits(op2, 3) == 0) {
613 return new Unknown(machInst);
614 } else {
615 const IntRegIndex rd =
616 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
617 const IntRegIndex rm =
618 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
619 const uint32_t rotation =
620 (uint32_t)bits(machInst, 5, 4) << 3;
621 switch (bits(op1, 2, 0)) {
622 case 0x0:
623 if (rn == 0xf) {
624 return new Sxth(machInst, rd, rotation, rm);
625 } else {
626 return new Sxtah(machInst, rd, rn, rm, rotation);
627 }
628 case 0x1:
629 if (rn == 0xf) {
630 return new Uxth(machInst, rd, rotation, rm);
631 } else {
632 return new Uxtah(machInst, rd, rn, rm, rotation);
633 }
634 case 0x2:
635 if (rn == 0xf) {
636 return new Sxtb16(machInst, rd, rotation, rm);
637 } else {
638 return new Sxtab16(machInst, rd, rn, rm, rotation);
639 }
640 case 0x3:
641 if (rn == 0xf) {
642 return new Uxtb16(machInst, rd, rotation, rm);
643 } else {
644 return new Uxtab16(machInst, rd, rn, rm, rotation);
645 }
646 case 0x4:
647 if (rn == 0xf) {
648 return new Sxtb(machInst, rd, rotation, rm);
649 } else {
650 return new Sxtab(machInst, rd, rn, rm, rotation);
651 }
652 case 0x5:
653 if (rn == 0xf) {
654 return new Uxtb(machInst, rd, rotation, rm);
655 } else {
656 return new Uxtab(machInst, rd, rn, rm, rotation);
657 }
658 default:
659 return new Unknown(machInst);
660 }
661 }
662 } else {
663 if (bits(op2, 3) == 0) {
664 const IntRegIndex rd =
665 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
666 const IntRegIndex rm =
667 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
668 if (bits(op2, 2) == 0x0) {
669 const uint32_t op1 = bits(machInst, 22, 20);
670 const uint32_t op2 = bits(machInst, 5, 4);
671 switch (op2) {
672 case 0x0:
673 switch (op1) {
674 case 0x1:
675 return new Sadd16RegCc(machInst, rd,
676 rn, rm, 0, LSL);
677 case 0x2:
678 return new SasxRegCc(machInst, rd,
679 rn, rm, 0, LSL);
680 case 0x6:
681 return new SsaxRegCc(machInst, rd,
682 rn, rm, 0, LSL);
683 case 0x5:
684 return new Ssub16RegCc(machInst, rd,
685 rn, rm, 0, LSL);
686 case 0x0:
687 return new Sadd8RegCc(machInst, rd,
688 rn, rm, 0, LSL);
689 case 0x4:
690 return new Ssub8RegCc(machInst, rd,
691 rn, rm, 0, LSL);
692 }
693 break;
694 case 0x1:
695 switch (op1) {
696 case 0x1:
697 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
698 case 0x2:
699 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
700 case 0x6:
701 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
702 case 0x5:
703 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
704 case 0x0:
705 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
706 case 0x4:
707 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
708 }
709 break;
710 case 0x2:
711 switch (op1) {
712 case 0x1:
713 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
714 case 0x2:
715 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
716 case 0x6:
717 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
718 case 0x5:
719 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
720 case 0x0:
721 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
722 case 0x4:
723 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
724 }
725 break;
726 }
727 } else {
728 const uint32_t op1 = bits(machInst, 22, 20);
729 const uint32_t op2 = bits(machInst, 5, 4);
730 switch (op2) {
731 case 0x0:
732 switch (op1) {
733 case 0x1:
734 return new Uadd16RegCc(machInst, rd,
735 rn, rm, 0, LSL);
736 case 0x2:
737 return new UasxRegCc(machInst, rd,
738 rn, rm, 0, LSL);
739 case 0x6:
740 return new UsaxRegCc(machInst, rd,
741 rn, rm, 0, LSL);
742 case 0x5:
743 return new Usub16RegCc(machInst, rd,
744 rn, rm, 0, LSL);
745 case 0x0:
746 return new Uadd8RegCc(machInst, rd,
747 rn, rm, 0, LSL);
748 case 0x4:
749 return new Usub8RegCc(machInst, rd,
750 rn, rm, 0, LSL);
751 }
752 break;
753 case 0x1:
754 switch (op1) {
755 case 0x1:
756 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
757 case 0x2:
758 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
759 case 0x6:
760 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
761 case 0x5:
762 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
763 case 0x0:
764 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
765 case 0x4:
766 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
767 }
768 break;
769 case 0x2:
770 switch (op1) {
771 case 0x1:
772 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
773 case 0x2:
774 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
775 case 0x6:
776 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
777 case 0x5:
778 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
779 case 0x0:
780 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
781 case 0x4:
782 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
783 }
784 break;
785 }
786 }
787 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
788 const uint32_t op1 = bits(machInst, 22, 20);
789 const uint32_t op2 = bits(machInst, 5, 4);
790 const IntRegIndex rd =
791 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
792 const IntRegIndex rm =
793 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
794 switch (op1) {
795 case 0x0:
796 switch (op2) {
797 case 0x0:
798 return new QaddRegCc(machInst, rd,
799 rm, rn, 0, LSL);
800 case 0x1:
801 return new QdaddRegCc(machInst, rd,
802 rm, rn, 0, LSL);
803 case 0x2:
804 return new QsubRegCc(machInst, rd,
805 rm, rn, 0, LSL);
806 case 0x3:
807 return new QdsubRegCc(machInst, rd,
808 rm, rn, 0, LSL);
809 }
810 break;
811 case 0x1:
812 switch (op2) {
813 case 0x0:
814 return new Rev(machInst, rd, rn);
815 case 0x1:
816 return new Rev16(machInst, rd, rn);
817 case 0x2:
818 return new Rbit(machInst, rd, rm);
819 case 0x3:
820 return new Revsh(machInst, rd, rn);
821 }
822 break;
823 case 0x2:
824 if (op2 == 0) {
825 return new Sel(machInst, rd, rn, rm);
826 }
827 break;
828 case 0x3:
829 if (op2 == 0) {
830 return new Clz(machInst, rd, rm);
831 }
832 break;
833 }
834 } else if (bits(op1, 3, 2) == 0x3 && bits(op2, 3, 2) == 0x2) {
835 const uint32_t op1 = bits(machInst, 22, 20);
836 const uint32_t op2 = bits(machInst, 5, 4);
837 const IntRegIndex rd =
838 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
839 const IntRegIndex rm =
840 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
841 switch (op1) {
833 case 0x4:
834 switch (op2) {
835 case 0x0:
836 return new Crc32b(machInst, rd, rn, rm);
837 case 0x1:
838 return new Crc32h(machInst, rd, rn, rm);
839 case 0x2:
840 return new Crc32w(machInst, rd, rn, rm);
841 }
842 break;
843 case 0x5:
844 switch (op2) {
845 case 0x0:
846 return new Crc32cb(machInst, rd, rn, rm);
847 case 0x1:
848 return new Crc32ch(machInst, rd, rn, rm);
849 case 0x2:
850 return new Crc32cw(machInst, rd, rn, rm);
851 }
852 break;
853 }
854 }
855 return new Unknown(machInst);
856 }
857 }
858 '''
859}};
860
861def format Thumb16ShiftAddSubMoveCmp() {{
862 decode_block = '''
863 {
864 const uint32_t imm5 = bits(machInst, 10, 6);
865 const uint32_t imm3 = bits(machInst, 8, 6);
866 const uint32_t imm8 = bits(machInst, 7, 0);
867 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
868 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
869 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
870 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
871 switch (bits(machInst, 13, 11)) {
872 case 0x0: // lsl
873 if (machInst.itstateMask) {
874 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
875 } else {
876 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
877 }
878 case 0x1: // lsr
879 if (machInst.itstateMask) {
880 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
881 } else {
882 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
883 }
884 case 0x2: // asr
885 if (machInst.itstateMask) {
886 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
887 } else {
888 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
889 }
890 case 0x3:
891 switch (bits(machInst, 10, 9)) {
892 case 0x0:
893 if (machInst.itstateMask) {
894 return new AddReg(machInst, rd, rn, rm, 0, LSL);
895 } else {
896 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
897 }
898 case 0x1:
899 if (machInst.itstateMask) {
900 return new SubReg(machInst, rd, rn, rm, 0, LSL);
901 } else {
902 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
903 }
904 case 0x2:
905 if (machInst.itstateMask) {
906 return new AddImm(machInst, rd, rn, imm3, true);
907 } else {
908 return new AddImmCc(machInst, rd, rn, imm3, true);
909 }
910 case 0x3:
911 if (machInst.itstateMask) {
912 return new SubImm(machInst, rd, rn, imm3, true);
913 } else {
914 return new SubImmCc(machInst, rd, rn, imm3, true);
915 }
916 default:
917 M5_UNREACHABLE;
918 }
919 case 0x4:
920 if (machInst.itstateMask) {
921 return new MovImm(machInst, rd8, INTREG_ZERO, imm8, false);
922 } else {
923 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
924 }
925 case 0x5:
926 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
927 case 0x6:
928 if (machInst.itstateMask) {
929 return new AddImm(machInst, rd8, rd8, imm8, true);
930 } else {
931 return new AddImmCc(machInst, rd8, rd8, imm8, true);
932 }
933 case 0x7:
934 if (machInst.itstateMask) {
935 return new SubImm(machInst, rd8, rd8, imm8, true);
936 } else {
937 return new SubImmCc(machInst, rd8, rd8, imm8, true);
938 }
939 default:
940 M5_UNREACHABLE;
941 }
942 }
943 '''
944}};
945
946def format Thumb16DataProcessing() {{
947 decode_block = '''
948 {
949 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
950 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
951 switch (bits(machInst, 9, 6)) {
952 case 0x0:
953 if (machInst.itstateMask) {
954 return new AndReg(machInst, rdn, rdn, rm, 0, LSL);
955 } else {
956 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
957 }
958 case 0x1:
959 if (machInst.itstateMask) {
960 return new EorReg(machInst, rdn, rdn, rm, 0, LSL);
961 } else {
962 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
963 }
964 case 0x2: //lsl
965 if (machInst.itstateMask) {
966 return new MovRegReg(machInst, rdn,
967 INTREG_ZERO, rdn, rm, LSL);
968 } else {
969 return new MovRegRegCc(machInst, rdn,
970 INTREG_ZERO, rdn, rm, LSL);
971 }
972 case 0x3: //lsr
973 if (machInst.itstateMask) {
974 return new MovRegReg(machInst, rdn,
975 INTREG_ZERO, rdn, rm, LSR);
976 } else {
977 return new MovRegRegCc(machInst, rdn,
978 INTREG_ZERO, rdn, rm, LSR);
979 }
980 case 0x4: //asr
981 if (machInst.itstateMask) {
982 return new MovRegReg(machInst, rdn,
983 INTREG_ZERO, rdn, rm, ASR);
984 } else {
985 return new MovRegRegCc(machInst, rdn,
986 INTREG_ZERO, rdn, rm, ASR);
987 }
988 case 0x5:
989 if (machInst.itstateMask) {
990 return new AdcReg(machInst, rdn, rdn, rm, 0, LSL);
991 } else {
992 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
993 }
994 case 0x6:
995 if (machInst.itstateMask) {
996 return new SbcReg(machInst, rdn, rdn, rm, 0, LSL);
997 } else {
998 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
999 }
1000 case 0x7: // ror
1001 if (machInst.itstateMask) {
1002 return new MovRegReg(machInst, rdn,
1003 INTREG_ZERO, rdn, rm, ROR);
1004 } else {
1005 return new MovRegRegCc(machInst, rdn,
1006 INTREG_ZERO, rdn, rm, ROR);
1007 }
1008 case 0x8:
1009 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1010 case 0x9:
1011 if (machInst.itstateMask) {
1012 return new RsbImm(machInst, rdn, rm, 0, true);
1013 } else {
1014 return new RsbImmCc(machInst, rdn, rm, 0, true);
1015 }
1016 case 0xa:
1017 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1018 case 0xb:
1019 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1020 case 0xc:
1021 if (machInst.itstateMask) {
1022 return new OrrReg(machInst, rdn, rdn, rm, 0, LSL);
1023 } else {
1024 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
1025 }
1026 case 0xd:
1027 if (machInst.itstateMask) {
1028 return new Mul(machInst, rdn, rm, rdn);
1029 } else {
1030 return new MulCc(machInst, rdn, rm, rdn);
1031 }
1032 case 0xe:
1033 if (machInst.itstateMask) {
1034 return new BicReg(machInst, rdn, rdn, rm, 0, LSL);
1035 } else {
1036 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
1037 }
1038 case 0xf:
1039 if (machInst.itstateMask) {
1040 return new MvnReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1041 } else {
1042 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1043 }
1044 default:
1045 M5_UNREACHABLE;
1046 }
1047 }
1048 '''
1049}};
1050
1051def format Thumb16SpecDataAndBx() {{
1052 decode_block = '''
1053 {
1054 const IntRegIndex rdn =
1055 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
1056 (bits(machInst, 7) << 3));
1057 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
1058 switch (bits(machInst, 9, 8)) {
1059 case 0x0:
1060 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
1061 case 0x1:
1062 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1063 case 0x2:
1064 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1065 case 0x3:
1066 if (bits(machInst, 7) == 0) {
1067 return new BxReg(machInst,
1068 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1069 COND_UC);
1070 } else {
1071 return new BlxReg(machInst,
1072 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1073 COND_UC);
1074 }
1075 default:
1076 M5_UNREACHABLE;
1077 }
1078 }
1079 '''
1080}};
1081
1082def format Thumb16Adr() {{
1083 decode_block = '''
1084 {
1085 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1086 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1087 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
1088 }
1089 '''
1090}};
1091
1092def format Thumb16AddSp() {{
1093 decode_block = '''
1094 {
1095 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1096 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1097 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
1098 }
1099 '''
1100}};
1101
1102def format ArmMisc() {{
1103 decode_block = '''
1104 {
1105 const uint32_t unrotated = bits(machInst, 7, 0);
1106 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
1107 const uint32_t imm = rotate_imm(unrotated, rotation);
1108 const uint8_t byteMask = bits(machInst, 19, 16);
1109 switch (OPCODE) {
1110 case 0x8:
1111 return new MovImm(machInst, (IntRegIndex)(uint32_t)RD,
1112 (IntRegIndex)INTREG_ZERO,
1113 bits(machInst, 11, 0) | (bits(machInst, 19, 16) << 12),
1114 false);
1115 case 0x9:
1116 if (RN == 0) {
1117 if ((IMM & 0xf0) == 0xf0) {
1118 return new Dbg(machInst);
1119 } else {
1120 switch (IMM) {
1121 case 0x0:
1122 return new NopInst(machInst);
1123 case 0x1:
1124 return new YieldInst(machInst);
1125 case 0x2:
1126 return new WfeInst(machInst);
1127 case 0x3:
1128 return new WfiInst(machInst);
1129 case 0x4:
1130 return new SevInst(machInst);
1131 case 0x5:
1132 return new WarnUnimplemented(
1133 "sevl", machInst);
1134 case 0x10:
1135 return new WarnUnimplemented(
1136 "esb", machInst);
1137 case 0x12:
1138 return new WarnUnimplemented(
1139 "tsb csync", machInst);
1140 case 0x14:
1141 return new WarnUnimplemented(
1142 "csdb", machInst);
1143 default:
1144 return new WarnUnimplemented(
1145 "unallocated_hint", machInst);
1146 }
1147 }
1148 } else {
1149 return new MsrCpsrImm(machInst, imm, byteMask);
1150 }
1151 case 0xa:
1152 {
1153 const uint32_t timm = (bits(machInst, 19, 16) << 12) |
1154 bits(machInst, 11, 0);
1155 return new MovtImm(machInst, (IntRegIndex)(uint32_t)RD,
1156 (IntRegIndex)(uint32_t)RD, timm, true);
1157 }
1158 case 0xb:
1159 return new MsrSpsrImm(machInst, imm, byteMask);
1160 default:
1161 return new Unknown(machInst);
1162 }
1163 }
1164 '''
1165}};
1166
1167def format Thumb16Misc() {{
1168 decode_block = '''
1169 {
1170 switch (bits(machInst, 11, 8)) {
1171 case 0x0:
1172 if (bits(machInst, 7)) {
1173 return new SubImm(machInst, INTREG_SP, INTREG_SP,
1174 bits(machInst, 6, 0) << 2, true);
1175 } else {
1176 return new AddImm(machInst, INTREG_SP, INTREG_SP,
1177 bits(machInst, 6, 0) << 2, true);
1178 }
1179 case 0x2:
1180 {
1181 const IntRegIndex rd =
1182 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1183 const IntRegIndex rm =
1184 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1185 switch (bits(machInst, 7, 6)) {
1186 case 0x0:
1187 return new Sxth(machInst, rd, 0, rm);
1188 case 0x1:
1189 return new Sxtb(machInst, rd, 0, rm);
1190 case 0x2:
1191 return new Uxth(machInst, rd, 0, rm);
1192 case 0x3:
1193 return new Uxtb(machInst, rd, 0, rm);
1194 default:
1195 M5_UNREACHABLE;
1196 }
1197 }
1198 case 0x1:
1199 case 0x3:
1200 return new Cbz(machInst,
1201 (bits(machInst, 9) << 6) |
1202 (bits(machInst, 7, 3) << 1),
1203 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1204 case 0x4:
1205 case 0x5:
1206 {
1207 const uint32_t m = bits(machInst, 8);
1208 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
1209 return new LdmStm(machInst, INTREG_SP, false, false, false,
1210 true, false, regList);
1211 }
1212 case 0x6:
1213 {
1214 const uint32_t opBits = bits(machInst, 7, 5);
1215 if (opBits == 2) {
1216 return new Setend(machInst, bits(machInst, 3));
1217 } else if (opBits == 3) {
1218 const bool enable = (bits(machInst, 4) == 0);
1219 const uint32_t mods = (bits(machInst, 2, 0) << 5) |
1220 ((enable ? 1 : 0) << 9);
1221 return new Cps(machInst, mods);
1222 }
1223 return new Unknown(machInst);
1224 }
1225 case 0xa:
1226 {
1227 const uint8_t op1 = bits(machInst, 7, 6);
1228 if (op1 == 0x2) {
1229 return new Hlt(machInst, bits(machInst, 5, 0));
1230 } else {
1231 IntRegIndex rd =
1232 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1233 IntRegIndex rm =
1234 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1235
1236 switch (op1) {
1237 case 0x0:
1238 return new Rev(machInst, rd, rm);
1239 case 0x1:
1240 return new Rev16(machInst, rd, rm);
1241 case 0x3:
1242 return new Revsh(machInst, rd, rm);
1243 default:
1244 break;
1245 }
1246 }
1247 }
1248 break;
1249 case 0x9:
1250 case 0xb:
1251 return new Cbnz(machInst,
1252 (bits(machInst, 9) << 6) |
1253 (bits(machInst, 7, 3) << 1),
1254 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1255 case 0xc:
1256 case 0xd:
1257 {
1258 const uint32_t p = bits(machInst, 8);
1259 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1260 return new LdmStm(machInst, INTREG_SP, true, true, false,
1261 true, true, regList);
1262 }
1263 case 0xe:
1264 return new BkptInst(machInst);
1265 case 0xf:
1266 if (bits(machInst, 3, 0) != 0)
1267 return new ItInst(machInst);
1268 switch (bits(machInst, 7, 4)) {
1269 case 0x0:
1270 return new NopInst(machInst);
1271 case 0x1:
1272 return new YieldInst(machInst);
1273 case 0x2:
1274 return new WfeInst(machInst);
1275 case 0x3:
1276 return new WfiInst(machInst);
1277 case 0x4:
1278 return new SevInst(machInst);
1279 default:
1280 return new WarnUnimplemented("unallocated_hint", machInst);
1281 }
1282 default:
1283 break;
1284 }
1285 return new Unknown(machInst);
1286 }
1287 '''
1288}};
1289
1290def format Thumb32DataProcModImm() {{
1291
1292 def decInst(mnem, dest="rd", op1="rn"):
1293 return '''
1294 if (s) {
1295 return new %(mnem)sImmCc(machInst, %(dest)s,
1296 %(op1)s, imm, rotC);
1297 } else {
1298 return new %(mnem)sImm(machInst, %(dest)s,
1299 %(op1)s, imm, rotC);
1300 }
1301 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1302
1303 decode_block = '''
1304 {
1305 const uint32_t op = bits(machInst, 24, 21);
1306 const bool s = (bits(machInst, 20) == 1);
1307 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1308 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1309 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1310 bits(machInst, 14, 12);
1311 const bool rotC = ctrlImm > 3;
1312 const uint32_t dataImm = bits(machInst, 7, 0);
1313 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1314 switch (op) {
1315 case 0x0:
1316 if (rd == INTREG_PC) {
1317 %(tst)s
1318 } else {
1319 %(and)s
1320 }
1321 case 0x1:
1322 %(bic)s
1323 case 0x2:
1324 if (rn == INTREG_PC) {
1325 %(mov)s
1326 } else {
1327 %(orr)s
1328 }
1329 case 0x3:
1330 if (rn == INTREG_PC) {
1331 %(mvn)s
1332 } else {
1333 %(orn)s
1334 }
1335 case 0x4:
1336 if (rd == INTREG_PC) {
1337 %(teq)s
1338 } else {
1339 %(eor)s
1340 }
1341 case 0x8:
1342 if (rd == INTREG_PC) {
1343 %(cmn)s
1344 } else {
1345 %(add)s
1346 }
1347 case 0xa:
1348 %(adc)s
1349 case 0xb:
1350 %(sbc)s
1351 case 0xd:
1352 if (rd == INTREG_PC) {
1353 %(cmp)s
1354 } else {
1355 %(sub)s
1356 }
1357 case 0xe:
1358 %(rsb)s
1359 default:
1360 return new Unknown(machInst);
1361 }
1362 }
1363 ''' % {
1364 "tst" : decInst("Tst", "INTREG_ZERO"),
1365 "and" : decInst("And"),
1366 "bic" : decInst("Bic"),
1367 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1368 "orr" : decInst("Orr"),
1369 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1370 "orn" : decInst("Orn"),
1371 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1372 "eor" : decInst("Eor"),
1373 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1374 "add" : decInst("Add"),
1375 "adc" : decInst("Adc"),
1376 "sbc" : decInst("Sbc"),
1377 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1378 "sub" : decInst("Sub"),
1379 "rsb" : decInst("Rsb")
1380 }
1381}};
1382
1383def format Thumb32DataProcPlainBin() {{
1384 decode_block = '''
1385 {
1386 const uint32_t op = bits(machInst, 24, 20);
1387 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1388 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1389 switch (op) {
1390 case 0x0:
1391 {
1392 const uint32_t imm = bits(machInst, 7, 0) |
1393 (bits(machInst, 14, 12) << 8) |
1394 (bits(machInst, 26) << 11);
1395 if (rn == 0xf) {
1396 return new AdrImm(machInst, rd, (IntRegIndex)1,
1397 imm, false);
1398 } else {
1399 return new AddImm(machInst, rd, rn, imm, true);
1400 }
1401 }
1402 case 0x4:
1403 {
1404 const uint32_t imm = bits(machInst, 7, 0) |
1405 (bits(machInst, 14, 12) << 8) |
1406 (bits(machInst, 26) << 11) |
1407 (bits(machInst, 19, 16) << 12);
1408 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1409 }
1410 case 0xa:
1411 {
1412 const uint32_t imm = bits(machInst, 7, 0) |
1413 (bits(machInst, 14, 12) << 8) |
1414 (bits(machInst, 26) << 11);
1415 if (rn == 0xf) {
1416 return new AdrImm(machInst, rd, (IntRegIndex)0,
1417 imm, false);
1418 } else {
1419 return new SubImm(machInst, rd, rn, imm, true);
1420 }
1421 }
1422 case 0xc:
1423 {
1424 const uint32_t imm = bits(machInst, 7, 0) |
1425 (bits(machInst, 14, 12) << 8) |
1426 (bits(machInst, 26) << 11) |
1427 (bits(machInst, 19, 16) << 12);
1428 return new MovtImm(machInst, rd, rd, imm, true);
1429 }
1430 case 0x12:
1431 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1432 const uint32_t satImm = bits(machInst, 4, 0);
1433 return new Ssat16(machInst, rd, satImm + 1, rn);
1434 }
1435 M5_FALLTHROUGH;
1436 case 0x10:
1437 {
1438 const uint32_t satImm = bits(machInst, 4, 0);
1439 const uint32_t imm = bits(machInst, 7, 6) |
1440 (bits(machInst, 14, 12) << 2);
1441 const ArmShiftType type =
1442 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1443 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1444 }
1445 case 0x14:
1446 {
1447 const uint32_t lsb = bits(machInst, 7, 6) |
1448 (bits(machInst, 14, 12) << 2);
1449 const uint32_t msb = lsb + bits(machInst, 4, 0);
1450 return new Sbfx(machInst, rd, rn, lsb, msb);
1451 }
1452 case 0x16:
1453 {
1454 const uint32_t lsb = bits(machInst, 7, 6) |
1455 (bits(machInst, 14, 12) << 2);
1456 const uint32_t msb = bits(machInst, 4, 0);
1457 if (rn == 0xf) {
1458 return new Bfc(machInst, rd, rd, lsb, msb);
1459 } else {
1460 return new Bfi(machInst, rd, rn, lsb, msb);
1461 }
1462 }
1463 case 0x1a:
1464 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1465 const uint32_t satImm = bits(machInst, 4, 0);
1466 return new Usat16(machInst, rd, satImm, rn);
1467 }
1468 M5_FALLTHROUGH;
1469 case 0x18:
1470 {
1471 const uint32_t satImm = bits(machInst, 4, 0);
1472 const uint32_t imm = bits(machInst, 7, 6) |
1473 (bits(machInst, 14, 12) << 2);
1474 const ArmShiftType type =
1475 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1476 return new Usat(machInst, rd, satImm, rn, imm, type);
1477 }
1478 case 0x1c:
1479 {
1480 const uint32_t lsb = bits(machInst, 7, 6) |
1481 (bits(machInst, 14, 12) << 2);
1482 const uint32_t msb = lsb + bits(machInst, 4, 0);
1483 return new Ubfx(machInst, rd, rn, lsb, msb);
1484 }
1485 default:
1486 return new Unknown(machInst);
1487 }
1488 }
1489 '''
1490}};
1491
1492def format Thumb32DataProcShiftReg() {{
1493
1494 def decInst(mnem, dest="rd", op1="rn"):
1495 return '''
1496 if (s) {
1497 return new %(mnem)sRegCc(machInst, %(dest)s,
1498 %(op1)s, rm, amt, type);
1499 } else {
1500 return new %(mnem)sReg(machInst, %(dest)s,
1501 %(op1)s, rm, amt, type);
1502 }
1503 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1504
1505 decode_block = '''
1506 {
1507 const uint32_t op = bits(machInst, 24, 21);
1508 const bool s = (bits(machInst, 20) == 1);
1509 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1510 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1511 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1512 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1513 bits(machInst, 7, 6);
1514 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1515 switch (op) {
1516 case 0x0:
1517 if (rd == INTREG_PC) {
1518 %(tst)s
1519 } else {
1520 %(and)s
1521 }
1522 case 0x1:
1523 %(bic)s
1524 case 0x2:
1525 if (rn == INTREG_PC) {
1526 %(mov)s
1527 } else {
1528 %(orr)s
1529 }
1530 case 0x3:
1531 if (rn == INTREG_PC) {
1532 %(mvn)s
1533 } else {
1534 %(orn)s
1535 }
1536 case 0x4:
1537 if (rd == INTREG_PC) {
1538 %(teq)s
1539 } else {
1540 %(eor)s
1541 }
1542 case 0x6:
1543 if (type) {
1544 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1545 } else {
1546 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1547 }
1548 case 0x8:
1549 if (rd == INTREG_PC) {
1550 %(cmn)s
1551 } else {
1552 %(add)s
1553 }
1554 case 0xa:
1555 %(adc)s
1556 case 0xb:
1557 %(sbc)s
1558 case 0xd:
1559 if (rd == INTREG_PC) {
1560 %(cmp)s
1561 } else {
1562 %(sub)s
1563 }
1564 case 0xe:
1565 %(rsb)s
1566 default:
1567 return new Unknown(machInst);
1568 }
1569 }
1570 ''' % {
1571 "tst" : decInst("Tst", "INTREG_ZERO"),
1572 "and" : decInst("And"),
1573 "bic" : decInst("Bic"),
1574 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1575 "orr" : decInst("Orr"),
1576 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1577 "orn" : decInst("Orn"),
1578 "teq" : decInst("Teq", "INTREG_ZERO"),
1579 "eor" : decInst("Eor"),
1580 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1581 "add" : decInst("Add"),
1582 "adc" : decInst("Adc"),
1583 "sbc" : decInst("Sbc"),
1584 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1585 "sub" : decInst("Sub"),
1586 "rsb" : decInst("Rsb")
1587 }
1588}};
842 case 0x4:
843 switch (op2) {
844 case 0x0:
845 return new Crc32b(machInst, rd, rn, rm);
846 case 0x1:
847 return new Crc32h(machInst, rd, rn, rm);
848 case 0x2:
849 return new Crc32w(machInst, rd, rn, rm);
850 }
851 break;
852 case 0x5:
853 switch (op2) {
854 case 0x0:
855 return new Crc32cb(machInst, rd, rn, rm);
856 case 0x1:
857 return new Crc32ch(machInst, rd, rn, rm);
858 case 0x2:
859 return new Crc32cw(machInst, rd, rn, rm);
860 }
861 break;
862 }
863 }
864 return new Unknown(machInst);
865 }
866 }
867 '''
868}};
869
870def format Thumb16ShiftAddSubMoveCmp() {{
871 decode_block = '''
872 {
873 const uint32_t imm5 = bits(machInst, 10, 6);
874 const uint32_t imm3 = bits(machInst, 8, 6);
875 const uint32_t imm8 = bits(machInst, 7, 0);
876 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
877 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
878 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
879 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
880 switch (bits(machInst, 13, 11)) {
881 case 0x0: // lsl
882 if (machInst.itstateMask) {
883 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
884 } else {
885 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
886 }
887 case 0x1: // lsr
888 if (machInst.itstateMask) {
889 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
890 } else {
891 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
892 }
893 case 0x2: // asr
894 if (machInst.itstateMask) {
895 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
896 } else {
897 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
898 }
899 case 0x3:
900 switch (bits(machInst, 10, 9)) {
901 case 0x0:
902 if (machInst.itstateMask) {
903 return new AddReg(machInst, rd, rn, rm, 0, LSL);
904 } else {
905 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
906 }
907 case 0x1:
908 if (machInst.itstateMask) {
909 return new SubReg(machInst, rd, rn, rm, 0, LSL);
910 } else {
911 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
912 }
913 case 0x2:
914 if (machInst.itstateMask) {
915 return new AddImm(machInst, rd, rn, imm3, true);
916 } else {
917 return new AddImmCc(machInst, rd, rn, imm3, true);
918 }
919 case 0x3:
920 if (machInst.itstateMask) {
921 return new SubImm(machInst, rd, rn, imm3, true);
922 } else {
923 return new SubImmCc(machInst, rd, rn, imm3, true);
924 }
925 default:
926 M5_UNREACHABLE;
927 }
928 case 0x4:
929 if (machInst.itstateMask) {
930 return new MovImm(machInst, rd8, INTREG_ZERO, imm8, false);
931 } else {
932 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
933 }
934 case 0x5:
935 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
936 case 0x6:
937 if (machInst.itstateMask) {
938 return new AddImm(machInst, rd8, rd8, imm8, true);
939 } else {
940 return new AddImmCc(machInst, rd8, rd8, imm8, true);
941 }
942 case 0x7:
943 if (machInst.itstateMask) {
944 return new SubImm(machInst, rd8, rd8, imm8, true);
945 } else {
946 return new SubImmCc(machInst, rd8, rd8, imm8, true);
947 }
948 default:
949 M5_UNREACHABLE;
950 }
951 }
952 '''
953}};
954
955def format Thumb16DataProcessing() {{
956 decode_block = '''
957 {
958 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
959 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
960 switch (bits(machInst, 9, 6)) {
961 case 0x0:
962 if (machInst.itstateMask) {
963 return new AndReg(machInst, rdn, rdn, rm, 0, LSL);
964 } else {
965 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
966 }
967 case 0x1:
968 if (machInst.itstateMask) {
969 return new EorReg(machInst, rdn, rdn, rm, 0, LSL);
970 } else {
971 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
972 }
973 case 0x2: //lsl
974 if (machInst.itstateMask) {
975 return new MovRegReg(machInst, rdn,
976 INTREG_ZERO, rdn, rm, LSL);
977 } else {
978 return new MovRegRegCc(machInst, rdn,
979 INTREG_ZERO, rdn, rm, LSL);
980 }
981 case 0x3: //lsr
982 if (machInst.itstateMask) {
983 return new MovRegReg(machInst, rdn,
984 INTREG_ZERO, rdn, rm, LSR);
985 } else {
986 return new MovRegRegCc(machInst, rdn,
987 INTREG_ZERO, rdn, rm, LSR);
988 }
989 case 0x4: //asr
990 if (machInst.itstateMask) {
991 return new MovRegReg(machInst, rdn,
992 INTREG_ZERO, rdn, rm, ASR);
993 } else {
994 return new MovRegRegCc(machInst, rdn,
995 INTREG_ZERO, rdn, rm, ASR);
996 }
997 case 0x5:
998 if (machInst.itstateMask) {
999 return new AdcReg(machInst, rdn, rdn, rm, 0, LSL);
1000 } else {
1001 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
1002 }
1003 case 0x6:
1004 if (machInst.itstateMask) {
1005 return new SbcReg(machInst, rdn, rdn, rm, 0, LSL);
1006 } else {
1007 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
1008 }
1009 case 0x7: // ror
1010 if (machInst.itstateMask) {
1011 return new MovRegReg(machInst, rdn,
1012 INTREG_ZERO, rdn, rm, ROR);
1013 } else {
1014 return new MovRegRegCc(machInst, rdn,
1015 INTREG_ZERO, rdn, rm, ROR);
1016 }
1017 case 0x8:
1018 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1019 case 0x9:
1020 if (machInst.itstateMask) {
1021 return new RsbImm(machInst, rdn, rm, 0, true);
1022 } else {
1023 return new RsbImmCc(machInst, rdn, rm, 0, true);
1024 }
1025 case 0xa:
1026 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1027 case 0xb:
1028 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1029 case 0xc:
1030 if (machInst.itstateMask) {
1031 return new OrrReg(machInst, rdn, rdn, rm, 0, LSL);
1032 } else {
1033 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
1034 }
1035 case 0xd:
1036 if (machInst.itstateMask) {
1037 return new Mul(machInst, rdn, rm, rdn);
1038 } else {
1039 return new MulCc(machInst, rdn, rm, rdn);
1040 }
1041 case 0xe:
1042 if (machInst.itstateMask) {
1043 return new BicReg(machInst, rdn, rdn, rm, 0, LSL);
1044 } else {
1045 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
1046 }
1047 case 0xf:
1048 if (machInst.itstateMask) {
1049 return new MvnReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1050 } else {
1051 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1052 }
1053 default:
1054 M5_UNREACHABLE;
1055 }
1056 }
1057 '''
1058}};
1059
1060def format Thumb16SpecDataAndBx() {{
1061 decode_block = '''
1062 {
1063 const IntRegIndex rdn =
1064 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
1065 (bits(machInst, 7) << 3));
1066 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
1067 switch (bits(machInst, 9, 8)) {
1068 case 0x0:
1069 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
1070 case 0x1:
1071 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1072 case 0x2:
1073 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1074 case 0x3:
1075 if (bits(machInst, 7) == 0) {
1076 return new BxReg(machInst,
1077 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1078 COND_UC);
1079 } else {
1080 return new BlxReg(machInst,
1081 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1082 COND_UC);
1083 }
1084 default:
1085 M5_UNREACHABLE;
1086 }
1087 }
1088 '''
1089}};
1090
1091def format Thumb16Adr() {{
1092 decode_block = '''
1093 {
1094 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1095 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1096 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
1097 }
1098 '''
1099}};
1100
1101def format Thumb16AddSp() {{
1102 decode_block = '''
1103 {
1104 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1105 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1106 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
1107 }
1108 '''
1109}};
1110
1111def format ArmMisc() {{
1112 decode_block = '''
1113 {
1114 const uint32_t unrotated = bits(machInst, 7, 0);
1115 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
1116 const uint32_t imm = rotate_imm(unrotated, rotation);
1117 const uint8_t byteMask = bits(machInst, 19, 16);
1118 switch (OPCODE) {
1119 case 0x8:
1120 return new MovImm(machInst, (IntRegIndex)(uint32_t)RD,
1121 (IntRegIndex)INTREG_ZERO,
1122 bits(machInst, 11, 0) | (bits(machInst, 19, 16) << 12),
1123 false);
1124 case 0x9:
1125 if (RN == 0) {
1126 if ((IMM & 0xf0) == 0xf0) {
1127 return new Dbg(machInst);
1128 } else {
1129 switch (IMM) {
1130 case 0x0:
1131 return new NopInst(machInst);
1132 case 0x1:
1133 return new YieldInst(machInst);
1134 case 0x2:
1135 return new WfeInst(machInst);
1136 case 0x3:
1137 return new WfiInst(machInst);
1138 case 0x4:
1139 return new SevInst(machInst);
1140 case 0x5:
1141 return new WarnUnimplemented(
1142 "sevl", machInst);
1143 case 0x10:
1144 return new WarnUnimplemented(
1145 "esb", machInst);
1146 case 0x12:
1147 return new WarnUnimplemented(
1148 "tsb csync", machInst);
1149 case 0x14:
1150 return new WarnUnimplemented(
1151 "csdb", machInst);
1152 default:
1153 return new WarnUnimplemented(
1154 "unallocated_hint", machInst);
1155 }
1156 }
1157 } else {
1158 return new MsrCpsrImm(machInst, imm, byteMask);
1159 }
1160 case 0xa:
1161 {
1162 const uint32_t timm = (bits(machInst, 19, 16) << 12) |
1163 bits(machInst, 11, 0);
1164 return new MovtImm(machInst, (IntRegIndex)(uint32_t)RD,
1165 (IntRegIndex)(uint32_t)RD, timm, true);
1166 }
1167 case 0xb:
1168 return new MsrSpsrImm(machInst, imm, byteMask);
1169 default:
1170 return new Unknown(machInst);
1171 }
1172 }
1173 '''
1174}};
1175
1176def format Thumb16Misc() {{
1177 decode_block = '''
1178 {
1179 switch (bits(machInst, 11, 8)) {
1180 case 0x0:
1181 if (bits(machInst, 7)) {
1182 return new SubImm(machInst, INTREG_SP, INTREG_SP,
1183 bits(machInst, 6, 0) << 2, true);
1184 } else {
1185 return new AddImm(machInst, INTREG_SP, INTREG_SP,
1186 bits(machInst, 6, 0) << 2, true);
1187 }
1188 case 0x2:
1189 {
1190 const IntRegIndex rd =
1191 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1192 const IntRegIndex rm =
1193 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1194 switch (bits(machInst, 7, 6)) {
1195 case 0x0:
1196 return new Sxth(machInst, rd, 0, rm);
1197 case 0x1:
1198 return new Sxtb(machInst, rd, 0, rm);
1199 case 0x2:
1200 return new Uxth(machInst, rd, 0, rm);
1201 case 0x3:
1202 return new Uxtb(machInst, rd, 0, rm);
1203 default:
1204 M5_UNREACHABLE;
1205 }
1206 }
1207 case 0x1:
1208 case 0x3:
1209 return new Cbz(machInst,
1210 (bits(machInst, 9) << 6) |
1211 (bits(machInst, 7, 3) << 1),
1212 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1213 case 0x4:
1214 case 0x5:
1215 {
1216 const uint32_t m = bits(machInst, 8);
1217 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
1218 return new LdmStm(machInst, INTREG_SP, false, false, false,
1219 true, false, regList);
1220 }
1221 case 0x6:
1222 {
1223 const uint32_t opBits = bits(machInst, 7, 5);
1224 if (opBits == 2) {
1225 return new Setend(machInst, bits(machInst, 3));
1226 } else if (opBits == 3) {
1227 const bool enable = (bits(machInst, 4) == 0);
1228 const uint32_t mods = (bits(machInst, 2, 0) << 5) |
1229 ((enable ? 1 : 0) << 9);
1230 return new Cps(machInst, mods);
1231 }
1232 return new Unknown(machInst);
1233 }
1234 case 0xa:
1235 {
1236 const uint8_t op1 = bits(machInst, 7, 6);
1237 if (op1 == 0x2) {
1238 return new Hlt(machInst, bits(machInst, 5, 0));
1239 } else {
1240 IntRegIndex rd =
1241 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1242 IntRegIndex rm =
1243 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1244
1245 switch (op1) {
1246 case 0x0:
1247 return new Rev(machInst, rd, rm);
1248 case 0x1:
1249 return new Rev16(machInst, rd, rm);
1250 case 0x3:
1251 return new Revsh(machInst, rd, rm);
1252 default:
1253 break;
1254 }
1255 }
1256 }
1257 break;
1258 case 0x9:
1259 case 0xb:
1260 return new Cbnz(machInst,
1261 (bits(machInst, 9) << 6) |
1262 (bits(machInst, 7, 3) << 1),
1263 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1264 case 0xc:
1265 case 0xd:
1266 {
1267 const uint32_t p = bits(machInst, 8);
1268 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1269 return new LdmStm(machInst, INTREG_SP, true, true, false,
1270 true, true, regList);
1271 }
1272 case 0xe:
1273 return new BkptInst(machInst);
1274 case 0xf:
1275 if (bits(machInst, 3, 0) != 0)
1276 return new ItInst(machInst);
1277 switch (bits(machInst, 7, 4)) {
1278 case 0x0:
1279 return new NopInst(machInst);
1280 case 0x1:
1281 return new YieldInst(machInst);
1282 case 0x2:
1283 return new WfeInst(machInst);
1284 case 0x3:
1285 return new WfiInst(machInst);
1286 case 0x4:
1287 return new SevInst(machInst);
1288 default:
1289 return new WarnUnimplemented("unallocated_hint", machInst);
1290 }
1291 default:
1292 break;
1293 }
1294 return new Unknown(machInst);
1295 }
1296 '''
1297}};
1298
1299def format Thumb32DataProcModImm() {{
1300
1301 def decInst(mnem, dest="rd", op1="rn"):
1302 return '''
1303 if (s) {
1304 return new %(mnem)sImmCc(machInst, %(dest)s,
1305 %(op1)s, imm, rotC);
1306 } else {
1307 return new %(mnem)sImm(machInst, %(dest)s,
1308 %(op1)s, imm, rotC);
1309 }
1310 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1311
1312 decode_block = '''
1313 {
1314 const uint32_t op = bits(machInst, 24, 21);
1315 const bool s = (bits(machInst, 20) == 1);
1316 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1317 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1318 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1319 bits(machInst, 14, 12);
1320 const bool rotC = ctrlImm > 3;
1321 const uint32_t dataImm = bits(machInst, 7, 0);
1322 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1323 switch (op) {
1324 case 0x0:
1325 if (rd == INTREG_PC) {
1326 %(tst)s
1327 } else {
1328 %(and)s
1329 }
1330 case 0x1:
1331 %(bic)s
1332 case 0x2:
1333 if (rn == INTREG_PC) {
1334 %(mov)s
1335 } else {
1336 %(orr)s
1337 }
1338 case 0x3:
1339 if (rn == INTREG_PC) {
1340 %(mvn)s
1341 } else {
1342 %(orn)s
1343 }
1344 case 0x4:
1345 if (rd == INTREG_PC) {
1346 %(teq)s
1347 } else {
1348 %(eor)s
1349 }
1350 case 0x8:
1351 if (rd == INTREG_PC) {
1352 %(cmn)s
1353 } else {
1354 %(add)s
1355 }
1356 case 0xa:
1357 %(adc)s
1358 case 0xb:
1359 %(sbc)s
1360 case 0xd:
1361 if (rd == INTREG_PC) {
1362 %(cmp)s
1363 } else {
1364 %(sub)s
1365 }
1366 case 0xe:
1367 %(rsb)s
1368 default:
1369 return new Unknown(machInst);
1370 }
1371 }
1372 ''' % {
1373 "tst" : decInst("Tst", "INTREG_ZERO"),
1374 "and" : decInst("And"),
1375 "bic" : decInst("Bic"),
1376 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1377 "orr" : decInst("Orr"),
1378 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1379 "orn" : decInst("Orn"),
1380 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1381 "eor" : decInst("Eor"),
1382 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1383 "add" : decInst("Add"),
1384 "adc" : decInst("Adc"),
1385 "sbc" : decInst("Sbc"),
1386 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1387 "sub" : decInst("Sub"),
1388 "rsb" : decInst("Rsb")
1389 }
1390}};
1391
1392def format Thumb32DataProcPlainBin() {{
1393 decode_block = '''
1394 {
1395 const uint32_t op = bits(machInst, 24, 20);
1396 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1397 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1398 switch (op) {
1399 case 0x0:
1400 {
1401 const uint32_t imm = bits(machInst, 7, 0) |
1402 (bits(machInst, 14, 12) << 8) |
1403 (bits(machInst, 26) << 11);
1404 if (rn == 0xf) {
1405 return new AdrImm(machInst, rd, (IntRegIndex)1,
1406 imm, false);
1407 } else {
1408 return new AddImm(machInst, rd, rn, imm, true);
1409 }
1410 }
1411 case 0x4:
1412 {
1413 const uint32_t imm = bits(machInst, 7, 0) |
1414 (bits(machInst, 14, 12) << 8) |
1415 (bits(machInst, 26) << 11) |
1416 (bits(machInst, 19, 16) << 12);
1417 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1418 }
1419 case 0xa:
1420 {
1421 const uint32_t imm = bits(machInst, 7, 0) |
1422 (bits(machInst, 14, 12) << 8) |
1423 (bits(machInst, 26) << 11);
1424 if (rn == 0xf) {
1425 return new AdrImm(machInst, rd, (IntRegIndex)0,
1426 imm, false);
1427 } else {
1428 return new SubImm(machInst, rd, rn, imm, true);
1429 }
1430 }
1431 case 0xc:
1432 {
1433 const uint32_t imm = bits(machInst, 7, 0) |
1434 (bits(machInst, 14, 12) << 8) |
1435 (bits(machInst, 26) << 11) |
1436 (bits(machInst, 19, 16) << 12);
1437 return new MovtImm(machInst, rd, rd, imm, true);
1438 }
1439 case 0x12:
1440 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1441 const uint32_t satImm = bits(machInst, 4, 0);
1442 return new Ssat16(machInst, rd, satImm + 1, rn);
1443 }
1444 M5_FALLTHROUGH;
1445 case 0x10:
1446 {
1447 const uint32_t satImm = bits(machInst, 4, 0);
1448 const uint32_t imm = bits(machInst, 7, 6) |
1449 (bits(machInst, 14, 12) << 2);
1450 const ArmShiftType type =
1451 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1452 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1453 }
1454 case 0x14:
1455 {
1456 const uint32_t lsb = bits(machInst, 7, 6) |
1457 (bits(machInst, 14, 12) << 2);
1458 const uint32_t msb = lsb + bits(machInst, 4, 0);
1459 return new Sbfx(machInst, rd, rn, lsb, msb);
1460 }
1461 case 0x16:
1462 {
1463 const uint32_t lsb = bits(machInst, 7, 6) |
1464 (bits(machInst, 14, 12) << 2);
1465 const uint32_t msb = bits(machInst, 4, 0);
1466 if (rn == 0xf) {
1467 return new Bfc(machInst, rd, rd, lsb, msb);
1468 } else {
1469 return new Bfi(machInst, rd, rn, lsb, msb);
1470 }
1471 }
1472 case 0x1a:
1473 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1474 const uint32_t satImm = bits(machInst, 4, 0);
1475 return new Usat16(machInst, rd, satImm, rn);
1476 }
1477 M5_FALLTHROUGH;
1478 case 0x18:
1479 {
1480 const uint32_t satImm = bits(machInst, 4, 0);
1481 const uint32_t imm = bits(machInst, 7, 6) |
1482 (bits(machInst, 14, 12) << 2);
1483 const ArmShiftType type =
1484 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1485 return new Usat(machInst, rd, satImm, rn, imm, type);
1486 }
1487 case 0x1c:
1488 {
1489 const uint32_t lsb = bits(machInst, 7, 6) |
1490 (bits(machInst, 14, 12) << 2);
1491 const uint32_t msb = lsb + bits(machInst, 4, 0);
1492 return new Ubfx(machInst, rd, rn, lsb, msb);
1493 }
1494 default:
1495 return new Unknown(machInst);
1496 }
1497 }
1498 '''
1499}};
1500
1501def format Thumb32DataProcShiftReg() {{
1502
1503 def decInst(mnem, dest="rd", op1="rn"):
1504 return '''
1505 if (s) {
1506 return new %(mnem)sRegCc(machInst, %(dest)s,
1507 %(op1)s, rm, amt, type);
1508 } else {
1509 return new %(mnem)sReg(machInst, %(dest)s,
1510 %(op1)s, rm, amt, type);
1511 }
1512 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1513
1514 decode_block = '''
1515 {
1516 const uint32_t op = bits(machInst, 24, 21);
1517 const bool s = (bits(machInst, 20) == 1);
1518 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1519 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1520 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1521 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1522 bits(machInst, 7, 6);
1523 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1524 switch (op) {
1525 case 0x0:
1526 if (rd == INTREG_PC) {
1527 %(tst)s
1528 } else {
1529 %(and)s
1530 }
1531 case 0x1:
1532 %(bic)s
1533 case 0x2:
1534 if (rn == INTREG_PC) {
1535 %(mov)s
1536 } else {
1537 %(orr)s
1538 }
1539 case 0x3:
1540 if (rn == INTREG_PC) {
1541 %(mvn)s
1542 } else {
1543 %(orn)s
1544 }
1545 case 0x4:
1546 if (rd == INTREG_PC) {
1547 %(teq)s
1548 } else {
1549 %(eor)s
1550 }
1551 case 0x6:
1552 if (type) {
1553 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1554 } else {
1555 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1556 }
1557 case 0x8:
1558 if (rd == INTREG_PC) {
1559 %(cmn)s
1560 } else {
1561 %(add)s
1562 }
1563 case 0xa:
1564 %(adc)s
1565 case 0xb:
1566 %(sbc)s
1567 case 0xd:
1568 if (rd == INTREG_PC) {
1569 %(cmp)s
1570 } else {
1571 %(sub)s
1572 }
1573 case 0xe:
1574 %(rsb)s
1575 default:
1576 return new Unknown(machInst);
1577 }
1578 }
1579 ''' % {
1580 "tst" : decInst("Tst", "INTREG_ZERO"),
1581 "and" : decInst("And"),
1582 "bic" : decInst("Bic"),
1583 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1584 "orr" : decInst("Orr"),
1585 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1586 "orn" : decInst("Orn"),
1587 "teq" : decInst("Teq", "INTREG_ZERO"),
1588 "eor" : decInst("Eor"),
1589 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1590 "add" : decInst("Add"),
1591 "adc" : decInst("Adc"),
1592 "sbc" : decInst("Sbc"),
1593 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1594 "sub" : decInst("Sub"),
1595 "rsb" : decInst("Rsb")
1596 }
1597}};