comparison arm7dis/armdis.c @ 92:708f2452d1ae

armdis: full ldr/str decoding implemented
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 30 Mar 2014 01:47:28 +0000
parents daf69d5edb3f
children 5ebebbc74622
comparison
equal deleted inserted replaced
91:daf69d5edb3f 92:708f2452d1ae
207 regnames[word&0xF], regnames[(word>>8)&0xF]); 207 regnames[word&0xF], regnames[(word>>8)&0xF]);
208 else 208 else
209 printf("<invalid multiply>\n"); 209 printf("<invalid multiply>\n");
210 } 210 }
211 211
212 static int
213 check_ldr_litpool(off, word, loff, size)
214 unsigned off, word, loff;
215 {
216 unsigned litoff, datum;
217
218 /* base reg must be 15 */
219 if (((word >> 16) & 0xF) != 15)
220 return(0);
221 /* must be a load */
222 if (!(word & 0x100000))
223 return(0);
224 /* no writeback allowed */
225 if (word & 0x200000)
226 return(0);
227 /* alignment */
228 if (loff & (size - 1))
229 return(0);
230 /* range */
231 off += 8;
232 if (word & 0x800000)
233 litoff = off + loff;
234 else {
235 if (loff > off)
236 return(0);
237 litoff = off - loff;
238 }
239 if (litoff >= disasm_len)
240 return(0);
241 /* all checks passed, proceed */
242 switch (size) {
243 case 1:
244 datum = filemap[litoff];
245 break;
246 case 2:
247 datum = get_u16(filemap + litoff);
248 break;
249 case 4:
250 datum = get_u32(filemap + litoff);
251 break;
252 }
253 printf("=0x%x\t; via 0x%x\n", datum, litoff);
254 return(1);
255 }
256
212 static void 257 static void
213 ldr_str_imm_pre(off, word) 258 ldr_str_imm_pre(off, word)
214 unsigned off, word; 259 unsigned off, word;
215 { 260 {
216 unsigned loff = word & 0xFFF; 261 unsigned loff = word & 0xFFF;
217 262
218 /* check for literal pool fetches will go here */ 263 printf("%s%s%s\t%s, ", word&0x100000 ? "ldr" : "str",
219 printf("%s%s%s\t%s, [%s", word&0x100000 ? "ldr" : "str",
220 condition_decode[word>>28], word&0x400000 ? "b" : "", 264 condition_decode[word>>28], word&0x400000 ? "b" : "",
221 regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]); 265 regnames[(word>>12)&0xF]);
266 if (check_ldr_litpool(off, word, loff, word&0x400000 ? 1 : 4))
267 return;
268 printf("[%s", regnames[(word>>16)&0xF]);
222 if (loff || word&0x200000) 269 if (loff || word&0x200000)
223 printf(", #%s%u", word&0x800000 ? "" : "-", loff); 270 printf(", #%s%u", word&0x800000 ? "" : "-", loff);
224 putchar(']'); 271 putchar(']');
225 if (word & 0x200000) 272 if (word & 0x200000)
226 putchar('!'); 273 putchar('!');
285 332
286 static void 333 static void
287 ldr_str_ext(off, word) 334 ldr_str_ext(off, word)
288 unsigned off, word; 335 unsigned off, word;
289 { 336 {
290 printf("<extended ldr/str>\n"); 337 unsigned loff;
338
339 if (!(word&0x01000000) && word&0x200000) {
340 printf("<invalid ldrh/strh: P=0, W=1>\n");
341 return;
342 }
343 if (!(word&0x400000) && word&0xF00) {
344 printf("<invalid ldrh/strh: SBZ!=0>\n");
345 return;
346 }
347 printf("%s%s%s%c\t%s, ", word&0x100000 ? "ldr" : "str",
348 condition_decode[word>>28],
349 word&0x40 ? "s" : "",
350 word&0x20 ? 'h' : 'b',
351 regnames[(word>>12)&0xF]);
352 if (word & 0x400000)
353 loff = ((word & 0xF00) >> 4) | (word & 0xF);
354 switch (word & 0x01400000) {
355 case 0:
356 /* reg post */
357 printf("[%s], %s%s", regnames[(word>>16)&0xF],
358 word&0x800000 ? "" : "-", regnames[word&0xF]);
359 break;
360 case 0x400000:
361 /* imm post */
362 printf("[%s], #%s%u", regnames[(word>>16)&0xF],
363 word&0x800000 ? "" : "-", loff);
364 if (loff >= 10)
365 printf("\t; 0x%x", loff);
366 break;
367 case 0x01000000:
368 /* reg pre */
369 printf("[%s, %s%s]%s", regnames[(word>>16)&0xF],
370 word&0x800000 ? "" : "-", regnames[word&0xF],
371 word&0x200000 ? "!" : "");
372 break;
373 case 0x01400000:
374 /* imm pre */
375 if (check_ldr_litpool(off, word, loff, word&0x20 ? 2 : 1))
376 return;
377 printf("[%s", regnames[(word>>16)&0xF]);
378 if (loff || word&0x200000)
379 printf(", #%s%u", word&0x800000 ? "" : "-", loff);
380 putchar(']');
381 if (word & 0x200000)
382 putchar('!');
383 if (loff >= 10)
384 printf("\t; 0x%x", loff);
385 break;
386 }
387 putchar('\n');
291 } 388 }
292 389
293 static void 390 static void
294 dataproc_74_overlay(off, word) 391 dataproc_74_overlay(off, word)
295 unsigned off, word; 392 unsigned off, word;