Question

I am trying to "redefine" the UInt64 type for the Delphi 3 compiler. The reason for that is that I do not use system.pas nor sysinit.pas. So I only have native var types like Integer, Cardinal etc. How could I reproduce the UInt64?

Was it helpful?

Solution

Delphi 7 doesn't have an unsigned 64-bit integer type. You can tell from its Windows.pas, where ULARGE_INTEGER is defined as a variant record holding either two unsigned 32-bit integers, or one signed 64-bit integer, which makes little sense, until you realise that that's simply the least bad alternative if you really need something that's binary compatible with unsigned 64-bit integer types from another system.

An unsigned 64-bit integer type requires compiler support, which your compiler lacks, so you cannot create it, sorry. Newer Delphi versions do have compiler support for it, so you might consider upgrading.

Delphi 3 is even worse, it doesn't have any 64-bit integer type, not even a signed one. Int64 was added in Delphi 4, and that might be sufficient to avoid the need for a working 64-bit unsigned integer type, but if you're stuck on Delphi 3, not even that will work.

As a side note, seemingly contrary to this answer, Delphi 7 does have a UInt64 type. However, this is highly misleading. It's a signed 64-bit integer type in this version, just like Int64.

OTHER TIPS

As I have explained in the comments, what really matters here is which operations you wish to support. The data type is simple enough. You represent it as two adjacent 32 bit integers. But the complexity lies in implementing the operations on that data type.

On a 32 bit machine, you cannot operate directly on 64 bit integers, so you need to build 64 bit operations using the functionality of the 32 bit CPU.

Here is an example of how to implement incrementing of an unsigned 64 bit integer by a signed 32 bit integer.

type
  UInt64 = record
    Lo: Cardinal;
    Hi: Cardinal;
  end;

procedure Increment(var op1: UInt64; op2: Integer);
// IN: eax = pointer to op1; edx = op2
asm
  mov ecx,eax
  mov eax,edx
  cdq
  add eax,[ecx]
  adc edx,[ecx+4]
  mov [ecx],eax
  mov [ecx+4],edx
end;

The tricky part of this function is the cdq instruction. That sign extends the signed double word in eax to a signed quad word in edx:eax.

Implementing other operations is broadly similar. Obviously addition is the simplest. Multiplication gets a little more difficult.


In the comments you state:

I am trying to port the latest BTMemoryModule.pas to make it work without UInt64. It uses UInt64 so it supports x64 but I only need it for x86.

Since you only need x86 support, because your compiler is 32 bit, then I don't think you actually need UInt64 operations. You replace those variables with Cardinal.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top