Index: src/invocation/invoke-x86_64.m ================================================================== --- src/invocation/invoke-x86_64.m +++ src/invocation/invoke-x86_64.m @@ -111,10 +111,36 @@ memcpy(&newContext->stack[newContext->stack_size], &value, 16); newContext->stack_size += 2; *context = newContext; } +#ifndef __clang__ +static void +alignStack(struct call_context **context, size_t alignment) +{ + size_t stackSize = (*context)->stack_size; + struct call_context *newContext; + + if (stackSize % alignment == 0) + return; + + stackSize += alignment - stackSize % alignment; + + if ((newContext = realloc(*context, + sizeof(**context) + stackSize * 8)) == NULL) { + free(*context); + @throw [OFOutOfMemoryException exceptionWithRequestedSize: + sizeof(**context) + stackSize * 8]; + } + + memset(&newContext->stack[newContext->stack_size], '\0', + (stackSize - newContext->stack_size) * 8); + newContext->stack_size = stackSize; + *context = newContext; +} +#endif + void of_invocation_invoke(OFInvocation *invocation) { OFMethodSignature *methodSignature = [invocation methodSignature]; size_t numberOfArguments = [methodSignature numberOfArguments]; @@ -155,10 +181,17 @@ case 't': case 'T':; uint64_t int128Tmp[2]; [invocation getArgument: int128Tmp atIndex: i]; +# ifndef __clang__ + /* + * Clang violates the x86_64 ABI and does not properly + * align __int128 on the stack. + */ + alignStack(&context, 2); +# endif pushGPR(&context, ¤tGPR, int128Tmp[0]); pushGPR(&context, ¤tGPR, int128Tmp[1]); break; #endif case 'f':;