Differences From Artifact [03bcbc3b9d]:
- File src/invocation/invoke-x86_64.m — part of check-in [2379608969] at 2017-09-16 20:05:42 on branch trunk — invoke-x86_64.m: Fix compilation with GCC (user: js, size: 7146) [annotate] [blame] [check-ins using]
To Artifact [1d2004b374]:
- File
src/invocation/invoke-x86_64.m
— part of check-in
[c14dfdc8e5]
at
2017-09-16 20:20:35
on branch trunk
— invoke-x86_64.m: Correctly align __int128 for GCC
GCC correctly aligns __int128 with 16 bytes on the stack, like specified
in the ABI, while Clang does not.Unfortunately, this means that GCC and Clang have a different ABI and
thus are incompatible as soon as code uses __int128. (user: js, size: 7963) [annotate] [blame] [check-ins using]
︙ | ︙ | |||
109 110 111 112 113 114 115 116 117 118 119 120 121 122 | } memcpy(&newContext->stack[newContext->stack_size], &value, 16); newContext->stack_size += 2; *context = newContext; } void of_invocation_invoke(OFInvocation *invocation) { OFMethodSignature *methodSignature = [invocation methodSignature]; size_t numberOfArguments = [methodSignature numberOfArguments]; struct call_context *context; const char *typeEncoding; | > > > > > > > > > > > > > > > > > > > > > > > > > > | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | } 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]; struct call_context *context; const char *typeEncoding; |
︙ | ︙ | |||
153 154 155 156 157 158 159 160 161 162 163 164 165 166 | CASE_GPR('Q', unsigned long long) #ifdef __SIZEOF_INT128__ case 't': case 'T':; uint64_t int128Tmp[2]; [invocation getArgument: int128Tmp atIndex: i]; pushGPR(&context, ¤tGPR, int128Tmp[0]); pushGPR(&context, ¤tGPR, int128Tmp[1]); break; #endif case 'f':; float floatTmp; [invocation getArgument: &floatTmp | > > > > > > > | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | CASE_GPR('Q', unsigned long long) #ifdef __SIZEOF_INT128__ 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':; float floatTmp; [invocation getArgument: &floatTmp |
︙ | ︙ |