AMD64とEM64Tの非互換性

EM64TはAMD64と基本的に互換性があります。ただし、互換性は100%ではありません。

(本記事の初稿は2005年です。10年以上経過した現在でも有用な内容と思われるので、そのままの内容で公開します。)

例えばAMD独自の拡張である3DNow!はEM64Tにはありません。SSE3は初期のAMD64(SledgeHammer/ClawHammer/NewCastle/Winchesterなど)では使えません。(AMD64でのSSE3はVenice/SanDiego(など)以降で利用可能。)
それ以外にも相違点があります。

■LAHF/SAHF

AMD64では64-bit modeでもLAHF/SAHFが使えますが、EM64Tでは使えません。インテルがEM64Tの実装を進める際に拠り所としたAMD64の仕様書が古かったことによるものらしいです。

AMD64のマニュアル(AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions, Rev 3.09)を見ると、どちらも記載があって、利用可能となっていますが、EM64Tのマニュアル(Intel Extended Memory 64 Technology Software Developers Guide Rev 1.1)を見ると、「Invalid in 64-bit mode」(64ビットモードでは無効)となっています。無理に実行しようとすると、#UDのExceptionが発生することになります。(Windows上で実行しようとすると、「不正な処理をしました」みたいになるのでしょう。)

LAHF/SAHFのいずれも他の命令で代替できるので、困ることはないでしょう。でも、なんでAMDはこれらの命令を最初外したのでしょう?「8080の名残を残しているだけで、x87命令の補助程度にしか使い道がない」とでも考えたのでしょうか?x86の継承なのだから、(現在では盲腸のような存在であるものの)こういった命令もきっちり実装してくれなくては。

(追記)改訂されたAMD64のマニュアル(AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions, Rev 3.10)を見ると、「64ビットモードでのLAHF/SAHFサポートは、CPUのフィーチャーフラグ(EAX=8000_0001hでCPUIDを実行した時のECXのbit0)を見よ」となっています。bit0=0なら未サポート、bit0=1ならサポート有となるわけです。AMD64側がEM64Tに歩み寄る余地を持たせたように思われます。ちなみにVeniceコアのAthlon64では、bit0=1すなわち「64ビットモードでのLAHF/SAHFサポートは有り」となっています。

(追記)インテルのマニュアル(IA-32 Intel Architecture and Intel Extended Memory 64 Technology Software Developer’s Manual Documentation Changes, March 2005)によれば、インテルもEM64Tの64ビットモードでのLAHF/SAHFをサポートしてしまったようです。(“LAHF/SAHF are now enabled on some 64-Bit steppings.”)さらに読み進めると、「LAHF/SAHFサポートの有無はCPUのフィーチャーフラグを見よ」となっています。(フィーチャーフラグの場所はAMD64と同じ)EM64TはAMD64に歩み寄ったと言えそうです。

ここまで来れば「LAHF/SAHFにおけるAMD64とEM64Tの非互換性は解消された」と言って差し支えないでしょう。(AMDの対応は予想できたものの、インテルが歩み寄ることまでは予想できなかった。)

■FFXSR bit (FXSAVE/FXRSTOR)

AMD64のEFER(Extended Feature Enable Register)には、下記のようにFFXSR bit(Fast FXSAVE/FXRSTOR bit)があります。このビットを立てると、CPL=0かつ64bit modeでFXSAVE/FXRSTORを実行する際にXMMレジスタ(XMM0-XMM15)のセーブ・リストアを行わなくなります。(CR4レジスタのOSFXSR bit(FXSAVE/FXRSTOR Support bit)とは別です。)

EM64Tでは、EFERに対応するレジスタをIA32_EFER(Extended Feature Enable MSR)と呼びますが、AMD64のFFXSR bitに相当するものが、EM64TのIA32_EFERにはなぜかありません。

AMD64ではFast FXSAVE/FXRSTORができるが、EM64TではFast FXSAVE/FXRSTORができないということになります。(EM64Tのマニュアルが古いだけのような気もしますが。)

■NX bit

AMD64では全モデルでNX bitがサポートされていますが、EM64Tでは最初期のプロセッサではサポートされていません。Pentium4 3.20F/3.40F/3.60F/3.80F GHz(Pentium4 6xx以前に存在したEM64T対応Pentium4)ではサポートされていないものの、Pentium4 6xxよりExecute Disable Bit(略してXD bit)としてサポートされています。ただしインテルのEM64Tのマニュアル(Rev. 1.1)にはXD bitについての記載がありません。

■CMPXCHG16B

CMPXCHG16BはEM64Tにしかありません。AMD64にはありません。(AMD64のマニュアルに記載そのものがない。)
この命令の有無は、EAX=1hでCPUID命令を実行した時のECXレジスタのbit13に示されます。

(追記)改訂されたAMD64のマニュアル(AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions, Rev 3.10)を見ると、CMPXCHG16Bについての記述が追加されています。ただし、「CMPXCHG16BのサポートはCPUの実装に依存する。サポートの有無はCPUのフィーチャーフラグを見よ」となっています。(フィーチャーフラグの場所はEM64Tと同じ。)AMD64側がEM64Tに歩み寄る余地を確保したと言えるでしょう。
ちなみにNewCastle/VeniceコアのAthlon64ではbit13=0、すなわちCMPXCHG16Bは未サポートとなっています。

ところで、CMPXCHG8Bの説明を見比べると、AMD64では「実効オペランドサイズが64-bitでない時にCMPXCHG8Bを実行すると#UDを生成する」となっていますが、EM64Tにはこのような記述がありません。非互換性というよりもEM64Tの記述が不充分なだけのような気がしますが、念のためメモしておきます。

■SYSCALL/SYSRET

SYSCALL/SYSRETはAMD64では(Long mode下の)64-bit mode, Compatibility mode, 及びLegacy modeで使えますが、EM64Tでは(IA-32e mode下の)64-bit modeでしか使えません。(Compatibility mode, 及びLegacy modeでは、#UDになってしまう。)

■SYSENTER/SYSEXIT

逆にSYSENTER/SYSEXITはAMD64では, Long mode下の64-bit mode, Compatibility modeにおいて使えませんが、
EM64TではIA-32e mode下の64-bit mode, Compatibility modeでも使えます。(当然のことながらLegacy modeでは、AMD64/EM64Tのいずれにおいても使える。)64-bitにおいてAMDはSYSCALL/SYSEXITを推し、一方インテルはSYSENTER/SYSEXITにこだわっているように見え、AMDとインテルとの確執めいたものを感じますが、真相はいかに?


起草日:2005年5月8日(日)(www.marbacka.net内の別のサイトで公開)
最終更新日:2017年2月19日(日)

スポンサーリンク