From: Julian Seward Date: Sun, 15 Jun 2003 23:26:04 +0000 (+0000) Subject: Add some more SSE/SSE2 floating point instructions. X-Git-Tag: svn/VALGRIND_2_0_0~83 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=31afdd2051ab0d181f5d455a95aa14d2efa8dfee;p=thirdparty%2Fvalgrind.git Add some more SSE/SSE2 floating point instructions. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1701 --- diff --git a/addrcheck/ac_main.c b/addrcheck/ac_main.c index c65b98cab9..fc70ce9361 100644 --- a/addrcheck/ac_main.c +++ b/addrcheck/ac_main.c @@ -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: diff --git a/coregrind/vg_to_ucode.c b/coregrind/vg_to_ucode.c index 067d347c07..643ce1dbbb 100644 --- a/coregrind/vg_to_ucode.c +++ b/coregrind/vg_to_ucode.c @@ -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