Gas64 (no more use of gcc, only gas) WDS / LNX

User projects written in or related to FreeBASIC.
Post Reply
SARG
Posts: 1767
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Gas64 (no more use of gcc, only gas) :-)

Post by SARG »

Hi coderJeff,

What gas64 version (date from post in the forum) do you use ?
Because I did some changes e.g. Using '#idef FB_LINUX' instead 'if ctx.target=FB_COMPTARGET_LINUX then' is not the same. A big mistake, I saw that when generating code for linux....

Anyway thanks for taking the time to test and review the code.

I'll made a more complete anwswer later but some points.

-About SSE4.1 I forgot to add the case single/double converted to uinteger. Dont' know why. I guess the numerous errors in test suite come from there because no_roundsd returns a value in rax but for uinteger data it is needed in xmm0 for the rest of the process so all the results are false.
For now I'm trying to find a clever way. Maybe I'll simply use the existing 'nearby' functions.
Obviously no problem to move the detection in a suitable place.

- typeDumpToStr() is used to display interesting/important information in the 'dev' version of gas64. I just compile symb.bas (only this module) with -g. The function could be copied temporary in ir-gas64. Maybe, no checked, there are dependancies so not enough.
SARG
Posts: 1767
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Gas64 (no more use of gcc, only gas) :-)

Post by SARG »

Hi coderJeff,

My long (for me) answer.
coderJeff wrote:My local commit history on your gas64 branch is a little messy, so I can't tell in all cases if it was your bug, or my bad rebase. I'll review the changes I made again and post.
I'll run the last test suite (1.0.8) with my version to remove all the failures.
You can also test on your side with the new provided files (based on 1.0.8). http://users.freebasic-portal.de/sarg/fbc64_gas64.zip
There is also the usual exe. I hope not too much issues as I did a lot of changes.

As I have not yet install github and try to remember how to use it, I provide the 3 changed files, sorry. And thank you for creating the branch.
- ir-gas64.bas
- fbc.bas (one error added, when gas64 only -asm intel is allowed like for gas32)
- ast-node-misc.bas (see below 'debugging flag' removed)
And parser-toplevel.bas can returned at its original version

coderJeff wrote:1) fbc is cross compiler, so __FB_LINUX__ or __FB_WIN32__ or SSE 4.1 detection within fbc compiler itself can only be used to detect suitable defaults. Otherwise the backend emitter should use the env.clopt.target (and other options), to determine code generation.
As written in my previous post it was changed (end of december) using target (linux/windows).
Thanks to cross-compiling I got a64 code for Linux. Now an old laptop under linux is ready for testing exes.
I didn't find where put the SSE41 detection.
coderJeff wrote:2) the emitter doesn't come alive until _emitBegin() is called, and must completely die in _emitEnd(). Should not expect to carry emitter information forward from one module compile to next module compile. For example, in the version I had, the 'ctx.head_txt' was not cleared so caused assembly error in second module to compile.
OK. I did that to keep information given when _supportsop was executed, useless now.
coderJeff wrote:3) my CPU doesn't support sse 4.1 and there were some unguarded 'roundss' and 'roundsd' instructions. (I called no_roundsd instead).
Now fixed using nearbyint(f) functions for double/single --> uinteger. However I have found a very fast way maybe a change to come...
coderJeff wrote:4) manipulating the mxcsr register in a global variable seems like would not be thread safe.
I changed the no_roundsd sub. Give me your advice. If still not safe nearbyint will do the job.
coderJeff wrote:5) Symbols cannot be emitted based on their ALIAS only. For example local scope statics do not have a mangled public name and must get a unique identifier otherwise will get duplicate definitions in the .a64 file. I removed all of your custom symbol mangling and call only 'symbGetMangledName()'. The llvm mangling almost works as-is, except for GAS64 need to mangle statics to a unique id.
I should say that I don't understand completly what it's done in the part dedicated to gas64. Some explanations are welcome.

However there is an issue : using register names as variable names is not possible.
So is it possible (as I did before) to add an underscore only for variables in symbmangling ?
Calling a procedure named with a register is allowed (eg. sub rdx() --> call rdx) but when called causes a crash.

