diff options
Diffstat (limited to 'lib/mlibc/options/internal/x86')
-rw-r--r-- | lib/mlibc/options/internal/x86/fenv.S | 168 | ||||
-rw-r--r-- | lib/mlibc/options/internal/x86/mlibc_crtbegin.S | 29 | ||||
-rw-r--r-- | lib/mlibc/options/internal/x86/mlibc_crtend.S | 24 | ||||
-rw-r--r-- | lib/mlibc/options/internal/x86/setjmp.S | 53 |
4 files changed, 274 insertions, 0 deletions
diff --git a/lib/mlibc/options/internal/x86/fenv.S b/lib/mlibc/options/internal/x86/fenv.S new file mode 100644 index 0000000..a46b5fa --- /dev/null +++ b/lib/mlibc/options/internal/x86/fenv.S @@ -0,0 +1,168 @@ +# The functions below are taken from musl. + +.hidden __hwcap + +.global feclearexcept +.type feclearexcept,@function +feclearexcept: + mov 4(%esp),%ecx + and $0x3f,%ecx + fnstsw %ax + # consider sse fenv as well if the cpu has XMM capability + call 1f +1: addl $__hwcap-1b,(%esp) + pop %edx + testl $0x02000000,(%edx) + jz 2f + # maintain exceptions in the sse mxcsr, clear x87 exceptions + test %eax,%ecx + jz 1f + fnclex +1: push %edx + stmxcsr (%esp) + pop %edx + and $0x3f,%eax + or %eax,%edx + test %edx,%ecx + jz 1f + not %ecx + and %ecx,%edx + push %edx + ldmxcsr (%esp) + pop %edx +1: xor %eax,%eax + ret + # only do the expensive x87 fenv load/store when needed +2: test %eax,%ecx + jz 1b + not %ecx + and %ecx,%eax + test $0x3f,%eax + jz 1f + fnclex + jmp 1b +1: sub $32,%esp + fnstenv (%esp) + mov %al,4(%esp) + fldenv (%esp) + add $32,%esp + xor %eax,%eax + ret + +.global feraiseexcept +.type feraiseexcept,@function +feraiseexcept: + mov 4(%esp),%eax + and $0x3f,%eax + sub $32,%esp + fnstenv (%esp) + or %al,4(%esp) + fldenv (%esp) + add $32,%esp + xor %eax,%eax + ret + +.global __fesetround +.hidden __fesetround +.type __fesetround,@function +__fesetround: + mov 4(%esp),%ecx + push %eax + xor %eax,%eax + fnstcw (%esp) + andb $0xf3,1(%esp) + or %ch,1(%esp) + fldcw (%esp) + # consider sse fenv as well if the cpu has XMM capability + call 1f +1: addl $__hwcap-1b,(%esp) + pop %edx + testl $0x02000000,(%edx) + jz 1f + stmxcsr (%esp) + shl $3,%ch + andb $0x9f,1(%esp) + or %ch,1(%esp) + ldmxcsr (%esp) +1: pop %ecx + ret + +.global fegetround +.type fegetround,@function +fegetround: + push %eax + fnstcw (%esp) + pop %eax + and $0xc00,%eax + ret + +.global fegetenv +.type fegetenv,@function +fegetenv: + mov 4(%esp),%ecx + xor %eax,%eax + fnstenv (%ecx) + # consider sse fenv as well if the cpu has XMM capability + call 1f +1: addl $__hwcap-1b,(%esp) + pop %edx + testl $0x02000000,(%edx) + jz 1f + push %eax + stmxcsr (%esp) + pop %edx + and $0x3f,%edx + or %edx,4(%ecx) +1: ret + +.global fesetenv +.type fesetenv,@function +fesetenv: + mov 4(%esp),%ecx + xor %eax,%eax + inc %ecx + jz 1f + fldenv -1(%ecx) + movl -1(%ecx),%ecx + jmp 2f +1: push %eax + push %eax + push %eax + push %eax + pushl $0xffff + push %eax + pushl $0x37f + fldenv (%esp) + add $28,%esp + # consider sse fenv as well if the cpu has XMM capability +2: call 1f +1: addl $__hwcap-1b,(%esp) + pop %edx + testl $0x02000000,(%edx) + jz 1f + # mxcsr := same rounding mode, cleared exceptions, default mask + and $0xc00,%ecx + shl $3,%ecx + or $0x1f80,%ecx + mov %ecx,4(%esp) + ldmxcsr 4(%esp) +1: ret + +.global fetestexcept +.type fetestexcept,@function +fetestexcept: + mov 4(%esp),%ecx + and $0x3f,%ecx + fnstsw %ax + # consider sse fenv as well if the cpu has XMM capability + call 1f +1: addl $__hwcap-1b,(%esp) + pop %edx + testl $0x02000000,(%edx) + jz 1f + stmxcsr 4(%esp) + or 4(%esp),%eax +1: and %ecx,%eax + ret + +.section .note.GNU-stack,"",%progbits diff --git a/lib/mlibc/options/internal/x86/mlibc_crtbegin.S b/lib/mlibc/options/internal/x86/mlibc_crtbegin.S new file mode 100644 index 0000000..d317451 --- /dev/null +++ b/lib/mlibc/options/internal/x86/mlibc_crtbegin.S @@ -0,0 +1,29 @@ + +.section .data +.hidden __dso_handle +.global __dso_handle +__dso_handle: + .long __dso_handle + +.section .init +.hidden _init +.global _init +_init: + +.section .fini +.hidden _fini +.global _fini +_fini: + +.section .ctors +.hidden __CTOR_LIST__ +.global __CTOR_LIST__ +__CTOR_LIST__: + +.section .dtors +.hidden __DTOR_LIST__ +.global __DTOR_LIST__ +__DTOR_LIST__: + +.section .note.GNU-stack,"",%progbits + diff --git a/lib/mlibc/options/internal/x86/mlibc_crtend.S b/lib/mlibc/options/internal/x86/mlibc_crtend.S new file mode 100644 index 0000000..e9d9136 --- /dev/null +++ b/lib/mlibc/options/internal/x86/mlibc_crtend.S @@ -0,0 +1,24 @@ + +.hidden __mlibc_do_ctors +.hidden __mlibc_do_dtors + +.section .init + call __mlibc_do_ctors + ret + +.section .fini + call __mlibc_do_dtors + ret + +.section .ctors +.hidden __CTOR_END__ +.global __CTOR_END__ +__CTOR_END__: + +.section .dtors +.hidden __DTOR_END__ +.global __DTOR_END__ +__DTOR_END__: + +.section .note.GNU-stack,"",%progbits + diff --git a/lib/mlibc/options/internal/x86/setjmp.S b/lib/mlibc/options/internal/x86/setjmp.S new file mode 100644 index 0000000..fa6644c --- /dev/null +++ b/lib/mlibc/options/internal/x86/setjmp.S @@ -0,0 +1,53 @@ + +.type __setjmp, "function" +__setjmp: + mov 4(%esp), %eax # Save argument (buffer) in edi + mov %ebx, 0x00(%eax) + mov %ebp, 0x04(%eax) + mov %esi, 0x08(%eax) + mov %edi, 0x0c(%eax) + + lea 4(%esp), %ecx # esp before return eip is pushed + mov %ecx, 0x10(%eax) + mov (%esp), %ecx # Return eip + mov %ecx, 0x14(%eax) + + test %edx, %edx + jnz 1f + xor %eax, %eax + ret + +1: + jmp __sigsetjmp@PLT + +.global setjmp +.type setjmp, "function" +setjmp: + xor %edx, %edx + jmp __setjmp + +.global sigsetjmp +.type sigsetjmp, "function" +sigsetjmp: + mov $1, %edx + jmp __setjmp + +.global longjmp +.type longjmp, "function" +longjmp: + mov 4(%esp), %ecx + mov 0x00(%ecx), %ebx + mov 0x04(%ecx), %ebp + mov 0x08(%ecx), %esi + mov 0x0c(%ecx), %edi + + mov 8(%esp), %eax + test %eax, %eax + jnz 1f + inc %eax +1: + mov 0x10(%ecx), %esp + jmp *0x14(%ecx) + +.section .note.GNU-stack,"",%progbits + |