Update 2020-11-20
The file contains the exes for WDS 1.07 / 1.08 and only the modifications for 1.07 not yet in github.
http://users.freebasic-portal.de/sarg/fbc64_gas64_W.zip
For 1.08 the sources (github fbc master + lastest modifications not yet included) can be found here --> https://github.com/SARG-FB/fbc/tree/gas64_rev
----------------------------------------------------------------------------------------------------------------------------------
VERSION 2020-08-05 http://users.freebasic-portal.de/sarg/fbc64_gas64.zip
Since about 5 months I'm coding a 64bit gas version, no more use of gcc only gas.exe.
It's well advanced however still a bit of work, mostly tests.
For now it's only for Windows but our Linux's friends are not forgotten and I hope be able to extend this option for them.
The changes are handled in few procs so a relatively easy adaptation.
The current version can compile all the FBC modules without error. However just compiled, it doesn't mean that the execution will not be wrong....
And my test programs run fine.
http://users.freebasic-portal.de/sarg/fbcgas64.zip
Next steps :
- cleaning the code and adding more optimizations I thought about. For example the order of used registers.
- FBC self compilation and tests
- compiling every code of test suite to find missing cases. If someone is enough kind to do that and give me the report
- executing the obtained executables
I need some help in testing so try it and report every issue you meet by posting or sending the faulty code.
A second way could be to look at the generated code and suggest modifications.
However the generated asm is function of the flow of op codes so it's not possible to change everything as we want.
''--------------
Some precisions
''--------------
- The exe speed should be at least as good if not better that the gcc version (without the Ox options) could provide.
- To start the project I used the ir-llvm module (llvm is very close to assembly) and when necessary I look at the asm generated with gcc.
- One of trick is to reset the used registers for each basic line. So very big/complex lines could generate errors.
That also forces to use the -g option (for the moment).
- The asm file extension is .a64 (output from fbc and sent to the assembler) to distinguish from the current asm files.
- An a64 file contains a lot of information to easily debug the generated code (see example below). So these files can be very huge. Obviously that
will be removed in the future.
- There are few changes in the fbc modules mostly the add of a new module ir-gas64.bas.
* ast-node-proc : loadres for GAS64 (seems also missing for llvm)
* fb.bi : added FB_BACKEND_GAS64
* fbc : allowing GAS64 / only one stage / file name .a64
* ir.bi : extern vtbl
* ir : irgas64_vtbl
* parser-toplevel : commented lines to get the text code for all modules (include files)
* symb-mangling : added GAS64
''------------
''How use it
''------------
As usual with the new option -gen gas64 and adding -g is mandatory
*** compilation via 32 *** KEEP -g
fbc32_gas64 -arch 64 -RR -R -gen gas64 -v -g test_asm64.bas
*** compilation via 64 *** KEEP -g
fbc64_gas64 -RR -R -gen gas64 -v -g test_asm64.bas
''-----------------------------------------
'' Benchmark using example posted by Marpon
''-----------------------------------------
- gcc = 48.31
- gccO2/O3 = 43.86
- gas64 = 10.56 (64bit integer) <---- not so bad
- gas32 = 8.78 (32bit integer)
- gccft = 3.73
''----------------------------
''Example (partial) of a64 file
''----------------------------
Code: Select all
# Info --> registers released
# -----------------------------------------
# basic --> If pold=pslh Then pold=999999
# -----------------------------------------
# Info --> CONVERTING vr188 [integer] := POLD+-152 [long]
# Info --> vregdump v1=reg 188 [integer] xx 188
# Info --> vregdump v2=var POLD ofs=-152 [long] symbdump=var local accessed declared POLD [long] xx -1
# Info --> virtual register =188 real register=r11
# Info --> size dst > size src changing src dtype by dst dtype
# Info --> marked as used register=r11
movsxd r11, DWORD PTR -152[rbp]
# Info --> CONVERTING vr189 [integer] := PSLH+-148 [long]
# Info --> vregdump v1=reg 189 [integer] xx 189
# Info --> vregdump v2=var PSLH ofs=-148 [long] symbdump=var local accessed declared PSLH [long] xx -1
# Info --> virtual register =189 real register=r10
# Info --> size dst > size src changing src dtype by dst dtype
# Info --> marked as used register=r10
movsxd r10, DWORD PTR -148[rbp]
# Info --> branchbop vr188 [integer] <> vr189 [integer] .Lt_0032
# Info --> v1=reg 188 [integer]
# Info --> v2=reg 189 [integer]
# Info --> Vr=0 op =>icmp ne
# Info --> virtual register =188 real register=r11
# Info --> virtual register =189 real register=r10
# Info --> Release done for register=r10
# Info --> Release done for register=r11
cmp r11, r10
jne .Lt_0032
# Info --> store POLD+-152 [long] := 999999 [long]
# Info --> v1=var POLD ofs=-152 [long] symbdump=var local accessed declared POLD [long]
# Info --> v2=imm 999999 [long]
mov DWORD PTR -152[rbp], 999999
.Lt_0032: #label not mangled=.Lt_0032
''2 Examples of optimization
''----------------------------------
1/ #O5lea r11, -136[rbp]
#O5mov r10, r11
lea r10, -136[rbp] #Optim 5
2/ mov r11, rax
#O1 mov rax, r11