As hsymname and hgetudtname don't do more than calling *symbGetMangledName( sym ) they can be simply removed. Yes ?
coderJeff wrote:Of personal preference:
- I changed the default to -gen gas64 for windows rather than forcing the options. That way I can still control code gen from the command line for other targets using same built fbc exe.
Ok. It's another way to simplificate compilations for users.
As you removed also the forced debugging (-g) I did a small change in ast-node-misc.bas/ proc astnewdbg to keep an indicator (AST_OP_DBG_LINEEND) when a 'basic' line is treated. This information is used to release the registers. And parser-toplevel no more modified for gas64.
coderJeff wrote:For CVA_* on Linux x86-64, see https://www.uclibc.org/docs/psABI-x86_64.pdf starting around pg 50. The needed structure is already built in in to the compiler (see 'FB_CVA_LIST_BUILTIN_C_STD' and 'symbKeywordTypeInit()'). Rather than one saved pointer to fetch the next arg (like on windows and linux x86), the structure has indexes in to the register save area and stack areas to track next argument.
I'll read the doc but I'm going to firstly follow my way. It seems "easier".
coderJeff wrote:I posted your code on top of current fbc/master (1.08.0) plus my changes at SARG-gas64. There are some compiler warnings (if using -w pedantic), and at least one error when building a release version of fbc because internal typeDumpToStr() is only available when building the debug version of fbc.
All warnings fixed
symbdumptostr, typedumptostr and 2 other procedures are copied in ir-gas. They are used (also compiled) only if infodata is defined. Infodata is used to display information for debugging so mostly by me....

No more need to compile symb.bas with -g or -edebug.

Enough for today :-)
SARG
Posts: 1767
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Gas64 (no more use of gcc, only gas) :-)

Post by SARG »

Hi coderJeff

Every failure has been fixed. Mostly they were already fixed however there were some due to an unusefull aligment for strings. Another big one was the use of a local static for a string not reset between each call.
And, as I guessed, incorrect converting of float to uinteger when the proc doesn't support SSE41.

I fell in a trap due to the new field added in array descriptor. After 3 hours of search I finally understood why some programs were crashing.
Thanks to st_W I downloaded the new rtlibs and all goes fine, removing also others problems.

@users
Do not use the previous version of fbc64_gas64.exe it's buggy in some cases for strings.

New version ir-gas and fb64_gas64 : http://users.freebasic-portal.de/sarg/fbc64_gas64.zip
integer
Posts: 408
Joined: Feb 01, 2007 16:54
Location: usa

Re: Gas64 (no more use of gcc, only gas) :-)

Post by integer »

SARG wrote: ...
New version ir-gas and fb64_gas64 : http://users.freebasic-portal.de/sarg/fbc64_gas64.zip
@sarg: Thank you.
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: Gas64 (no more use of gcc, only gas) :-)

Post by srvaldez »

thank you SARG :-)
SARG
Posts: 1767
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Gas64 (no more use of gcc, only gas) :-)

Post by SARG »

srvaldez wrote:thank you SARG :-)
integer wrote:
SARG wrote: ...
New version ir-gas and fb64_gas64 : http://users.freebasic-portal.de/sarg/fbc64_gas64.zip
@sarg: Thank you.
You are welcome. Do not hesitate to test and report any issue.

The exe in my previous post MUST be used in a 1.08 environment.
So if you are still under the 1.07(1) version of Fbc, compile with this version : http://users.freebasic-portal.de/sarg/f ... 64_107.zip

Otherwise something like below should crash. The 1.08 compiler uses a different descriptor for arrays (one field added) but not the 1.07 rtlibs.....

Code: Select all

scope
dim as string array(5)
end scope 
@coderJeff
Is the release date for 1.08 already planned ?
Xusinboy Bekchanov
Posts: 791
Joined: Jul 26, 2018 18:28

Re: Gas64 (no more use of gcc, only gas) :-)

Post by Xusinboy Bekchanov »

