changeset 90:f68d8e7a904f

armdis: implemented decoding of multiplication instructions
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sat, 29 Mar 2014 22:19:21 +0000
parents c5d52666d2eb
children daf69d5edb3f
files arm7dis/armdis.c
diffstat 1 files changed, 49 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/arm7dis/armdis.c	Sat Mar 29 21:36:22 2014 +0000
+++ b/arm7dis/armdis.c	Sat Mar 29 22:19:21 2014 +0000
@@ -99,15 +99,8 @@
 }
 
 static void
-dataproc_74_overlay(off, word)
-	unsigned off, word;
-{
-	printf("<dataproc overlay with 7&4 set>\n");
-}
-
-static void
-dataproc_tstcmp_overlay(off, word)
-	unsigned off, word;
+dataproc_tstcmp_overlay(word)
+	unsigned word;
 {
 	char msrmask[5], *cp;
 
@@ -146,8 +139,8 @@
 }
 
 static void
-dataproc(off, word)
-	unsigned off, word;
+dataproc(word)
+	unsigned word;
 {
 	unsigned opc;
 
@@ -185,11 +178,53 @@
 				regnames[(word>>16)&0xF]);
 			dataproc_op2(word);
 		} else
-			dataproc_tstcmp_overlay(off, word);
+			dataproc_tstcmp_overlay(word);
 		return;
 	}
 }
 
+static void
+multiply(word)
+	unsigned word;
+{
+	if ((word & 0x0FE000F0) == 0x90)
+		printf("mul%s%s\t%s, %s, %s\n", condition_decode[word>>28],
+			word&0x100000 ? "s" : "", regnames[(word>>16)&0xF],
+			regnames[word&0xF], regnames[(word>>8)&0xF]);
+	else if ((word & 0x0FE000F0) == 0x00200090)
+		printf("mla%s%s\t%s, %s, %s, %s\n", condition_decode[word>>28],
+			word&0x100000 ? "s" : "", regnames[(word>>16)&0xF],
+			regnames[word&0xF], regnames[(word>>8)&0xF],
+			regnames[(word>>12)&0xF]);
+	else if ((word & 0x0F8000F0) == 0x00800090)
+		printf("%c%sl%s%s\t%s, %s, %s, %s\n",
+			word&0x400000 ? 's' : 'u',
+			word&0x200000 ? "mla" : "mul",
+			condition_decode[word>>28],
+			word&0x100000 ? "s" : "",
+			regnames[(word>>12)&0xF], regnames[(word>>16)&0xF],
+			regnames[word&0xF], regnames[(word>>8)&0xF]);
+	else
+		printf("<invalid multiply>\n");
+}
+
+static void
+ldr_str_ext(off, word)
+	unsigned off, word;
+{
+	printf("<extended ldr/str>\n");
+}
+
+static void
+dataproc_74_overlay(off, word)
+	unsigned off, word;
+{
+	if (word & 0x60)
+		ldr_str_ext(off, word);
+	else
+		multiply(word);
+}
+
 void
 arm_disasm_line(off)
 	unsigned off;
@@ -208,11 +243,11 @@
 		if ((word & 0x90) == 0x90)
 			dataproc_74_overlay(off, word);
 		else
-			dataproc(off, word);
+			dataproc(word);
 		return;
 	case 2:
 	case 3:
-		dataproc(off, word);
+		dataproc(word);
 		return;
 	case 4:
 	case 5: