From: Julian Seward Date: Fri, 13 Jun 2003 00:26:02 +0000 (+0000) Subject: Tonight's installment of SSE madness. Add a couple more nasties X-Git-Tag: svn/VALGRIND_2_0_0~101 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dfaded70ea93cf6ec0f0d850d52f0324f7409e61;p=thirdparty%2Fvalgrind.git Tonight's installment of SSE madness. Add a couple more nasties (pextrw/pinsrw). git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1683 --- diff --git a/coregrind/vg_from_ucode.c b/coregrind/vg_from_ucode.c index 0b90f11146..4be45a74d4 100644 --- a/coregrind/vg_from_ucode.c +++ b/coregrind/vg_from_ucode.c @@ -1486,6 +1486,60 @@ static void emit_SSE3g ( FlagSet uses_sflags, ); } +static void emit_SSE3g1_RegWr ( FlagSet uses_sflags, + FlagSet sets_sflags, + UChar first_byte, + UChar second_byte, + UChar third_byte, + UChar fourth_byte, + UChar fifth_byte, + Int ireg ) +{ + VG_(new_emit)(True, uses_sflags, sets_sflags); + VG_(emitB) ( first_byte ); + VG_(emitB) ( second_byte ); + VG_(emitB) ( third_byte ); + fourth_byte &= 0xC7; /* mask out reg field */ + fourth_byte |= 0xC0; /* set top two bits: mod = 11b */ + fourth_byte |= ((ireg & 7) << 3); /* patch in our ireg */ + VG_(emitB) ( fourth_byte ); + VG_(emitB) ( fifth_byte ); + if (dis) + VG_(printf)( + "\n\t\tssereg-to-ireg--0x%x:0x%x:0x%x:0x%x:0x%x-(%s)\n", + (UInt)first_byte, (UInt)second_byte, + (UInt)third_byte, (UInt)fourth_byte, (UInt)fifth_byte, + nameIReg(4,ireg) + ); +} + +static void emit_SSE3g1_RegRd ( FlagSet uses_sflags, + FlagSet sets_sflags, + UChar first_byte, + UChar second_byte, + UChar third_byte, + UChar fourth_byte, + UChar fifth_byte, + Int ireg ) +{ + VG_(new_emit)(True, uses_sflags, sets_sflags); + VG_(emitB) ( first_byte ); + VG_(emitB) ( second_byte ); + VG_(emitB) ( third_byte ); + fourth_byte &= 0xF8; /* mask out reg field */ + fourth_byte |= 0xC0; /* set top two bits: mod = 11b */ + fourth_byte |= (ireg & 7); /* patch in our ireg */ + VG_(emitB) ( fourth_byte ); + VG_(emitB) ( fifth_byte ); + if (dis) + VG_(printf)( + "\n\t\tireg-to-ssereg--0x%x:0x%x:0x%x:0x%x:0x%x-(%s)\n", + (UInt)first_byte, (UInt)second_byte, + (UInt)third_byte, (UInt)fourth_byte, (UInt)fifth_byte, + nameIReg(4,ireg) + ); +} + static void emit_SSE4 ( FlagSet uses_sflags, FlagSet sets_sflags, UChar first_byte, @@ -3750,6 +3804,44 @@ static void emitUInstr ( UCodeBlock* cb, Int i, u->opcode==SSE3g_RegRd ? True : False ); break; + case SSE3g1_RegWr: + vg_assert(u->size == 4); + vg_assert(u->tag1 == Lit16); + vg_assert(u->tag2 == Lit16); + vg_assert(u->tag3 == RealReg); + vg_assert(!anyFlagUse(u)); + if (!(*sselive)) { + emit_get_sse_state(); + *sselive = True; + } + emit_SSE3g1_RegWr ( u->flags_r, u->flags_w, + (u->val1 >> 8) & 0xFF, + u->val1 & 0xFF, + (u->val2 >> 8) & 0xFF, + u->val2 & 0xFF, + u->lit32 & 0xFF, + u->val3 ); + break; + + case SSE3g1_RegRd: + vg_assert(u->size == 2); + vg_assert(u->tag1 == Lit16); + vg_assert(u->tag2 == Lit16); + vg_assert(u->tag3 == RealReg); + vg_assert(!anyFlagUse(u)); + if (!(*sselive)) { + emit_get_sse_state(); + *sselive = True; + } + emit_SSE3g1_RegRd ( u->flags_r, u->flags_w, + (u->val1 >> 8) & 0xFF, + u->val1 & 0xFF, + (u->val2 >> 8) & 0xFF, + u->val2 & 0xFF, + u->lit32 & 0xFF, + u->val3 ); + break; + case SSE4: vg_assert(u->size == 0); vg_assert(u->tag1 == Lit16); diff --git a/coregrind/vg_to_ucode.c b/coregrind/vg_to_ucode.c index 31dc89be8b..3f6e2defce 100644 --- a/coregrind/vg_to_ucode.c +++ b/coregrind/vg_to_ucode.c @@ -3754,6 +3754,16 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd ) goto decode_success; } +#if 0 + /* SUBSD */ + if (insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0x5C) { + vg_assert(sz == 4); + eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+3, 8, "subsd", + insn[0], insn[1], insn[2] ); + goto decode_success; + } +#endif + /* ADDSD */ if (insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0x58) { vg_assert(sz == 4); @@ -3880,6 +3890,49 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd ) goto decode_success; } + /* PEXTRW from SSE register; writes ireg */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xC5) { + t1 = newTemp(cb); + modrm = insn[2]; + vg_assert(epartIsReg(modrm)); + vg_assert((modrm & 0xC0) == 0xC0); + uInstr3(cb, SSE3g1_RegWr, 4, + Lit16, (((UShort)0x66) << 8) | (UShort)insn[0], + Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, + TempReg, t1 ); + uLiteral(cb, insn[3]); + uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, gregOfRM(modrm)); + if (dis) + VG_(printf)("pextrw %s, %d, %s\n", + nameXMMReg(eregOfRM(modrm)), (Int)insn[3], + nameIReg(4, gregOfRM(modrm))); + eip += 4; + goto decode_success; + } + + /* PINSRW to SSE register; reads mem or ireg */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xC4) { + t1 = newTemp(cb); + modrm = insn[2]; + if (epartIsReg(modrm)) { + uInstr2(cb, GET, 2, ArchReg, eregOfRM(modrm), TempReg, t1); + uInstr3(cb, SSE3g1_RegRd, 2, + Lit16, (((UShort)0x66) << 8) | (UShort)insn[0], + Lit16, (((UShort)insn[1]) << 8) | (UShort)modrm, + TempReg, t1 ); + uLiteral(cb, insn[3]); + if (dis) + VG_(printf)("pinsrw %s, %d, %s\n", + nameIReg(2, eregOfRM(modrm)), + (Int)insn[3], + nameXMMReg(gregOfRM(modrm))); + eip += 4; + } else { + VG_(core_panic)("PINSRW mem"); + } + goto decode_success; + } + /* Fall through into the non-SSE decoder. */ } /* if (VG_(have_ssestate)) */ diff --git a/coregrind/vg_translate.c b/coregrind/vg_translate.c index b2e30ced24..0ac4d8dd98 100644 --- a/coregrind/vg_translate.c +++ b/coregrind/vg_translate.c @@ -402,6 +402,7 @@ Int VG_(realreg_to_rank) ( Int realReg ) Bool VG_(saneUInstr) ( Bool beforeRA, Bool beforeLiveness, UInstr* u ) { # define LIT0 (u->lit32 == 0) +# define LIT8 (((u->lit32) & 0xFFFFFF00) == 0) # define LIT1 (!(LIT0)) # define LITm (u->tag1 == Literal ? True : LIT0 ) # define SZ8 (u->size == 8) @@ -564,6 +565,8 @@ Bool VG_(saneUInstr) ( Bool beforeRA, Bool beforeLiveness, UInstr* u ) case SSE3a_MemRd: return LIT0 && SZsse && CCf && Ls1 && Ls2 && TR3 && XOTHER; case SSE3g_RegRd: return LIT0 && SZ4 && CC0 && Ls1 && Ls2 && TR3 && XOTHER; case SSE3g_RegWr: return LIT0 && SZ4 && CC0 && Ls1 && Ls2 && TR3 && XOTHER; + case SSE3g1_RegWr: return LIT8 && SZ4 && CC0 && Ls1 && Ls2 && TR3 && XOTHER; + case SSE3g1_RegRd: return LIT8 && SZ2 && CC0 && Ls1 && Ls2 && TR3 && XOTHER; case SSE3: return LIT0 && SZ0 && CC0 && Ls1 && Ls2 && N3 && XOTHER; case SSE4: return LIT0 && SZ0 && CC0 && Ls1 && Ls2 && N3 && XOTHER; default: @@ -578,6 +581,7 @@ Bool VG_(saneUInstr) ( Bool beforeRA, Bool beforeLiveness, UInstr* u ) } # undef LIT0 # undef LIT1 +# undef LIT8 # undef LITm # undef SZ8 # undef SZ4 @@ -881,6 +885,8 @@ Char* VG_(name_UOpcode) ( Bool upper, Opcode opc ) case SSE2a_MemRd: return "SSE2a_MRd"; case SSE3g_RegRd: return "SSE3g_RRd"; case SSE3g_RegWr: return "SSE3g_RWr"; + case SSE3g1_RegWr: return "SSE3g1_RWr"; + case SSE3g1_RegRd: return "SSE3g1_RRd"; case SSE3: return "SSE3"; case SSE4: return "SSE4"; case SSE3a_MemWr: return "SSE3a_MWr"; @@ -1058,6 +1064,15 @@ void pp_UInstrWorker ( Int instrNo, UInstr* u, Bool ppRegsLiveness ) VG_(pp_UOperand)(u, 3, 4, True); break; + case SSE3g1_RegWr: + case SSE3g1_RegRd: + VG_(printf)("0x%x:0x%x:0x%x:0x%x:0x%x", + (u->val1 >> 8) & 0xFF, u->val1 & 0xFF, + (u->val2 >> 8) & 0xFF, u->val2 & 0xFF, + u->lit32 ); + VG_(pp_UOperand)(u, 3, 4, True); + break; + case SSE3: VG_(printf)("0x%x:0x%x:0x%x", (u->val1 >> 8) & 0xFF, u->val1 & 0xFF, @@ -1219,8 +1234,10 @@ Int VG_(get_reg_usage) ( UInstr* u, Tag tag, Int* regs, Bool* isWrites ) case SSE3a_MemWr: case SSE3a_MemRd: case SSE2a_MemWr: + case SSE3g1_RegRd: case SSE2a_MemRd: RD(3); break; + case SSE3g1_RegWr: case SSE3g_RegWr: WR(3); break; case MMX2_RegRd: RD(2); break; @@ -1380,7 +1397,8 @@ Int maybe_uinstrReadsArchReg ( UInstr* u ) case MMX2_RegRd: case MMX2_RegWr: case SSE2a_MemWr: case SSE2a_MemRd: case SSE3a_MemWr: case SSE3a_MemRd: - case SSE3g_RegRd: case SSE3g_RegWr: + case SSE3g_RegRd: case SSE3g_RegWr: + case SSE3g1_RegWr: case SSE3g1_RegRd: case SSE4: case SSE3: case WIDEN: /* GETSEG and USESEG are to do with ArchRegS, not ArchReg */ @@ -2249,7 +2267,7 @@ void VG_(translate) ( /*IN*/ ThreadState* tst, UChar* final_code; UCodeBlock* cb; Bool notrace_until_done; - Int notrace_until_limit = 15000; + Int notrace_until_limit = 23500; VGP_PUSHCC(VgpTranslate); debugging_translation diff --git a/include/vg_skin.h b/include/vg_skin.h index fc4c1909fa..73b5fb8880 100644 --- a/include/vg_skin.h +++ b/include/vg_skin.h @@ -635,6 +635,24 @@ typedef */ SSE3g_RegWr, + /* 5 bytes, writes an integer register. Insns of the form + bbbbbbbb:bbbbbbbb:bbbbbbbb: 11 ireg bbb :bbbbbbbb. Held in + val1[15:0] and val2[15:0] and lit32[7:0], and ireg is to be + replaced at codegen time by a reference to the relevant + RealReg. Transfer is always at size 4. Arg3 holds this + Temp/Real Reg. + */ + SSE3g1_RegWr, + + /* 5 bytes, reads an integer register. Insns of the form + bbbbbbbb:bbbbbbbb:bbbbbbbb: 11 bbb ireg :bbbbbbbb. Held in + val1[15:0] and val2[15:0] and lit32[7:0], and ireg is to be + replaced at codegen time by a reference to the relevant + RealReg. Transfer is always at size 4. Arg3 holds this + Temp/Real Reg. + */ + SSE3g1_RegRd, + /* 4 bytes, reads an integer register. Insns of the form bbbbbbbb:bbbbbbbb:bbbbbbbb:11 xmmreg ireg. Held in val1[15:0] and val2[15:0], and ireg is to be replaced