]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add some more SSE/SSE2 floating point instructions.
authorJulian Seward <jseward@acm.org>
Sun, 15 Jun 2003 23:26:04 +0000 (23:26 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 15 Jun 2003 23:26:04 +0000 (23:26 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1701

addrcheck/ac_main.c
coregrind/vg_to_ucode.c

index c65b98cab9f84781d00e4be58c632ecc40b5eeb2..fc70ce9361a5f4201e9f001ebb6da1ec0b579c13 100644 (file)
@@ -1013,13 +1013,13 @@ UCodeBlock* SK_(instrument)(UCodeBlock* cb_in, Addr orig_addr)
 
            //         case SSE2a1_MemRd:
            //         case SSE2a1_MemWr:
-         case SSE3e1_RegRd:
           //         case SSE3a1_MemRd:
           //         case SSE3a1_MemWr:
            VG_(pp_UInstr)(0,u_in);
            VG_(skin_panic)("AddrCheck: unhandled SSE uinstr");
            break;
 
+         case SSE3e1_RegRd:
          case SSE3e_RegWr:
          case SSE3g1_RegWr:
          case SSE5:
index 067d347c07c0f023d19722bda195e9e2f8961458..643ce1dbbb797d5cd9a6ed1f5eb31f81cca1c095 100644 (file)
@@ -3659,14 +3659,18 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
       goto decode_success;
    }
 
-   /* CVTTSD2SI (0xF2,0x0F,0x2C) -- convert a double-precision float value in
-      memory or xmm reg to int and put it in an ireg.  Truncate. */
-   /* CVTTSS2SI (0xF3,0x0F,0x2C) -- convert a single-precision float value in
-      memory or xmm reg to int and put it in an ireg.  Truncate. */
-   /* CVTSD2SI (0xF2,0x0F,0x2D) -- convert a double-precision float value in
-      memory or xmm reg to int and put it in an ireg.  Round as per MXCSR. */
-   /* CVTSS2SI (0xF3,0x0F,0x2D) -- convert a single-precision float value in
-      memory or xmm reg to int and put it in an ireg.  Round as per MXCSR. */
+   /* CVTTSD2SI (0xF2,0x0F,0x2C) -- convert a double-precision float
+      value in memory or xmm reg to int and put it in an ireg.
+      Truncate. */
+   /* CVTTSS2SI (0xF3,0x0F,0x2C) -- convert a single-precision float
+      value in memory or xmm reg to int and put it in an ireg.
+      Truncate. */
+   /* CVTSD2SI (0xF2,0x0F,0x2D) -- convert a double-precision float
+      value in memory or xmm reg to int and put it in an ireg.  Round
+      as per MXCSR. */
+   /* CVTSS2SI (0xF3,0x0F,0x2D) -- convert a single-precision float
+      value in memory or xmm reg to int and put it in an ireg.  Round
+      as per MXCSR. */
    if ((insn[0] == 0xF2 || insn[0] == 0xF3)
        && insn[1] == 0x0F 
        && (insn[2] == 0x2C || insn[2] == 0x2D)) {
@@ -3804,10 +3808,27 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
    }
 
    /* MULPS */
+   /* 0x66: MULPD */
    if (insn[0] == 0x0F && insn[1] == 0x59) {
-      vg_assert(sz == 4);
-      eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, "mulps",
-                                      insn[0], insn[1] );
+      vg_assert(sz == 4 || sz == 2);
+      if (sz == 4) {
+         eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, "mulps",
+                                         insn[0], insn[1] );
+      } else {
+         eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "mulpd",
+                                         0x66, insn[0], insn[1] );
+      }
+      goto decode_success;
+   }
+
+   /* 0x66: SUBPD */
+   if (sz == 2
+       && insn[0] == 0x0F && insn[1] == 0x5C) {
+      vg_assert(sz == 2);
+      {
+         eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "subpd",
+                                         0x66, insn[0], insn[1] );
+      }
       goto decode_success;
    }
 
@@ -3844,10 +3865,16 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
    }
 
    /* ADDPS */
+   /* 0x66: ADDPD */
    if (insn[0] == 0x0F && insn[1] == 0x58) {
-      vg_assert(sz == 4);
-      eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, "addps",
-                                      insn[0], insn[1] );
+      vg_assert(sz == 4 || sz == 2);
+      if (sz == 4) {
+         eip = dis_SSE2_reg_or_mem ( cb, sorb, eip+2, 16, "addps",
+                                         insn[0], insn[1] );
+      } else {
+         eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "addpd",
+                                         0x66, insn[0], insn[1] );
+      }
       goto decode_success;
    }
 
@@ -3859,6 +3886,22 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
       goto decode_success;
    }
 
+   /* ANDPD (src)xmmreg-or-mem, (dst)xmmreg */
+   if (sz == 2
+       && insn[0] == 0x0F && insn[1] == 0x54) {
+      eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "andpd",
+                                      0x66, insn[0], insn[1] );
+      goto decode_success;
+   }
+
+   /* ORPD (src)xmmreg-or-mem, (dst)xmmreg */
+   if (sz == 2
+       && insn[0] == 0x0F && insn[1] == 0x56) {
+      eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "orpd",
+                                      0x66, insn[0], insn[1] );
+      goto decode_success;
+   }
+
    /* PXOR (src)xmmreg-or-mem, (dst)xmmreg */
    if (sz == 2
        && insn[0] == 0x0F && insn[1] == 0xEF) {
@@ -3945,6 +3988,17 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
       goto decode_success;
    }
 
+   /* 0x14: UNPCKLPD (src)xmmreg-or-mem, (dst)xmmreg */
+   /* 0x15: UNPCKHPD (src)xmmreg-or-mem, (dst)xmmreg */
+   if (sz == 2
+       && insn[0] == 0x0F 
+       && (insn[1] == 0x14 || insn[1] == 0x15)) {
+      eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, 
+                                      "unpck{l,h}pd",
+                                      0x66, insn[0], insn[1] );
+      goto decode_success;
+   }
+
    /* 0xFC: PADDB (src)xmmreg-or-mem, (dst)xmmreg */
    /* 0xFD: PADDW (src)xmmreg-or-mem, (dst)xmmreg */
    /* 0xFE: PADDD (src)xmmreg-or-mem, (dst)xmmreg */
@@ -4191,6 +4245,19 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
       goto decode_success;
    }
 
+   /* MOVLPD -- 8-byte load/store. */
+   if (sz == 2 
+       && insn[0] == 0x0F 
+       && (insn[1] == 0x12 || insn[1] == 0x13)) {
+      Bool is_store = insn[1]==0x13;
+      /* Cannot be used for reg-reg moves, according to Intel docs. */
+      vg_assert(!epartIsReg(insn[2]));
+      eip = dis_SSE3_load_store_or_mov
+               (cb, sorb, eip+2, 16, is_store, "movlpd", 
+                    0x66, insn[0], insn[1] );
+      goto decode_success;
+   }
+
    /* MOVDQU -- unaligned 16-byte load/store. */
    if (insn[0] == 0xF3
        && insn[1] == 0x0F