You need to sign in or sign up before continuing.
提交 664cd341 编写于 作者: R rofl0r

x32 port (diff against vanilla x86_64)

上级 323272db
#define _Addr long #define _Addr int
#define _Int64 long #define _Int64 long long
#define _Reg long #define _Reg long long
TYPEDEF __builtin_va_list va_list; TYPEDEF __builtin_va_list va_list;
TYPEDEF __builtin_va_list __isoc_va_list; TYPEDEF __builtin_va_list __isoc_va_list;
#ifndef __cplusplus #ifndef __cplusplus
TYPEDEF int wchar_t; TYPEDEF long wchar_t;
#endif #endif
TYPEDEF unsigned wint_t; TYPEDEF unsigned wint_t;
...@@ -18,8 +18,8 @@ TYPEDEF float float_t; ...@@ -18,8 +18,8 @@ TYPEDEF float float_t;
TYPEDEF double double_t; TYPEDEF double double_t;
#endif #endif
TYPEDEF long time_t; TYPEDEF long long time_t;
TYPEDEF long suseconds_t; TYPEDEF long long suseconds_t;
TYPEDEF struct { union { int __i[14]; unsigned long __s[7]; } __u; } pthread_attr_t; TYPEDEF struct { union { int __i[14]; unsigned long __s[7]; } __u; } pthread_attr_t;
TYPEDEF struct { union { int __i[10]; void *__p[5]; } __u; } pthread_mutex_t; TYPEDEF struct { union { int __i[10]; void *__p[5]; } __u; } pthread_mutex_t;
......
...@@ -7,8 +7,8 @@ struct ipc_perm ...@@ -7,8 +7,8 @@ struct ipc_perm
gid_t cgid; gid_t cgid;
mode_t mode; mode_t mode;
int __ipc_perm_seq; int __ipc_perm_seq;
long __pad1; long long __pad1;
long __pad2; long long __pad2;
}; };
#define IPC_64 0 #define IPC_64 0
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#define PAGE_SIZE 4096 #define PAGE_SIZE 4096
#define LONG_BIT 64 #define LONG_BIT 32
#endif #endif
#define LONG_MAX 0x7fffffffffffffffL #define LONG_MAX 0x7fffffffL
#define LLONG_MAX 0x7fffffffffffffffLL #define LLONG_MAX 0x7fffffffffffffffLL
...@@ -5,9 +5,12 @@ struct msqid_ds ...@@ -5,9 +5,12 @@ struct msqid_ds
time_t msg_rtime; time_t msg_rtime;
time_t msg_ctime; time_t msg_ctime;
unsigned long msg_cbytes; unsigned long msg_cbytes;
long __unused1;
msgqnum_t msg_qnum; msgqnum_t msg_qnum;
long __unused2;
msglen_t msg_qbytes; msglen_t msg_qbytes;
long __unused3;
pid_t msg_lspid; pid_t msg_lspid;
pid_t msg_lrpid; pid_t msg_lrpid;
unsigned long __unused[2]; unsigned long long __unused[2];
}; };
#undef __WORDSIZE #undef __WORDSIZE
#define __WORDSIZE 64 #define __WORDSIZE 32
#define R15 0 #define R15 0
#define R14 1 #define R14 1
#define R13 2 #define R13 2
......
typedef unsigned long __jmp_buf[8]; typedef unsigned long long __jmp_buf[8];
...@@ -10,16 +10,24 @@ struct shmid_ds ...@@ -10,16 +10,24 @@ struct shmid_ds
pid_t shm_cpid; pid_t shm_cpid;
pid_t shm_lpid; pid_t shm_lpid;
unsigned long shm_nattch; unsigned long shm_nattch;
unsigned long __pad1; unsigned long __pad0;
unsigned long __pad2; unsigned long long __pad1;
unsigned long long __pad2;
}; };
struct shminfo { struct shminfo {
unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4]; unsigned long shmmax, __pad0, shmmin, __pad1, shmmni, __pad2,
shmseg, __pad3, shmall, __pad4;
unsigned long long __unused[4];
}; };
struct shm_info { struct shm_info {
int __used_ids; int __used_ids;
unsigned long shm_tot, shm_rss, shm_swp; int __pad_ids;
unsigned long __swap_attempts, __swap_successes; unsigned long shm_tot, __pad0, shm_rss, __pad1, shm_swp, __pad2;
}; unsigned long __swap_attempts, __pad3, __swap_successes, __pad4;
}
#ifdef __GNUC__
__attribute__((__aligned__(8)))
#endif
;
...@@ -42,12 +42,12 @@ typedef struct _fpstate { ...@@ -42,12 +42,12 @@ typedef struct _fpstate {
unsigned padding[24]; unsigned padding[24];
} *fpregset_t; } *fpregset_t;
struct sigcontext { struct sigcontext {
unsigned long r8, r9, r10, r11, r12, r13, r14, r15; unsigned long long r8, r9, r10, r11, r12, r13, r14, r15;
unsigned long rdi, rsi, rbp, rbx, rdx, rax, rcx, rsp, rip, eflags; unsigned long long rdi, rsi, rbp, rbx, rdx, rax, rcx, rsp, rip, eflags;
unsigned short cs, gs, fs, __pad0; unsigned short cs, gs, fs, __pad0;
unsigned long err, trapno, oldmask, cr2; unsigned long long err, trapno, oldmask, cr2;
struct _fpstate *fpstate; struct _fpstate *fpstate;
unsigned long __reserved1[8]; unsigned long long __reserved1[8];
}; };
typedef struct { typedef struct {
gregset_t gregs; gregset_t gregs;
...@@ -56,7 +56,7 @@ typedef struct { ...@@ -56,7 +56,7 @@ typedef struct {
} mcontext_t; } mcontext_t;
#else #else
typedef struct { typedef struct {
unsigned long __space[32]; unsigned long long __space[32];
} mcontext_t; } mcontext_t;
#endif #endif
...@@ -66,7 +66,7 @@ typedef struct __ucontext { ...@@ -66,7 +66,7 @@ typedef struct __ucontext {
stack_t uc_stack; stack_t uc_stack;
mcontext_t uc_mcontext; mcontext_t uc_mcontext;
sigset_t uc_sigmask; sigset_t uc_sigmask;
unsigned long __fpregs_mem[64]; unsigned long long __fpregs_mem[64];
} ucontext_t; } ucontext_t;
#define SA_NOCLDSTOP 1 #define SA_NOCLDSTOP 1
......
...@@ -18,5 +18,5 @@ struct stat { ...@@ -18,5 +18,5 @@ struct stat {
struct timespec st_atim; struct timespec st_atim;
struct timespec st_mtim; struct timespec st_mtim;
struct timespec st_ctim; struct timespec st_ctim;
long __unused[3]; long long __unused[3];
}; };
...@@ -12,9 +12,9 @@ typedef uint32_t uint_fast32_t; ...@@ -12,9 +12,9 @@ typedef uint32_t uint_fast32_t;
#define UINT_FAST16_MAX UINT32_MAX #define UINT_FAST16_MAX UINT32_MAX
#define UINT_FAST32_MAX UINT32_MAX #define UINT_FAST32_MAX UINT32_MAX
#define INTPTR_MIN INT64_MIN #define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT64_MAX #define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT64_MAX #define UINTPTR_MAX UINT32_MAX
#define PTRDIFF_MIN INT64_MIN #define PTRDIFF_MIN INT32_MIN
#define PTRDIFF_MAX INT64_MAX #define PTRDIFF_MAX INT32_MAX
#define SIZE_MAX UINT64_MAX #define SIZE_MAX UINT32_MAX
此差异已折叠。
#include <sys/syscall.h>
long __syscall_cp_internal(volatile void*, long long, long long, long long, long long,
long long, long long, long long);
struct __timespec { long long tv_sec; long tv_nsec; };
struct __timespec_kernel { long long tv_sec; long long tv_nsec; };
#define __tsc(X) ((struct __timespec*)(unsigned long)(X))
long __syscall_cp_asm (volatile void * foo, long long n, long long a1, long long a2, long long a3,
long long a4, long long a5, long long a6) {
switch (n) {
case SYS_mq_timedsend: case SYS_mq_timedreceive: case SYS_pselect6:
if(a5) a5 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(a5)->tv_sec, .tv_nsec = __tsc(a5)->tv_nsec});
break;
case SYS_futex:
if(a4) a4 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(a4)->tv_sec, .tv_nsec = __tsc(a4)->tv_nsec});
if(n == SYS_futex) break;
case SYS_clock_nanosleep:
case SYS_rt_sigtimedwait: case SYS_ppoll:
if(a3) a3 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(a3)->tv_sec, .tv_nsec = __tsc(a3)->tv_nsec});
break;
case SYS_nanosleep:
if(a1) a1 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(a1)->tv_sec, .tv_nsec = __tsc(a1)->tv_nsec});
if(a2) a2 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(a2)->tv_sec, .tv_nsec = __tsc(a2)->tv_nsec});
break;
}
return __syscall_cp_internal(foo, n, a1, a2, a3, a4, a5, a6);
}
#define __SYSCALL_LL_E(x) (x) #define __SYSCALL_LL_E(x) (x)
#define __SYSCALL_LL_O(x) (x) #define __SYSCALL_LL_O(x) (x)
static __inline long __syscall0(long n) #define __scc(X) sizeof(1?(X):0ULL) < 8 ? (unsigned long) (X) : (long long) (X)
#define syscall_arg_t long long
struct __timespec { long long tv_sec; long tv_nsec; };
struct __timespec_kernel { long long tv_sec; long long tv_nsec; };
#define __tsc(X) ((struct __timespec*)(unsigned long)(X))
static __inline long __syscall0(long long n)
{ {
unsigned long ret; unsigned long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory"); __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory");
return ret; return ret;
} }
static __inline long __syscall1(long n, long a1) static __inline long __syscall1(long long n, long long a1)
{ {
unsigned long ret; unsigned long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory"); __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory");
return ret; return ret;
} }
static __inline long __syscall2(long n, long a1, long a2) static __inline long __syscall2(long long n, long long a1, long long a2)
{ {
unsigned long ret; unsigned long ret;
struct __timespec *ts2 = 0;
switch (n) {
case SYS_nanosleep:
if(a1) a1 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(a1)->tv_sec, .tv_nsec = __tsc(a1)->tv_nsec});
break;
case SYS_clock_settime:
if(a2) a2 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(a2)->tv_sec, .tv_nsec = __tsc(a2)->tv_nsec});
}
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2) __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
return ret; return ret;
} }
static __inline long __syscall3(long n, long a1, long a2, long a3) static __inline long __syscall3(long long n, long long a1, long long a2, long long a3)
{ {
unsigned long ret; unsigned long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
...@@ -31,32 +47,75 @@ static __inline long __syscall3(long n, long a1, long a2, long a3) ...@@ -31,32 +47,75 @@ static __inline long __syscall3(long n, long a1, long a2, long a3)
return ret; return ret;
} }
static __inline long __syscall4(long n, long a1, long a2, long a3, long a4) static __inline long __syscall4(long long n, long long a1, long long a2, long long a3,
long long a4)
{ {
unsigned long ret; unsigned long ret;
register long r10 __asm__("r10") = a4; register long long r10 __asm__("r10") = a4;
switch (n) {
case SYS_futex:
if((a2 & (~128 /* FUTEX_PRIVATE_FLAG */)) == 0 /* FUTEX_WAIT */) {
if(r10) r10 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(r10)->tv_sec, .tv_nsec = __tsc(r10)->tv_nsec});
}
break;
case SYS_utimensat:
if(a3) a3 = (unsigned long) ((struct __timespec_kernel[2]) {
[0] = {.tv_sec = __tsc(a3)[0].tv_sec, .tv_nsec = __tsc(a3)[0].tv_nsec},
[1] = {.tv_sec = __tsc(a3)[1].tv_sec, .tv_nsec = __tsc(a3)[1].tv_nsec},
});
break;
case SYS_clock_nanosleep:
case SYS_rt_sigtimedwait: case SYS_ppoll:
if(a3) a3 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(a3)->tv_sec, .tv_nsec = __tsc(a3)->tv_nsec});
}
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
"d"(a3), "r"(r10): "rcx", "r11", "memory"); "d"(a3), "r"(r10): "rcx", "r11", "memory");
return ret; return ret;
} }
static __inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5) static __inline long __syscall5(long long n, long long a1, long long a2, long long a3,
long long a4, long long a5)
{ {
unsigned long ret; unsigned long ret;
register long r10 __asm__("r10") = a4; register long long r10 __asm__("r10") = a4;
register long r8 __asm__("r8") = a5; register long long r8 __asm__("r8") = a5;
switch (n) {
case SYS_futex:
if((a2 & (~128 /* FUTEX_PRIVATE_FLAG */)) == 0 /* FUTEX_WAIT */) {
if(r10) r10 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(r10)->tv_sec, .tv_nsec = __tsc(r10)->tv_nsec});
}
break;
case SYS_mq_timedsend: case SYS_mq_timedreceive:
if(r8) r8 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(r8)->tv_sec, .tv_nsec = __tsc(r8)->tv_nsec});
}
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
"d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory"); "d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory");
return ret; return ret;
} }
static __inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6) static __inline long __syscall6(long long n, long long a1, long long a2, long long a3,
long long a4, long long a5, long long a6)
{ {
unsigned long ret; unsigned long ret;
register long r10 __asm__("r10") = a4; register long long r10 __asm__("r10") = a4;
register long r8 __asm__("r8") = a5; register long long r8 __asm__("r8") = a5;
register long r9 __asm__("r9") = a6; register long long r9 __asm__("r9") = a6;
switch (n) {
case SYS_futex:
if((a2 & (~128 /* FUTEX_PRIVATE_FLAG */)) == 0 /* FUTEX_WAIT */) {
if(r10) r10 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(r10)->tv_sec, .tv_nsec = __tsc(r10)->tv_nsec});
}
break;
case SYS_pselect6:
if(r8) r8 = (unsigned long) (&(struct __timespec_kernel) {
.tv_sec = __tsc(r8)->tv_sec, .tv_nsec = __tsc(r8)->tv_nsec});
}
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
"d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory"); "d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory");
return ret; return ret;
} }
...@@ -8,14 +8,14 @@ feclearexcept: ...@@ -8,14 +8,14 @@ feclearexcept:
test %eax,%ecx test %eax,%ecx
jz 1f jz 1f
fnclex fnclex
1: stmxcsr -8(%rsp) 1: stmxcsr -8(%esp)
and $0x3f,%eax and $0x3f,%eax
or %eax,-8(%rsp) or %eax,-8(%esp)
test %ecx,-8(%rsp) test %ecx,-8(%esp)
jz 1f jz 1f
not %ecx not %ecx
and %ecx,-8(%rsp) and %ecx,-8(%esp)
ldmxcsr -8(%rsp) ldmxcsr -8(%esp)
1: xor %eax,%eax 1: xor %eax,%eax
ret ret
...@@ -23,9 +23,9 @@ feclearexcept: ...@@ -23,9 +23,9 @@ feclearexcept:
.type feraiseexcept,@function .type feraiseexcept,@function
feraiseexcept: feraiseexcept:
and $0x3f,%edi and $0x3f,%edi
stmxcsr -8(%rsp) stmxcsr -8(%esp)
or %edi,-8(%rsp) or %edi,-8(%esp)
ldmxcsr -8(%rsp) ldmxcsr -8(%esp)
xor %eax,%eax xor %eax,%eax
ret ret
...@@ -35,15 +35,15 @@ __fesetround: ...@@ -35,15 +35,15 @@ __fesetround:
push %rax push %rax
xor %eax,%eax xor %eax,%eax
mov %edi,%ecx mov %edi,%ecx
fnstcw (%rsp) fnstcw (%esp)
andb $0xf3,1(%rsp) andb $0xf3,1(%esp)
or %ch,1(%rsp) or %ch,1(%esp)
fldcw (%rsp) fldcw (%esp)
stmxcsr (%rsp) stmxcsr (%esp)
shl $3,%ch shl $3,%ch
andb $0x9f,1(%rsp) andb $0x9f,1(%esp)
or %ch,1(%rsp) or %ch,1(%esp)
ldmxcsr (%rsp) ldmxcsr (%esp)
pop %rcx pop %rcx
ret ret
...@@ -51,7 +51,7 @@ __fesetround: ...@@ -51,7 +51,7 @@ __fesetround:
.type fegetround,@function .type fegetround,@function
fegetround: fegetround:
push %rax push %rax
stmxcsr (%rsp) stmxcsr (%esp)
pop %rax pop %rax
shr $3,%eax shr $3,%eax
and $0xc00,%eax and $0xc00,%eax
...@@ -61,27 +61,27 @@ fegetround: ...@@ -61,27 +61,27 @@ fegetround:
.type fegetenv,@function .type fegetenv,@function
fegetenv: fegetenv:
xor %eax,%eax xor %eax,%eax
fnstenv (%rdi) fnstenv (%edi)
stmxcsr 28(%rdi) stmxcsr 28(%edi)
ret ret
.global fesetenv .global fesetenv
.type fesetenv,@function .type fesetenv,@function
fesetenv: fesetenv:
xor %eax,%eax xor %eax,%eax
inc %rdi inc %edi
jz 1f jz 1f
fldenv -1(%rdi) fldenv -1(%edi)
ldmxcsr 27(%rdi) ldmxcsr 27(%edi)
ret ret
1: push %rax 1: push %rax
push %rax push %rax
pushq $0xffff pushq $0xffff
pushq $0x37f pushq $0x37f
fldenv (%rsp) fldenv (%esp)
pushq $0x1f80 pushq $0x1f80
ldmxcsr (%rsp) ldmxcsr (%esp)
add $40,%rsp add $40,%esp
ret ret
.global fetestexcept .global fetestexcept
...@@ -89,7 +89,7 @@ fesetenv: ...@@ -89,7 +89,7 @@ fesetenv:
fetestexcept: fetestexcept:
and $0x3f,%edi and $0x3f,%edi
push %rax push %rax
stmxcsr (%rsp) stmxcsr (%esp)
pop %rsi pop %rsi
fnstsw %ax fnstsw %ax
or %esi,%eax or %esi,%eax
......
.text .text
.global _start .global _start
_start: _start:
mov (%rsp),%rdi mov (%rsp),%rdi /* move argc into 1st argument slot */
lea 8(%rsp),%rsi lea 4(%rsp),%rsi /* move argv into 2nd argument slot */
call __dynlink call __dynlink
pop %rdi /* in case the dynlinker was called directly, it sets the "consumed"
argv values to -1. so we must loop over the array as long as -1
is in the top argv slot, decrement argc, and then set the stackpointer
to the new argc as well as argc's new value.
as the x32 abi has longs in the argv array, we cannot use push/pop.*/
movl (%rsp),%edi /* copy argc into edi */
xor %rdx,%rdx /* we use rdx as an offset to the current argv member */
1: dec %edi 1: dec %edi
pop %rsi addl $4, %edx
cmp $-1,%rsi movl (%rsp, %rdx), %esi
cmp $-1,%esi
jz 1b jz 1b
inc %edi inc %edi
push %rsi subl $4, %edx
push %rdi lea (%rsp, %rdx), %rsp /* set rsp to new argv[-1] */
movl %edi, (%rsp) /* write new argc there */
xor %edx,%edx xor %edx,%edx
jmp *%rax jmp *%rax
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.global acosl .global acosl
.type acosl,@function .type acosl,@function
acosl: acosl:
fldt 8(%rsp) fldt 8(%esp)
1: fld %st(0) 1: fld %st(0)
fld1 fld1
fsub %st(0),%st(1) fsub %st(0),%st(1)
......
.global asinl .global asinl
.type asinl,@function .type asinl,@function
asinl: asinl:
fldt 8(%rsp) fldt 8(%esp)
1: fld %st(0) 1: fld %st(0)
fld1 fld1
fsub %st(0),%st(1) fsub %st(0),%st(1)
......
.global atan2l .global atan2l
.type atan2l,@function .type atan2l,@function
atan2l: atan2l:
fldt 8(%rsp) fldt 8(%esp)
fldt 24(%rsp) fldt 24(%esp)
fpatan fpatan
ret ret
.global atanl .global atanl
.type atanl,@function .type atanl,@function
atanl: atanl:
fldt 8(%rsp) fldt 8(%esp)
fld1 fld1
fpatan fpatan
ret ret
.global expm1l .global expm1l
.type expm1l,@function .type expm1l,@function
expm1l: expm1l:
fldt 8(%rsp) fldt 8(%esp)
fldl2e fldl2e
fmulp fmulp
movl $0xc2820000,-4(%rsp) movl $0xc2820000,-4(%esp)
flds -4(%rsp) flds -4(%esp)
fucomp %st(1) fucomp %st(1)
fnstsw %ax fnstsw %ax
sahf sahf
...@@ -35,21 +35,21 @@ expm1l: ...@@ -35,21 +35,21 @@ expm1l:
.global exp2l .global exp2l
.type exp2l,@function .type exp2l,@function
exp2l: exp2l:
fldt 8(%rsp) fldt 8(%esp)
1: fld %st(0) 1: fld %st(0)
sub $16,%rsp sub $16,%esp
fstpt (%rsp) fstpt (%esp)
mov 8(%rsp),%ax mov 8(%esp),%ax
and $0x7fff,%ax and $0x7fff,%ax
cmp $0x3fff+13,%ax cmp $0x3fff+13,%ax
jb 4f # |x| < 8192 jb 4f # |x| < 8192
cmp $0x3fff+15,%ax cmp $0x3fff+15,%ax
jae 3f # |x| >= 32768 jae 3f # |x| >= 32768
fsts (%rsp) fsts (%esp)
cmpl $0xc67ff800,(%rsp) cmpl $0xc67ff800,(%esp)
jb 2f # x > -16382 jb 2f # x > -16382
movl $0x5f000000,(%rsp) movl $0x5f000000,(%esp)
flds (%rsp) # 0x1p63 flds (%esp) # 0x1p63
fld %st(1) fld %st(1)
fsub %st(1) fsub %st(1)
faddp faddp
...@@ -57,10 +57,10 @@ exp2l: ...@@ -57,10 +57,10 @@ exp2l:
fnstsw fnstsw
sahf sahf
je 2f # x - 0x1p63 + 0x1p63 == x je 2f # x - 0x1p63 + 0x1p63 == x
movl $1,(%rsp) movl $1,(%esp)
flds (%rsp) # 0x1p-149 flds (%esp) # 0x1p-149
fdiv %st(1) fdiv %st(1)
fstps (%rsp) # raise underflow fstps (%esp) # raise underflow
2: fld1 2: fld1
fld %st(1) fld %st(1)
frndint frndint
...@@ -70,21 +70,21 @@ exp2l: ...@@ -70,21 +70,21 @@ exp2l:
faddp # 2^(x-rint(x)) faddp # 2^(x-rint(x))
1: fscale 1: fscale
fstp %st(1) fstp %st(1)
add $16,%rsp add $16,%esp
ret ret
3: xor %eax,%eax 3: xor %eax,%eax
4: cmp $0x3fff-64,%ax 4: cmp $0x3fff-64,%ax
fld1 fld1
jb 1b # |x| < 0x1p-64 jb 1b # |x| < 0x1p-64
fstpt (%rsp) fstpt (%esp)
fistl 8(%rsp) fistl 8(%esp)
fildl 8(%rsp) fildl 8(%esp)
fsubrp %st(1) fsubrp %st(1)
addl $0x3fff,8(%rsp) addl $0x3fff,8(%esp)
f2xm1 f2xm1
fld1 fld1
faddp # 2^(x-rint(x)) faddp # 2^(x-rint(x))
fldt (%rsp) # 2^rint(x) fldt (%esp) # 2^rint(x)
fmulp fmulp
add $16,%rsp add $16,%esp
ret ret
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
.global expl .global expl
.type expl,@function .type expl,@function
expl: expl:
fldt 8(%rsp) fldt 8(%esp)
# interesting case: 0x1p-32 <= |x| < 16384 # interesting case: 0x1p-32 <= |x| < 16384
# check if (exponent|0x8000) is in [0xbfff-32, 0xbfff+13] # check if (exponent|0x8000) is in [0xbfff-32, 0xbfff+13]
mov 16(%rsp), %ax mov 16(%esp), %ax
or $0x8000, %ax or $0x8000, %ax
sub $0xbfdf, %ax sub $0xbfdf, %ax
cmp $45, %ax cmp $45, %ax
...@@ -29,29 +29,29 @@ expl: ...@@ -29,29 +29,29 @@ expl:
# should be 0x1.71547652b82fe178p0L == 0x3fff b8aa3b29 5c17f0bc # should be 0x1.71547652b82fe178p0L == 0x3fff b8aa3b29 5c17f0bc
# it will be wrong on non-nearest rounding mode # it will be wrong on non-nearest rounding mode
2: fldl2e 2: fldl2e
subq $48, %rsp sub $48, %esp
# hi = log2e_hi*x # hi = log2e_hi*x
# 2^hi = exp2l(hi) # 2^hi = exp2l(hi)
fmul %st(1),%st fmul %st(1),%st
fld %st(0) fld %st(0)
fstpt (%rsp) fstpt (%esp)
fstpt 16(%rsp) fstpt 16(%esp)
fstpt 32(%rsp) fstpt 32(%esp)
call exp2l call exp2l
# if 2^hi == inf return 2^hi # if 2^hi == inf return 2^hi
fld %st(0) fld %st(0)
fstpt (%rsp) fstpt (%esp)
cmpw $0x7fff, 8(%rsp) cmpw $0x7fff, 8(%esp)
je 1f je 1f
fldt 32(%rsp) fldt 32(%esp)
fldt 16(%rsp) fldt 16(%esp)
# fpu stack: 2^hi x hi # fpu stack: 2^hi x hi
# exact mult: x*log2e # exact mult: x*log2e
fld %st(1) fld %st(1)
# c = 0x1p32+1 # c = 0x1p32+1
movq $0x41f0000000100000,%rax movq $0x41f0000000100000,%rax
pushq %rax pushq %rax
fldl (%rsp) fldl (%esp)
# xh = x - c*x + c*x # xh = x - c*x + c*x
# xl = x - xh # xl = x - xh
fmulp fmulp
...@@ -63,7 +63,7 @@ expl: ...@@ -63,7 +63,7 @@ expl:
# yh = log2e_hi - c*log2e_hi + c*log2e_hi # yh = log2e_hi - c*log2e_hi + c*log2e_hi
movq $0x3ff7154765200000,%rax movq $0x3ff7154765200000,%rax
pushq %rax pushq %rax
fldl (%rsp) fldl (%esp)
# fpu stack: 2^hi x hi xh xl yh # fpu stack: 2^hi x hi xh xl yh
# lo = hi - xh*yh + xl*yh # lo = hi - xh*yh + xl*yh
fld %st(2) fld %st(2)
...@@ -74,7 +74,7 @@ expl: ...@@ -74,7 +74,7 @@ expl:
# yl = log2e_hi - yh # yl = log2e_hi - yh
movq $0x3de705fc2f000000,%rax movq $0x3de705fc2f000000,%rax
pushq %rax pushq %rax
fldl (%rsp) fldl (%esp)
# fpu stack: 2^hi x lo xh xl yl # fpu stack: 2^hi x lo xh xl yl
# lo += xh*yl + xl*yl # lo += xh*yl + xl*yl
fmul %st, %st(2) fmul %st, %st(2)
...@@ -87,8 +87,8 @@ expl: ...@@ -87,8 +87,8 @@ expl:
pushq %rax pushq %rax
movq $0x82f0025f2dc582ee,%rax movq $0x82f0025f2dc582ee,%rax
pushq %rax pushq %rax
fldt (%rsp) fldt (%esp)
addq $40,%rsp add $40,%esp
# fpu stack: 2^hi x lo log2e_lo # fpu stack: 2^hi x lo log2e_lo
# lo += log2e_lo*x # lo += log2e_lo*x
# return 2^hi + 2^hi (2^lo - 1) # return 2^hi + 2^hi (2^lo - 1)
...@@ -97,5 +97,5 @@ expl: ...@@ -97,5 +97,5 @@ expl:
f2xm1 f2xm1
fmul %st(1), %st fmul %st(1), %st
faddp faddp
1: addq $48, %rsp 1: add $48, %esp
ret ret
.global fabsl .global fabsl
.type fabsl,@function .type fabsl,@function
fabsl: fabsl:
fldt 8(%rsp) fldt 8(%esp)
fabs fabs
ret ret
.global floorl .global floorl
.type floorl,@function .type floorl,@function
floorl: floorl:
fldt 8(%rsp) fldt 8(%esp)
1: mov $0x7,%al 1: mov $0x7,%al
1: fstcw 8(%rsp) 1: fstcw 8(%esp)
mov 9(%rsp),%ah mov 9(%esp),%ah
mov %al,9(%rsp) mov %al,9(%esp)
fldcw 8(%rsp) fldcw 8(%esp)
frndint frndint
mov %ah,9(%rsp) mov %ah,9(%esp)
fldcw 8(%rsp) fldcw 8(%esp)
ret ret
.global ceill .global ceill
.type ceill,@function .type ceill,@function
ceill: ceill:
fldt 8(%rsp) fldt 8(%esp)
mov $0xb,%al mov $0xb,%al
jmp 1b jmp 1b
.global truncl .global truncl
.type truncl,@function .type truncl,@function
truncl: truncl:
fldt 8(%rsp) fldt 8(%esp)
mov $0xf,%al mov $0xf,%al
jmp 1b jmp 1b
.global fmodl .global fmodl
.type fmodl,@function .type fmodl,@function
fmodl: fmodl:
fldt 24(%rsp) fldt 24(%esp)
fldt 8(%rsp) fldt 8(%esp)
1: fprem 1: fprem
fstsw %ax fstsw %ax
sahf sahf
......
.global llrintl .global llrintl
.type llrintl,@function .type llrintl,@function
llrintl: llrintl:
fldt 8(%rsp) fldt 8(%esp)
fistpll 8(%rsp) fistpll 8(%esp)
mov 8(%rsp),%rax mov 8(%esp),%rax
ret ret
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
.type log10l,@function .type log10l,@function
log10l: log10l:
fldlg2 fldlg2
fldt 8(%rsp) fldt 8(%esp)
fyl2x fyl2x
ret ret
.global log1pl .global log1pl
.type log1pl,@function .type log1pl,@function
log1pl: log1pl:
mov 14(%rsp),%eax mov 14(%esp),%eax
fldln2 fldln2
and $0x7fffffff,%eax and $0x7fffffff,%eax
fldt 8(%rsp) fldt 8(%esp)
cmp $0x3ffd9400,%eax cmp $0x3ffd9400,%eax
ja 1f ja 1f
fyl2xp1 fyl2xp1
......
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
.type log2l,@function .type log2l,@function
log2l: log2l:
fld1 fld1
fldt 8(%rsp) fldt 8(%esp)
fyl2x fyl2x
ret ret
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
.type logl,@function .type logl,@function
logl: logl:
fldln2 fldln2
fldt 8(%rsp) fldt 8(%esp)
fyl2x fyl2x
ret ret
.global lrintl .global lrintl
.type lrintl,@function .type lrintl,@function
lrintl: lrintl:
fldt 8(%rsp) fldt 8(%esp)
fistpll 8(%rsp) fistpll 8(%esp)
mov 8(%rsp),%rax mov 8(%esp),%rax
ret ret
.global remainderl .global remainderl
.type remainderl,@function .type remainderl,@function
remainderl: remainderl:
fldt 24(%rsp) fldt 24(%esp)
fldt 8(%rsp) fldt 8(%esp)
1: fprem1 1: fprem1
fstsw %ax fstsw %ax
sahf sahf
......
.global rintl .global rintl
.type rintl,@function .type rintl,@function
rintl: rintl:
fldt 8(%rsp) fldt 8(%esp)
frndint frndint
ret ret
.global sqrtl .global sqrtl
.type sqrtl,@function .type sqrtl,@function
sqrtl: fldt 8(%rsp) sqrtl: fldt 8(%esp)
fsqrt fsqrt
ret ret
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
__vfork: __vfork:
vfork: vfork:
pop %rdx pop %rdx
mov $58,%eax mov $0x4000003a,%eax /* SYS_vfork */
syscall syscall
push %rdx push %rdx
mov %rax,%rdi mov %rax,%rdi
......
...@@ -4,5 +4,5 @@ ...@@ -4,5 +4,5 @@
.type __restore,@function .type __restore,@function
__restore_rt: __restore_rt:
__restore: __restore:
movl $15, %eax movl $0x40000201, %eax /* SYS_rt_sigreturn */
syscall syscall
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
__set_thread_area: __set_thread_area:
mov %rdi,%rsi /* shift for syscall */ mov %rdi,%rsi /* shift for syscall */
movl $0x1002,%edi /* SET_FS register */ movl $0x1002,%edi /* SET_FS register */
movl $158,%eax /* set fs segment to */ movl $0x4000009e,%eax /* set fs segment to */
syscall /* arch_prctl(SET_FS, arg)*/ syscall /* arch_prctl(SET_FS, arg)*/
ret ret
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
.global __unmapself .global __unmapself
.type __unmapself,@function .type __unmapself,@function
__unmapself: __unmapself:
movl $11,%eax /* SYS_munmap */ movl $0x4000000b,%eax /* SYS_munmap */
syscall /* munmap(arg2,arg3) */ syscall /* munmap(arg2,arg3) */
xor %rdi,%rdi /* exit() args: always return success */ xor %rdi,%rdi /* exit() args: always return success */
movl $60,%eax /* SYS_exit */ movl $0x4000003c,%eax /* SYS_exit */
syscall /* exit(0) */ syscall /* exit(0) */
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
.global __clone .global __clone
.type __clone,@function .type __clone,@function
__clone: __clone:
xor %eax,%eax movl $0x40000038,%eax /* SYS_clone */
mov $56,%al
mov %rdi,%r11 mov %rdi,%r11
mov %rdx,%rdi mov %rdx,%rdi
mov %r8,%rdx mov %r8,%rdx
...@@ -20,8 +19,7 @@ __clone: ...@@ -20,8 +19,7 @@ __clone:
pop %rdi pop %rdi
call *%r9 call *%r9
mov %eax,%edi mov %eax,%edi
xor %eax,%eax movl $0x4000003c,%eax /* SYS_exit */
mov $60,%al
syscall syscall
hlt hlt
1: ret 1: ret
.text .text
.global __syscall_cp_asm .global __syscall_cp_internal
.type __syscall_cp_asm,@function .type __syscall_cp_internal,@function
__syscall_cp_asm: __syscall_cp_internal:
.global __cp_begin .global __cp_begin
__cp_begin: __cp_begin:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册