Jump to content
  • Advertisement
Sign in to follow this  
_Vicious_

Native calling convention support for mingw x64

This topic is 2528 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello!

We're using mingw to cross compile our binary files for 2 different architectures: lin/win X x86/x64. Now that we've discovered that native calling convention is only supported for x64 when compiled by msvc, what is required to get it working under mingw?

Share this post


Link to post
Share on other sites
Advertisement
It is probably mostly about tweaking the as_config.h a bit to enable the native calling conventions with MinGW on Win64. You can start by making the configuration the same as for Linux, then run the test_features to check if it works.

If it fails, please let me know which of the tests that fail and I'll help you figure out what needs to be modified to get it working.

Share this post


Link to post
Share on other sites
Ok, thanks!

So I played around with a little.. Here's the first problem: mingw-w64 doesn't seem to define __LP64__ and indeed, sizeof(long) is 4. as_config.h seems to enable NCC for gcc only in case when __LP64__ is present. So where should I go from this?

Share this post


Link to post
Share on other sites
Can you obtain the list of predefines for MinGW? I think this is obtained by running the compiler for an empty file with a command line argument like -mD, or something similar. This will then print the defines.

It is necessary to determine what predefine that can be used to identify a 64bit target. There must be something instead of __LP64__ that can be used.

Share this post


Link to post
Share on other sites
Ok, here's the list of defines with 64 in the name:

#define _WIN64 1
#define __DBL_DENORM_MIN__ ((double)4.94065645841246544177e-324L)
#define __x86_64 1
#define __UINT_FAST64_MAX__ 18446744073709551615ULL
#define __DEC64_MAX_EXP__ 385
#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
#define __INT64_C(c) c ## LL
#define __WIN64 1
#define __INT32_MAX__ 2147483647
#define __INT_FAST32_MAX__ 2147483647
#define __INT64_MAX__ 9223372036854775807LL
#define __INT_LEAST32_MAX__ 2147483647
#define __amd64 1
#define __INT_FAST64_TYPE__ long long int
#define __UINT64_C(c) c ## ULL
#define __DEC64_EPSILON__ 1E-15DD
#define __UINT64_MAX__ 18446744073709551615ULL
#define __SIG_ATOMIC_MAX__ 2147483647
#define __x86_64__ 1
#define __UINT_LEAST64_TYPE__ long long unsigned int
#define __LONG_MAX__ 2147483647L
#define __DEC64_MAX__ 9.999999999999999E384DD
#define __DEC64_MANT_DIG__ 16
#define __INT_LEAST64_TYPE__ long long int
#define __LDBL_MANT_DIG__ 64
#define __DEC64_MIN_EXP__ (-382)
#define __INT_FAST64_MAX__ 9223372036854775807LL
#define __UINT_FAST64_TYPE__ long long unsigned int
#define __INT_MAX__ 2147483647
#define __amd64__ 1
#define __INT64_TYPE__ long long int
#define WIN64 1
#define __INT_LEAST64_MAX__ 9223372036854775807LL
#define __DEC64_MIN__ 1E-383DD
#define __UINT64_TYPE__ long long unsigned int
#define __MINGW64__ 1
#define __FLT_DENORM_MIN__ 1.40129846432481707092e-45F
#define _INTEGRAL_MAX_BITS 64
#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD
#define __WIN64__ 1


The relevant options are -E -dM

Share this post


Link to post
Share on other sites
The flag __MINGW64__ looks appropiate for detecting the 64bit target. __amd64 should be used to determine the cpu type.

It may be necessary to check in angelscript.h how the INT64 and QWORD types are typedefed. It should be with 'long long'.

Share this post


Link to post
Share on other sites
Yes, the QWORD typedef poses a problem in case __LP64__ is not defined, even if it's a 64-bit arch:
#ifdef __LP64__
typedef unsigned int asDWORD;
typedef unsigned long asQWORD;
typedef long asINT64;
#else
typedef unsigned long asDWORD;
#if defined(__GNUC__) || defined(__MWERKS__)
typedef unsigned long long asQWORD;
typedef long long asINT64;
#else
typedef unsigned __int64 asQWORD;
typedef __int64 asINT64;
#endif
#endif

Share this post


Link to post
Share on other sites
It seems that it would actually be correct. Since __LP64__ isn't defined, the asQWORD type will be typedefed as 'unsigned long long' which is correct from the MinGW64 predefines. (I'm assuming __GNUC__ is predefined by MinGW64).

Share this post


Link to post
Share on other sites
Ok, so I copied all those defines to the 'else' section of mingw set of defines, got it to compile.. The testbin suite crashes right after printing AngelScript version: 2.21.0
AngelScript options: AS_64BIT_PTR AS_WIN AS_X64_GCC
to console. Looks like it's going to be a bumpy ride :)

Share this post


Link to post
Share on other sites
I suggest you start with the tests that have been designed specifically for testing the native calling conventions. As these tests are targetted for very specific function calls, they are usually easier to understand and debug.

These tests start at line 303 in the test_feature/source/main.cpp file. Comment out the tests above those until all the tests for the native calling conventions work.

If you post the errors you get I can help figure out the changes that needs to be made.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!