diff --git a/src/app/test/asmjit_test_x86.cpp b/src/app/test/asmjit_test_x86.cpp index f4a9f19..2109e7c 100644 --- a/src/app/test/asmjit_test_x86.cpp +++ b/src/app/test/asmjit_test_x86.cpp @@ -2501,9 +2501,58 @@ struct X86Test_CallMisc2 : public X86Test { static double op(double a) { return a * a; } }; -void test() { -} +// ============================================================================ +// [X86Test_CallMisc3] +// ============================================================================ +struct X86Test_CallMisc3 : public X86Test { + X86Test_CallMisc3() : X86Test("[Call] Misc #3") {} + + static void add(PodVector& tests) { + tests.append(new X86Test_CallMisc3()); + } + + virtual void compile(X86Compiler& c) { + X86FuncNode* func = c.addFunc(kFuncConvHost, FuncBuilder1()); + + X86GpVar p(c, kVarTypeIntPtr, "p"); + X86GpVar fn(c, kVarTypeIntPtr, "fn"); + + X86XmmVar arg(c, kX86VarTypeXmmSd, "arg"); + X86XmmVar ret(c, kX86VarTypeXmmSd, "ret"); + + c.setArg(0, p); + c.movsd(arg, x86::ptr(p)); + c.mov(fn, imm_ptr((void*)op)); + + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder1()); + call->setArg(0, arg); + call->setRet(0, ret); + + c.xorps(arg, arg); + c.subsd(arg, ret); + + c.ret(arg); + c.endFunc(); + } + + virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) { + typedef double (*Func)(const double*); + Func func = asmjit_cast(_func); + + double arg = 2; + + double resultRet = func(&arg); + double expectRet = -op(arg); + + result.setFormat("ret=%g", resultRet); + expect.setFormat("ret=%g", expectRet); + + return resultRet == expectRet; + } + + static double op(double a) { return a * a; } +}; // ============================================================================ // [X86Test_ConstPoolBase] @@ -2633,6 +2682,7 @@ X86TestSuite::X86TestSuite() : ADD_TEST(X86Test_CallRecursive); ADD_TEST(X86Test_CallMisc1); ADD_TEST(X86Test_CallMisc2); + ADD_TEST(X86Test_CallMisc3); ADD_TEST(X86Test_ConstPoolBase); } diff --git a/src/asmjit/x86/x86context.cpp b/src/asmjit/x86/x86context.cpp index e36ff03..9e5cfdd 100644 --- a/src/asmjit/x86/x86context.cpp +++ b/src/asmjit/x86/x86context.cpp @@ -4414,6 +4414,8 @@ ASMJIT_INLINE void X86CallAlloc::ret() { uint32_t vf = _x86VarInfo[vd->getType()].getDesc(); uint32_t regIndex = ret.getRegIndex(); + // TODO: Is it necessary to check for kInvalidReg when unusing if it's + // checked by unuse<> as well? switch (vd->getClass()) { case kX86RegClassGp: ASMJIT_ASSERT(x86VarTypeToClass(ret.getVarType()) == vd->getClass()); @@ -4435,15 +4437,13 @@ ASMJIT_INLINE void X86CallAlloc::ret() { case kX86RegClassXyz: if (ret.getVarType() == kVarTypeFp32 || ret.getVarType() == kVarTypeFp64) { - if (vd->getRegIndex() != kInvalidReg) - _context->unuse(vd, kVarStateMem); - X86Mem m = _context->getVarMem(vd); m.setSize( (vf & kVarFlagSp) ? 4 : (vf & kVarFlagDp) ? 8 : (ret.getVarType() == kVarTypeFp32) ? 4 : 8); + _context->unuse(vd, kVarStateMem); _compiler->fstp(m); } else {