ARM64 Native Calling Convention Return Issue on Apple Silicon

Started by
3 comments, last by gjl 1 week, 3 days ago

Hi,

I think I have found a problem with the new native ARM64 calling convention on Mac when a function returns a structure with all doubles. Summarizing an excerpt of a larger code base here:

struct XYPair
{
   double x;
   double y;
};

class IDrawFont
{
};

enum TextExtentMode
{
	kTextExtentNormal
};

static XYPair IDrawFont_GetTextSize(const IDrawFont& font,const std::string& text,TextExtentMode mode)
{
    XYPair pair;
    pair.x=200.0;
    pair.y=12.5;
    return pair;
}

// registering the struct and a function that returns the struct
r = engine->RegisterObjectType("XYCoordinates", sizeof(XYPair), asOBJ_VALUE| asOBJ_POD | asGetTypeTraits<XYPair>() | asOBJ_APP_CLASS_ALLFLOATS); assert( r >= 0 );
r = engine->RegisterObjectProperty("XYCoordinates", "double x", asOFFSET(XYPair, x)); assert( r >= 0 );
r = engine->RegisterObjectProperty("XYCoordinates", "double y", asOFFSET(XYPair, y)); assert( r >= 0 );
r = engine->RegisterObjectMethod("DrawFont", "XYCoordinates GetTextSize(const string& text,TextExtentMode mode)", asFUNCTIONPR(IDrawFont_GetTextSize, (const IDrawFont&,const std::string&,TextExtentMode), XYPair), asCALL_CDECL_OBJFIRST); assert( r >= 0 );

Calling the GetTextSize() function returns a trashed structure where both values are zero or close to 0.

If I register the XYPair object type with the additional alignment directive (which seems to be necessary since it is all doubles?):

r = engine->RegisterObjectType("XYCoordinates", sizeof(XYPair), asOBJ_VALUE| asOBJ_POD | asGetTypeTraits<XYPair>() | asOBJ_APP_CLASS_ALLFLOATS | asOBJ_APP_CLASS_ALIGN8); assert( r >= 0 );

Then it crashes when called, in CallSystemFunctionNative in ascallfuncarm64.cpp on line 407

GETHFAReturnDouble(&retQW,&retQW2,structSize);

It seems that the retQW and retQW2 do not contain the expected data anyway. structSize looks fine.

Do you have an idea of what could be wrong here? My knowledge of ARM64 calling conventions is too limited to go further :-).

Advertisement

I will have to run this by Sam Tupy as he was the one that adapted the Arm64 Linux code to Apple M1/M2 code.

I will have to check if I have this type of structure in the regression test. If I don't it explains why Sam didn't mention any issue for it.

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

In the meantime, can you do a disassembly of the IDrawFont_GetTextSize function so I can see how the compiler is returning the value?

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

Here is the generated assembly for the exact function above:

IDrawFont_GetTextSize:
    0x1030afb04 <+0>:  sub    sp, sp, #0x30
    0x1030afb08 <+4>:  str    x0, [sp, #0x18]
    0x1030afb0c <+8>:  str    x1, [sp, #0x10]
    0x1030afb10 <+12>: str    w2, [sp, #0xc]
    0x1030afb14 <+16>: adrp   x8, 2631
    0x1030afb18 <+20>: ldr    d0, [x8, #0x1d0]
    0x1030afb1c <+24>: str    d0, [sp, #0x20]
    0x1030afb20 <+28>: fmov   d0, #12.50000000
    0x1030afb24 <+32>: str    d0, [sp, #0x28]
    0x1030afb28 <+36>: ldr    d0, [sp, #0x20]
    0x1030afb2c <+40>: ldr    d1, [sp, #0x28]
    0x1030afb30 <+44>: add    sp, sp, #0x30
    0x1030afb34 <+48>: ret   
Advertisement