summaryrefslogtreecommitdiff
path: root/newlib/libc/sys/sysvi386/_longjmp.s
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/sys/sysvi386/_longjmp.s')
-rw-r--r--newlib/libc/sys/sysvi386/_longjmp.s31
1 files changed, 31 insertions, 0 deletions
diff --git a/newlib/libc/sys/sysvi386/_longjmp.s b/newlib/libc/sys/sysvi386/_longjmp.s
new file mode 100644
index 00000000000..691409b0b16
--- /dev/null
+++ b/newlib/libc/sys/sysvi386/_longjmp.s
@@ -0,0 +1,31 @@
+/
+/ our buffer looks like:
+/ eax,ebx,ecx,edx,esi,edi,esp,ebp,pc
+/
+/ _longjmp is called with two parameters: jmp_buf*,int
+/ jmp_buf* is at 4(%esp), int is at 8(%esp)
+/ retaddr is, of course, at (%esp)
+
+ .globl _longjmp
+ .globl longjmp
+_longjmp:
+longjmp:
+ movl 4(%esp), %ebx / address of buf
+ movl 8(%esp), %eax / store return value
+
+ movl 24(%ebx), %esp / restore stack
+ movl 32(%ebx), %edi
+/ Next line sets up return address.
+ movl %edi, 0(%esp)
+ movl 8(%ebx), %ecx
+ movl 12(%ebx), %edx
+ movl 16(%ebx), %esi
+ movl 20(%ebx), %edi
+ movl 28(%ebx), %ebp
+ movl 4(%ebx), %ebx
+ testl %eax,%eax
+ jne bye
+ incl %eax / eax hold 0 if we are here
+bye:
+ ret
+