[PATCH 5 of 6]

Juan Perez-Sanchez <[email protected]>
Newsgroups org.kernel.vger.linux-8086
Message-ID <CAD6VGuYwgBAowZ6-Xbg59Aqr6P8-+mcTj_60j9tUdtn+u7vMNQ@mail.gmail.com>
Hi,

 Modified the implementation of functions find_first_non_zero_bit()
and find_first_zero_bit() in file arch/i86/lib/bitops.c to make them
faster. This came at the cost of an increase in code size. To
compensate for this, also optimized numerous functions in the
arch/i86/lib directory.

2. Code size increased by 32 bytes.

 The Image builded without errors. The kernel was tested with QEMU and
dioscuri emulators. Also in a PPro pc booting from floppy.

Greetings,

Juan
elksY.patch (application/octet-stream, 10.6 KB)
diff -Nur elks.orig/arch/i86/lib/bitops.c elks/arch/i86/lib/bitops.c
--- elks.orig/arch/i86/lib/bitops.c	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/bitops.c	2013-02-27 18:09:39.000000000 -0600
@@ -6,19 +6,19 @@
 /*
  *	Messy as we lack atomic bit operations on an 8086.
  */
- 
+
 unsigned char clear_bit(unsigned int bit,void *addr)
 {
     register unsigned char *ptr;
     flag_t flags;
     unsigned int mask;
 
-	ptr = ((unsigned char *)addr) + (bit / 8);
-    bit %= 8;
+    ptr = ((unsigned char *)addr) + (bit >> 3);
+    bit &= 0x07;
     mask = (1 << bit);
     save_flags(flags);
     clr_irq();
-	mask &= *ptr;
+    mask &= *ptr;
     *ptr &= ~mask;
     restore_flags(flags);
     return mask >> bit;
@@ -30,12 +30,12 @@
     flag_t flags;
     unsigned int mask, r;
 
-	ptr = ((unsigned char *)addr) + (bit / 8);
-    bit %= 8;
+    ptr = ((unsigned char *)addr) + (bit >> 3);
+    bit &= 0x07;
     mask = (1 << bit);
     save_flags(flags);
     clr_irq();
-	r = *ptr & mask;
+    r = *ptr & mask;
     *ptr |= mask;
     restore_flags(flags);
     return r >> bit;
@@ -43,40 +43,56 @@
 
 unsigned char test_bit(unsigned int bit,void *addr)
 {
-	return ( ((1 << (bit % 8))
-			  & ((unsigned char *) addr)[bit / 8]) != 0);
+	return ( ((1 << (bit & 0x07))
+			  & *((unsigned char *)addr + (bit >> 3))) != 0);
 }
 
 /* Ack... nobody even seemed to try to write to a file before 0.0.49a was
  * released, or otherwise they might have tracked it down to this being
- * non-existant :) 
+ * non-existant :)
  * - Chad
  */
 
 /* Use the old faithful version */
-unsigned int find_first_non_zero_bit(void *addr, unsigned int len)
+unsigned int find_first_non_zero_bit(register int *addr, unsigned int len)
 {
-	register char *pi = 0;
+    register char *bit = 0;
+    unsigned int mask;
 
-	while (((unsigned int) pi) < len) {
-		if (test_bit(((unsigned int) pi), addr)) {
-			break;
-		}
-		++pi;
+    do {
+	if(*addr) {
+	    mask = 1;
+	    while(!(*addr & mask)) {
+		mask <<= 1;
+		bit++;
+	    }
+	    break;
 	}
-	return (unsigned int) pi;
+	addr++;
+    } while((unsigned int)(bit += 16) < len);
+    if((unsigned int)bit > len)
+	bit = (char *)len;
+    return (unsigned int)bit;
 }
 
 /* Use the old faithful version */
-unsigned int find_first_zero_bit(void *addr, unsigned int len)
+unsigned int find_first_zero_bit(register int *addr, unsigned int len)
 {
-	register char *pi = 0;
+    register char *bit = 0;
+    unsigned int mask;
 
-	while (((unsigned int) pi) < len) {
-		if (!test_bit(((unsigned int) pi), addr)) {
-			break;
-		}
-		++pi;
+    do {
+	if(~(*addr)) {
+	    mask = 1;
+	    while(*addr & mask) {
+		mask <<= 1;
+		bit++;
+	    }
+	    break;
 	}
-	return (unsigned int) pi;
+	addr++;
+    } while((unsigned int)(bit += 16) < len);
+    if((unsigned int)bit > len)
+	bit = (char *)len;
+    return (unsigned int)bit;
 }
diff -Nur elks.orig/arch/i86/lib/border.s elks/arch/i86/lib/border.s
--- elks.orig/arch/i86/lib/border.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/border.s	2013-02-27 18:09:39.000000000 -0600
@@ -7,14 +7,11 @@
 
 _htonl:
 _ntohl:
-	push	bp
-	mov	bp,sp
-	mov     bx,4[bp]
-	mov     ax,6[bp]
-	mov	cl,#8
-	ror	ax,cl
-	ror	bx,cl
-	mov	dx,bx
-	pop	bp
-	ret
+	pop	bx
+	pop	dx
+	pop	ax
+	sub	sp,#4
+	xchg	ah,al
+	xchg	dh,dl
+	jmp	bx
 
diff -Nur elks.orig/arch/i86/lib/lcmpb.s elks/arch/i86/lib/lcmpb.s
--- elks.orig/arch/i86/lib/lcmpb.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/lcmpb.s	2013-02-27 18:09:39.000000000 -0600
@@ -10,12 +10,7 @@
 
 lcmpub:
 	sub	ax,(di)		! don't need to preserve ax
-	je	LCMP_NOT_SURE
-	ret
-
-	.even
-
-LCMP_NOT_SURE:
+	jne	LCMP_EXIT
 	cmp	bx,2(di)
 	jb	LCMP_B_AND_LT	! b (below) becomes lt (less than) as well
 	jge	LCMP_EXIT	! ge and already ae
diff -Nur elks.orig/arch/i86/lib/lcmpl.s elks/arch/i86/lib/lcmpl.s
--- elks.orig/arch/i86/lib/lcmpl.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/lcmpl.s	2013-02-27 18:09:39.000000000 -0600
@@ -10,12 +10,7 @@
 
 lcmpul:
 	sub	bx,2[di]	! don't need to preserve bx
-	je	LCMP_NOT_SURE
-	ret
-
-	.even
-
-LCMP_NOT_SURE:
+	jne	LCMP_EXIT
 	cmp	ax,[di]
 	jb	LCMP_B_AND_LT	! b (below) becomes lt (less than) as well
 	jge	LCMP_EXIT	! ge and already ae
diff -Nur elks.orig/arch/i86/lib/ldecb.s elks/arch/i86/lib/ldecb.s
--- elks.orig/arch/i86/lib/ldecb.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/ldecb.s	2013-02-27 18:09:39.000000000 -0600
@@ -8,14 +8,6 @@
 ldecb:
 
 ldecub:
-	cmp	2(bx),*0
-	je	LDEC_BOTH
-	dec	2(bx)
-	ret
-
-	.even
-
-LDEC_BOTH:
-	dec	2(bx)
-	dec	(bx)
+	sub	word ptr 2[bx],#1
+	sbb	word ptr [bx],#0
 	ret
diff -Nur elks.orig/arch/i86/lib/ldecl.s elks/arch/i86/lib/ldecl.s
--- elks.orig/arch/i86/lib/ldecl.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/ldecl.s	2013-02-27 18:09:39.000000000 -0600
@@ -8,14 +8,6 @@
 ldecl:
 
 ldecul:
-	cmp	word ptr [bx],*0
-	je	LDEC_BOTH
-	dec	word ptr [bx]
-	ret
-
-	.even
-
-LDEC_BOTH:
-	dec	word ptr [bx]
-	dec	word ptr 2[bx]
+	sub	word ptr [bx],#1
+	sbb	word ptr 2[bx],#0
 	ret
diff -Nur elks.orig/arch/i86/lib/lincb.s elks/arch/i86/lib/lincb.s
--- elks.orig/arch/i86/lib/lincb.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/lincb.s	2013-02-27 18:09:39.000000000 -0600
@@ -9,11 +9,7 @@
 
 lincub:
 	inc	2(bx)
-	je	LINC_HIGH_WORD
-	ret
-
-	.even
-
-LINC_HIGH_WORD:
+	jne	LINC_END
 	inc	(bx)
+LINC_END:
 	ret
diff -Nur elks.orig/arch/i86/lib/lsrb.s elks/arch/i86/lib/lsrb.s
--- elks.orig/arch/i86/lib/lsrb.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/lsrb.s	2013-02-27 18:09:39.000000000 -0600
@@ -9,7 +9,8 @@
 	mov	cx,di
 	jcxz	LSR_EXIT
 	cmp	cx,*32
-	jae	LSR_SIGNBIT
+	jb	LSR_LOOP
+	mov	cx,*32		! equivalent to +infinity in this context
 
 LSR_LOOP:
 	sar	ax,*1
@@ -19,8 +20,3 @@
 LSR_EXIT:
 	ret
 
-	.even
-
-LSR_SIGNBIT:
-	mov	cx,*32		! equivalent to +infinity in this context
-	j	LSR_LOOP
diff -Nur elks.orig/arch/i86/lib/lsrl.s elks/arch/i86/lib/lsrl.s
--- elks.orig/arch/i86/lib/lsrl.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/lsrl.s	2013-02-27 18:09:39.000000000 -0600
@@ -9,7 +9,8 @@
 	mov	cx,di
 	jcxz	LSR_EXIT
 	cmp	cx,*32
-	jae	LSR_SIGNBIT
+	jb	LSR_LOOP
+	mov	cx,*32		! equivalent to +infinity in this context
 
 LSR_LOOP:
 	sar	bx,*1
@@ -19,8 +20,3 @@
 LSR_EXIT:
 	ret
 
-	.even
-
-LSR_SIGNBIT:
-	mov	cx,*32		! equivalent to +infinity in this context
-	j	LSR_LOOP
diff -Nur elks.orig/arch/i86/lib/ltstb.s elks/arch/i86/lib/ltstb.s
--- elks.orig/arch/i86/lib/ltstb.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/ltstb.s	2013-02-27 19:49:32.000000000 -0600
@@ -10,18 +10,9 @@
 
 ltstub:
 	test	ax,ax
-	je	LTST_NOT_SURE
-	ret
-
-	.even
-
-LTST_NOT_SURE:
+	jne	LTSTB_RET
 	test	bx,bx
-	js	LTST_FIX_SIGN
-	ret
-
-	.even
-
-LTST_FIX_SIGN:
+	jns	LTST_RET
 	inc	ax		! clear ov and mi, set ne for greater than
+LTSTB_RET:
 	ret
diff -Nur elks.orig/arch/i86/lib/ltstl.s elks/arch/i86/lib/ltstl.s
--- elks.orig/arch/i86/lib/ltstl.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/ltstl.s	2013-02-27 19:51:12.000000000 -0600
@@ -9,18 +9,9 @@
 ltstl:
 ltstul:
 	test	bx,bx
-	je	LTST_NOT_SURE
-	ret
-
-	.even
-
-LTST_NOT_SURE:
+	jne	LTSTL_RET
 	test	ax,ax
-	js	LTST_FIX_SIGN
-	ret
-
-	.even
-
-LTST_FIX_SIGN:
+	jns	LTSTL_RET
 	inc	bx		! clear ov and mi, set ne for greater than
+LTSTL_RET:
 	ret
diff -Nur elks.orig/arch/i86/lib/memmove.c elks/arch/i86/lib/memmove.c
--- elks.orig/arch/i86/lib/memmove.c	2012-10-18 13:48:54.000000000 -0500
+++ elks/arch/i86/lib/memmove.c	2013-02-27 18:50:27.000000000 -0600
@@ -20,7 +20,7 @@
 
 	if ((sseg < dseg) || ((sseg == dseg) && (soff < doff))) {
 	    --bytes;
-	    blt_forth(sseg, soff+bytes, dseg, doff+bytes, bytes+1);
+	    blt_forth(soff+bytes, sseg, doff+bytes, dseg, bytes+1);
 	} else {
 	    fmemcpy(dseg, doff, sseg, soff, bytes );
 	}
@@ -30,26 +30,20 @@
 #ifndef S_SPLINT_S
 #asm
 	.text
-				! blt_forth( sseg, soff, dseg, doff, bytes )
-				! for to > from 
+				! blt_forth( soff, sseg, doff, dseg, bytes )
+				! for to > from
 	.even
 
 _blt_forth:
 	push	bp
 	mov	bp, sp
-	push	ax
 	push	es
 	push	ds
-	push	cx	
 	push	si
 	push	di
 	pushf
-	mov	ax, [bp+4]
-	mov	ds, ax
-	mov	si, [bp+6]
-	mov	ax, [bp+8]
-	mov	es, ax
-	mov	di, [bp+10]
+	lds	si, [bp+4]
+	les	di, [bp+8]
 	mov	cx, [bp+12]
 	std
 	rep
@@ -57,10 +51,8 @@
 	popf
 	pop	di
 	pop	si
-	pop	cx
 	pop	ds
 	pop	es
-	pop	ax
 	pop	bp
 	ret
 
diff -Nur elks.orig/arch/i86/lib/string.s elks/arch/i86/lib/string.s
--- elks.orig/arch/i86/lib/string.s	2012-08-18 13:28:59.000000000 -0500
+++ elks/arch/i86/lib/string.s	2013-02-27 19:40:31.000000000 -0600
@@ -17,8 +17,6 @@
 _strlen:			! needs more testing!
 	push	bp
 	mov	bp,sp
-	push	dx
-	push	cx
 	push	di
 	mov	dx,[bp+4]
 	mov	di,dx
@@ -31,8 +29,6 @@
 	mov	ax,di
 	dec	ax
 	pop	di
-	pop	cx
-	pop	dx
 	pop	bp
 	ret
 
@@ -49,15 +45,13 @@
 	push	si
 	mov	di,[bp+4]	! address of the destination string
 	mov	si,[bp+6]	! address of the source string
-	mov	ax,di
-	push	ax		! _strcpy returns a pointer to the destination string
 	cld
 
 copyon:	lodsb			! al = [ds:si++]
 	stosb			! [es:di++] = al
 	test	al,al
 	jnz	copyon
-	pop	ax
+	mov	ax,[bp+4]	! _strcpy returns a pointer to the destination string
 	pop	si
 	pop	di
 	pop	bp
@@ -102,16 +96,13 @@
 	push	bp
 	mov	bp,sp
 	push	di
-	push	cx
 	mov	di,[bp+4]	! address of the memory block
-	push	di		! return value = start addr of block
 	mov	ax,[bp+6]	! byte to write
 	mov	cx,[bp+8]	! loop count
 	cld
 	rep			! while(cx)
 	stosb			! 	cx--, [es:di++] = al
-	pop	ax
-	pop	cx
+	mov	ax,[bp+4]	! return value = start addr of block
 	pop	di
 	pop	bp
 	ret
diff -Nur elks.orig/arch/i86/mm/user.c elks/arch/i86/mm/user.c
--- elks.orig/arch/i86/mm/user.c	2012-10-17 13:38:32.000000000 -0500
+++ elks/arch/i86/mm/user.c	2013-02-27 19:17:32.000000000 -0600
@@ -118,8 +118,7 @@
 	push	es
 	pushf
 	mov	es, 4[bp]
-	mov	di, 6[bp]
-	mov	ds, 8[bp]
+	lds	di, 6[bp]
 	mov	si, 10[bp]
 	mov	cx, 12[bp]
 	cld			! Must move upwards...
@@ -163,7 +162,6 @@
 #asm
 
 	push	di
-	push	si
 	mov	dx,es
 	mov	es,[bp+.strlen_fromfs.ds]	! source segment (local variable)
 	mov	di,[bp+.strlen_fromfs.saddr]	! source address
@@ -176,7 +174,6 @@
 	dec	di
 	mov	[bp+.strlen_fromfs.ds],di	! save in local var ds
 	mov	es,dx
-	pop	si
 	pop	di
 #endasm
 #endif
diff -Nur elks.orig/include/arch/bitops.h elks/include/arch/bitops.h
--- elks.orig/include/arch/bitops.h	2012-08-18 13:28:59.000000000 -0500
+++ elks/include/arch/bitops.h	2013-02-27 18:09:39.000000000 -0600
@@ -5,7 +5,7 @@
 extern unsigned char set_bit(unsigned int,void *);
 extern unsigned char test_bit(unsigned int,void *);
 
-extern unsigned int find_first_non_zero_bit(void *,unsigned int);
-extern unsigned int find_first_zero_bit(void *,unsigned int);
+extern unsigned int find_first_non_zero_bit(register void *,unsigned int);
+extern unsigned int find_first_zero_bit(register void *,unsigned int);
 
 #endif
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.