I'm trying to import a .o
file from Lazarus into Delphi.
function Test: boolean;
const
TestData: array[0..15] of byte = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
asm
movdqu xmm0,[rip+testData] //xmm0 should be all zeros
pcmpeqq xmm1,xmm1 //xmm1 is all ones
ptest xmm0,xmm1 //ZF = (xmm0 and xmm1) = 0
setz al //return true if test works, false if not
end;
The above routine works in Delphi, but fails in Lazarus.
I'm importing the .o file using
{$L 'C:\pathname\TestUnit.o'}
function TESTUNIT_TEST: boolean; external name 'TESTUNIT_$$_TEST$$BOOLEAN';
Lazarus replaces the reference to TestData
with a zero offset.
AVXGENERATE_TEST:
//never mind the stack frame
0000000000A0F3B0 488D6424F8 lea rsp,[rsp-$08]
// rel 0? why?
0000000000A0F3B5 F30F6F0500000000 movdqu xmm0,dqword ptr [rel $00000000]
0000000000A0F3BD 660F3829C9 pcmpeqq xmm1,xmm1
0000000000A0F3C2 660F3817C1 ptest xmm0,xmm1
0000000000A0F3C7 0F94C0 setz al
0000000000A0F3CA 488D642408 lea rsp,[rsp+$08]
0000000000A0F3CF C3 ret
Here is the output from `objdump -dr "C:\pathname\TestUnit.o"
Disassembly of section .text.n_avxgenerate_$$_test$$boolean:
0000000000000000 <AVXGENERATE_$$_TEST$$BOOLEAN>:
0: 48 8d 64 24 f8 lea -0x8(%rsp),%rsp
5: f3 0f 6f 05 00 00 00 movdqu 0x0(%rip),%xmm0 # d <AVXGENERATE_$$_TEST$$BOOLEAN+0xd>
c: 00
9: R_X86_64_PC32 .data.n_tc_$avxgenerate_$$_testdata
d: 66 0f 38 29 c9 pcmpeqq %xmm1,%xmm1
12: 66 0f 38 17 c1 ptest %xmm1,%xmm0
17: 0f 94 c0 sete %al
1a: 48 8d 64 24 08 lea 0x8(%rsp),%rsp
1f: c3
How do I get lazarus to read the constant correctly into an xmm
register?
Is there a workaround for this issue?
I plan to include some AVX
assembly written in lazarus in a Delphi program.
For testing purposes I'm just using SSE
code here.
Version info
FPC 3.0.0
Lazarus version 1.6.2
A workaround is to put the routines to be imported into a DLL.
This means that you no longer have all your stuff in a standalone .exe
file.
But at least all code links correctly.
In Lazarus
library Test_lib;
{$mode delphi}{$H+}
uses
Classes,
TestUnit;
{$R *.res}
exports
Test;
begin
end.
in Delphi
const
Testlib = 'C:\pathname\Lazarus\Test_lib.dll';
function LazarusTest: boolean; external Testlib name 'Test';
Now the output is:
0000000110020570 488D6424F8 lea rsp,[rsp-$08]
{ links to the correct location VVVVVV}
0000000110020575 F30F6F0553930000 movdqu xmm0,dqword ptr [rel $00009353]
000000011002057D 660F3829C9 pcmpeqq xmm1,xmm1
0000000110020582 660F3817C1 ptest xmm0,xmm1
0000000110020587 0F94C0 setz al
000000011002058A 488D642408 lea rsp,[rsp+$08]
000000011002058F C3 ret
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With