mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-18 13:04:36 +03:00
TestX86 - Added more tests (float / double arguments)
X86Func - Fixed Win64 float arguments handling.
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user