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

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

このコミットは、GoランタイムのARMアセンブリコードにおけるフォーマットの修正を目的としています。具体的には、アセンブリ命令のオペランド間の区切り文字として、スペースではなくタブを使用するように統一することで、コードの可読性と一貫性を向上させています。

コミット

commit 92254d4463efb5c3a91ccd6d62abe3f7587a145a
Author: Dmitriy Vyukov <dvyukov@google.com>
Date:   Mon Aug 12 21:36:33 2013 +0400

    runtime: fix ARM assembly formatting
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/12702048

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

https://github.com/golang/go/commit/92254d4463efb5c3a91ccd6d62abe3f7587a145a

元コミット内容

runtime: fix ARM assembly formatting

このコミットは、GoランタイムのARMアセンブリコードにおけるフォーマットの不整合を修正します。

変更の背景

ソフトウェア開発において、コードのフォーマットの一貫性は非常に重要です。特にアセンブリ言語のような低レベルのコードでは、命令とオペランドの区切り方一つで可読性が大きく変わります。このコミットが行われた2013年当時、GoのARMアセンブリコードには、命令とオペランドの間、あるいはオペランド同士の区切りにスペースとタブが混在している箇所がありました。このような不統一は、コードレビューを困難にし、将来的なコードの自動整形ツールやリンターの導入の妨げとなる可能性があります。

この変更の背景には、Goプロジェクト全体でのコード品質と保守性の向上という目標があります。アセンブリコードは特定のアーキテクチャに依存し、デバッグが困難な場合が多いため、その可読性を高めることは、バグの発見や修正、新しい機能の追加を容易にする上で不可欠です。このコミットは、そのような品質向上の一環として、ARMアセンブリコードのフォーマットを統一し、よりクリーンで一貫性のあるコードベースを目指すものです。

前提知識の解説

ARMアセンブリ言語

ARMアセンブリ言語は、ARMアーキテクチャのプロセッサ上で実行される機械語命令を人間が読める形式で記述したものです。ARMは、スマートフォン、タブレット、組み込みシステムなど、幅広いデバイスで利用されているRISC(Reduced Instruction Set Computer)ベースのCPUアーキテクチャです。

アセンブリ言語のコードは、通常、以下のような構造を持っています。

命令 オペランド1, オペランド2, ...

例: MOVW R0, R1 (R1レジスタの値をR0レジスタに移動する)

このコミットで問題となっているのは、命令オペランドの間、またはオペランド同士の区切りに、スペースとタブが混在していた点です。

Goランタイム

Goランタイムは、Goプログラムの実行を管理する低レベルのコンポーネント群です。これには、ガベージコレクタ、スケジューラ、メモリ管理、システムコールインターフェースなどが含まれます。Goはクロスプラットフォーム言語であり、様々なCPUアーキテクチャ(x86, ARM, MIPSなど)をサポートしています。

Goランタイムの一部は、パフォーマンスが非常に重要であったり、ハードウェアに直接アクセスする必要があるため、C言語やアセンブリ言語で記述されています。ARMアセンブリコードは、ARMアーキテクチャ上でGoプログラムが効率的に動作するために、特に重要な部分(例えば、コンテキストスイッチ、アトミック操作、システムコールなど)で使用されます。

コードフォーマットと可読性

プログラミングにおいて、コードのフォーマット(インデント、スペース、タブ、改行などの使い方)は、コードの可読性に直接影響します。一貫性のあるフォーマットは、コードを理解しやすくし、エラーを見つけにくくします。特に、複数の開発者が関わる大規模なプロジェクトでは、フォーマットの統一は必須です。

このコミットでは、アセンブリコードにおける命令とオペランドの間の区切り文字をスペースからタブに統一しています。これは、視覚的なアライメントを改善し、コードの構造をより明確にする効果があります。

技術的詳細

このコミットの技術的な変更は非常にシンプルですが、その影響はコードの可読性において重要です。変更の核心は、ARMアセンブリコード内の命令とオペランド、またはオペランド間の区切りに使用されていた複数のスペースを単一のタブ文字(\t)に置き換えることです。

具体的には、以下のパターンが修正されています。

  • 命令 オペランド -> 命令\tオペランド
  • オペランド, オペランド -> オペランド,\tオペランド

例えば、元のコードでは以下のような行がありました。

WORD    $0xe1200071 // BKPT 0x0001

これが、コミットによって以下のように変更されています。

WORD\t$0xe1200071\t// BKPT 0x0001

同様に、条件分岐命令やアトミック操作に関連する命令でも、スペースがタブに置き換えられています。

// 変更前
CMP		R0, R2
BNE		casfail

// 変更後
CMP\tR0, R2
BNE\tcasfail

