AsmJit cleanup and refactoring

This commit is contained in:
kobalicek
2020-05-31 23:38:22 +02:00
parent e78bba83da
commit f986f7fc44
121 changed files with 13790 additions and 10627 deletions

View File

@@ -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>();