summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asmjit/test/asmjit_test_misc.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asmjit/test/asmjit_test_misc.h')
-rw-r--r--3rdparty/asmjit/test/asmjit_test_misc.h203
1 files changed, 137 insertions, 66 deletions
diff --git a/3rdparty/asmjit/test/asmjit_test_misc.h b/3rdparty/asmjit/test/asmjit_test_misc.h
index 03273272d1b..6231971f01f 100644
--- a/3rdparty/asmjit/test/asmjit_test_misc.h
+++ b/3rdparty/asmjit/test/asmjit_test_misc.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_TEST_MISC_H_INCLUDED
#define ASMJIT_TEST_MISC_H_INCLUDED
@@ -28,42 +10,42 @@
namespace asmtest {
-// Generate a typical alpha blend function using SSE2 instruction set. Used
-// for benchmarking and also in test86. The generated code should be stable
-// and fully functional.
-static void generateAlphaBlend(asmjit::x86::Compiler& cc) {
- using namespace asmjit;
- using namespace asmjit::x86;
+using namespace asmjit;
- Gp dst = cc.newIntPtr("dst");
- Gp src = cc.newIntPtr("src");
+// Generates a typical alpha blend function that uses SSE2 instruction set.
+// This function combines emitting instructions with control flow constructs
+// like binding Labels and jumping to them. This should be pretty representative.
+template<typename Emitter>
+static void generateSseAlphaBlendInternal(
+ Emitter& cc,
+ const x86::Gp& dst, const x86::Gp& src, const x86::Gp& n,
+ const x86::Gp& gp0,
+ const x86::Xmm& simd0, const x86::Xmm& simd1, const x86::Xmm& simd2, const x86::Xmm& simd3,
+ const x86::Xmm& simd4, const x86::Xmm& simd5, const x86::Xmm& simd6, const x86::Xmm& simd7) {
- Gp i = cc.newIntPtr("i");
- Gp j = cc.newIntPtr("j");
- Gp t = cc.newIntPtr("t");
+ x86::Gp i = n;
+ x86::Gp j = gp0;
- Xmm vzero = cc.newXmm("vzero");
- Xmm v0080 = cc.newXmm("v0080");
- Xmm v0101 = cc.newXmm("v0101");
+ x86::Xmm vzero = simd0;
+ x86::Xmm v0080 = simd1;
+ x86::Xmm v0101 = simd2;
Label L_SmallLoop = cc.newLabel();
Label L_SmallEnd = cc.newLabel();
Label L_LargeLoop = cc.newLabel();
Label L_LargeEnd = cc.newLabel();
- Label L_DataPool = cc.newLabel();
-
- cc.addFunc(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost));
+ Label L_Done = cc.newLabel();
- cc.setArg(0, dst);
- cc.setArg(1, src);
- cc.setArg(2, i);
-
- // How many pixels have to be processed to make the loop aligned.
- cc.lea(t, x86::ptr(L_DataPool));
+ // Load SIMD Constants.
cc.xorps(vzero, vzero);
- cc.movaps(v0080, x86::ptr(t, 0));
- cc.movaps(v0101, x86::ptr(t, 16));
+ cc.mov(gp0.r32(), 0x00800080);
+ cc.movd(v0080, gp0.r32());
+ cc.mov(gp0.r32(), 0x01010101);
+ cc.movd(v0101, gp0.r32());
+ cc.pshufd(v0080, v0080, x86::shuffleImm(0, 0, 0, 0));
+ cc.pshufd(v0101, v0101, x86::shuffleImm(0, 0, 0, 0));
+ // How many pixels have to be processed to make the loop aligned.
cc.xor_(j, j);
cc.sub(j, dst);
cc.and_(j, 15);
@@ -71,15 +53,15 @@ static void generateAlphaBlend(asmjit::x86::Compiler& cc) {
cc.jz(L_SmallEnd);
cc.cmp(j, i);
- cc.cmovg(j, i); // j = min(i, j).
- cc.sub(i, j); // i -= j.
+ cc.cmovg(j, i); // j = min(i, j)
+ cc.sub(i, j); // i -= j
// Small loop.
cc.bind(L_SmallLoop);
{
- Xmm x0 = cc.newXmm("x0");
- Xmm y0 = cc.newXmm("y0");
- Xmm a0 = cc.newXmm("a0");
+ x86::Xmm x0 = simd3;
+ x86::Xmm y0 = simd4;
+ x86::Xmm a0 = simd5;
cc.movd(y0, x86::ptr(src));
cc.movd(x0, x86::ptr(dst));
@@ -89,7 +71,7 @@ static void generateAlphaBlend(asmjit::x86::Compiler& cc) {
cc.psrlw(a0, 8);
cc.punpcklbw(x0, vzero);
- cc.pshuflw(a0, a0, x86::Predicate::shuf(1, 1, 1, 1));
+ cc.pshuflw(a0, a0, x86::shuffleImm(1, 1, 1, 1));
cc.punpcklbw(y0, vzero);
cc.pmullw(x0, a0);
@@ -113,7 +95,7 @@ static void generateAlphaBlend(asmjit::x86::Compiler& cc) {
cc.test(i, i);
cc.mov(j, i);
- cc.jz(cc.func()->exitLabel());
+ cc.jz(L_Done);
cc.and_(j, 3);
cc.shr(i, 2);
@@ -122,11 +104,11 @@ static void generateAlphaBlend(asmjit::x86::Compiler& cc) {
// Aligned loop.
cc.bind(L_LargeLoop);
{
- Xmm x0 = cc.newXmm("x0");
- Xmm x1 = cc.newXmm("x1");
- Xmm y0 = cc.newXmm("y0");
- Xmm a0 = cc.newXmm("a0");
- Xmm a1 = cc.newXmm("a1");
+ x86::Xmm x0 = simd3;
+ x86::Xmm x1 = simd4;
+ x86::Xmm y0 = simd5;
+ x86::Xmm a0 = simd6;
+ x86::Xmm a1 = simd7;
cc.movups(y0, x86::ptr(src));
cc.movaps(x0, x86::ptr(dst));
@@ -144,8 +126,8 @@ static void generateAlphaBlend(asmjit::x86::Compiler& cc) {
cc.punpckhbw(x1, vzero);
cc.punpckhwd(a1, a1);
- cc.pshufd(a0, a0, x86::Predicate::shuf(3, 3, 1, 1));
- cc.pshufd(a1, a1, x86::Predicate::shuf(3, 3, 1, 1));
+ cc.pshufd(a0, a0, x86::shuffleImm(3, 3, 1, 1));
+ cc.pshufd(a1, a1, x86::shuffleImm(3, 3, 1, 1));
cc.pmullw(x0, a0);
cc.pmullw(x1, a1);
@@ -172,13 +154,102 @@ static void generateAlphaBlend(asmjit::x86::Compiler& cc) {
cc.test(j, j);
cc.jnz(L_SmallLoop);
- cc.endFunc();
+ cc.bind(L_Done);
+}
+
+static void generateSseAlphaBlend(asmjit::BaseEmitter& emitter, bool emitPrologEpilog) {
+ using namespace asmjit::x86;
- // Data.
- cc.align(kAlignData, 16);
- cc.bind(L_DataPool);
- cc.embedUInt16(uint16_t(0x0080u), 8);
- cc.embedUInt16(uint16_t(0x0101u), 8);
+ if (emitter.isAssembler()) {
+ Assembler& cc = *emitter.as<Assembler>();
+
+ x86::Gp dst = cc.zax();
+ x86::Gp src = cc.zcx();
+ x86::Gp i = cc.zdx();
+ x86::Gp j = cc.zdi();
+
+ if (emitPrologEpilog) {
+ FuncDetail func;
+ func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
+
+ FuncFrame frame;
+ frame.init(func);
+ frame.addDirtyRegs(dst, src, i, j);
+ frame.addDirtyRegs(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
+
+ FuncArgsAssignment args(&func);
+ args.assignAll(dst, src, i);
+ args.updateFuncFrame(frame);
+ frame.finalize();
+
+ cc.emitProlog(frame);
+ cc.emitArgsAssignment(frame, args);
+ generateSseAlphaBlendInternal(cc, dst, src, i, j, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
+ cc.emitEpilog(frame);
+ }
+ else {
+ generateSseAlphaBlendInternal(cc, dst, src, i, j, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
+ }
+ }
+#ifndef ASMJIT_NO_BUILDER
+ else if (emitter.isBuilder()) {
+ Builder& cc = *emitter.as<Builder>();
+
+ x86::Gp dst = cc.zax();
+ x86::Gp src = cc.zcx();
+ x86::Gp i = cc.zdx();
+ x86::Gp j = cc.zdi();
+
+ if (emitPrologEpilog) {
+ FuncDetail func;
+ func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
+
+ FuncFrame frame;
+ frame.init(func);
+ frame.addDirtyRegs(dst, src, i, j);
+ frame.addDirtyRegs(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
+
+ FuncArgsAssignment args(&func);
+ args.assignAll(dst, src, i);
+ args.updateFuncFrame(frame);
+ frame.finalize();
+
+ cc.emitProlog(frame);
+ cc.emitArgsAssignment(frame, args);
+ generateSseAlphaBlendInternal(cc, dst, src, i, j, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
+ cc.emitEpilog(frame);
+ }
+ else {
+ generateSseAlphaBlendInternal(cc, dst, src, i, j, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
+ }
+ }
+#endif
+#ifndef ASMJIT_NO_COMPILER
+ else if (emitter.isCompiler()) {
+ Compiler& cc = *emitter.as<Compiler>();
+
+ Gp dst = cc.newIntPtr("dst");
+ Gp src = cc.newIntPtr("src");
+ Gp i = cc.newIntPtr("i");
+ Gp j = cc.newIntPtr("j");
+
+ Xmm v0 = cc.newXmm("v0");
+ Xmm v1 = cc.newXmm("v1");
+ Xmm v2 = cc.newXmm("v2");
+ Xmm v3 = cc.newXmm("v3");
+ Xmm v4 = cc.newXmm("v4");
+ Xmm v5 = cc.newXmm("v5");
+ Xmm v6 = cc.newXmm("v6");
+ Xmm v7 = cc.newXmm("v7");
+
+ FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*, const void*, size_t>());
+ funcNode->setArg(0, dst);
+ funcNode->setArg(1, src);
+ funcNode->setArg(2, i);
+ generateSseAlphaBlendInternal(cc, dst, src, i, j, v0, v1, v2, v3, v4, v5, v6, v7);
+ cc.endFunc();
+ }
+#endif
}
} // {asmtest}