Hi,
There is few tricks can be used, but i can't find valuable for you in this case without affecting the performance for this performance critical procedure.
This is perfect workaround for 32bit but will not compile for 64 for the obvious reason
Code:
procedure AddC(var Value: UInt32; Add: UInt32; var Carry: Boolean);
begin
Value := Value + Add;
PByte(Value) := PByte(Value) + Ord(Add);
end;
Its assembly
Code:
Project5.dpr.15: Value := Value + Add;
0041A2BC 0110 add [eax],edx
0041A2BE 7305 jnb $0041a2c5
0041A2C0 E83FB3FEFF call @IntOver
Project5.dpr.16: PByte(Value) := PByte(Value) + Ord(Add);
0041A2C5 0110 add [eax],edx
Project5.dpr.21: end;
0041A2C7 C3 ret
The overhead is one instruction in this case.
but all the other tricks and shenanigans that work for both platforms i can think of will introduce huge overhead instead of one or two instruction.
Like this one
Code:
procedure AddC(var Value: UInt32; Add: UInt32; var Carry: Boolean);
begin
Value := Value + Add;
Value := UInt32(PByte(Value) + Ord(Add));
end;
Generated code :
Code:
Project5.dpr.15: Value := Value + Add;
0041A2BC 0110 add [eax],edx
0041A2BE 7305 jnb $0041a2c5
0041A2C0 E83FB3FEFF call @IntOver
Project5.dpr.16: Value := UInt32(PByte(Value) + Ord(Add));
0041A2C5 8B08 mov ecx,[eax]
0041A2C7 03CA add ecx,edx
0041A2C9 8908 mov [eax],ecx
Project5.dpr.22: end;
0041A2CB C3 ret
Code:
Project5.dpr.15: Value := Value + Add;
00000000004261E8 0111 add [rcx],edx
00000000004261EA 7305 jnb AddC + $11
00000000004261EC E8AF12FEFF call @IntOver
Project5.dpr.16: Value := UInt32(PByte(Value) + Ord(Add));
00000000004261F1 8B01 mov eax,[rcx]
00000000004261F3 8BD2 mov edx,edx
00000000004261F5 488D0410 lea rax,[rax+rdx]
00000000004261F9 8901 mov [rcx],eax
Project5.dpr.22: end;
00000000004261FB 488D6520 lea rsp,[rbp+$20]
00000000004261FF 5D pop rbp
0000000000426200 C3 ret
We have stupid and outdated compiler !
Though the above result is on XE8, and i have no idea on how or will it even compile on newer versions.