ARM64: Fixes and more support for FRINT<X> instructions.

Fix simulation and tests for the [-0.5, -0.0[ range for FRINTA and FRINTN, and
add support for FRINTM.

R=ulan@chromium.org

Review URL: https://codereview.chromium.org/223843002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20487 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent eb94807f
......@@ -1660,6 +1660,13 @@ void Assembler::frinta(const FPRegister& fd,
}
void Assembler::frintm(const FPRegister& fd,
const FPRegister& fn) {
ASSERT(fd.SizeInBits() == fn.SizeInBits());
FPDataProcessing1Source(fd, fn, FRINTM);
}
void Assembler::frintn(const FPRegister& fd,
const FPRegister& fn) {
ASSERT(fd.SizeInBits() == fn.SizeInBits());
......
......@@ -1584,6 +1584,9 @@ class Assembler : public AssemblerBase {
// FP round to integer (nearest with ties to away).
void frinta(const FPRegister& fd, const FPRegister& fn);
// FP round to integer (toward minus infinity).
void frintm(const FPRegister& fd, const FPRegister& fn);
// FP round to integer (nearest with ties to even).
void frintn(const FPRegister& fd, const FPRegister& fn);
......
......@@ -833,6 +833,12 @@ void MacroAssembler::Frinta(const FPRegister& fd, const FPRegister& fn) {
}
void MacroAssembler::Frintm(const FPRegister& fd, const FPRegister& fn) {
ASSERT(allow_macro_instructions_);
frintm(fd, fn);
}
void MacroAssembler::Frintn(const FPRegister& fd, const FPRegister& fn) {
ASSERT(allow_macro_instructions_);
frintn(fd, fn);
......
......@@ -387,6 +387,7 @@ class MacroAssembler : public Assembler {
const FPRegister& fm,
const FPRegister& fa);
inline void Frinta(const FPRegister& fd, const FPRegister& fn);
inline void Frintm(const FPRegister& fd, const FPRegister& fn);
inline void Frintn(const FPRegister& fd, const FPRegister& fn);
inline void Frintz(const FPRegister& fd, const FPRegister& fn);
inline void Fsqrt(const FPRegister& fd, const FPRegister& fn);
......
......@@ -2390,6 +2390,10 @@ void Simulator::VisitFPDataProcessing1Source(Instruction* instr) {
case FSQRT_d: set_dreg(fd, FPSqrt(dreg(fn))); break;
case FRINTA_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieAway)); break;
case FRINTA_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieAway)); break;
case FRINTM_s:
set_sreg(fd, FPRoundInt(sreg(fn), FPNegativeInfinity)); break;
case FRINTM_d:
set_dreg(fd, FPRoundInt(dreg(fn), FPNegativeInfinity)); break;
case FRINTN_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieEven)); break;
case FRINTN_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieEven)); break;
case FRINTZ_s: set_sreg(fd, FPRoundInt(sreg(fn), FPZero)); break;
......@@ -2656,17 +2660,27 @@ double Simulator::FPRoundInt(double value, FPRounding round_mode) {
double error = value - int_result;
switch (round_mode) {
case FPTieAway: {
// Take care of correctly handling the range ]-0.5, -0.0], which must
// yield -0.0.
if ((-0.5 < value) && (value < 0.0)) {
int_result = -0.0;
} else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) {
// If the error is greater than 0.5, or is equal to 0.5 and the integer
// result is positive, round up.
if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) {
int_result++;
}
break;
}
case FPTieEven: {
// Take care of correctly handling the range [-0.5, -0.0], which must
// yield -0.0.
if ((-0.5 <= value) && (value < 0.0)) {
int_result = -0.0;
// If the error is greater than 0.5, or is equal to 0.5 and the integer
// result is odd, round up.
if ((error > 0.5) ||
} else if ((error > 0.5) ||
((error == 0.5) && (fmod(int_result, 2) != 0))) {
int_result++;
}
......
......@@ -6032,6 +6032,7 @@ TEST(frinta) {
__ Fmov(s24, kFP32NegativeInfinity);
__ Fmov(s25, 0.0);
__ Fmov(s26, -0.0);
__ Fmov(s27, -0.2);
__ Frinta(s0, s16);
__ Frinta(s1, s17);
......@@ -6044,6 +6045,7 @@ TEST(frinta) {
__ Frinta(s8, s24);
__ Frinta(s9, s25);
__ Frinta(s10, s26);
__ Frinta(s11, s27);
__ Fmov(d16, 1.0);
__ Fmov(d17, 1.1);
......@@ -6056,18 +6058,20 @@ TEST(frinta) {
__ Fmov(d24, kFP32NegativeInfinity);
__ Fmov(d25, 0.0);
__ Fmov(d26, -0.0);
__ Fmov(d27, -0.2);
__ Frinta(d11, d16);
__ Frinta(d12, d17);
__ Frinta(d13, d18);
__ Frinta(d14, d19);
__ Frinta(d15, d20);
__ Frinta(d16, d21);
__ Frinta(d17, d22);
__ Frinta(d18, d23);
__ Frinta(d19, d24);
__ Frinta(d20, d25);
__ Frinta(d21, d26);
__ Frinta(d12, d16);
__ Frinta(d13, d17);
__ Frinta(d14, d18);
__ Frinta(d15, d19);
__ Frinta(d16, d20);
__ Frinta(d17, d21);
__ Frinta(d18, d22);
__ Frinta(d19, d23);
__ Frinta(d20, d24);
__ Frinta(d21, d25);
__ Frinta(d22, d26);
__ Frinta(d23, d27);
END();
RUN();
......@@ -6083,17 +6087,108 @@ TEST(frinta) {
ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
ASSERT_EQUAL_FP32(0.0, s9);
ASSERT_EQUAL_FP32(-0.0, s10);
ASSERT_EQUAL_FP64(1.0, d11);
ASSERT_EQUAL_FP32(-0.0, s11);
ASSERT_EQUAL_FP64(1.0, d12);
ASSERT_EQUAL_FP64(2.0, d13);
ASSERT_EQUAL_FP64(1.0, d13);
ASSERT_EQUAL_FP64(2.0, d14);
ASSERT_EQUAL_FP64(3.0, d15);
ASSERT_EQUAL_FP64(-2.0, d16);
ASSERT_EQUAL_FP64(-3.0, d17);
ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
ASSERT_EQUAL_FP64(0.0, d20);
ASSERT_EQUAL_FP64(-0.0, d21);
ASSERT_EQUAL_FP64(2.0, d15);
ASSERT_EQUAL_FP64(3.0, d16);
ASSERT_EQUAL_FP64(-2.0, d17);
ASSERT_EQUAL_FP64(-3.0, d18);
ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
ASSERT_EQUAL_FP64(0.0, d21);
ASSERT_EQUAL_FP64(-0.0, d22);
ASSERT_EQUAL_FP64(-0.0, d23);
TEARDOWN();
}
TEST(frintm) {
INIT_V8();
SETUP();
START();
__ Fmov(s16, 1.0);
__ Fmov(s17, 1.1);
__ Fmov(s18, 1.5);
__ Fmov(s19, 1.9);
__ Fmov(s20, 2.5);
__ Fmov(s21, -1.5);
__ Fmov(s22, -2.5);
__ Fmov(s23, kFP32PositiveInfinity);
__ Fmov(s24, kFP32NegativeInfinity);
__ Fmov(s25, 0.0);
__ Fmov(s26, -0.0);
__ Fmov(s27, -0.2);
__ Frintm(s0, s16);
__ Frintm(s1, s17);
__ Frintm(s2, s18);
__ Frintm(s3, s19);
__ Frintm(s4, s20);
__ Frintm(s5, s21);
__ Frintm(s6, s22);
__ Frintm(s7, s23);
__ Frintm(s8, s24);
__ Frintm(s9, s25);
__ Frintm(s10, s26);
__ Frintm(s11, s27);
__ Fmov(d16, 1.0);
__ Fmov(d17, 1.1);
__ Fmov(d18, 1.5);
__ Fmov(d19, 1.9);
__ Fmov(d20, 2.5);
__ Fmov(d21, -1.5);
__ Fmov(d22, -2.5);
__ Fmov(d23, kFP32PositiveInfinity);
__ Fmov(d24, kFP32NegativeInfinity);
__ Fmov(d25, 0.0);
__ Fmov(d26, -0.0);
__ Fmov(d27, -0.2);
__ Frintm(d12, d16);
__ Frintm(d13, d17);
__ Frintm(d14, d18);
__ Frintm(d15, d19);
__ Frintm(d16, d20);
__ Frintm(d17, d21);
__ Frintm(d18, d22);
__ Frintm(d19, d23);
__ Frintm(d20, d24);
__ Frintm(d21, d25);
__ Frintm(d22, d26);
__ Frintm(d23, d27);
END();
RUN();
ASSERT_EQUAL_FP32(1.0, s0);
ASSERT_EQUAL_FP32(1.0, s1);
ASSERT_EQUAL_FP32(1.0, s2);
ASSERT_EQUAL_FP32(1.0, s3);
ASSERT_EQUAL_FP32(2.0, s4);
ASSERT_EQUAL_FP32(-2.0, s5);
ASSERT_EQUAL_FP32(-3.0, s6);
ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
ASSERT_EQUAL_FP32(0.0, s9);
ASSERT_EQUAL_FP32(-0.0, s10);
ASSERT_EQUAL_FP32(-1.0, s11);
ASSERT_EQUAL_FP64(1.0, d12);
ASSERT_EQUAL_FP64(1.0, d13);
ASSERT_EQUAL_FP64(1.0, d14);
ASSERT_EQUAL_FP64(1.0, d15);
ASSERT_EQUAL_FP64(2.0, d16);
ASSERT_EQUAL_FP64(-2.0, d17);
ASSERT_EQUAL_FP64(-3.0, d18);
ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
ASSERT_EQUAL_FP64(0.0, d21);
ASSERT_EQUAL_FP64(-0.0, d22);
ASSERT_EQUAL_FP64(-1.0, d23);
TEARDOWN();
}
......@@ -6115,6 +6210,7 @@ TEST(frintn) {
__ Fmov(s24, kFP32NegativeInfinity);
__ Fmov(s25, 0.0);
__ Fmov(s26, -0.0);
__ Fmov(s27, -0.2);
__ Frintn(s0, s16);
__ Frintn(s1, s17);
......@@ -6127,6 +6223,7 @@ TEST(frintn) {
__ Frintn(s8, s24);
__ Frintn(s9, s25);
__ Frintn(s10, s26);
__ Frintn(s11, s27);
__ Fmov(d16, 1.0);
__ Fmov(d17, 1.1);
......@@ -6139,18 +6236,20 @@ TEST(frintn) {
__ Fmov(d24, kFP32NegativeInfinity);
__ Fmov(d25, 0.0);
__ Fmov(d26, -0.0);
__ Fmov(d27, -0.2);
__ Frintn(d11, d16);
__ Frintn(d12, d17);
__ Frintn(d13, d18);
__ Frintn(d14, d19);
__ Frintn(d15, d20);
__ Frintn(d16, d21);
__ Frintn(d17, d22);
__ Frintn(d18, d23);
__ Frintn(d19, d24);
__ Frintn(d20, d25);
__ Frintn(d21, d26);
__ Frintn(d12, d16);
__ Frintn(d13, d17);
__ Frintn(d14, d18);
__ Frintn(d15, d19);
__ Frintn(d16, d20);
__ Frintn(d17, d21);
__ Frintn(d18, d22);
__ Frintn(d19, d23);
__ Frintn(d20, d24);
__ Frintn(d21, d25);
__ Frintn(d22, d26);
__ Frintn(d23, d27);
END();
RUN();
......@@ -6166,17 +6265,19 @@ TEST(frintn) {
ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
ASSERT_EQUAL_FP32(0.0, s9);
ASSERT_EQUAL_FP32(-0.0, s10);
ASSERT_EQUAL_FP64(1.0, d11);
ASSERT_EQUAL_FP32(-0.0, s11);
ASSERT_EQUAL_FP64(1.0, d12);
ASSERT_EQUAL_FP64(2.0, d13);
ASSERT_EQUAL_FP64(1.0, d13);
ASSERT_EQUAL_FP64(2.0, d14);
ASSERT_EQUAL_FP64(2.0, d15);
ASSERT_EQUAL_FP64(-2.0, d16);
ASSERT_EQUAL_FP64(2.0, d16);
ASSERT_EQUAL_FP64(-2.0, d17);
ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
ASSERT_EQUAL_FP64(0.0, d20);
ASSERT_EQUAL_FP64(-0.0, d21);
ASSERT_EQUAL_FP64(-2.0, d18);
ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
ASSERT_EQUAL_FP64(0.0, d21);
ASSERT_EQUAL_FP64(-0.0, d22);
ASSERT_EQUAL_FP64(-0.0, d23);
TEARDOWN();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment