[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