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

User projects written in or related to FreeBASIC.
Post Reply
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

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

Post by srvaldez »

SARG wrote: -gen gas64 and also -g are mandatory.
Without -gen gas64 the default compiler backend is selected (on 64bit --> gcc). I could force the gas64 option when using fbc64/32_gas64.exe ????
Without -g it could work with very small codes as the registers are not anymore freed each line.
since FB-Win32 uses GAS when not otherwise directed, it makes sense that fbc64 would do the same.
frisian
Posts: 249
Joined: Oct 08, 2009 17:25

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

Post by frisian »

@SARG

about my FP to integer problem

Code: Select all

dim as integer<32> test = 10,answer
answer = rnd * 10
print answer
My CPU is a AMD Athlon II X4 645 (Propus) based on the K10 core released Sep. 2010, my computer is from 2013.
The following instructions sets are supported: MMX (+), 3DNow! (+), SSE, SSE2, SSE3, SSE4A, x86-64, AMD-V
The a64 file that is produced has the instruction roundsd xmm0,xmm0,4 a unsupported instruction by my CPU, only newer CPU's support it.
The GCC 64bit version does run, had a look into the GCC version. it calls a subroutine that use FPU instructions to do the conversion.

Therefore I shall only report on compiler error's for the moment.

Good news.
Srvaldez nbody.bas benchmark will compile, run and give the correct results.

Bad news.(sorry)
Some of my programs would run and give the expected result(Version 1.06.0 (03-18-2019).
But with the new FBC64_GAS64.exe (Version 1.06.0 (03-21-2019,) they will not even compile, the compiler returns the
following message Error: invalid character ',' in mnemonic. all the lines in the a64 files are the same except the memory location (-160).
rdx, -160[rbp] #Optim 6], the instruction mov is missing.

Keep up the good work.

P.S. what about cvtsd2si instead off rounds ... cvttsd2si ... .
Last edited by frisian on Mar 30, 2019 23:13, edited 1 time in total.
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

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

Post by SARG »

Hi frisian,
frisian wrote:about my FP to integer problem
My CPU is a AMD Athlon II X4 645 (Propus) based on the K10 core released Sep. 2010, my computer is from 2013.
The following instructions sets are supported: MMX (+), 3DNow! (+), SSE, SSE2, SSE3, SSE4A, x86-64, AMD-V
The a64 file that is produced has the instruction roundsd xmm0,xmm0,4 a unsupported instruction by my CPU, only newer CPU's support it.
The GCC 64bit version does run, had a look into the GCC version. it calls a subroutine that use FPU instructions to do the conversion.

Therefore I shall only report on compiler error's for the moment.
I saw the calls (executing just roundsd) when looking at the asm generated by gcc without understanding why it didn't use directly that instruction....
Maybe it's possible to test on what CPU the compiler is running and use roundsd or the routine.
Anyway all reports are welcome :-)
frisian wrote:Bad news.(sorry)
Some of my programs would run and give the expected result(Version 1.06.0 (03-18-2019).
But with the new FBC64_GAS64.exe (Version 1.06.0 (03-21-2019,) they will not even compile, the compiler returns the
following message Error: invalid character ',' in mnemonic. all the lines in the a64 files are the same except the memory location (-160).
rdx, -160[rbp] #Optim 6], the instruction mov is missing.
No problem. However strange, optimization wrongly achieved.
Post the lines between #O6 and #Optim 6 like below.

Code: Select all

#O6mov r10, QWORD PTR 16[rbp]
   # Info --> call fb_StrSwap / mang=fb_StrSwap
   # Info --> vr=<NULL>
   # Info --> level=1
   # Info --> arg vr56 [any ptr]
   # Info --> arg=reg 56 [any ptr] vreg=56
   # Info --> virtual register =56 real register=r10
   # Info --> Release done for register=r10
   # Info --> OPTIMIZATION 6
   # Info --> part1=rcx part2=r10 prevpart1=r10 prevpart2=QWORD PTR 16[rbp]
   # Info --> END OF OPTIMIZATION6
   #O6mov rcx, r10
   mov rcx, QWORD PTR 16[rbp] #Optim 6
frisian wrote:what about cvtsd2si instead off rounds ... cvttsd2si ... .
Not enough skilled to answer. What are you suggesting ? Or What is the best instruction ?
frisian wrote:Keep up the good work.
Thanks, no problem.

In next release Global constructors/destructors will be back. And no more need -gen gas64 / -g.
frisian
Posts: 249
Joined: Oct 08, 2009 17:25

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

Post by frisian »

@SARG

The instructions STMXCSR, LDMXCSR, CVTSD2SI and CVTTSD2SI will work on all the CPU's (old and new)
To work with CVTSD2SI some extra code is needed, and space for 2x 32bit storage in memory.
For testing I created two extra integer variables into the basic file.

convert a double/single value to a integer (FB rounds off to nearest).

################################## old
#roundsd xmm0,xmm0,4
#cvttsd2si rax, xmm0
################################## new
# This method ignores the possible changes in MXCSR since there is no testing after CVTSD2SI is executed.
# The method requires memory for 2 32bit variables to hold the old and new value of MXCRS.
# STMXCSR and LDMXCSR can only store and load from memory.
# store the value of mxcsr into first 32bit memory location.
stmxcsr -128[rbp]
# store the value of mxcsr into the second 32bit memory location.
stmxcsr -132[rbp]
# clear bit 13 and 14. round off to the nearest
and dword ptr -132[rbp], 0xFFFF9FFF
# load the contents from memory in MXCSR.
ldmxcsr -132[rbp]
# convert double into integer using the set method (round to the nearest).
cvtsd2si rax, xmm0
# restore the original contents of MXCSR
ldmxcsr -128[rbp]
# free up memory used for 2 32bit storages if needed
################################## continue with original

cleaned up
################################## old
#roundsd xmm0,xmm0,4
#cvttsd2si rax, xmm0
################################## new
stmxcsr -128[rbp]
stmxcsr -132[rbp]
and dword ptr -132[rbp], 0xFFFF9FFF
ldmxcsr -132[rbp]
cvtsd2si rax, xmm0
ldmxcsr -128[rbp]
################################## continue with original

for INT() (floor the result)

################################## old
#roundsd xmm0,xmm0,4
#cvttsd2si rax, xmm0
################################## new
# This method ignores the possible changes in MXCSR since there is no testing after CVTSD2SI is executed.
# The method requires memory for 2 32bit variables to hold the old and new value of MXCRS.
# STMXCSR and LDMXCSR can only store and load from memory.
# store the value of mxcsr into first 32bit memory location.
stmxcsr -128[rbp]
# store the value of mxcsr into the second 32bit memory location.
stmxcsr -132[rbp]
# clear bit 13 and 14.
and dword ptr -132[rbp], 0xFFFF9FFF
# set bit 13 and 14. floor the result
or dword ptr -132[rbp], 0x2000
# load the contents from memory in MXCSR.
ldmxcsr -132[rbp]
# convert double into integer using the set method (floor).
cvtsd2si rax, xmm0
# restore the original contents of MXCSR
ldmxcsr -128[rbp]
# free up memory used for 2 32bit storages if needed
################################## continue with original

cleaned up
################################## old
#roundsd xmm0,xmm0,4
#cvttsd2si rax, xmm0
################################## new
stmxcsr -128[rbp]
stmxcsr -132[rbp]
and dword ptr -132[rbp], 0xFFFF9FFF
or dword ptr -132[rbp], 0x2000 # 1 extra instruction compared with the previous code
ldmxcsr -132[rbp]
cvtsd2si rax, xmm0
ldmxcsr -128[rbp]
################################## continue with original

for FIX() (round off to zero / truncate )
not else needed
################################## old
#roundsd xmm0,xmm0,4
#cvttsd2si rax, xmm0
################################## new
cvttsd2si rax, xmm0 # cvttsd2si round off to zero
################################## continue with original

I need more info let me know.
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

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

Post by SARG »

@frisian
Thank you for your code.
Roundsd is supported if SSE4_1 flag feature is set.
So with the help of cpuid it should be possible, when compiling, to know if roundsd can be used or your "workaround". I''ll try that.

About fix instruction the 2 asm lines are from gcc. I guess the devs know what they are doing.....

By the way you didn't post the data for optim6 which doesn't work on your side.
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

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

Post by SARG »

Hi all,

New version : http://users.freebasic-portal.de/sarg/fbcgas64.zip

- Temporarily -gen gas64 and -g are forced so no need to add them as parameters. fbc64_gas64 <name.bas> should be enough.
The asm file (a64) is not preserved, to keep it add -R.
The options gas, gcc, if any, are overwritten.

- Global constructors/destructors added. Note : only one level of priority, I need an example with at least two levels.
- Compiling with -exx should work. At least z.exe doesn't crash.
- Several bugs fixed (some cases when using memclear, jumpptr [r11] instead r11, use of mov instead lea..., too strong optim#6...)


Next steps :
- no use of roundsd for "old" x64 processeurs, code from frisian and use of cpuid I hope.
- starting of test suite.
- fixing bugs reported by coders :-)
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

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

Post by SARG »

@frisian
Could you execute this code for testing if roundsd is supported or not.
On your PC it should display "not supported".
Thanks in advance.

Code: Select all

dim as long lecx
asm
    mov  eax,1
    cpuid
    mov [lecx],ecx
end asm

print hex(lecx)
if bit(lecx,19) then
    print "roundsd/ss supported"
else    
    print "roundsd/ss not supported"
end if
sleep
@coderjeff
I started the test suite. Now casting.bas works fine (bug fixed, my optimization failing...) and yes, math-torture0.bas takes very long time even when comments are removed. I'll compare with gas32. However reduced to the 300 first lines (instead more than 2000) it seems to work.
frisian
Posts: 249
Joined: Oct 08, 2009 17:25

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

Post by frisian »

@SARG
SARG wrote:@frisian
Could you execute this code for testing if roundsd is supported or not.
On your PC it should display "not supported".
Thanks in advance.
run your little test and the result is:
802009
roundsd/ss not supported

By the way you didn't post the data for optim6 which doesn't work on your side.
I sorry about that somehow I forgot about it. If you are stil interested in that let me know.

New version of fbc64_gas64.exe compiles a more files than the previous one. A improvement would be if INT() statement would work.

First a few observations I made looking at the a64 files

MOV EAX, 0
In early days XOR EAX, EAX was used because it was faster, and it was also a few bytes shorter. Nowadays both are equal fast but XOR EAX, EAX is still shorter. The only thing you can't do is XOR MEM, MEM (MEM = memory).

ADD EAX, 1 : ADD EAX, -1
Use DEC EAX and INC EAX instead, time is the same but the code is a few bytes shorter. You can even use it on memory locations.

Best argument to use XOR, DEC and INC Freebasic and GCC do it this way.

ROUNDSD XMM0, XMM0, 4
CVTTSD2SI RAX, XMM0

ROUNDSD (SSE4_1) convert a DOUBLE to a INTEGER, CVT(T)SD2SI (SSE2) convert a SINGLE to a INTEGER.
Since the DOUBLE is already a INTEGER, CVT(T)SD2SI will do nothing because it source is already a integer.

ERROR'S
A few bas files will not compile, Aborting due to runtime error 7 (null pointer access) at line 3046 of ir-gas64.bas::_EMITUOP() the a64 file length is 0.

Sometimes the compiler makes a mistake, it wants to load immediate data into XXM registers, it seems to skip a step.
movsd xmm0, 0x4072C00000000000 # Double=300 <== this line produces a GAS compiler error.
movsd xmm1, -144[rbp]
subsd xmm0, xmm1


The compiler normally will produce this sort of lines of code.
mov rax, 0x4072C00000000000 # Double=300
movsd xmm0, rax
movsd xmm1, -144[rbp]
subsd xmm0, xmm1


This would also correct.
mov rax, 0x4072C00000000000 # Double=300
movq xmm0, rax
subsd xmm0, -144[rbp]


The FPU processor can't load immediate data nor it can load from then registers therefore all immediate data has to stored in memory. The XMM registers can be load from other (integer) registers. But add, sub, mul, div can only use XMM registers and/of data stored in memory.

Somewhere in the program.
mov qword ptr [name], 0x4072C00000000000 # Double=300
When needed load value direct in XMM register.
movq xmm0, [name]
subsd xmm0, -144[rbp]



Snippet from a a64 file, the compiler is lost since it alter the value of a variable.

Code: Select all

   # -----------------------------------------
   # basic --> col = 15 - col ' col alternate between 0 (black) and 15 (white)
   # -----------------------------------------
   # Info --> v1=var COL ofs=-136 [uinteger] symbdump=var local accessed declared COL [uinteger]
   # Info --> uop NEG COL+-136 [uinteger]
   # Info --> vr=reg 29 [uinteger]
   # Info --> virtual register =29 real register=r11
   neg QWORD PTR -136[rbp]
   # Info --> bop vr-1 [uinteger] + 15 [uinteger]
   # Info --> v1=reg -1 [uinteger]
   # Info --> v2=imm 15 [uinteger]
   # Info --> vr=reg 30 [uinteger]
   # Info --> Vr<>0 op =>add

   # Info --> ****************************************************************************
   # Info --> * ERROR virtual register=-1 no real register corresponding, using KREG_XXX *
   # Info --> ****************************************************************************
   FOUND AN ERROR : virtual register=-1 no real register corresponding, using KREG_XXX

   add * X_Q, 15
   # Info --> store COL+-136 [uinteger] := vr-1 [uinteger]
   # Info --> v1=var COL ofs=-136 [uinteger] symbdump=var local accessed declared COL [uinteger]
   # Info --> v2=reg -1 [uinteger]

   # Info --> ****************************************************************************
   # Info --> * ERROR virtual register=-1 no real register corresponding, using KREG_XXX *
   # Info --> ****************************************************************************
   FOUND AN ERROR : virtual register=-1 no real register corresponding, using KREG_XXX

   mov -136[rbp], * X_Q
   # Info --> registers released
Lets cleanup a little bit, the statement is executed as col = -col + 15
# -----------------------------------------
# basic --> col = 15 - col ' col alternate between 0 (black) and 15 (white)
# -----------------------------------------
Start is good
neg QWORD PTR -136[rbp]
Then it's lost
add * X_Q, 15
mov -136[rbp], * X_Q

All what's needed is to add 15 so
neg QWORD PTR -136[rbp]
add QWORD PTR -136[rbp], 15
And we are all done.

gmptest.bas

Code: Select all

#include once "gmp.bi"
When trying to compile I get the following three errors
gmptest.a64:107: Error: symbol `__gmp_bits_per_limb' is already defined
gmptest.a64:117: Error: symbol `__gmp_errno' is already defined
gmptest.a64:127: Error: symbol `__gmp_version' is already defined

gmptest.a64 (symbols at the end of the file)

Code: Select all

.intel_syntax noprefix
.file "gmptest.bas"
.section .text

# Info --> registers released
# Info --> =============================================================================
# Info --> ===== Proc begin : main / main =====
# Info --> =============================================================================
   # Info --> stk4=112 reserved space for saving registers when proc calls
   # Info --> registers released
   # Info --> proc shared public declared parsed hasalias mainproc procemitted  cdecl [long]
   .text
   # Info --> Not accessed --> not used ??
   .globl main
main:
   # Info --> usefull ? [long] main( [long] __FB_ARGC__, [zstring ptr ptr] __FB_ARGV__ )
   push rbp
   mov  rbp,rsp
   sub rsp, 160
   call __main
   # Info --> paramvar=__FB_ARGC__ real typ=[long] symbgetlen=4
   # Info --> var local parambyval declared __FB_ARGC__ [long]
   # Info --> lgt=4 real=4
   mov DWORD PTR 16[rbp], ecx
   # Info --> paramvar=__FB_ARGV__ real typ=[zstring ptr ptr] symbgetlen=8
   # Info --> var local parambyval declared argv __FB_ARGV__ [zstring ptr ptr]
   # Info --> lgt=8 real=8
   mov QWORD PTR 24[rbp], rdx
   # Info --> localvar fb$result
   # Info --> fb$result fb$result
   # Info --> symbdump=var local funcresult declared implicit fb$result [long]
   # Info --> lgt=4 real=4
   # Info --> var total size=4
   # Info --> stk=112
   # Info --> stk1=116
   # Info --> addrof fb$result+-116 [long]
   # Info --> v1=var fb$result ofs=-116 [long] symbdump=var local funcresult accessed declared implicit fb$result [long]
   # Info --> vr=reg 0 [long ptr]
   # Info --> virtual register =0 real register=r11
   # Info --> marked as used register=r11
#O4lea r11, -116[rbp]
   # Info --> memclear vr0 [long ptr]
   # Info --> v1=reg 0 [long ptr]
   # Info --> v2=imm 4 [integer]
   # Info --> virtual register =0 real register=r11
   # Info --> Release done for register=r11
   # Info --> OPTIMIZATION 4 (lea)
   # Info --> END OF OPTIMIZATION4
   #O4mov DWORD PTR [r11], 0
   mov DWORD PTR -116[rbp], 0 #Optim 4
   # Info --> call fb_Init / mang=fb_Init
   # Info --> vr=<NULL>
   # Info --> level=1
   # Info --> arg __FB_ARGC__+16 [long]
   # Info --> arg=var __FB_ARGC__ ofs=16 [long] symbdump=var local parambyval accessed declared __FB_ARGC__ [long] vreg=-1
   mov ecx, 16[rbp]
   # Info --> arg __FB_ARGV__+24 [zstring ptr ptr]
   # Info --> arg=var __FB_ARGV__ ofs=24 [zstring ptr ptr] symbdump=var local parambyval accessed declared argv __FB_ARGV__ [zstring ptr ptr] vreg=-1
   mov rdx, 24[rbp]
   # Info --> arg 0 [long]
   # Info --> arg=imm 0 [long] vreg=-1
   mov r8d, 0
   call fb_Init
   .Lt_0002: #label not mangled=.Lt_0002
   # Info --> registers released
   # -----------------------------------------
   # basic --> #include once "gmp.bi"
   # -----------------------------------------
   .Lt_0003: #label not mangled=.Lt_0003
   # Info --> call fb_End / mang=fb_End
   # Info --> vr=<NULL>
   # Info --> level=1
   # Info --> arg 0 [long]
   # Info --> arg=imm 0 [long] vreg=-1
   mov ecx, 0
   call fb_End
   # Info --> loadres fb$result+-116 [long]
   # Info --> v1=var fb$result ofs=-116 [long] symbdump=var local funcresult accessed declared implicit fb$result [long]
   # Info --> vr=reg 1 [long]
   mov eax, -116[rbp]
   # Info --> stk=116
   # Info --> stk5=160

   mov rsp,rbp
   pop rbp
   ret
# Info --> ===== End of proc =====

   # Info -->  __fb_ZTS6Object
   # Info --> symbdump=var shared extern hasalias <unnamed> alias "__fb_ZTS6Object" [struct FB_RTTI$]
   .section .bss
   # Info --> __fb_ZTS6Object
   # Info --> var total size=24
   .lcomm __fb_ZTS6Object,24,8
   # Info --> >>[struct FB_RTTI$]
   # Info --> {fbsc} Lt_0000
   # Info --> symbdump=var shared literal const hasalias {fbsc} alias "Lt_0000" [zstring]
   # Info --> Not accessed
   # Info --> __GMP_BITS_PER_LIMB __gmp_bits_per_limb
   # Info --> symbdump=var shared static extern __GMP_BITS_PER_LIMB alias "__gmp_bits_per_limb" [const long]
   # Info --> var total size=4
   .lcomm __gmp_bits_per_limb,4,4
   # Info --> >>[long]
   # Info --> MP_BITS_PER_LIMB __gmp_bits_per_limb
   # Info --> symbdump=var shared static extern hasalias MP_BITS_PER_LIMB alias "__gmp_bits_per_limb" [const long]
   # Info --> var total size=4
   .lcomm __gmp_bits_per_limb,4,4
   # Info --> >>[long]
   # Info --> __GMP_ERRNO __gmp_errno
   # Info --> symbdump=var shared static extern __GMP_ERRNO alias "__gmp_errno" [long]
   # Info --> var total size=4
   .lcomm __gmp_errno,4,4
   # Info --> >>[long]
   # Info --> GMP_ERRNO __gmp_errno
   # Info --> symbdump=var shared static extern hasalias GMP_ERRNO alias "__gmp_errno" [long]
   # Info --> var total size=4
   .lcomm __gmp_errno,4,4
   # Info --> >>[long]
   # Info --> __GMP_VERSION __gmp_version
   # Info --> symbdump=var shared static extern __GMP_VERSION alias "__gmp_version" [const zstring const ptr]
   # Info --> var total size=8
   .lcomm __gmp_version,8,8
   # Info --> >>[zstring ptr]
   # Info --> GMP_VERSION __gmp_version
   # Info --> symbdump=var shared static extern hasalias GMP_VERSION alias "__gmp_version" [const zstring const ptr]
   # Info --> var total size=8
   .lcomm __gmp_version,8,8
   # Info --> >>[zstring ptr]
   .section .text
If you need more info let me know.
regards
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

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

Post by SARG »

Hi all,

Like every week a new version : http://users.freebasic-portal.de/sarg/fbcgas64.zip

@frisian
Big thanks for your help :-)

0/Conv, int and fix for float --> integer when SSE4_1 feature is not avaliable
done with your code for all integer variables except uinteger. I tested simulating the SEE41 lack but check on your side.
for uinteger I'm not sure how it could be done. Could you propose a solution. Maybe VCVTS(D/S)2USI instructions are usable.

1/ use of xor
done.(hdocall and emitstore)

2/use of inc/dec
done. if operand is 1/-1 with add and sub (bop procedure)

At the start of the project I was using dec/inc then I read somewhere that was not efficient. I don't remember why.

3/error in uop with aborting compiler
fixed.
by the way as ir_gas64 is compiled with -exx when an error arises the compiler stops and the a64 file stays empty.

4/puting an immediat in xmmo
fixed. I was doing the right way only with xmm1 (second operand) .....

About

Code: Select all

 mov rax, IMM            versus   mov rax, IMM
      movq xmm0, rax              movsd xmm0, rax
      subsd xmm0, <memory>        mov xmm1, <memory>
                                  subsd xmm0, xmm1
It's not directly possible as instructions are sent step by step so ir-gas64 doesn't know what it will receive after each instruction.
However some optimizations are done by keeping information from previous lines. See check_optim. In this case I guess it's possible but to be studied for future improvements.

5/col = 15 - col
fixed. neg instruction, also fixed for sgn and not

about short code same remark than above.

6/gmptest
fixed. No need to define variables which are only declared extern (with no dim).

@coderjeff
Maybe long compilation times with some codes could be reduced by sizing greater the strings used to receive the asm codes.


@for those that interests :
Global constructors and destructors for shared variables/objects are executed before and after the main procedure.
to do that the calls to them are stored in 2 (or more) special sections named .ctors<priority>/.dtors<priority> and these codes are executed before/after the main code contained in .text section.
The priority allows executing in a certain order....
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

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

Post by jj2007 »

SARG wrote:At the start of the project I was using dec/inc then I read somewhere that was not efficient. I don't remember why
Once upon a time there were CPUs which were slightly slower when using inc instead of add reg32, 1. Modern CPUs don't show any performance difference, but inc is a one-byter while add costs three bytes - and the instruction cache is limited ;-)
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

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

Post by SARG »

new version : http://users.freebasic-portal.de/sarg/fbcgas64.zip

- speed issue when compiling big procedures fixed with a workaround.
that's an old problem reported 7 years ago by fxm and maybe will be solved quickly by coderjeff ;-)
- several bugs fixed
- some internal optimizations
- more asm instructions added for used/free register handling.

Next release :
- implementation of register spilling.
- linux version but I have not yet decided between physical/virtual machine or other ways, for testings. Any idea ?
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

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

Post by badidea »

SARG wrote:- linux version but I have not yet decided between physical/virtual machine or other ways, for testings. Any idea ?
I would do both. If you currently don't have a linux install, go with a virtual setup first. Easy to switch between windows and linux that way. But for performance testing you might want a 'real' install as well. I would also choose different (stable) mainstream distro's for the two.
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

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

Post by SARG »

new version : http://users.freebasic-portal.de/sarg/fbcgas64.zip

Now this version should be linux compliant. It means that the ABI is respected (used registers for calling, etc).
But as I have not yet a linux box or virtual machine even if the a64 file seems correct executables could run wrongly.

However using a such command line "fbc -s console -arch 64 -RR -R -v -target linux-x86_64 -Wc -mabi=sysv,-msse4.1 bug.bas"
allows, although under windows, to get an asm linux version for easy comparing with a64 files.

I also don't provide a linux version of fbc.exe so compile your own with the modified source codes.
Please do tests and report any issue.

@badidea thank you. I'll bring out my old linux box and install a fresh distro.
Under windows it's possible to install a linux sub-system I will try this but any advice/remark is welcome.

Next steps :
- finishing the register spilling
- beginning seriously the tests with test suite.
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

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

Post by srvaldez »

hello SARG :-)
I am glad that you are making progress, but there are still some problems.
when compiling with fbc64_gas64 inline asm fails when used in naked functions
and a rather long program compiled OK but failed viewtopic.php?f=7&t=18057&p=159343&hili ... le#p159343
the program stops working at the point

Code: Select all

? "convert the string 2.7182818 ... to extended precision and back to string"
asctoeg(s, @ip(0), NBITS)
? etoasc(@ip(0), 45)
convert the string 2.7182818 ... to extended precision and back to string


------------------
(program exited with code: -1073741819)
the same program works OK when compiled using fbc32_gas64
Last edited by srvaldez on May 02, 2019 0:32, edited 2 times in total.
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

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

Post by srvaldez »

using fbc64_gas64
the following function works OK

Code: Select all

function sqrt cdecl(byval x as double) as double
   Asm
      sqrtsd xmm0, xmm0
      movsd [function],xmm0
   End Asm
end function
?sqrt(2)
but the following does not work

Code: Select all

function sqrt naked cdecl(byval x as double) as double
   Asm
      sqrtsd xmm0, xmm0
      ret
   End Asm
end function
?sqrt(2)
it compiles OK with fbc32_gas64 but the result is "-1.#IND", which is to be expected, however the following works with fbc32_gas64

Code: Select all

function sqrt naked cdecl(byval x as double) as double
	Asm
		movsd xmm0,[esp+4]
		sqrtsd xmm0, xmm0
		movsd [esp-32],xmm0
		fld qword ptr [esp-32]
		ret
	End Asm
end function
?sqrt(2)
[edit] the name fbc32_gas64 is confusing to me, I expected that it would produce a 64-bit executable
Post Reply