Index: test/cctest/test-assembler-arm.cc |
diff --git a/test/cctest/test-assembler-arm.cc b/test/cctest/test-assembler-arm.cc |
index da45c25f8f7e79ac37561cc90ab720d3261accdb..8efd8be312107e4401de1c628702fb56c51b4480 100644 |
--- a/test/cctest/test-assembler-arm.cc |
+++ b/test/cctest/test-assembler-arm.cc |
@@ -1894,6 +1894,111 @@ TEST(code_relative_offset) { |
} |
+TEST(ARMv8_float32_vrintX) { |
+ // Test the vrintX floating point instructions. |
+ CcTest::InitializeVM(); |
+ Isolate* isolate = CcTest::i_isolate(); |
+ HandleScope scope(isolate); |
+ |
+ typedef struct { |
+ float input; |
+ float ar; |
+ float nr; |
+ float mr; |
+ float pr; |
+ float zr; |
+ } T; |
+ T t; |
+ |
+ // Create a function that accepts &t, and loads, manipulates, and stores |
+ // the floats. |
+ Assembler assm(isolate, NULL, 0); |
+ Label L, C; |
+ |
+ |
+ if (CpuFeatures::IsSupported(ARMv8)) { |
+ CpuFeatureScope scope(&assm, ARMv8); |
+ |
+ __ mov(ip, Operand(sp)); |
+ __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); |
+ |
+ __ mov(r4, Operand(r0)); |
+ |
+ // Test vrinta |
+ __ vldr(s6, r4, offsetof(T, input)); |
+ __ vrinta(s5, s6); |
+ __ vstr(s5, r4, offsetof(T, ar)); |
+ |
+ // Test vrintn |
+ __ vldr(s6, r4, offsetof(T, input)); |
+ __ vrintn(s5, s6); |
+ __ vstr(s5, r4, offsetof(T, nr)); |
+ |
+ // Test vrintp |
+ __ vldr(s6, r4, offsetof(T, input)); |
+ __ vrintp(s5, s6); |
+ __ vstr(s5, r4, offsetof(T, pr)); |
+ |
+ // Test vrintm |
+ __ vldr(s6, r4, offsetof(T, input)); |
+ __ vrintm(s5, s6); |
+ __ vstr(s5, r4, offsetof(T, mr)); |
+ |
+ // Test vrintz |
+ __ vldr(s6, r4, offsetof(T, input)); |
+ __ vrintz(s5, s6); |
+ __ vstr(s5, r4, offsetof(T, zr)); |
+ |
+ __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); |
+ |
+ CodeDesc desc; |
+ assm.GetCode(&desc); |
+ Handle<Code> code = isolate->factory()->NewCode( |
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
+#ifdef DEBUG |
+ OFStream os(stdout); |
+ code->Print(os); |
+#endif |
+ F3 f = FUNCTION_CAST<F3>(code->entry()); |
+ |
+ Object* dummy = nullptr; |
+ USE(dummy); |
+ |
+#define CHECK_VRINT(input_val, ares, nres, mres, pres, zres) \ |
+ t.input = input_val; \ |
+ dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); \ |
+ CHECK_EQ(ares, t.ar); \ |
+ CHECK_EQ(nres, t.nr); \ |
+ CHECK_EQ(mres, t.mr); \ |
+ CHECK_EQ(pres, t.pr); \ |
+ CHECK_EQ(zres, t.zr); |
+ |
+ CHECK_VRINT(-0.5, -1.0, -0.0, -1.0, -0.0, -0.0) |
+ CHECK_VRINT(-0.6, -1.0, -1.0, -1.0, -0.0, -0.0) |
+ CHECK_VRINT(-1.1, -1.0, -1.0, -2.0, -1.0, -1.0) |
+ CHECK_VRINT(0.5, 1.0, 0.0, 0.0, 1.0, 0.0) |
+ CHECK_VRINT(0.6, 1.0, 1.0, 0.0, 1.0, 0.0) |
+ CHECK_VRINT(1.1, 1.0, 1.0, 1.0, 2.0, 1.0) |
+ float inf = std::numeric_limits<float>::infinity(); |
+ CHECK_VRINT(inf, inf, inf, inf, inf, inf) |
+ CHECK_VRINT(-inf, -inf, -inf, -inf, -inf, -inf) |
+ CHECK_VRINT(-0.0, -0.0, -0.0, -0.0, -0.0, -0.0) |
+ |
+ // Check NaN propagation. |
+ float nan = std::numeric_limits<float>::quiet_NaN(); |
+ t.input = nan; |
+ dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); |
+ CHECK_EQ(bit_cast<int32_t>(nan), bit_cast<int32_t>(t.ar)); |
+ CHECK_EQ(bit_cast<int32_t>(nan), bit_cast<int32_t>(t.nr)); |
+ CHECK_EQ(bit_cast<int32_t>(nan), bit_cast<int32_t>(t.mr)); |
+ CHECK_EQ(bit_cast<int32_t>(nan), bit_cast<int32_t>(t.pr)); |
+ CHECK_EQ(bit_cast<int32_t>(nan), bit_cast<int32_t>(t.zr)); |
+ |
+#undef CHECK_VRINT |
+ } |
+} |
+ |
+ |
TEST(ARMv8_vrintX) { |
// Test the vrintX floating point instructions. |
CcTest::InitializeVM(); |