Delphi-PRAXiS
Seite 2 von 7     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Der DEC x32 ASM in x64/PurePascal Konvertierungsthread (https://www.delphipraxis.net/165599-der-dec-x32-asm-x64-purepascal-konvertierungsthread.html)

himitsu 8. Jan 2012 11:36

AW: 256 bit Integer Addition von ASM in PurePascal
 
Zitat:

Zitat von jbg (Beitrag 1144884)
the caller writes to EDX what automatically clears the high DWORD of RDX

Und das ist auch immer definitiv so?
Nja, ein kleiner zusätzlicher Befehl, um das zu leeren/sicherzustellen, sollte auch nicht so sehr stören.



Für eine zukünftig unbestimmte Portierungen auf weitere Systeme/CPUs wäre jeweils eine (zusätzliche) PurePascal-Variante bestimmt kein Nachteil.

jbg 8. Jan 2012 11:56

AW: 256 bit Integer Addition von ASM in PurePascal
 
Zitat:

Zitat von himitsu (Beitrag 1144885)
Zitat:

Zitat von jbg (Beitrag 1144884)
the caller writes to EDX what automatically clears the high DWORD of RDX

Und das ist auch immer definitiv so?

Ja, da der Prozessor bei einem "MOV EDX, xyz" immer das obere QWORD ablöscht (steht auch so in der x64 Instruction Set Beschreibung) und zudem die Win64 Calling Convention es vorschreibt den zweiten Parameter im RDX Register zu übergeben. Da steht nichts von EDX sondern RDX, also alle Bits.

Zitat:

Für eine zukünftig unbestimmte Portierungen auf weitere Systeme/CPUs wäre jeweils eine (zusätzliche) PurePascal-Variante bestimmt kein Nachteil.
Portabel ist der x64-Assembler Code natürlich nicht. Der ist speziell für Win64 geschrieben. Nur mit PurePascal bist du platformunabhängig.

jbg 8. Jan 2012 12:08

AW: 256 bit Integer Addition von ASM in PurePascal
 
Zitat:

Zitat von Assertor (Beitrag 1144882)
Ich stelle hier schonmal die nächste ASM Funktion zur Diskussion und Hijacke damit meinen eigenen Thread:
Delphi-Quellcode:
{ TODO : Consider implementing IDEAMul() as PurePascal if porting to FPC }
function IDEAMul(X, Y: LongWord): LongWord; assembler;
asm
       AND   EAX,0FFFFh
       JZ    @@1
       AND   EDX,0FFFFh
       JZ    @@1
       MUL   EDX
       MOV   EDX,EAX
       MOV   ECX,EAX
       SHR   EDX,16
       SUB   EAX,EDX
       SUB   CX,AX
       ADC   EAX,0
       RET
@@1:  LEA   EAX,[EAX + EDX - 1]
       NEG   EAX
end;

Hier die Win64 kompatible Version. Ein "MOV EAX,ECX" das den ersten Parameter in EAX kopiert, reicht aus und alles läuft wie gewohnt weiter.
Delphi-Quellcode:
function IDEAMul(X, Y: LongWord): LongWord; assembler;
asm
{$IFDEF CPUX64}
       MOV EAX,ECX
{$ENDIF CPUX64}
       AND EAX,0FFFFh
       JZ @@1
       AND EDX,0FFFFh
       JZ @@1
       MUL EDX
       MOV EDX,EAX
       MOV ECX,EAX
       SHR EDX,16
       SUB EAX,EDX
       SUB CX,AX
       ADC EAX,0
       RET
@@1: LEA EAX,[EAX + EDX - 1]
       NEG EAX
end;


UPDATE:
Und hier die PurePascal Version:
Delphi-Quellcode:
function IDEAMul(X, Y: LongWord): LongWord;
begin
  X := X and $FFFF;
  if X <> 0 then
  begin
    Y := Y and $FFFF;
    if Y <> 0 then
    begin
      X := X * Y;
      Result := X - (X shr 16);
      if Word(X) < Word(Result) then // carry flag check for "sub cx,ax"
        Inc(Result);
      Exit;
    end;
  end;
  Result := -(X + Y - 1);
end;

Assertor 8. Jan 2012 12:33

AW: 256 bit Integer Addition von ASM in PurePascal
 
Nice, Andreas :)

Zitat:

Zitat von jbg (Beitrag 1144884)
Ob das "JC HashingOverflowError" so gut mit der strikten Aufrufkonvention unter x64 vereinbar ist, kann ich jetzt nicht beurteilen, da ich den Code des Sprungziels nicht kenne.

Delphi-Quellcode:
procedure HashingOverflowError;
begin
  raise EDECHashException.CreateRes(@sHashingOverflowError);
end;
Sollte imo also kein Problem sein.

Zitat:

Zitat von jbg (Beitrag 1144884)
Und wenn man schon 64bit Assembler hat kann man den auch gleich verwenden:
Delphi-Quellcode:
procedure Increment8(var Value; Add: LongWord);
asm
  SHL RDX, 3 // the caller writes to EDX what automatically clears the high DWORD of RDX
  ADD QWORD PTR [RCX    ], RDX
  ADC QWORD PTR [RCX +  8], 0
  ADC QWORD PTR [RCX + 16], 0
  ADC QWORD PTR [RCX + 24], 0
  JC HashingOverflowError
