Int alen;
IRTemp addr;
UChar rm = getIByte(delta);
+ // Sqrt32Fx4 and Sqrt64Fx2 take a rounding mode, which is faked
+ // up in the usual way.
+ Bool needsIRRM = op == Iop_Sqrt32Fx4 || op == Iop_Sqrt64Fx2;
if (epartIsReg(rm)) {
- putXMMReg( gregOfRM(rm),
- unop(op, getXMMReg(eregOfRM(rm))) );
+ IRExpr* src = getXMMReg(eregOfRM(rm));
+ /* XXXROUNDINGFIXME */
+ IRExpr* res = needsIRRM ? binop(op, get_FAKE_roundingmode(), src)
+ : unop(op, src);
+ putXMMReg( gregOfRM(rm), res );
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),
- unop(op, loadLE(Ity_V128, mkexpr(addr))) );
+ IRExpr* src = loadLE(Ity_V128, mkexpr(addr));
+ /* XXXROUNDINGFIXME */
+ IRExpr* res = needsIRRM ? binop(op, get_FAKE_roundingmode(), src)
+ : unop(op, src);
+ putXMMReg( gregOfRM(rm), res );
DIP("%s %s,%s\n", opname,
dis_buf,
nameXMMReg(gregOfRM(rm)) );
case Iop_RecipEst32Fx4: op = Xsse_RCPF; goto do_32Fx4_unary;
case Iop_RSqrtEst32Fx4: op = Xsse_RSQRTF; goto do_32Fx4_unary;
- case Iop_Sqrt32Fx4: op = Xsse_SQRTF; goto do_32Fx4_unary;
do_32Fx4_unary:
{
HReg arg = iselVecExpr(env, e->Iex.Unop.arg);
return dst;
}
- 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);
- REQUIRE_SSE2;
- addInstr(env, X86Instr_Sse64Fx2(op, arg, dst));
- return dst;
- }
-
case Iop_RecipEst32F0x4: op = Xsse_RCPF; goto do_32F0x4_unary;
case Iop_RSqrtEst32F0x4: op = Xsse_RSQRTF; goto do_32F0x4_unary;
case Iop_Sqrt32F0x4: op = Xsse_SQRTF; goto do_32F0x4_unary;
if (e->tag == Iex_Binop) {
switch (e->Iex.Binop.op) {
+ case Iop_Sqrt64Fx2:
+ REQUIRE_SSE2;
+ /* fallthrough */
+ case Iop_Sqrt32Fx4: {
+ /* :: (rmode, vec) -> vec */
+ HReg arg = iselVecExpr(env, e->Iex.Binop.arg2);
+ HReg dst = newVRegV(env);
+ /* XXXROUNDINGFIXME */
+ /* set roundingmode here */
+ addInstr(env, (e->Iex.Binop.op == Iop_Sqrt64Fx2
+ ? X86Instr_Sse64Fx2 : X86Instr_Sse32Fx4)
+ (Xsse_SQRTF, arg, dst));
+ return dst;
+ }
+
case Iop_SetV128lo32: {
HReg dst = newVRegV(env);
HReg srcV = iselVecExpr(env, e->Iex.Binop.arg1);