nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 Copyright (c) 2013, Jurriaan Bremer
3 All rights reserved.
4  
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13 * Neither the name of the darm developer(s) nor the names of its
14 contributors may be used to endorse or promote products derived from this
15 software without specific prior written permission.
16  
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 POSSIBILITY OF SUCH DAMAGE.
28 */
29  
30 #include <stdio.h>
31 #include <stdint.h>
32 #include <string.h>
33 #include "darm.h"
34 #include "darm-internal.h"
35 #include "armv7-tbl.h"
36  
37 #define BITMSK_12 ((1 << 12) - 1)
38 #define BITMSK_16 ((1 << 16) - 1)
39 #define BITMSK_24 ((1 << 24) - 1)
40  
41 #define ROR(val, rotate) (((val) >> (rotate)) | ((val) << (32 - (rotate))))
42  
43 // the upper four bits define the rotation value, but we have to multiply the
44 // rotation value by two, so instead of right shifting by eight, we do a
45 // right shift of seven, effectively avoiding the left shift of one
46 #define ARMExpandImm(imm12) ROR((imm12) & 0xff, ((imm12) >> 7) & b11110)
47  
48 static struct {
49 const char *mnemonic_extension;
50 const char *meaning_integer;
51 const char *meaning_fp;
52 } g_condition_codes[] = {
53 {"EQ", "Equal", "Equal"},
54 {"NE", "Not equal", "Not equal, or unordered"},
55 {"CS", "Carry Set", "Greater than, equal, or unordered"},
56 {"CC", "Carry Clear", "Less than"},
57 {"MI", "Minus, negative", "Less than"},
58 {"PL", "Plus, positive or zero", "Greater than, equal, or unordered"},
59 {"VS", "Overflow", "Unordered"},
60 {"VC", "No overflow", "Not unordered"},
61 {"HI", "Unsigned higher", "Greater than, unordered"},
62 {"LS", "Unsigned lower or same", "Greater than, or unordered"},
63 {"GE", "Signed greater than or equal", "Greater than, or unordered"},
64 {"LT", "Signed less than", "Less than, or unordered"},
65 {"GT", "Signed greater than", "Greater than"},
66 {"LE", "Signed less than or equal", "Less than, equal, or unordered"},
67 {"AL", "Always (unconditional)", "Always (unconditional)"},
68 {"", "Unconditional", "Unconditional Instruction"},
69  
70 // alias for CS
71 {"HS", "Carry Set", "Greater than, equal, or unordered"},
72 // alias for CC
73 {"LO", "Carry Clear", "Less than"},
74 };
75  
76 static const char *shift_types[] = {
77 "LSL", "LSR", "ASR", "ROR",
78 };
79  
80 int darm_immshift_decode(const darm_t *d, const char **type,
81 uint32_t *immediate)
82 {
83 if(d->shift_type == S_INVLD) {
84 *type = NULL, *immediate = 0;
85 return -1;
86 }
87 else if(d->shift_type == S_ROR && d->Rs == R_INVLD && d->shift == 0) {
88 *type = "RRX", *immediate = 0;
89 }
90 else {
91 *type = darm_shift_type_name(d->shift_type);
92 *immediate = d->shift;
93  
94 // 32 is encoded as 0 for immediate shifts
95 if((d->shift_type == S_LSR || d->shift_type == S_ASR) &&
96 d->Rs == R_INVLD && d->shift == 0) {
97 *immediate = 32;
98 }
99 }
100 return 0;
101 }
102  
103 static int armv7_disas_uncond(darm_t *d, uint32_t w)
104 {
105 d->instr_type = T_ARM_UNCOND;
106  
107 // there are not a lot of unconditional instructions, so the following
108 // values are a bit hardcoded
109 switch ((w >> 25) & b111) {
110 case b000:
111 d->instr = I_SETEND;
112 d->E = (w >> 9) & 1;
113 return 0;
114  
115 case b010:
116 // if the 21th bit is set, then it's one of the CLREX, DMB, DSB or ISB
117 // instructions
118 if((w >> 21) & 1) {
119 d->instr = type_uncond2_instr_lookup[(w >> 4) & b111];
120 if(d->instr != I_INVLD) {
121 // if the instruction is either DMB, DSB or ISB, then the last
122 // four bits represent an "option"
123 if(d->instr != I_CLREX) {
124 d->option = w & b1111;
125 }
126 return 0;
127 }
128 }
129 // otherwise, if the 21th bit is not set, it's either the PLD or the
130 // PLI instruction
131 // we fall-through here, as 0b011 also handles the PLD and PLI
132 // instructions
133  
134 case b011:
135 // if the 24th bit is set, then this is a PLD instruction, otherwise
136 // it's a PLI instruction
137 d->instr = (w >> 24) & 1 ? I_PLD : I_PLI;
138  
139 d->Rn = (w >> 16) & b1111;
140 d->U = (w >> 23) & 1;
141  
142 // if the 25th bit is set, then this instruction takes a shifted
143 // register as offset, otherwise, it takes an immediate as offset
144 if((w >> 25) & 1) {
145 d->Rm = w & b1111;
146 d->shift_type = (w >> 5) & b11;
147 d->shift = (w >> 7) & b11111;
148 }
149 else {
150 d->I = B_SET;
151 d->imm = w & BITMSK_12;
152 }
153  
154 // if this instruction is PLD and the 22th bit is not set, then this
155 // is in fact PLDW
156 if(d->instr == I_PLD && ((w >> 22) & 1) == 0) {
157 d->instr = I_PLDW;
158 }
159 return 0;
160  
161 case b101:
162 d->instr = I_BLX;
163 d->H = (w >> 24) & 1;
164 d->imm = w & BITMSK_24;
165 d->I = B_SET;
166  
167 // check if the highest bit of the imm24 is set, if so, we
168 // manually sign-extend the integer
169 if((d->imm >> 23) & 1) {
170 d->imm = (d->imm | 0xff000000) << 2;
171 }
172 else {
173 d->imm = d->imm << 2;
174 }
175  
176 // add the H bit
177 d->imm |= d->H << 1;
178 return 0;
179  
180 case b111:
181 d->CRn = (w >> 16) & b1111;
182 d->coproc = (w >> 8) & b1111;
183 d->opc2 = (w >> 5) & b111;
184 d->CRm = w & b1111;
185  
186 if(((w >> 4) & 1) == 0) {
187 d->instr = I_CDP2;
188 d->CRd = (w >> 12) & b1111;
189 d->opc1 = (w >> 20) & b1111;
190 }
191 else {
192 d->instr = (w >> 20) & 1 ? I_MRC2 : I_MCR2;
193 d->opc1 = (w >> 21) & b111;
194 d->Rt = (w >> 12) & b1111;
195 }
196 return 0;
197 }
198 return -1;
199 }
200  
201 static int armv7_disas_cond(darm_t *d, uint32_t w)
202 {
203 // we first handle some exceptions for MUL, STR, and LDR-like
204 // instructions, which don't fit in the regular table (as they interfere
205 // with the other instructions)
206  
207 // we have to check two parts of the encoded instruction, namely bits
208 // 25..27 which should be zero, and bits 4..7, of which bit 4 and bit 7
209 // should be one
210 const uint32_t mask = (b111 << 25) | (b1001 << 4);
211 if((w & mask) == (b1001 << 4)) {
212  
213 // all variants of the MUL instruction
214 if(((w >> 24) & 1) == 0 && ((w >> 4) & b1111) == b1001) {
215  
216 d->instr = type_mul_instr_lookup[(w >> 21) & b111];
217 d->instr_type = T_ARM_MUL;
218  
219 // except for UMAAL and MLS, every variant takes the S bit
220 d->S = (w >> 20) & 1;
221  
222 // each variant takes Rm and Rn
223 d->Rm = (w >> 8) & b1111;
224 d->Rn = w & b1111;
225  
226 // if this is the UMAAL or MLS instruction *and* the S bit is set,
227 // then this is an invalid instruction
228 if((d->instr == I_UMAAL || d->instr == I_MLS) && d->S != 0) {
229 return -1;
230 }
231  
232 switch ((uint32_t) d->instr) {
233 case I_MLA: case I_MLS:
234 d->Ra = (w >> 12) & b1111;
235 // fall-through
236  
237 case I_MUL:
238 d->Rd = (w >> 16) & b1111;
239 break;
240  
241 case I_UMAAL: case I_UMULL: case I_UMLAL: case I_SMULL:
242 case I_SMLAL:
243 d->RdHi = (w >> 16) & b1111;
244 d->RdLo = (w >> 12) & b1111;
245 break;
246 }
247 return 0;
248 }
249 else if(((w >> 24) & 1) == 0 && ((w >> 5) & b11) != 0 &&
250 (w >> 21) & 1) {
251  
252 // the high 2 bits are represented by the 5th and 6th bit, the
253 // lower bit is represented by the 20th bit
254 uint32_t index = ((w >> 4) & b110) | ((w >> 20) & 1);
255 d->instr = type_stack1_instr_lookup[index];
256 if(d->instr == I_INVLD) return -1;
257  
258 d->instr_type = T_ARM_STACK1;
259 d->Rn = (w >> 16) & b1111;
260 d->Rt = (w >> 12) & b1111;
261 d->P = (w >> 24) & 1;
262 d->U = (w >> 23) & 1;
263  
264 // depending on the register form we either have to extract a
265 // register or an immediate
266 if(((w >> 22) & 1) == 0) {
267 d->Rm = w & b1111;
268 }
269 else {
270 // the four high bits start at bit 8, so we shift them right
271 // to their destination
272 d->imm = ((w >> 4) & b11110000) | (w & b1111);
273 d->I = B_SET;
274 }
275 return 0;
276 }
277 else if(((w >> 5) & b11) != 0 && ((w >> 20) & b10010) != b00010) {
278  
279 // the high 2 bits are represented by the 5th and 6th bit, the
280 // lower bit is represented by the 20th bit
281 uint32_t index = ((w >> 4) & b110) | ((w >> 20) & 1);
282 d->instr = type_stack2_instr_lookup[index];
283 if(d->instr == I_INVLD) return -1;
284  
285 d->instr_type = T_ARM_STACK2;
286 d->Rn = (w >> 16) & b1111;
287 d->Rt = (w >> 12) & b1111;
288 d->P = (w >> 24) & 1;
289 d->U = (w >> 23) & 1;
290 d->W = (w >> 21) & 1;
291  
292 // depending on the register form we either have to extract a
293 // register or an immediate
294 if(((w >> 22) & 1) == 0) {
295 d->Rm = w & b1111;
296 }
297 else {
298 // the four high bits start at bit 8, so we shift them right
299 // to their destination
300 d->imm = ((w >> 4) & b11110000) | (w & b1111);
301 d->I = B_SET;
302 }
303 return 0;
304 }
305 // synchronization primitive instructions
306 else if(((w >> 24) & 1) == 1 && ((w >> 4) & b1111) == b1001) {
307 d->instr = type_sync_instr_lookup[(w >> 20) & b1111];
308 d->instr_type = T_ARM_SYNC;
309 d->Rn = (w >> 16) & b1111;
310 switch ((uint32_t) d->instr) {
311 case I_SWP: case I_SWPB:
312 d->B = (w >> 22) & 1;
313 d->Rt = (w >> 12) & b1111;
314 d->Rt2 = w & b1111;
315 return 0;
316  
317 case I_LDREX: case I_LDREXD: case I_LDREXB: case I_LDREXH:
318 d->Rt = (w >> 12) & b1111;
319 return 0;
320  
321 case I_STREX: case I_STREXD: case I_STREXB: case I_STREXH:
322 d->Rd = (w >> 12) & b1111;
323 d->Rt = w & b1111;
324 return 0;
325 }
326 }
327 }
328 // handles the STR, STRT, LDR, LDRT, STRB, STRBT, LDRB, LDRBT stack
329 // instructions, and the media instructions
330 else if(((w >> 26) & b11) == b01) {
331  
332 // if both the 25th and the 4th bit are set, then this is a media
333 // instruction, which is handled in the big switch-case statement
334 const uint32_t media_mask = (1 << 25) | (1 << 4);
335 if((w & media_mask) != media_mask) {
336 d->instr = type_stack0_instr_lookup[(w >> 20) & b11111];
337 d->instr_type = T_ARM_STACK0;
338  
339 d->Rn = (w >> 16) & b1111;
340 d->Rt = (w >> 12) & b1111;
341  
342 // extract some flags
343 d->P = (w >> 24) & 1;
344 d->U = (w >> 23) & 1;
345 d->W = (w >> 21) & 1;
346  
347 // if the 25th bit is not set, then this instruction takes an
348 // immediate, otherwise, it takes a shifted register
349 if(((w >> 25) & 1) == 0) {
350 d->imm = w & BITMSK_12;
351 d->I = B_SET;
352 }
353 else {
354 d->shift_type = (w >> 5) & b11;
355 d->shift = (w >> 7) & b11111;
356 d->Rm = w & b1111;
357 }
358  
359 // if Rn == SP and P = 1 and U = 0 and W = 1 and imm12 = 4 and
360 // this is a STR instruction, then this is a PUSH instruction
361 if(d->instr == I_STR && d->Rn == SP && d->P == 1 && d->U == 0 &&
362 d->W == 1 && d->imm == 4) {
363 d->instr = I_PUSH;
364 }
365 // if Rn == SP and P = 0 and U = 1 and W = 0 and imm12 = 4 and
366 // this is a LDR instruction, then this is a POP instruction
367 else if(d->instr == I_LDR && d->Rn == SP && d->P == 0 &&
368 d->U == 1 && d->W == 0 && d->imm == 4) {
369 d->instr = I_POP;
370 }
371 return 0;
372 }
373 }
374 // handle saturating addition and subtraction instructions, these
375 // instructions have various masks; of bits 20..27 bit 24 is set and bits
376 // 21..22 specify which instruction this is, furthermore, bits 4..7
377 // represent the value 0b0101
378 const uint32_t mask2 = (b11111001 << 20) | (b1111 << 4);
379 if((w & mask2) == ((1 << 24) | (b0101 << 4))) {
380 d->instr = type_sat_instr_lookup[(w >> 21) & b11];
381 d->instr_type = T_ARM_SAT;
382 d->Rn = (w >> 16) & b1111;
383 d->Rd = (w >> 12) & b1111;
384 d->Rm = w & b1111;
385 return 0;
386 }
387 // handle packing, unpacking, saturation, and reversal instructions, these
388 // instructions have the 4th bit set and bits 23..27 represent 0b01101
389 const uint32_t mask3 = (b11111 << 23) | (1 << 4);
390 if((w & mask3) == ((b01101 << 23) | (1 << 4))) {
391 // some instructions are already handled elsewhere (namely, PKH, SEL,
392 // REV, REV16, RBIT, and REVSH)
393 uint32_t op1 = (w >> 20) & b111;
394 uint32_t A = (w >> 16) & b1111;
395 uint32_t op2 = (w >> 5) & b111;
396  
397 d->instr_type = T_ARM_PUSR;
398  
399 // the (SX|UX)T(A)(B|H)(16) instructions
400 // op1 represents the upper three bits, and A = 0b1111 represents
401 if(op2 == b011) {
402 // the lower bit
403 d->instr = type_pusr_instr_lookup[(op1 << 1) | (A == b1111)];
404 if(d->instr != I_INVLD) {
405 d->Rd = (w >> 12) & b1111;
406 d->Rm = w & b1111;
407  
408 // rotation is shifted to the left by three, so we do this
409 // directly in our shift as well
410 d->rotate = (w >> 7) & b11000;
411  
412 // if A is not 0b1111, then A represents the Rn operand
413 if(A != b1111) {
414 d->Rn = A;
415 }
416 return 0;
417 }
418 }
419  
420 // SSAT
421 if((op1 & b010) == b010 && (op2 & 1) == 0) {
422 // if the upper bit is set, then it's USAT, otherwise SSAT
423 d->instr = (op1 >> 2) ? I_USAT : I_SSAT;
424 d->imm = (w >> 16) & b11111;
425 d->I = B_SET;
426 // signed saturate adds one to the immediate
427 if(d->instr == I_SSAT) {
428 d->imm++;
429 }
430 d->Rd = (w >> 12) & b1111;
431 d->shift = (w >> 7) & b11111;
432 d->shift_type = (w >> 5) & b11;
433 d->Rn = w & b1111;
434 return 0;
435 }
436  
437 // SSAT16 and USAT16
438 if((op1 == b010 || op1 == b110) && op2 == b001) {
439 d->instr = op1 == b010 ? I_SSAT16 : I_USAT16;
440 d->imm = (w >> 16) & b1111;
441 d->I = B_SET;
442 // signed saturate 16 adds one to the immediate
443 if(d->instr == I_SSAT16) {
444 d->imm++;
445 }
446 d->Rd = (w >> 12) & b1111;
447 d->Rn = w & b1111;
448 return 0;
449 }
450 }
451  
452 // the instruction label
453 d->instr = armv7_instr_labels[(w >> 20) & 0xff];
454 d->instr_type = armv7_instr_types[(w >> 20) & 0xff];
455  
456 // do a lookup for the type of instruction
457 switch ((uint32_t) d->instr_type) {
458 case T_ARM_ARITH_SHIFT:
459 d->S = (w >> 20) & 1;
460 d->Rd = (w >> 12) & b1111;
461 d->Rn = (w >> 16) & b1111;
462 d->Rm = w & b1111;
463 d->shift_type = (w >> 5) & b11;
464  
465 // type == 1, shift with the value of the lower bits of Rs
466 if(((w >> 4) & 1) == B_SET) {
467 d->Rs = (w >> 8) & b1111;
468 }
469 else {
470 d->shift = (w >> 7) & b11111;
471 }
472 return 0;
473  
474 case T_ARM_ARITH_IMM:
475 d->S = (w >> 20) & 1;
476 d->Rd = (w >> 12) & b1111;
477 d->Rn = (w >> 16) & b1111;
478 d->imm = ARMExpandImm(w & BITMSK_12);
479 d->I = B_SET;
480  
481 // check whether this instruction is in fact an ADR instruction
482 if((d->instr == I_ADD || d->instr == I_SUB) &&
483 d->S == 0 && d->Rn == PC) {
484 d->instr = I_ADR, d->Rn = R_INVLD;
485 d->U = (w >> 23) & 1;
486 }
487 return 0;
488  
489 case T_ARM_BITS:
490 d->instr = type_bits_instr_lookup[(w >> 21) & b11];
491  
492 d->instr_type = T_ARM_BITS;
493 d->Rd = (w >> 12) & b1111;
494 d->Rn = w & b1111;
495 d->lsb = (w >> 7) & b11111;
496  
497 // the bfi and bfc instructions specify the MSB, whereas the SBFX and
498 // UBFX instructions specify the width minus one
499 if(d->instr == I_BFI) {
500 d->width = ((w >> 16) & b11111) - d->lsb + 1;
501  
502 // if Rn is 0b1111, then this is in fact the BFC instruction
503 if(d->Rn == b1111) {
504 d->Rn = R_INVLD;
505 d->instr = I_BFC;
506 }
507 }
508 else {
509 d->width = ((w >> 16) & b11111) + 1;
510 }
511 return 0;
512  
513 case T_ARM_BRNCHSC:
514 d->imm = w & BITMSK_24;
515 d->I = B_SET;
516  
517 // if the instruction is B or BL, then we have to sign-extend it and
518 // multiply it with four
519 if(d->instr != I_SVC) {
520 // check if the highest bit of the imm24 is set, if so, we
521 // manually sign-extend the integer
522 if((d->imm >> 23) & 1) {
523 d->imm = (d->imm | 0xff000000) << 2;
524 }
525 else {
526 d->imm = d->imm << 2;
527 }
528 }
529 return 0;
530  
531 case T_ARM_BRNCHMISC:
532 // first get the real instruction label
533 d->instr = type_brnchmisc_instr_lookup[(w >> 4) & b1111];
534  
535 // now we do a switch statement based on the instruction label,
536 // rather than some magic values
537 switch ((uint32_t) d->instr) {
538 case I_BKPT:
539 d->imm = (((w >> 8) & BITMSK_12) << 4) + (w & b1111);
540 d->I = B_SET;
541 return 0;
542  
543 case I_BX: case I_BXJ: case I_BLX:
544 d->Rm = w & b1111;
545 return 0;
546  
547 case I_MSR:
548 d->Rn = w & b1111;
549 d->imm = (w >> 18) & b11;
550 d->I = B_SET;
551 return 0;
552  
553 case I_QSUB: case I_SMLAW: case I_SMULW: default:
554 // returns -1
555 break;
556 }
557 break;
558  
559 case T_ARM_MOV_IMM:
560 d->Rd = (w >> 12) & b1111;
561 d->imm = w & BITMSK_12;
562 d->I = B_SET;
563  
564 // the MOV and MVN instructions have an S bit
565 if(d->instr == I_MOV || d->instr == I_MVN) {
566 d->S = (w >> 20) & 1;
567  
568 // the immediate values of the MOV and MVN instructions have to
569 // be decoded
570 d->imm = ARMExpandImm(d->imm);
571 }
572 // the MOVW and the MOVT instructions take another 4 bits of immediate
573 else {
574 d->imm |= ((w >> 16) & b1111) << 12;
575 }
576 return 0;
577  
578 case T_ARM_CMP_OP:
579 d->Rn = (w >> 16) & b1111;
580 d->Rm = w & b1111;
581 d->shift_type = (w >> 5) & b11;
582  
583 // type == 1, shift with the value of the lower bits of Rs
584 if(((w >> 4) & 1) == B_SET) {
585 d->Rs = (w >> 8) & b1111;
586 }
587 else {
588 d->shift = (w >> 7) & b11111;
589 }
590 return 0;
591  
592 case T_ARM_CMP_IMM:
593 d->Rn = (w >> 16) & b1111;
594 d->imm = ARMExpandImm(w & BITMSK_12);
595 d->I = B_SET;
596 return 0;
597  
598 case T_ARM_OPLESS:
599 d->instr = type_opless_instr_lookup[w & b111];
600 return d->instr == I_INVLD ? -1 : 0;
601  
602 case T_ARM_DST_SRC:
603 d->instr = type_shift_instr_lookup[(w >> 4) & b1111];
604 if(d->instr == I_INVLD) return -1;
605  
606 d->S = (w >> 20) & 1;
607 d->Rd = (w >> 12) & b1111;
608 d->shift_type = (w >> 5) & b11;
609 if((w >> 4) & 1) {
610 d->Rm = (w >> 8) & b1111;
611 d->Rn = w & b1111;
612 }
613 else {
614 d->Rm = w & b1111;
615 d->shift = (w >> 7) & b11111;
616  
617 // if this is a LSL instruction with a zero shift, then it's
618 // actually a MOV instruction (there's no register-shifted LSL)
619 if(d->instr == I_LSL && d->shift_type == S_LSL && d->shift == 0) {
620 d->instr = I_MOV;
621 }
622  
623 // if this is a ROR instruction with a zero shift, then it's
624 // actually a RRX instruction (there's no register-shifted ROR)
625 else if(d->instr == I_ROR && d->shift_type == S_ROR &&
626 d->shift == 0) {
627 d->instr = I_RRX;
628 }
629 }
630  
631 return 0;
632  
633 case T_ARM_LDSTREGS:
634 d->W = (w >> 21) & 1;
635 d->Rn = (w >> 16) & b1111;
636 d->reglist = w & BITMSK_16;
637  
638 // if this is the LDM instruction and W = 1 and Rn = SP then this is
639 // a POP instruction
640 if(d->instr == I_LDM && d->W == 1 && d->Rn == SP) {
641 d->instr = I_POP;
642 }
643 // if this is the STMDB instruction and W = 1 and Rn = SP then this is
644 // the PUSH instruction
645 else if(d->instr == I_STMDB && d->W == 1 && d->Rn == SP) {
646 d->instr = I_PUSH;
647 }
648 return 0;
649  
650 case T_ARM_BITREV:
651 d->Rd = (w >> 12) & b1111;
652 d->Rm = w & b1111;
653  
654 // if this is the REV16 instruction and bits 4..7 are 0b0011, then
655 // this is in fact the REV instruction
656 if(d->instr == I_REV16 && ((w >> 4) & b1111) == b0011) {
657 d->instr = I_REV;
658 }
659 // if this is the REVSH instruction and bits 4..7 are 0b0011, then
660 // this is in fact the RBIT instruction
661 else if(d->instr == I_REVSH && ((w >> 4) & b1111) == b0011) {
662 d->instr = I_RBIT;
663 }
664 return 0;
665  
666 case T_ARM_MISC:
667 switch ((uint32_t) d->instr) {
668 case I_MVN:
669 d->S = (w >> 20) & 1;
670 d->Rd = (w >> 12) & b1111;
671 d->shift_type = (w >> 5) & b11;
672 d->Rm = w & b1111;
673 if(((w >> 4) & 1) == B_UNSET) {
674 d->shift = (w >> 7) & b11111;
675 }
676 else {
677 d->Rs = (w >> 8) & b1111;
678 }
679 return 0;
680  
681 case I_DBG:
682 d->option = w & b1111;
683 return 0;
684  
685 case I_SMC:
686 switch ((w >> 4) & b1111) {
687 // if the 7th bit is 1 and the 4th bit 0, then this is
688 // the SMUL instruction
689 case b1000: case b1010: case b1100: case b1110:
690 d->instr = I_SMUL;
691 d->instr_type = T_ARM_SM;
692 d->Rd = (w >> 16) & b1111;
693 d->Rm = (w >> 8) & b1111;
694 d->M = (w >> 6) & 1;
695 d->N = (w >> 5) & 1;
696 d->Rn = w & b1111;
697 break;
698  
699 // smc
700 case b0111:
701 d->instr = I_SMC;
702 d->imm = w & b1111;
703 d->I = B_SET;
704 break;
705  
706 // clz
707 case b0001:
708 d->instr = I_CLZ;
709 d->Rm = w & b1111;
710 d->Rd = (w >> 12) & b1111;
711 break;
712  
713 default:
714 return -1;
715 }
716 return 0;
717  
718 case I_SEL:
719 d->Rd = (w >> 12) & b1111;
720 d->Rn = (w >> 16) & b1111;
721 d->Rm = w & b1111;
722  
723 // the SEL and PKH instructions share the same 8-bit identifier,
724 // if the 5th bit is set, then this is the SEL instruction,
725 // otherwise it's the PKH instruction
726 if(((w >> 5) & 1) == 0) {
727 d->instr = I_PKH;
728 d->shift_type = (w >> 5) & b10;
729 d->shift = (w >> 7) & b11111;
730 d->T = (w >> 6) & 1;
731 }
732 return 0;
733 }
734  
735 case T_ARM_SM:
736 switch ((uint32_t) d->instr) {
737 case I_SMMUL:
738 d->Rd = (w >> 16) & b1111;
739 d->Ra = (w >> 12) & b1111;
740 d->Rm = (w >> 8) & b1111;
741 d->R = (w >> 5) & 1;
742 d->Rn = w & b1111;
743  
744 // this can be either the SMMUL, the SMMLA, or the SMMLS
745 // instruction, depending on the 6th bit and Ra
746 if((w >> 6) & 1) {
747 d->instr = I_SMMLS;
748 }
749 // if it's SMMUL instruction, but Ra is not 0b1111, then this is
750 // the SMMLA instruction
751 else if(d->Ra != b1111) {
752 d->instr = I_SMMLA;
753 }
754 return 0;
755  
756 case I_SMUSD:
757 d->Rd = (w >> 16) & b1111;
758 d->Ra = (w >> 12) & b1111;
759 d->Rm = (w >> 8) & b1111;
760 d->M = (w >> 5) & 1;
761 d->Rn = w & b1111;
762  
763 // this can be either the SMLAD, the SMLSD, the SMUAD, or the
764 // SMUSD instruction, depending on the 6th bit and Ra
765 if((w >> 6) & 1 && d->Rn != b1111) {
766 d->instr = I_SMLSD;
767 }
768 else if(((w >> 6) & 1) == 0) {
769 d->instr = d->Ra == b1111 ? I_SMUAD : I_SMLAD;
770 }
771 return 0;
772  
773 case I_SMLSLD:
774 d->RdHi = (w >> 16) & b1111;
775 d->RdLo = (w >> 12) & b1111;
776 d->Rm = (w >> 8) & b1111;
777 d->M = (w >> 5) & 1;
778 d->Rn = w & b1111;
779  
780 // if the 6th bit is zero, then this is in fact the SMLALD
781 // instruction
782 if(((w >> 6) & 1) == 0) {
783 d->instr = I_SMLALD;
784 }
785 return 0;
786  
787 case I_SMLA:
788 d->Rd = (w >> 16) & b1111;
789 d->Ra = (w >> 12) & b1111;
790 d->Rm = (w >> 8) & b1111;
791 d->M = (w >> 6) & 1;
792 d->N = (w >> 5) & 1;
793 d->Rn = w & b1111;
794 return 0;
795  
796 case I_SMLAL:
797 d->RdHi = (w >> 16) & b1111;
798 d->RdLo = (w >> 12) & b1111;
799 d->Rm = (w >> 8) & b1111;
800 d->M = (w >> 6) & 1;
801 d->N = (w >> 5) & 1;
802 d->Rn = w & b1111;
803 return 0;
804  
805 case I_SMUL:
806 // SMUL overlaps with SMC, so we define SMUL in SMC..
807 break;
808 }
809  
810 case T_ARM_PAS:
811 // we have a lookup table with size 64, for all parallel signed and
812 // unsigned addition and subtraction instructions
813 // the upper three bits are represented by bits 20..22, so we only
814 // right-shift those 17 bytes, the lower three bits are represented
815 // by bits 5..7
816 d->instr = type_pas_instr_lookup[((w >> 17) & b111000) |
817 ((w >> 5) & b111)];
818 if(d->instr == I_INVLD) return -1;
819  
820 d->Rn = (w >> 16) & b1111;
821 d->Rd = (w >> 12) & b1111;
822 d->Rm = w & b1111;
823 return 0;
824  
825 case T_ARM_MVCR:
826 d->CRn = (w >> 16) & b1111;
827 d->coproc = (w >> 8) & b1111;
828 d->opc2 = (w >> 5) & b111;
829 d->CRm = w & b1111;
830  
831 if(((w >> 4) & 1) == 0) {
832 d->instr = I_CDP;
833 d->opc1 = (w >> 20) & b1111;
834 d->CRd = (w >> 12) & b1111;
835 }
836 else {
837 d->opc1 = (w >> 21) & b111;
838 d->Rt = (w >> 12) & b1111;
839 }
840 return 0;
841  
842 case T_ARM_UDF:
843 d->I = B_SET;
844 d->imm = (w & b1111) | ((w >> 4) & (BITMSK_12 << 4));
845 return 0;
846 }
847 return -1;
848 }
849  
850 int darm_armv7_disasm(darm_t *d, uint32_t w)
851 {
852 int ret;
853  
854 darm_init(d);
855 d->w = w;
856 d->cond = (w >> 28) & b1111;
857  
858 if(d->cond == C_UNCOND) {
859 ret = armv7_disas_uncond(d, w);
860 }
861 else {
862 ret = armv7_disas_cond(d, w);
863 }
864  
865 // return error
866 if(ret < 0) return ret;
867  
868 // if the shift-type is set to S_LSL, but Rs is R_INVLD and shift is zero,
869 // then there's effectively no shift, so we set shift-type to S_INVLD
870 if(d->shift_type == S_LSL && d->Rs == R_INVLD && d->shift == 0) {
871 d->shift_type = S_INVLD;
872 }
873  
874 return 0;
875 }
876  
877 const char *darm_mnemonic_name(darm_instr_t instr)
878 {
879 return instr < ARRAYSIZE(darm_mnemonics) ?
880 darm_mnemonics[instr] : NULL;
881 }
882  
883 const char *darm_enctype_name(darm_enctype_t enctype)
884 {
885 return enctype < ARRAYSIZE(darm_enctypes) ?
886 darm_enctypes[enctype] : NULL;
887 }
888  
889 const char *darm_register_name(darm_reg_t reg)
890 {
891 return reg != R_INVLD && reg < (int32_t) ARRAYSIZE(darm_registers) ?
892 darm_registers[reg] : NULL;
893 }
894  
895 const char *darm_shift_type_name(darm_shift_type_t shifttype)
896 {
897 return
898 shifttype != S_INVLD && shifttype < (int32_t) ARRAYSIZE(shift_types) ?
899 shift_types[shifttype] : NULL;
900 }
901  
902 const char *darm_condition_name(darm_cond_t cond, int omit_always_execute)
903 {
904 // we don't give the AL postfix, as almost every instruction would need
905 // one then
906 if(omit_always_execute != 0 && cond == C_AL) return "";
907  
908 return cond != C_INVLD && cond < (int32_t) ARRAYSIZE(g_condition_codes) ?
909 g_condition_codes[cond].mnemonic_extension : NULL;
910 }
911  
912 const char *darm_condition_meaning_int(darm_cond_t cond)
913 {
914 return cond != C_INVLD && cond < (int32_t) ARRAYSIZE(g_condition_codes) ?
915 g_condition_codes[cond].meaning_integer : NULL;
916 }
917  
918 const char *darm_condition_meaning_fp(darm_cond_t cond)
919 {
920 return cond != C_INVLD && cond < (int32_t) ARRAYSIZE(g_condition_codes) ?
921 g_condition_codes[cond].meaning_fp : NULL;
922 }
923  
924 darm_cond_t darm_condition_index(const char *condition_code)
925 {
926 if(condition_code == NULL) return -1;
927  
928 // the "AL" condition flag
929 if(condition_code[0] == 0) return C_AL;
930  
931 for (uint32_t i = 0; i < ARRAYSIZE(g_condition_codes); i++) {
932 if(!strcmp(condition_code, g_condition_codes[i].mnemonic_extension)) {
933 return i;
934 }
935 }
936  
937 return C_INVLD;
938 }