TestX86 - Added more tests (float / double arguments)

X86Func - Fixed Win64 float arguments handling.
This commit is contained in:
kobalicekp
2014-03-06 00:33:30 +01:00
parent f77f792cc4
commit 1abb041ecb
3 changed files with 144 additions and 38 deletions

View File

@@ -1124,28 +1124,25 @@ struct X86Test_AllocIfElse4 : public X86Test {
}; };
// ============================================================================ // ============================================================================
// [X86Test_AllocArgs] // [X86Test_AllocArgsIntPtr]
// ============================================================================ // ============================================================================
struct X86Test_AllocArgs : public X86Test { struct X86Test_AllocArgsIntPtr : public X86Test {
X86Test_AllocArgs() : X86Test("[Alloc] Args") {} X86Test_AllocArgsIntPtr() : X86Test("[Alloc] Args-IntPtr") {}
static void add(PodVector<X86Test*>& tests) { static void add(PodVector<X86Test*>& tests) {
tests.append(new X86Test_AllocArgs()); tests.append(new X86Test_AllocArgsIntPtr());
} }
virtual void compile(Compiler& c) { virtual void compile(Compiler& c) {
c.addFunc(kFuncConvHost, c.addFunc(kFuncConvHost,
FuncBuilder8<FnVoid, void*, void*, void*, void*, void*, void*, void*, void*>()); FuncBuilder8<FnVoid, void*, void*, void*, void*, void*, void*, void*, void*>());
GpVar var[8];
uint32_t i; uint32_t i;
GpVar var[8];
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
var[i] = c.newGpVar(); var[i] = c.newGpVar();
}
for (i = 0; i < 8; i++) {
c.setArg(i, var[i]); c.setArg(i, var[i]);
} }
@@ -1185,6 +1182,114 @@ struct X86Test_AllocArgs : public X86Test {
} }
}; };
// ============================================================================
// [X86Test_AllocArgsFloat]
// ============================================================================
struct X86Test_AllocArgsFloat : public X86Test {
X86Test_AllocArgsFloat() : X86Test("[Alloc] Args-Float") {}
static void add(PodVector<X86Test*>& tests) {
tests.append(new X86Test_AllocArgsFloat());
}
virtual void compile(Compiler& c) {
c.addFunc(kFuncConvHost,
FuncBuilder8<FnVoid, float, float, float, float, float, float, float, void*>());
uint32_t i;
XmmVar xv[7];
GpVar p(c);
for (i = 0; i < 7; i++) {
xv[i] = c.newXmmVar(kVarTypeXmmSs);
c.setArg(i, xv[i]);
}
c.setArg(7, p);
c.addss(xv[0], xv[1]);
c.addss(xv[0], xv[2]);
c.addss(xv[0], xv[3]);
c.addss(xv[0], xv[4]);
c.addss(xv[0], xv[5]);
c.addss(xv[0], xv[6]);
c.movss(ptr(p), xv[0]);
c.endFunc();
}
virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) {
typedef void (*Func)(float, float, float, float, float, float, float, float*);
Func func = asmjit_cast<Func>(_func);
float resultRet;
float expectRet = 1.0f + 2.0f + 3.0f + 4.0f + 5.0f + 6.0f + 7.0f;
func(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, &resultRet);
result.setFormat("ret={%g}", resultRet);
expect.setFormat("ret={%g}", expectRet);
return resultRet == expectRet;
}
};
// ============================================================================
// [X86Test_AllocArgsDouble]
// ============================================================================
struct X86Test_AllocArgsDouble : public X86Test {
X86Test_AllocArgsDouble() : X86Test("[Alloc] Args-Float") {}
static void add(PodVector<X86Test*>& tests) {
tests.append(new X86Test_AllocArgsDouble());
}
virtual void compile(Compiler& c) {
c.addFunc(kFuncConvHost,
FuncBuilder8<FnVoid, double, double, double, double, double, double, double, void*>());
uint32_t i;
XmmVar xv[7];
GpVar p(c);
for (i = 0; i < 7; i++) {
xv[i] = c.newXmmVar(kVarTypeXmmSd);
c.setArg(i, xv[i]);
}
c.setArg(7, p);
c.addsd(xv[0], xv[1]);
c.addsd(xv[0], xv[2]);
c.addsd(xv[0], xv[3]);
c.addsd(xv[0], xv[4]);
c.addsd(xv[0], xv[5]);
c.addsd(xv[0], xv[6]);
c.movsd(ptr(p), xv[0]);
c.endFunc();
}
virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) {
typedef void (*Func)(double, double, double, double, double, double, double, double*);
Func func = asmjit_cast<Func>(_func);
double resultRet;
double expectRet = 1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0;
func(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, &resultRet);
result.setFormat("ret={%g}", resultRet);
expect.setFormat("ret={%g}", expectRet);
return resultRet == expectRet;
}
};
// ============================================================================ // ============================================================================
// [X86Test_AllocStack] // [X86Test_AllocStack]
// ============================================================================ // ============================================================================
@@ -2111,7 +2216,9 @@ X86TestSuite::X86TestSuite() :
ADD_TEST(X86Test_AllocIfElse2); ADD_TEST(X86Test_AllocIfElse2);
ADD_TEST(X86Test_AllocIfElse3); ADD_TEST(X86Test_AllocIfElse3);
ADD_TEST(X86Test_AllocIfElse4); ADD_TEST(X86Test_AllocIfElse4);
ADD_TEST(X86Test_AllocArgs); ADD_TEST(X86Test_AllocArgsIntPtr);
ADD_TEST(X86Test_AllocArgsFloat);
ADD_TEST(X86Test_AllocArgsDouble);
ADD_TEST(X86Test_AllocStack); ADD_TEST(X86Test_AllocStack);
ADD_TEST(X86Test_AllocMemcpy); ADD_TEST(X86Test_AllocMemcpy);
ADD_TEST(X86Test_AllocBlend); ADD_TEST(X86Test_AllocBlend);

