mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 12:34:35 +03:00
AsmJit cleanup and refactoring
This commit is contained in:
@@ -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]);
|
||||
@@ -1970,6 +1970,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);
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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*)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();
|
||||
@@ -2658,6 +2710,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;
|
||||
|
||||
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, aXmm);
|
||||
invokeNode->setArg(1, bXmm);
|
||||
invokeNode->setRet(0, xXmm);
|
||||
|
||||
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>();
|
||||
|
||||
Reference in New Issue
Block a user