From: Julian Seward Date: Tue, 7 Dec 2004 11:16:04 +0000 (+0000) Subject: Copy-n-paste 32x4 floating point stuff into 64x2 floating point stuff so X-Git-Tag: svn/VALGRIND_3_0_1^2~704 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=867ab938c4cf8eeda46200ec7da346cb4a93963a;p=thirdparty%2Fvalgrind.git Copy-n-paste 32x4 floating point stuff into 64x2 floating point stuff so as to form a basis for SSE2 floating point support. git-svn-id: svn://svn.valgrind.org/vex/trunk@630 --- diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index b5b18a5441..72c2c99956 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -6991,6 +6991,40 @@ static UInt dis_SSE_E_to_G_lo32 ( UChar sorb, UInt delta, } } +/* Lower 64-bit lane only SSE binary operation, G = G `op` E. */ + +static UInt dis_SSE_E_to_G_lo64 ( UChar sorb, UInt delta, + HChar* opname, IROp op ) +{ + HChar dis_buf[50]; + Int alen; + IRTemp addr; + UChar rm = getIByte(delta); + IRExpr* gpart = getXMMReg(gregOfRM(rm)); + if (epartIsReg(rm)) { + putXMMReg( gregOfRM(rm), + binop(op, gpart, + getXMMReg(eregOfRM(rm))) ); + DIP("%s %s,%s\n", opname, + nameXMMReg(eregOfRM(rm)), + nameXMMReg(gregOfRM(rm)) ); + return delta+1; + } else { + /* We can only do a 64-bit memory read, so the upper half of the + E operand needs to be made simply of zeroes. */ + IRTemp epart = newTemp(Ity_V128); + addr = disAMode ( &alen, sorb, delta, dis_buf ); + assign( epart, unop( Iop_64Uto128, + loadLE(Ity_I64, mkexpr(addr))) ); + putXMMReg( gregOfRM(rm), + binop(op, gpart, mkexpr(epart)) ); + DIP("%s %s,%s\n", opname, + dis_buf, + nameXMMReg(gregOfRM(rm)) ); + return delta+alen; + } +} + /* All lanes unary SSE operation, G = op(E). */ static UInt dis_SSE_E_to_G_unary_all ( @@ -7155,6 +7189,12 @@ static IRExpr* /* :: Ity_I32 */ get_sse_roundingmode ( void ) mkU32(3) ); } +static void put_sse_roundingmode ( IRExpr* sseround ) +{ + vassert(typeOfIRExpr(irbb->tyenv, sseround) == Ity_I32); + stmt( IRStmt_Put( OFFB_SSEROUND, sseround ) ); +} + /* Break a 128-bit value up into four 32-bit ints. */ static void breakup128to32s ( IRTemp t128, @@ -7326,8 +7366,7 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, insn = (UChar*)&guest_code[delta]; /* 0F 58 = ADDPS -- add 32Fx4 from R/M to R */ - if (insn[0] == 0x0F && insn[1] == 0x58) { - vassert(sz == 4); + if (sz == 4 && insn[0] == 0x0F && insn[1] == 0x58) { delta = dis_SSE_E_to_G_all( sorb, delta+2, "addps", Iop_Add32Fx4 ); goto decode_success; } @@ -7340,22 +7379,19 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, } /* 0F 55 = ANDNPS -- G = (not G) and E */ - if (insn[0] == 0x0F && insn[1] == 0x55) { - vassert(sz == 4); + if (sz == 4 && insn[0] == 0x0F && insn[1] == 0x55) { delta = dis_SSE_E_to_G_all_invG( sorb, delta+2, "andnps", Iop_And128 ); goto decode_success; } /* 0F 54 = ANDPS -- G = G and E */ - if (insn[0] == 0x0F && insn[1] == 0x54) { - vassert(sz == 4); + if (sz == 4 && insn[0] == 0x0F && insn[1] == 0x54) { delta = dis_SSE_E_to_G_all( sorb, delta+2, "andps", Iop_And128 ); goto decode_success; } /* 0F C2 = CMPPS -- 32Fx4 comparison from R/M to R */ - if (insn[0] == 0x0F && insn[1] == 0xC2) { - vassert(sz == 4); + if (sz == 4 && insn[0] == 0x0F && insn[1] == 0xC2) { delta = dis_SSEcmp_E_to_G( sorb, delta+2, "cmpps", True, 4 ); goto decode_success; } @@ -7621,7 +7657,7 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, ) ); - //put_sseround( unop(Iop_64to32, mkexpr(t64)) ); + put_sse_roundingmode( unop(Iop_64to32, mkexpr(t64)) ); assign( ew, unop(Iop_64HIto32, mkexpr(t64) ) ); put_emwarn( mkexpr(ew) ); /* Finally, if an emulation warning was reported, side-exit to @@ -8386,6 +8422,42 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, goto decode_success; } + /* ---------------------------------------------------- */ + /* --- end of the SSE decoder. --- */ + /* ---------------------------------------------------- */ + + /* ---------------------------------------------------- */ + /* --- start of the SSE2 decoder. --- */ + /* ---------------------------------------------------- */ + + insn = (UChar*)&guest_code[delta]; + + /* 66 0F 58 = ADDPD -- add 32Fx4 from R/M to R */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x58) { + delta = dis_SSE_E_to_G_all( sorb, delta+2, "addpd", Iop_Add64Fx2 ); + goto decode_success; + } + + /* F2 0F 58 = ADDSD -- add 64F0x2 from R/M to R */ + if (insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0x58) { + vassert(sz == 4); + delta = dis_SSE_E_to_G_lo64( sorb, delta+3, "addsd", Iop_Add64F0x2 ); + goto decode_success; + } + + /* 66 0F 55 = ANDNPD -- G = (not G) and E */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x55) { + delta = dis_SSE_E_to_G_all_invG( sorb, delta+2, "andnpd", Iop_And128 ); + goto decode_success; + } + + /* 66 0F 54 = ANDPD -- G = G and E */ + if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x54) { + delta = dis_SSE_E_to_G_all( sorb, delta+2, "andpd", Iop_And128 ); + goto decode_success; + } + + //-- //-- /* FXSAVE/FXRSTOR m32 -- load/store the FPU/MMX/SSE state. */ //-- if (insn[0] == 0x0F && insn[1] == 0xAE diff --git a/VEX/priv/host-x86/hdefs.c b/VEX/priv/host-x86/hdefs.c index c070507d0a..380ac56318 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -765,7 +765,7 @@ X86Instr* X86Instr_Sse128 ( X86SseOp op, HReg src, HReg dst ) { || op == Xsse_AND || op == Xsse_OR || op == Xsse_XOR); return i; } -X86Instr* X86Instr_Sse32Fx4 ( X86SseOp op, HReg src, HReg dst ) { +X86Instr* X86Instr_Sse32Fx4 ( X86SseOp op, HReg src, HReg dst ) { X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); i->tag = Xin_Sse32Fx4; i->Xin.Sse32Fx4.op = op; @@ -773,7 +773,7 @@ X86Instr* X86Instr_Sse32Fx4 ( X86SseOp op, HReg src, HReg dst ) { i->Xin.Sse32Fx4.dst = dst; return i; } -X86Instr* X86Instr_Sse32FLo ( X86SseOp op, HReg src, HReg dst ) { +X86Instr* X86Instr_Sse32FLo ( X86SseOp op, HReg src, HReg dst ) { X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); i->tag = Xin_Sse32FLo; i->Xin.Sse32FLo.op = op; @@ -781,6 +781,22 @@ X86Instr* X86Instr_Sse32FLo ( X86SseOp op, HReg src, HReg dst ) { i->Xin.Sse32FLo.dst = dst; return i; } +X86Instr* X86Instr_Sse64Fx2 ( X86SseOp op, HReg src, HReg dst ) { + X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); + i->tag = Xin_Sse64Fx2; + i->Xin.Sse64Fx2.op = op; + i->Xin.Sse64Fx2.src = src; + i->Xin.Sse64Fx2.dst = dst; + return i; +} +X86Instr* X86Instr_Sse64FLo ( X86SseOp op, HReg src, HReg dst ) { + X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); + i->tag = Xin_Sse64FLo; + i->Xin.Sse64FLo.op = op; + i->Xin.Sse64FLo.src = src; + i->Xin.Sse64FLo.dst = dst; + return i; +} void ppX86Instr ( X86Instr* i ) { switch (i->tag) { @@ -1007,6 +1023,18 @@ void ppX86Instr ( X86Instr* i ) { vex_printf(","); ppHRegX86(i->Xin.Sse32FLo.dst); return; + case Xin_Sse64Fx2: + vex_printf("%spd ", showX86SseOp(i->Xin.Sse64Fx2.op)); + ppHRegX86(i->Xin.Sse64Fx2.src); + vex_printf(","); + ppHRegX86(i->Xin.Sse64Fx2.dst); + return; + case Xin_Sse64FLo: + vex_printf("%ssd ", showX86SseOp(i->Xin.Sse64FLo.op)); + ppHRegX86(i->Xin.Sse64FLo.src); + vex_printf(","); + ppHRegX86(i->Xin.Sse64FLo.dst); + return; default: vpanic("ppX86Instr"); @@ -1198,6 +1226,24 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i) addHRegUse(u, unary ? HRmWrite : HRmModify, i->Xin.Sse32FLo.dst); return; + case Xin_Sse64Fx2: + vassert(i->Xin.Sse64Fx2.op != Xsse_MOV); + unary = i->Xin.Sse64Fx2.op == Xsse_RCPF + || i->Xin.Sse64Fx2.op == Xsse_RSQRTF + || i->Xin.Sse64Fx2.op == Xsse_SQRTF; + addHRegUse(u, HRmRead, i->Xin.Sse64Fx2.src); + addHRegUse(u, unary ? HRmWrite : HRmModify, + i->Xin.Sse64Fx2.dst); + return; + case Xin_Sse64FLo: + vassert(i->Xin.Sse64FLo.op != Xsse_MOV); + unary = i->Xin.Sse64FLo.op == Xsse_RCPF + || i->Xin.Sse64FLo.op == Xsse_RSQRTF + || i->Xin.Sse64FLo.op == Xsse_SQRTF; + addHRegUse(u, HRmRead, i->Xin.Sse64FLo.src); + addHRegUse(u, unary ? HRmWrite : HRmModify, + i->Xin.Sse64FLo.dst); + return; default: ppX86Instr(i); vpanic("getRegUsage_X86Instr"); @@ -1326,6 +1372,14 @@ void mapRegs_X86Instr (HRegRemap* m, X86Instr* i) mapReg(m, &i->Xin.Sse32FLo.src); mapReg(m, &i->Xin.Sse32FLo.dst); return; + case Xin_Sse64Fx2: + mapReg(m, &i->Xin.Sse64Fx2.src); + mapReg(m, &i->Xin.Sse64Fx2.dst); + return; + case Xin_Sse64FLo: + mapReg(m, &i->Xin.Sse64FLo.src); + mapReg(m, &i->Xin.Sse64FLo.dst); + return; default: ppX86Instr(i); vpanic("mapRegs_X86Instr"); @@ -2427,16 +2481,14 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) goto done; case Xin_SseLdzLO: - if (i->Xin.SseLdzLO.sz == 4) { - /* movss amode, %xmm-dst */ - *p++ = 0xF3; - *p++ = 0x0F; - *p++ = 0x10; - p = doAMode_M(p, fake(vregNo(i->Xin.SseLdzLO.reg)), - i->Xin.SseLdzLO.addr); - goto done; - } - break; + vassert(i->Xin.SseLdzLO.sz == 4 || i->Xin.SseLdzLO.sz == 8); + /* movs[sd] amode, %xmm-dst */ + *p++ = i->Xin.SseLdzLO.sz==4 ? 0xF3 : 0xF2; + *p++ = 0x0F; + *p++ = 0x10; + p = doAMode_M(p, fake(vregNo(i->Xin.SseLdzLO.reg)), + i->Xin.SseLdzLO.addr); + goto done; case Xin_Sse128: *p++ = 0x0F; @@ -2475,6 +2527,31 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) *p++ = (UChar)(xtra & 0xFF); goto done; + case Xin_Sse64Fx2: + xtra = 0; + *p++ = 0x66; + *p++ = 0x0F; + switch (i->Xin.Sse64Fx2.op) { + case Xsse_ADDF: *p++ = 0x58; break; + case Xsse_DIVF: *p++ = 0x5E; break; + case Xsse_MAXF: *p++ = 0x5F; break; + case Xsse_MINF: *p++ = 0x5D; break; + case Xsse_MULF: *p++ = 0x59; break; + case Xsse_RCPF: *p++ = 0x53; break; + case Xsse_RSQRTF: *p++ = 0x52; break; + case Xsse_SQRTF: *p++ = 0x51; break; + case Xsse_SUBF: *p++ = 0x5C; break; + case Xsse_CMPEQF: *p++ = 0xC2; xtra = 0x100; break; + case Xsse_CMPLTF: *p++ = 0xC2; xtra = 0x101; break; + case Xsse_CMPLEF: *p++ = 0xC2; xtra = 0x102; break; + default: goto bad; + } + p = doAMode_R(p, fake(vregNo(i->Xin.Sse64Fx2.dst)), + fake(vregNo(i->Xin.Sse64Fx2.src)) ); + if (xtra & 0x100) + *p++ = (UChar)(xtra & 0xFF); + goto done; + case Xin_Sse32FLo: xtra = 0; *p++ = 0xF3; @@ -2500,6 +2577,31 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) *p++ = (UChar)(xtra & 0xFF); goto done; + case Xin_Sse64FLo: + xtra = 0; + *p++ = 0xF2; + *p++ = 0x0F; + switch (i->Xin.Sse64FLo.op) { + case Xsse_ADDF: *p++ = 0x58; break; + case Xsse_DIVF: *p++ = 0x5E; break; + case Xsse_MAXF: *p++ = 0x5F; break; + case Xsse_MINF: *p++ = 0x5D; break; + case Xsse_MULF: *p++ = 0x59; break; + case Xsse_RCPF: *p++ = 0x53; break; + case Xsse_RSQRTF: *p++ = 0x52; break; + case Xsse_SQRTF: *p++ = 0x51; break; + case Xsse_SUBF: *p++ = 0x5C; break; + case Xsse_CMPEQF: *p++ = 0xC2; xtra = 0x100; break; + case Xsse_CMPLTF: *p++ = 0xC2; xtra = 0x101; break; + case Xsse_CMPLEF: *p++ = 0xC2; xtra = 0x102; break; + default: goto bad; + } + p = doAMode_R(p, fake(vregNo(i->Xin.Sse64FLo.dst)), + fake(vregNo(i->Xin.Sse64FLo.src)) ); + if (xtra & 0x100) + *p++ = (UChar)(xtra & 0xFF); + goto done; + default: goto bad; } diff --git a/VEX/priv/host-x86/hdefs.h b/VEX/priv/host-x86/hdefs.h index 64d57a40aa..7c16b86472 100644 --- a/VEX/priv/host-x86/hdefs.h +++ b/VEX/priv/host-x86/hdefs.h @@ -353,9 +353,9 @@ typedef 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 */ - // Xin_Sse64FLo, /* SSE binary, 64F in lowest lane only */ + Xin_Sse32FLo, /* SSE binary, 32F in lowest lane only */ + Xin_Sse64Fx2, /* SSE binary, 64Fx2 */ + Xin_Sse64FLo /* SSE binary, 64F in lowest lane only */ /* Xin_SseUn32Fx4 */ } X86InstrTag; @@ -551,6 +551,16 @@ typedef HReg src; HReg dst; } Sse32FLo; + struct { + X86SseOp op; + HReg src; + HReg dst; + } Sse64Fx2; + struct { + X86SseOp op; + HReg src; + HReg dst; + } Sse64FLo; } Xin; } @@ -590,6 +600,8 @@ 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 ); +extern X86Instr* X86Instr_Sse64FLo ( X86SseOp, HReg, HReg ); extern void ppX86Instr ( X86Instr* ); diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index a617334a6c..94467b3dfa 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -2437,6 +2437,17 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) return dst; } + case Iop_Recip64Fx2: op = Xsse_RCPF; goto do_64Fx2_unary; + case Iop_RSqrt64Fx2: op = Xsse_RSQRTF; goto do_64Fx2_unary; + case Iop_Sqrt64Fx2: op = Xsse_SQRTF; goto do_64Fx2_unary; + do_64Fx2_unary: + { + HReg arg = iselVecExpr(env, e->Iex.Unop.arg); + HReg dst = newVRegV(env); + addInstr(env, X86Instr_Sse64Fx2(op, arg, dst)); + return dst; + } + case Iop_Recip32F0x4: op = Xsse_RCPF; goto do_32F0x4_unary; case Iop_RSqrt32F0x4: op = Xsse_RSQRTF; goto do_32F0x4_unary; case Iop_Sqrt32F0x4: op = Xsse_SQRTF; goto do_32F0x4_unary; @@ -2455,6 +2466,24 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) return dst; } + case Iop_Recip64F0x2: op = Xsse_RCPF; goto do_64F0x2_unary; + case Iop_RSqrt64F0x2: op = Xsse_RSQRTF; goto do_64F0x2_unary; + case Iop_Sqrt64F0x2: op = Xsse_SQRTF; goto do_64F0x2_unary; + do_64F0x2_unary: + { + /* A bit subtle. We have to copy the arg to the result + register first, because actually doing the SSE scalar insn + leaves the upper half of the destination register + unchanged. Whereas the required semantics of these + primops is that the upper half is simply copied in from the + argument. */ + HReg arg = iselVecExpr(env, e->Iex.Unop.arg); + HReg dst = newVRegV(env); + addInstr(env, mk_vMOVsd_RR(arg, dst)); + addInstr(env, X86Instr_Sse64FLo(op, arg, dst)); + return dst; + } + case Iop_32Uto128: { HReg dst = newVRegV(env); X86AMode* esp0 = X86AMode_IR(0, hregX86_ESP()); @@ -2465,6 +2494,18 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) return dst; } + case Iop_64Uto128: { + HReg rHi, rLo; + HReg dst = newVRegV(env); + X86AMode* esp0 = X86AMode_IR(0, hregX86_ESP()); + iselInt64Expr(&rHi, &rLo, env, e->Iex.Unop.arg); + addInstr(env, X86Instr_Push(X86RMI_Reg(rHi))); + addInstr(env, X86Instr_Push(X86RMI_Reg(rLo))); + addInstr(env, X86Instr_SseLdzLO(8, dst, esp0)); + add_to_esp(env, 8); + return dst; + } + default: break; } /* switch (e->Iex.Unop.op) */ @@ -2541,6 +2582,25 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) return dst; } + case Iop_CmpEQ64Fx2: op = Xsse_CMPEQF; goto do_64Fx2; + case Iop_CmpLT64Fx2: op = Xsse_CMPLTF; goto do_64Fx2; + case Iop_CmpLE64Fx2: op = Xsse_CMPLEF; goto do_64Fx2; + case Iop_Add64Fx2: op = Xsse_ADDF; goto do_64Fx2; + case Iop_Div64Fx2: op = Xsse_DIVF; goto do_64Fx2; + case Iop_Max64Fx2: op = Xsse_MAXF; goto do_64Fx2; + case Iop_Min64Fx2: op = Xsse_MINF; goto do_64Fx2; + case Iop_Mul64Fx2: op = Xsse_MULF; goto do_64Fx2; + case Iop_Sub64Fx2: op = Xsse_SUBF; goto do_64Fx2; + do_64Fx2: + { + 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_Sse64Fx2(op, argR, dst)); + return dst; + } + case Iop_CmpEQ32F0x4: op = Xsse_CMPEQF; goto do_32F0x4; case Iop_CmpLT32F0x4: op = Xsse_CMPLTF; goto do_32F0x4; case Iop_CmpLE32F0x4: op = Xsse_CMPLEF; goto do_32F0x4; @@ -2559,6 +2619,24 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) return dst; } + case Iop_CmpEQ64F0x2: op = Xsse_CMPEQF; goto do_64F0x2; + case Iop_CmpLT64F0x2: op = Xsse_CMPLTF; goto do_64F0x2; + case Iop_CmpLE64F0x2: op = Xsse_CMPLEF; goto do_64F0x2; + case Iop_Add64F0x2: op = Xsse_ADDF; goto do_64F0x2; + case Iop_Div64F0x2: op = Xsse_DIVF; goto do_64F0x2; + case Iop_Max64F0x2: op = Xsse_MAXF; goto do_64F0x2; + case Iop_Min64F0x2: op = Xsse_MINF; goto do_64F0x2; + case Iop_Mul64F0x2: op = Xsse_MULF; goto do_64F0x2; + case Iop_Sub64F0x2: op = Xsse_SUBF; goto do_64F0x2; + do_64F0x2: { + 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_Sse64FLo(op, argR, dst)); + return dst; + } + default: break; } /* switch (e->Iex.Binop.op) */ diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index 7b90c922fb..696143d789 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -227,46 +227,73 @@ void ppIROp ( IROp op ) case Iop_Add32Fx4: vex_printf("Add32Fx4"); return; case Iop_Add32F0x4: vex_printf("Add32F0x4"); return; + case Iop_Add64Fx2: vex_printf("Add64Fx2"); return; + case Iop_Add64F0x2: vex_printf("Add64F0x2"); return; case Iop_Div32Fx4: vex_printf("Div32Fx4"); return; case Iop_Div32F0x4: vex_printf("Div32F0x4"); return; + case Iop_Div64Fx2: vex_printf("Div64Fx2"); return; + case Iop_Div64F0x2: vex_printf("Div64F0x2"); return; case Iop_Max32Fx4: vex_printf("Max32Fx4"); return; case Iop_Max32F0x4: vex_printf("Max32F0x4"); return; + case Iop_Max64Fx2: vex_printf("Max64Fx2"); return; + case Iop_Max64F0x2: vex_printf("Max64F0x2"); return; case Iop_Min32Fx4: vex_printf("Min32Fx4"); return; case Iop_Min32F0x4: vex_printf("Min32F0x4"); return; + case Iop_Min64Fx2: vex_printf("Min64Fx2"); return; + case Iop_Min64F0x2: vex_printf("Min64F0x2"); return; case Iop_Mul32Fx4: vex_printf("Mul32Fx4"); return; case Iop_Mul32F0x4: vex_printf("Mul32F0x4"); return; + case Iop_Mul64Fx2: vex_printf("Mul64Fx2"); return; + case Iop_Mul64F0x2: vex_printf("Mul64F0x2"); return; case Iop_Recip32Fx4: vex_printf("Recip32Fx4"); return; case Iop_Recip32F0x4: vex_printf("Recip32F0x4"); return; + case Iop_Recip64Fx2: vex_printf("Recip64Fx2"); return; + case Iop_Recip64F0x2: vex_printf("Recip64F0x2"); return; case Iop_RSqrt32Fx4: vex_printf("RSqrt32Fx4"); return; case Iop_RSqrt32F0x4: vex_printf("RSqrt32F0x4"); return; + case Iop_RSqrt64Fx2: vex_printf("RSqrt64Fx2"); return; + case Iop_RSqrt64F0x2: vex_printf("RSqrt64F0x2"); return; - case Iop_Sqrt32Fx4: vex_printf("Sqrt32Fx4"); return; - case Iop_Sqrt32F0x4 : vex_printf("Sqrt32F0x4"); return; + case Iop_Sqrt32Fx4: vex_printf("Sqrt32Fx4"); return; + case Iop_Sqrt32F0x4: vex_printf("Sqrt32F0x4"); return; + case Iop_Sqrt64Fx2: vex_printf("Sqrt64Fx2"); return; + case Iop_Sqrt64F0x2: vex_printf("Sqrt64F0x2"); return; case Iop_Sub32Fx4: vex_printf("Sub32Fx4"); return; case Iop_Sub32F0x4: vex_printf("Sub32F0x4"); return; + case Iop_Sub64Fx2: vex_printf("Sub64Fx2"); return; + case Iop_Sub64F0x2: vex_printf("Sub64F0x2"); return; case Iop_CmpEQ32Fx4: vex_printf("CmpEQ32Fx4"); return; case Iop_CmpLT32Fx4: vex_printf("CmpLT32Fx4"); return; case Iop_CmpLE32Fx4: vex_printf("CmpLE32Fx4"); return; case Iop_CmpUN32Fx4: vex_printf("CmpUN32Fx4"); return; + case Iop_CmpEQ64Fx2: vex_printf("CmpEQ64Fx2"); return; + case Iop_CmpLT64Fx2: vex_printf("CmpLT64Fx2"); return; + case Iop_CmpLE64Fx2: vex_printf("CmpLE64Fx2"); return; + case Iop_CmpUN64Fx2: vex_printf("CmpUN64Fx2"); return; case Iop_CmpEQ32F0x4: vex_printf("CmpEQ32F0x4"); return; case Iop_CmpLT32F0x4: vex_printf("CmpLT32F0x4"); return; case Iop_CmpLE32F0x4: vex_printf("CmpLE32F0x4"); return; case Iop_CmpUN32F0x4: vex_printf("CmpUN32F0x4"); return; + case Iop_CmpEQ64F0x2: vex_printf("CmpEQ64F0x2"); return; + case Iop_CmpLT64F0x2: vex_printf("CmpLT64F0x2"); return; + case Iop_CmpLE64F0x2: vex_printf("CmpLE64F0x2"); return; + case Iop_CmpUN64F0x2: vex_printf("CmpUN64F0x2"); return; case Iop_64HLto128: vex_printf("64HLto128"); return; case Iop_128to64: vex_printf("128to64"); return; case Iop_128HIto64: vex_printf("128HIto64"); return; case Iop_32Uto128: vex_printf("32Uto128"); return; + case Iop_64Uto128: vex_printf("64Uto128"); return; case Iop_Set128lo32: vex_printf("Set128lo32"); return; default: vpanic("ppIROp(1)"); @@ -1126,24 +1153,38 @@ void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 ) UNARY(Ity_I64, Ity_V128); case Iop_32Uto128: UNARY(Ity_V128, Ity_I32); + case Iop_64Uto128: UNARY(Ity_V128, Ity_I64); case Iop_Set128lo32: BINARY(Ity_V128, Ity_V128,Ity_I32); case Iop_CmpEQ32Fx4: case Iop_CmpLT32Fx4: + case Iop_CmpEQ64Fx2: case Iop_CmpLT64Fx2: case Iop_CmpLE32Fx4: case Iop_CmpUN32Fx4: + case Iop_CmpLE64Fx2: case Iop_CmpUN64Fx2: case Iop_CmpEQ32F0x4: case Iop_CmpLT32F0x4: + case Iop_CmpEQ64F0x2: case Iop_CmpLT64F0x2: case Iop_CmpLE32F0x4: case Iop_CmpUN32F0x4: + case Iop_CmpLE64F0x2: case Iop_CmpUN64F0x2: case Iop_Add32Fx4: case Iop_Add32F0x4: + case Iop_Add64Fx2: case Iop_Add64F0x2: case Iop_Div32Fx4: case Iop_Div32F0x4: + case Iop_Div64Fx2: case Iop_Div64F0x2: case Iop_Max32Fx4: case Iop_Max32F0x4: + case Iop_Max64Fx2: case Iop_Max64F0x2: case Iop_Min32Fx4: case Iop_Min32F0x4: + case Iop_Min64Fx2: case Iop_Min64F0x2: case Iop_Mul32Fx4: case Iop_Mul32F0x4: + case Iop_Mul64Fx2: case Iop_Mul64F0x2: case Iop_Sub32Fx4: case Iop_Sub32F0x4: + case Iop_Sub64Fx2: case Iop_Sub64F0x2: case Iop_And128: case Iop_Or128: case Iop_Xor128: BINARY(Ity_V128, Ity_V128,Ity_V128); case Iop_Recip32Fx4: case Iop_Recip32F0x4: + case Iop_Recip64Fx2: case Iop_Recip64F0x2: case Iop_RSqrt32Fx4: case Iop_RSqrt32F0x4: + case Iop_RSqrt64Fx2: case Iop_RSqrt64F0x2: case Iop_Sqrt32Fx4: case Iop_Sqrt32F0x4: + case Iop_Sqrt64Fx2: case Iop_Sqrt64F0x2: UNARY(Ity_V128, Ity_V128); default: diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 581ecbcd59..fe3b1b2015 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -337,12 +337,9 @@ typedef Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4, Iop_Max32Fx4, Iop_Min32Fx4, Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4, - Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4, /* unary */ Iop_Recip32Fx4, Iop_Sqrt32Fx4, Iop_RSqrt32Fx4, - //Iop_ItoF32x4, /* first arg is IRRoundingMode (Ity_I32) */ - //Iop_FtoI32x4, /* first arg is IRRoundingMode (Ity_I32) */ /* --- 32x4 lowest-lane-only scalar FP --- */ @@ -352,11 +349,33 @@ typedef /* binary */ Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4, Iop_Max32F0x4, Iop_Min32F0x4, + Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4, /* unary */ Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4, - //Iop_ItoF320x4, /* first arg is IRRoundingMode (Ity_I32) */ - //Iop_FtoI320x4, /* first arg is IRRoundingMode (Ity_I32) */ + + /* --- 64x2 vector FP --- */ + + /* binary */ + Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2, + Iop_Max64Fx2, Iop_Min64Fx2, + Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2, + + /* unary */ + Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2, + + /* --- 64x2 lowest-lane-only scalar FP --- */ + + /* In binary cases, upper half is copied from first operand. In + unary cases, upper half is copied from the operand. */ + + /* binary */ + Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2, + Iop_Max64F0x2, Iop_Min64F0x2, + Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2, + + /* unary */ + Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2, /* --- pack / unpack --- */ @@ -366,6 +385,7 @@ typedef Iop_64HLto128, // :: (I64,I64) -> V128 Iop_32Uto128, + Iop_64Uto128, Iop_Set128lo32, /* 128 -> 32 bit unpack */ //Iop_128W3to32, // :: V128 -> I32, bits 127-96