end;

Das läuft in x64 Delphi, das RDX Register scheint dem FPC x64 Compiler aber nicht zu gefallen:
Zitat:

Error: Unknown identifier "RDX"
Gleich in der ersten Zeile bei SHL RDX, 3.

Nun gut, ich kenne FPC nicht weiter, möglicherweise ist dies bekannt und über Defines steuerbar. Ggf bleibt dort der Weg über PurePascal, was wegen der breiteren Unterstützung ja mit o.g. Delphi Code möglich ist.

Übrig sind noch gut 9 Assembler Funktionen, bis zur Lauffähigkeit. Wenn keine Einwände bestehen, würde ich diese gerne ebenfalls in diesem Thread zur Diskussion stellen.

@Andreas: Gerade schon ein Ping für Dein IDEAMul Post bekommen. Wow, Du bist schnell :)

Gruß
Assertor

P.S: Das wird eine lange Namensliste im ChangeLog - Attribution to Himitsu, Jaenicke, jbg, NamenLozer (alphabetisch) :)

Assertor 8. Jan 2012 12:55

AW: Der DEC x32 ASM in x64/PurePascal Konvertierungsthread
 
So, weiter geht es (*):
Delphi-Quellcode:
function DoRndBuffer(Seed: Cardinal; var Buffer; Size: Integer): Cardinal; assembler;
// comparable to Borlands Random() function
asm
      AND    EDX,EDX
      JZ     @@2
      AND    ECX,ECX
      JLE    @@2
      PUSH   EBX
@@1: IMUL   EAX,EAX,08088405H // 134775813
      INC    EAX
      MOV    EBX,EAX
      SHR    EBX,24
      MOV    [EDX],BL
      INC    EDX
      DEC    ECX
      JNZ    @@1
      POP    EBX
@@2:
end;

function RandomSystemTime: Cardinal; assembler;
// create Seed from Systemtime and PerformanceCounter
var
  SysTime: record
    Year: Word;
    Month: Word;
    DayOfWeek: Word;
    Day: Word;
    Hour: Word;
    Minute: Word;
    Second: Word;
    MilliSeconds: Word;
    Reserved: array [0..7] of Byte;
  end;
  Counter: record
    Lo,
    Hi: Integer;
  end;
asm
      LEA    EAX,SysTime
      PUSH   EAX
      CALL   GetSystemTime
      MOVZX  EAX,Word Ptr SysTime.Hour
      IMUL   EAX,60
      ADD    AX,SysTime.Minute
      IMUL   EAX,60
      MOVZX  ECX,Word Ptr SysTime.Second
      ADD    EAX,ECX
      IMUL   EAX,1000
      MOV    CX,SysTime.MilliSeconds
      ADD    EAX,ECX
      PUSH   EAX
      LEA    EAX,Counter
      PUSH   EAX
      CALL   QueryPerformanceCounter
      POP    EAX
      ADD    EAX,Counter.Hi
      ADC    EAX,Counter.Lo
end;
Bei RandomSystemTime wird es tricky: QueryPerformanceCounter in RandomSystemTime ist natürlich ein No-Go für Crossplatform, also bleibt nur PurePascal.

Kennt da jemand was, was auch FPC versteht? Wie gesagt, ich arbeite nicht mit FPC, das hier ist nur für die Vielen, die danach fragen... Ich muß erstmal die RTL von XE2 durchsuchen, ob es eine Win/OSX Kapselung gibt.

Falls sich jemand fragt, wie viel noch kommt: die CRC Funktionen (5 an der Zahl).

@Himitsu: Hattest Du nicht schonmal LHSZ für FPC bzw. x64 portiert? Ich meine mich da an irgendwas zu erinnern...

Ihr seid klasse :) Während hier Code gepostet wird, kann ich schon an anderer Stelle weitermachen - so könnte die DEC 6.0 wirklich was werden!

Gruß
Assertor

(*) Kein Edit, für die Benachrichtigung - Andreas hat ja gerade einen Lauf :)

jbg 8. Jan 2012 14:31

AW: Der DEC x32 ASM in x64/PurePascal Konvertierungsthread
 
Also für beide Funktionen ist überhaupt kein Assembler notwendig. Vor allem nicht für DoRndBuffer. Delphi generiert da fast haargenau den selben Assemblercode.
Was aber bei allen PurePascal Funktionen wichtig ist, ist dass {$RANGECHECKS OFF} genutzt wird, da sonst die gewünschten Arithmetiküberläufe zu Exceptions führen.

Delphi-Quellcode:
function RandomSystemTime: Cardinal;
// create Seed from Systemtime and PerformanceCounter
type
  TInt64Rec = packed record
    Lo, Hi: LongWord;
  end;
var
  {$IFDEF MSWINDOWS}
  SysTime: TSystemTime;
  {$ELSE}
  Hour, Minute, Second, Milliseconds: Word;
  {$ENDIF MSWINDOWS}
  Counter: TInt64Rec;
  Time: Cardinal;
begin
  {$IFDEF MSWINDOWS}
  GetSystemTime(SysTime);
  Time := ((Cardinal(SysTime.wHour) * 60 + SysTime.wMinute) * 60 + SysTime.wSecond) * 1000 + SysTime.wMilliseconds;
  QueryPerformanceCounter(Int64(Counter));
  {$ELSE}
  DecodeTime(Now, Hour, Minute, Second, Milliseconds);
  Time := ((Cardinal(Hour) * 60 + Minute) * 60 + Second) * 1000 + Milliseconds;
  Int64(Counter) := TStopwatch.GetTimeStamp; // uses System.Diagnostics
  {$ENDIF MSWINDOWS}

  Result := Time + Counter.Hi;
  Inc(Result, Ord(Result < Time)); // add "carry flag"
  Inc(Result, Counter.Lo);
end;

function DoRndBuffer(Seed: Cardinal; var Buffer; Size: Integer): Cardinal;
// comparable to Borlands Random() function
var
  P: PByte;
begin
  Result := Seed;
  P := @Buffer;
  if P <> nil then
  begin
    while Size > 0 do
    begin
      Result := Result * $08088405 + 1;
      P^ := Byte(Result shr 24);
      Inc(P);
      Dec(Size);
    end;
  end;
end;

himitsu 8. Jan 2012 14:34

AW: Der DEC x32 ASM in x64/PurePascal Konvertierungsthread
 
Zitat:

Zitat von Assertor (Beitrag 1144895)
@Himitsu: Hattest Du nicht schonmal LHSZ für FPC bzw. x64 portiert? Ich meine mich da an irgendwas zu erinnern...

Gute Frage :gruebel:

Selber arbeite ich nicht mit FPC (das Mistding Compilerchen mochte mich nicht ... vonwegen installieren und fertig).

Ich könnte höchsten mal sehn, ob ich noch was (wieder)finde.


Ach ja, mit kleinem h :zwinker:
Ich kenn zwar noch eine Himitsu, aber die hat es nicht so, mit dem Programmieren. :stupid:

Assertor 8. Jan 2012 14:57

AW: Der DEC x32 ASM in x64/PurePascal Konvertierungsthread
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke, Andreas!

Damit komme ich viel weiter, TStopWatch muß ich nur unter FPC ersetzen - aber da findet sich was.

Ich hänge die letzte Datei einfach mal an, dort sind 5 Funktionen zur CRC16/CRC32 Berechnung. Hagen hatte den Code seinerzeit sicherlich auf Performance optimiert.

In PurePascal wird das schon etwas schwieriger...

Zitat:

Zitat von himitsu (Beitrag 1144901)
Zitat:

Zitat von Assertor (Beitrag 1144895)
@Himitsu: Hattest Du nicht schonmal LHSZ für FPC bzw. x64 portiert? Ich meine mich da an irgendwas zu erinnern...

Gute Frage :gruebel:

Selber arbeite ich nicht mit FPC (das Mistding Compilerchen mochte mich nicht ... vonwegen installieren und fertig).

Ich könnte höchsten mal sehn, ob ich noch was (wieder)finde.

Ach ja, mit kleinem h :zwinker:
Ich kenn zwar noch eine Himitsu, aber die hat es nicht so, mit dem Programmieren. :stupid:

Ok, himitsu - ist notiert :oops:

Falls Du die Anpassungen noch hast, gerne her damit. Es steht inzwischen fest, dass ich lediglich die CPU.pas, ASN1.pas und TypInfoEx.pas *nicht* mehr weiterpflege. Diese fliegen raus aus der DEC und werden in ein Tools Archiv verschoben - für den Crypto Einsatz sind diese auch nicht notwendig. Ja, ich weiß. ASN1... Trotzem, nicht für den üblichen DEC Anwender.

Tricky wird dann noch, überall die Kompatibilität herzustellen und zu prüfen (DEC 5.1 <> DEC 6.0), also bitte nicht in den nächsten Wochen mit einem Release rechnen. Ich poste dann, wenn ich Beta Tester suche (x32/x64, C++ Builder, Delphi, FPC, Win, Mac und Linux... puh!).

Viele Grüße
Assertor

Namenloser 8. Jan 2012 15:32

AW: 256 bit Integer Addition von ASM in PurePascal
 
Zitat:

Zitat von jaenicke (Beitrag 1144868)
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.

Nanu, ich dachte für 64-Bit gäbe es gar keinen Inline-Assembler mehr bei Delphi?

jbg 8. Jan 2012 15:43

AW: 256 bit Integer Addition von ASM in PurePascal
 
Zitat:

Zitat von NamenLozer (Beitrag 1144910)
Nanu, ich dachte für 64-Bit gäbe es gar keinen Inline-Assembler mehr bei Delphi?

Doch, den gibt es. Man kann aber keinen Inline-Assembler mit Pascal-Funktionen mischen. Es heißt also entweder PurePascal- oder InlineAssembler-Funktion.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:55 Uhr.
Seite 2 von 7     12 34     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz