Pure FB Runtime Library (in progress)

User projects written in or related to FreeBASIC.
Imortis
Posts: 1382
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Pure FB Runtime Library (in progress)

Postby Imortis » Sep 13, 2017 15:59

So for those who missed it here I am going to attempt to convert the freeBASIC rtlib to FB. I am going to post my progress and questions here, so if anyone is interested or wants to help in any way, this is the place to do it. I plan to make this a stand alone library first. Make small pieces and test them one at a time. This will make progress and testing a bit more manageable.

First things first: I am going to try and work on the error handling/reporting first because EVERY other part of the rtlib uses it in some way.
PaulSquires
Posts: 578
Joined: Jul 14, 2005 23:41
Contact:

Re: Pure FB Runtime Library (in progress)

Postby PaulSquires » Sep 13, 2017 16:28

Awesome Imortis, I'm sure that there's many people here that will love to help as much as we can. Good luck!
Imortis
Posts: 1382
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Pure FB Runtime Library (in progress)

Postby Imortis » Sep 13, 2017 20:48

I have already run in to a bit of a conundrum...

When did Solaris support get added to the RTLib, and why is there no __FB_SOLARIS__ define?
TeeEmCee
Posts: 170
Joined: Jul 22, 2006 0:54
Location: Auckland

Re: Pure FB Runtime Library (in progress)

Postby TeeEmCee » Sep 14, 2017 9:46

I had never even noticed Solaris support before. It was added in 2015 by Stefan Schmidt

Don't worry about details like that. You can use __FB_SOLARIS__ even though it doesn't exist yet. Someone can add it to the compiler later.
St_W
Posts: 993
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Pure FB Runtime Library (in progress)

Postby St_W » Sep 17, 2017 11:28

Is there some (public) VCS repository one could follow? (e.g. on GitHub or BitBucket)
Imortis
Posts: 1382
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Pure FB Runtime Library (in progress)

Postby Imortis » Sep 18, 2017 13:00

Not yet. I will make a github repo once Ihave something usable. Right now It is mostly just grunt work of converting all the ground work so other things can work.
counting_pine
Site Admin
Posts: 5775
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Pure FB Runtime Library (in progress)

Postby counting_pine » Sep 18, 2017 14:32

Do we have provisioning yet for including bas files when compiling the rtlib?
I wouldn't have thought it would be too hard, but feels like an important first step.
Imortis
Posts: 1382
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Pure FB Runtime Library (in progress)

Postby Imortis » Sep 18, 2017 16:14

counting_pine wrote:Do we have provisioning yet for including bas files when compiling the rtlib?
I wouldn't have thought it would be too hard, but feels like an important first step.


My goal is to make it a standalone lib at first, so I can test it alongside the current to make sure everything works as it did before. That way, I don't have to include single objects to the current, I can include the whole thing all at once when I get it working.
Imortis
Posts: 1382
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Pure FB Runtime Library (in progress)

Postby Imortis » Sep 18, 2017 17:49

This bit is using inline asm. I have never used that part of FB, and while I am sure I could figure it out over time, it would be quicker if someone more familiar could take a look at it.

Code: Select all

/' CPU-dependent macros and inline functions *'/
#ifdef HOST_X86
    static __inline__ int FB_MEMCMP( const void *p1, const void *p2, size_t len )
    {
        int res;
        if( len==0 )
            return 0;
        __asm volatile (
               " pushl %%esi      \n"
               " pushl %%edi      \n"
               " repe             \n"
               " cmpsb            \n"
               " je 0f            \n"
               " movl $1, %%ecx   \n"
               " ja 0f            \n"
               " neg %%ecx        \n"
               "0:                \n"
               " popl %%edi       \n"
               " popl %%esi       \n"
               : "=c" (res)
               : "c" (len), "S" (p1), "D" (p2)
              );
        return res;
    }

    static __inline__ void *FB_MEMCPY( void *dest, const void *src, size_t n )
    {
        __asm volatile (
               " pushl %%ecx      \n"
               " pushl %%esi      \n"
               " pushl %%edi      \n"
               " pushl %%ecx      \n"
               " shrl $2,%%ecx    \n"
               " rep              \n"
               " movsd            \n"
               " popl %%ecx       \n"
               " andl $3,%%ecx    \n"
               " rep              \n"
               " movsb            \n"
               " popl %%edi       \n"
               " popl %%esi       \n"
               " popl %%ecx       \n"
               :
               : "c" (n), "S" (src), "D" (dest)
              );
        return dest;
    }

    /'* Same as FB_MEMCPY but returns position after destination string.
     '/
    static __inline__ void *FB_MEMCPYX( void *dest, const void *src, size_t n )
    {
        __asm volatile (
               " pushl %%ecx      \n"
               " pushl %%esi      \n"
               " pushl %%ecx      \n"
               " shrl $2,%%ecx    \n"
               " rep              \n"
               " movsd            \n"
               " popl %%ecx       \n"
               " andl $3,%%ecx    \n"
               " rep              \n"
               " movsb            \n"
               " popl %%esi       \n"
               " popl %%ecx       \n"
               : "=D" (dest)
               : "c" (n), "S" (src), "D" (dest)
              );
        return dest;
    }

    static __inline__ const void *FB_MEMCHR( const void *s, int c, size_t n )
    {
        const void *dst;
        if( n==0 )
            return NULL;
        __asm volatile (
               " pushl %%ecx            \n"
               " pushf                  \n"
               " cld                    \n"
               " repne                  \n"
               " scasb                  \n"
               " jne 0f                 \n"
               " dec %%edi              \n"
               " jmp 1f                 \n"
               "0:                      \n"
               " xorl %%edi, %%edi      \n"
               "1:                      \n"
               " popf                   \n"
               " popl %%ecx             \n"
               : "=D" (dst)
               : "c" (n), "a" (c), "D" (s)
              );
        return dst;
    }

    /'* Searches for the first ocurrence of a character unequal to c.
     '/
    static __inline__ size_t FB_MEMLEN( const void *s, int c, size_t n )
    {
        size_t len;
        if( n==0 )
            return 0;
        __asm volatile (
               " pushl %%edi            \n"
               " pushf                  \n"
               " std                    \n"  /* DF = 1 -> from hi to lo */
               " repe                   \n"
               " scasb                  \n"
               " je 0f                  \n"
               " inc %%ecx              \n"
               "0:                      \n"
               " popf                   \n"
               " popl %%edi             \n"
               : "=c" (len)
               : "c" (n), "a" (c), "D" ((const char*) s + n - 1)
              );
        return len;
    }

   #define RORW(num, bits) __asm__ __volatile__("rorw %1, %0" : "=m"(num) : "c"(bits) : "memory")
   #define RORW1(num)      __asm__ __volatile__("rorw $1, %0" : "=m"(bit) : : "memory");
