[PATCH] asm versions of some memxxx() type functions for z8k
Christian Groessler
chris@groessler.org
Tue May 25 11:09:00 GMT 2004
Hi,
the following patch provides assembler versions of memcmp, memcpy,
memmove, and memset for the z8k.
It also fixes _setjmp/_longjmp for Z8002 and provides a
implementation of those for the stdcall (stack based) calling
convention.
regards,
chris
2004-05-22 Christian Groessler <chris@groessler.org>
* libc/machine/z8k/memcmp.S: New file.
* libc/machine/z8k/memcpy.S: Ditto.
* libc/machine/z8k/memmove.S: Ditto.
* libc/machine/z8k/memset.S: Ditto.
* libc/machine/z8k/Makefile.am: Add new files.
* libc/machine/z8k/Makefile.in: Regenerated.
* libc/machine/z8k/setjmp.S: Fix indirect register usage in Z8002
part. Implement Z8002 stdcall version.
Patch for the libc/machine/z8k directory:
-------------------
Index: Makefile.am
===================================================================
RCS file: /nfs/soft/src/CVSdepot/m20newlib/newlib/libc/machine/z8k/Makefile.am,v
retrieving revision 1.1.1.1
retrieving revision 1.5
diff -b -u -r1.1.1.1 -r1.5
--- Makefile.am 16 Aug 2001 15:30:34 -0000 1.1.1.1
+++ Makefile.am 1 May 2004 23:05:21 -0000 1.5
@@ -6,7 +6,7 @@
noinst_LIBRARIES = lib.a
-lib_a_SOURCES = setjmp.S
+lib_a_SOURCES = setjmp.S memset.S memcpy.S memmove.S memcmp.S
ACLOCAL_AMFLAGS = -I ../../..
CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
Index: Makefile.in
===================================================================
RCS file: /nfs/soft/src/CVSdepot/m20newlib/newlib/libc/machine/z8k/Makefile.in,v
retrieving revision 1.1.1.3
diff -b -u -r1.1.1.3 Makefile.in
--- Makefile.in 21 Apr 2004 20:36:30 -0000 1.1.1.3
+++ Makefile.in 22 May 2004 20:51:48 -0000
@@ -89,7 +89,7 @@
noinst_LIBRARIES = lib.a
-lib_a_SOURCES = setjmp.S
+lib_a_SOURCES = setjmp.S memset.S memcpy.S memmove.S memcmp.S
ACLOCAL_AMFLAGS = -I ../../..
CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
@@ -103,7 +103,7 @@
CPPFLAGS = @CPPFLAGS@
LIBS = @LIBS@
lib_a_LIBADD =
-lib_a_OBJECTS = setjmp.o
+lib_a_OBJECTS = setjmp.o memset.o memcpy.o memmove.o memcmp.o
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
Index: memcmp.S
===================================================================
RCS file: memcmp.S
diff -N memcmp.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ memcmp.S 22 May 2004 20:51:48 -0000
@@ -0,0 +1,177 @@
+/*
+ * memcmp routine for Z8000
+ * Written by Christian Groessler <chris@groessler.org>
+ */
+
+/* int memcmp(const void *b1, const void *b2, size_t length);
+ */
+
+ name "memcmp.S"
+
+ .text
+ even
+global _memcmp
+
+_memcmp:
+
+#ifdef __Z8001__
+ segm
+
+#ifdef __STD_CALL__
+ ldl rr6,rr14(#4)
+ ldl rr4,rr14(#8)
+ ldl rr2,rr14(#12)
+#endif
+
+/* rr2 - length (high word ignored)
+ * rr4 - b2
+ * rr6 - b1
+ */
+
+ clr r1 /* initialize return value */
+ testl rr2
+ jr z,finish
+
+ bitb rl7,#0 /* odd b1? */
+ jr nz,testb2
+ bitb rl5,#0 /* odd b2? */
+ jr nz,odd_cmp /* b1 even, b2 odd */
+ jr t,even_cmp
+
+testb2:
+ bitb rl5,#0
+ jr z,odd_cmp /* b2 even, b1 odd */
+
+ cpsib @rr6,@rr4,r3,eq
+ jr z,beq /* bytes are the same */
+ jr t,byte_diff
+
+beq: jr ov,finish /* jump if r3 is zero now */
+
+/* compare words */
+even_cmp:
+ ld r2,r3 /* remember length */
+ srl r3,#1
+ jr z,no_words
+
+ cpsir @rr6,@rr4,r3,ne
+ jr nz,no_words
+
+ dec r7,#2
+ dec r5,#2 /* point to different bytes */
+ ldk r3,#2
+ jr t,odd_cmp
+
+no_words:
+ bitb rl2,#0 /* odd length? */
+ jr z,finish
+
+ cpsib @rr6,@rr4,r3,eq
+ jr z,finish /* last bytes are the same */
+ jr t,byte_diff
+
+/* compare bytes */
+odd_cmp:
+ cpsirb @rr6,@rr4,r3,ne
+ jr nz,finish
+
+byte_diff:
+ dec r7,#1
+ dec r5,#1 /* point to different bytes */
+
+ ldb rl1,@rr6
+ clr r0
+ ldb rl0,@rr4
+ sub r1,r0
+
+finish: /* set return value */
+#ifdef __STD_CALL__
+ ld r7,r1
+#else
+ ld r2,r1
+#endif
+
+
+#else /* above Z8001, below Z8002 */
+
+
+ unsegm
+
+#ifdef __STD_CALL__
+ ld r7,r15(#2)
+ ld r6,r15(#4)
+ ld r5,r15(#6)
+#endif
+
+/* r5 - length
+ * r6 - b2
+ * r7 - b1
+ */
+
+ clr r1 /* initialize return value */
+ test r5
+ jr z,finish
+
+ bitb rl7,#0 /* odd destination address? */
+ jr nz,testb2
+ bitb rl6,#0 /* odd source address? */
+ jr nz,odd_cmp /* b1 even, b2 odd */
+ jr t,even_cmp
+
+testb2:
+ bitb rl6,#0
+ jr z,odd_cmp /* b2 even, b1 odd */
+
+ cpsib @r7,@r6,r5,eq
+ jr z,beq /* bytes are the same */
+ jr t,byte_diff
+
+beq: jr ov,finish /* jump if r3 is zero now */
+
+/* compare words */
+even_cmp:
+ ld r4,r5 /* remember length */
+ srl r5,#1
+ jr z,no_words
+
+ cpsir @r7,@r6,r5,ne
+ jr nz,no_words
+
+ dec r7,#2
+ dec r6,#2 /* point to different bytes */
+ ldk r5,#2
+ jr t,odd_cmp
+
+no_words:
+ bitb rl4,#0 /* odd length? */
+ jr z,finish
+
+ cpsib @r7,@r6,r4,eq
+ jr z,finish /* last bytes are the same */
+ jr t,byte_diff
+
+/* compare bytes */
+odd_cmp:
+ cpsirb @r7,@r6,r5,ne
+ jr nz,finish
+
+byte_diff:
+ dec r7,#1
+ dec r6,#1 /* point to different bytes */
+
+ ldb rl1,@r7
+ clr r0
+ ldb rl0,@r6
+ sub r1,r0
+
+finish:
+#ifdef __STD_CALL__
+ ld r7,r1
+#else
+ ld r2,r1
+#endif
+
+#endif /* Z8002 */
+
+ ret
+ .end
Index: memcpy.S
===================================================================
RCS file: memcpy.S
diff -N memcpy.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ memcpy.S 22 May 2004 20:51:48 -0000
@@ -0,0 +1,137 @@
+/*
+ * memcpy routine for Z8000
+ * Written by Christian Groessler <chris@groessler.org>
+ */
+
+/* void *memcpy(void *dest, const void *src, size_t length);
+ */
+
+ name "memcpy.S"
+
+ .text
+ even
+global _memcpy
+global memmove_entry
+
+_memcpy:
+
+#ifdef __Z8001__
+ segm
+
+#ifdef __STD_CALL__
+ ldl rr6,rr14(#4)
+ ldl rr4,rr14(#8)
+ ldl rr2,rr14(#12)
+#else
+ pushl @rr14,rr6
+#endif
+
+/* rr2 - length (high word ignored)
+ * rr4 - src
+ * rr6 - dest
+ */
+
+ testl rr2
+ jr z,finish
+
+memmove_entry: /* external entry point from memmove */
+
+ bitb rl7,#0 /* odd destination address? */
+ jr nz,testsrc
+ bitb rl5,#0 /* odd source address? */
+ jr nz,odd_copy
+ jr t,even_copy /* dest even, src odd */
+
+testsrc:
+ bitb rl5,#0
+ jr z,odd_copy /* src even, dest odd */
+ ldib @rr6,@rr4,r3
+ jr ov,finish /* jump if r3 is zero now */
+
+/* copy words */
+even_copy:
+ ld r2,r3 /* remember length */
+ srl r3,#1
+ jr z,no_words
+
+ ldir @rr6,@rr4,r3
+
+no_words:
+ bitb rl2,#0 /* odd length? */
+ jr z,finish
+ ldib @rr6,@rr4,r2 /* yes, copy last byte */
+ jr finish
+
+/* copy bytes */
+odd_copy:
+ ldirb @rr6,@rr4,r3
+
+finish:
+#ifdef __STD_CALL__
+ ldl rr6,rr14(#4)
+#else
+ popl rr2,@rr14
+#endif
+
+
+#else /* above Z8001, below Z8002 */
+
+
+ unsegm
+
+#ifdef __STD_CALL__
+ ld r7,r15(#2)
+ ld r6,r15(#4)
+ ld r5,r15(#6)
+#else
+ ld r2,r7 /* buffer pointer return value */
+#endif
+
+/* r5 - length
+ * r6 - src
+ * r7 - dest
+ */
+ test r5
+ jr z,finish
+
+memmove_entry: /* external entry point from memmove */
+
+ bitb rl7,#0 /* odd destination address? */
+ jr nz,testsrc
+ bitb rl6,#0 /* odd source address? */
+ jr nz,odd_copy
+ jr t,even_copy /* dest even, src odd */
+
+testsrc:
+ bitb rl6,#0
+ jr z,odd_copy /* src even, dest odd */
+ ldib @r7,@r6,r5
+ jr ov,finish /* jump if r5 is zero now */
+
+/* copy words */
+even_copy:
+ ld r4,r5 /* remember length */
+ srl r5,#1
+ jr z,no_words
+
+ ldir @r7,@r6,r5
+
+no_words:
+ bitb rl4,#0 /* odd length? */
+ jr z,finish
+ ldib @r7,@r6,r4 /* yes, copy last byte */
+ jr finish
+
+/* copy bytes */
+odd_copy:
+ ldirb @r7,@r6,r5
+
+finish:
+#ifdef __STD_CALL__
+ ld r7,r15(#2)
+#endif
+
+#endif /* Z8002 */
+
+ ret
+ .end
Index: memmove.S
===================================================================
RCS file: memmove.S
diff -N memmove.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ memmove.S 22 May 2004 20:51:48 -0000
@@ -0,0 +1,172 @@
+/*
+ * memmove routine for Z8000
+ * Written by Christian Groessler <chris@groessler.org>
+ */
+
+/* void *memmove(void *dest, const void *src, size_t length);
+ */
+
+ name "memmove.S"
+
+ .text
+ even
+global _memmove
+
+_memmove:
+
+#ifdef __Z8001__
+ segm
+
+#ifdef __STD_CALL__
+ ldl rr6,rr14(#4)
+ ldl rr4,rr14(#8)
+ ldl rr2,rr14(#12)
+#else
+ pushl @rr14,rr6
+#endif
+
+/* rr2 - length (high word ignored)
+ * rr4 - src
+ * rr6 - dest
+ */
+
+ testl rr2
+ jr z,finish
+
+/* check for destructive overlap (src < dest && dest < src + length) */
+
+ cpl rr6,rr4
+ jp ule,memmove_entry /* non-destructive, let memcpy do the work */
+ ldl rr0,rr2
+ addl rr0,rr4 /* rr0 = src + length */
+ cpl rr0,rr6
+ jp ult,memmove_entry /* non-destructive, let memcpy do the work */
+
+/* set-up pointers to copy backwards, add (length - 1) */
+ addl rr4,rr2 /* src + length */
+ addl rr6,rr2 /* dest + length */
+ subl rr4,#1
+ subl rr6,#1
+
+/* check alignment */
+ bitb rl7,#0 /* odd destination address? */
+ jr z,testsrc
+ bitb rl5,#0 /* odd source address? */
+ jr z,odd_copy
+ jr even_copy
+
+testsrc:
+ bitb rl5,#0
+ jr nz,odd_copy /* src even, dest odd */
+ lddb @rr6,@rr4,r3
+ jr ov,finish /* jump if r5 is zero now */
+
+/* copy words */
+even_copy:
+ ld r2,r3 /* remember length */
+ srl r3,#1
+/* jr z,no_words it cannot be zero here */
+
+ dec r5,#1
+ dec r7,#1
+ lddr @rr6,@rr4,r3
+
+no_words:
+ bitb rl2,#0 /* odd length? */
+ jr z,finish
+ inc r5,#1
+ inc r7,#1
+ lddb @rr6,@rr4,r2 /* yes, copy last byte */
+ jr finish
+
+/* copy bytes */
+odd_copy:
+ lddrb @rr6,@rr4,r3
+
+finish:
+#ifdef __STD_CALL__
+ ldl rr6,rr14(#4)
+#else
+ popl rr2,@rr14
+#endif
+
+
+#else /* above Z8001, below Z8002 */
+
+
+ unsegm
+
+#ifdef __STD_CALL__
+ ld r7,r15(#2)
+ ld r6,r15(#4)
+ ld r5,r15(#6)
+#else
+ ld r2,r7 /* buffer pointer return value */
+#endif
+
+/* r5 - length
+ * r6 - src
+ * r7 - dest
+ */
+ test r5
+ jr z,finish
+
+/* check for destructive overlap (src < dest && dest < src + length) */
+
+ cp r7,r6
+ jp ule,memmove_entry /* non-destructive, let memcpy do the work */
+ ld r0,r5
+ add r0,r6 /* r0 = src + length */
+ cp r0,r7
+ jp ult,memmove_entry /* non-destructive, let memcpy do the work */
+
+/* set-up pointers to copy backwards, add (length - 1) */
+ add r6,r5 /* src + length */
+ add r7,r5 /* dest + length */
+ dec r6,#1
+ dec r7,#1
+
+/* check alignment */
+ bitb rl7,#0 /* odd destination address? */
+ jr z,testsrc
+ bitb rl6,#0 /* odd source address? */
+ jr z,odd_copy
+ jr even_copy
+
+testsrc:
+ bitb rl6,#0
+ jr nz,odd_copy /* src even, dest odd */
+ lddb @r7,@r6,r5
+ jr ov,finish /* jump if r5 is zero now */
+
+/* copy words */
+even_copy:
+ ld r4,r5 /* remember length */
+ srl r5,#1
+/* jr z,no_words it cannot be zero here */
+
+ dec r6,#1
+ dec r7,#1
+ lddr @r7,@r6,r5
+
+no_words:
+ bitb rl4,#0 /* odd length? */
+ jr z,finish
+ inc r6,#1
+ inc r7,#1
+ lddb @r7,@r6,r4 /* yes, copy last byte */
+ jr finish
+
+/* copy bytes */
+odd_copy:
+ lddrb @r7,@r6,r5
+
+finish:
+#ifdef __STD_CALL__
+ ld r7,r15(#2)
+#endif
+
+#endif /* Z8002 */
+
+ ret
+ .end
Index: memset.S
===================================================================
RCS file: memset.S
diff -N memset.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ memset.S 22 May 2004 20:51:48 -0000
@@ -0,0 +1,127 @@
+/*
+ * memset routine for Z8000
+ * Written by Christian Groessler <chris@groessler.org>
+ */
+
+/* void *memset(void *buffer, int value, size_t length);
+ */
+
+ name "memset.S"
+
+ .text
+ even
+global _memset
+
+_memset:
+
+#ifdef __Z8001__
+ segm
+
+#ifdef __STD_CALL__
+ ldl rr6,rr14(#4)
+ ld r5,rr14(#8)
+ ldl rr2,rr14(#10)
+#else
+ pushl @rr14,rr6
+#endif
+
+/* rr2 - length
+ * rl5 - value
+ * rr6 - buffer
+ */
+ testl rr2
+ jr z,finish
+
+ ldb rh5,rl5
+ ld r1,r5 /* r1 contains value */
+ bit r7,#0
+ jr z,not_odd
+
+ ldb @rr6,rl1
+ inc r7,#1
+ subl rr2,#1
+ jr z,finish
+
+not_odd:ld r0,r3 /* remember length */
+ srl r3,#1
+ jr z,no_words
+
+ ldl rr4,rr6
+ ld @rr6,r1
+ inc r7,#2
+ dec r3,#1
+ jr z,no_words
+
+ ldir @rr6,@rr4,r3 /* fill words */
+
+no_words:
+ bit r0,#0 /* one byte remaining? */
+ jr z,finish
+
+ ldb @rr6,rl1
+
+finish:
+#ifdef __STD_CALL__
+ ldl rr6,rr14(#4)
+#else
+ popl rr2,@rr14
+#endif
+
+
+#else /* above Z8001, below Z8002 */
+
+
+ unsegm
+
+#ifdef __STD_CALL__
+ ld r7,r15(#2)
+ ld r6,r15(#4)
+ ld r5,r15(#6)
+#else
+ ld r2,r7 /* buffer pointer return value */
+#endif
+
+/* r5 - length
+ * r6 - value
+ * r7 - buffer
+ */
+ test r5
+ jr z,finish
+
+ ldb rh6,rl6
+ ld r1,r6 /* r1 contains value */
+ bit r7,#0
+ jr z,not_odd
+
+ ldb @r7,rl1
+ inc r7,#1
+ dec r5,#1
+ jr z,finish
+
+not_odd:ld r0,r5 /* remember length */
+ srl r5,#1
+ jr z,no_words
+
+ ld r4,r7
+ ld @r7,r1
+ inc r7,#2
+ dec r5,#1
+ jr z,no_words
+
+ ldir @r7,@r4,r5 /* fill words */
+
+no_words:
+ bit r0,#0 /* one byte remaining? */
+ jr z,finish
+
+ ldb @r7,rl1
+
+finish:
+#ifdef __STD_CALL__
+ ld r7,r15(#2)
+#endif
+
+#endif /* Z8002 */
+
+ ret
+ .end
Index: setjmp.S
===================================================================
RCS file: /nfs/soft/src/CVSdepot/m20newlib/newlib/libc/machine/z8k/setjmp.S,v
retrieving revision 1.1.1.2
retrieving revision 1.7
diff -b -u -r1.1.1.2 -r1.7
--- setjmp.S 21 Apr 2004 20:36:30 -0000 1.1.1.2
+++ setjmp.S 30 Apr 2004 21:03:59 -0000 1.7
@@ -1,10 +1,9 @@
+ .global _setjmp
+ .global _longjmp
#ifdef __Z8001__
segm
- .global _setjmp
- .globl _longjmp
-
#ifdef __STD_CALL__
_setjmp:
@@ -56,10 +55,31 @@
unseg
#ifdef __STD_CALL__
-#warning Z8002 std call not implemented!
-#endif
- .global _setjmp
+_setjmp:
+ ld r7,r15(#2) ! get argument
+ ld r2,@r15 ! fetch pc
+ ld @r7,r2 ! save it
+ ldl r7(#14),rr8
+ ldl r7(#2),rr10
+ ldl r7(#6),rr12 ! remember frame pointer
+ ldl r7(#10),rr14 ! remember stack pointer
+ ldk r7,#0
+ ret t
+
+_longjmp:
+ ld r4,r15(#2) ! get first argument (jmp_buf)
+ ld r7,r15(#4) ! get return value
+ ldl rr8,r4(#14)
+ ldl rr10,r4(#2)
+ ldl rr12,r4(#6) ! restore old frame pointer
+ ldl rr14,r4(#10) ! restore old stack pointer
+ ld r4,@r4 ! return address
+ inc r15,#2
+ jp @r4
+
+#else /* above __STD_CALL_, below not */
+
_setjmp:
ld r2,@r15 ! fetch pc
ld @r7,r2 ! save it
@@ -69,14 +89,14 @@
ldk r2,#0
ret t
- .globl _longjmp
-
_longjmp:
ld r2,r6 ! get return value
ld r4,@r7
- ldl rr10,rr7(4)
- ldl rr12,rr7(8)
- ldl rr14,rr7(12)
- jp @rr4
+ ldl rr10,r7(4)
+ ldl rr12,r7(8)
+ ldl rr14,r7(12)
+ inc r15,#2
+ jp @r4
+#endif /* not __STD_CALL__ */
#endif /* Z8002 version */
-------------------
More information about the Newlib
mailing list