mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-18 13:04:36 +03:00
Fixed bug in manual variable spill() and added a test-case for that.
Minor changes in annotations.
This commit is contained in:
@@ -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<X86Test*>& tests) {
|
||||||
|
tests.append(new X86Test_AllocUseMem());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(Compiler& c) {
|
||||||
|
c.addFunc(kFuncConvHost, FuncBuilder2<int, int, int>());
|
||||||
|
|
||||||
|
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>(_func);
|
||||||
|
|
||||||
|
int resultRet = func(10, 20);
|
||||||
|
int expectRet = 20;
|
||||||
|
|
||||||
|
result.setFormat("ret=%d", resultRet);
|
||||||
|
expect.setFormat("ret=%d", expectRet);
|
||||||
|
|
||||||
|
return resultRet == expectRet;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [X86Test_AllocMany1]
|
// [X86Test_AllocMany1]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -2284,6 +2336,7 @@ X86TestSuite::X86TestSuite() :
|
|||||||
// Alloc.
|
// Alloc.
|
||||||
ADD_TEST(X86Test_AllocBase);
|
ADD_TEST(X86Test_AllocBase);
|
||||||
ADD_TEST(X86Test_AllocManual);
|
ADD_TEST(X86Test_AllocManual);
|
||||||
|
ADD_TEST(X86Test_AllocUseMem);
|
||||||
ADD_TEST(X86Test_AllocMany1);
|
ADD_TEST(X86Test_AllocMany1);
|
||||||
ADD_TEST(X86Test_AllocMany2);
|
ADD_TEST(X86Test_AllocMany2);
|
||||||
ADD_TEST(X86Test_AllocImul1);
|
ADD_TEST(X86Test_AllocImul1);
|
||||||
|
|||||||
@@ -2777,11 +2777,11 @@ static void X86X64Context_annotateVariable(X86X64Context* self,
|
|||||||
|
|
||||||
const char* name = vd->getName();
|
const char* name = vd->getName();
|
||||||
if (name != NULL && name[0] != '\0') {
|
if (name != NULL && name[0] != '\0') {
|
||||||
sb._appendString(name);
|
sb.appendString(name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sb._appendChar('v');
|
sb.appendChar('v');
|
||||||
sb._appendUInt32(vd->getId() & kOperandIdNum);
|
sb.appendUInt(vd->getId() & kOperandIdNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2795,7 +2795,7 @@ static void X86X64Context_annotateOperand(X86X64Context* self,
|
|||||||
const Mem* m = static_cast<const Mem*>(op);
|
const Mem* m = static_cast<const Mem*>(op);
|
||||||
bool isAbsolute = false;
|
bool isAbsolute = false;
|
||||||
|
|
||||||
sb._appendChar('[');
|
sb.appendChar('[');
|
||||||
switch (m->getMemType()) {
|
switch (m->getMemType()) {
|
||||||
case kMemTypeBaseIndex:
|
case kMemTypeBaseIndex:
|
||||||
case kMemTypeStackIndex:
|
case kMemTypeStackIndex:
|
||||||
@@ -2816,12 +2816,12 @@ static void X86X64Context_annotateOperand(X86X64Context* self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m->hasIndex()) {
|
if (m->hasIndex()) {
|
||||||
sb._appendChar('+');
|
sb.appendChar('+');
|
||||||
X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getIndex()));
|
X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getIndex()));
|
||||||
|
|
||||||
if (m->getShift()) {
|
if (m->getShift()) {
|
||||||
sb._appendChar('*');
|
sb.appendChar('*');
|
||||||
sb._appendChar("1248"[m->getShift() & 3]);
|
sb.appendChar("1248"[m->getShift() & 3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2835,17 +2835,17 @@ static void X86X64Context_annotateOperand(X86X64Context* self,
|
|||||||
prefix = '-';
|
prefix = '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
sb._appendChar(prefix);
|
sb.appendChar(prefix);
|
||||||
/*
|
/*
|
||||||
if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) {
|
if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) {
|
||||||
sb._appendString("0x", 2);
|
sb.appendString("0x", 2);
|
||||||
base = 16;
|
base = 16;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
sb.appendUInt(static_cast<uint32_t>(dispOffset), base);
|
sb.appendUInt(static_cast<uint32_t>(dispOffset), base);
|
||||||
}
|
}
|
||||||
|
|
||||||
sb._appendChar(']');
|
sb.appendChar(']');
|
||||||
}
|
}
|
||||||
else if (op->isImm()) {
|
else if (op->isImm()) {
|
||||||
const Imm* i = static_cast<const Imm*>(op);
|
const Imm* i = static_cast<const Imm*>(op);
|
||||||
@@ -2861,22 +2861,19 @@ static void X86X64Context_annotateOperand(X86X64Context* self,
|
|||||||
sb.appendFormat("L%u", op->getId());
|
sb.appendFormat("L%u", op->getId());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sb._appendString("None", 4);
|
sb.appendString("None", 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool X86X64Context_annotateInstruction(X86X64Context* self,
|
static bool X86X64Context_annotateInstruction(X86X64Context* self,
|
||||||
StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) {
|
StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) {
|
||||||
|
|
||||||
if (!sb.reserve(sb.getLength() + 128))
|
sb.appendString(_instInfo[code].getName());
|
||||||
return false;
|
|
||||||
|
|
||||||
sb._appendString(_instInfo[code].getName());
|
|
||||||
for (uint32_t i = 0; i < opCount; i++) {
|
for (uint32_t i = 0; i < opCount; i++) {
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
sb._appendChar(' ');
|
sb.appendChar(' ');
|
||||||
else
|
else
|
||||||
sb._appendString(", ", 2);
|
sb.appendString(", ", 2);
|
||||||
X86X64Context_annotateOperand(self, sb, &opList[i]);
|
X86X64Context_annotateOperand(self, sb, &opList[i]);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -2888,8 +2885,9 @@ Error X86X64Context::annotate() {
|
|||||||
BaseNode* node_ = func;
|
BaseNode* node_ = func;
|
||||||
BaseNode* end = func->getEnd();
|
BaseNode* end = func->getEnd();
|
||||||
|
|
||||||
StringBuilderT<128> sb;
|
|
||||||
Zone& sa = _compiler->_stringAllocator;
|
Zone& sa = _compiler->_stringAllocator;
|
||||||
|
StringBuilderT<128> sb;
|
||||||
|
|
||||||
uint32_t maxLen = 0;
|
uint32_t maxLen = 0;
|
||||||
|
|
||||||
while (node_ != end) {
|
while (node_ != end) {
|
||||||
@@ -3475,6 +3473,12 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() {
|
|||||||
occupied |= regMask;
|
occupied |= regMask;
|
||||||
continue;
|
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().
|
// 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];
|
VarData* vd = sVars[i];
|
||||||
ASMJIT_ASSERT(vd != NULL);
|
ASMJIT_ASSERT(vd != NULL);
|
||||||
ASMJIT_ASSERT(vd->getVa() == NULL);
|
ASMJIT_ASSERT(vd->getVa() == NULL || (vd->getVa()->getFlags() & kVarAttrInOutReg) == 0);
|
||||||
|
|
||||||
if (vd->isModified() && availableRegs) {
|
if (vd->isModified() && availableRegs) {
|
||||||
uint32_t m = guessSpill<C>(vd, availableRegs);
|
uint32_t m = guessSpill<C>(vd, availableRegs);
|
||||||
|
|||||||
Reference in New Issue
Block a user