#else
   /' We use memcmp from C because the compiler might replace this by a built-in
    * function which will definately be faster than our own implementation in C. '/
   #define FB_MEMCMP(p1, p2, len) memcmp( p1, p2, len )
   #define FB_MEMCPY( dest, src, n ) memcpy(dest, src, n)
   #define FB_MEMCHR( s, c, n ) memchr( s, c, n )

   /' We have to wrap memcpy here because our MEMCPYX should return the position
   * after the destination string. '/
   static __inline__ void *FB_MEMCPYX( void *dest, const void *src, size_t n )
   {
      memcpy(dest, src, n);
      return ((char *)dest)+n;
   }

   static __inline__ size_t FB_MEMLEN( const void *s, int c, size_t n )
   {
      const char *pachData = (const char*) s;
      while (n--) {
         if( pachData[n]!=(char)c )
            return n+1;
      }
      return 0;
   }

   #define RORW(num, bits) num = (((((num) & &hFFFF) >> (bits) ) | ((num) << (16 - bits))) & &hFFFF)
   #define RORW1(num)      RORW(num, 1)
#endif
TeeEmCee
Posts: 170
Joined: Jul 22, 2006 0:54
Location: Auckland

Re: Pure FB Runtime Library (in progress)

Postby TeeEmCee » Sep 19, 2017 7:38

The set of functions you posted using raw assembly are guarded by a preprocessor check. They are completely optional; just ignore it.

I have no idea why the rtlib includes asm versions of standard C function calls. Probably they should just be deleted; the C versions, either in libc or a compiler intrinsic, are likely to be many times faster than those naive asm versions.

(That said, sometimes glibc tries to be too clever and has major performance problems. I noticed that a certain x64 cpu-specific memcmp specialisation in glibc is over 10x slower on my AMD CPU than the 32 bit version of memcmp; it seems to be using some fancy new instructions that AMD didn't optimise. I've also seen an intern at Intel try to get a braindead CPU-specific memcpy specialisation into glibc that used a different version of memcpy for every length up to about 256 bytes, icache be damned!)
counting_pine
Site Admin
Posts: 5775
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Pure FB Runtime Library (in progress)

Postby counting_pine » Sep 19, 2017 11:52

The asm code was possibly more relevant when we only had a 'gas' emitter. (Thankfully FB has fewer gas emissions now :)
Now seems like a good time to remove the assembly. We could always re-add it at a later date if need be.

Edit: actually, given it's used specifically within the rtlib, I don't think it can have been related to the old emitter.
Either it was actually faster, or someone was just being "clever", and never actually benchmarked it.
Imortis
Posts: 1382
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Pure FB Runtime Library (in progress)

Postby Imortis » Sep 19, 2017 14:44

Thanks guys. I will just include the crt versions then.
marcov
Posts: 2328
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: Pure FB Runtime Library (in progress)

Postby marcov » Sep 19, 2017 17:26

What are the cross-backend asm options?
dodicat
Posts: 4225
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Pure FB Runtime Library (in progress)

Postby dodicat » Sep 19, 2017 18:22

A pure fb runtime library, geared up for a C backend?
I am confused!
Surely I misunderstand something.
Imortis
Posts: 1382
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Pure FB Runtime Library (in progress)

Postby Imortis » Sep 19, 2017 19:35

dodicat wrote:geared up for a C backend?

I don't know what you mean here...

Return to “Projects”

Who is online

Users browsing this forum: No registered users and 3 guests