gm2
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Partial success building the trunk on MSYS2/Windows platform


From: Runar Tenfjord
Subject: Re: Partial success building the trunk on MSYS2/Windows platform
Date: Mon, 31 Oct 2022 20:41:27 +0100

Hi,

Thank you for your detailed explanation. My knowledge of the C language
is limited and I missed a bit the distinction between the various types.

I was trying to port the 'strlen' function from newlib and looked
into the examples in the testsuite for inspiration as suggested
and came up with:

(* Adapted from GNU NewLib *)
(* gm2 -g  -fcpp -Wall String.mod *)
MODULE String ;

FROM SYSTEM IMPORT ADR, BITSET32, WORD, TSIZE ;
FROM ASCII IMPORT nul;

TYPE
(* defined(__x86_64) || (defined(__alpha__) && defined(__arch64__)) || defined(__LP64__) *)
#if defined(HAS_BITSET64)
   BITS = BITSET64 ;
   WRD = LONGCARD ;
#else
   BITS = BITSET32 ;
   WRD = CARDINAL ;
#endif

CONST
   BLOCK_SIZE = TSIZE(WRD) ;
(* defined(__x86_64) || (defined(__alpha__) && defined(__arch64__)) || defined(__LP64__) *)
#if defined(HAS_BITSET64)
   NULLMASK1 = 0101010101010101H ;
   NULLMASK2 = 8080808080808080H ;
#else
   NULLMASK1 = 01010101H ;
   NULLMASK2 = 80808080H ;
#endif

#define DETECTNULL(X) (BITSET(VAL(WRD,X^) - VAL(WRD,NULLMASK1)) * (-VAL(BITSET,X^)) * VAL(BITSET,NULLMASK2))

(* Find length of string *)
PROCEDURE Length (VAR a: ARRAY OF CHAR) : CARDINAL ;
VAR
   Len, High: CARDINAL ;
   PWord: POINTER TO WRD ;
BEGIN
   Len := 0;
   High := HIGH(a) ;
#if !(defined LIBRARY_OPTIMIZE_SIZE)
   (* Check block by block *)
   (* https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord *)
   PWord := ADR(a[Len]);
   LOOP
      IF DETECTNULL(PWord) # 0 THEN
         EXIT;
      END;
      INC(PWord, BLOCK_SIZE);
      INC(Len, BLOCK_SIZE);
      IF (Len > (High - BLOCK_SIZE)) THEN
         EXIT;
      END;
   END;
   (* Find position in last block *)
#endif
   WHILE (Len <= High) AND (a[Len] # nul) DO
      INC(Len);
   END;
   RETURN(Len);
END Length ;

VAR  
   str : ARRAY[0..256] OF CHAR;
   i, len : CARDINAL;

BEGIN
   str := '123';
   len := Length(str);
END String.

This works fine and look readable still.
Except for when I use the flag -fsoft-check-all.
It then failed with a segmentation fault.

For now this is a fun exercise in porting Newlib
functions in order to learn/evaluate the language. 

I think this could work perfectly for bare-metal embedded
development and potential much safer than C/C++.
It is for a reason the IEC 61131-3 PLC structured text
language is based on Modula-2 and not C/C++.

Best regards
Runar Tenfjord 

On Thu, Oct 27, 2022 at 5:19 PM Gaius Mulley <gaiusmod2@gmail.com> wrote:
Runar Tenfjord <runar.tenfjord@gmail.com> writes:

> Excellent,


Hi Runar,

> Currently I am using ArchLinux for testing and development.
> It builds flawlessly as expected.

great news thanks!

> When gm2 is back ported to GCC12, I will submit a build recipe to the MSYS2
> repository and get some help with the outstanding issued.

awesome!

> Some other issues:

> * BITSET64 seems to be missing. Is this temporary or some
>  fundamental reason for the omission?

BITSET was fixed to WORD/INTEGER/CARDINAL.  But you're right as gm2
supports CARDINAL64 (if the architecture supports it) and
INTEGER64/WORD64 - then it looks like an oversight that BITSET64 is
missing!  Thanks I will fix this and test.  I suspect it might need
some runtime support - (if I recall from past experimentation).

> * I find that the WORD type is 32bit on my 64bit installation.

Yes as SIZE(WORD) = SIZE(BITSET) = SIZE(INTEGER) and on a LP64 system
(or amd64) then sizeof(int) = 4.

>  Is this connected to the above issue? Or due to portability?

It is also connected to interfacing to C (SIZE(INTEGER) == SIZE(WORD) ==
sizeof(int)) necessary for the underlying libraries.  Hence we can use
CARDINAL64 or INTEGER64 without breaking anything (but we cannot
guarantee CARDINAL64 will exist).

> * Can platform differences (Linux_x86_64, Windows64, etc) be switched
>  with the preprocessor or must this be handled by outer build system
>  like make?

The preprocessor can be used in user programs (some of the testsuite
does this for example).  The codebase of gm2 doesn't do this though as
the compiler is bootstrapped by converting it to C (or C++).  Is there a
particular problem you are trying to solve re: preprocessor?  I tend to
use the preprocessor in the underlying C code connecting to the system
calls though.  These choices were mainly down to keeping everything as
simple as possible (re: host/build/target differences).

regards,
Gaius

reply via email to

[Prev in Thread] Current Thread [Next in Thread]