diff --git a/src/asmjit/core/emithelper.cpp b/src/asmjit/core/emithelper.cpp index c06bbe2..36b984f 100644 --- a/src/asmjit/core/emithelper.cpp +++ b/src/asmjit/core/emithelper.cpp @@ -216,14 +216,17 @@ ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& fram } else { WorkData& wd = workData[outGroup]; - if (!wd.isAssigned(outId)) { + if (!wd.isAssigned(outId) || curId == outId) { EmitMove: ASMJIT_PROPAGATE( emitArgMove( BaseReg(archTraits.regTypeToSignature(out.regType()), outId), out.typeId(), BaseReg(archTraits.regTypeToSignature(cur.regType()), curId), cur.typeId())); - wd.reassign(varId, outId, curId); + // Only reassign if this is not a sign/zero extension that happens on the same in/out register. + if (curId != outId) + wd.reassign(varId, outId, curId); + cur.initReg(out.regType(), outId, out.typeId()); if (outId == out.regId()) diff --git a/src/asmjit/core/environment.h b/src/asmjit/core/environment.h index cac3eb0..71e2f06 100644 --- a/src/asmjit/core/environment.h +++ b/src/asmjit/core/environment.h @@ -24,7 +24,7 @@ enum class Vendor : uint8_t { //! Unknown or uninitialized platform vendor. kUnknown = 0, - //! Maximum value of `PlatformVendor`. + //! Maximum value of `Vendor`. kMaxValue = kUnknown, //! Platform vendor detected at compile-time. @@ -500,7 +500,7 @@ public: return isFamilyAArch32(arch) || isFamilyAArch64(arch); } - //! Tests whether the given architecture family is MISP or MIPS64. + //! Tests whether the given architecture family is MIPS or MIPS64. static ASMJIT_INLINE_NODEBUG bool isFamilyMIPS(Arch arch) noexcept { return isArchMIPS32(arch) || isArchMIPS64(arch); } diff --git a/src/asmjit/core/func.h b/src/asmjit/core/func.h index bf5fb0c..dac6dc8 100644 --- a/src/asmjit/core/func.h +++ b/src/asmjit/core/func.h @@ -180,6 +180,11 @@ struct CallConv { //! Natural stack alignment as defined by OS/ABI. uint8_t _naturalStackAlignment; + //! \cond INTERNAL + //! Reserved for future use. + uint8_t _reserved[2]; + //! \endcond + //! Calling convention flags. CallConvFlags _flags; @@ -220,7 +225,7 @@ struct CallConv { //! as it prevents from using an uninitialized data (CallConv doesn't have a constructor that would initialize it, //! it's just a struct). ASMJIT_INLINE_NODEBUG void reset() noexcept { - memset(this, 0, sizeof(*this)); + *this = CallConv{}; memset(_passedOrder.data(), 0xFF, sizeof(_passedOrder)); } diff --git a/src/asmjit/core/funcargscontext.cpp b/src/asmjit/core/funcargscontext.cpp index 1db50a7..a658087 100644 --- a/src/asmjit/core/funcargscontext.cpp +++ b/src/asmjit/core/funcargscontext.cpp @@ -102,9 +102,23 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co ASMJIT_ASSERT(dstWd != nullptr); dstWd->assign(varId, srcId); - // The best case, register is allocated where it is expected to be. - if (dstId == srcId) - var.markDone(); + // The best case, register is allocated where it is expected to be. However, we should + // not mark this as done if both registers are GP and sign or zero extension is required. + if (dstId == srcId) { + if (dstGroup != RegGroup::kGp) { + var.markDone(); + } + else { + TypeId dt = dst.typeId(); + TypeId st = src.typeId(); + + uint32_t dstSize = TypeUtils::sizeOf(dt); + uint32_t srcSize = TypeUtils::sizeOf(st); + + if (dt == TypeId::kVoid || st == TypeId::kVoid || dstSize <= srcSize) + var.markDone(); + } + } } else { if (ASMJIT_UNLIKELY(srcGroup > RegGroup::kMaxVirt)) diff --git a/src/asmjit/core/type.h b/src/asmjit/core/type.h index a54ad4e..415fe0a 100644 --- a/src/asmjit/core/type.h +++ b/src/asmjit/core/type.h @@ -202,9 +202,13 @@ static ASMJIT_INLINE_NODEBUG constexpr bool isInt64(TypeId typeId) noexcept { re //! Tests whether a given type is a scalar 64-bit integer (unsigned). static ASMJIT_INLINE_NODEBUG constexpr bool isUInt64(TypeId typeId) noexcept { return typeId == TypeId::kUInt64; } +//! Tests whether a given type is an 8-bit general purpose register representing either signed or unsigned 8-bit integer. static ASMJIT_INLINE_NODEBUG constexpr bool isGp8(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt8, TypeId::kUInt8); } +//! Tests whether a given type is a 16-bit general purpose register representing either signed or unsigned 16-bit integer static ASMJIT_INLINE_NODEBUG constexpr bool isGp16(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt16, TypeId::kUInt16); } +//! Tests whether a given type is a 32-bit general purpose register representing either signed or unsigned 32-bit integer static ASMJIT_INLINE_NODEBUG constexpr bool isGp32(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt32, TypeId::kUInt32); } +//! Tests whether a given type is a 64-bit general purpose register representing either signed or unsigned 64-bit integer static ASMJIT_INLINE_NODEBUG constexpr bool isGp64(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt64, TypeId::kUInt64); } //! Tests whether a given type is a scalar floating point of any size. @@ -216,21 +220,41 @@ static ASMJIT_INLINE_NODEBUG constexpr bool isFloat64(TypeId typeId) noexcept { //! Tests whether a given type is a scalar 80-bit float. static ASMJIT_INLINE_NODEBUG constexpr bool isFloat80(TypeId typeId) noexcept { return typeId == TypeId::kFloat80; } +//! Tests whether a given type is a mask register of any size. static ASMJIT_INLINE_NODEBUG constexpr bool isMask(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kMaskStart, TypeId::_kMaskEnd); } +//! Tests whether a given type is an 8-bit mask register. static ASMJIT_INLINE_NODEBUG constexpr bool isMask8(TypeId typeId) noexcept { return typeId == TypeId::kMask8; } +//! Tests whether a given type is an 16-bit mask register. static ASMJIT_INLINE_NODEBUG constexpr bool isMask16(TypeId typeId) noexcept { return typeId == TypeId::kMask16; } +//! Tests whether a given type is an 32-bit mask register. static ASMJIT_INLINE_NODEBUG constexpr bool isMask32(TypeId typeId) noexcept { return typeId == TypeId::kMask32; } +//! Tests whether a given type is an 64-bit mask register. static ASMJIT_INLINE_NODEBUG constexpr bool isMask64(TypeId typeId) noexcept { return typeId == TypeId::kMask64; } +//! Tests whether a given type is an MMX register. +//! +//! \note MMX functionality is in general deprecated on X86 architecture. AsmJit provides it just for completeness. static ASMJIT_INLINE_NODEBUG constexpr bool isMmx(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kMmxStart, TypeId::_kMmxEnd); } +//! Tests whether a given type is an MMX register, which only uses the low 32 bits of data (only specific cases). +//! +//! \note MMX functionality is in general deprecated on X86 architecture. AsmJit provides it just for completeness. static ASMJIT_INLINE_NODEBUG constexpr bool isMmx32(TypeId typeId) noexcept { return typeId == TypeId::kMmx32; } +//! Tests whether a given type is an MMX register, which uses 64 bits of data (default). +//! +//! \note MMX functionality is in general deprecated on X86 architecture. AsmJit provides it just for completeness. static ASMJIT_INLINE_NODEBUG constexpr bool isMmx64(TypeId typeId) noexcept { return typeId == TypeId::kMmx64; } +//! Tests whether a given type is a vector register of any size. static ASMJIT_INLINE_NODEBUG constexpr bool isVec(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec32Start, TypeId::_kVec512End); } +//! Tests whether a given type is a 32-bit or 32-bit view of a vector register. static ASMJIT_INLINE_NODEBUG constexpr bool isVec32(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec32Start, TypeId::_kVec32End); } +//! Tests whether a given type is a 64-bit or 64-bit view of a vector register. static ASMJIT_INLINE_NODEBUG constexpr bool isVec64(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec64Start, TypeId::_kVec64End); } +//! Tests whether a given type is a 128-bit or 128-bit view of a vector register. static ASMJIT_INLINE_NODEBUG constexpr bool isVec128(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec128Start, TypeId::_kVec128End); } +//! Tests whether a given type is a 256-bit or 256-bit view of a vector register. static ASMJIT_INLINE_NODEBUG constexpr bool isVec256(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec256Start, TypeId::_kVec256End); } +//! Tests whether a given type is a 512-bit or 512-bit view of a vector register. static ASMJIT_INLINE_NODEBUG constexpr bool isVec512(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec512Start, TypeId::_kVec512End); } //! \cond diff --git a/src/asmjit/x86/x86emithelper.cpp b/src/asmjit/x86/x86emithelper.cpp index 1219503..7633af1 100644 --- a/src/asmjit/x86/x86emithelper.cpp +++ b/src/asmjit/x86/x86emithelper.cpp @@ -22,6 +22,18 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86) // x86::EmitHelper - Utilities // =========================== +static constexpr OperandSignature regSizeToGpSignature[8 + 1] = { + OperandSignature{0}, + OperandSignature{RegTraits::kSignature}, + OperandSignature{RegTraits::kSignature}, + OperandSignature{0}, + OperandSignature{RegTraits::kSignature}, + OperandSignature{0}, + OperandSignature{0}, + OperandSignature{0}, + OperandSignature{RegTraits::kSignature} +}; + static inline uint32_t getXmmMovInst(const FuncFrame& frame) { bool avx = frame.isAvxEnabled(); bool aligned = frame.hasAlignedVecSR(); @@ -182,41 +194,42 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove( // Not a real loop, just 'break' is nicer than 'goto'. for (;;) { if (TypeUtils::isInt(dstTypeId)) { + // Sign extend. if (TypeUtils::isInt(srcTypeId)) { - instId = Inst::kIdMovsx; uint32_t castOp = makeCastOp(dstTypeId, srcTypeId); - // Sign extend by using 'movsx'. if (castOp == makeCastOp(TypeId::kInt16, TypeId::kInt8 ) || castOp == makeCastOp(TypeId::kInt32, TypeId::kInt8 ) || - castOp == makeCastOp(TypeId::kInt32, TypeId::kInt16) || castOp == makeCastOp(TypeId::kInt64, TypeId::kInt8 ) || - castOp == makeCastOp(TypeId::kInt64, TypeId::kInt16)) - break; + castOp == makeCastOp(TypeId::kInt32, TypeId::kInt16) || + castOp == makeCastOp(TypeId::kInt64, TypeId::kInt16) || + castOp == makeCastOp(TypeId::kInt64, TypeId::kInt32)) { + // Sign extend by using 'movsx' or 'movsxd'. + instId = + castOp == makeCastOp(TypeId::kInt64, TypeId::kInt32) + ? Inst::kIdMovsxd + : Inst::kIdMovsx; - // Sign extend by using 'movsxd'. - instId = Inst::kIdMovsxd; - if (castOp == makeCastOp(TypeId::kInt64, TypeId::kInt32)) + dst.setSignature(regSizeToGpSignature[dstSize]); + if (src.isReg()) + src.setSignature(regSizeToGpSignature[srcSize]); break; + } } + // Zero extend. if (TypeUtils::isInt(srcTypeId) || src_.isMem()) { - // Zero extend by using 'movzx' or 'mov'. - if (dstSize <= 4 && srcSize < 4) { - instId = Inst::kIdMovzx; - dst.setSignature(Reg::signatureOfT()); - } - else { - // We should have caught all possibilities where `srcSize` is less than 4, so we don't have to worry - // about 'movzx' anymore. Minimum size is enough to determine if we want 32-bit or 64-bit move. - instId = Inst::kIdMov; - srcSize = Support::min(srcSize, dstSize); + uint32_t movSize = Support::min(srcSize, dstSize); + if (movSize <= 4) + dstSize = 4; - dst.setSignature(srcSize == 4 ? Reg::signatureOfT() - : Reg::signatureOfT()); - if (src.isReg()) - src.setSignature(dst.signature()); - } + // Zero extend by using 'movzx' or 'mov'. + instId = movSize < 4 ? Inst::kIdMovzx : Inst::kIdMov; + srcSize = Support::min(srcSize, movSize); + + dst.setSignature(regSizeToGpSignature[dstSize]); + if (src.isReg()) + src.setSignature(regSizeToGpSignature[srcSize]); break; } diff --git a/test/asmjit_test_compiler.cpp b/test/asmjit_test_compiler.cpp index 9062ef1..cfbb7ed 100644 --- a/test/asmjit_test_compiler.cpp +++ b/test/asmjit_test_compiler.cpp @@ -35,6 +35,7 @@ using namespace asmjit; int TestApp::handleArgs(int argc, const char* const* argv) { CmdLine cmd(argc, argv); _arch = cmd.valueOf("--arch", "all"); + _filter = cmd.valueOf("--filter", nullptr); if (cmd.hasArg("--help")) _helpOnly = true; if (cmd.hasArg("--verbose")) _verbose = true; @@ -56,11 +57,12 @@ void TestApp::showInfo() { asmjitArchAsString(Arch::kHost)); printf("Usage:\n"); - printf(" --help Show usage only\n"); - printf(" --arch= Select architecture to run ('all' by default)\n"); - printf(" --verbose Verbose output\n"); - printf(" --dump-asm Assembler output\n"); - printf(" --dump-hex Hexadecimal output (relocated, only for host arch)\n"); + printf(" --help Show usage only\n"); + printf(" --arch= Select architecture to run ('all' by default)\n"); + printf(" --filter= Use a filter to restrict which test is called\n"); + printf(" --verbose Verbose output\n"); + printf(" --dump-asm Assembler output\n"); + printf(" --dump-hex Hexadecimal output (relocated, only for host arch)\n"); printf("\n"); } @@ -82,6 +84,13 @@ public: }; #endif // !ASMJIT_NO_LOGGING +bool TestApp::shouldRun(const TestCase* tc) { + if (!_filter) + return true; + + return strstr(tc->name(), _filter) != nullptr; +} + int TestApp::run() { #ifndef ASMJIT_NO_LOGGING FormatOptions formatOptions; @@ -120,6 +129,11 @@ int TestApp::run() { double finalizeTime = 0; for (std::unique_ptr& test : _tests) { + if (!shouldRun(test.get())) + continue; + + _numTests++; + for (uint32_t pass = 0; pass < 2; pass++) { bool runnable = false; CodeHolder code; @@ -306,7 +320,7 @@ int TestApp::run() { printf(" [Output]\n"); printf(" Returned: %s\n", result.data()); printf(" Expected: %s\n", expect.data()); - _nFailed++; + _numFailed++; } if (_dumpAsm) @@ -321,7 +335,7 @@ int TestApp::run() { printStringLoggerContent(); printf(" [Status]\n"); printf(" ERROR 0x%08X: %s\n", unsigned(err), errorHandler._message.data()); - _nFailed++; + _numFailed++; } } #endif // !ASMJIT_NO_JIT @@ -330,7 +344,7 @@ int TestApp::run() { if (err) { printf(" [Status]\n"); printf(" ERROR 0x%08X: %s\n", unsigned(err), errorHandler._message.data()); - _nFailed++; + _numFailed++; } else { printf("%s[COMPILE OK]\n", statusSeparator); @@ -352,12 +366,12 @@ int TestApp::run() { printf(" FinalizeTime: %.2f ms\n", finalizeTime); printf("\n"); - if (_nFailed == 0) - printf("** SUCCESS: All %u tests passed **\n", unsigned(_tests.size())); + if (_numFailed == 0) + printf("** SUCCESS: All %u tests passed **\n", _numTests); else - printf("** FAILURE: %u of %u tests failed **\n", _nFailed, unsigned(_tests.size())); + printf("** FAILURE: %u of %u tests failed **\n", _numFailed, _numTests); - return _nFailed == 0 ? 0 : 1; + return _numFailed == 0 ? 0 : 1; } int main(int argc, char* argv[]) { diff --git a/test/asmjit_test_compiler.h b/test/asmjit_test_compiler.h index 79414d0..433d479 100644 --- a/test/asmjit_test_compiler.h +++ b/test/asmjit_test_compiler.h @@ -52,12 +52,14 @@ public: std::vector> _tests; const char* _arch = nullptr; + const char* _filter = nullptr; bool _helpOnly = false; bool _verbose = false; bool _dumpAsm = false; bool _dumpHex = false; - unsigned _nFailed = 0; + unsigned _numTests = 0; + unsigned _numFailed = 0; size_t _outputSize = 0; TestApp() noexcept @@ -73,6 +75,8 @@ public: int handleArgs(int argc, const char* const* argv); void showInfo(); + + bool shouldRun(const TestCase* tc); int run(); }; diff --git a/test/asmjit_test_compiler_x86.cpp b/test/asmjit_test_compiler_x86.cpp index a0ca9fc..54442ef 100644 --- a/test/asmjit_test_compiler_x86.cpp +++ b/test/asmjit_test_compiler_x86.cpp @@ -203,7 +203,7 @@ public: result.assignFormat("ret={%u, %u}", resultRet >> 28, resultRet & 0x0FFFFFFFu); expect.assignFormat("ret={%u, %u}", expectRet >> 28, expectRet & 0x0FFFFFFFu); - return resultRet == expectRet; + return result == expect; } uint32_t _argCount; @@ -437,7 +437,7 @@ public: result.assignFormat("ret={%d}", resultRet); expect.assignFormat("ret={%d}", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -912,7 +912,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -1192,7 +1192,7 @@ public: result.assignFormat("result=%d", resultRet); expect.assignFormat("result=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -1288,7 +1288,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -1373,7 +1373,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -1409,7 +1409,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -1860,7 +1860,7 @@ public: result.assignFormat("ret={%g}", resultRet); expect.assignFormat("ret={%g}", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -1911,7 +1911,7 @@ public: result.assignFormat("ret={%g}", resultRet); expect.assignFormat("ret={%g}", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -2001,7 +2001,7 @@ public: result.assignFormat("ret={%g}", resultRet); expect.assignFormat("ret={%g}", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -2040,7 +2040,7 @@ public: result.assignFormat("ret={%g}", resultRet); expect.assignFormat("ret={%g}", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -2075,7 +2075,7 @@ public: result.assignFormat("ret={%g}", resultRet); expect.assignFormat("ret={%g}", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -2114,7 +2114,7 @@ public: result.assignFormat("ret={%g}", resultRet); expect.assignFormat("ret={%g}", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -2181,7 +2181,7 @@ public: result.assignInt(resultRet); expect.assignInt(expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -2406,6 +2406,47 @@ public: } }; +// x86::Compiler - X86Test_FuncArgInt8 +// =================================== + +class X86Test_FuncArgInt8 : public X86TestCase { +public: + X86Test_FuncArgInt8() : X86TestCase("FuncArgInt8") {} + + static void add(TestApp& app) { + app.add(new X86Test_FuncArgInt8()); + } + + virtual void compile(x86::Compiler& cc) { + x86::Gp v0 = cc.newUInt32("v0"); + x86::Gp v1 = cc.newUInt32("v1"); + + FuncNode* funcNode = cc.addFunc(FuncSignature::build()); + funcNode->setArg(0, v0); + funcNode->setArg(1, v1); + + cc.add(v0, v1); + + cc.ret(v0); + cc.endFunc(); + } + + virtual bool run(void* _func, String& result, String& expect) { + typedef uint32_t (*Func)(uint8_t, uint8_t, uint32_t); + Func func = ptr_as_func(_func); + + uint32_t arg = uint32_t(uintptr_t(_func) & 0xFFFFFFFF); + + unsigned resultRet = func(uint8_t(arg & 0xFF), uint8_t(arg & 0xFF), arg); + unsigned expectRet = (arg & 0xFF) * 2; + + result.assignFormat("ret=%u", resultRet); + expect.assignFormat("ret=%u", expectRet); + + return result == expect; + } +}; + // x86::Compiler - X86Test_FuncCallBase1 // ===================================== @@ -2454,7 +2495,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } static int calledFunc(int a, int b, int c) { return (a + b) * c; } @@ -2537,7 +2578,7 @@ public: result.assignInt(resultRet); expect.assignInt(expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -2585,7 +2626,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } // STDCALL function that is called inside the generated one. @@ -2635,7 +2676,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } // FASTCALL function that is called inside the generated one. @@ -2906,7 +2947,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -2963,7 +3004,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -3016,7 +3057,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -3082,7 +3123,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -3148,7 +3189,7 @@ public: result.assignFormat("ret={%08X %08X %08X %08X %08X}", resultRet, inputs[0], inputs[1], inputs[2], inputs[3]); expect.assignFormat("ret={%08X %08X %08X %08X %08X}", expectRet, outputs[0], outputs[1], outputs[2], outputs[3]); - return resultRet == expectRet; + return result == expect; } }; @@ -3198,7 +3239,7 @@ public: result.assignFormat("ret=%g", resultRet); expect.assignFormat("ret=%g", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -3247,7 +3288,7 @@ public: result.assignFormat("ret=%g", resultRet); expect.assignFormat("ret=%g", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -3403,7 +3444,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -3454,7 +3495,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -3510,7 +3551,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } static int calledFunc(size_t n, ...) { @@ -3578,7 +3619,7 @@ public: result.assignFormat("ret=%f", resultRet); expect.assignFormat("ret=%f", expectRet); - return resultRet == expectRet; + return result == expect; } static double calledFunc(size_t n, ...) { @@ -3639,7 +3680,7 @@ public: result.assignFormat("ret=%llu", (unsigned long long)resultRet); expect.assignFormat("ret=%llu", (unsigned long long)expectRet); - return resultRet == expectRet; + return result == expect; } static double calledFunc(size_t n, ...) { @@ -3701,7 +3742,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -3749,7 +3790,7 @@ public: result.assignFormat("ret=%g", resultRet); expect.assignFormat("ret=%g", expectRet); - return resultRet == expectRet; + return result == expect; } static double op(double a) { return a * a; } @@ -3802,7 +3843,7 @@ public: result.assignFormat("ret=%g", resultRet); expect.assignFormat("ret=%g", expectRet); - return resultRet == expectRet; + return result == expect; } static double op(double a) { return a * a; } @@ -3849,7 +3890,7 @@ public: result.assignFormat("ret=%g", resultRet); expect.assignFormat("ret=%g", expectRet); - return resultRet == expectRet; + return result == expect; } static double calledFunc() { return 3.14; } @@ -3907,7 +3948,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } static void calledFunc() {} @@ -3967,7 +4008,7 @@ public: result.assignFormat("ret=%u", resultRet); expect.assignFormat("ret=%u", expectRet); - return resultRet == expectRet; + return result == expect; } static uint32_t calledFunc(uint32_t x) { return x + 1; } @@ -4129,7 +4170,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -4171,7 +4212,7 @@ public: result.assignFormat("ret=%d", resultRet); expect.assignFormat("ret=%d", expectRet); - return resultRet == expectRet; + return result == expect; } }; @@ -4377,7 +4418,7 @@ public: result.assignFormat("ret={%d}", resultRet); expect.assignFormat("ret={%d}", expectRet); - return resultRet == expectRet; + return result == expect; } static void ASMJIT_FASTCALL handler() { longjmp(globalJmpBuf, 1); } @@ -4437,6 +4478,9 @@ void compiler_add_x86_tests(TestApp& app) { app.addT(); app.addT(); + // Function arguments handling tests. + app.addT(); + // Function call tests. app.addT(); app.addT();