diff options
Diffstat (limited to '3rdparty/asmjit/test/asmjit_test_x86_cc.cpp')
-rw-r--r-- | 3rdparty/asmjit/test/asmjit_test_x86_cc.cpp | 590 |
1 files changed, 376 insertions, 214 deletions
diff --git a/3rdparty/asmjit/test/asmjit_test_x86_cc.cpp b/3rdparty/asmjit/test/asmjit_test_x86_cc.cpp index a0e50e97097..9e80d871978 100644 --- a/3rdparty/asmjit/test/asmjit_test_x86_cc.cpp +++ b/3rdparty/asmjit/test/asmjit_test_x86_cc.cpp @@ -27,6 +27,12 @@ #include <stdlib.h> #include <string.h> +#include <memory> +#include <vector> + +// Required for function tests that pass / return XMM registers. +#include <emmintrin.h> + #include "./asmjit_test_misc.h" #ifdef _MSC_VER @@ -67,7 +73,7 @@ public: virtual void handleError(Error err, const char* message, BaseEmitter* origin) { DebugUtils::unused(origin); _err = err; - _message.assignString(message); + _message.assign(message); } Error _err; @@ -81,7 +87,7 @@ public: //! Base test interface for testing `x86::Compiler`. class X86Test { public: - X86Test(const char* name = nullptr) { _name.assignString(name); } + X86Test(const char* name = nullptr) { _name.assign(name); } virtual ~X86Test() {} inline const char* name() const { return _name.data(); } @@ -98,9 +104,7 @@ public: class X86TestApp { public: - Zone _zone; - ZoneAllocator _allocator; - ZoneVector<X86Test*> _tests; + std::vector<std::unique_ptr<X86Test>> _tests; unsigned _nFailed; size_t _outputSize; @@ -109,20 +113,15 @@ public: bool _dumpAsm; X86TestApp() noexcept - : _zone(8096 - Zone::kBlockOverhead), - _allocator(&_zone), - _nFailed(0), + : _nFailed(0), _outputSize(0), _verbose(false), _dumpAsm(false) {} - ~X86TestApp() noexcept { - for (X86Test* test : _tests) - delete test; - } + ~X86TestApp() noexcept {} - Error add(X86Test* test) noexcept{ - return _tests.append(&_allocator, test); + void add(X86Test* test) noexcept { + _tests.push_back(std::unique_ptr<X86Test>(test)); } template<class T> @@ -169,12 +168,12 @@ int X86TestApp::run() { stringLogger.addFlags(kFormatFlags); #endif - for (X86Test* test : _tests) { + for (std::unique_ptr<X86Test>& test : _tests) { JitRuntime runtime; CodeHolder code; SimpleErrorHandler errorHandler; - code.init(runtime.codeInfo()); + code.init(runtime.environment()); code.setErrorHandler(&errorHandler); #ifndef ASMJIT_NO_LOGGING @@ -207,7 +206,7 @@ int X86TestApp::run() { if (!_verbose) printf("\n"); String sb; - cc.dump(sb, kFormatFlags); + Formatter::formatNodeList(sb, kFormatFlags, &cc); printf("%s", sb.data()); } #endif @@ -261,11 +260,12 @@ int X86TestApp::run() { } if (_nFailed == 0) - printf("\n[PASSED] All %u tests passed\n", unsigned(_tests.size())); + printf("\nSuccess:\n All %u tests passed\n", unsigned(_tests.size())); else - printf("\n[FAILED] %u %s of %u failed\n", _nFailed, _nFailed == 1 ? "test" : "tests", unsigned(_tests.size())); + printf("\nFailure:\n %u %s of %u failed\n", _nFailed, _nFailed == 1 ? "test" : "tests", unsigned(_tests.size())); printf(" OutputSize=%zu\n", _outputSize); + printf("\n"); return _nFailed == 0 ? 0 : 1; } @@ -703,8 +703,8 @@ public: func(); - result.appendString("ret={}"); - expect.appendString("ret={}"); + result.append("ret={}"); + expect.append("ret={}"); return true; } @@ -750,8 +750,8 @@ public: func(); - result.appendString("ret={}"); - expect.appendString("ret={}"); + result.append("ret={}"); + expect.append("ret={}"); return true; } @@ -1051,8 +1051,8 @@ public: for (i = 0; i < ASMJIT_ARRAY_SIZE(resultBuf); i++) { if (i != 0) { - result.appendChar(','); - expect.appendChar(','); + result.append(','); + expect.append(','); } result.appendFormat("%u", resultBuf[i]); @@ -1971,6 +1971,59 @@ public: }; // ============================================================================ +// [X86Test_AllocArgsVec] +// ============================================================================ + +class X86Test_AllocArgsVec : public X86Test { +public: + X86Test_AllocArgsVec() : X86Test("AllocArgsVec") {} + + static void add(X86TestApp& app) { + // Not supported on Windows. +#ifndef _WIN32 + app.add(new X86Test_AllocArgsVec()); +#endif + } + + virtual void compile(x86::Compiler& cc) { + cc.addFunc(FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm>(CallConv::kIdHost)); + + x86::Xmm a = cc.newXmm("aXmm"); + x86::Xmm b = cc.newXmm("bXmm"); + + cc.setArg(0, a); + cc.setArg(1, b); + + cc.paddb(a, b); + cc.ret(a); + + cc.endFunc(); + } + + virtual bool run(void* _func, String& result, String& expect) { + typedef __m128i (*Func)(__m128i, __m128i); + Func func = ptr_as_func<Func>(_func); + + uint8_t aData[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + uint8_t bData[16] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + + uint8_t rData[16]; + uint8_t eData[16] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }; + + __m128i aVec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(aData)); + __m128i bVec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(bData)); + + __m128i rVec = func(aVec, bVec); + _mm_storeu_si128(reinterpret_cast<__m128i*>(rData), rVec); + + result.appendHex(rData, 16); + expect.appendHex(eData, 16); + + return result == expect; + } +}; + +// ============================================================================ // [X86Test_AllocRetFloat1] // ============================================================================ @@ -2253,21 +2306,21 @@ public: func(dstBuffer, srcBuffer, kCount); - result.assignString("buf={"); - expect.assignString("buf={"); + result.assign("buf={"); + expect.assign("buf={"); for (i = 0; i < kCount; i++) { if (i != 0) { - result.appendString(", "); - expect.appendString(", "); + result.append(", "); + expect.append(", "); } result.appendFormat("%u", unsigned(dstBuffer[i])); expect.appendFormat("%u", unsigned(srcBuffer[i])); } - result.appendString("}"); - expect.appendString("}"); + result.append("}"); + expect.append("}"); return result == expect; } @@ -2395,21 +2448,21 @@ public: func(dstBuffer, srcBuffer, kCount); - result.assignString("buf={"); - expect.assignString("buf={"); + result.assign("buf={"); + expect.assign("buf={"); for (i = 0; i < kCount; i++) { if (i != 0) { - result.appendString(", "); - expect.appendString(", "); + result.append(", "); + expect.append(", "); } result.appendFormat("%08X", unsigned(dstBuffer[i])); expect.appendFormat("%08X", unsigned(expBuffer[i])); } - result.appendString("}"); - expect.appendString("}"); + result.append("}"); + expect.append("}"); return result == expect; } @@ -2443,11 +2496,12 @@ public: cc.shl(v2, 1); // Call a function. - FuncCallNode* call = cc.call(imm((void*)calledFunc), FuncSignatureT<int, int, int, int>(CallConv::kIdHost)); - call->setArg(0, v2); - call->setArg(1, v1); - call->setArg(2, v0); - call->setRet(0, v0); + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int, int, int>(CallConv::kIdHost)); + invokeNode->setArg(0, v2); + invokeNode->setArg(1, v1); + invokeNode->setArg(2, v0); + invokeNode->setRet(0, v0); cc.ret(v0); cc.endFunc(); @@ -2498,29 +2552,29 @@ public: Label L_Exit = cc.newLabel(); static const char token[kTokenSize] = "-+:|abcdefghijklmnopqrstuvwxyz|"; - FuncCallNode* call; + InvokeNode* invokeNode; cc.lea(p1, s1); cc.lea(p2, s2); // Try to corrupt the stack if wrongly allocated. - call = cc.call(imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdHostCDecl)); - call->setArg(0, p1); - call->setArg(1, imm(token)); - call->setArg(2, imm(kTokenSize)); - call->setRet(0, p1); - - call = cc.call(imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdHostCDecl)); - call->setArg(0, p2); - call->setArg(1, imm(token)); - call->setArg(2, imm(kTokenSize)); - call->setRet(0, p2); - - call = cc.call(imm((void*)memcmp), FuncSignatureT<int, void*, void*, size_t>(CallConv::kIdHostCDecl)); - call->setArg(0, p1); - call->setArg(1, p2); - call->setArg(2, imm(kTokenSize)); - call->setRet(0, ret); + cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdCDecl)); + invokeNode->setArg(0, p1); + invokeNode->setArg(1, imm(token)); + invokeNode->setArg(2, imm(kTokenSize)); + invokeNode->setRet(0, p1); + + cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdCDecl)); + invokeNode->setArg(0, p2); + invokeNode->setArg(1, imm(token)); + invokeNode->setArg(2, imm(kTokenSize)); + invokeNode->setRet(0, p2); + + cc.invoke(&invokeNode, imm((void*)memcmp), FuncSignatureT<int, void*, void*, size_t>(CallConv::kIdCDecl)); + invokeNode->setArg(0, p1); + invokeNode->setArg(1, p2); + invokeNode->setArg(2, imm(kTokenSize)); + invokeNode->setRet(0, ret); // This should be 0 on success, however, if both `p1` and `p2` were // allocated in the same address this check will still pass. @@ -2573,13 +2627,14 @@ public: cc.setArg(1, y); cc.setArg(2, z); - FuncCallNode* call = cc.call( + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)calledFunc), - FuncSignatureT<int, int, int, int>(CallConv::kIdHostStdCall)); - call->setArg(0, x); - call->setArg(1, y); - call->setArg(2, z); - call->setRet(0, x); + FuncSignatureT<int, int, int, int>(CallConv::kIdStdCall)); + invokeNode->setArg(0, x); + invokeNode->setArg(1, y); + invokeNode->setArg(2, z); + invokeNode->setRet(0, x); cc.ret(x); cc.endFunc(); @@ -2622,18 +2677,15 @@ public: cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost)); cc.setArg(0, var); - FuncCallNode* call; - call = cc.call( - imm((void*)calledFunc), - FuncSignatureT<int, int>(CallConv::kIdHostFastCall)); - call->setArg(0, var); - call->setRet(0, var); + InvokeNode* invokeNode; - call = cc.call( - imm((void*)calledFunc), - FuncSignatureT<int, int>(CallConv::kIdHostFastCall)); - call->setArg(0, var); - call->setRet(0, var); + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int>(CallConv::kIdFastCall)); + invokeNode->setArg(0, var); + invokeNode->setRet(0, var); + + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int>(CallConv::kIdFastCall)); + invokeNode->setArg(0, var); + invokeNode->setRet(0, var); cc.ret(var); cc.endFunc(); @@ -2659,6 +2711,97 @@ public: }; // ============================================================================ +// [X86Test_FuncCallSIMD] +// ============================================================================ + +class X86Test_FuncCallSIMD : public X86Test { +public: + bool _useVectorCall; + + X86Test_FuncCallSIMD(bool useVectorCall) + : X86Test(), + _useVectorCall(useVectorCall) { + _name.assignFormat("FuncCallSIMD {%s}", _useVectorCall ? "__vectorcall" : "__cdecl"); + } + + static void add(X86TestApp& app) { + app.add(new X86Test_FuncCallSIMD(false)); +#ifdef _MSC_VER + app.add(new X86Test_FuncCallSIMD(true)); +#endif + } + + virtual void compile(x86::Compiler& cc) { + cc.addFunc(FuncSignatureT<void, void*, const void*, const void*>(CallConv::kIdHost)); + + x86::Gp resultPtr = cc.newIntPtr("resultPtr"); + x86::Gp aPtr = cc.newIntPtr("aPtr"); + x86::Gp bPtr = cc.newIntPtr("bPtr"); + x86::Gp pFn = cc.newIntPtr("pFn"); + + x86::Xmm aXmm = cc.newXmm("aXmm"); + x86::Xmm bXmm = cc.newXmm("bXmm"); + + cc.setArg(0, resultPtr); + cc.setArg(1, aPtr); + cc.setArg(2, bPtr); + + uint32_t ccId = CallConv::kIdCDecl; + Imm pFnImm = imm((void*)calledFunc_cdecl); + +#ifdef _MSC_VER + if (_useVectorCall) { + ccId = CallConv::kIdVectorCall; + pFnImm = imm((void*)calledFunc_vcall); + } +#endif + + cc.mov(pFn, pFnImm); + cc.movdqu(aXmm, x86::ptr(aPtr)); + cc.movdqu(bXmm, x86::ptr(bPtr)); + + InvokeNode* invokeNode; + cc.invoke(&invokeNode, pFn, FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm>(ccId)); + + invokeNode->setArg(0, aXmm); + invokeNode->setArg(1, bXmm); + invokeNode->setRet(0, aXmm); + + cc.movdqu(x86::ptr(resultPtr), aXmm); + + cc.endFunc(); + } + + virtual bool run(void* _func, String& result, String& expect) { + typedef void (*Func)(void*, const void*, const void*); + Func func = ptr_as_func<Func>(_func); + + uint8_t aData[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + uint8_t bData[16] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + + uint8_t rData[16]; + uint8_t eData[16] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }; + + func(rData, aData, bData); + + result.appendHex(rData, 16); + expect.appendHex(eData, 16); + + return result == expect; + } + + static __m128i calledFunc_cdecl(__m128i a, __m128i b) { + return _mm_add_epi8(a, b); + } + +#ifdef _MSC_VER + static __m128i __vectorcall calledFunc_vcall(__m128i a, __m128i b) { + return _mm_add_epi8(a, b); + } +#endif +}; + +// ============================================================================ // [X86Test_FuncCallLight] // ============================================================================ @@ -2671,8 +2814,8 @@ public: } virtual void compile(x86::Compiler& cc) { - FuncSignatureT<void, const void*, const void*, const void*, const void*, void*> funcSig(CallConv::kIdHostCDecl); - FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm> fastSig(CallConv::kIdHostLightCall2); + FuncSignatureT<void, const void*, const void*, const void*, const void*, void*> funcSig(CallConv::kIdCDecl); + FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm> fastSig(CallConv::kIdLightCall2); FuncNode* func = cc.newFunc(funcSig); FuncNode* fast = cc.newFunc(fastSig); @@ -2705,15 +2848,17 @@ public: x86::Xmm xXmm = cc.newXmm("xXmm"); x86::Xmm yXmm = cc.newXmm("yXmm"); - FuncCallNode* call1 = cc.call(fast->label(), fastSig); - call1->setArg(0, aXmm); - call1->setArg(1, bXmm); - call1->setRet(0, xXmm); + InvokeNode* invokeNode; + + cc.invoke(&invokeNode, fast->label(), fastSig); + invokeNode->setArg(0, aXmm); + invokeNode->setArg(1, bXmm); + invokeNode->setRet(0, xXmm); - FuncCallNode* call2 = cc.call(fast->label(), fastSig); - call2->setArg(0, cXmm); - call2->setArg(1, dXmm); - call2->setRet(0, yXmm); + cc.invoke(&invokeNode, fast->label(), fastSig); + invokeNode->setArg(0, cXmm); + invokeNode->setArg(1, dXmm); + invokeNode->setRet(0, yXmm); cc.pmullw(xXmm, yXmm); cc.movups(x86::ptr(pOut), xXmm); @@ -2798,21 +2943,22 @@ public: cc.mov(vi, 0x18); cc.mov(vj, 0x1E); - // Call function. - FuncCallNode* call = cc.call( + // Function call. + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost)); - call->setArg(0, va); - call->setArg(1, vb); - call->setArg(2, vc); - call->setArg(3, vd); - call->setArg(4, ve); - call->setArg(5, vf); - call->setArg(6, vg); - call->setArg(7, vh); - call->setArg(8, vi); - call->setArg(9, vj); - call->setRet(0, va); + invokeNode->setArg(0, va); + invokeNode->setArg(1, vb); + invokeNode->setArg(2, vc); + invokeNode->setArg(3, vd); + invokeNode->setArg(4, ve); + invokeNode->setArg(5, vf); + invokeNode->setArg(6, vg); + invokeNode->setArg(7, vh); + invokeNode->setArg(8, vi); + invokeNode->setArg(9, vj); + invokeNode->setRet(0, va); cc.ret(va); cc.endFunc(); @@ -2856,20 +3002,21 @@ public: cc.mov(a, 3); // Call function. - FuncCallNode* call = cc.call( + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost)); - call->setArg(0, a); - call->setArg(1, a); - call->setArg(2, a); - call->setArg(3, a); - call->setArg(4, a); - call->setArg(5, a); - call->setArg(6, a); - call->setArg(7, a); - call->setArg(8, a); - call->setArg(9, a); - call->setRet(0, a); + invokeNode->setArg(0, a); + invokeNode->setArg(1, a); + invokeNode->setArg(2, a); + invokeNode->setArg(3, a); + invokeNode->setArg(4, a); + invokeNode->setArg(5, a); + invokeNode->setArg(6, a); + invokeNode->setArg(7, a); + invokeNode->setArg(8, a); + invokeNode->setArg(9, a); + invokeNode->setRet(0, a); cc.ret(a); cc.endFunc(); @@ -2908,21 +3055,22 @@ public: x86::Gp rv = cc.newInt32("rv"); // Call function. - FuncCallNode* call = cc.call( + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)X86Test_FuncCallManyArgs::calledFunc), FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost)); - call->setArg(0, imm(0x03)); - call->setArg(1, imm(0x12)); - call->setArg(2, imm(0xA0)); - call->setArg(3, imm(0x0B)); - call->setArg(4, imm(0x2F)); - call->setArg(5, imm(0x02)); - call->setArg(6, imm(0x0C)); - call->setArg(7, imm(0x12)); - call->setArg(8, imm(0x18)); - call->setArg(9, imm(0x1E)); - call->setRet(0, rv); + invokeNode->setArg(0, imm(0x03)); + invokeNode->setArg(1, imm(0x12)); + invokeNode->setArg(2, imm(0xA0)); + invokeNode->setArg(3, imm(0x0B)); + invokeNode->setArg(4, imm(0x2F)); + invokeNode->setArg(5, imm(0x02)); + invokeNode->setArg(6, imm(0x0C)); + invokeNode->setArg(7, imm(0x12)); + invokeNode->setArg(8, imm(0x18)); + invokeNode->setArg(9, imm(0x1E)); + invokeNode->setRet(0, rv); cc.ret(rv); cc.endFunc(); @@ -2974,21 +3122,22 @@ public: x86::Gp rv = cc.newInt32("rv"); // Call function. - FuncCallNode* call = cc.call( + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>(CallConv::kIdHost)); - call->setArg(0, imm(0x01)); - call->setArg(1, imm(0x02)); - call->setArg(2, imm(0x03)); - call->setArg(3, imm(0x04)); - call->setArg(4, imm(0x05)); - call->setArg(5, imm(0x06)); - call->setArg(6, imm(0x07)); - call->setArg(7, imm(0x08)); - call->setArg(8, imm(0x09)); - call->setArg(9, imm(0x0A)); - call->setRet(0, rv); + invokeNode->setArg(0, imm(0x01)); + invokeNode->setArg(1, imm(0x02)); + invokeNode->setArg(2, imm(0x03)); + invokeNode->setArg(3, imm(0x04)); + invokeNode->setArg(4, imm(0x05)); + invokeNode->setArg(5, imm(0x06)); + invokeNode->setArg(6, imm(0x07)); + invokeNode->setArg(7, imm(0x08)); + invokeNode->setArg(8, imm(0x09)); + invokeNode->setArg(9, imm(0x0A)); + invokeNode->setRet(0, rv); cc.ret(rv); cc.endFunc(); @@ -3044,15 +3193,16 @@ public: cc.setArg(3, arg4); // Call function. - FuncCallNode* call = cc.call( + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int&, int&, int&, int&>(CallConv::kIdHost)); - call->setArg(0, arg1); - call->setArg(1, arg2); - call->setArg(2, arg3); - call->setArg(3, arg4); - call->setRet(0, rv); + invokeNode->setArg(0, arg1); + invokeNode->setArg(1, arg2); + invokeNode->setArg(2, arg3); + invokeNode->setArg(3, arg4); + invokeNode->setRet(0, rv); cc.ret(rv); cc.endFunc(); @@ -3101,12 +3251,11 @@ public: cc.setArg(1, b); // Call function. - FuncCallNode* call = cc.call( - imm((void*)calledFunc), - FuncSignatureT<float, float, float>(CallConv::kIdHost)); - call->setArg(0, a); - call->setArg(1, b); - call->setRet(0, ret); + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<float, float, float>(CallConv::kIdHost)); + invokeNode->setArg(0, a); + invokeNode->setArg(1, b); + invokeNode->setRet(0, ret); cc.ret(ret); cc.endFunc(); @@ -3152,12 +3301,11 @@ public: cc.setArg(0, a); cc.setArg(1, b); - FuncCallNode* call = cc.call( - imm((void*)calledFunc), - FuncSignatureT<double, double, double>(CallConv::kIdHost)); - call->setArg(0, a); - call->setArg(1, b); - call->setRet(0, ret); + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<double, double, double>(CallConv::kIdHost)); + invokeNode->setArg(0, a); + invokeNode->setArg(1, b); + invokeNode->setRet(0, ret); cc.ret(ret); cc.endFunc(); @@ -3194,7 +3342,7 @@ public: x86::Gp y = cc.newInt32("y"); x86::Gp op = cc.newInt32("op"); - FuncCallNode* call; + InvokeNode* invokeNode; x86::Gp result; cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost)); @@ -3217,19 +3365,19 @@ public: cc.bind(opAdd); result = cc.newInt32("result_1"); - call = cc.call((uint64_t)calledFuncAdd, FuncSignatureT<int, int, int>(CallConv::kIdHost)); - call->setArg(0, x); - call->setArg(1, y); - call->setRet(0, result); + cc.invoke(&invokeNode, (uint64_t)calledFuncAdd, FuncSignatureT<int, int, int>(CallConv::kIdHost)); + invokeNode->setArg(0, x); + invokeNode->setArg(1, y); + invokeNode->setRet(0, result); cc.ret(result); cc.bind(opMul); result = cc.newInt32("result_2"); - call = cc.call((uint64_t)calledFuncMul, FuncSignatureT<int, int, int>(CallConv::kIdHost)); - call->setArg(0, x); - call->setArg(1, y); - call->setRet(0, result); + cc.invoke(&invokeNode, (uint64_t)calledFuncMul, FuncSignatureT<int, int, int>(CallConv::kIdHost)); + invokeNode->setArg(0, x); + invokeNode->setArg(1, y); + invokeNode->setRet(0, result); cc.ret(result); cc.endFunc(); @@ -3291,25 +3439,25 @@ public: x86::Gp ret = cc.newInt32("ret"); x86::Gp ptr = cc.newIntPtr("ptr"); x86::Gp idx = cc.newInt32("idx"); - FuncCallNode* call; + InvokeNode* invokeNode; cc.mov(ptr, buf); cc.mov(idx, int(i)); - call = cc.call((uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdHostFastCall)); - call->setArg(0, ptr); - call->setArg(1, idx); - call->setRet(0, ret); + cc.invoke(&invokeNode, (uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdFastCall)); + invokeNode->setArg(0, ptr); + invokeNode->setArg(1, idx); + invokeNode->setRet(0, ret); cc.add(acc0, ret); cc.mov(ptr, buf); cc.mov(idx, int(i)); - call = cc.call((uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdHostFastCall)); - call->setArg(0, ptr); - call->setArg(1, idx); - call->setRet(0, ret); + cc.invoke(&invokeNode, (uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdFastCall)); + invokeNode->setArg(0, ptr); + invokeNode->setArg(1, idx); + invokeNode->setRet(0, ret); cc.sub(acc1, ret); } @@ -3361,9 +3509,11 @@ public: cc.mov(tmp, val); cc.dec(tmp); - FuncCallNode* call = cc.call(func->label(), FuncSignatureT<int, int>(CallConv::kIdHost)); - call->setArg(0, tmp); - call->setRet(0, tmp); + InvokeNode* invokeNode; + + cc.invoke(&invokeNode, func->label(), FuncSignatureT<int, int>(CallConv::kIdHost)); + invokeNode->setArg(0, tmp); + invokeNode->setRet(0, tmp); cc.mul(cc.newInt32(), val, tmp); cc.bind(skip); @@ -3413,15 +3563,16 @@ public: // We call `int func(size_t, ...)` // - The `vaIndex` must be 1 (first argument after size_t). // - The full signature of varargs (int, int, int, int) must follow. - FuncCallNode* call = cc.call( + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, size_t, int, int, int, int>(CallConv::kIdHost, 1)); - call->setArg(0, imm(4)); - call->setArg(1, a0); - call->setArg(2, a1); - call->setArg(3, a2); - call->setArg(4, a3); - call->setRet(0, a0); + invokeNode->setArg(0, imm(4)); + invokeNode->setArg(1, a0); + invokeNode->setArg(2, a1); + invokeNode->setArg(3, a2); + invokeNode->setArg(4, a3); + invokeNode->setRet(0, a0); cc.ret(a0); cc.endFunc(); @@ -3481,15 +3632,16 @@ public: // We call `double func(size_t, ...)` // - The `vaIndex` must be 1 (first argument after size_t). // - The full signature of varargs (double, double, double, double) must follow. - FuncCallNode* call = cc.call( + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<double, size_t, double, double, double, double>(CallConv::kIdHost, 1)); - call->setArg(0, imm(4)); - call->setArg(1, a0); - call->setArg(2, a1); - call->setArg(3, a2); - call->setArg(4, a3); - call->setRet(0, a0); + invokeNode->setArg(0, imm(4)); + invokeNode->setArg(1, a0); + invokeNode->setArg(2, a1); + invokeNode->setArg(3, a2); + invokeNode->setArg(4, a3); + invokeNode->setRet(0, a0); cc.ret(a0); cc.endFunc(); @@ -3545,11 +3697,12 @@ public: cc.setArg(0, a); cc.setArg(1, b); - FuncCallNode* call = cc.call( + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)dummy), FuncSignatureT<void, int, int>(CallConv::kIdHost)); - call->setArg(0, a); - call->setArg(1, b); + invokeNode->setArg(0, a); + invokeNode->setArg(1, b); cc.lea(r, x86::ptr(a, b)); cc.ret(r); @@ -3593,11 +3746,12 @@ public: cc.setArg(0, p); cc.movsd(arg, x86::ptr(p)); - FuncCallNode* call = cc.call( + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)op), FuncSignatureT<double, double>(CallConv::kIdHost)); - call->setArg(0, arg); - call->setRet(0, ret); + invokeNode->setArg(0, arg); + invokeNode->setRet(0, ret); cc.ret(ret); cc.endFunc(); @@ -3643,11 +3797,12 @@ public: cc.setArg(0, p); cc.movsd(arg, x86::ptr(p)); - FuncCallNode* call = cc.call( + InvokeNode* invokeNode; + cc.invoke(&invokeNode, imm((void*)op), FuncSignatureT<double, double>(CallConv::kIdHost)); - call->setArg(0, arg); - call->setRet(0, ret); + invokeNode->setArg(0, arg); + invokeNode->setRet(0, ret); cc.xorps(arg, arg); cc.subsd(arg, ret); @@ -3687,18 +3842,20 @@ public: } virtual void compile(x86::Compiler& cc) { - FuncSignatureBuilder funcPrototype; - funcPrototype.setCallConv(CallConv::kIdHost); - funcPrototype.setRet(Type::kIdF64); - cc.addFunc(funcPrototype); + InvokeNode* invokeNode; - FuncSignatureBuilder callPrototype; - callPrototype.setCallConv(CallConv::kIdHost); - callPrototype.setRet(Type::kIdF64); - FuncCallNode* call = cc.call(imm((void*)calledFunc), callPrototype); + FuncSignatureBuilder funcSignature; + funcSignature.setCallConv(CallConv::kIdHost); + funcSignature.setRet(Type::kIdF64); + cc.addFunc(funcSignature); + FuncSignatureBuilder invokeSignature; + invokeSignature.setCallConv(CallConv::kIdHost); + invokeSignature.setRet(Type::kIdF64); + + cc.invoke(&invokeNode, imm((void*)calledFunc), invokeSignature); x86::Xmm ret = cc.newXmmSd("ret"); - call->setRet(0, ret); + invokeNode->setRet(0, ret); cc.ret(ret); cc.endFunc(); @@ -3739,7 +3896,7 @@ public: x86::Gp pFn = cc.newIntPtr("pFn"); x86::Gp vars[16]; - uint32_t i, regCount = cc.gpCount(); + uint32_t i, regCount = cc.arch() == Environment::kArchX86 ? 8 : 16; ASMJIT_ASSERT(regCount <= ASMJIT_ARRAY_SIZE(vars)); cc.mov(pFn, imm((void*)calledFunc)); @@ -3752,7 +3909,9 @@ public: cc.mov(vars[i], 1); } - cc.call(pFn, FuncSignatureT<void>(CallConv::kIdHost)); + InvokeNode* invokeNode; + cc.invoke(&invokeNode, pFn, FuncSignatureT<void>(CallConv::kIdHost)); + for (i = 1; i < regCount; i++) if (vars[i].isValid()) cc.add(vars[0], vars[i]); @@ -3979,10 +4138,11 @@ public: cc.setArg(0, a); cc.setArg(1, b); - FuncCallNode* call = cc.call(f2->label(), FuncSignatureT<int, int, int>(CallConv::kIdHost)); - call->setArg(0, a); - call->setArg(1, b); - call->setRet(0, a); + InvokeNode* invokeNode; + cc.invoke(&invokeNode, f2->label(), FuncSignatureT<int, int, int>(CallConv::kIdHost)); + invokeNode->setArg(0, a); + invokeNode->setArg(1, b); + invokeNode->setRet(0, a); cc.ret(a); cc.endFunc(); @@ -4037,7 +4197,7 @@ public: // arguments will be passed by registers and there won't be any stack // misalignment when we call the `handler()`. This was failing on OSX // when targeting 32-bit. - cc.addFunc(FuncSignatureT<int, int, void*>(CallConv::kIdHostFastCall)); + cc.addFunc(FuncSignatureT<int, int, void*>(CallConv::kIdFastCall)); x86::Gp a = cc.newInt32("a"); x86::Gp b = cc.newIntPtr("b"); @@ -4123,6 +4283,7 @@ int main(int argc, char* argv[]) { app.addT<X86Test_AllocArgsIntPtr>(); app.addT<X86Test_AllocArgsFloat>(); app.addT<X86Test_AllocArgsDouble>(); + app.addT<X86Test_AllocArgsVec>(); app.addT<X86Test_AllocRetFloat1>(); app.addT<X86Test_AllocRetFloat2>(); app.addT<X86Test_AllocRetDouble1>(); @@ -4137,6 +4298,7 @@ int main(int argc, char* argv[]) { app.addT<X86Test_FuncCallBase2>(); app.addT<X86Test_FuncCallStd>(); app.addT<X86Test_FuncCallFast>(); + app.addT<X86Test_FuncCallSIMD>(); app.addT<X86Test_FuncCallLight>(); app.addT<X86Test_FuncCallManyArgs>(); app.addT<X86Test_FuncCallDuplicateArgs>(); |