From 224de356cbb2c8a3267c406723558763aaa17536 Mon Sep 17 00:00:00 2001 From: theraven Date: Mon, 24 Oct 2011 14:09:54 +0000 Subject: [PATCH] Save %xmm when it can be used for args, put the args in the right order. --- Test/objc_msgSend.m | 16 ++++++++++++++ objc_msgSend.x86-64.S | 49 +++++++++++++++++++++++++++++++++++-------- selector_table.c | 6 +++--- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/Test/objc_msgSend.m b/Test/objc_msgSend.m index 35384de..db5da2d 100644 --- a/Test/objc_msgSend.m +++ b/Test/objc_msgSend.m @@ -4,6 +4,7 @@ #include #include #include +#include id objc_msgSend(id, SEL, ...); @@ -32,6 +33,21 @@ Class TestCls; s st = {1,2,3,4,5}; 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; } @end int main(void) diff --git a/objc_msgSend.x86-64.S b/objc_msgSend.x86-64.S index d435a86..5318247 100644 --- a/objc_msgSend.x86-64.S +++ b/objc_msgSend.x86-64.S @@ -3,7 +3,14 @@ #define SHIFT_OFFSET 4 #define DATA_OFFSET 16 #define SLOT_OFFSET 32 + .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 jz 4f # return nil 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 %rbx push %rcx - push %rdx push %r8 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 .ifc "\receiver", "%rdi" + push %rdi + mov %rsp, %rdi push %rsi # Save _cmd (not preserved across calls) + push %rdx .else 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 - push \receiver # Store the receiver on the stack - mov %rsp, %rdi # First argument is &self + .cfi_def_cfa_offset 80 call slowMsgLookup # Call the slow lookup function mov %rax, %r10 # Load the returned IMP - pop \receiver # Load the (potentially) new receiver -.if \receiver == %rdi + pop %rdx pop %rsi -.else 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 %r8 - pop %rdx pop %rcx pop %rbx pop %rax @@ -97,6 +127,7 @@ add %r11, %r10 mov (%r10), %r10 jmp 1b + .cfi_endproc .endm .globl objc_msgSend .type objc_msgSend, @function diff --git a/selector_table.c b/selector_table.c index 4f9ecbf..d75e1c4 100644 --- a/selector_table.c +++ b/selector_table.c @@ -269,7 +269,7 @@ static inline void register_selector_locked(SEL aSel) uintptr_t idx = selector_count++; 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); objc_resize_dtables(selector_count); return; @@ -281,7 +281,7 @@ static inline void register_selector_locked(SEL aSel) untyped = selector_pool_alloc(); untyped->name = aSel->name; 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); // If we are in type dependent dispatch mode, the uid for the typed // 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; 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 this set of types to the list.