[syslinux:firmware] This patch implements the setjmp/longjmp, memcpy, memmove, memset and mempcpy functions as appropriate for the architecture. The code came from klibc. com32/ lib has i386 and x86_64 sub directories implementing the code.
syslinux-bot for chandramouli narayanan
mouli at linux.intel.com
Fri Nov 9 09:06:19 PST 2012
Commit-ID: 5caee9aeaf89dbbc45269737cc1dac7de070b867
Gitweb: http://www.syslinux.org/commit/5caee9aeaf89dbbc45269737cc1dac7de070b867
Author: chandramouli narayanan <mouli at linux.intel.com>
AuthorDate: Mon, 25 Jun 2012 12:34:46 -0700
Committer: chandramouli narayanan <mouli at linux.intel.com>
CommitDate: Mon, 25 Jun 2012 12:34:46 -0700
This patch implements the setjmp/longjmp, memcpy, memmove, memset and mempcpy functions as appropriate for the architecture. The code came from klibc. com32/lib has i386 and x86_64 sub directories implementing the code.
The code in com32/lib/libgcc/__muldi3.S essentially has fixes for building x86_64.
The file x86_init_fpu.c is split into the respective architecture specific files and
reside under com32/lib/sys/i386 and com32/lib/sys/x86_64.
The file com32/lib/sys/farcall.c has fixes for architecture-specific code. The com32 lib
dependends on it.
Remanants of the unused old i386-only files, if any, need to be pruned.
---
com32/lib/{ => i386}/setjmp.S | 0
com32/lib/libgcc/__muldi3.S | 49 ++++++++++++++++++++++++++
com32/lib/memcpy.c | 29 +++++++++++++++
com32/lib/memmove.c | 36 +++++++++++++++++++
com32/lib/mempcpy.c | 14 +++++++
com32/lib/memset.c | 30 ++++++++++++++++
com32/lib/setjmp.S | 11 +++++-
com32/lib/sys/farcall.c | 10 +++++-
com32/lib/sys/{ => i386}/x86_init_fpu.c | 0
com32/lib/sys/{ => x86_64}/x86_init_fpu.c | 6 ++--
com32/lib/sys/x86_init_fpu.c | 22 ++++++++++++
com32/lib/x86_64/setjmp.S | 54 +++++++++++++++++++++++++++++
12 files changed, 256 insertions(+), 5 deletions(-)
diff --git a/com32/lib/setjmp.S b/com32/lib/i386/setjmp.S
similarity index 100%
copy from com32/lib/setjmp.S
copy to com32/lib/i386/setjmp.S
diff --git a/com32/lib/libgcc/__muldi3.S b/com32/lib/libgcc/__muldi3.S
index 648a88a..424787c 100644
--- a/com32/lib/libgcc/__muldi3.S
+++ b/com32/lib/libgcc/__muldi3.S
@@ -9,6 +9,8 @@
.globl __muldi3
.type __muldi3, at function
__muldi3:
+#if __SIZEOF_POINTER__ == 4
+ /* i386 */
push %esi
#ifndef REGPARM
movl 8(%esp),%eax
@@ -31,4 +33,51 @@ __muldi3:
#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
diff --git a/com32/lib/memcpy.c b/com32/lib/memcpy.c
new file mode 100644
index 0000000..5ce206d
--- /dev/null
+++ b/com32/lib/memcpy.c
@@ -0,0 +1,29 @@
+/*
+ * 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;
+}
diff --git a/com32/lib/memmove.c b/com32/lib/memmove.c
new file mode 100644
index 0000000..a398cd8
--- /dev/null
+++ b/com32/lib/memmove.c
@@ -0,0 +1,36 @@
+/*
+ * 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;
+}
diff --git a/com32/lib/mempcpy.c b/com32/lib/mempcpy.c
new file mode 100644
index 0000000..be23b66
--- /dev/null
+++ b/com32/lib/mempcpy.c
@@ -0,0 +1,14 @@
+/*
+ * 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;
+}
diff --git a/com32/lib/memset.c b/com32/lib/memset.c
new file mode 100644
index 0000000..aa00b5b
--- /dev/null
+++ b/com32/lib/memset.c
@@ -0,0 +1,30 @@
+/*
+ * 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;
+}
diff --git a/com32/lib/setjmp.S b/com32/lib/setjmp.S
index 658df48..2fb5c23 100644
--- a/com32/lib/setjmp.S
+++ b/com32/lib/setjmp.S
@@ -13,7 +13,7 @@
* %edi
* <return address>
*/
-
+/*
.text
.align 4
@@ -61,3 +61,12 @@ longjmp:
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
+
diff --git a/com32/lib/sys/farcall.c b/com32/lib/sys/farcall.c
index 988ee6d..2749083 100644
--- a/com32/lib/sys/farcall.c
+++ b/com32/lib/sys/farcall.c
@@ -6,9 +6,17 @@
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;
}
diff --git a/com32/lib/sys/x86_init_fpu.c b/com32/lib/sys/i386/x86_init_fpu.c
similarity index 100%
copy from com32/lib/sys/x86_init_fpu.c
copy to com32/lib/sys/i386/x86_init_fpu.c
diff --git a/com32/lib/sys/x86_init_fpu.c b/com32/lib/sys/x86_64/x86_init_fpu.c
similarity index 90%
copy from com32/lib/sys/x86_init_fpu.c
copy to com32/lib/sys/x86_64/x86_init_fpu.c
index cf33693..c5d3946 100644
--- a/com32/lib/sys/x86_init_fpu.c
+++ b/com32/lib/sys/x86_64/x86_init_fpu.c
@@ -9,14 +9,14 @@
static inline uint64_t get_cr0(void)
{
- uint32_t v;
-asm("movl %%cr0,%0":"=r"(v));
+ uint64_t v;
+asm("movq %%cr0,%0":"=r"(v));
return v;
}
static inline void set_cr0(uint32_t v)
{
- asm volatile ("movl %0,%%cr0"::"r" (v));
+ asm volatile ("movq %0,%%cr0"::"r" ((uint64_t)v));
}
#define CR0_PE 0x00000001
diff --git a/com32/lib/sys/x86_init_fpu.c b/com32/lib/sys/x86_init_fpu.c
index cf33693..cacb4ea 100644
--- a/com32/lib/sys/x86_init_fpu.c
+++ b/com32/lib/sys/x86_init_fpu.c
@@ -4,19 +4,40 @@
* 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
@@ -56,3 +77,4 @@ int x86_init_fpu(void)
return 0;
}
+#endif
diff --git a/com32/lib/x86_64/setjmp.S b/com32/lib/x86_64/setjmp.S
new file mode 100644
index 0000000..45f547b
--- /dev/null
+++ b/com32/lib/x86_64/setjmp.S
@@ -0,0 +1,54 @@
+#
+# 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
More information about the Syslinux-commits
mailing list