Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-05

Error in x32 compiler when using SSE3

7 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

OBones

Hello all,

I'm compiling the program at the end of this message in x86 and x64 mode using the following command lines:

ppc386 -MDelphi -CfSSE3 testFPU.dpr
ppcrossx64 -MDelphi -CfSSE3 testFPU.dpr

while I get an exe file and no error in x64 mode, I get the following error message with ppc386:

testFPU.dpr(22,33) Error: Asm: [comisd mem??,xmmreg] invalid combination
of opcode and operands
testFPU.dpr(30,1) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted

Is this a known issue?
Is there a workaround for this?

I really need to have the same instruction set used for floating point maths, hence the use of SSE3 in both cases.

Regards

Reply by email

Jonas Maebe
to OBones
OBones wrote
I'm compiling the program at the end of this message

The program is missing.

I really need to have the same instruction set used for floating point maths, hence the use of SSE3 in both cases.

If your x86-64 target is Win64, using -CfSSE2/-CfSSE3 will not result in exactly the same fpu instructions on i386 and x86-64 under all circumstances. The reason is that it is impossible to disable 80 bit extended floating point support in the i386 version of the compiler (and impossible to enable it in FPC/Win64). As a result: a) constants that cannot be represented exactly using double precision will still be parsed as extended precision by the compiler (and as a result, other terms in the same expression will be promoted along with it) b) several run time library functions and constants are declared using the most precise real type type available on the platform (i.e., extended on i386 and double on Win64)

Jonas

Reply by email

OBones
to Jonas Maebe
Jonas Maebe wrote
On 28 May 2012, at 14:41, OBones wrote: > I'm compiling the program at the end of this message The program is missing.

Bugger, why does this keep happening to me???
Anyway, this time it is at the end.

Show quoted text 5 lines
> I really need to have the same instruction set used for floating point maths, hence the use of SSE3 in both cases. If your x86-64 target is Win64, using -CfSSE2/-CfSSE3 will not result in exactly the same fpu instructions on i386 and x86-64 under all circumstances. The reason is that it is impossible to disable 80 bit extended floating point support in the i386 version of the compiler (and impossible to enable it in FPC/Win64). As a result: a) constants that cannot be represented exactly using double precision will still be parsed as extended precision by the compiler (and as a result, other terms in the same expression will be promoted along with it) b) several run time library functions and constants are declared using the most precise real type type available on the platform (i.e., extended on i386 and double on Win64)

Yes, I'm aware of that, but I want to minimize the places where differences can come from, so using the same instruction set helps doing that.

==================================================================

program testFPU;
uses
    Math;
var
   current: Integer;
   __VARIABLE: Double;
type
    NS = class
      class function VARIABLE: Double;
    end;
class function NS.VARIABLE: Double;
begin
   Result:= __VARIABLE;
end;
function ComputeIt: Double;
begin
   if Frac(current/NS.VARIABLE) = current/NS.VARIABLE then
     Result := Trunc(current/NS.VARIABLE)
   else
     Result := Trunc(current/NS.VARIABLE)+1
end;
begin
end.

Reply by email

Jonas Maebe
to OBones
OBones wrote
Bugger, why does this keep happening to me??? Anyway, this time it is at the end.

I cannot reproduce the problem with 2.6.0/2.7.1 on Mac OS X/i386, nor with 2.7.1 on Linux/i386. I even don't see any comis* instructions in the code, the comparison is performed by the x87 fpu because frac() returns an extended result on i386. The only way I can get a comisd, is a) when targeting Win64/x86-64, but then it's a "comisd reg,reg" instruction b) when compiling in ObjFPC mode rather than Delphi mode and compiling for i386, and adding an explicit double() typecast around the result of frac (that's not possible in Delphi mode, because Delphi does not allow changing the precision of floating point expressions via explicit typecasts). Then I do see a "comisd ref, reg", but it compiles fine here with 2.7.1 for Mac OS X/i386 and Linux/i386 (I don't have a 2.6.0 rtl for Linux or Win32 handy to test).

Jonas

Reply by email

OBones
to Jonas Maebe
Jonas Maebe wrote 7 lines
On 28 May 2012, at 15:19, OBones wrote: > Bugger, why does this keep happening to me??? > Anyway, this time it is at the end. I cannot reproduce the problem with 2.6.0/2.7.1 on Mac OS X/i386, nor with 2.7.1 on Linux/i386. I even don't see any comis* instructions in the code, the comparison is performed by the x87 fpu because frac() returns an extended result on i386. The only way I can get a comisd, is a) when targeting Win64/x86-64, but then it's a "comisd reg,reg" instruction b) when compiling in ObjFPC mode rather than Delphi mode and compiling for i386, and adding an explicit double() typecast around the result of frac (that's not possible in Delphi mode, because Delphi does not allow changing the precision of floating point expressions via explicit typecasts). Then I do see a "comisd ref, reg", but it compiles fine here with 2.7.1 for Mac OS X/i386 and Linux/i386 (I don't have a 2.6.0 rtl for Linux or Win32 handy to test).

Boy, I'm having a hard day and I'm very sorry to make you waste so much time.
Frac was here to see the impact of some changes on the issue, but the original code that crashes is with Trunc instead of Frac so that the comparison looks like this:

   if Trunc(current/NS.VARIABLE) = current/NS.VARIABLE then

Once again, sorry for all the troubles.

Reply by email

Jonas Maebe
to OBones

OBones wrote on Mon, 28 May 2012:

Show quoted text 8 lines
Boy, I'm having a hard day and I'm very sorry to make you waste so much time. Frac was here to see the impact of some changes on the issue, but the original code that crashes is with Trunc instead of Frac so that the comparison looks like this: if Trunc(current/NS.VARIABLE) = current/NS.VARIABLE then Once again, sorry for all the troubles.

Ok, please file a bug report so it won't be forgotten.

Jonas

Reply by email

OBones
to Jonas Maebe
Jonas Maebe wrote 14 lines
OBones wrote on Mon, 28 May 2012: > Boy, I'm having a hard day and I'm very sorry to make you waste so > much time. > Frac was here to see the impact of some changes on the issue, but the > original code that crashes is with Trunc instead of Frac so that the > comparison looks like this: > > if Trunc(current/NS.VARIABLE) = current/NS.VARIABLE then > > Once again, sorry for all the troubles. Ok, please file a bug report so it won't be forgotten.

Done: http://bugs.freepascal.org/view.php?id=22150

Reply by email