add vroundps, impl Op::floor on x86

Change-Id: Iad94adda2da74fefb5657d883120f85ad362327e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/263461
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Klein 2020-01-09 07:27:39 -06:00 committed by Skia Commit-Bot
parent 064c7f9f1c
commit f22faaf254
3 changed files with 44 additions and 1 deletions

View File

@ -1145,6 +1145,11 @@ namespace skvm {
this->byte(imm);
}
void Assembler::vroundps(Ymm dst, Ymm x, int imm) {
this->op(0x66,0x3a0f,0x08, dst,x);
this->byte(imm);
}
void Assembler::vmovdqa(Ymm dst, Ymm src) { this->op(0x66,0x0f,0x6f, dst,src); }
void Assembler::vcvtdq2ps (Ymm dst, Ymm x) { this->op(0, 0x0f,0x5b, dst,x); }
@ -2354,6 +2359,7 @@ namespace skvm {
a->vpor (dst(), tmp(), r[x]);
break;
case Op::floor : a->vroundps (dst(), r[x], Assembler::FLOOR); break;
case Op::to_f32: a->vcvtdq2ps (dst(), r[x]); break;
case Op::trunc : a->vcvttps2dq(dst(), r[x]); break;
case Op::round : a->vcvtps2dq (dst(), r[x]); break;

View File

@ -105,7 +105,10 @@ namespace skvm {
using DstEqXOpImm = void(Ymm dst, Ymm x, int imm);
DstEqXOpImm vpslld, vpsrld, vpsrad,
vpsrlw,
vpermq;
vpermq,
vroundps;
enum { NEAREST, FLOOR, CEIL, TRUNC }; // vroundps immediates
using DstEqOpX = void(Ymm dst, Ymm x);
DstEqOpX vmovdqa, vcvtdq2ps, vcvttps2dq, vcvtps2dq;

View File

@ -603,6 +603,28 @@ DEF_TEST(SkVM_madder, r) {
});
}
DEF_TEST(SkVM_floor, r) {
skvm::Builder b;
{
skvm::Arg arg = b.varying<float>();
b.store32(arg, b.bit_cast(b.floor(b.bit_cast(b.load32(arg)))));
}
#if defined(SK_CPU_X86)
test_jit_and_interpreter
#else
test_interpreter_only
#endif
(r, b.done(), [&](const skvm::Program& program) {
float buf[] = { -2.0f, -1.5f, -1.0f, 0.0f, 1.0f, 1.5f, 2.0f };
float want[] = { -2.0f, -2.0f, -1.0f, 0.0f, 1.0f, 1.0f, 2.0f };
program.eval(SK_ARRAY_COUNT(buf), buf);
for (int i = 0; i < (int)SK_ARRAY_COUNT(buf); i++) {
REPORTER_ASSERT(r, buf[i] == want[i]);
}
});
}
DEF_TEST(SkVM_hoist, r) {
// This program uses enough constants that it will fail to JIT if we hoist them.
// The JIT will try again without hoisting, and that'll just need 2 registers.
@ -877,6 +899,18 @@ DEF_TEST(SkVM_Assembler, r) {
0xc4,0xe3,0xfd, 0x00,0xca, 0x05,
});
test_asm(r, [&](A& a) {
a.vroundps(A::ymm1, A::ymm2, A::NEAREST);
a.vroundps(A::ymm1, A::ymm2, A::FLOOR);
a.vroundps(A::ymm1, A::ymm2, A::CEIL);
a.vroundps(A::ymm1, A::ymm2, A::TRUNC);
},{
0xc4,0xe3,0x7d,0x08,0xca,0x00,
0xc4,0xe3,0x7d,0x08,0xca,0x01,
0xc4,0xe3,0x7d,0x08,0xca,0x02,
0xc4,0xe3,0x7d,0x08,0xca,0x03,
});
test_asm(r, [&](A& a) {
A::Label l = a.here();
a.byte(1);