裏目小僧の部屋でLazarusの話

Lazarusで作ったSIMD関数をDelphiで使う

私が普段使ってるのはDelphi5です。小さな実行ファイルを作ってくれるのが利点です。問題はアセンブラがAVXどころかSSEにも対応してない事。そこで、アセンブラ出力を DB に変換する事を考えました。DelphiのWin64版もAVXに対応してないようですから使えるかもしれないと入れてあります。

  • 説明はいらない Delphiで動くソース寄こせの人は→ AVX_func_delphi.inc(56)
    • MpySumSingle ΣAn*Bn
    • AVXcoffAddShort An:=An+c*Bn
    • Win32とWin64が入っています Delphi5でWin32/Delphi 10.4.2 でWin64双方確認しました。
    • Lazarusでも使えます。Win32/Win64双方確認しました。
    • 自由に使って下さい。ソースの公開も自由です。出来ればリンク元の表示をしてくれたら嬉しいなという程度。
お名前: コメント:

ObjDump.exeを呼びだす

  • Lazarusは ,pas をコンパイルすると .o の拡張子でオブジェクトファイルを作成します
  • この .o を objDump.exeでダンプして DB 命令にしよう
obj dumpの出力はこんな感じ
 e5:	41 83 f9 02          	cmp    $0x2,%r9d
 e9:	7c 09                	jl     f4 <UMYFUNC_$$_AV...
 eb:	0f c6 c9 39          	shufps $0x39,%xmm1,%xmm1
 ef:	f3 0f 11 49 08       	movss  %xmm1,0x8(%rcx)
 f4:	48 8d 65 00          	lea    0x0(%rbp),%rsp
 f8:	5d                   	pop    %rbp              
これを
 @Le5: DB $41,$83,$f9,$02          //cmp    $0x2,%r9d
 @Le9: DB $7c,$09                  //jl    @Lf4
 @Leb: DB $0f,$c6,$c9,$39          //shufps $0x39,%xmm1,%xmm1
 @Lef: DB $f3,$0f,$11,$49,$08      //movss  %xmm1,0x8(%rcx)
 @Lf4: DB $48,$8d,$65,$00          //lea    0x0(%rbp),%rsp
 @Lf8: DB $5d                      //pop    %rbp            
と変換して asm 文の中で使えるようにしようというわけです
左側の@Lはラベルになり分岐命令の分岐先になるので そちらも変更します
なにか修正する場合は 分岐命令のコメントを外しDB命令を削除すれば動かせますからね

 ツールを作った

  • ソースファイル→ ObjDump1.zip(25)
    • LazarusでObjDump1.lprを開き 実行
    • その窓に 拡張子 o のファイルをDrop
    • ObjDump.exeを呼びだすので少し待って下さい
    • 上のような変換された表示がSynEditに表示されます
    • 元の様子が見たいなら 上のチェックボックスで表示入れ替えます
  • Lazarus/FPC配下のObjDumpを呼び出しているので、作ったObjDump1.exeだけでは動きません
    • 外で動かすなら Lazarusをインストールする必要があります
    • Lazarus\FPC\bin\バージョンとかOS\ObjDump.exe とセットにして下さい
    • その場合、objdump.exeのパスを要求されます
    • また ObjDump1の実行で ユーザー領域にFreePascalフォルダが作られます
    • 結果2回目からは パスの入力は不要です

asmで利用時の注意

  • スタックフレームの処理はコメントアウトします
    • 先頭の2〜3行と 後方の2〜3行です
    • 確認方法はブレークポイントを仕掛けて被りを見て下さい
以下の3行はステックフレームの作成で アセンブラ関数でも自動作成されます
@L0: DB $55                     //push   %ebp
@L1: DB $89,$e5                 //mov    %esp,%ebp
@L3: DB $8d,$64,$24,$xx         //lea    -xx(%esp),%esp <--この行は無い場合がある
以下の3行はステックフレームの開放とreturn命令です これも自動作成されます
@Lxx: DB $89,$ec                //mov    %ebp,%esp <--これはWin32だとDelphiで作られないかもしれない
@Lxx: DB $5d                    //pop    %ebp
@Lxx: DB $c2,$xx,$xx            //ret    ${xxxx} win64ならretq だったり色々
  • Win32で アセンブラ文の スタックフレームの処理がLazarusとDelphiで 違うようです
    • よって最終行の上の mov %ebp,%esp はコメントアウトしない方が良いようです
    • Lazarusでは2度同じ命令を実行する事になるので無駄ですが

プライバシーポリシー本文は日本語以外に翻訳禁止 click寄付