From: Julian Seward Date: Mon, 21 Feb 2005 13:58:26 +0000 (+0000) Subject: More amd64 SSE/FP bits and pieces. X-Git-Tag: svn/VALGRIND_3_0_1^2~395 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e871d908c6cfcf9c651cfa861213df98a11d7608;p=thirdparty%2Fvalgrind.git More amd64 SSE/FP bits and pieces. git-svn-id: svn://svn.valgrind.org/vex/trunk@939 --- diff --git a/VEX/priv/guest-amd64/toIR.c b/VEX/priv/guest-amd64/toIR.c index 7ad3ecf26f..b7aefb781c 100644 --- a/VEX/priv/guest-amd64/toIR.c +++ b/VEX/priv/guest-amd64/toIR.c @@ -653,14 +653,14 @@ static UChar getUChar ( ULong delta ) return v; } -//.. static UInt getUDisp16 ( UInt delta ) +//.. static UInt getUDisp16 ( ULong delta ) //.. { //.. UInt v = guest_code[delta+1]; v <<= 8; //.. v |= guest_code[delta+0]; //.. return v & 0xFFFF; //.. } //.. -//.. static UInt getUDisp ( Int size, UInt delta ) +//.. static UInt getUDisp ( Int size, ULong delta ) //.. { //.. switch (size) { //.. case 4: return getUDisp32(delta); @@ -4169,7 +4169,7 @@ ULong dis_imul_I_E_G ( Prefix pfx, //.. //.. //.. static -//.. UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) +//.. UInt dis_FPU ( Bool* decode_ok, UChar sorb, ULong delta ) //.. { //.. Int len; //.. UInt r_src, r_dst; @@ -5765,7 +5765,7 @@ ULong dis_imul_I_E_G ( Prefix pfx, //.. /* Vector by scalar shift of G by the amount specified at the bottom //.. of E. This is a straight copy of dis_SSE_shiftG_byE. */ //.. -//.. static UInt dis_MMX_shiftG_byE ( UChar sorb, UInt delta, +//.. static UInt dis_MMX_shiftG_byE ( UChar sorb, ULong delta, //.. HChar* opname, IROp op ) //.. { //.. HChar dis_buf[50]; @@ -5841,7 +5841,7 @@ ULong dis_imul_I_E_G ( Prefix pfx, //.. straight copy of dis_SSE_shiftE_imm. */ //.. //.. static -//.. UInt dis_MMX_shiftE_imm ( UInt delta, HChar* opname, IROp op ) +//.. UInt dis_MMX_shiftE_imm ( ULong delta, HChar* opname, IROp op ) //.. { //.. Bool shl, shr, sar; //.. UChar rm = getUChar(delta); @@ -5896,7 +5896,7 @@ ULong dis_imul_I_E_G ( Prefix pfx, //.. /* Completely handle all MMX instructions except emms. */ //.. //.. static -//.. UInt dis_MMX ( Bool* decode_ok, UChar sorb, Int sz, UInt delta ) +//.. UInt dis_MMX ( Bool* decode_ok, UChar sorb, Int sz, ULong delta ) //.. { //.. Int len; //.. UChar modrm; @@ -6212,7 +6212,7 @@ ULong dis_imul_I_E_G ( Prefix pfx, //.. v-size (no b- variant). */ //.. static //.. UInt dis_SHLRD_Gv_Ev ( UChar sorb, -//.. UInt delta, UChar modrm, +//.. ULong delta, UChar modrm, //.. Int sz, //.. IRExpr* shift_amt, //.. Bool amt_is_literal, @@ -6346,7 +6346,7 @@ ULong dis_imul_I_E_G ( Prefix pfx, //.. //.. //.. static -//.. UInt dis_bt_G_E ( UChar sorb, Int sz, UInt delta, BtOp op ) +//.. UInt dis_bt_G_E ( UChar sorb, Int sz, ULong delta, BtOp op ) //.. { //.. HChar dis_buf[50]; //.. UChar modrm; @@ -6475,7 +6475,7 @@ ULong dis_imul_I_E_G ( Prefix pfx, //.. //.. /* Handle BSF/BSR. Only v-size seems necessary. */ //.. static -//.. UInt dis_bs_E_G ( UChar sorb, Int sz, UInt delta, Bool fwds ) +//.. UInt dis_bs_E_G ( UChar sorb, Int sz, ULong delta, Bool fwds ) //.. { //.. Bool isReg; //.. UChar modrm; @@ -6832,7 +6832,7 @@ ULong dis_cmov_E_G ( Prefix pfx, //.. static -//.. UInt dis_xadd_G_E ( UChar sorb, Int sz, UInt delta0 ) +//.. UInt dis_xadd_G_E ( UChar sorb, Int sz, ULong delta0 ) //.. { //.. Int len; //.. UChar rm = getUChar(delta0); @@ -6876,7 +6876,7 @@ ULong dis_cmov_E_G ( Prefix pfx, //.. /* Move 16 bits from Ew (ireg or mem) to G (a segment register). */ //.. //.. static -//.. UInt dis_mov_Ew_Sw ( UChar sorb, UInt delta0 ) +//.. UInt dis_mov_Ew_Sw ( UChar sorb, ULong delta0 ) //.. { //.. Int len; //.. IRTemp addr; @@ -6976,52 +6976,52 @@ void dis_ret ( ULong d64 ) Handles full width G = G `op` E and G = (not G) `op` E. */ -//.. static UInt dis_SSE_E_to_G_all_wrk ( -//.. UChar sorb, UInt delta, -//.. HChar* opname, IROp op, -//.. Bool invertG -//.. ) -//.. { -//.. HChar dis_buf[50]; -//.. Int alen; -//.. IRTemp addr; -//.. UChar rm = getUChar(delta); -//.. IRExpr* gpart -//.. = invertG ? unop(Iop_Not128, getXMMReg(gregOfRM(rm))) -//.. : 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 { -//.. addr = disAMode ( &alen, sorb, delta, dis_buf ); -//.. putXMMReg( gregOfRM(rm), -//.. binop(op, gpart, -//.. loadLE(Ity_V128, mkexpr(addr))) ); -//.. DIP("%s %s,%s\n", opname, -//.. dis_buf, -//.. nameXMMReg(gregOfRM(rm)) ); -//.. return delta+alen; -//.. } -//.. } -//.. -//.. -//.. /* All lanes SSE binary operation, G = G `op` E. */ -//.. -//.. static -//.. UInt dis_SSE_E_to_G_all ( UChar sorb, UInt delta, HChar* opname, IROp op ) -//.. { -//.. return dis_SSE_E_to_G_all_wrk( sorb, delta, opname, op, False ); -//.. } -//.. +static UInt dis_SSE_E_to_G_all_wrk ( + Prefix pfx, ULong delta, + HChar* opname, IROp op, + Bool invertG + ) +{ + HChar dis_buf[50]; + Int alen; + IRTemp addr; + UChar rm = getUChar(delta); + IRExpr* gpart + = invertG ? unop(Iop_NotV128, getXMMReg(gregOfRexRM(pfx,rm))) + : getXMMReg(gregOfRexRM(pfx,rm)); + if (epartIsReg(rm)) { + putXMMReg( gregOfRexRM(pfx,rm), + binop(op, gpart, + getXMMReg(eregOfRexRM(pfx,rm))) ); + DIP("%s %s,%s\n", opname, + nameXMMReg(eregOfRexRM(pfx,rm)), + nameXMMReg(gregOfRexRM(pfx,rm)) ); + return delta+1; + } else { + addr = disAMode ( &alen, pfx, delta, dis_buf, 0 ); + putXMMReg( gregOfRexRM(pfx,rm), + binop(op, gpart, + loadLE(Ity_V128, mkexpr(addr))) ); + DIP("%s %s,%s\n", opname, + dis_buf, + nameXMMReg(gregOfRexRM(pfx,rm)) ); + return delta+alen; + } +} + + +/* All lanes SSE binary operation, G = G `op` E. */ + +static +UInt dis_SSE_E_to_G_all ( Prefix pfx, ULong delta, HChar* opname, IROp op ) +{ + return dis_SSE_E_to_G_all_wrk( pfx, delta, opname, op, False ); +} + //.. /* All lanes SSE binary operation, G = (not G) `op` E. */ //.. //.. static -//.. UInt dis_SSE_E_to_G_all_invG ( UChar sorb, UInt delta, +//.. UInt dis_SSE_E_to_G_all_invG ( UChar sorb, ULong delta, //.. HChar* opname, IROp op ) //.. { //.. return dis_SSE_E_to_G_all_wrk( sorb, delta, opname, op, True ); @@ -7030,7 +7030,7 @@ void dis_ret ( ULong d64 ) //.. //.. /* Lowest 32-bit lane only SSE binary operation, G = G `op` E. */ //.. -//.. static UInt dis_SSE_E_to_G_lo32 ( UChar sorb, UInt delta, +//.. static UInt dis_SSE_E_to_G_lo32 ( UChar sorb, ULong delta, //.. HChar* opname, IROp op ) //.. { //.. HChar dis_buf[50]; @@ -7065,7 +7065,7 @@ void dis_ret ( ULong d64 ) /* Lower 64-bit lane only SSE binary operation, G = G `op` E. */ -static UInt dis_SSE_E_to_G_lo64 ( Prefix pfx, UInt delta, +static UInt dis_SSE_E_to_G_lo64 ( Prefix pfx, ULong delta, HChar* opname, IROp op ) { HChar dis_buf[50]; @@ -7101,7 +7101,7 @@ static UInt dis_SSE_E_to_G_lo64 ( Prefix pfx, UInt delta, //.. /* All lanes unary SSE operation, G = op(E). */ //.. //.. static UInt dis_SSE_E_to_G_unary_all ( -//.. UChar sorb, UInt delta, +//.. UChar sorb, ULong delta, //.. HChar* opname, IROp op //.. ) //.. { @@ -7131,7 +7131,7 @@ static UInt dis_SSE_E_to_G_lo64 ( Prefix pfx, UInt delta, //.. /* Lowest 32-bit lane only unary SSE operation, G = op(E). */ //.. //.. static UInt dis_SSE_E_to_G_unary_lo32 ( -//.. UChar sorb, UInt delta, +//.. UChar sorb, ULong delta, //.. HChar* opname, IROp op //.. ) //.. { @@ -7174,7 +7174,7 @@ static UInt dis_SSE_E_to_G_lo64 ( Prefix pfx, UInt delta, /* Lowest 64-bit lane only unary SSE operation, G = op(E). */ static UInt dis_SSE_E_to_G_unary_lo64 ( - Prefix pfx, UInt delta, + Prefix pfx, ULong delta, HChar* opname, IROp op ) { @@ -7219,7 +7219,7 @@ static UInt dis_SSE_E_to_G_unary_lo64 ( //.. G = E `op` G (eLeft == True) //.. */ //.. static UInt dis_SSEint_E_to_G( -//.. UChar sorb, UInt delta, +//.. UChar sorb, ULong delta, //.. HChar* opname, IROp op, //.. Bool eLeft //.. ) @@ -7305,7 +7305,7 @@ static UInt dis_SSE_E_to_G_unary_lo64 ( //.. //.. /* Handles SSE 32F comparisons. */ //.. -//.. static UInt dis_SSEcmp_E_to_G ( UChar sorb, UInt delta, +//.. static UInt dis_SSEcmp_E_to_G ( UChar sorb, ULong delta, //.. HChar* opname, Bool all_lanes, Int sz ) //.. { //.. HChar dis_buf[50]; @@ -7361,7 +7361,7 @@ static UInt dis_SSE_E_to_G_unary_lo64 ( //.. /* Vector by scalar shift of G by the amount specified at the bottom //.. of E. */ //.. -//.. static UInt dis_SSE_shiftG_byE ( UChar sorb, UInt delta, +//.. static UInt dis_SSE_shiftG_byE ( UChar sorb, ULong delta, //.. HChar* opname, IROp op ) //.. { //.. HChar dis_buf[50]; @@ -7435,7 +7435,7 @@ static UInt dis_SSE_E_to_G_unary_lo64 ( //.. /* Vector by scalar shift of E by an immediate byte. */ //.. //.. static -//.. UInt dis_SSE_shiftE_imm ( UInt delta, HChar* opname, IROp op ) +//.. UInt dis_SSE_shiftE_imm ( ULong delta, HChar* opname, IROp op ) //.. { //.. Bool shl, shr, sar; //.. UChar rm = getUChar(delta); @@ -10052,13 +10052,13 @@ DisResult disInstr ( /*IN*/ Bool resteerOK, //.. //.. goto decode_success; //.. } -//.. -//.. /* 66 0F 57 = XORPD -- G = G and E */ -//.. if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x57) { -//.. delta = dis_SSE_E_to_G_all( sorb, delta+2, "xorpd", Iop_Xor128 ); -//.. goto decode_success; -//.. } -//.. + + /* 66 0F 57 = XORPD -- G = G xor E */ + if (have66noF2noF3(pfx) && insn[0] == 0x0F && insn[1] == 0x57) { + delta = dis_SSE_E_to_G_all( pfx, delta+2, "xorpd", Iop_XorV128 ); + goto decode_success; + } + //.. /* 66 0F 6B = PACKSSDW */ //.. if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6B) { //.. delta = dis_SSEint_E_to_G( sorb, delta+2, @@ -11155,7 +11155,7 @@ DisResult disInstr ( /*IN*/ Bool resteerOK, //.. case 0xDD: //.. case 0xDE: //.. case 0xDF: { -//.. UInt delta0 = delta; +//.. ULong delta0 = delta; //.. Bool decode_OK = False; //.. delta = dis_FPU ( &decode_OK, sorb, delta ); //.. if (!decode_OK) { @@ -12892,7 +12892,7 @@ DisResult disInstr ( /*IN*/ Bool resteerOK, //.. case 0xE1: /* PSRAgg (src)mmxreg-or-mem, (dst)mmxreg */ //.. case 0xE2: //.. { -//.. UInt delta0 = delta-1; +//.. ULong delta0 = delta-1; //.. Bool decode_OK = False; //.. //.. /* If sz==2 this is SSE, and we assume sse idec has diff --git a/VEX/priv/host-amd64/hdefs.c b/VEX/priv/host-amd64/hdefs.c index 672ffa0d9f..0eeb993808 100644 --- a/VEX/priv/host-amd64/hdefs.c +++ b/VEX/priv/host-amd64/hdefs.c @@ -3039,7 +3039,7 @@ Int emit_AMD64Instr ( UChar* buf, Int nbuf, AMD64Instr* i ) switch (i->Ain.SseReRg.op) { case Asse_MOV: /*movups*/ XX(rex); XX(0x0F); XX(0x10); break; //.. case Xsse_OR: XX(rex); XX(0x0F); XX(0x56); break; -//.. case Xsse_XOR: XX(rex); XX(0x0F); XX(0x57); break; + case Asse_XOR: XX(rex); XX(0x0F); XX(0x57); break; //.. case Xsse_AND: XX(rex); XX(0x0F); XX(0x54); break; //.. case Xsse_PACKSSD: XX(0x66); XX(rex); XX(0x0F); XX(0x6B); break; //.. case Xsse_PACKSSW: XX(0x66); XX(rex); XX(0x0F); XX(0x63); break; diff --git a/VEX/priv/host-amd64/isel.c b/VEX/priv/host-amd64/isel.c index c268358cab..e8ed1f319c 100644 --- a/VEX/priv/host-amd64/isel.c +++ b/VEX/priv/host-amd64/isel.c @@ -2646,15 +2646,15 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) //.. add_to_esp(env, 8); //.. return freg; //.. } -//.. -//.. if (e->tag == Iex_LDle) { -//.. X86AMode* am; -//.. HReg res = newVRegF(env); -//.. vassert(e->Iex.LDle.ty == Ity_F64); -//.. am = iselIntExpr_AMode(env, e->Iex.LDle.addr); -//.. addInstr(env, X86Instr_FpLdSt(True/*load*/, 8, res, am)); -//.. return res; -//.. } + + if (e->tag == Iex_LDle) { + AMD64AMode* am; + HReg res = newVRegV(env); + vassert(e->Iex.LDle.ty == Ity_F64); + am = iselIntExpr_AMode(env, e->Iex.LDle.addr); + addInstr(env, AMD64Instr_SseLdSt( True/*load*/, 8, res, am )); + return res; + } if (e->tag == Iex_Get) { AMD64AMode* am = AMD64AMode_IR( e->Iex.Get.offset, @@ -2842,7 +2842,7 @@ static HReg iselVecExpr ( ISelEnv* env, IRExpr* e ) /* DO NOT CALL THIS DIRECTLY */ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) { -//.. Bool arg1isEReg = False; + Bool arg1isEReg = False; AMD64SseOp op = Asse_INVALID; IRType ty = typeOfIRExpr(env->type_env,e); vassert(e); @@ -3206,7 +3206,7 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) //.. //.. 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_XorV128: op = Asse_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; @@ -3238,22 +3238,21 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) //.. case Iop_QSub16Sx8: op = Xsse_QSUB16S; goto do_SseReRg; //.. case Iop_QSub8Ux16: op = Xsse_QSUB8U; goto do_SseReRg; //.. case Iop_QSub16Ux8: op = Xsse_QSUB16U; goto do_SseReRg; -//.. do_SseReRg: { -//.. HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1); -//.. HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2); -//.. HReg dst = newVRegV(env); -//.. if (op != Xsse_OR && op != Xsse_AND && op != Xsse_XOR) -//.. REQUIRE_SSE2; -//.. if (arg1isEReg) { -//.. addInstr(env, mk_vMOVsd_RR(arg2, dst)); -//.. addInstr(env, X86Instr_SseReRg(op, arg1, dst)); -//.. } else { -//.. addInstr(env, mk_vMOVsd_RR(arg1, dst)); -//.. addInstr(env, X86Instr_SseReRg(op, arg2, dst)); -//.. } -//.. return dst; -//.. } -//.. + do_SseReRg: { + HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1); + HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2); + HReg dst = newVRegV(env); + if (arg1isEReg) { + goto vec_fail; /* awaiting test case */ + addInstr(env, mk_vMOVsd_RR(arg2, dst)); + addInstr(env, AMD64Instr_SseReRg(op, arg1, dst)); + } else { + addInstr(env, mk_vMOVsd_RR(arg1, dst)); + addInstr(env, AMD64Instr_SseReRg(op, arg2, dst)); + } + return dst; + } + //.. case Iop_ShlN16x8: op = Xsse_SHL16; goto do_SseShift; //.. case Iop_ShlN32x4: op = Xsse_SHL32; goto do_SseShift; //.. case Iop_ShlN64x2: op = Xsse_SHL64; goto do_SseShift; @@ -3296,7 +3295,7 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) //.. return dst; //.. } //.. -//.. vec_fail: + vec_fail: vex_printf("iselVecExpr (amd64, subarch = %s): can't reduce\n", LibVEX_ppVexSubArch(env->subarch)); ppIRExpr(e);