--- /dev/null
+/*
+ * arch/i386/setjmp.S
+ *
+ * setjmp/longjmp for the i386 architecture
+ *
+ *
+ *
+ * The jmp_buf is assumed to contain the following, in order:
+ * %ebx
+ * %esp
+ * %ebp
+ * %esi
+ * %edi
+ * <return address>
+ */
+
+ .text
+ .align 4
+
+ .globl _setjmp
+ .type _setjmp, @function
+_setjmp: # gcc 4.0.1 wants this as an alias?
+
+ .globl setjmp
+ .type setjmp, @function
+setjmp:
+#ifdef REGPARM
+ movl %eax,%edx
+#else
+ movl 4(%esp),%edx
+#endif
+ popl %ecx # Return address, and adjust the stack
+ xorl %eax,%eax # Return value
+ movl %ebx,(%edx)
+ movl %esp,4(%edx) # Post-return %esp!
+ pushl %ecx # Make the call/return stack happy
+ movl %ebp,8(%edx)
+ movl %esi,12(%edx)
+ movl %edi,16(%edx)
+ movl %ecx,20(%edx) # Return address
+ ret
+
+ .size setjmp,.-setjmp
+
+ .text
+ .align 4
+ .globl longjmp
+ .type longjmp, @function
+longjmp:
+#ifdef REGPARM
+ xchgl %eax,%edx
+#else
+ movl 4(%esp),%edx # jmp_ptr address
+ movl 8(%esp),%eax # Return value
+#endif
+ movl (%edx),%ebx
+ movl 4(%edx),%esp
+ movl 8(%edx),%ebp
+ movl 12(%edx),%esi
+ movl 16(%edx),%edi
+ jmp *20(%edx)
+
+ .size longjmp,.-longjmp
.globl __muldi3
.type __muldi3,@function
__muldi3:
+#if __SIZEOF_POINTER__ == 4
+ /* i386 */
push %esi
#ifndef REGPARM
movl 8(%esp),%eax
#endif
pop %esi
ret
+#elif __SIZEOF_POINTER__ == 8
+ /* x86_64 */
+ push %rsi
+#ifndef REGPARM
+/*
+ movl 8(%esp),%eax
+ movl %eax,%esi
+ movl 16(%esp),%ecx
+ mull %ecx
+ imull 12(%esp),%ecx
+ imull 20(%esp),%esi
+ addl %ecx,%edx
+ addl %esi,%edx
+*/
+ movq 8(%rsp),%rax
+ movq %rax,%rsi
+ movq 16(%rsp),%rcx
+ mulq %rcx
+ imulq 12(%rsp),%rcx
+ imulq 20(%rsp),%rsi
+ addq %rcx,%rdx
+ addq %rsi,%rdx
+#else
+/*
+ movl %eax,%esi
+ push %edx
+ mull %ecx
+ imull 8(%esp),%esi
+ addl %esi,%edx
+ pop %rsi
+ imull %esi,%ecx
+ addl %ecx,%edx
+*/
+ movq %rax,%rsi
+ pushq %rdx
+ mulq %rcx
+ imulq 8(%rsp),%rsi
+ addq %rsi,%rdx
+ popq %rsi
+ imulq %rsi,%rcx
+ addq %rcx,%rdx
+#endif
+ pop %rsi
+ ret
+#else
+#error "Unsupported architecture for __muldi3.S"
+#endif
.size __muldi3,.-__muldi3
--- /dev/null
+/*
+ * memcpy.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+void *memcpy(void *dst, const void *src, size_t n)
+{
+ const char *p = src;
+ char *q = dst;
+#if defined(__i386__)
+ size_t nl = n >> 2;
+ asm volatile ("cld ; rep ; movsl ; movl %3,%0 ; rep ; movsb":"+c" (nl),
+ "+S"(p), "+D"(q)
+ :"r"(n & 3));
+#elif defined(__x86_64__)
+ size_t nq = n >> 3;
+ asm volatile ("cld ; rep ; movsq ; movl %3,%%ecx ; rep ; movsb":"+c"
+ (nq), "+S"(p), "+D"(q)
+ :"r"((uint32_t) (n & 7)));
+#else
+ while (n--) {
+ *q++ = *p++;
+ }
+#endif
+
+ return dst;
+}
--- /dev/null
+/*
+ * memmove.c
+ */
+
+#include <string.h>
+
+void *memmove(void *dst, const void *src, size_t n)
+{
+ const char *p = src;
+ char *q = dst;
+#if defined(__i386__) || defined(__x86_64__)
+ if (q < p) {
+ asm volatile("cld; rep; movsb"
+ : "+c" (n), "+S"(p), "+D"(q));
+ } else {
+ p += (n - 1);
+ q += (n - 1);
+ asm volatile("std; rep; movsb; cld"
+ : "+c" (n), "+S"(p), "+D"(q));
+ }
+#else
+ if (q < p) {
+ while (n--) {
+ *q++ = *p++;
+ }
+ } else {
+ p += n;
+ q += n;
+ while (n--) {
+ *--q = *--p;
+ }
+ }
+#endif
+
+ return dst;
+}
--- /dev/null
+/*
+ * mempcpy.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+/* simply a wrapper around memcpy implementation */
+
+void *mempcpy(void *dst, const void *src, size_t n)
+{
+
+ return (char *)memcpy(dst, src, n) + n;
+}
--- /dev/null
+/*
+ * memset.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+void *memset(void *dst, int c, size_t n)
+{
+ char *q = dst;
+
+#if defined(__i386__)
+ size_t nl = n >> 2;
+ asm volatile ("cld ; rep ; stosl ; movl %3,%0 ; rep ; stosb"
+ : "+c" (nl), "+D" (q)
+ : "a" ((unsigned char)c * 0x01010101U), "r" (n & 3));
+#elif defined(__x86_64__)
+ size_t nq = n >> 3;
+ asm volatile ("cld ; rep ; stosq ; movl %3,%%ecx ; rep ; stosb"
+ :"+c" (nq), "+D" (q)
+ : "a" ((unsigned char)c * 0x0101010101010101U),
+ "r" ((uint32_t) n & 7));
+#else
+ while (n--) {
+ *q++ = c;
+ }
+#endif
+
+ return dst;
+}
* %edi
* <return address>
*/
-
+/*
.text
.align 4
jmp *20(%edx)
.size longjmp,.-longjmp
+*/
+#if __SIZEOF_POINTER__ == 4
+#include <i386/setjmp.S>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/setjmp.S>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+
static inline uint32_t eflags(void)
{
- uint32_t v;
+ //uint32_t v;
+#if __SIZEOF_POINTER__ == 4
+ uint32_t v;
asm volatile("pushfl ; popl %0" : "=rm" (v));
+#elif __SIZEOF_POINTER__ == 8
+ uint64_t v;
+ asm volatile("pushfq ; pop %0" : "=rm" (v));
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
return v;
}
--- /dev/null
+/*
+ * x86_has_fpu.c
+ *
+ * Test for an x86 FPU, and do any necessary setup.
+ */
+
+#include <inttypes.h>
+#include <sys/fpu.h>
+
+static inline uint64_t get_cr0(void)
+{
+ uint32_t v;
+asm("movl %%cr0,%0":"=r"(v));
+ return v;
+}
+
+static inline void set_cr0(uint32_t v)
+{
+ asm volatile ("movl %0,%%cr0"::"r" (v));
+}
+
+#define CR0_PE 0x00000001
+#define CR0_MP 0x00000002
+#define CR0_EM 0x00000004
+#define CR0_TS 0x00000008
+#define CR0_ET 0x00000010
+#define CR0_NE 0x00000020
+#define CR0_WP 0x00010000
+#define CR0_AM 0x00040000
+#define CR0_NW 0x20000000
+#define CR0_CD 0x40000000
+#define CR0_PG 0x80000000
+
+int x86_init_fpu(void)
+{
+ uint32_t cr0;
+ uint16_t fsw = 0xffff;
+ uint16_t fcw = 0xffff;
+
+ cr0 = get_cr0();
+ cr0 &= ~(CR0_EM | CR0_TS);
+ cr0 |= CR0_MP;
+ set_cr0(cr0);
+
+ asm volatile ("fninit");
+ asm volatile ("fnstsw %0":"+m" (fsw));
+ if (fsw != 0)
+ return -1;
+
+ asm volatile ("fnstcw %0":"+m" (fcw));
+ if ((fcw & 0x103f) != 0x3f)
+ return -1;
+
+ /* Techically, this could be a 386 with a 287. We could add a check
+ for that here... */
+
+ return 0;
+}
--- /dev/null
+/*
+ * x86_has_fpu.c
+ *
+ * Test for an x86 FPU, and do any necessary setup.
+ */
+
+#include <inttypes.h>
+#include <sys/fpu.h>
+
+static inline uint64_t get_cr0(void)
+{
+ uint64_t v;
+asm("movq %%cr0,%0":"=r"(v));
+ return v;
+}
+
+static inline void set_cr0(uint32_t v)
+{
+ asm volatile ("movq %0,%%cr0"::"r" ((uint64_t)v));
+}
+
+#define CR0_PE 0x00000001
+#define CR0_MP 0x00000002
+#define CR0_EM 0x00000004
+#define CR0_TS 0x00000008
+#define CR0_ET 0x00000010
+#define CR0_NE 0x00000020
+#define CR0_WP 0x00010000
+#define CR0_AM 0x00040000
+#define CR0_NW 0x20000000
+#define CR0_CD 0x40000000
+#define CR0_PG 0x80000000
+
+int x86_init_fpu(void)
+{
+ uint32_t cr0;
+ uint16_t fsw = 0xffff;
+ uint16_t fcw = 0xffff;
+
+ cr0 = get_cr0();
+ cr0 &= ~(CR0_EM | CR0_TS);
+ cr0 |= CR0_MP;
+ set_cr0(cr0);
+
+ asm volatile ("fninit");
+ asm volatile ("fnstsw %0":"+m" (fsw));
+ if (fsw != 0)
+ return -1;
+
+ asm volatile ("fnstcw %0":"+m" (fcw));
+ if ((fcw & 0x103f) != 0x3f)
+ return -1;
+
+ /* Techically, this could be a 386 with a 287. We could add a check
+ for that here... */
+
+ return 0;
+}
* Test for an x86 FPU, and do any necessary setup.
*/
+#if __SIZEOF_POINTER__ == 4
+#include <i386/x86_init_fpu.c>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/x86_init_fpu.c>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+#if 0
#include <inttypes.h>
#include <sys/fpu.h>
static inline uint64_t get_cr0(void)
{
+#if __SIZEOF_POINTER__ == 4
uint32_t v;
asm("movl %%cr0,%0":"=r"(v));
+#elif __SIZEOF_POINTER__ == 8
+ uint64_t v;
+asm("movq %%cr0,%0":"=r"(v));
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
return v;
}
static inline void set_cr0(uint32_t v)
{
+#if __SIZEOF_POINTER__ == 4
asm volatile ("movl %0,%%cr0"::"r" (v));
+#elif __SIZEOF_POINTER__ == 8
+ asm volatile ("movq %0,%%cr0"::"r" ((uint64_t)v));
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
}
#define CR0_PE 0x00000001
return 0;
}
+#endif
--- /dev/null
+#
+# arch/x86_64/setjmp.S
+#
+# setjmp/longjmp for the x86-64 architecture
+#
+
+#
+# The jmp_buf is assumed to contain the following, in order:
+# %rbx
+# %rsp (post-return)
+# %rbp
+# %r12
+# %r13
+# %r14
+# %r15
+# <return address>
+#
+
+ .text
+ .align 4
+ .globl setjmp
+ .type setjmp, @function
+setjmp:
+ pop %rsi # Return address, and adjust the stack
+ xorl %eax,%eax # Return value
+ movq %rbx,(%rdi)
+ movq %rsp,8(%rdi) # Post-return %rsp!
+ push %rsi # Make the call/return stack happy
+ movq %rbp,16(%rdi)
+ movq %r12,24(%rdi)
+ movq %r13,32(%rdi)
+ movq %r14,40(%rdi)
+ movq %r15,48(%rdi)
+ movq %rsi,56(%rdi) # Return address
+ ret
+
+ .size setjmp,.-setjmp
+
+ .text
+ .align 4
+ .globl longjmp
+ .type longjmp, @function
+longjmp:
+ movl %esi,%eax # Return value (int)
+ movq (%rdi),%rbx
+ movq 8(%rdi),%rsp
+ movq 16(%rdi),%rbp
+ movq 24(%rdi),%r12
+ movq 32(%rdi),%r13
+ movq 40(%rdi),%r14
+ movq 48(%rdi),%r15
+ jmp *56(%rdi)
+
+ .size longjmp,.-longjmp