summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-11-17 22:32:39 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-11-17 22:32:39 +0000
commit37e264971d57609cd9cf1bb417df64acc5371340 (patch)
tree2527c5bcdd5b8f5993b0cd3c710f5c03445b0e8d /sys/arch
parent3fea4cab24ade8220623a26c4e0e4f3458abf436 (diff)
Move m88k memory copy and fill functions to libkern. The copy functions will
no longer share the same code, but will be instead be duplicated from the same source, so that bcopy() and memcpy() do not need to check for overlap, and memcpy() and memmove() are shorter.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/m88k/m88k/subr.S479
1 files changed, 1 insertions, 478 deletions
diff --git a/sys/arch/m88k/m88k/subr.S b/sys/arch/m88k/m88k/subr.S
index 2d966e1cdbf..ffd80af475a 100644
--- a/sys/arch/m88k/m88k/subr.S
+++ b/sys/arch/m88k/m88k/subr.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr.S,v 1.12 2006/11/10 19:20:29 miod Exp $ */
+/* $OpenBSD: subr.S,v 1.13 2006/11/17 22:32:35 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1992 Carnegie Mellon University
@@ -1018,483 +1018,6 @@ ASLOCAL(kr_strat)
word _ASM_LABEL(kr_3byte_word_copy)
/*
- * Gcc 2 generates calls to memcpy for bcopies of unknown size. memcpy can
- * simply be implemented as ovbcopy but the src (r2, r3) and dst args need to
- * be switched.
- */
-/*
- * void memcpy(dest, source, count)
- *
- */
-ENTRY(memcpy)
- or r5, r0, r2 /* dst -> tmp */
- or r2, r0, r3 /* src -> 1st arg */
- br.n _C_LABEL(ovbcopy)
- or r3, r0, r5 /* dst -> 2nd arg */
-
-/*
- * void bcopy(source, destination, count)
- *
- * copy count bytes of data from source to destination
- * Don Harper (don@omron.co.jp), Omron Corporation.
- *
- */
-
-ENTRY(bcopy)
-ENTRY(ovbcopy)
- bcnd eq0,r4,_ASM_LABEL(bcopy_out) /* nothing to do if == 0 */
-/*
- * check position of source and destination data
- */
- cmp r9,r2,r3 /* compare source address to destination */
- bb1 eq,r9,_ASM_LABEL(bcopy_out) /* nothing to do if equal */
- bb1 lo,r9,_ASM_LABEL(bcopy_reverse) /* reverse copy if src < dest */
-/*
- * source address is greater than destination address, copy forward
- */
- cmp r9,r4,16 /* see if we have at least 16 bytes */
- bb1 lt,r9,_ASM_LABEL(f_byte_copy) /* copy bytes for small data length */
-/*
- * determine copy strategy based on alignment of source and destination
- */
- mask r6,r2,3 /* get 2 low order bits of source address */
- mask r7,r3,3 /* get 2 low order bits of destintation addr */
- mak r6,r6,0<4> /* convert source bits to table offset */
- mak r7,r7,0<2> /* convert destination bits to table offset */
- or.u r12,r0,hi16(_ASM_LABEL(f_strat))
- or r12,r12,lo16(_ASM_LABEL(f_strat))
- addu r6,r6,r7 /* compute final table offset for strategy */
- ld r12,r12,r6 /* load the strategy routine */
- jmp r12 /* branch to strategy routine */
-
-
-/*
- * Copy three bytes from src to destination then copy words
- */
-ASLOCAL(f_3byte_word_copy)
- ld.bu r6,r2,0 /* load byte from source */
- ld.bu r7,r2,1 /* load byte from source */
- ld.bu r8,r2,2 /* load byte from source */
- st.b r6,r3,0 /* store byte to destination */
- st.b r7,r3,1 /* store byte to destination */
- st.b r8,r3,2 /* store byte to destination */
- addu r2,r2,3 /* increment source pointer */
- addu r3,r3,3 /* increment destination pointer */
- br.n _ASM_LABEL(f_word_copy) /* copy full words */
- subu r4,r4,3 /* decrement length */
-
-/*
- * Copy 1 halfword from src to destination then copy words
- */
-ASLOCAL(f_1half_word_copy)
- ld.hu r6,r2,0 /* load half-word from source */
- st.h r6,r3,0 /* store half-word to destination */
- addu r2,r2,2 /* increment source pointer */
- addu r3,r3,2 /* increment destination pointer */
- br.n _ASM_LABEL(f_word_copy) /* copy full words */
- subu r4,r4,2 /* decrement remaining length */
-
-/*
- * Copy 1 byte from src to destination then copy words
- */
-ASLOCAL(f_1byte_word_copy)
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to word copy */
-/*
- * Copy as many full words as possible, 4 words per loop
- */
-ASLOCAL(f_word_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(f_byte_copy) /* not enough left, copy bytes */
- ld r6,r2,0 /* load first word */
- ld r7,r2,4 /* load second word */
- ld r8,r2,8 /* load third word */
- ld r9,r2,12 /* load fourth word */
- st r6,r3,0 /* store first word */
- st r7,r3,4 /* store second word */
- st r8,r3,8 /* store third word */
- st r9,r3,12 /* store fourth word */
- addu r2,r2,16 /* increment source pointer */
- addu r3,r3,16 /* increment destination pointer */
- br.n _ASM_LABEL(f_word_copy) /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(f_1byte_half_copy)
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to half copy */
-
-ASLOCAL(f_half_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(f_byte_copy) /* not enough left, copy bytes */
- ld.hu r6,r2,0 /* load first half-word */
- ld.hu r7,r2,2 /* load second half-word */
- ld.hu r8,r2,4 /* load third half-word */
- ld.hu r9,r2,6 /* load fourth half-word */
- ld.hu r10,r2,8 /* load fifth half-word */
- ld.hu r11,r2,10 /* load sixth half-word */
- ld.hu r12,r2,12 /* load seventh half-word */
- ld.hu r13,r2,14 /* load eighth half-word */
- st.h r6,r3,0 /* store first half-word */
- st.h r7,r3,2 /* store second half-word */
- st.h r8,r3,4 /* store third half-word */
- st.h r9,r3,6 /* store fourth half-word */
- st.h r10,r3,8 /* store fifth half-word */
- st.h r11,r3,10 /* store sixth half-word */
- st.h r12,r3,12 /* store seventh half-word */
- st.h r13,r3,14 /* store eighth half-word */
- addu r2,r2,16 /* increment source pointer */
- addu r3,r3,16 /* increment destination pointer */
- br.n _ASM_LABEL(f_half_copy) /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(f_byte_copy)
- bcnd eq0,r4,_ASM_LABEL(bcopy_out) /* branch if nothing left to copy */
- ld.bu r6,r2,0 /* load byte from source */
- st.b r6,r3,0 /* store byte in destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- br.n _ASM_LABEL(f_byte_copy) /* branch for next byte */
- subu r4,r4,1 /* decrement remaining length */
-
-/*
- * source address is less than destination address, copy in reverse
- */
-ASLOCAL(bcopy_reverse)
-/*
- * start copy pointers at end of data
- */
- addu r2,r2,r4 /* start source at end of data */
- addu r3,r3,r4 /* start destination at end of data */
-/*
- * check for short data
- */
- cmp r9,r4,16 /* see if we have at least 16 bytes */
- bb1 lt,r9,_ASM_LABEL(r_byte_copy) /* copy bytes for small data length */
-/*
- * determine copy strategy based on alignment of source and destination
- */
- mask r6,r2,3 /* get 2 low order bits of source address */
- mask r7,r3,3 /* get 2 low order bits of destintation addr */
- mak r6,r6,0<4> /* convert source bits to table offset */
- mak r7,r7,0<2> /* convert destination bits to table offset */
- or.u r12,r0,hi16(_ASM_LABEL(r_strat))
- or r12,r12,lo16(_ASM_LABEL(r_strat))
- addu r6,r6,r7 /* compute final table offset for strategy */
- ld r12,r12,r6 /* load the strategy routine */
- jmp r12 /* branch to strategy routine */
-
-/*
- * Copy three bytes from src to destination then copy words
- */
-ASLOCAL(r_3byte_word_copy)
- subu r2,r2,3 /* decrement source pointer */
- subu r3,r3,3 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load byte from source */
- ld.bu r7,r2,1 /* load byte from source */
- ld.bu r8,r2,2 /* load byte from source */
- st.b r6,r3,0 /* store byte to destination */
- st.b r7,r3,1 /* store byte to destination */
- st.b r8,r3,2 /* store byte to destination */
- br.n _ASM_LABEL(r_word_copy) /* copy full words */
- subu r4,r4,3 /* decrement length */
-
-/*
- * Copy 1 halfword from src to destination then copy words
- */
-ASLOCAL(r_1half_word_copy)
- subu r2,r2,2 /* decrement source pointer */
- subu r3,r3,2 /* decrement destination pointer */
- ld.hu r6,r2,0 /* load half-word from source */
- st.h r6,r3,0 /* store half-word to destination */
- br.n _ASM_LABEL(r_word_copy) /* copy full words */
- subu r4,r4,2 /* decrement remaining length */
-
-/*
- * Copy 1 byte from src to destination then copy words
- */
-ASLOCAL(r_1byte_word_copy)
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to word copy */
-/*
- * Copy as many full words as possible, 4 words per loop
- */
-ASLOCAL(r_word_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(r_byte_copy) /* not enough left, copy bytes */
- subu r2,r2,16 /* decrement source pointer */
- subu r3,r3,16 /* decrement destination pointer */
- ld r6,r2,0 /* load first word */
- ld r7,r2,4 /* load second word */
- ld r8,r2,8 /* load third word */
- ld r9,r2,12 /* load fourth word */
- st r6,r3,0 /* store first word */
- st r7,r3,4 /* store second word */
- st r8,r3,8 /* store third word */
- st r9,r3,12 /* store fourth word */
- br.n _ASM_LABEL(r_word_copy) /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(r_1byte_half_copy)
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to half copy */
-
-ASLOCAL(r_half_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,_ASM_LABEL(r_byte_copy) /* not enough left, copy bytes */
- subu r2,r2,16 /* decrement source pointer */
- subu r3,r3,16 /* decrement destination pointer */
- ld.hu r6,r2,0 /* load first half-word */
- ld.hu r7,r2,2 /* load second half-word */
- ld.hu r8,r2,4 /* load third half-word */
- ld.hu r9,r2,6 /* load fourth half-word */
- ld.hu r10,r2,8 /* load fifth half-word */
- ld.hu r11,r2,10 /* load sixth half-word */
- ld.hu r12,r2,12 /* load seventh half-word */
- ld.hu r13,r2,14 /* load eighth half-word */
- st.h r6,r3,0 /* store first half-word */
- st.h r7,r3,2 /* store second half-word */
- st.h r8,r3,4 /* store third half-word */
- st.h r9,r3,6 /* store fourth half-word */
- st.h r10,r3,8 /* store fifth half-word */
- st.h r11,r3,10 /* store sixth half-word */
- st.h r12,r3,12 /* store seventh half-word */
- st.h r13,r3,14 /* store eighth half-word */
- br.n _ASM_LABEL(r_half_copy) /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-ASLOCAL(r_byte_copy)
- bcnd eq0,r4,_ASM_LABEL(bcopy_out) /* branch if nothing left to copy */
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load byte from source */
- st.b r6,r3,0 /* store byte in destination */
- br.n _ASM_LABEL(r_byte_copy) /* branch for next byte */
- subu r4,r4,1 /* decrement remaining length */
-
-ASLOCAL(bcopy_out)
- jmp r1 /* all done, return to caller */
-
- data
- align 4
-ASLOCAL(f_strat)
- word _ASM_LABEL(f_word_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_half_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_3byte_word_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_1byte_half_copy)
- word _ASM_LABEL(f_half_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_1half_word_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_1byte_half_copy)
- word _ASM_LABEL(f_byte_copy)
- word _ASM_LABEL(f_1byte_word_copy)
-
-ASLOCAL(r_strat)
- word _ASM_LABEL(r_word_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_half_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_1byte_word_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_1byte_half_copy)
- word _ASM_LABEL(r_half_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_1half_word_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_1byte_half_copy)
- word _ASM_LABEL(r_byte_copy)
- word _ASM_LABEL(r_3byte_word_copy)
-
- text
-
-/*######################################################################*/
-
-/*
- * April 1990, Omron Corporation
- * jfriedl@nff.ncl.omron.co.jp
- *
- * void bzero(destination, length)
- *
- * Clear (set to zero) LENGTH bytes of memory starting at DESTINATION.
- * Note that there is no return value.
- *
- * This is fast. Really fast. Especially for long lengths.
- */
-#define R_dest r2
-#define R_len r3
-
-#define R_bytes r4
-#define R_mark_address r5
-#define R_addr r6 /* R_addr && R_temp SHARE */
-#define R_temp r6 /* R_addr && R_temp SHARE */
-
-ENTRY(bzero)
- /*
- * If the destination is not word aligned, we'll word align
- * it first to make things easier.
- *
- * We'll check to see first if bit #0 is set and then bit #1
- * (of the destination address). If either are set, it's
- * not word aligned.
- */
- bb1 0, R_dest, _ASM_LABEL(not_initially_word_aligned)
- bb1 1, R_dest, _ASM_LABEL(not_initially_word_aligned)
-
-ASLOCAL(now_word_aligned)
- /*
- * before we get into the main loop, grab the
- * address of the label "mark" below.
- */
- or.u R_mark_address, r0, hi16(_ASM_LABEL(mark))
- or R_mark_address, R_mark_address, lo16(_ASM_LABEL(mark))
-
-ASLOCAL(top_of_main_loop)
-#define MAX_AT_ONE_TIME 128
- /*
- * Now we find out how many words we can zero-fill in a row.
- * We do this by doing something like:
- *
- * bytes &= 0xfffffffc;
- * if (bytes > MAX_AT_ONE_TIME)
- * bytes = MAX_AT_ONE_TIME;
- */
-
- /*
- * Clear lower two bits of length to give us the number of bytes
- * ALIGNED TO THE WORD LENGTH remaining to move.
- */
- clr R_bytes, R_len, 2<0>
-
- /* if we're done clearing WORDS, jump out */
- bcnd eq0, R_bytes, _ASM_LABEL(done_doing_words)
-
- /* if the number of bytes > MAX_AT_ONE_TIME, do only the max */
- cmp R_temp, R_bytes, MAX_AT_ONE_TIME
- bb1 lt, R_temp, 1f
-
- /*
- * Since we're doing the max, we know exactly where we're
- * jumping (the first one in the list!), so we can jump
- * right there. However, we've still got to adjust
- * the length, so we'll jump to where we ajust the length
- * which just happens to fall through to the first store zero
- * in the list.
- *
- * Note, however, that we're jumping to an instruction that
- * would be in the delay slot for the jump in front of it,
- * so if you change things here, WATCH OUT.
- */
- br.n do_max
- or R_bytes, r0, MAX_AT_ONE_TIME
-
-1:
- /*
- * Now we have the number of bytes to zero during this iteration,
- * (which, as it happens, is the last iteration if we're here).
- * We'll calculate the proper place to jump and then jump there,
- * after adjusting the length. NOTE that there is a label between
- * the "jmp.n" and the "subu" below... the "subu" is NOT always
- * executed in the delay slot of the "jmp.n".
- */
- subu R_addr, R_mark_address, R_bytes
-
- /* and go there (after adjusting the length via ".n") */
- jmp.n R_addr
-ASLOCAL(do_max)
- subu R_len, R_len, R_bytes /* NOTE: this is in the delay slot! */
-
- st r0, R_dest, 0x7c /* 128 */
- st r0, R_dest, 0x78 /* 124 */
- st r0, R_dest, 0x74 /* 120 */
- st r0, R_dest, 0x70 /* 116 */
- st r0, R_dest, 0x6c /* 112 */
- st r0, R_dest, 0x68 /* 108 */
- st r0, R_dest, 0x64 /* 104 */
- st r0, R_dest, 0x60 /* 100 */
- st r0, R_dest, 0x5c /* 96 */
- st r0, R_dest, 0x58 /* 92 */
- st r0, R_dest, 0x54 /* 88 */
- st r0, R_dest, 0x50 /* 84 */
- st r0, R_dest, 0x4c /* 80 */
- st r0, R_dest, 0x48 /* 76 */
- st r0, R_dest, 0x44 /* 72 */
- st r0, R_dest, 0x40 /* 68 */
- st r0, R_dest, 0x3c /* 64 */
- st r0, R_dest, 0x38 /* 60 */
- st r0, R_dest, 0x34 /* 56 */
- st r0, R_dest, 0x30 /* 52 */
- st r0, R_dest, 0x2c /* 44 */
- st r0, R_dest, 0x28 /* 40 */
- st r0, R_dest, 0x24 /* 36 */
- st r0, R_dest, 0x20 /* 32 */
- st r0, R_dest, 0x1c /* 28 */
- st r0, R_dest, 0x18 /* 24 */
- st r0, R_dest, 0x14 /* 20 */
- st r0, R_dest, 0x10 /* 16 */
- st r0, R_dest, 0x0c /* 12 */
- st r0, R_dest, 0x08 /* 8 */
- st r0, R_dest, 0x04 /* 4 */
- st r0, R_dest, 0x00 /* 0 */
-
-ASLOCAL(mark)
- br.n _ASM_LABEL(top_of_main_loop)
- addu R_dest, R_dest, R_bytes /* bump up the dest address */
-
-ASLOCAL(done_doing_words)
- bcnd ne0, R_len, 1f
- jmp r1
-
-1:
- subu R_len, R_len, 1
- bcnd.n ne0, R_len, 1b
- st.b r0, R_dest, R_len
-1:
- jmp r1
-
-ASLOCAL(not_initially_word_aligned)
- /*
- * Bzero to word-align the address (at least if the length allows it).
- */
- bcnd eq0, R_len, 1b
- st.b r0, R_dest, 0
- addu R_dest, R_dest, 1
- mask R_temp, R_dest, 0x3
- bcnd.n eq0, R_temp, _ASM_LABEL(now_word_aligned)
- subu R_len, R_len, 1
- br _ASM_LABEL(not_initially_word_aligned)
-
-#undef R_dest
-#undef R_len
-#undef R_bytes
-#undef R_mark_address
-#undef R_addr
-#undef R_temp
-#undef MAX_AT_ONE_TIME
-
-/*
* non-local goto
* int setjmp(label_t *);
* void longjmp(label_t*);