From: Julian Seward Date: Fri, 10 Dec 2004 01:48:18 +0000 (+0000) Subject: Finish almost all SSE2 integer instructions. (!) X-Git-Tag: svn/VALGRIND_3_0_1^2~694 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cca70dff127f90975dbc3fe7981d7d4601b44e30;p=thirdparty%2Fvalgrind.git Finish almost all SSE2 integer instructions. (!) git-svn-id: svn://svn.valgrind.org/vex/trunk@640 --- diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index be26775793..7a337517ba 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -9783,6 +9783,76 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, goto decode_success; } + /* 66 0F 68 = PUNPCKHBW */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x68) { + delta = dis_SSEint_E_to_G( sorb, delta+2, + "punpckhbw", + Iop_InterleaveHI8x16, True ); + goto decode_success; + } + + /* 66 0F 6A = PUNPCKHDQ */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6A) { + delta = dis_SSEint_E_to_G( sorb, delta+2, + "punpckhdq", + Iop_InterleaveHI32x4, True ); + goto decode_success; + } + + /* 66 0F 6D = PUNPCKHQDQ */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6D) { + delta = dis_SSEint_E_to_G( sorb, delta+2, + "punpckhqdq", + Iop_InterleaveHI64x2, True ); + goto decode_success; + } + + /* 66 0F 69 = PUNPCKHWD */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x69) { + delta = dis_SSEint_E_to_G( sorb, delta+2, + "punpckhwd", + Iop_InterleaveHI16x8, True ); + goto decode_success; + } + + /* 66 0F 60 = PUNPCKLBW */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x60) { + delta = dis_SSEint_E_to_G( sorb, delta+2, + "punpcklbw", + Iop_InterleaveLO8x16, True ); + goto decode_success; + } + + /* 66 0F 62 = PUNPCKLDQ */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x62) { + delta = dis_SSEint_E_to_G( sorb, delta+2, + "punpckldq", + Iop_InterleaveLO32x4, True ); + goto decode_success; + } + + /* 66 0F 6C = PUNPCKLQDQ */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6C) { + delta = dis_SSEint_E_to_G( sorb, delta+2, + "punpcklqdq", + Iop_InterleaveLO64x2, True ); + goto decode_success; + } + + /* 66 0F 61 = PUNPCKLWD */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x61) { + delta = dis_SSEint_E_to_G( sorb, delta+2, + "punpcklwd", + Iop_InterleaveLO16x8, True ); + goto decode_success; + } + + /* 66 0F EF = PXOR */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xEF) { + delta = dis_SSE_E_to_G_all( sorb, delta+2, "pxor", Iop_Xor128 ); + goto decode_success; + } + //-- //-- /* FXSAVE/FXRSTOR m32 -- load/store the FPU/MMX/SSE state. */ diff --git a/VEX/priv/host-x86/hdefs.c b/VEX/priv/host-x86/hdefs.c index 00de9e1262..d61f216471 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -560,12 +560,14 @@ HChar* showX86SseOp ( X86SseOp op ) { case Xsse_PACKSSD: return "packssdw"; case Xsse_PACKSSW: return "packsswb"; case Xsse_PACKUSW: return "packuswb"; - case Xsse_PUNPCKHB: return "punpckhb"; - case Xsse_PUNPCKHW: return "punpckhw"; - case Xsse_PUNPCKHD: return "punpckhd"; - case Xsse_PUNPCKLB: return "punpcklb"; - case Xsse_PUNPCKLW: return "punpcklw"; - case Xsse_PUNPCKLD: return "punpckld"; + case Xsse_UNPCKHB: return "punpckhb"; + case Xsse_UNPCKHW: return "punpckhw"; + case Xsse_UNPCKHD: return "punpckhd"; + case Xsse_UNPCKHQ: return "punpckhq"; + case Xsse_UNPCKLB: return "punpcklb"; + case Xsse_UNPCKLW: return "punpcklw"; + case Xsse_UNPCKLD: return "punpckld"; + case Xsse_UNPCKLQ: return "punpcklq"; default: vpanic("showX86SseOp"); } } @@ -803,16 +805,6 @@ X86Instr* X86Instr_SseLdzLO ( Int sz, HReg reg, X86AMode* addr ) vassert(sz == 4 || sz == 8); return i; } -X86Instr* X86Instr_Sse128 ( X86SseOp op, HReg src, HReg dst ) { - X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); - i->tag = Xin_Sse128; - i->Xin.Sse128.op = op; - i->Xin.Sse128.src = src; - i->Xin.Sse128.dst = dst; - vassert(op == Xsse_MOV - || op == Xsse_AND || op == Xsse_OR || op == Xsse_XOR); - return i; -} X86Instr* X86Instr_Sse32Fx4 ( X86SseOp op, HReg src, HReg dst ) { X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); i->tag = Xin_Sse32Fx4; @@ -855,7 +847,6 @@ X86Instr* X86Instr_SseReRg ( X86SseOp op, HReg re, HReg rg ) { i->Xin.SseReRg.op = op; i->Xin.SseReRg.src = re; i->Xin.SseReRg.dst = rg; - vassert(op != Xsse_MOV); return i; } X86Instr* X86Instr_SseCMov ( X86CondCode cond, HReg src, HReg dst ) { @@ -1071,16 +1062,6 @@ void ppX86Instr ( X86Instr* i ) { vex_printf(","); ppHRegX86(i->Xin.SseLdzLO.reg); return; - case Xin_Sse128: - if (i->Xin.Sse128.op == Xsse_MOV) { - vex_printf("mov "); - } else { - vex_printf("p%s ", showX86SseOp(i->Xin.Sse128.op)); - } - ppHRegX86(i->Xin.Sse128.src); - vex_printf(","); - ppHRegX86(i->Xin.Sse128.dst); - return; case Xin_Sse32Fx4: vex_printf("%sps ", showX86SseOp(i->Xin.Sse32Fx4.op)); ppHRegX86(i->Xin.Sse32Fx4.src); @@ -1285,11 +1266,6 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i) case Xin_SseConst: addHRegUse(u, HRmWrite, i->Xin.SseConst.dst); return; - case Xin_Sse128: - addHRegUse(u, HRmRead, i->Xin.Sse128.src); - addHRegUse(u, i->Xin.Sse128.op==Xsse_MOV ? HRmWrite : HRmModify, - i->Xin.Sse128.dst); - return; case Xin_Sse32Fx4: vassert(i->Xin.Sse32Fx4.op != Xsse_MOV); unary = i->Xin.Sse32Fx4.op == Xsse_RCPF @@ -1327,9 +1303,9 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i) i->Xin.Sse64FLo.dst); return; case Xin_SseReRg: - vassert(i->Xin.SseReRg.op != Xsse_MOV); - addHRegUse(u, HRmRead, i->Xin.SseReRg.src); - addHRegUse(u, HRmModify, i->Xin.SseReRg.dst); + addHRegUse(u, HRmRead, i->Xin.SseReRg.src); + addHRegUse(u, i->Xin.SseReRg.op == Xsse_MOV ? HRmWrite : HRmModify, + i->Xin.SseReRg.dst); return; case Xin_SseCMov: addHRegUse(u, HRmRead, i->Xin.SseCMov.src); @@ -1451,10 +1427,6 @@ void mapRegs_X86Instr (HRegRemap* m, X86Instr* i) mapReg(m, &i->Xin.SseLdzLO.reg); mapRegs_X86AMode(m, i->Xin.SseLdzLO.addr); break; - case Xin_Sse128: - mapReg(m, &i->Xin.Sse128.src); - mapReg(m, &i->Xin.Sse128.dst); - return; case Xin_Sse32Fx4: mapReg(m, &i->Xin.Sse32Fx4.src); mapReg(m, &i->Xin.Sse32Fx4.dst); @@ -1509,11 +1481,11 @@ Bool isMove_X86Instr ( X86Instr* i, HReg* src, HReg* dst ) *dst = i->Xin.FpUnary.dst; return True; } - if (i->tag == Xin_Sse128) { - if (i->Xin.Sse128.op != Xsse_MOV) + if (i->tag == Xin_SseReRg) { + if (i->Xin.SseReRg.op != Xsse_MOV) return False; - *src = i->Xin.Sse128.src; - *dst = i->Xin.Sse128.dst; + *src = i->Xin.SseReRg.src; + *dst = i->Xin.SseReRg.dst; return True; } return False; @@ -2589,19 +2561,6 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) i->Xin.SseLdzLO.addr); goto done; - case Xin_Sse128: - *p++ = 0x0F; - switch (i->Xin.Sse128.op) { - case Xsse_OR: *p++ = 0x56; break; - case Xsse_XOR: *p++ = 0x57; break; - case Xsse_AND: *p++ = 0x54; break; - case Xsse_MOV: *p++ = 0x10; break; - default: goto bad; - } - p = doAMode_R(p, fake(vregNo(i->Xin.Sse128.dst)), - fake(vregNo(i->Xin.Sse128.src)) ); - goto done; - case Xin_Sse32Fx4: xtra = 0; *p++ = 0x0F; @@ -2704,6 +2663,10 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) case Xin_SseReRg: # define XX(_n) *p++ = (_n) switch (i->Xin.SseReRg.op) { + case Xsse_MOV: /*movups*/ XX(0x0F); XX(0x10); break; + case Xsse_OR: XX(0x0F); XX(0x56); break; + case Xsse_XOR: XX(0x0F); XX(0x57); break; + case Xsse_AND: XX(0x0F); XX(0x54); break; case Xsse_PACKSSD: XX(0x66); XX(0x0F); XX(0x6B); break; case Xsse_PACKSSW: XX(0x66); XX(0x0F); XX(0x63); break; case Xsse_PACKUSW: XX(0x66); XX(0x0F); XX(0x67); break; @@ -2746,6 +2709,14 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) case Xsse_QSUB16S: XX(0x66); XX(0x0F); XX(0xE9); break; case Xsse_QSUB8U: XX(0x66); XX(0x0F); XX(0xD8); break; case Xsse_QSUB16U: XX(0x66); XX(0x0F); XX(0xD9); break; + case Xsse_UNPCKHB: XX(0x66); XX(0x0F); XX(0x68); break; + case Xsse_UNPCKHW: XX(0x66); XX(0x0F); XX(0x69); break; + case Xsse_UNPCKHD: XX(0x66); XX(0x0F); XX(0x6A); break; + case Xsse_UNPCKHQ: XX(0x66); XX(0x0F); XX(0x6D); break; + case Xsse_UNPCKLB: XX(0x66); XX(0x0F); XX(0x60); break; + case Xsse_UNPCKLW: XX(0x66); XX(0x0F); XX(0x61); break; + case Xsse_UNPCKLD: XX(0x66); XX(0x0F); XX(0x62); break; + case Xsse_UNPCKLQ: XX(0x66); XX(0x0F); XX(0x6C); break; default: goto bad; } p = doAMode_R(p, fake(vregNo(i->Xin.SseReRg.dst)), diff --git a/VEX/priv/host-x86/hdefs.h b/VEX/priv/host-x86/hdefs.h index 415b1ea6bf..92d21f1925 100644 --- a/VEX/priv/host-x86/hdefs.h +++ b/VEX/priv/host-x86/hdefs.h @@ -337,9 +337,9 @@ typedef Xsse_SHL16, Xsse_SHL32, Xsse_SHL64, Xsse_SHR16, Xsse_SHR32, Xsse_SHR64, Xsse_SAR16, Xsse_SAR32, - Xsse_PACKSSD, Xsse_PACKSSW, Xsse_PACKUSW, - Xsse_PUNPCKHB, Xsse_PUNPCKHW, Xsse_PUNPCKHD, - Xsse_PUNPCKLB, Xsse_PUNPCKLW, Xsse_PUNPCKLD + Xsse_PACKSSD, Xsse_PACKSSW, Xsse_PACKUSW, + Xsse_UNPCKHB, Xsse_UNPCKHW, Xsse_UNPCKHD, Xsse_UNPCKHQ, + Xsse_UNPCKLB, Xsse_UNPCKLW, Xsse_UNPCKLD, Xsse_UNPCKLQ } X86SseOp; @@ -379,7 +379,6 @@ typedef Xin_SseConst, /* Generate restricted SSE literal */ Xin_SseLdSt, /* SSE load/store, no alignment constraints */ Xin_SseLdzLO, /* SSE load low 32/64 bits, zero remainder of reg */ - Xin_Sse128, /* SSE binary typeless (and/or/xor/andn) */ Xin_Sse32Fx4, /* SSE binary, 32Fx4 */ Xin_Sse32FLo, /* SSE binary, 32F in lowest lane only */ Xin_Sse64Fx2, /* SSE binary, 64Fx2 */ @@ -565,11 +564,6 @@ typedef HReg reg; X86AMode* addr; } SseLdzLO; - struct { - X86SseOp op; /* MOV/AND/OR/XOR/ANDN only */ - HReg src; - HReg dst; - } Sse128; struct { X86SseOp op; HReg src; @@ -638,7 +632,6 @@ extern X86Instr* X86Instr_FpCmp ( HReg srcL, HReg srcR, HReg dst ); extern X86Instr* X86Instr_SseConst ( UShort con, HReg dst ); extern X86Instr* X86Instr_SseLdSt ( Bool isLoad, HReg, X86AMode* ); extern X86Instr* X86Instr_SseLdzLO ( Int sz, HReg, X86AMode* ); -extern X86Instr* X86Instr_Sse128 ( X86SseOp, HReg, HReg ); extern X86Instr* X86Instr_Sse32Fx4 ( X86SseOp, HReg, HReg ); extern X86Instr* X86Instr_Sse32FLo ( X86SseOp, HReg, HReg ); extern X86Instr* X86Instr_Sse64Fx2 ( X86SseOp, HReg, HReg ); diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index 11ae76938c..a913691687 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -324,7 +324,7 @@ static X86Instr* mk_vMOVsd_RR ( HReg src, HReg dst ) { vassert(hregClass(src) == HRcVec128); vassert(hregClass(dst) == HRcVec128); - return X86Instr_Sse128(Xsse_MOV, src, dst); + return X86Instr_SseReRg(Xsse_MOV, src, dst); } /* Advance/retreat %esp by n. */ @@ -2590,19 +2590,6 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) return dst; } - case Iop_And128: op = Xsse_AND; goto do_128; - case Iop_Or128: op = Xsse_OR; goto do_128; - case Iop_Xor128: op = Xsse_XOR; goto do_128; - do_128: - { - HReg argL = iselVecExpr(env, e->Iex.Binop.arg1); - HReg argR = iselVecExpr(env, e->Iex.Binop.arg2); - HReg dst = newVRegV(env); - addInstr(env, mk_vMOVsd_RR(argL, dst)); - addInstr(env, X86Instr_Sse128(op, argR, dst)); - return dst; - } - case Iop_CmpEQ32Fx4: op = Xsse_CMPEQF; goto do_32Fx4; case Iop_CmpLT32Fx4: op = Xsse_CMPLTF; goto do_32Fx4; case Iop_CmpLE32Fx4: op = Xsse_CMPLEF; goto do_32Fx4; @@ -2677,12 +2664,34 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) return dst; } - case Iop_QNarrow32Sx4: op = Xsse_PACKSSD; - arg1isEReg = True; goto do_SseReRg; - case Iop_QNarrow16Sx8: op = Xsse_PACKSSW; - arg1isEReg = True; goto do_SseReRg; - case Iop_QNarrow16Ux8: op = Xsse_PACKUSW; - arg1isEReg = True; goto do_SseReRg; + case Iop_QNarrow32Sx4: + op = Xsse_PACKSSD; arg1isEReg = True; goto do_SseReRg; + case Iop_QNarrow16Sx8: + op = Xsse_PACKSSW; arg1isEReg = True; goto do_SseReRg; + case Iop_QNarrow16Ux8: + op = Xsse_PACKUSW; arg1isEReg = True; goto do_SseReRg; + + case Iop_InterleaveHI8x16: + op = Xsse_UNPCKHB; arg1isEReg = True; goto do_SseReRg; + case Iop_InterleaveHI16x8: + op = Xsse_UNPCKHW; arg1isEReg = True; goto do_SseReRg; + case Iop_InterleaveHI32x4: + op = Xsse_UNPCKHD; arg1isEReg = True; goto do_SseReRg; + case Iop_InterleaveHI64x2: + op = Xsse_UNPCKHQ; arg1isEReg = True; goto do_SseReRg; + + case Iop_InterleaveLO8x16: + op = Xsse_UNPCKLB; arg1isEReg = True; goto do_SseReRg; + case Iop_InterleaveLO16x8: + op = Xsse_UNPCKLW; arg1isEReg = True; goto do_SseReRg; + case Iop_InterleaveLO32x4: + op = Xsse_UNPCKLD; arg1isEReg = True; goto do_SseReRg; + case Iop_InterleaveLO64x2: + op = Xsse_UNPCKLQ; arg1isEReg = True; goto do_SseReRg; + + case Iop_And128: op = Xsse_AND; goto do_SseReRg; + case Iop_Or128: op = Xsse_OR; goto do_SseReRg; + case Iop_Xor128: op = Xsse_XOR; goto do_SseReRg; case Iop_Add8x16: op = Xsse_ADD8; goto do_SseReRg; case Iop_Add16x8: op = Xsse_ADD16; goto do_SseReRg; case Iop_Add32x4: op = Xsse_ADD32; goto do_SseReRg;