Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 14573] ファイルの概要

このコミットは、Go言語のアセンブラツール cmd/8a において、XMMレジスタのサポートを追加するものです。具体的には、アセンブラの構文解析器(パーサー)と字句解析器(レキサー)がXMMレジスタを認識し、それらを使用する命令を適切に処理できるように変更されています。また、Bisonのバージョンが2.4.1から2.6.5に更新されています。

コミット

commit 755e13877f390253f8937a277e4929eac6610484
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date:   Thu Dec 6 07:27:38 2012 +0100

    cmd/8a: support XMM registers.
    
    R=rsc, golang-dev
    CC=golang-dev
    https://golang.org/cl/6884046

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/755e13877f390253f8937a277e4929eac6610484

元コミット内容

cmd/8a: support XMM registers.

R=rsc, golang-dev
CC=golang-dev
https://golang.org/cl/6884046

変更の背景

この変更の背景には、Go言語がx86アーキテクチャ、特に64ビット環境での浮動小数点演算やSIMD(Single Instruction, Multiple Data)命令のサポートを強化する必要があったことが挙げられます。XMMレジスタは、IntelのSSE(Streaming SIMD Extensions)命令セットで使用される128ビットレジスタであり、単一の命令で複数のデータ要素(例えば、複数の浮動小数点数)を並列に処理する能力を提供します。

cmd/8a はGo言語のツールチェインの一部であり、x86アーキテクチャ向けのアセンブラです。Goのコンパイラが生成するアセンブリコードや、手書きのアセンブリコードを機械語に変換する役割を担っています。XMMレジスタのサポートがなければ、GoプログラムはSSE命令を直接利用できず、パフォーマンスが重要な数値計算やメディア処理などの分野で最適化の機会を逸することになります。

また、Bisonのバージョンアップは、パーサー生成ツールの改善やバグ修正を取り込むための一般的なメンテナンス作業と考えられます。古いバージョンのBisonで生成されたコードには、新しいバージョンで修正された問題が含まれている可能性があり、ツールチェイン全体の安定性と信頼性を向上させる目的があったと推測されます。

前提知識の解説

x86アーキテクチャとレジスタ

x86アーキテクチャは、Intelが開発したマイクロプロセッサの命令セットアーキテクチャです。PCやサーバーで広く利用されており、時代とともに拡張されてきました。レジスタはCPU内部にある高速な記憶領域で、CPUがデータを一時的に保持したり、演算を行ったりする際に使用します。

浮動小数点演算とSIMD

  • 浮動小数点演算: 小数点を含む数値を扱う演算です。科学技術計算、グラフィックス、ゲームなどで不可欠です。
  • SIMD (Single Instruction, Multiple Data): 単一の命令で複数のデータ要素に対して同じ操作を同時に実行する並列処理の形態です。これにより、大量のデータを効率的に処理できます。

SSE (Streaming SIMD Extensions)

Intelが開発したSIMD命令セットの拡張機能です。SSEは、浮動小数点演算のパフォーマンス向上と、メディア処理などのデータ並列処理を目的として導入されました。SSE命令は、専用の128ビットレジスタであるXMMレジスタを使用します。

XMMレジスタ

XMM0からXMM7(64ビットモードではXMM0からXMM15)までの128ビットレジスタです。これらのレジスタは、単精度浮動小数点数(32ビット)を4つ、倍精度浮動小数点数(64ビット)を2つ、または整数(8ビット、16ビット、32ビット、64ビット)を複数格納できます。SSE命令はこれらのXMMレジスタを操作して、並列演算を実行します。

アセンブラ (cmd/8a)

Go言語のツールチェインに含まれるアセンブラの一つで、x86アーキテクチャ(32ビットおよび64ビット)向けのアセンブリコードを機械語に変換します。Go言語のコンパイラは、最終的なバイナリを生成する過程でこのアセンブラを利用します。

Bison (GNU Bison)

