Tag: Inline ASM

ftol and the 64bit Delphi inline asm changes

function _ftol( f: double) : Integer; cdecl;
begin
  asm
    lea    eax, f
    fstp  qword ptr [eax]
  end;
  result := Trunc(f);
end;

Above is a Delphi inline asm version of the ftol (Floating Point to Integer Conversion) function used by our HotPDF Delphi PDF component.

When compiling above Delphi codes in the 64-bit target platform, Delphi will raise below error:
[dcc64 Error] E1025 Unsupported language feature: ‘ASM’

The reason is: The 64-bit Delphi compiler DCC64 does not support mixed Pascal/assembly code.
DCC64.EXE supports 64-bit assembly code, but the routines must be written completely in assembler.

In addition, the 64-bit asm codes have many different than the 32-bit ones, you can not copy the 32-bit asm codes to the 64-bit assembler routines directly, you must re-write them from scratch, I found below codes from the internet:

function _ftol: Integer; cdecl;
// Assumes double value is in FPU stack on entry
// Make a truncation to integer and put it into function result
var
  TmpVal: Int64;
  SaveCW, ScratchCW: word;

asm
  .NOFRAME
  fnstcw word ptr [SaveCW]
  fnstcw word ptr [ScratchCW]
  or word ptr [ScratchCW], 0F00h  ;// trunc toward zero, full precision
  fldcw word ptr [ScratchCW]
  fistp qword ptr [TmpVal]
  fldcw word ptr [SaveCW]
  mov rax, TmpVal
end;

But maybe we do not really need assembly this routine,

function _ftol(f: double): integer; cdecl;
begin
  Result := Trunc(f);
end;

The trunc function of Delphi just returns the integer part of a floating point number, that’s the conversion from floating point to integer. The speed of this version should be not bad.