diff options
author | comex | 2015-01-16 06:32:58 -0500 |
---|---|---|
committer | comex | 2015-01-16 06:32:58 -0500 |
commit | 4ac639ebb0172560f6719f3eed45d1a3f054efe5 (patch) | |
tree | 6d9d2dd67d92928a0463d0585ff827d4c332a876 /lib/objc-asm.S | |
parent | handle oom and silly machos and stuff (diff) | |
download | substitute-4ac639ebb0172560f6719f3eed45d1a3f054efe5.tar.gz |
and now for something completely different: assembly maybestret-IMPL
forwarding functions for atomicity
Diffstat (limited to 'lib/objc-asm.S')
-rw-r--r-- | lib/objc-asm.S | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/objc-asm.S b/lib/objc-asm.S new file mode 100644 index 0000000..d3dae8a --- /dev/null +++ b/lib/objc-asm.S @@ -0,0 +1,81 @@ +/* These all try to re-invoke old_ptr. To make things worse, we don't know + * whether it will be called as stret or not, so we have to guess. */ +.globl _temp_block_invoke +.section __TEXT,__text,regular,pure_instructions +#if defined(__x86_64__) +_temp_block_invoke: + push %rcx + mov 0x10(%rsi), %rax; /* block if stret, else self */ + lea _temp_block_invoke(%rip), %rcx + cmp %rax, %rcx + pop %rcx + je 2f + mov %rdi, %rax + mov %rsi, %rdi + mov 0x28(%rax), %rsi + mov 0x20(%rax), %rax + jmp *(%rax) +2: /* stret */ + mov %rsi, %rax + mov %rdx, %rsi + mov 0x28(%rsi), %rdx + mov 0x20(%rsi), %rax + jmp *(%rax) +#elif defined(__i386__) +_temp_block_invoke: + call 1f +1: + pop %edx + lea _temp_block_invoke-1b(%edx), %edx + mov 8(%esp), %ecx; /* block if stret, else self */ + mov 0xc(%ecx), %eax + cmp %eax, %edx + je 2f + mov 4(%esp), %eax; /* block */ + mov %ecx, 4(%esp) + mov 0x18(%eax), %ecx + mov %ecx, 8(%esp) + mov 0x14(%eax), %eax + jmp *(%eax) +2: /* stret */ + mov 12(%esp), %ecx; /* self */ + mov 8(%esp), %eax; /* block */ + mov %ecx, 4(%esp) + mov 0x18(%eax), %ecx + mov %ecx, 12(%esp) + mov 0x14(%eax), %eax + jmp *(%eax) +#elif defined(__arm__) +.thumb_func _temp_block_invoke +.thumb +_temp_block_invoke: +1: + ldr r9, [r1, #0xc] + adr r12, 1b + cmp r9, r12 + beq 2f + mov r9, r0 + mov r0, r1 + ldr r1, [r9, #0x18] + ldr r9, [r9, #0x14] + ldr r9, [r9] + bx r9 +2: /* stret */ + mov r9, r1 + mov r1, r2 + ldr r2, [r9, #0x18] + ldr r9, [r9, #0x14] + ldr r9, [r9] + bx r9 +#elif defined(__arm64__) +.align 2 +_temp_block_invoke: + mov x9, x0 + mov x0, x1 + ldr x1, [x9, #0x28] + ldr x9, [x9, #0x20] + ldr x9, [x9] + br x9 +#else +#error No forwarding assembly definition for this arch +#endif |