View File

@@ -3838,16 +3838,6 @@ static ASMJIT_INLINE uint32_t x86VarTypeToClass(uint32_t vType) {
return _varInfo[vType].getClass(); return _varInfo[vType].getClass();
} }
static ASMJIT_INLINE bool x86VarIsInt(uint32_t vType) {
ASMJIT_ASSERT(vType < kVarTypeCount);
return IntUtil::inInterval<uint32_t>(vType, _kVarTypeIntStart, _kVarTypeIntEnd);
}
static ASMJIT_INLINE bool x86VarIsFloat(uint32_t vType) {
ASMJIT_ASSERT(vType < kVarTypeCount);
return (_varInfo[vType].getDesc() & (kVarDescSp | kVarDescDp)) != 0;
}
//! @} //! @}
} // x86x64 namespace } // x86x64 namespace

View File

@@ -28,12 +28,22 @@ namespace x86x64 {
// [asmjit::X86X64FuncDecl - Helpers] // [asmjit::X86X64FuncDecl - Helpers]
// ============================================================================ // ============================================================================
static ASMJIT_INLINE uint32_t x86FpVarTypeToXmmType(uint32_t vType) { static ASMJIT_INLINE bool x86ArgIsInt(uint32_t aType) {
if (vType == kVarTypeFp32) ASMJIT_ASSERT(aType < kVarTypeCount);
return IntUtil::inInterval<uint32_t>(aType, _kVarTypeIntStart, _kVarTypeIntEnd);
}
static ASMJIT_INLINE bool x86ArgIsFp(uint32_t aType) {
ASMJIT_ASSERT(aType < kVarTypeCount);
return IntUtil::inInterval<uint32_t>(aType, _kVarTypeFpStart, _kVarTypeFpEnd);
}
static ASMJIT_INLINE uint32_t x86ArgTypeToXmmType(uint32_t aType) {
if (aType == kVarTypeFp32)
return kVarTypeXmmSs; return kVarTypeXmmSs;
if (vType == kVarTypeFp64) if (aType == kVarTypeFp64)
return kVarTypeXmmSd; return kVarTypeXmmSd;
return vType; return aType;
} }
// ============================================================================ // ============================================================================
@@ -318,7 +328,7 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
FuncInOut& arg = self->getArg(i); FuncInOut& arg = self->getArg(i);
uint32_t varType = varMapping[arg.getVarType()]; uint32_t varType = varMapping[arg.getVarType()];
if (x86VarIsInt(varType) && gpPos < 16 && self->_passedOrderGp[gpPos] != kInvalidReg) { if (x86ArgIsInt(varType) && gpPos < 16 && self->_passedOrderGp[gpPos] != kInvalidReg) {
arg._regIndex = self->_passedOrderGp[gpPos++]; arg._regIndex = self->_passedOrderGp[gpPos++];
self->_used.add(kRegClassGp, IntUtil::mask(arg.getRegIndex())); self->_used.add(kRegClassGp, IntUtil::mask(arg.getRegIndex()));
} }
@@ -342,11 +352,11 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
if (arg.hasRegIndex()) if (arg.hasRegIndex())
continue; continue;
if (x86VarIsInt(varType)) { if (x86ArgIsInt(varType)) {
stackOffset -= 4; stackOffset -= 4;
arg._stackOffset = static_cast<int16_t>(stackOffset); arg._stackOffset = static_cast<int16_t>(stackOffset);
} }
else if (x86VarIsFloat(varType)) { else if (x86ArgIsFp(varType)) {
int32_t size = static_cast<int32_t>(_varInfo[varType].getSize()); int32_t size = static_cast<int32_t>(_varInfo[varType].getSize());
stackOffset -= size; stackOffset -= size;
arg._stackOffset = static_cast<int16_t>(stackOffset); arg._stackOffset = static_cast<int16_t>(stackOffset);
@@ -365,12 +375,12 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
FuncInOut& arg = self->getArg(i); FuncInOut& arg = self->getArg(i);
uint32_t varType = varMapping[arg.getVarType()]; uint32_t varType = varMapping[arg.getVarType()];
if (x86VarIsInt(varType)) { if (x86ArgIsInt(varType)) {
arg._regIndex = self->_passedOrderGp[i]; arg._regIndex = self->_passedOrderGp[i];
self->_used.add(kRegClassGp, IntUtil::mask(arg.getRegIndex())); self->_used.add(kRegClassGp, IntUtil::mask(arg.getRegIndex()));
} }
else if (x86VarIsFloat(varType)) { else if (x86ArgIsFp(varType)) {
arg._varType = static_cast<uint8_t>(x86FpVarTypeToXmmType(varType)); arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType));
arg._regIndex = self->_passedOrderXmm[i]; arg._regIndex = self->_passedOrderXmm[i];
self->_used.add(kRegClassXy, IntUtil::mask(arg.getRegIndex())); self->_used.add(kRegClassXy, IntUtil::mask(arg.getRegIndex()));
} }
@@ -384,13 +394,12 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
if (arg.hasRegIndex()) if (arg.hasRegIndex())
continue; continue;
if (x86VarIsInt(varType)) { if (x86ArgIsInt(varType)) {
stackOffset -= 8; // Always 8 bytes. stackOffset -= 8; // Always 8 bytes.
arg._stackOffset = stackOffset; arg._stackOffset = stackOffset;
} }
else if (x86VarIsFloat(varType)) { else if (x86ArgIsFp(varType)) {
int32_t size = static_cast<int32_t>(_varInfo[varType].getSize()); stackOffset -= 8; // Always 8 bytes (float/double).
stackOffset -= size;
arg._stackOffset = stackOffset; arg._stackOffset = stackOffset;
} }
} }
@@ -404,7 +413,7 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
FuncInOut& arg = self->getArg(i); FuncInOut& arg = self->getArg(i);
uint32_t varType = varMapping[arg.getVarType()]; uint32_t varType = varMapping[arg.getVarType()];
if (x86VarIsInt(varType) && gpPos < 32 && self->_passedOrderGp[gpPos] != kInvalidReg) { if (x86ArgIsInt(varType) && gpPos < 32 && self->_passedOrderGp[gpPos] != kInvalidReg) {
arg._regIndex = self->_passedOrderGp[gpPos++]; arg._regIndex = self->_passedOrderGp[gpPos++];
self->_used.add(kRegClassGp, IntUtil::mask(arg.getRegIndex())); self->_used.add(kRegClassGp, IntUtil::mask(arg.getRegIndex()));
} }
@@ -415,8 +424,8 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
FuncInOut& arg = self->getArg(i); FuncInOut& arg = self->getArg(i);
uint32_t varType = varMapping[arg.getVarType()]; uint32_t varType = varMapping[arg.getVarType()];
if (x86VarIsFloat(varType)) { if (x86ArgIsFp(varType)) {
arg._varType = static_cast<uint8_t>(x86FpVarTypeToXmmType(varType)); arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType));
arg._regIndex = self->_passedOrderXmm[xmmPos++]; arg._regIndex = self->_passedOrderXmm[xmmPos++];
self->_used.add(kRegClassXy, IntUtil::mask(arg.getRegIndex())); self->_used.add(kRegClassXy, IntUtil::mask(arg.getRegIndex()));
} }
@@ -430,11 +439,11 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
if (arg.hasRegIndex()) if (arg.hasRegIndex())
continue; continue;
if (x86VarIsInt(varType)) { if (x86ArgIsInt(varType)) {
stackOffset -= 8; stackOffset -= 8;
arg._stackOffset = static_cast<int16_t>(stackOffset); arg._stackOffset = static_cast<int16_t>(stackOffset);
} }
else if (x86VarIsFloat(varType)) { else if (x86ArgIsFp(varType)) {
int32_t size = static_cast<int32_t>(_varInfo[varType].getSize()); int32_t size = static_cast<int32_t>(_varInfo[varType].getSize());
stackOffset -= size; stackOffset -= size;