Save %xmm when it can be used for args, put the args in the right order.

main
theraven 14 years ago
parent 1e3343c149
commit 224de356cb

@ -4,6 +4,7 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <class.h> #include <class.h>
#include <stdarg.h>
id objc_msgSend(id, SEL, ...); id objc_msgSend(id, SEL, ...);
@ -32,6 +33,21 @@ Class TestCls;
s st = {1,2,3,4,5}; s st = {1,2,3,4,5};
return st; return st;
} }
+ (void)printf: (const char*)str, ...
{
va_list ap;
char *s;
va_start(ap, str);
vasprintf(&s, str, ap);
va_end(ap);
assert(strcmp(s, "Format string 42 42.000000\n") ==0);
}
+ (void)initialize
{
[self printf: "Format %s %d %f%c", "string", 42, 42.0, '\n'];
}
+ nothing { return 0; } + nothing { return 0; }
@end @end
int main(void) int main(void)

@ -3,7 +3,14 @@
#define SHIFT_OFFSET 4 #define SHIFT_OFFSET 4
#define DATA_OFFSET 16 #define DATA_OFFSET 16
#define SLOT_OFFSET 32 #define SLOT_OFFSET 32
.macro MSGSEND receiver, sel .macro MSGSEND receiver, sel
.cfi_startproc # Start emitting unwind data. We
# don't actually care about any of
# the stuff except the slow call,
# because that's the only one that
# can throw.
test \receiver, \receiver # If the receiver is nil test \receiver, \receiver # If the receiver is nil
jz 4f # return nil jz 4f # return nil
movq $SMALLOBJ_MASK, %r10 # Load the small object mask movq $SMALLOBJ_MASK, %r10 # Load the small object mask
@ -59,33 +66,56 @@
push %rax # We need to preserve all registers that may contain arguments: push %rax # We need to preserve all registers that may contain arguments:
push %rbx push %rbx
push %rcx push %rcx
push %rdx
push %r8 push %r8
push %r9 push %r9
//push %r9 # Fudge to ensure stack alignment stays at 16 bytes, or SSE dies
sub $0x98, %rsp
movups %xmm0, 0x80(%rsp)
movups %xmm1, 0x70(%rsp)
movups %xmm2, 0x60(%rsp)
movups %xmm3, 0x50(%rsp)
movups %xmm4, 0x40(%rsp)
movups %xmm5, 0x30(%rsp)
movups %xmm6, 0x20(%rsp)
movups %xmm7, 0x10(%rsp)
#rdi rsi rdx
# We're (potentially) modifying the self argument with the lookup, so we don't want to be # We're (potentially) modifying the self argument with the lookup, so we don't want to be
.ifc "\receiver", "%rdi" .ifc "\receiver", "%rdi"
push %rdi
mov %rsp, %rdi
push %rsi # Save _cmd (not preserved across calls) push %rsi # Save _cmd (not preserved across calls)
push %rdx
.else .else
push %rdi # Save the sret pointer push %rdi # Save the sret pointer
mov \sel, %rsi # move _cmd to where the callee expects it to be push %rsi # Save self where it can be modified
mov %rsp, %rdi
push %rdx
mov %rdx, %rsi # move _cmd to where the callee expects it to be
.endif .endif
push \receiver # Store the receiver on the stack .cfi_def_cfa_offset 80
mov %rsp, %rdi # First argument is &self
call slowMsgLookup # Call the slow lookup function call slowMsgLookup # Call the slow lookup function
mov %rax, %r10 # Load the returned IMP mov %rax, %r10 # Load the returned IMP
pop \receiver # Load the (potentially) new receiver
.if \receiver == %rdi pop %rdx
pop %rsi pop %rsi
.else
pop %rdi pop %rdi
.endif
movups 0x80(%rsp), %xmm0
movups 0x70(%rsp), %xmm1
movups 0x60(%rsp), %xmm2
movups 0x50(%rsp), %xmm3
movups 0x40(%rsp), %xmm4
movups 0x30(%rsp), %xmm5
movups 0x20(%rsp), %xmm6
movups 0x10(%rsp), %xmm7
add $0x98, %rsp
//pop %r9 # Fudge to ensure stack alignment stays at 16 bytes, or SSE dies
pop %r9 pop %r9
pop %r8 pop %r8
pop %rdx
pop %rcx pop %rcx
pop %rbx pop %rbx
pop %rax pop %rax
@ -97,6 +127,7 @@
add %r11, %r10 add %r11, %r10
mov (%r10), %r10 mov (%r10), %r10
jmp 1b jmp 1b
.cfi_endproc
.endm .endm
.globl objc_msgSend .globl objc_msgSend
.type objc_msgSend, @function .type objc_msgSend, @function

@ -269,7 +269,7 @@ static inline void register_selector_locked(SEL aSel)
uintptr_t idx = selector_count++; uintptr_t idx = selector_count++;
if (NULL == aSel->types) if (NULL == aSel->types)
{ {
fprintf(stderr, "Registering selector %d %s\n", idx, sel_getNameNonUnique(aSel)); fprintf(stderr, "Registering selector %d %s\n", (int)idx, sel_getNameNonUnique(aSel));
add_selector_to_table(aSel, idx, idx); add_selector_to_table(aSel, idx, idx);
objc_resize_dtables(selector_count); objc_resize_dtables(selector_count);
return; return;
@ -281,7 +281,7 @@ static inline void register_selector_locked(SEL aSel)
untyped = selector_pool_alloc(); untyped = selector_pool_alloc();
untyped->name = aSel->name; untyped->name = aSel->name;
untyped->types = 0; untyped->types = 0;
fprintf(stderr, "Registering selector %d %s\n", idx, sel_getNameNonUnique(aSel)); fprintf(stderr, "Registering selector %d %s\n", (int)idx, sel_getNameNonUnique(aSel));
add_selector_to_table(untyped, idx, idx); add_selector_to_table(untyped, idx, idx);
// If we are in type dependent dispatch mode, the uid for the typed // If we are in type dependent dispatch mode, the uid for the typed
// and untyped versions will be different // and untyped versions will be different
@ -294,7 +294,7 @@ static inline void register_selector_locked(SEL aSel)
} }
uintptr_t uid = (uintptr_t)untyped->name; uintptr_t uid = (uintptr_t)untyped->name;
TDD(uid = idx); TDD(uid = idx);
fprintf(stderr, "Registering typed selector %d %s %s\n", uid, sel_getNameNonUnique(aSel), sel_getType_np(aSel)); fprintf(stderr, "Registering typed selector %d %s %s\n", (int)uid, sel_getNameNonUnique(aSel), sel_getType_np(aSel));
add_selector_to_table(aSel, uid, idx); add_selector_to_table(aSel, uid, idx);
// Add this set of types to the list. // Add this set of types to the list.

Loading…
Cancel
Save