Lazarus

Free Pascal => General => Topic started by: PeterX on July 18, 2016, 10:08:21 pm

Title: Assembler - logN and many more ..
Post by: PeterX on July 18, 2016, 10:08:21 pm
Hi all,

there's no sub forum for Assembler questions here ..
.. which means, only a very few people
are working on assembler code in FPC / LCL  ?


I need some mathematical functions such as logN:
( Log.N(X) := Log.2(X) / Log.2(N) )


From which sources can I learn how to write
working FPC / LCL assembler code to make my functions work ?

Thanks,
Peter


The following code works in Delphi 5, but not in Lazarus (1.6).

-----------------------------------------------------
function LogN( Base, X: Extended): Extended;
{$ifdef FPC} begin {$ASMMODE intel} {$endif}
asm
        FLD1
        FLD     X
        FYL2X
        FLD1
        FLD     Base
        FYL2X
        FDIV           // Lazarus Warning: fdivrp without operand translated into fdivrpP
        FWAIT
end;
{$ifdef FPC} end; {$endif}


Title: Re: Assembler - logN and many more ..
Post by: Jonas Maebe on July 19, 2016, 08:02:22 pm
Are you compiling that code in a unit that uses {$mode delphi}? When using Delphi code, always compile using {$mode delphi}.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 10:27:03 pm
Oh, yes, I compile with {$mode objfpc}{$H+}

Does this have an influence on how the assembler code is compiled ?
Title: Re: Assembler - logN and many more ..
Post by: Jonas Maebe on July 19, 2016, 10:30:16 pm
It influences whether or need you need to use the "assembler" modifier for a pure assembly routine. It does not change how the inline assembly gets parsed.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 10:35:00 pm
Okay, because I switched back to DELPHI mode and the error messages are the same :

FDIV:
- Warning: fdivrp without operand translated into fdivrpP
- Warning: "fdivrp" without operand translated into "fdivrp %st,%st(1)"
Title: Re: Assembler - logN and many more ..
Post by: Jonas Maebe on July 19, 2016, 10:38:21 pm
Those are not errors. They are warnings. If the resulting code has different behaviour in Delphi and FPC, please file a bug report at http://bugs.freepascal.org
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 10:39:44 pm
Are You sure ?
This is an old Dephi 5 project ..
Title: Re: Assembler - logN and many more ..
Post by: Jonas Maebe on July 19, 2016, 10:40:23 pm
Am I sure about what?
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 10:42:55 pm
Well, did Borland / Inprise / Embarcadero probably change the synthax of assembler over the years ?
I have no possibilities to verify this assembler code in an actual Delphi compiler ..
Title: Re: Assembler - logN and many more ..
Post by: Jonas Maebe on July 19, 2016, 10:44:17 pm
I did not say they changed the behaviour. I said to file a bug report with FPC if the behaviour is different in Delphi compared to FPC.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 10:46:33 pm
Okay, no problem.

I'll file a bug report.

But often I get the answer - "it is as it is".


Is out there any table that translates DELPHI assembler  to AT&T or intel assembler ?
Title: Re: Assembler - logN and many more ..
Post by: Jonas Maebe on July 19, 2016, 10:48:01 pm
Delphi only supports Intel-style assembly. I.e., Intel-style assembly in FPC should behave the same as the assembly in Delphi.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 10:49:35 pm
Delphi only supports Intel-style assembly. I.e., Intel-style assembly in FPC should behave the same as the assembly in Delphi.
Okay, I take Your word .. ;-)
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 10:51:58 pm
Bug report:

