Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
Delphi 11 Alexandria
|
AW: 256 bit Integer Addition von ASM in PurePascal
8. Jan 2012, 10:02
Wie gesagt ist die Funktion für 32-Bit-Systeme ausgelegt, da ich 1. nur ein 32-Bit-Windows und 2. nur ein 32-Bit-Delphi besitze. Sollte aber kein Problem sein, sie ggf. auf 64 Bit anzupassen.
Sie funktioniert mit XE2 für 64-Bit 1:1 genauso. Zum Vergleich habe ich kurz die Assemblervariante auf 64-Bit umgeschrieben:
Delphi-Quellcode:
procedure Increment8( var Value; Add: LongWord); assembler;
asm
MOV EBX,EDX
LEA EDX,[EDX * 8]
SHR EBX,29 // 12/13/2011 Fixed
ADD [ECX].DWord[ 0],EDX
ADC [ECX].DWord[ 4],EBX
ADC [ECX].DWord[ 8],0
ADC [ECX].DWord[12],0
ADC [ECX].DWord[16],0
ADC [ECX].DWord[20],0
ADC [ECX].DWord[24],0
ADC [ECX].DWord[28],0
JC HashingOverflowError
end;
Der Test läuft 1:1 durch.
Insgesamt sieht das also so aus mit deiner Variante integriert:
Delphi-Quellcode:
procedure Increment8( var Value; Add: LongWord); {$IFNDEF PUREPASCAL} assembler; {$ENDIF !PUREPASCAL}
// Value := Value + 8 * Add
// Value is array[0..7] of LongWord
{$IFDEF PUREPASCAL}
var
HiBits: LongWord;
Add8: LongWord;
Data: TData absolute Value;
Carry: Boolean;
procedure AddC( var Value: LongWord; const Add: LongWord; var Carry: Boolean); inline;
begin
if Carry then
begin
Value := Value + 1;
Carry := (Value = 0); // we might cause another overflow by adding the carry bit
end
else
Carry := False;
Value := Value + Add;
Carry := Carry or (Value < Add); // set Carry Flag on overflow
end;
begin
HiBits := Add shr 29; // Save most significant 3 bits in case an overflow occurs
Add8 := Add * 8;
Carry := False;
AddC(Data[0], Add8, Carry);
AddC(Data[1], HiBits, Carry);
AddC(Data[2], 0, Carry);
AddC(Data[3], 0, Carry);
AddC(Data[4], 0, Carry);
AddC(Data[5], 0, Carry);
AddC(Data[6], 0, Carry);
AddC(Data[7], 0, Carry);
if Carry then
HashingOverflowError;
end;
{$ELSE !PUREPASCAL}
{$IFDEF CPUX86}
asm
MOV ECX,EDX
LEA EDX,[EDX * 8]
SHR ECX,29 // 12/13/2011 Fixed
ADD [EAX].DWord[ 0],EDX
ADC [EAX].DWord[ 4],ECX
ADC [EAX].DWord[ 8],0
ADC [EAX].DWord[12],0
ADC [EAX].DWord[16],0
ADC [EAX].DWord[20],0
ADC [EAX].DWord[24],0
ADC [EAX].DWord[28],0
JC HashingOverflowError
end;
{$ENDIF CPUX86}
{$IFDEF CPUX64}
asm
MOV EBX,EDX
LEA EDX,[EDX * 8]
SHR EBX,29 // 12/13/2011 Fixed
ADD [ECX].DWord[ 0],EDX
ADC [ECX].DWord[ 4],EBX
ADC [ECX].DWord[ 8],0
ADC [ECX].DWord[12],0
ADC [ECX].DWord[16],0
ADC [ECX].DWord[20],0
ADC [ECX].DWord[24],0
ADC [ECX].DWord[28],0
JC HashingOverflowError
end;
{$ENDIF CPUX64}
{$ENDIF !PUREPASCAL}
Geändert von jaenicke ( 8. Jan 2012 um 10:11 Uhr)
|