この変更は、アセンブリコードの構文解析には影響を与えません。アセンブラは通常、複数のスペースやタブを単一の区切り文字として扱います。しかし、人間がコードを読む際には、タブによる整列は視覚的に命令とオペランドの境界を明確にし、コードの構造を把握しやすくします。特に、コメントが命令の後に続く場合、タブを使用することでコメントの位置が揃いやすくなり、全体的なコードの「見た目」が改善されます。

この種のフォーマット修正は、コードの機能には影響を与えませんが、長期的な保守性と開発者の体験を向上させる上で重要な「クリーンアップ」作業と見なされます。

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

このコミットによって変更されたファイルは以下の通りです。

  • src/pkg/runtime/asm_arm.s
  • src/pkg/runtime/sys_linux_arm.s
  • src/pkg/sync/atomic/asm_linux_arm.s

これらのファイルはすべて、Goランタイムおよび標準ライブラリの一部として、ARMアーキテクチャ向けのアセンブリコードを含んでいます。

具体的な変更行は以下の通りです(一部抜粋)。

src/pkg/runtime/asm_arm.s

  • WORD $0xe1200071 // BKPT 0x0001 -> WORD\t$0xe1200071\t// BKPT 0x0001
  • MOVW runtime·goarm(SB), R11 -> MOVW\truntime·goarm(SB), R11
  • CMP $5, R11 -> CMP\t$5, R11
  • BLE 4(PC) -> BLE\t4(PC)
  • WORD $0xeef1ba10 // vmrs r11, fpscr -> WORD\t$0xeef1ba10\t// vmrs r11, fpscr
  • BIC $(1<<24), R11 -> BIC\t$(1<<24), R11
  • WORD $0xeee1ba10 // vmsr fpscr, r11 -> WORD\t$0xeee1ba10\t// vmsr fpscr, r11
  • B.NE havem -> B.NE\thavem
  • CMP R0, R2 -> CMP\tR0, R2
  • BNE casfail -> BNE\tcasfail
  • CMP $0, R0 -> CMP\t$0, R0
  • BNE casl -> BNE\tcasl

src/pkg/runtime/sys_linux_arm.s

  • MOVW $1, R0 -> MOVW\t$1, R0
  • MOVW $0, R0 -> MOVW\t$0, R0
  • SWI $0 -> SWI\t$0

src/pkg/sync/atomic/asm_linux_arm.s

  • BL cas<>(SB) -> BL\tcas<>(SB)
  • BL cas64<>(SB) -> BL\tcas64<>(SB)
  • CMP $6, R0 // TODO(minux): how to differentiate ARMv6 with ARMv6K? -> CMP\t$6, R0 // TODO(minux): how to differentiate ARMv6 with ARMv6K?
  • B setupAndCallCAS64<>(SB) -> B\tsetupAndCallCAS64<>(SB)

コアとなるコードの解説

変更されたコードは、主にARMアセンブリ命令のフォーマットに関するものです。機能的な変更は一切なく、命令のオペランド間の区切り文字がスペースからタブに統一されています。

例えば、src/pkg/runtime/asm_arm.sruntime·breakpoint 関数内の以下の行を見てみましょう。

// 変更前
WORD    $0xe1200071 // BKPT 0x0001

// 変更後
WORD\t$0xe1200071\t// BKPT 0x0001
  • WORD: 32ビットのワードを定義する擬似命令。
  • $0xe1200071: 定義されるワードの値。これはARMのBKPT(Breakpoint)命令のエンコードされた値です。
  • // BKPT 0x0001: コメント。

変更前はWORD$0xe1200071の間に複数のスペースがありましたが、変更後はタブ(\t)に置き換えられています。これにより、命令、オペランド、コメントの各要素がより明確に区切られ、視覚的に整列されます。

同様に、runtime·asminit 関数内のVFP(Vector Floating Point)ユニットの初期化に関する部分や、runtime·armcas 関数内のアトミックな比較交換(Compare-and-Swap)操作のループでも、命令とオペランドの間のスペースがタブに置き換えられています。

LDREX (Load-Exclusive) と STREX (Store-Exclusive) 命令は、ARMv6以降で導入されたアトミック操作をサポートするための命令です。これらの命令は、マルチコア環境での共有メモリへの安全なアクセスを保証するために使用されます。このコミットでは、これらの命令のフォーマットも修正されています。

src/pkg/runtime/sys_linux_arm.ssrc/pkg/sync/atomic/asm_linux_arm.s の変更も同様に、システムコール(SWI命令)やアトミック操作(cas<>, cas64<>などのヘルパー関数呼び出し)に関連するアセンブリコードのフォーマットを統一しています。

これらの変更は、GoのARMアセンブリコードベース全体で一貫したコーディングスタイルを確立し、将来的なメンテナンスやデバッグを容易にすることを目的としています。

関連リンク

参考にした情報源リンク