| Index: test/cctest/test-assembler-arm.cc
|
| diff --git a/test/cctest/test-assembler-arm.cc b/test/cctest/test-assembler-arm.cc
|
| index 3763f064930e353497b7541d7778a090842098fb..78cba516ee6448b452bf8ee3b04c66921051903c 100644
|
| --- a/test/cctest/test-assembler-arm.cc
|
| +++ b/test/cctest/test-assembler-arm.cc
|
| @@ -2231,6 +2231,158 @@ TEST(ARMv8_vrintX) {
|
| }
|
| }
|
|
|
| +TEST(ARMv8_vsel) {
|
| + // Test the vsel floating point instructions.
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + Assembler assm(isolate, NULL, 0);
|
| +
|
| + // Used to indicate whether a condition passed or failed.
|
| + static constexpr float kResultPass = 1.0f;
|
| + static constexpr float kResultFail = -kResultPass;
|
| +
|
| + struct ResultsF32 {
|
| + float vseleq_;
|
| + float vselge_;
|
| + float vselgt_;
|
| + float vselvs_;
|
| +
|
| + // The following conditions aren't architecturally supported, but the
|
| + // assembler implements them by swapping the inputs.
|
| + float vselne_;
|
| + float vsellt_;
|
| + float vselle_;
|
| + float vselvc_;
|
| + };
|
| +
|
| + struct ResultsF64 {
|
| + double vseleq_;
|
| + double vselge_;
|
| + double vselgt_;
|
| + double vselvs_;
|
| +
|
| + // The following conditions aren't architecturally supported, but the
|
| + // assembler implements them by swapping the inputs.
|
| + double vselne_;
|
| + double vsellt_;
|
| + double vselle_;
|
| + double vselvc_;
|
| + };
|
| +
|
| + if (CpuFeatures::IsSupported(ARMv8)) {
|
| + CpuFeatureScope scope(&assm, ARMv8);
|
| +
|
| + // Create a helper function:
|
| + // void TestVsel(uint32_t nzcv,
|
| + // ResultsF32* results_f32,
|
| + // ResultsF64* results_f64);
|
| + __ msr(CPSR_f, Operand(r0));
|
| +
|
| + __ vmov(s1, kResultPass);
|
| + __ vmov(s2, kResultFail);
|
| +
|
| + __ vsel(eq, s0, s1, s2);
|
| + __ vstr(s0, r1, offsetof(ResultsF32, vseleq_));
|
| + __ vsel(ge, s0, s1, s2);
|
| + __ vstr(s0, r1, offsetof(ResultsF32, vselge_));
|
| + __ vsel(gt, s0, s1, s2);
|
| + __ vstr(s0, r1, offsetof(ResultsF32, vselgt_));
|
| + __ vsel(vs, s0, s1, s2);
|
| + __ vstr(s0, r1, offsetof(ResultsF32, vselvs_));
|
| +
|
| + __ vsel(ne, s0, s1, s2);
|
| + __ vstr(s0, r1, offsetof(ResultsF32, vselne_));
|
| + __ vsel(lt, s0, s1, s2);
|
| + __ vstr(s0, r1, offsetof(ResultsF32, vsellt_));
|
| + __ vsel(le, s0, s1, s2);
|
| + __ vstr(s0, r1, offsetof(ResultsF32, vselle_));
|
| + __ vsel(vc, s0, s1, s2);
|
| + __ vstr(s0, r1, offsetof(ResultsF32, vselvc_));
|
| +
|
| + __ vmov(d1, kResultPass);
|
| + __ vmov(d2, kResultFail);
|
| +
|
| + __ vsel(eq, d0, d1, d2);
|
| + __ vstr(d0, r2, offsetof(ResultsF64, vseleq_));
|
| + __ vsel(ge, d0, d1, d2);
|
| + __ vstr(d0, r2, offsetof(ResultsF64, vselge_));
|
| + __ vsel(gt, d0, d1, d2);
|
| + __ vstr(d0, r2, offsetof(ResultsF64, vselgt_));
|
| + __ vsel(vs, d0, d1, d2);
|
| + __ vstr(d0, r2, offsetof(ResultsF64, vselvs_));
|
| +
|
| + __ vsel(ne, d0, d1, d2);
|
| + __ vstr(d0, r2, offsetof(ResultsF64, vselne_));
|
| + __ vsel(lt, d0, d1, d2);
|
| + __ vstr(d0, r2, offsetof(ResultsF64, vsellt_));
|
| + __ vsel(le, d0, d1, d2);
|
| + __ vstr(d0, r2, offsetof(ResultsF64, vselle_));
|
| + __ vsel(vc, d0, d1, d2);
|
| + __ vstr(d0, r2, offsetof(ResultsF64, vselvc_));
|
| +
|
| + __ bx(lr);
|
| +
|
| + 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
|
| + F5 f = FUNCTION_CAST<F5>(code->entry());
|
| + Object* dummy = nullptr;
|
| + USE(dummy);
|
| +
|
| + STATIC_ASSERT(kResultPass == -kResultFail);
|
| +#define CHECK_VSEL(n, z, c, v, vseleq, vselge, vselgt, vselvs) \
|
| + do { \
|
| + ResultsF32 results_f32; \
|
| + ResultsF64 results_f64; \
|
| + uint32_t nzcv = (n << 31) | (z << 30) | (c << 29) | (v << 28); \
|
| + dummy = CALL_GENERATED_CODE(isolate, f, nzcv, &results_f32, &results_f64, \
|
| + 0, 0); \
|
| + CHECK_EQ(vseleq, results_f32.vseleq_); \
|
| + CHECK_EQ(vselge, results_f32.vselge_); \
|
| + CHECK_EQ(vselgt, results_f32.vselgt_); \
|
| + CHECK_EQ(vselvs, results_f32.vselvs_); \
|
| + CHECK_EQ(-vseleq, results_f32.vselne_); \
|
| + CHECK_EQ(-vselge, results_f32.vsellt_); \
|
| + CHECK_EQ(-vselgt, results_f32.vselle_); \
|
| + CHECK_EQ(-vselvs, results_f32.vselvc_); \
|
| + CHECK_EQ(vseleq, results_f64.vseleq_); \
|
| + CHECK_EQ(vselge, results_f64.vselge_); \
|
| + CHECK_EQ(vselgt, results_f64.vselgt_); \
|
| + CHECK_EQ(vselvs, results_f64.vselvs_); \
|
| + CHECK_EQ(-vseleq, results_f64.vselne_); \
|
| + CHECK_EQ(-vselge, results_f64.vsellt_); \
|
| + CHECK_EQ(-vselgt, results_f64.vselle_); \
|
| + CHECK_EQ(-vselvs, results_f64.vselvc_); \
|
| + } while (0);
|
| +
|
| + // N Z C V vseleq vselge vselgt vselvs
|
| + CHECK_VSEL(0, 0, 0, 0, kResultFail, kResultPass, kResultPass, kResultFail);
|
| + CHECK_VSEL(0, 0, 0, 1, kResultFail, kResultFail, kResultFail, kResultPass);
|
| + CHECK_VSEL(0, 0, 1, 0, kResultFail, kResultPass, kResultPass, kResultFail);
|
| + CHECK_VSEL(0, 0, 1, 1, kResultFail, kResultFail, kResultFail, kResultPass);
|
| + CHECK_VSEL(0, 1, 0, 0, kResultPass, kResultPass, kResultFail, kResultFail);
|
| + CHECK_VSEL(0, 1, 0, 1, kResultPass, kResultFail, kResultFail, kResultPass);
|
| + CHECK_VSEL(0, 1, 1, 0, kResultPass, kResultPass, kResultFail, kResultFail);
|
| + CHECK_VSEL(0, 1, 1, 1, kResultPass, kResultFail, kResultFail, kResultPass);
|
| + CHECK_VSEL(1, 0, 0, 0, kResultFail, kResultFail, kResultFail, kResultFail);
|
| + CHECK_VSEL(1, 0, 0, 1, kResultFail, kResultPass, kResultPass, kResultPass);
|
| + CHECK_VSEL(1, 0, 1, 0, kResultFail, kResultFail, kResultFail, kResultFail);
|
| + CHECK_VSEL(1, 0, 1, 1, kResultFail, kResultPass, kResultPass, kResultPass);
|
| + CHECK_VSEL(1, 1, 0, 0, kResultPass, kResultFail, kResultFail, kResultFail);
|
| + CHECK_VSEL(1, 1, 0, 1, kResultPass, kResultPass, kResultFail, kResultPass);
|
| + CHECK_VSEL(1, 1, 1, 0, kResultPass, kResultFail, kResultFail, kResultFail);
|
| + CHECK_VSEL(1, 1, 1, 1, kResultPass, kResultPass, kResultFail, kResultPass);
|
| +
|
| +#undef CHECK_VSEL
|
| + }
|
| +}
|
|
|
| TEST(regress4292_b) {
|
| CcTest::InitializeVM();
|
|
|