SARG wrote: The exe in my previous post MUST be used in a 1.08 environment.
Where can I get 1.08 environment?
SARG
Posts: 1767
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Gas64 (no more use of gcc, only gas) :-)

Post by SARG »

Hi Xusinboy Bekchanov,
Xusinboy Bekchanov wrote:Where can I get 1.08 environment?
St_W provides a 'daily builds' : http://users.freebasic-portal.de/stw/builds/ thank you :-)

More precisely for Windows/64bit : http://users.freebasic-portal.de/stw/builds/win64/
The zip file contains bin/inc/lib folders and a recent version of fbc.exe.

Extract all the files then put fbc64_gas64 executable from http://users.freebasic-portal.de/sarg/fbc64_gas64.zip in the same folder than fbc. The default backend is gas64 but in this version the gcc backend can also be selected (changes by coderJeff).

That's all. If trouble ask me.
SARG
Posts: 1767
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Gas64 (no more use of gcc, only gas) :-)

Post by SARG »

Hi all,

When looking for conversion double --> uinteger, I found a very fast algo for values [0 to 4503599627370495]. It's not used in gas64 because of the limited ranges. However to well understand it I wrote a small code. Then I tested with gcc64 and gas64. Results in second with my box. I know that's a particular case but it gives a good idea of possible benefit of gas64.

gcc64
fast algo : 4.7
classic way : 64.7 oh my dear !

gas64
fast algo : 4.7
classic way : 5.2 Not so bad !

Code: Select all

dim as double dbl,tim
dim as ulongint ulgt

tim=timer
for i as integer=1 to 1000000000
    dbl=i
    asm
        movq xmm0,[dbl]
        mov rax,4841369599423283200 # 2^52 in float
        movq xmm1, rax
        addsd xmm0, xmm1
        movq [ulgt], xmm0
        xor [ulgt],  rax
    end asm
next
print timer-tim,ulgt

tim=timer
for i as integer=1 to 1000000000
    dbl=i
    ulgt=dbl
next
print timer-tim,ulgt

sleep
Xusinboy Bekchanov
Posts: 791
Joined: Jul 26, 2018 18:28

Re: Gas64 (no more use of gcc, only gas) :-)

Post by Xusinboy Bekchanov »

SARG wrote:Hi Xusinboy Bekchanov,
Xusinboy Bekchanov wrote:Where can I get 1.08 environment?
St_W provides a 'daily builds' : http://users.freebasic-portal.de/stw/builds/ thank you :-)

More precisely for Windows/64bit : http://users.freebasic-portal.de/stw/builds/win64/
The zip file contains bin/inc/lib folders and a recent version of fbc.exe.

Extract all the files then put fbc64_gas64 executable from http://users.freebasic-portal.de/sarg/fbc64_gas64.zip in the same folder than fbc. The default backend is gas64 but in this version the gcc backend can also be selected (changes by coderJeff).

That's all. If trouble ask me.
1.08.0 version read empty lines from unicode file via Line Input

Code: Select all

If Open("1.bas" For Input Encoding "utf-8" As #3) = 0 Then
   Dim As WString Ptr buff
   buff = Cast(WString Ptr, Reallocate(buff, (LOF(3) + 1) * SizeOf(WString)))
   Do Until EOF(3)
      Line Input #3, *buff
      ?*buff
   Loop
End If
SARG
Posts: 1767
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Gas64 (no more use of gcc, only gas) :-)

Post by SARG »

Xusinboy Bekchanov wrote:1.08.0 version read empty lines from unicode file via Line Input
It seems you can't do that with a wstring ptr regardless of the backend. I tested with gcc it also doesn't work.

You should use a wstring * nnn as the example below.
In the asm code generated with gas 64, we see that there is a parameter defining the max lenght for line input : 32 for wstg and 0 for *buff.

Code: Select all

lea r11, -192[rbp]
   mov ecx, 3
   mov rdx, r11
   mov r8d, 32     <-------------------------- max lenght 32,  value put in wstg
   call fb_FileLineInputWstr
   mov ecx, 3
   mov rdx, -200[rbp]
   xor r8d, r8d    <-------------------------- max lenght 0, value put in *buff
   call fb_FileLineInputWstr

