diff options
author | 2022-02-11 17:16:46 +0700 | |
---|---|---|
committer | 2022-02-13 21:26:55 +0700 | |
commit | 1fba2b4f2c27a2f4162855056f9765ee79db31e9 (patch) | |
tree | f98b63565a8b12895b0bb057c0790b88b11a7b2e /3rdparty/asmjit/test/asmjit_test_misc.h | |
parent | 3a7e08d47d4e1b0e075360e19be1763d9b29f557 (diff) |
asmjit: sync with upstream
Diffstat (limited to '3rdparty/asmjit/test/asmjit_test_misc.h')
-rw-r--r-- | 3rdparty/asmjit/test/asmjit_test_misc.h | 203 |
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..0839d30ac00 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(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), 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(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), 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(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost)); + 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} |