Under "Category " there is no option "Assembler"  .. :-(
Title: Re: Assembler - logN and many more ..
Post by: Jonas Maebe on July 19, 2016, 10:52:30 pm
It's part of the compiler.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 10:55:11 pm
Thanks Jonas, I'll file it soon.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 10:58:28 pm
Submitted as 0030389: assembler code compiles different under Delphi 5 and Lazarus 1.6
Title: Re: Assembler - logN and many more ..
Post by: Jonas Maebe on July 19, 2016, 11:09:26 pm
I just noticed you added begin/end between {$ifdef fpc}: that is wrong. It will probably also crash under Delphi if you would do that, because then it is no longer a pure assembly routine and the compiler will insert extra code around your assembler code. Remove the begin/end and use {$mode delphi} instead.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 11:17:50 pm
The whole project contains ~750.000 lines of code.
It still compiles under Delphi 5 (yes, it was a lot of work .. the past years ..).

And it still compiles under both Lazarus 1.6 AND Delphi 5 !
Title: Re: Assembler - logN and many more ..
Post by: engkin on July 19, 2016, 11:31:54 pm
I just tried Jonas' suggestion:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2.  
  3. function LogN( Base, X: Extended): Extended;
  4. {$ifdef FPC}
  5. {$ASMMODE intel}
  6. {$endif}
  7. asm
  8.         FLD1
  9.         FLD     X
  10.         FYL2X
  11.         FLD1
  12.         FLD     Base
  13.         FYL2X
  14.         FDIV           // Lazarus Warning: fdivrp without operand translated into fdivrpP
  15.         FWAIT
  16. end;
  17.  
  18. begin
  19.   WriteLn('LogN(10,10000): ', LogN(10,10000));
  20.   ReadLn;
  21. end.
  22.  

The result for LogN(10,10000) is 4.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 11:46:43 pm
I have a Test Project for this unit.

I can confirm now that it compiles under both Lazarus 1.6 and Dephi 5 with {$mode delphi} !
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 19, 2016, 11:50:37 pm
Switching back to  {$mode objfpc}{$H+} I get ..

.. Fatal: Syntax error, "BEGIN" expected but "ASM" found


Is there no way to make it compile with {$mode objfpc}{$H+}  ?

I would like to leave behind the Delphi 5 version ..
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 20, 2016, 12:13:07 am
Thanks Jonas and engkin !

Maybe it guides me to make a failing project work under Lazarus - tomorrow !
In my TimeZone it's time to go to bed now .. ;-)
Title: Re: Assembler - logN and many more ..
Post by: engkin on July 20, 2016, 01:14:29 am
Switching back to  {$mode objfpc}{$H+} I get ..

.. Fatal: Syntax error, "BEGIN" expected but "ASM" found


Is there no way to make it compile with {$mode objfpc}{$H+}  ?

I would like to leave behind the Delphi 5 version ..
In objfpc mode you need to add the keyword (http://www.freepascal.org/docs-html/ref/refse95.html#x186-20800014.9) assembler:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2.  
  3. function LogN( Base, X: Extended): Extended; assembler;
Title: Re: Assembler - logN and many more ..
Post by: Jonas Maebe on July 20, 2016, 10:49:06 am
Is there no way to make it compile with {$mode objfpc}{$H+}  ?

I would like to leave behind the Delphi 5 version ..

See engkin's answer for that, but you can perfectly keep compiling your code using {$mode delphi} in FPC. We don't plan on removing this mode, nor on changing it so that it will break your code. All breaking changes added by Delphi 2009 and later will be added to {$mode delphiunicode}
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 20, 2016, 11:50:15 am
.. you can perfectly keep compiling your code using {$mode delphi} in FPC. We don't plan on removing this mode, nor on changing it so that it will break your code.

I try to avoid the DELPHI mode as far as possible.
In FPC mode the rules are stricter.
So - from my point of view - it helps cleaning the (foreign) code.

In my project folder there are ~2.500 files
(lots of overhead due to backups and TestProjects)
But only 597 files still in {mode Delphi}

Most of the differences between DELPHI 5 and LAZARUS can be solved.
I just checked this - currently there are 2751 {$ifdef FPC} in my code ... hahaha !
OMG ..
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 20, 2016, 11:52:44 am
In objfpc mode you need to add the keyword (http://www.freepascal.org/docs-html/ref/refse95.html#x186-20800014.9) assembler
Thanks for this hint !

I'll check this in both D' & L' version of the project.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 20, 2016, 11:53:56 am
Feedback from FPC bug tracker:

"That is a known Delphi 5 bug:   Delphi compiles FDIV indeed as FDIVP."
Title: Re: Assembler - logN and many more ..
Post by: Thaddy on July 20, 2016, 12:06:32 pm
Indeed. Delphi users can verify the fact that FDIV is compiled as FDIVP through the CPU/FPU window.
It is not an FPC bug and the bug is still (since 2004 at least) open in Delphi. I reported it at the time....
The solution for compatibility is to write FDIVP and that will be accepted by both Delphi and FPC.
But it is a Delphi bug in BASM.

Note this guidance also means that the other way around is hardly possible: compile fpc code that contains proper FDIV into Delphi ....would lead to floating point stack corruption.
But in this case, changing Delphi sourcecode FDIV's to FDIVP's will solve it.
Title: Re: Assembler - logN and many more ..
Post by: Thaddy on July 20, 2016, 12:31:09 pm
Jonas, although you resolved that on Mantis with "The problem had nothing to do with fdiv/fdivp, but with the fact that the code contains an extra "begin .. end" around the assembler block when compiled with FPC. That means it was no longer a pure assembler routine, and the compiler inserted entry and exit code that did not expect a value to be left on the FPU stack at the end of the assembler block. "

that is not really the case. I don't know if you have access to a Delphi compiler of that era D2,3,4,5,6,2005,2006)  but it is still a Delphi bug as you would be able to see if you open up the CPU/FPU window in delphi.
It can of course be the case that there where actually 2 bugs. If you solved it both ways? Cudo's.... but I think there is more to it than just the begin/end.
Title: Re: Assembler - logN and many more ..
Post by: Jonas Maebe on July 20, 2016, 12:37:04 pm
This program prints exactly the same result when compiled with Kylix 3 (~ Delphi 6.5) and FPC 3.1.1:

Code: [Select]
fpc}
{$mode delphi}
{$endif}

function LogN( Base, X: Extended): Extended;
assembler;
asm
        FLD1
        FLD     X
        FYL2X
        FLD1
        FLD     Base
        FYL2X
        FDIV           // Lazarus Warning: fdivrp without operand translated into fdivrpP
        FWAIT
end;

begin
  writeln(logn(2,10));
end.

Result:

Code: [Select]
$ dcc tt3.pp
Borland Delphi for Linux Version 14.5
Copyright (c) 1983,2002 Borland Software Corporation
tt3.pp(22)
23 lines, 0.01 seconds, 23412 bytes code, 3132 bytes data.
$ ./tt3
 3.32192809488736E+0000


$ ppn69 ./tt3.pp
Free Pascal Compiler version 3.1.1 [2016/07/19] for i386
Copyright (c) 1993-2016 by Florian Klaempfl and others
Target OS: Linux for i386
Compiling ./tt3.pp
tt3.pp(14,9) Warning: fdivrp without operand translated into fdivrpP
tt3.pp(14,9) Warning: "fdivrp" without operand translated into "fdivrp %st,%st(1)"
Linking tt3
21 lines compiled, 0.2 sec
2 warning(s) issued

$ ./tt3
 3.32192809488736234781E+0000

So at least FPC and Kylix 3 interpret "fdiv" in Intel-style inline assembly in exactly the same way.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 20, 2016, 12:44:37 pm
Note this guidance also means that the other way around is hardly possible: compile fpc code that contains proper FDIV into Delphi ....would lead to floating point stack corruption.
But in this case, changing Delphi sourcecode FDIV's to FDIVP's will solve it.
I have replaced the FDIV with FDIVP.

Now Lazarus (1.6) reports for FDIVP:        Warning: "fdivrp" without operand translated into "fdivrp %st,%st(1)"

What would be the proper assembler code for this in FreePascal ASM ?
Title: Re: Assembler - logN and many more ..
Post by: PeterX on July 20, 2016, 01:23:50 pm
Thaddy, Jonas,

You both contributed to the solution !


Thaddy, the code I first presented, really crashes in Lazarus but not in Delphi !
=> removed  begin .. end   and added   assembler;

Jonas, I want correct code in FPC style, for the future.
=> replacing the FDIV with FDIVP is one step forward !


Thank You both !
Title: Re: Assembler - logN and many more ..
Post by: PeterX on September 09, 2016, 05:45:48 pm
I am not finished with all these ancient assembler things ..
I still have some warnings with unresolved ASM instructions.


Today I found an old thread on google:
https://groups.google.com/forum/#!topic/borland.public.delphi.language.basm/pJDd8LFXVQw


Maybe this helps fixing all these old Delphi 5 code fragments, throwing

- Warning: fmulp without operand translated into fmulpP
- Warning: "faddp" without operand translated into "faddp %st,%st(1)"
- Warning: "faddp" without operand translated into "faddp %st,%st(1)"
etc ...
Title: Re: Assembler - logN and many more ..
Post by: PeterX on September 09, 2016, 06:21:22 pm
Okay, in the google thread I found a INTEL statement:

".. FADD instruction:

The no operand version of the floating point add instructions always results
in the register stack being popped.  In some assemblers, the mnemonic for
this instruction is FADD rather than FADDP.

    Sentences that are virtually identical to this appear for FSUB, FMUL,
and FDIV.  What this means is that no matter how the no operand version of
the instruction is implemented, be it FADD, or FADDP, it will pop the stack.
This means that even though some assemblers choose to support the FADD
mnemonic, it will always act like the FADDP instruction.  You can expect
similar behavior for FSUB, FMUL, and FDIV."



And from another post:    FADD = FADDP = FADDP ST(1) = FADDP ST(1),ST(0)


This should make it clear, finally ..  :)
Title: Re: Assembler - logN and many more ..
Post by: PeterX on September 09, 2016, 06:53:29 pm
.. and these warnings from Lazarus 1.6 are the wrong text:

FADD   =>   Warning: faddp without operand translated into faddpP"

FMUL   =>   "Warning: fmulp without operand translated into fmulpP"

FSUB   =>   "Warning: fsubrp without operand translated into fsubrpP"
Title: Re: Assembler - logN and many more ..
Post by: PeterX on September 09, 2016, 07:32:08 pm
When I use "FDIVP", I get

=> Warning: "fdivrp" without operand translated into "fdivrp %st,%st(1)"


When I then replace "FDIVP"   with   "fdivrp %st,%st(1)", I get

=> Fatal: illegal character "'%'" ($25)


Wrong recommendation text ?
Or because I use {$ASMMODE intel} ?
Title: Re: Assembler - logN and many more ..
Post by: marcov on September 09, 2016, 09:14:10 pm
I think you get a general errormessage that is for AT&T syntax.

So probably you simply need to use two operand syntax

fdivrp st1,st0

or so. I gambled that AT&T->intel required an inversion of arguments, but my copro asm is not really 100%.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on September 10, 2016, 04:31:52 pm
I gambled that AT&T->intel required an inversion of arguments, but my copro asm is not really 100%.
Yes, seems to be AT&T synthax.

And  "fdivp st(1), st(0)"   instead of  "fdivrp %st,%st(1)"  compiles.
Title: Re: Assembler - logN and many more ..
Post by: PeterX on September 17, 2016, 09:54:26 pm
on     FSUB
I get  "Warning: fsubrp without operand translated into fsubrpP"

But to me  FSUB ST(1), ST(0)  is <>  fsubrpP
TinyPortal © 2005-2018