[fpc-devel] Trunc / Win 32 bit cross compile generates incorrect range checks
Martin Frb
lazarus at mfriebe.de
Mon Nov 11 11:15:55 CET 2024
I have a problem with a cross compiler build...
I know there officially isn't a win-32 64bit to 32bit cross compiler. So
taking my chances here...
But afaik that is due to diff results between compile time and run time.
Not due to wrong range checks?
Anyway this works fine in 3.2.2 and 3.2.3 and older 3.3.1 (not sure how
long back).
Now with b693af69a6 it generates incorrect range check.
The build is done with (starting compiler 3.2.2)
make.exe all LINKSMART=1 CREATESMART=1 OPTIMIZE=1 OPT="-CX -gl -gw3
-O-1" "OS_TARGET=win32" "CPU_TARGET=i386" OPTNEW="-CX -gl -gw3
-O-1" FPMAKEOPT="-T 6"
The project is compiled cross compiled to win32 i386.
LCL and project with
-O1 -Criot
The project just calls
LclType.MulDiv(-13, 72,76);
in LclType
function MulDiv(nNumber, nNumerator, nDenominator: Integer): Integer;
begin
if nDenominator = 0 then
Result := -1
else
if nNumerator = nDenominator then
Result := nNumber
else
Result := MathRound(int64(nNumber) * int64(nNumerator) / nDenominator);
end;
And the asm code
B:\lazarus_main\lcl\lcltype.pp:3048 begin
00000000004B3030 55 push ebp
00000000004B3031 89E5 mov ebp,esp
00000000004B3033 8D6424D0 lea esp,[esp-$30]
00000000004B3037 53 push ebx
00000000004B3038 8945FC mov [ebp-$04],eax
00000000004B303B 8955F8 mov [ebp-$08],edx
00000000004B303E 894DF4 mov [ebp-$0C],ecx
00000000004B3041 C745F055555555 mov [ebp-$10],$55555555
B:\lazarus_main\lcl\lcltype.pp:3049 if nDenominator = 0 then
00000000004B3048 837DF400 cmp dword ptr [ebp-$0C],$00
00000000004B304C 7512 jnz +$12 #
$00000000004B3060 MulDiv+48 lcltype.pp:3052
B:\lazarus_main\lcl\lcltype.pp:3050 Result := -1
00000000004B304E C745F0FFFFFFFF mov [ebp-$10],$FFFFFFFF
00000000004B3055 E9C6000000 jmp +$000000C6 #
$00000000004B3120 MulDiv+240 lcltype.pp:3056
00000000004B305A 660F1F440000 nop word ptr [eax+eax+$00]
B:\lazarus_main\lcl\lcltype.pp:3052 if nNumerator = nDenominator then
00000000004B3060 8B45F4 mov eax,[ebp-$0C]
00000000004B3063 3B45F8 cmp eax,[ebp-$08]
00000000004B3066 7510 jnz +$10 #
$00000000004B3078 MulDiv+72 lcltype.pp:3055
B:\lazarus_main\lcl\lcltype.pp:3053 Result := nNumber
00000000004B3068 8B45FC mov eax,[ebp-$04]
00000000004B306B 8945F0 mov [ebp-$10],eax
00000000004B306E E9AD000000 jmp +$000000AD #
$00000000004B3120 MulDiv+240 lcltype.pp:3056
00000000004B3073 0F1F440000 nop dword ptr [eax+eax+$00]
B:\lazarus_main\lcl\lcltype.pp:3055 Result :=
MathRound(int64(nNumber) * int64(nNumerator) / nDenominator);
00000000004B3078 8B55F8 mov edx,[ebp-$08]
00000000004B307B C4E273F645FC mulx ecx,eax,edx,[ebp-$04]
00000000004B3081 894DD8 mov [ebp-$28],ecx
00000000004B3084 8945DC mov [ebp-$24],eax
00000000004B3087 DF6DD8 fild qword ptr [ebp-$28]
00000000004B308A DB45F4 fild dword ptr [ebp-$0C]
00000000004B308D DEF9 fdivp st(1),st(0)
00000000004B308F DB7DE0 fstp tbyte ptr [ebp-$20]
00000000004B3092 D9EE fldz
00000000004B3094 DB6DE0 fld tbyte ptr [ebp-$20]
00000000004B3097 DFF1 fcomip st(0),st(1)
00000000004B3099 DDD8 fstp st(0)
00000000004B309B 7A33 jp +$33 # $00000000004B30D0
MulDiv+160 lcltype.pp:3055
00000000004B309D 7231 jb +$31 # $00000000004B30D0
MulDiv+160 lcltype.pp:3055
00000000004B309F D97DD8 fnstcw word ptr [ebp-$28]
00000000004B30A2 D97DDC fnstcw word ptr [ebp-$24]
00000000004B30A5 66814DD8000F or [ebp-$28],$0F00
00000000004B30AB DB6DE0 fld tbyte ptr [ebp-$20]
00000000004B30AE DB2DB0A97900 fld tbyte ptr [$0079A9B0]
00000000004B30B4 DEC1 faddp st(1),st(0)
00000000004B30B6 D96DD8 fldcw word ptr [ebp-$28]
00000000004B30B9 DF7DD0 fistp qword ptr [ebp-$30]
00000000004B30BC D96DDC fldcw word ptr [ebp-$24]
00000000004B30BF 9B fwait
00000000004B30C0 8B5DD0 mov ebx,[ebp-$30]
00000000004B30C3 8B45D4 mov eax,[ebp-$2C]
00000000004B30C6 EB2F jmp +$2F #
$00000000004B30F7 MulDiv+199 lcltype.pp:3055
00000000004B30C8 0F1F840000000000 nop dword ptr [eax+eax+$00000000]
00000000004B30D0 D97DD8 fnstcw word ptr [ebp-$28]
00000000004B30D3 D97DDC fnstcw word ptr [ebp-$24]
00000000004B30D6 66814DD8000F or [ebp-$28],$0F00
00000000004B30DC DB6DE0 fld tbyte ptr [ebp-$20]
00000000004B30DF DB2DB0A97900 fld tbyte ptr [$0079A9B0]
00000000004B30E5 DEE9 fsubp st(1),st(0)
00000000004B30E7 D96DD8 fldcw word ptr [ebp-$28]
00000000004B30EA DF7DD0 fistp qword ptr [ebp-$30]
00000000004B30ED D96DDC fldcw word ptr [ebp-$24]
00000000004B30F0 9B fwait
00000000004B30F1 8B5DD0 mov ebx,[ebp-$30]
00000000004B30F4 8B45D4 mov eax,[ebp-$2C]
00000000004B30F7 85C0 test eax,eax
eax is zero, => jump
00000000004B30F9 740A jz +$0A # $00000000004B3105
MulDiv+213 lcltype.pp:3055
why compare with $FF ?
Anyway eax is zero at this point, so this is not reached
00000000004B30FB 83F8FF cmp eax,$FF
00000000004B30FE 7414 jz +$14 # $00000000004B3114
MulDiv+228 lcltype.pp:3055
00000000004B3100 E86BE6F5FF call -$000A1995 #
$0000000000411770 $fpc_rangeerror system.inc:1001
execution goes here
ebx = $BFFFFFF6
not sure where that came from
00000000004B3105 81FBFFFFFF7F cmp ebx,$7FFFFFFF
00000000004B310B 7610 jbe +$10 #
$00000000004B311D MulDiv+237 lcltype.pp:3055
calls range check on next line
00000000004B310D E85EE6F5FF call -$000A19A2 #
$0000000000411770 $fpc_rangeerror system.inc:1001
00000000004B3112 EB09 jmp +$09 #
$00000000004B311D MulDiv+237 lcltype.pp:3055
00000000004B3114 85DB test ebx,ebx
00000000004B3116 7C05 jl +$05 # $00000000004B311D
MulDiv+237 lcltype.pp:3055
00000000004B3118 E853E6F5FF call -$000A19AD #
$0000000000411770 $fpc_rangeerror system.inc:1001
00000000004B311D 895DF0 mov [ebp-$10],ebx
B:\lazarus_main\lcl\lcltype.pp:3056 end;
0000000000415C00 8B45F0 mov eax,[ebp-$10]
0000000000415C03 5B pop ebx
0000000000415C04 89EC mov esp,ebp
0000000000415C06 5D pop ebp
0000000000415C07 C3 ret
==============
The calling code
C:\Users\martin\AppData\Local\Temp\project1.lpr:8 MulDiv(-13,72,96);
0000000000401718 B960000000 mov ecx,$00000060
000000000040171D BA48000000 mov edx,$00000048
0000000000401722 B8F3FFFFFF mov eax,$FFFFFFF3
0000000000401727 E8E4430100 call +$000143E4 #
$0000000000415B10 MulDiv lcltype.pp:3048
More information about the fpc-devel
mailing list