genericopenlibs/openenvcore/libc/src/jmp_x86gcc.cia
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/openenvcore/libc/src/jmp_x86gcc.cia	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,73 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <setjmp.h>
+#include <cpudefs.h>
+
+extern "C" {
+
+EXPORT_C __NAKED__ int setjmp(jmp_buf __jmpb)
+	{
+	asm ("mov eax, [esp+4]"); // eax = __jmpb
+	asm ("mov [eax],    ebx");
+	asm ("mov [eax+4],  esi");
+	asm ("mov [eax+8],  edi");
+
+	// Get caller's ESP by popping the parameter and the return address (8 bytes) from current ESP value
+	asm ("mov edx, esp"); 
+	asm ("add edx, 8"); 
+	asm ("mov [eax+12], edx");	// caller's ESP
+	asm ("mov [eax+16], ds");
+	asm ("mov [eax+20], es");
+	asm ("mov [eax+24], fs");
+	asm ("mov [eax+28], gs");
+	asm ("mov [eax+32], ebp");	// caller's EBP (stack frame)
+	asm ("mov edx, [esp]");		// Save the retaddr because it's also the
+	asm ("mov [eax+36], edx");	// place in the calling function to which longjmp() must return to
+	asm ("mov eax, 0");
+	asm ("ret");
+	}
+
+EXPORT_C __NAKED__ void longjmp(jmp_buf __jmpb, int __retval)
+	{
+	asm("mov eax, [esp+4]");	// eax = __jmpb
+
+	// If __retval is 0 (KErrNone?) change it to a non-zero value
+	asm("mov edx, [esp+8]");	// edx = __retval
+	asm("cmp edx, 0");
+	asm("jne is_not_zero");
+	asm("inc edx"); 
+	asm("is_not_zero:");	
+	asm("mov [eax+40],edx");	// __jmpb[10]=__retval
+
+	asm("mov ebp, [eax+12]");
+	asm("mov esp, ebp");		// restore setjmp caller's ESP 
+	asm("mov ebx, [eax]");
+	asm("mov esi, [eax+4]");
+	asm("mov edi, [eax+8]");
+	asm("mov ds, [eax+16]");
+	asm("mov es, [eax+20]");
+	asm("mov fs, [eax+24]");
+	asm("mov gs, [eax+28]");
+
+	asm("mov ebp, [eax+32]"); // restore setjmp caller's EBP
+		
+	asm("mov eax, [eax+36]"); // push return address on stack
+	asm("push eax");
+	asm("mov eax,edx");	
+	asm("ret");				// magically ret's to instruction following call to setjmp() with eax==__retval
+	}
+
+} // extern "C"