Bisonは、文法定義から構文解析器(パーサー)を生成するツールです。Yacc(Yet Another Compiler Compiler)のGNU版であり、プログラミング言語のコンパイラやインタプリタのフロントエンド部分を開発する際に広く利用されます。文法規則を記述したファイル(通常は .y 拡張子)をBisonに与えると、C言語などのソースコード(通常は y.tab.c)が生成されます。

字句解析器 (Lexer/Scanner)

字句解析器は、入力されたソースコードをトークン(意味のある最小単位)の並びに分解する役割を担います。例えば、int x = 10; というコードは、int(キーワード)、x(識別子)、=(演算子)、10(整数リテラル)、;(区切り文字)といったトークンに分解されます。通常、Lex(またはFlex)のようなツールが字句解析器を生成します。

技術的詳細

このコミットの技術的詳細は、主にcmd/8aのアセンブラがXMMレジスタとそれに関連する命令をどのように認識し、処理するように変更されたかにあります。

  1. a.y (Bison文法定義ファイル) の変更:

    • %token <lval> LXREG の追加: これは、XMMレジスタを表す新しいトークン LXREG を定義しています。<lval> は、このトークンに関連付けられる値の型を示しており、おそらくレジスタのインデックスなどを格納するために使用されます。
    • reg: ルールに | LXREG の追加: これにより、アセンブリコード内でXMMレジスタがレジスタとして認識されるようになります。$$ = nullgen; $$.type = $1; は、構文解析ツリー内でXMMレジスタの型情報を設定するアクションです。
  2. lex.c (字句解析器のソースファイル) の変更:

    • XMMレジスタ名(X0からX7)とそれに対応するトークンタイプ LXREG、およびレジスタ番号(D_X0+0からD_X0+7)のマッピングが追加されています。これにより、字句解析器がアセンブリコード中の X0, X1, ... X7LXREG トークンとして正しく識別できるようになります。
  3. y.tab.c および y.tab.h (Bison生成ファイル) の変更:

    • Bisonのバージョンが2.4.1から2.6.5に更新されたことにより、これらのファイルの内容が大幅に変更されています。これは、Bisonの内部実装や生成されるコードの構造がバージョン間で異なるためです。
    • LXREG トークンの追加に伴い、トークン番号の定義(#define LXREG 281 など)や、yytname 配列(デバッグ時にトークン名を文字列で表示するための配列)に LXREG が追加されています。
    • YYNRULES (ルールの数) や YYNTOKENS (トークンの数) など、パーサーの内部定数が更新されています。これは、新しいトークンと文法ルールが追加されたためです。
    • y.tab.c 内のBisonランタイムコードも、新しいBisonバージョンに合わせて更新されています。これには、エラー処理、スタック管理、メモリ割り当てなどの変更が含まれる可能性があります。

これらの変更により、cmd/8a はアセンブリコード内で X0, X1, ... X7 といったXMMレジスタを認識し、それらを使用する命令(例: MOVSD X0, X1)を正しく構文解析できるようになります。これは、Go言語がSSE命令を利用した高性能なコードを生成・実行するための基盤となります。

コアとなるコードの変更箇所

src/cmd/8a/a.y

--- a/src/cmd/8a/a.y
+++ b/src/cmd/8a/a.y
@@ -55,7 +55,7 @@
 %token	<lval>	LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
 %token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG LTYPEXC
 %token	<lval>	LCONST LFP LPC LSB
-%token	<lval>	LBREG LLREG LSREG LFREG
+%token	<lval>	LBREG LLREG LSREG LFREG LXREG
 %token	<dval>	LFCONST
 %token	<sval>	LSCONST LSP
 %token	<sym>	LNAME LLAB LVAR
@@ -359,6 +359,11 @@ reg:
 		$$ = nullgen;
 		$$.type = $1;
 	}
