1 // Copyright (c) 2010 ARM Limited
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.
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.
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.
36 // Authors: Gabe Black
38 def format ArmDataProcReg() {{
43 return new %(className)sRegCc(machInst, %(dest)s, %(op1)s,
46 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
51 return new %(className)sRegRegCc(machInst, %(dest)s,
52 %(op1)s, rm, rs, type);
54 return new %(className)sRegReg(machInst, %(dest)s,
55 %(op1)s, rm, rs, type);
61 def instCode(opcode, mnem, dest="rd", op1="rn"):
63 return instDecode % { "className": mnem.capitalize(),
70 const bool immShift = (bits(machInst, 4) == 0);
71 const bool setCc = (bits(machInst, 20) == 1);
72 const uint32_t imm5 = bits(machInst, 11, 7);
73 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
74 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
75 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
76 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
77 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
80 decode_block += instCode(0x0, "and")
81 decode_block += instCode(0x1, "eor")
82 decode_block += instCode(0x2, "sub")
83 decode_block += instCode(0x3, "rsb")
84 decode_block += instCode(0x4, "add")
85 decode_block += instCode(0x5, "adc")
86 decode_block += instCode(0x6, "sbc")
87 decode_block += instCode(0x7, "rsc")
88 decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
89 decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
90 decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
91 decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
92 decode_block += instCode(0xc, "orr")
93 decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
94 decode_block += instCode(0xe, "bic")
95 decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
98 return new Unknown(machInst);
104 def format ArmDataProcImm() {{
108 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
111 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
117 def instCode(opcode, mnem, dest="rd", op1="rn"):
119 return instDecode % { "className": mnem.capitalize(),
126 const bool setCc = (bits(machInst, 20) == 1);
127 const uint32_t unrotated = bits(machInst, 7, 0);
128 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
129 const bool rotC = (rotation != 0);
130 const uint32_t imm = rotate_imm(unrotated, rotation);
131 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
132 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
135 decode_block += instCode(0x0, "and")
136 decode_block += instCode(0x1, "eor")
137 decode_block += instCode(0x2, "sub")
138 decode_block += instCode(0x3, "rsb")
139 decode_block += instCode(0x4, "add")
140 decode_block += instCode(0x5, "adc")
141 decode_block += instCode(0x6, "sbc")
142 decode_block += instCode(0x7, "rsc")
143 decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
144 decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
145 decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
146 decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
147 decode_block += instCode(0xc, "orr")
148 decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
149 decode_block += instCode(0xe, "bic")
150 decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
153 return new Unknown(machInst);
159 def format Thumb16ShiftAddSubMoveCmp() {{
162 const uint32_t imm5 = bits(machInst, 10, 6);
163 const uint32_t imm3 = bits(machInst, 8, 6);
164 const uint32_t imm8 = bits(machInst, 7, 0);
165 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
166 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
167 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
168 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
169 switch (bits(machInst, 13, 11)) {
171 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
173 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
175 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
177 switch (bits(machInst, 10, 9)) {
179 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
181 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
183 return new AddImmCc(machInst, rd, rn, imm3, true);
185 return new SubImmCc(machInst, rd, rn, imm3, true);
188 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
190 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
192 return new AddImmCc(machInst, rd8, rd8, imm8, true);
194 return new SubImmCc(machInst, rd8, rd8, imm8, true);
200 def format Thumb16DataProcessing() {{
203 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
204 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
205 switch (bits(machInst, 9, 6)) {
207 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
209 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
211 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
213 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
215 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
217 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
219 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
221 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
223 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
225 return new RsbImmCc(machInst, rdn, rm, 0, true);
227 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
229 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
231 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
233 return new MulCc(machInst, rdn, rm, rdn);
235 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
237 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
243 def format Thumb16SpecDataAndBx() {{
246 const IntRegIndex rdn =
247 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
248 (bits(machInst, 7) << 3));
249 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
250 switch (bits(machInst, 9, 8)) {
252 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
254 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
256 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
258 if (bits(machInst, 7) == 0) {
259 return new BxReg(machInst,
260 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
263 return new BlxReg(machInst,
264 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
272 def format Thumb16Adr() {{
275 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
276 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
277 return new AddImm(machInst, rd, INTREG_PC, imm8, true);
282 def format Thumb16AddSp() {{
285 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
286 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
287 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
292 def format Thumb16Misc() {{
295 switch (bits(machInst, 11, 8)) {
297 if (bits(machInst, 7)) {
298 return new SubImm(machInst, INTREG_SP, INTREG_SP,
299 bits(machInst, 6, 0) << 2, true);
301 return new AddImm(machInst, INTREG_SP, INTREG_SP,
302 bits(machInst, 6, 0) << 2, true);
305 return new Cbz(machInst,
306 (bits(machInst, 9) << 6) |
307 (bits(machInst, 7, 3) << 1),
308 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
310 switch (bits(machInst, 7, 6)) {
312 return new WarnUnimplemented("sxth", machInst);
314 return new WarnUnimplemented("sxtb", machInst);
316 return new WarnUnimplemented("uxth", machInst);
318 return new WarnUnimplemented("uxtb", machInst);
321 return new Cbz(machInst,
322 (bits(machInst, 9) << 6) |
323 (bits(machInst, 7, 3) << 1),
324 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
327 return new WarnUnimplemented("push", machInst);
330 const uint32_t opBits = bits(machInst, 7, 5);
332 return new WarnUnimplemented("setend", machInst);
333 } else if (opBits == 3) {
334 return new WarnUnimplemented("cps", machInst);
338 return new Cbnz(machInst,
339 (bits(machInst, 9) << 6) |
340 (bits(machInst, 7, 3) << 1),
341 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
343 switch (bits(machInst, 7, 5)) {
345 return new WarnUnimplemented("rev", machInst);
347 return new WarnUnimplemented("rev16", machInst);
349 return new WarnUnimplemented("revsh", machInst);
355 return new Cbnz(machInst,
356 (bits(machInst, 9) << 6) |
357 (bits(machInst, 7, 3) << 1),
358 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
361 return new WarnUnimplemented("pop", machInst);
363 return new WarnUnimplemented("bkpt", machInst);
365 if (bits(machInst, 3, 0) != 0)
366 return new WarnUnimplemented("it", machInst);
367 switch (bits(machInst, 7, 4)) {
369 return new WarnUnimplemented("nop", machInst);
371 return new WarnUnimplemented("yield", machInst);
373 return new WarnUnimplemented("wfe", machInst);
375 return new WarnUnimplemented("wfi", machInst);
377 return new WarnUnimplemented("sev", machInst);
379 return new WarnUnimplemented("unallocated_hint", machInst);
384 return new Unknown(machInst);
389 def format Thumb32DataProcModImm() {{
391 def decInst(mnem, dest="rd", op1="rn"):
394 return new %(mnem)sImmCc(machInst, %(dest)s,
397 return new %(mnem)sImm(machInst, %(dest)s,
400 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
404 const uint32_t op = bits(machInst, 24, 21);
405 const bool s = (bits(machInst, 20) == 1);
406 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
407 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
408 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
409 bits(machInst, 14, 12);
410 const bool rotC = ctrlImm > 3;
411 const uint32_t dataImm = bits(machInst, 7, 0);
412 const uint32_t imm = modified_imm(ctrlImm, dataImm);
415 if (rd == INTREG_PC) {
423 if (rn == INTREG_PC) {
429 if (rn == INTREG_PC) {
435 if (rd == INTREG_PC) {
441 if (rd == INTREG_PC) {
451 if (rd == INTREG_PC) {
459 return new Unknown(machInst);
463 "tst" : decInst("Tst", "INTREG_ZERO"),
464 "and" : decInst("And"),
465 "bic" : decInst("Bic"),
466 "mov" : decInst("Mov", op1="INTREG_ZERO"),
467 "orr" : decInst("Orr"),
468 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
469 "orn" : decInst("Orn"),
470 "teq" : decInst("Teq", dest="INTREG_ZERO"),
471 "eor" : decInst("Eor"),
472 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
473 "add" : decInst("Add"),
474 "adc" : decInst("Adc"),
475 "sbc" : decInst("Sbc"),
476 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
477 "sub" : decInst("Sub"),
478 "rsb" : decInst("Rsb")
482 def format Thumb32DataProcPlainBin() {{
485 const uint32_t op = bits(machInst, 24, 20);
486 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
487 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
491 const uint32_t imm = bits(machInst, 7, 0) |
492 (bits(machInst, 14, 12) << 8) |
493 (bits(machInst, 26) << 11);
494 return new AddImm(machInst, rd, rn, imm, true);
498 const uint32_t imm = bits(machInst, 7, 0) |
499 (bits(machInst, 14, 12) << 8) |
500 (bits(machInst, 26) << 11) |
501 (bits(machInst, 19, 16) << 12);
502 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
506 const uint32_t imm = bits(machInst, 7, 0) |
507 (bits(machInst, 14, 12) << 8) |
508 (bits(machInst, 26) << 11);
509 return new SubImm(machInst, rd, rn, imm, true);
513 const uint32_t imm = bits(machInst, 7, 0) |
514 (bits(machInst, 14, 12) << 8) |
515 (bits(machInst, 26) << 11) |
516 (bits(machInst, 19, 16) << 12);
517 return new MovtImm(machInst, rd, rd, imm, true);
520 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
521 return new WarnUnimplemented("ssat16", machInst);
523 // Fall through on purpose...
525 return new WarnUnimplemented("ssat", machInst);
527 return new WarnUnimplemented("sbfx", machInst);
530 return new WarnUnimplemented("bfc", machInst);
532 return new WarnUnimplemented("bfi", machInst);
535 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
536 return new WarnUnimplemented("usat16", machInst);
538 // Fall through on purpose...
540 return new WarnUnimplemented("usat", machInst);
542 return new WarnUnimplemented("ubfx", machInst);
544 return new Unknown(machInst);
550 def format Thumb32DataProcShiftReg() {{
552 def decInst(mnem, dest="rd", op1="rn"):
555 return new %(mnem)sRegCc(machInst, %(dest)s,
556 %(op1)s, rm, amt, type);
558 return new %(mnem)sReg(machInst, %(dest)s,
559 %(op1)s, rm, amt, type);
561 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
565 const uint32_t op = bits(machInst, 24, 21);
566 const bool s = (bits(machInst, 20) == 1);
567 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
568 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
569 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
570 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
571 bits(machInst, 7, 6);
572 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
575 if (rd == INTREG_PC) {
583 if (rn == INTREG_PC) {
589 if (rn == INTREG_PC) {
595 if (rd == INTREG_PC) {
601 return new WarnUnimplemented("pkh", machInst);
603 if (rd == INTREG_PC) {
613 if (rd == INTREG_PC) {
621 return new Unknown(machInst);
625 "tst" : decInst("Tst", "INTREG_ZERO"),
626 "and" : decInst("And"),
627 "bic" : decInst("Bic"),
628 "mov" : decInst("Mov", op1="INTREG_ZERO"),
629 "orr" : decInst("Orr"),
630 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
631 "orn" : decInst("Orn"),
632 "teq" : decInst("Teq", "INTREG_ZERO"),
633 "eor" : decInst("Eor"),
634 "cmn" : decInst("Cmn", "INTREG_ZERO"),
635 "add" : decInst("Add"),
636 "adc" : decInst("Adc"),
637 "sbc" : decInst("Sbc"),
638 "cmp" : decInst("Cmp", "INTREG_ZERO"),
639 "sub" : decInst("Sub"),
640 "rsb" : decInst("Rsb")