]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Implement AMD 3DNOW disassembly.
authorUlrich Drepper <drepper@redhat.com>
Fri, 19 Dec 2008 09:14:12 +0000 (01:14 -0800)
committerUlrich Drepper <drepper@redhat.com>
Fri, 19 Dec 2008 09:14:12 +0000 (01:14 -0800)
libcpu/ChangeLog
libcpu/defs/i386
libcpu/i386_disasm.c
tests/ChangeLog
tests/testfile44.S.bz2
tests/testfile44.expect.bz2
tests/testfile45.S.bz2
tests/testfile45.expect.bz2

index c634865925556253ed1011d47606282bb90ce52e..db2a3f025e258ec0ea3c9914e3cf2f7ece11327b 100644 (file)
@@ -1,3 +1,8 @@
+2008-12-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * defs/i386: Add entry for AMD 3DNOW.
+       * i386_disasm.c: Implement AMD 3DNOW disassembly.
+
 2008-12-17  Ulrich Drepper  <drepper@redhat.com>
 
        * i386_disasm.c (i386_disasm): If instruction matches prefix,
index 4abbc261bb2a347144669a514d8b69865658d1e7..3ae25ccb719856af3e5852f9299215313398e23a 100644 (file)
@@ -911,6 +911,7 @@ ifdef(`i386',
 00001111,10101110,11110000:mfence
 00001111,10101110,11111000:sfence
 00001111,10101110,{mod}111{r_m}:clflush {mod}{r_m}
+00001111,00001111,{MOD}{mmxreg}{R_M}:INVALID {MOD}{R_M},{mmxreg}
 # ORDER:
 dnl Many previous entries depend on this being last.
 000{sreg2}111:pop {sreg2}
index b676216a8eaa2504eea160f7581a0ab020457b5e..5da61705b84f5cfebc4b29cc97e11411759c1f40 100644 (file)
@@ -184,6 +184,73 @@ static const char *prefix_str[] =
 #endif
 
 
+static const char amd3dnowstr[] =
+#define MNE_3DNOW_PAVGUSB 1
+  "pavgusb\0"
+#define MNE_3DNOW_PFADD (MNE_3DNOW_PAVGUSB + 8)
+  "pfadd\0"
+#define MNE_3DNOW_PFSUB (MNE_3DNOW_PFADD + 6)
+  "pfsub\0"
+#define MNE_3DNOW_PFSUBR (MNE_3DNOW_PFSUB + 6)
+  "pfsubr\0"
+#define MNE_3DNOW_PFACC (MNE_3DNOW_PFSUBR + 7)
+  "pfacc\0"
+#define MNE_3DNOW_PFCMPGE (MNE_3DNOW_PFACC + 6)
+  "pfcmpge\0"
+#define MNE_3DNOW_PFCMPGT (MNE_3DNOW_PFCMPGE + 8)
+  "pfcmpgt\0"
+#define MNE_3DNOW_PFCMPEQ (MNE_3DNOW_PFCMPGT + 8)
+  "pfcmpeq\0"
+#define MNE_3DNOW_PFMIN (MNE_3DNOW_PFCMPEQ + 8)
+  "pfmin\0"
+#define MNE_3DNOW_PFMAX (MNE_3DNOW_PFMIN + 6)
+  "pfmax\0"
+#define MNE_3DNOW_PI2FD (MNE_3DNOW_PFMAX + 6)
+  "pi2fd\0"
+#define MNE_3DNOW_PF2ID (MNE_3DNOW_PI2FD + 6)
+  "pf2id\0"
+#define MNE_3DNOW_PFRCP (MNE_3DNOW_PF2ID + 6)
+  "pfrcp\0"
+#define MNE_3DNOW_PFRSQRT (MNE_3DNOW_PFRCP + 6)
+  "pfrsqrt\0"
+#define MNE_3DNOW_PFMUL (MNE_3DNOW_PFRSQRT + 8)
+  "pfmul\0"
+#define MNE_3DNOW_PFRCPIT1 (MNE_3DNOW_PFMUL + 6)
+  "pfrcpit1\0"
+#define MNE_3DNOW_PFRSQIT1 (MNE_3DNOW_PFRCPIT1 + 9)
+  "pfrsqit1\0"
+#define MNE_3DNOW_PFRCPIT2 (MNE_3DNOW_PFRSQIT1 + 9)
+  "pfrcpit2\0"
+#define MNE_3DNOW_PMULHRW (MNE_3DNOW_PFRCPIT2 + 9)
+  "pmulhrw";
+
+#define AMD3DNOW_LOW_IDX 0x0d
+#define AMD3DNOW_HIGH_IDX (sizeof (amd3dnow) + AMD3DNOW_LOW_IDX - 1)
+#define AMD3DNOW_IDX(val) ((val) - AMD3DNOW_LOW_IDX)
+static unsigned char amd3dnow[] =
+  {
+    [AMD3DNOW_IDX (0xbf)] = MNE_3DNOW_PAVGUSB,
+    [AMD3DNOW_IDX (0x9e)] = MNE_3DNOW_PFADD,
+    [AMD3DNOW_IDX (0x9a)] = MNE_3DNOW_PFSUB,
+    [AMD3DNOW_IDX (0xaa)] = MNE_3DNOW_PFSUBR,
+    [AMD3DNOW_IDX (0xae)] = MNE_3DNOW_PFACC,
+    [AMD3DNOW_IDX (0x90)] = MNE_3DNOW_PFCMPGE,
+    [AMD3DNOW_IDX (0xa0)] = MNE_3DNOW_PFCMPGT,
+    [AMD3DNOW_IDX (0xb0)] = MNE_3DNOW_PFCMPEQ,
+    [AMD3DNOW_IDX (0x94)] = MNE_3DNOW_PFMIN,
+    [AMD3DNOW_IDX (0xa4)] = MNE_3DNOW_PFMAX,
+    [AMD3DNOW_IDX (0x0d)] = MNE_3DNOW_PI2FD,
+    [AMD3DNOW_IDX (0x1d)] = MNE_3DNOW_PF2ID,
+    [AMD3DNOW_IDX (0x96)] = MNE_3DNOW_PFRCP,
+    [AMD3DNOW_IDX (0x97)] = MNE_3DNOW_PFRSQRT,
+    [AMD3DNOW_IDX (0xb4)] = MNE_3DNOW_PFMUL,
+    [AMD3DNOW_IDX (0xa6)] = MNE_3DNOW_PFRCPIT1,
+    [AMD3DNOW_IDX (0xa7)] = MNE_3DNOW_PFRSQIT1,
+    [AMD3DNOW_IDX (0xb6)] = MNE_3DNOW_PFRCPIT2,
+    [AMD3DNOW_IDX (0xb7)] = MNE_3DNOW_PMULHRW
+  };
+
+
 struct output_data
 {
   GElf_Addr addr;
@@ -623,6 +690,24 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
                          break;
 
                        case 0x0f:
+                         if (data[1] == 0x0f)
+                           {
+                             /* AMD 3DNOW.  We need one more byte.  */
+                             if (param_start >= end)
+                               goto not;
+                             if (*param_start < AMD3DNOW_LOW_IDX
+                                 || *param_start > AMD3DNOW_HIGH_IDX)
+                               goto not;
+                             unsigned int idx
+                               = amd3dnow[AMD3DNOW_IDX (*param_start)];
+                             if (idx == 0)
+                               goto not;
+                             str = amd3dnowstr + idx - 1;
+                             /* Eat the immediate byte indicating the
+                                operation.  */
+                             ++param_start;
+                             break;
+                           }
 #ifdef X86_64
                          if (data[1] == 0xc7)
                            {
index b1471c1b08a0fd9b9b38c038830db6704d1f757d..28667d67383d9b50ee55bf7f0b25e3fb3655bdc2 100644 (file)
@@ -1,3 +1,10 @@
+2008-12-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * testfile44.S.bz2: Add tests for AMD 3DNOW.
+       * testfile45.S.bz2: Likewise.
+       * testfile44.expect.bz2: Adjust accordingly.
+       * testfile45.expect.bz2: Likewise.
+
 2008-11-26  Roland McGrath  <roland@redhat.com>
 
        * dwfl-bug-getmodules.c: New file.
index cbd0da3d1faff52981768aa147f96574d16bb601..64bddea391a2b2473693519b557809a22ae3909a 100644 (file)
Binary files a/tests/testfile44.S.bz2 and b/tests/testfile44.S.bz2 differ
index 2347aea1cf09e6a5cb9278ad0861883723f3f1d7..5987731519e2b20da2961b1d0e13938d04f21082 100644 (file)
Binary files a/tests/testfile44.expect.bz2 and b/tests/testfile44.expect.bz2 differ
index 91b47955993aa159e6fcd754fc4e34115e61871f..95bcf8649207d22a920d94a71ef82e0e4e0b65bc 100644 (file)
Binary files a/tests/testfile45.S.bz2 and b/tests/testfile45.S.bz2 differ
index 06b4d9bd251c31bc3b8f58136a65bb63d4341b18..dcd7b9a9fa19173917d462904346ca3120664777 100644 (file)
Binary files a/tests/testfile45.expect.bz2 and b/tests/testfile45.expect.bz2 differ