Linux PARISC architecture development
 help / color / mirror / Atom feed
From: "Joel Soete" <soete.joel@tiscali.be>
To: "Michael S. Zick" <mszick@goquest.com>, parisc-linux@parisc-linux.org
Subject: Re: [parisc-linux] uninline in bitops.c as ia64 or sparc64?
Date: Wed, 11 Aug 2004 13:58:01 +0200	[thread overview]
Message-ID: <40FB89640000B461@ocpmta2.freegates.net> (raw)
In-Reply-To: <200408101145.20933.mszick@goquest.com>


Hello *,

> Subject: Re: [parisc-linux] uninline in bitops.c as ia64 or sparc64?
> 
> 
> On Tue August 10 2004 09:51, John David Anglin wrote:
> > > On Mon, Aug 09, 2004 at 09:54:08AM -0500, Michael S. Zick wrote:
> > > > generic_ffz is defined as integer - is 'integer' the same size
> > > > cpu32 and cpu64?  If not, that routine needs a size-conditional
> > > > test for the other 32 bits on cpu64.
> > > 
> > > Integers are the same size. The 64-bit boxes are LP64.
> > 
> > To be more specific, the 'int' types are the same size.  The 'long'
> > types are different.
> > 
> > Dave
> Thanks -
> I was able to get my other questions answered with
> a little bit of work with the x-compiler and code snippets.
> 
> I am beginning to think I will learn more than I ever wanted
> to know about a hand-full of hp-instructions before I am done.
> 
> Still, it is an interesting problem and Joel has volunteered
> to test.
> 
Here is the smal test case I tested:
#ifndef __LP64__
#include <stdio.h>
#include <limits.h>
#else
#include "64bit/lib/headers.h"

#define print1(str, num) \
	print(str); \
	hex((unsigned long)num, buf); \
	print(buf); \
	print("\n")
#endif


/*
 * ffs: find first bit set. This is defined the same way as
 * the libc and compiler builtin ffs routines, therefore
 * differs in spirit from the above ffz (man ffs).
 */

/* Extended version for ulong param x */

static __inline__ unsigned long generic_ffs(unsigned long x)
{
        unsigned long r =3D 1;

        if (!x)
                return 0;
#ifdef __LP64__
        if (!(x & 0xffffffffUL)) {
                x >>=3D 32;
                r +=3D 32;
        }
#endif
        if (!(x & 0xffffUL)) {
                x >>=3D 16;
                r +=3D 16;
        }
        if (!(x & 0xffUL)) {
                x >>=3D 8;
                r +=3D 8;
        }
        if (!(x & 0xfUL)) {
                x >>=3D 4;
                r +=3D 4;
        }
        if (!(x & 3UL)) {
                x >>=3D 2;
                r +=3D 2;
        }
        if (!(x & 1UL)) {
                x >>=3D 1;
                r +=3D 1;
        }
        return r;
}

static __inline__ unsigned long __ffs(unsigned long x)
{
	unsigned long ret;

	__asm__(
#ifdef __LP64__
		" ldi       63,%1\n"
		" extrd,u,*<>  %0,63,32,%%r0\n"
		" extrd,u,*TR  %0,31,32,%0\n"	/* move top 32-bits down */
		" addi    -32,%1,%1\n"
		" extrd,u,*<>  %0,63,16,%%r0\n"
		" extrd,u,*TR  %0,47,16,%0\n"   /* xxxx0000 -> 0000xxxx */
		" addi    -16,%1,%1\n"
		" extrd,u,*<>  %0,63,8,%%r0\n"
		" extrd,u,*TR  %0,55,8,%0\n"    /* 0000xx00 -> 000000xx */
		" addi    -8,%1,%1\n"
		" extrd,u,*<>  %0,63,4,%%r0\n"
		" extrd,u,*TR  %0,59,4,%0\n"    /* 000000x0 -> 0000000x */
		" addi    -4,%1,%1\n"
		" extrd,u,*<>  %0,63,2,%%r0\n"
		" extrd,u,*TR  %0,61,2,%0\n"    /* 0000000y, 1100b -> 0011b */
		" addi    -2,%1,%1\n"
		" extrd,u,*=3D  %0,63,1,%%r0\n"   /* check last bit */
		" addi    -1,%1,%1\n"
#else
		" ldi       31,%1\n"
		" extru,<>  %0,31,16,%%r0\n"
		" extru,TR  %0,15,16,%0\n"	/* xxxx0000 -> 0000xxxx */
		" addi    -16,%1,%1\n"
		" extru,<>  %0,31,8,%%r0\n"
		" extru,TR  %0,23,8,%0\n"	/* 0000xx00 -> 000000xx */
		" addi    -8,%1,%1\n"
		" extru,<>  %0,31,4,%%r0\n"
		" extru,TR  %0,27,4,%0\n"	/* 000000x0 -> 0000000x */
		" addi    -4,%1,%1\n"
		" extru,<>  %0,31,2,%%r0\n"
		" extru,TR  %0,29,2,%0\n"	/* 0000000y, 1100b -> 0011b */
		" addi    -2,%1,%1\n"
		" extru,=3D  %0,31,1,%%r0\n"	/* check last bit */
		" addi    -1,%1,%1\n"
#endif
			: "+r" (x), "=3Dr" (ret) );
	return ret;
}

