mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 20:44:37 +03:00
Mark clobbered registers when allocating "call" (X86Compiler)
This commit is contained in:
@@ -161,7 +161,7 @@ struct ConstPool {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_Visit:
|
_Visit:
|
||||||
visitor.visit(node);
|
visitor.visit(node);
|
||||||
link = node->_link[1];
|
link = node->_link[1];
|
||||||
|
|
||||||
|
|||||||
@@ -371,14 +371,13 @@ struct Utils {
|
|||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
static ASMJIT_INLINE uint32_t bitCountSlow(uint32_t x) noexcept {
|
static ASMJIT_INLINE uint32_t bitCountSlow(uint32_t x) noexcept {
|
||||||
|
// From: http://graphics.stanford.edu/~seander/bithacks.html
|
||||||
x = x - ((x >> 1) & 0x55555555U);
|
x = x - ((x >> 1) & 0x55555555U);
|
||||||
x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U);
|
x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U);
|
||||||
return (((x + (x >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24;
|
return (((x + (x >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get count of bits in `x`.
|
//! Get count of bits in `x`.
|
||||||
//!
|
|
||||||
//! Taken from http://graphics.stanford.edu/~seander/bithacks.html .
|
|
||||||
static ASMJIT_INLINE uint32_t bitCount(uint32_t x) noexcept {
|
static ASMJIT_INLINE uint32_t bitCount(uint32_t x) noexcept {
|
||||||
#if ASMJIT_CC_GCC || ASMJIT_CC_CLANG
|
#if ASMJIT_CC_GCC || ASMJIT_CC_CLANG
|
||||||
return __builtin_popcount(x);
|
return __builtin_popcount(x);
|
||||||
|
|||||||
@@ -4475,6 +4475,7 @@ ASMJIT_INLINE void X86CallAlloc::alloc() {
|
|||||||
}
|
}
|
||||||
else if (aIndex != kInvalidReg) {
|
else if (aIndex != kInvalidReg) {
|
||||||
_context->move<C>(aVd, bIndex);
|
_context->move<C>(aVd, bIndex);
|
||||||
|
_context->_clobberedRegs.or_(C, Utils::mask(bIndex));
|
||||||
|
|
||||||
aVa->orFlags(kVarAttrAllocRDone);
|
aVa->orFlags(kVarAttrAllocRDone);
|
||||||
addVaDone(C);
|
addVaDone(C);
|
||||||
@@ -4484,6 +4485,7 @@ ASMJIT_INLINE void X86CallAlloc::alloc() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_context->alloc<C>(aVd, bIndex);
|
_context->alloc<C>(aVd, bIndex);
|
||||||
|
_context->_clobberedRegs.or_(C, Utils::mask(bIndex));
|
||||||
|
|
||||||
aVa->orFlags(kVarAttrAllocRDone);
|
aVa->orFlags(kVarAttrAllocRDone);
|
||||||
addVaDone(C);
|
addVaDone(C);
|
||||||
|
|||||||
@@ -2670,6 +2670,59 @@ struct X86Test_CallMisc4 : public X86Test {
|
|||||||
static double calledFunc() { return 3.14; }
|
static double calledFunc() { return 3.14; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [X86Test_CallMisc5]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// The register allocator should clobber the register used by the `call` itself.
|
||||||
|
struct X86Test_CallMisc5 : public X86Test {
|
||||||
|
X86Test_CallMisc5() : X86Test("[Call] Misc #5") {}
|
||||||
|
|
||||||
|
static void add(PodVector<X86Test*>& tests) {
|
||||||
|
tests.append(new X86Test_CallMisc5());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(X86Compiler& c) {
|
||||||
|
X86FuncNode* func = c.addFunc(FuncBuilder1<int, void>(kCallConvHost));
|
||||||
|
|
||||||
|
X86GpVar vars[16];
|
||||||
|
uint32_t i, regCount = c.getRegCount().getGp();
|
||||||
|
|
||||||
|
for (i = 0; i < regCount; i++) {
|
||||||
|
if (i == kX86RegIndexBp || i == kX86RegIndexSp)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vars[i] = c.newInt32("v%u", static_cast<unsigned int>(i));
|
||||||
|
c.mov(vars[i], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
X86CallNode* call = c.call(imm_ptr(calledFunc), FuncBuilder0<void>(kCallConvHost));
|
||||||
|
|
||||||
|
for (i = 1; i < regCount; i++) {
|
||||||
|
if (vars[i].isInitialized())
|
||||||
|
c.add(vars[0], vars[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ret(vars[0]);
|
||||||
|
c.endFunc();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) {
|
||||||
|
typedef int (*Func)(void);
|
||||||
|
Func func = asmjit_cast<Func>(_func);
|
||||||
|
|
||||||
|
int resultRet = func();
|
||||||
|
int expectRet = sizeof(void*) == 4 ? 6 : 14;
|
||||||
|
|
||||||
|
result.setFormat("ret=%d", resultRet);
|
||||||
|
expect.setFormat("ret=%d", expectRet);
|
||||||
|
|
||||||
|
return resultRet == expectRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void calledFunc() {}
|
||||||
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [X86Test_MiscConstPool]
|
// [X86Test_MiscConstPool]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -3017,6 +3070,7 @@ X86TestSuite::X86TestSuite() :
|
|||||||
ADD_TEST(X86Test_CallMisc2);
|
ADD_TEST(X86Test_CallMisc2);
|
||||||
ADD_TEST(X86Test_CallMisc3);
|
ADD_TEST(X86Test_CallMisc3);
|
||||||
ADD_TEST(X86Test_CallMisc4);
|
ADD_TEST(X86Test_CallMisc4);
|
||||||
|
ADD_TEST(X86Test_CallMisc5);
|
||||||
|
|
||||||
// Misc.
|
// Misc.
|
||||||
ADD_TEST(X86Test_MiscConstPool);
|
ADD_TEST(X86Test_MiscConstPool);
|
||||||
|
|||||||
Reference in New Issue
Block a user