[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