Since D2006 Delphi supports operator overloading.

You can use inline and assembly in your custom operators, which can really help performance when you’re in a pinch.

In Program Control (Delphi) we can see:

Handling Function Results

For static-array, record, and set results, if the value occupies one byte it is returned in AL; if the value occupies two bytes it is returned in AX; and if the value occupies four bytes it is returned in EAX. Otherwise, the result is returned in an additional var parameter that is passed to the function after the declared parameters.

However the rules for register allocation with record operators is a bit strange, so for documentation (as well as my own future reference) here are the rules:

When the class operator returns a result that is too large to fit inside a register, an additional var parameter Result is inserted before the other parameters of the method.

Let’s define a record that holds a set.

type TMySet = record strict private FData: array[0..31] of byte; public class operator BitWiseAnd(const A, B: TMySet): TMySet; //translates to a procedure with one var and two const parameters. class operator Equal(const A, B: TMySet): boolean; //translates to a static class function end; implementation //Translates to class procedure TMySet.BitwiseAnd(var Result: TMySet; const [ref] A,B: TMySet); static; class operator TMySet.BitWiseAnd(const A, B: TMySet): TMySet; //translates to a procedure with one var and two const parameters. asm //rcx = @Result //rdx = @A //r8 = @B movdqu xmm0,[rdx] //Delphi does not do alignment movdqu xmm1,[rdx+16] movdqu xmm2,[r8] movdqu xmm3,[r8+16] pand xmm0,xmm2 pand xmm1,xmm3 movdqu [rcx],xmm0 movdqu [rcx+16],xmm1 end; //translates to class function TMySet.Equal(const [ref] A,B: TMySet): boolean; class operator TMySet.Equal(const A, B: TMySet): boolean; //translates to a static class function asm //rcx = @A //How confusing //RDX = @B mov xmm0,[rcx] mov xmm1,[rcx+16] mov xmm2,[rdx] mov xmm3,[rdx+16] xor edx,edx // pcmpeqq xmm0,xmm2 //xmm0=all ones if equal, zero's somewhere if not equal pcmpeqq xmm1,xmm3 //we have 2 comparisons per xmm-word pshufd xmm0,xmm1,$AA //mix comparisons A and B pmovmskb eax,xmm0 //eax=$0000FFFF if all equal cmp eax,$FFFF //is everything equal? mov eax,edx //Assume not equal setz al //if yes then put a true in result. end;

>

When we return a result that’s too large too fit inside the rax register, then the signature of the operator changes to a procedure with the result as the first parameter.

If the result fits inside a register, it is returned in rax as normal and the parameters work as usual with class functions.