Code: Select all

'1.08.0 version read empty lines from unicode file via Line Input
dim as wstring *32 wstg
If Open("lineinput-utf8.txt" For Input Encoding "utf-8" As #3) = 0 Then
   Dim As WString Ptr buff
   buff = Cast(WString Ptr, callocate(1, (LOF(3) + 1) * SizeOf(WString)))
print buff
   Do Until EOF(3)
      Line Input #3, wstg
      Line Input #3, *buff
      print "wstg=";wstg
      print "buff=";*buff
   Loop
End if

sleep
Xusinboy Bekchanov
Posts: 791
Joined: Jul 26, 2018 18:28

Re: Gas64 (no more use of gcc, only gas) :-)

Post by Xusinboy Bekchanov »

SARG wrote:It seems you can't do that with a wstring ptr regardless of the backend. I tested with gcc it also doesn't work.

You should use a wstring * nnn as the example below.
In the asm code generated with gas 64, we see that there is a parameter defining the max lenght for line input : 32 for wstg and 0 for *buff.
In version 1.06.0 worked
SARG
Posts: 1767
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Gas64 (no more use of gcc, only gas) :-)

Post by SARG »

Could you check again ?
Not working with 1.07 64 or 32bit

Maybe I'm wrong but in the C code (see below) used to generate the function lineinput utfxx, if max_chars is null the wstring should stay empty.

Code: Select all

fb_WstrConcatAssign( dst, max_chars, c );
CoderJeff/dkl could confirm that.

Code: Select all

/* UTF-encoded file device LINE INPUT for wstrings */

#include "fb.h"

int fb_DevFileReadLineEncodWstr( FB_FILE *handle, FB_WCHAR *dst, ssize_t max_chars )
{
	int res;

	FB_LOCK();

	FILE* fp = (FILE *)handle->opaque;
	if( fp == stdout || fp == stderr )
		fp = stdin;

	if( fp == NULL ) {
		FB_UNLOCK();
		return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );
	}

	/* Clear string first, we're only using += concat assign below... */
	dst[0] = _LC('\0');

	/* Read one byte at a time until CR and/or LF is found.
	   The fb_FileGetDataEx() will handle the decoding. The length to read
	   is specified in wchars, not bytes, because we're passing TRUE for
	   is_unicode. */
	while( TRUE ) {
		FB_WCHAR c[2];
		size_t len;

		res = fb_FileGetDataEx( handle, 0, c, 1, &len, FALSE, TRUE );
		if( (res != FB_RTERROR_OK) || (len == 0) )
			break;

		/* CR? Check for following LF too, and skip it if it's there */
		if( c[0] == _LC('\r') ) {
			res = fb_FileGetDataEx( handle, 0, c, 1, &len, FALSE, TRUE );
			if( (res != FB_RTERROR_OK) || (len == 0) )
				break;

			/* No LF? Ok then, don't skip it yet */
			if( c[0] != _LC('\n') )
				fb_FilePutBackEx( handle, c, 1 );

			break;
		}

		/* LF? */
		if( c[0] == _LC('\n') ) {
			break;
		}

		/* Any other char? Append to string, and continue... */
		c[1] = _LC('\0');
		fb_WstrConcatAssign( dst, max_chars, c );
	}

	FB_UNLOCK();

	return res;
}
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Gas64 (no more use of gcc, only gas) :-)

Post by coderJeff »

SARG, correct. fbc and run time do not support var-len wstrings (yet). Already answered with a work-around at viewtopic.php?f=17&t=27814&p=266589#p266127
Xusinboy Bekchanov
Posts: 791
Joined: Jul 26, 2018 18:28

Re: Gas64 (no more use of gcc, only gas) :-)

Post by Xusinboy Bekchanov »

coderJeff wrote:SARG, correct. fbc and run time do not support var-len wstrings (yet). Already answered with a work-around at viewtopic.php?f=17&t=27814&p=266589#p266127
Only today I found out that you answered my last question on this topic.
Post Reply