+|\tLXREG
+\t{
+\t\t$$ = nullgen;
+\t\t$$.type = $1;
+\t}
 |\tLSP
 	{
 		$$ = nullgen;

src/cmd/8a/lex.c

--- a/src/cmd/8a/lex.c
+++ b/src/cmd/8a/lex.c
@@ -210,6 +210,15 @@ struct
 	"F6",		LFREG,	D_F0+6,
 	"F7",		LFREG,	D_F0+7,
 
+	"X0",		LXREG,	D_X0+0,
+	"X1",		LXREG,	D_X0+1,
+	"X2",		LXREG,	D_X0+2,
+	"X3",		LXREG,	D_X0+3,
+	"X4",		LXREG,	D_X0+4,
+	"X5",		LXREG,	D_X0+5,
+	"X6",		LXREG,	D_X0+6,
+	"X7",		LXREG,	D_X0+7,
+
 	"CS",		LSREG,	D_CS,
 	"SS",		LSREG,	D_SS,
 	"DS",		LSREG,	D_DS,

src/cmd/8a/y.tab.c および src/cmd/8a/y.tab.h

これらのファイルはBisonによって自動生成されるため、変更内容はBisonのバージョンアップと新しいトークン LXREG の追加によって発生したものです。具体的な差分は非常に大きいため、ここでは省略しますが、主に以下の点が変更されています。

  • Bisonのバージョン情報が2.4.1から2.6.5に更新。
  • LXREG トークンに対応する内部定数(トークン番号)の追加。
  • パーサーの内部テーブル(yypact, yytable, yycheck, yyrhs, yyr1, yyr2 など)の再生成。
  • Bisonランタイムコードの更新。

コアとなるコードの解説

src/cmd/8a/a.y

このファイルは、cmd/8a アセンブラの構文を定義するBisonの文法ファイルです。

  • %token <lval> LXREG の行は、LXREG という新しいトークンを定義しています。このトークンは、XMMレジスタを表すために使用されます。<lval> は、このトークンが構文解析中に保持する値の型を指定します。
  • reg: ルールは、アセンブリ命令のオペランドとして使用できるレジスタの種類を定義しています。ここに | LXREG が追加されたことで、XMMレジスタも有効なレジスタとして認識されるようになりました。
  • $$ = nullgen; $$.type = $1; は、LXREG トークンが認識されたときに実行されるアクションです。nullgen はおそらくジェネレータの初期状態を表し、$$.type = $1; は、認識されたXMMレジスタの型(LXREG の値)を構文解析ツリーの対応するノードに設定します。

src/cmd/8a/lex.c

このファイルは、cmd/8a アセンブラの字句解析器の定義を含んでいます。

  • 追加されたブロックは、XMMレジスタの名前(X0からX7)と、それらに対応するトークンタイプ LXREG、そして内部的なレジスタ番号(D_X0+0からD_X0+7)をマッピングしています。
  • 字句解析器は、入力されたアセンブリコードを読み込み、これらの定義に基づいて X0 などの文字列を LXREG トークンとして識別し、対応するレジスタ番号を構文解析器に渡します。

これらの変更により、cmd/8a はXMMレジスタをアセンブリコードの有効な要素として認識し、それらを命令のオペランドとして使用できるようになります。これは、Go言語がx86アーキテクチャのSIMD機能を活用するための重要なステップです。

関連リンク

参考にした情報源リンク

  • Go言語の公式リポジトリ: https://github.com/golang/go
  • Bisonのバージョン履歴や変更点に関する情報(Bisonのリリースノートやメーリングリストのアーカイブを参照)
  • x86アーキテクチャ、SIMD、SSE、XMMレジスタに関する一般的なコンピュータアーキテクチャの資料やオンラインリソース。
  • Go言語のコードレビューシステム (Gerrit) の変更リスト: https://golang.org/cl/6884046

[インデックス 14573] ファイルの概要

このコミットは、Go言語のアセンブラツール cmd/8a において、XMMレジスタのサポートを追加するものです。具体的には、アセンブラの構文解析器(パーサー)と字句解析器(レキサー)がXMMレジスタを認識し、それらを使用する命令を適切に処理できるように変更されています。また、Bisonのバージョンが2.4.1から2.6.5に更新されています。

コミット

commit 755e13877f390253f8937a277e4929eac6610484
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date:   Thu Dec 6 07:27:38 2012 +0100

    cmd/8a: support XMM registers.
    
    R=rsc, golang-dev
    CC=golang-dev
    https://golang.org/cl/6884046

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/755e13877f390253f8937a277e4929eac6610484

元コミット内容

cmd/8a: support XMM registers.

R=rsc, golang-dev
CC=golang-dev
https://golang.org/cl/6884046

変更の背景

この変更の背景には、Go言語がx86アーキテクチャ、特に64ビット環境での浮動小数点演算やSIMD(Single Instruction, Multiple Data)命令のサポートを強化する必要があったことが挙げられます。XMMレジスタは、IntelのSSE(Streaming SIMD Extensions)命令セットで使用される128ビットレジスタであり、単一の命令で複数のデータ要素(例えば、複数の浮動小数点数)を並列に処理する能力を提供します。

cmd/8a はGo言語のツールチェインの一部であり、x86アーキテクチャ向けのアセンブラです。Goのコンパイラが生成するアセンブリコードや、手書きのアセンブリコードを機械語に変換する役割を担っています。XMMレジスタのサポートがなければ、GoプログラムはSSE命令を直接利用できず、パフォーマンスが重要な数値計算やメディア処理などの分野で最適化の機会を逸することになります。

また、Bisonのバージョンアップは、パーサー生成ツールの改善やバグ修正を取り込むための一般的なメンテナンス作業と考えられます。古いバージョンのBisonで生成されたコードには、新しいバージョンで修正された問題が含まれている可能性があり、ツールチェイン全体の安定性と信頼性を向上させる目的があったと推測されます。

前提知識の解説

x86アーキテクチャとレジスタ

x86アーキテクチャは、Intelが開発したマイクロプロセッサの命令セットアーキテクチャです。PCやサーバーで広く利用されており、時代とともに拡張されてきました。レジスタはCPU内部にある高速な記憶領域で、CPUがデータを一時的に保持したり、演算を行ったりする際に使用します。

浮動小数点演算とSIMD

  • 浮動小数点演算: 小数点を含む数値を扱う演算です。科学技術計算、グラフィックス、ゲームなどで不可欠です。
  • SIMD (Single Instruction, Multiple Data): 単一の命令で複数のデータ要素に対して同じ操作を同時に実行する並列処理の形態です。これにより、大量のデータを効率的に処理できます。

SSE (Streaming SIMD Extensions)

Intelが開発したSIMD命令セットの拡張機能です。SSEは、浮動小数点演算のパフォーマンス向上と、メディア処理などのデータ並列処理を目的として導入されました。SSE命令は、専用の128ビットレジスタであるXMMレジスタを使用します。

XMMレジスタ

XMM0からXMM7(64ビットモードではXMM0からXMM15)までの128ビットレジスタです。これらのレジスタは、単精度浮動小数点数(32ビット)を4つ、倍精度浮動小数点数(64ビット)を2つ、または整数(8ビット、16ビット、32ビット、64ビット)を複数格納できます。SSE命令はこれらのXMMレジスタを操作して、並列演算を実行します。XMMレジスタは、古いMMXレジスタとは異なり、x87 FPUレジスタとエイリアスしないため、浮動小数点演算と同時に使用することが容易です。

アセンブラ (cmd/8a)

Go言語のツールチェインに含まれるアセンブラの一つで、x86アーキテクチャ(32ビットおよび64ビット)向けのアセンブリコードを機械語に変換します。Go言語のコンパイラは、最終的なバイナリを生成する過程でこのアセンブラを利用します。

Bison (GNU Bison)

Bisonは、文法定義から構文解析器(パーサー)を生成するツールです。Yacc(Yet Another Compiler Compiler)のGNU版であり、プログラミング言語のコンパイラやインタプリタのフロントエンド部分を開発する際に広く利用されます。文法規則を記述したファイル(通常は .y 拡張子)をBisonに与えると、C言語などのソースコード(通常は y.tab.c)が生成されます。

字句解析器 (Lexer/Scanner)

字句解析器は、入力されたソースコードをトークン(意味のある最小単位)の並びに分解する役割を担います。例えば、int x = 10; というコードは、int(キーワード)、x(識別子)、=(演算子)、10(整数リテラル)、;(区切り文字)といったトークンに分解されます。通常、Lex(またはFlex)のようなツールが字句解析器を生成します。

技術的詳細

このコミットの技術的詳細は、主にcmd/8aのアセンブラがXMMレジスタとそれに関連する命令をどのように認識し、処理するように変更されたかにあります。

  1. a.y (Bison文法定義ファイル) の変更:

    • %token <lval> LXREG の追加: これは、XMMレジスタを表す新しいトークン LXREG を定義しています。<lval> は、このトークンに関連付けられる値の型を示しており、おそらくレジスタのインデックスなどを格納するために使用されます。
    • reg: ルールに | LXREG の追加: これにより、アセンブリコード内でXMMレジスタがレジスタとして認識されるようになります。$$ = nullgen; $$.type = $1; は、構文解析ツリー内でXMMレジスタの型情報を設定するアクションです。
  2. lex.c (字句解析器のソースファイル) の変更:

    • XMMレジスタ名(X0からX7)とそれに対応するトークンタイプ LXREG、およびレジスタ番号(D_X0+0からD_X0+7)のマッピングが追加されています。これにより、字句解析器がアセンブリコード中の X0, X1, ... X7LXREG トークンとして正しく識別できるようになります。
  3. y.tab.c および y.tab.h (Bison生成ファイル) の変更:

    • Bisonのバージョンが2.4.1から2.6.5に更新されたことにより、これらのファイルの内容が大幅に変更されています。これは、Bisonの内部実装や生成されるコードの構造がバージョン間で異なるためです。
    • LXREG トークンの追加に伴い、トークン番号の定義(#define LXREG 281 など)や、yytname 配列(デバッグ時にトークン名を文字列で表示するための配列)に LXREG が追加されています。
    • YYNRULES (ルールの数) や YYNTOKENS (トークンの数) など、パーサーの内部定数が更新されています。これは、新しいトークンと文法ルールが追加されたためです。
    • y.tab.c 内のBisonランタイムコードも、新しいBisonバージョンに合わせて更新されています。これには、エラー処理、スタック管理、メモリ割り当てなどの変更が含まれる可能性があります。

これらの変更により、cmd/8a はアセンブリコード内で X0, X1, ... X7 といったXMMレジスタを認識し、それらを使用する命令(例: MOVSD X0, X1)を正しく構文解析できるようになります。これは、Go言語がSSE命令を利用した高性能なコードを生成・実行するための基盤となります。

コアとなるコードの変更箇所

src/cmd/8a/a.y

--- a/src/cmd/8a/a.y
+++ b/src/cmd/8a/a.y
@@ -55,7 +55,7 @@
 %token	<lval>	LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
 %token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG LTYPEXC
 %token	<lval>	LCONST LFP LPC LSB
-%token	<lval>	LBREG LLREG LSREG LFREG
+%token	<lval>	LBREG LLREG LSREG LFREG LXREG
 %token	<dval>	LFCONST
 %token	<sval>	LSCONST LSP
 %token	<sym>	LNAME LLAB LVAR
@@ -359,6 +359,11 @@ reg:
 		$$ = nullgen;
 		$$.type = $1;
 	}
+|\tLXREG
+\t{
+\t\t$$ = nullgen;
+\t\t$$.type = $1;
+\t}
 |\tLSP
 	{
 		$$ = nullgen;

src/cmd/8a/lex.c

--- a/src/cmd/8a/lex.c
+++ b/src/cmd/8a/lex.c
@@ -210,6 +210,15 @@ struct
 	"F6",		LFREG,	D_F0+6,
 	"F7",		LFREG,	D_F0+7,
 
+	"X0",		LXREG,	D_X0+0,
+	"X1",		LXREG,	D_X0+1,
+	"X2",		LXREG,	D_X0+2,
+	"X3",		LXREG,	D_X0+3,
+	"X4",		LXREG,	D_X0+4,
+	"X5",		LXREG,	D_X0+5,
+	"X6",		LXREG,	D_X0+6,
+	"X7",		LXREG,	D_X0+7,
+
 	"CS",		LSREG,	D_CS,
 	"SS",		LSREG,	D_SS,
 	"DS",		LSREG,	D_DS,

src/cmd/8a/y.tab.c および src/cmd/8a/y.tab.h

これらのファイルはBisonによって自動生成されるため、変更内容はBisonのバージョンアップと新しいトークン LXREG の追加によって発生したものです。具体的な差分は非常に大きいため、ここでは省略しますが、主に以下の点が変更されています。

  • Bisonのバージョン情報が2.4.1から2.6.5に更新。
  • LXREG トークンに対応する内部定数(トークン番号)の追加。
  • パーサーの内部テーブル(yypact, yytable, yycheck, yyrhs, yyr1, yyr2 など)の再生成。
  • Bisonランタイムコードの更新。

コアとなるコードの解説

src/cmd/8a/a.y

このファイルは、cmd/8a アセンブラの構文を定義するBisonの文法ファイルです。

  • %token <lval> LXREG の行は、LXREG という新しいトークンを定義しています。このトークンは、XMMレジスタを表すために使用されます。<lval> は、このトークンが構文解析中に保持する値の型を指定します。
  • reg: ルールは、アセンブリ命令のオペランドとして使用できるレジスタの種類を定義しています。ここに | LXREG が追加されたことで、XMMレジスタも有効なレジスタとして認識されるようになりました。
  • $$ = nullgen; $$.type = $1; は、LXREG トークンが認識されたときに実行されるアクションです。nullgen はおそらくジェネレータの初期状態を表し、$$.type = $1; は、認識されたXMMレジスタの型(LXREG の値)を構文解析ツリーの対応するノードに設定します。

src/cmd/8a/lex.c

このファイルは、cmd/8a アセンブラの字句解析器の定義を含んでいます。

  • 追加されたブロックは、XMMレジスタの名前(X0からX7)と、それらに対応するトークンタイプ LXREG、そして内部的なレジスタ番号(D_X0+0からD_X0+7)をマッピングしています。
  • 字句解析器は、入力されたアセンブリコードを読み込み、これらの定義に基づいて X0 などの文字列を LXREG トークンとして識別し、対応するレジスタ番号を構文解析器に渡します。

これらの変更により、cmd/8a はXMMレジスタをアセンブリコードの有効な要素として認識し、それらを命令のオペランドとして使用できるようになります。これは、Go言語がx86アーキテクチャのSIMD機能を活用するための重要なステップです。

関連リンク

参考にした情報源リンク

  • Go言語の公式リポジトリ: https://github.com/golang/go
  • Bisonのバージョン履歴や変更点に関する情報(Bisonのリリースノートやメーリングリストのアーカイブを参照)
  • x86アーキテクチャ、SIMD、SSE、XMMレジスタに関する一般的なコンピュータアーキテクチャの資料やオンラインリソース。
  • Go言語のコードレビューシステム (Gerrit) の変更リスト: https://golang.org/cl/6884046