update for HEAD-2003050101
[reactos.git] / lib / freetype / i386 / setjmplongjmp.s
diff --git a/lib/freetype/i386/setjmplongjmp.s b/lib/freetype/i386/setjmplongjmp.s
new file mode 100644 (file)
index 0000000..36514db
--- /dev/null
@@ -0,0 +1,87 @@
+/* $Id$\r
+ *\r
+ * COPYRIGHT:         See COPYING in the top level directory\r
+ * PROJECT:           FreeType implementation for ReactOS\r
+ * PURPOSE:           Implementation of _setjmp/longjmp\r
+ * FILE:              thirdparty/freetype/i386/setjmplongjmp.s\r
+ * PROGRAMMER:        Ge van Geldorp (ge@gse.nl)\r
+ * NOTES:             Copied from glibc.
+ *                    I have the feeling this could be implemented using the SEH
+ *                    routines, but if it's good enough for glibc it's propably
+ *                    good enough for me...
+ *                    The MingW headers define jmp_buf to be an array of 16 ints,
+ *                    based on the jmp_buf used by MSCVRT. We're using only 6 of
+ *                    them, so plenty of space.\r
+ */
+\r
+#define JB_BX  0
+#define JB_SI  1
+#define JB_DI  2
+#define JB_BP  3
+#define JB_SP  4
+#define JB_PC  5
+
+#define PCOFF  0
+
+#define JMPBUF 4
+\r
+/*\r
+ * int\r
+ * _setjmp(jmp_buf env);\r
+ *\r
+ * Parameters:\r
+ *   [ESP+04h] - jmp_buf env\r
+ * Registers:\r
+ *   None\r
+ * Returns:\r
+ *   0\r
+ * Notes:\r
+ *   Sets up the jmp_buf
+ */\r
+.globl __setjmp\r
+__setjmp:\r
+    xorl %eax, %eax
+    movl JMPBUF(%esp), %edx
+
+    /* Save registers.  */
+    movl %ebx, (JB_BX*4)(%edx)
+    movl %esi, (JB_SI*4)(%edx)
+    movl %edi, (JB_DI*4)(%edx)
+    leal JMPBUF(%esp), %ecx    /* Save SP as it will be after we return.  */
+    movl %ecx, (JB_SP*4)(%edx)
+    movl PCOFF(%esp), %ecx     /* Save PC we are returning to now.  */
+    movl %ecx, (JB_PC*4)(%edx)
+    movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer.  */
+    ret
+
+#define VAL 8
+\r
+/*\r
+ * void\r
+ * longjmp(jmp_buf env, int value);\r
+ *\r
+ * Parameters:\r
+ *   [ESP+04h] - jmp_buf setup by _setjmp
+ *   [ESP+08h] - int     value to return\r
+ * Registers:\r
+ *   None\r
+ * Returns:\r
+ *   Doesn't return\r
+ * Notes:\r
+ *   Non-local goto
+ */\r
+.globl _longjmp\r
+_longjmp:\r
+    movl JMPBUF(%esp), %ecx   /* User's jmp_buf in %ecx.  */
+
+    movl VAL(%esp), %eax      /* Second argument is return value.  */
+    /* Save the return address now.  */
+    movl (JB_PC*4)(%ecx), %edx
+    /* Restore registers.  */
+    movl (JB_BX*4)(%ecx), %ebx
+    movl (JB_SI*4)(%ecx), %esi
+    movl (JB_DI*4)(%ecx), %edi
+    movl (JB_BP*4)(%ecx), %ebp
+    movl (JB_SP*4)(%ecx), %esp
+    /* Jump to saved PC.  */
+    jmp *%edx