These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / arch / x86_64 / core / setjmp.S
diff --git a/qemu/roms/ipxe/src/arch/x86_64/core/setjmp.S b/qemu/roms/ipxe/src/arch/x86_64/core/setjmp.S
new file mode 100644 (file)
index 0000000..e43200d
--- /dev/null
@@ -0,0 +1,65 @@
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+
+       .text
+       .code64
+
+       /* Must match jmp_buf structure layout */
+       .struct 0
+env_retaddr:   .quad   0
+env_stack:     .quad   0
+env_rbx:       .quad   0
+env_rbp:       .quad   0
+env_r12:       .quad   0
+env_r13:       .quad   0
+env_r14:       .quad   0
+env_r15:       .quad   0
+       .previous
+
+/*
+ * Save stack context for non-local goto
+ */
+       .globl  setjmp
+setjmp:
+       /* Save return address */
+       movq    0(%rsp), %rax
+       movq    %rax, env_retaddr(%rdi)
+       /* Save stack pointer */
+       movq    %rsp, env_stack(%rdi)
+       /* Save other registers */
+       movq    %rbx, env_rbx(%rdi)
+       movq    %rbp, env_rbp(%rdi)
+       movq    %r12, env_r12(%rdi)
+       movq    %r13, env_r13(%rdi)
+       movq    %r14, env_r14(%rdi)
+       movq    %r15, env_r15(%rdi)
+       /* Return 0 when returning as setjmp() */
+       xorq    %rax, %rax
+       ret
+       .size   setjmp, . - setjmp
+
+/*
+ * Non-local jump to a saved stack context
+ */
+       .globl  longjmp
+longjmp:
+       /* Get result in %rax */
+       movq    %rsi, %rax
+       /* Force result to non-zero */
+       testq   %rax, %rax
+       jnz     1f
+       incq    %rax
+1:     /* Restore stack pointer */
+       movq    env_stack(%rdi), %rsp
+       /* Restore other registers */
+       movq    env_rbx(%rdi), %rbx
+       movq    env_rbp(%rdi), %rbp
+       movq    env_r12(%rdi), %r12
+       movq    env_r13(%rdi), %r13
+       movq    env_r14(%rdi), %r14
+       movq    env_r15(%rdi), %r15
+       /* Replace return address on the new stack */
+       popq    %rcx    /* discard */
+       pushq   env_retaddr(%rdi)
+       /* Return to setjmp() caller */
+       ret
+       .size   longjmp, . - longjmp