break;
}
-//.. case 0xF5: { /* FPREM1 -- IEEE compliant */
-//.. IRTemp a1 = newTemp(Ity_F64);
-//.. IRTemp a2 = newTemp(Ity_F64);
-//.. DIP("fprem1\n");
-//.. /* Do FPREM1 twice, once to get the remainder, and once
-//.. to get the C3210 flag values. */
-//.. assign( a1, get_ST(0) );
-//.. assign( a2, get_ST(1) );
-//.. put_ST_UNCHECKED(0, binop(Iop_PRem1F64,
-//.. mkexpr(a1), mkexpr(a2)));
-//.. put_C3210( binop(Iop_PRem1C3210F64, mkexpr(a1), mkexpr(a2)) );
-//.. break;
-//.. }
+ case 0xF5: { /* FPREM1 -- IEEE compliant */
+ IRTemp a1 = newTemp(Ity_F64);
+ IRTemp a2 = newTemp(Ity_F64);
+ DIP("fprem1\n");
+ /* Do FPREM1 twice, once to get the remainder, and once
+ to get the C3210 flag values. */
+ assign( a1, get_ST(0) );
+ assign( a2, get_ST(1) );
+ put_ST_UNCHECKED(0,
+ triop(Iop_PRem1F64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1),
+ mkexpr(a2)));
+ put_C3210(
+ unop(Iop_32Uto64,
+ triop(Iop_PRem1C3210F64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1),
+ mkexpr(a2)) ));
+ break;
+ }
case 0xF7: /* FINCSTP */
DIP("fincstp\n");
case Afp_YL2X: return "yl2x";
case Afp_YL2XP1: return "yl2xp1";
case Afp_PREM: return "prem";
-//.. case Xfp_PREM1: return "prem1";
+ case Afp_PREM1: return "prem1";
case Afp_SQRT: return "sqrt";
//.. case Xfp_ABS: return "abs";
//.. case Xfp_NEG: return "chs";
case Afp_YL2X: *p++ = 0xD9; *p++ = 0xF1; break;
case Afp_YL2XP1: *p++ = 0xD9; *p++ = 0xF9; break;
case Afp_PREM: *p++ = 0xD9; *p++ = 0xF8; break;
+ case Afp_PREM1: *p++ = 0xD9; *p++ = 0xF5; break;
default: goto bad;
}
goto done;
enum {
Afp_INVALID,
/* Binary */
- Afp_SCALE, Afp_ATAN, Afp_YL2X, Afp_YL2XP1, Afp_PREM,
+ Afp_SCALE, Afp_ATAN, Afp_YL2X, Afp_YL2XP1, Afp_PREM, Afp_PREM1,
/* Unary */
Afp_SQRT,
Afp_SIN, Afp_COS, Afp_TAN,
case Iex_Triop: {
/* C3210 flags following FPU partial remainder (fprem), both
IEEE compliant (PREM1) and non-IEEE compliant (PREM). */
- if (e->Iex.Triop.op == Iop_PRemC3210F64) {
+ if (e->Iex.Triop.op == Iop_PRemC3210F64
+ || e->Iex.Triop.op == Iop_PRem1C3210F64) {
AMD64AMode* m8_rsp = AMD64AMode_IR(-8, hregAMD64_RSP());
HReg arg1 = iselDblExpr(env, e->Iex.Triop.arg2);
HReg arg2 = iselDblExpr(env, e->Iex.Triop.arg3);
case Iop_PRemC3210F64:
addInstr(env, AMD64Instr_A87FpOp(Afp_PREM));
break;
+ case Iop_PRem1C3210F64:
+ addInstr(env, AMD64Instr_A87FpOp(Afp_PREM1));
+ break;
default:
vassert(0);
}
|| e->Iex.Triop.op == Iop_AtanF64
|| e->Iex.Triop.op == Iop_Yl2xF64
|| e->Iex.Triop.op == Iop_Yl2xp1F64
- || e->Iex.Triop.op == Iop_PRemF64)
+ || e->Iex.Triop.op == Iop_PRemF64
+ || e->Iex.Triop.op == Iop_PRem1F64)
) {
AMD64AMode* m8_rsp = AMD64AMode_IR(-8, hregAMD64_RSP());
HReg arg1 = iselDblExpr(env, e->Iex.Triop.arg2);
HReg arg2 = iselDblExpr(env, e->Iex.Triop.arg3);
HReg dst = newVRegV(env);
Bool arg2first = toBool(e->Iex.Triop.op == Iop_ScaleF64
- || e->Iex.Triop.op == Iop_PRemF64);
+ || e->Iex.Triop.op == Iop_PRemF64
+ || e->Iex.Triop.op == Iop_PRem1F64);
addInstr(env, AMD64Instr_A87Free(2));
/* one arg -> top of x87 stack */
case Iop_PRemF64:
addInstr(env, AMD64Instr_A87FpOp(Afp_PREM));
break;
+ case Iop_PRem1F64:
+ addInstr(env, AMD64Instr_A87FpOp(Afp_PREM1));
+ break;
default:
vassert(0);
}