From 2bf1af0dde5116c3a312690c3364c84209736b76 Mon Sep 17 00:00:00 2001 From: kobalicekp Date: Sat, 22 Mar 2014 21:28:56 +0100 Subject: [PATCH] Fixed bug in manual variable spill() and added a test-case for that. Minor changes in annotations. --- src/app/test/testx86.cpp | 53 +++++++++++++++++++++++++++++++++++ src/asmjit/x86/x86context.cpp | 42 ++++++++++++++------------- 2 files changed, 76 insertions(+), 19 deletions(-) diff --git a/src/app/test/testx86.cpp b/src/app/test/testx86.cpp index bd79638..ff5c06b 100644 --- a/src/app/test/testx86.cpp +++ b/src/app/test/testx86.cpp @@ -396,6 +396,58 @@ struct X86Test_AllocManual : public X86Test { } }; +// ============================================================================ +// [X86Test_AllocUseMem] +// ============================================================================ + +struct X86Test_AllocUseMem : public X86Test { + X86Test_AllocUseMem() : X86Test("[Alloc] Alloc/use mem") {} + + static void add(PodVector& tests) { + tests.append(new X86Test_AllocUseMem()); + } + + virtual void compile(Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder2()); + + GpVar iIdx(c, kVarTypeInt32); + GpVar iEnd(c, kVarTypeInt32); + + GpVar aIdx(c, kVarTypeInt32); + GpVar aEnd(c, kVarTypeInt32); + + Label L_1(c); + + c.setArg(0, aIdx); + c.setArg(1, aEnd); + + c.mov(iIdx, aIdx); + c.mov(iEnd, aEnd); + c.spill(iEnd); + + c.bind(L_1); + c.inc(iIdx); + c.cmp(iIdx, iEnd.m()); + c.jne(L_1); + + c.ret(iIdx); + c.endFunc(); + } + + virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) { + typedef int (*Func)(int, int); + Func func = asmjit_cast(_func); + + int resultRet = func(10, 20); + int expectRet = 20; + + result.setFormat("ret=%d", resultRet); + expect.setFormat("ret=%d", expectRet); + + return resultRet == expectRet; + } +}; + // ============================================================================ // [X86Test_AllocMany1] // ============================================================================ @@ -2284,6 +2336,7 @@ X86TestSuite::X86TestSuite() : // Alloc. ADD_TEST(X86Test_AllocBase); ADD_TEST(X86Test_AllocManual); + ADD_TEST(X86Test_AllocUseMem); ADD_TEST(X86Test_AllocMany1); ADD_TEST(X86Test_AllocMany2); ADD_TEST(X86Test_AllocImul1); diff --git a/src/asmjit/x86/x86context.cpp b/src/asmjit/x86/x86context.cpp index 460636f..f987de6 100644 --- a/src/asmjit/x86/x86context.cpp +++ b/src/asmjit/x86/x86context.cpp @@ -2777,11 +2777,11 @@ static void X86X64Context_annotateVariable(X86X64Context* self, const char* name = vd->getName(); if (name != NULL && name[0] != '\0') { - sb._appendString(name); + sb.appendString(name); } else { - sb._appendChar('v'); - sb._appendUInt32(vd->getId() & kOperandIdNum); + sb.appendChar('v'); + sb.appendUInt(vd->getId() & kOperandIdNum); } } @@ -2795,7 +2795,7 @@ static void X86X64Context_annotateOperand(X86X64Context* self, const Mem* m = static_cast(op); bool isAbsolute = false; - sb._appendChar('['); + sb.appendChar('['); switch (m->getMemType()) { case kMemTypeBaseIndex: case kMemTypeStackIndex: @@ -2816,12 +2816,12 @@ static void X86X64Context_annotateOperand(X86X64Context* self, } if (m->hasIndex()) { - sb._appendChar('+'); + sb.appendChar('+'); X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getIndex())); if (m->getShift()) { - sb._appendChar('*'); - sb._appendChar("1248"[m->getShift() & 3]); + sb.appendChar('*'); + sb.appendChar("1248"[m->getShift() & 3]); } } @@ -2835,17 +2835,17 @@ static void X86X64Context_annotateOperand(X86X64Context* self, prefix = '-'; } - sb._appendChar(prefix); + sb.appendChar(prefix); /* if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) { - sb._appendString("0x", 2); + sb.appendString("0x", 2); base = 16; } */ sb.appendUInt(static_cast(dispOffset), base); } - sb._appendChar(']'); + sb.appendChar(']'); } else if (op->isImm()) { const Imm* i = static_cast(op); @@ -2861,22 +2861,19 @@ static void X86X64Context_annotateOperand(X86X64Context* self, sb.appendFormat("L%u", op->getId()); } else { - sb._appendString("None", 4); + sb.appendString("None", 4); } } static bool X86X64Context_annotateInstruction(X86X64Context* self, StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) { - if (!sb.reserve(sb.getLength() + 128)) - return false; - - sb._appendString(_instInfo[code].getName()); + sb.appendString(_instInfo[code].getName()); for (uint32_t i = 0; i < opCount; i++) { if (i == 0) - sb._appendChar(' '); + sb.appendChar(' '); else - sb._appendString(", ", 2); + sb.appendString(", ", 2); X86X64Context_annotateOperand(self, sb, &opList[i]); } return true; @@ -2888,8 +2885,9 @@ Error X86X64Context::annotate() { BaseNode* node_ = func; BaseNode* end = func->getEnd(); - StringBuilderT<128> sb; Zone& sa = _compiler->_stringAllocator; + StringBuilderT<128> sb; + uint32_t maxLen = 0; while (node_ != end) { @@ -3475,6 +3473,12 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { occupied |= regMask; continue; } + else if ((vaFlags & kVarAttrInOutMem) != 0) { + uint32_t regIndex = vd->getRegIndex(); + if (regIndex != kInvalidReg && (vaFlags & kVarAttrInOutMem) != kVarAttrOutMem) { + willSpill |= IntUtil::mask(regIndex); + } + } } // Set calculated masks back to the allocator; needed by spill() and alloc(). @@ -3505,7 +3509,7 @@ ASMJIT_INLINE void X86X64VarAlloc::spill() { VarData* vd = sVars[i]; ASMJIT_ASSERT(vd != NULL); - ASMJIT_ASSERT(vd->getVa() == NULL); + ASMJIT_ASSERT(vd->getVa() == NULL || (vd->getVa()->getFlags() & kVarAttrInOutReg) == 0); if (vd->isModified() && availableRegs) { uint32_t m = guessSpill(vd, availableRegs);