static unsigned long ULffs(unsigned long x)
{
	return x ? (__ffs((unsigned long)x) + 1) : 0;
}

main()
{
	char buf[512];
	unsigned long i, Extrd;

#ifndef __LP64__
	printf("Computing ffs() for i =3D %u to %u...\n", 0, 0xffffffffU);
	for (i=3D0x0UL; i<0xffffffffUL; i++) {
		if ( generic_ffs(i) !=3D ULffs(i) ) {
			printf("i =3D %#010x (%u)\n", i, i);
			printf("generic_ffs() =3D %u\n", generic_ffs(i));
			printf("ffs() =3D %u\n", ULffs(i));
		}
	}
	printf("i=3D %#010x (%u), finished.\n", i, i);
#else
	for (i=3D0xfffffffUL; i<0xf00000000UL; i++) {
		if ( generic_ffs(i) !=3D ULffs(i) ) {
			print1("i =3D ", i);
			print1("generic_ffs() =3D ", generic_ffs(i));
			print1("ffs() =3D ", ULffs(i));
		}
	}
#endif
}

I compile it with James 64bit lib with hppa64-linux-gcc (3.0.4) and run
it on a b2k (64bit cpu) with 2.6.8-rc2-pa7 64bit.
That's a long test (reason of delay) but it works fine.

I also test the 32bit binaries (compile with gcc-3.3.4) runing on the b2k=

with same kernel and it also works fine.

Please note that I have to abuse the original ffs() code with ULffs() and=

an unsigned long (64bit long for hppa64-gcc) as parameter (the original
was an integer of 32bit long for 64bit and 32bit gcc).

hth,
    Joel


-------------------------------------------------------------------------=
--
Tiscali ADSL LIGHT, 19,95 EUR/mois pendant 6 mois, c'est le moment de fai=
re
le pas!
http://reg.tiscali.be/default.asp?lg=3Dfr




_______________________________________________
parisc-linux mailing list
parisc-linux@lists.parisc-linux.org
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

       reply	other threads:[~2004-08-11 11:58 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <200408101145.20933.mszick@goquest.com>
2004-08-11 11:58 ` Joel Soete [this message]
2004-08-12 13:59   ` [parisc-linux] uninline in bitops.c as ia64 or sparc64? Michael S. Zick
2004-08-13 18:15     ` Michael S. Zick
2004-06-06 19:22 [parisc-linux] uniline ? Joel Soete
     [not found] ` <200407310929.29022.mszick@goquest.com>
     [not found]   ` <1091293141.1920.34.camel@mulgrave>
2004-08-09 14:54     ` [parisc-linux] uninline in bitops.c as ia64 or sparc64? Michael S. Zick
2004-08-09 17:15       ` Michael S. Zick

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=40FB89640000B461@ocpmta2.freegates.net \
    --to=soete.joel@tiscali.be \
    --cc=mszick@goquest.com \
    --cc=parisc-linux@parisc-linux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox