Einzelnen Beitrag anzeigen

mathias l.

Registriert seit: 23. Dez 2003
Ort: Bei Hamburg
4 Beiträge
 
#1

SIMD-Dll in asm für Delphi

  Alt 23. Dez 2003, 15:35
Hallo, ich würde gerne für die Berechnung von 4x4-Matrizen in Delphi SIMD (xmm) benutzen. Da ich unter Delphi5 per inline-asm diese Befehle nicht nutzen kann, möchte ich mit dem masm32 eine dll schreiben, die die Funktion "MultMatrix" exportiert. Leider Erhalte ich die Fehlermeldung EPrivileg. Villeicht mag sich ja mal jemand den Code anschauen.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen } 
  public
    { Public-Deklarationen } 
  end;

var
  Form1: TForm1;

function MultMatrix(x, y: Pointer): Pointer; stdcall; external 'test.dll';

implementation

{$R *.DFM} 

procedure TForm1.Button1Click(Sender: TObject);
var
  a,b,c,d: array of single;
  i: Integer;
begin

  setlength(d, 32);
  setlength(a, 16);
  setlength(b, 16);
  setlength(c, 16);

  d[0]:= 1.0; d[1]:= 0.0; d[2]:= 0.0; d[3]:= 0.0;
  d[4]:= 0.0; d[5]:= 1.0; d[6]:= 0.0; d[7]:= 0.0;
  d[8]:= 0.0; d[9]:= 0.0; d[10]:=1.0; d[11]:=0.0;
  d[12]:=0.0; d[13]:=0.0; d[14]:=0.0; d[15]:=1.0;
  d[16]:=1.0; d[17]:=0.0; d[18]:=0.0; d[19]:=0.0;
  d[20]:=0.0; d[21]:=1.0; d[22]:=0.0; d[23]:=0.0;
  d[24]:=0.0; d[25]:=0.0; d[26]:=1.0; d[27]:=0.0;
  d[28]:=0.0; d[29]:=0.0; d[30]:=0.0; d[31]:=1.0;

  for i:=0 to 15 do a[i]:= d[i]; // a ist eine 4x4 Einheitsmatrix
  for i:=0 to 15 do b[i]:= d[i+16]; // b auch. Beide miteinander multipliziert
                                       // sollten wieder ne Einheitsmatrix ergeben.


  c:= MultMatrix(a, b);
end;

end.

Und hier der asm-dll-code:

Code:
.586 
.xmm
.model flat, stdcall
option casemap: none

.data

  m2 dd 16 dup (0.0)

.code

MultMatrix proc ths: DWORD, m1: DWORD    ; Hier sollen 2 Adressen von Matritzen
                               ; (je 16 Single-Werte) übergeben werden
  push edi
  push esi
  push eax
  push edx
 
  mov edi, m1 

  movaps xmm4, [edi]
  movaps xmm5, [edi+16]
  movaps xmm6, [edi+32]
  movaps xmm7, [edi+48]

  mov esi, ths
  mov eax, 0 

  L1:
  movaps xmm0, [esi+eax]
  movaps xmm1, xmm0 
  movaps xmm2, xmm0 
  movaps xmm3, xmm0 

  shufps xmm0, xmm2, 000h
  shufps xmm1, xmm2, 055h
  shufps xmm2, xmm2, 0AAh
  shufps xmm3, xmm3, 0FFh

  mulps xmm0, [edi]
  mulps xmm1, [edi+16]
  mulps xmm2, [edi+32]
  mulps xmm3, [edi+48]

  addps xmm0, xmm1 
  addps xmm0, xmm2 
  addps xmm0, xmm3 
 
  mov edx, eax
  add edx, m2 
  movaps [edx], xmm0 

  add eax, 16 
  cmp eax, 48 
  jle L1 

  mov eax, offset m2           ; m2 enthält die Ergebnis-Matrix

  pop edx
  pop eax
  pop edi
  pop esi

  ret
MultMatrix endp

DllMain proc   hInstDll     :DWORD,
            dwNotification  :DWORD,
            lpReserved     :DWORD
  ret
DllMain endp

end
Insbsondere ist problematisch, das die xmm-SIMD Befehle eine 16Byte-Datenausrichtungen verlangen, aber in Delphi5 hab ich noch keine Direktive gefunden, die das bewerkstelligt.

Vielen Dank
  Mit Zitat antworten Zitat