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 {
X86Test_AllocArgs() : X86Test("[Alloc] Args") {}
struct X86Test_AllocArgsIntPtr : public X86Test {
X86Test_AllocArgsIntPtr() : X86Test("[Alloc] Args-IntPtr") {}
static void add(PodVector<X86Test*>& tests) {
tests.append(new X86Test_AllocArgs());
tests.append(new X86Test_AllocArgsIntPtr());
}
virtual void compile(Compiler& c) {
c.addFunc(kFuncConvHost,
FuncBuilder8<FnVoid, void*, void*, void*, void*, void*, void*, void*, void*>());
GpVar var[8];
uint32_t i;
GpVar var[8];
for (i = 0; i < 8; i++) {
var[i] = c.newGpVar();
}
for (i = 0; i < 8; 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]
// ============================================================================
@@ -2111,7 +2216,9 @@ X86TestSuite::X86TestSuite() :
ADD_TEST(X86Test_AllocIfElse2);
ADD_TEST(X86Test_AllocIfElse3);
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_AllocMemcpy);
ADD_TEST(X86Test_AllocBlend);

View File

@@ -3838,16 +3838,6 @@ static ASMJIT_INLINE uint32_t x86VarTypeToClass(uint32_t vType) {
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

View File

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