🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

x64 calling convention doesn't make room for return value in rcx

Started by
17 comments, last by WitchLord 3 years, 11 months ago

I'll check what it returns for me.

I used GLM 0.9.9.7 too but I removed some parts to not have to include the entire library as part of my regression test suite. Maybe I ended up impacting the end result with that, and that is why the problem wasn't reproduced.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement

Seems a little weird but yeah, maybe. It could be a lot of things I guess.

For me asGetTypeTraits<glm::vec2>() returns asOBJ_APP_CLASS | asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_CLASS_COPY_CONSTRUCTOR.

(or asOBJ_APP_CLASS_CAK)

This explains why it works for me, but not for you.

Now I just need to figure out why we're getting different results when in theory we're using the same code and compiler version.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I identified the difference. I had omitted the #include "../simd/platform.h" thinking it wouldn't impact the end result, but it did.

This file is where the glm code identifies that the compiler is MSVC 2019 and later in setup.hpp allows it to identify that the C++11 feature ‘defaulted functions’ is available and sets ‘#define GLM_DEFAULT = default’.

This in turn is what is causing the asGetTypeTraits<glm::vec2>() to return the wrong flags.

Unfortunately it doesn't seem to be a trivial fix. The C++ ABI in MSVC uses the existence of a non-trivial copy constructor to determine if the object type must be returned in memory instead of CPU registers. Unfortunately it seems the C++ ABI in MVSC doesn't treat a ‘defaulted’ copy constructor as trivial, even though it is supposed to mean the same thing.

I'll continue to investigate, but it may be that I'll be left with no options to fix this problem, and will just have to write it down as a restriction to the asGetTypeTraits that it doesn't work work classes that uses ‘defaulted’ functions.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Ah I see. Would this be worth reporting to Microsoft as a bug? Is this unusual in the standard? What happens in this case on GCC/Clang for example?

I don't think it would be considered a bug in the compiler. The C++ specification doesn't impose rules on how the ABI should be implemented, every vendor is free to do it how ever it wants.

It is just unfortunate for me that C++ doesn't give me enough compile-time or run-time information to automatically determine how a type should be handled in the ABI.

*thinking out aloud* Maybe I can automatically generate some dummy functions in asGetTypeTraits<T>() and then scan the instructions for hints on how the type is supposed to be handled.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Miss said:
What happens in this case on GCC/Clang for example?

I've tested it now with MinGW 64bit, and with the defaulted constructors/operators asGetTypeTraits<glm::vec2>() it also returns asOBJ_APP_CLASS without the additional flags. However, it doesn't cause any problem with the ABI so perhaps it might be a mistake/bug in MSVC after all.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

After further investigation I finally identified that the cause is due to the glm::vec2 having additional constructors, e.g. vec2(float, float) together with the default and copy constructors that have been defaulted.

In order to support this case I added an additional flag asOBJ_APP_CLASS_MORE_CONSTRUCTORS to inform when a class with defaulted constructors has additional non-trivial constructors.

With revision 2658 this can now be used to make glm::vec2 work properly with native calling conventions on MSVC compilers.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement