MC68020

1984年にMotorola社が発表した完全32 bitマイクロプロセッサがMC68020です。2 umのHCMOSプロセスで約200000トランジスタを集積しています。1980年代後半に普及していったエンジニアリングワークステーションで採用される例が多く、マイクロプロセッサの性能が組み込み用下位ミニコンピュータのレベルを越えて情報処理用中位ミニコンピュータと同じレベルまで到達した初期の製品といえるでしょう(なお、時期的にはNS社のNS32000シリーズマイクロプロセッサが先)。
MC68000アーキテクチャの命令体系に強力で複雑な間接アドレッシングモードを追加するなどの強化が行われています。ただし、浮動小数点演算やアドレス変換操作などのメモリ管理機能は内蔵されておらず、別チップを外部に接続して機能拡張を行わないと実現できません。そのコプロセッサインターフェースは標準化されて内蔵されています。

MC68020

ユーザモードで使用できるレジスタセットは、MC68010とまったく同一です。つまり、こうなっています。

MC68020 user mode registers

レジスタセットが同一だから、ユーザモードの機能も従来のMC68010と同じようなものかといえば、アドレッシングモードが強力になってレジスタの使いみちが増えていたりしますし、それなりに強化されています。ただ、バイナリレベルでも完全にMC68000/MC68010の命令セットを包含していますから、MC68000用に開発されたプログラムをそのまま動作させることも、可能な場合があります。
えーと、単純に「可能です」と書けないのは、アドレス端子A24 - A31の問題があるからです。たとえばアドレスレジスタをポインタとして使う場合、MC68000/MC68010ではアドレスレジスタの下位24 bit分のアドレスが出力されて、上位8 bitは無視されます。アドレスレジスタの内容が$00123456でも$99123456でも実際に読み書きされるメモリアドレスは$123456というわけです。そういうわけでMC68000/MC68010のポインタの上位8 bitの情報は使われずに無駄なビットとなっているので、ここに別の情報を押し込んでしまえ、という方針で書かれたプログラムがあったのです。たとえばLISPのように変数には型がないけれどもデータには多種類の型が存在する言語では、ポインタに数ビットのタグを付けて、タグによってポインタの指しているデータの型を識別すると便利なことがあります。タグビットとして、ポインタで未使用の上位8 bitを利用すると、メモリの利用効率が上がります。そのようなプログラムの場合、MC68020のように全32 bit分のアドレス情報を使用するプロセッサでは、まったく別のアドレスをアクセスする結果になるので、大規模な書き換えを行なわないと動作しません。メモリを大量に使える現在ではちょっと考えにくいですが、MC68000が使われ始めた時代は64 Kbitメモリの時代で、MC68000のシステムでも128 KByteからせいぜい512 KByteのメモリしか使えないのがあたりまえでしたから、メモリの節約は重要な課題でした。で、まぁ、こんなふうに完全32 bitメモリ空間のシステムとは共存できないプログラミングも行われていたと、そういうわけです。

レジスタセットに関する拡張は、MC68010の際と同じようにスーパバイザモードでだけ使用できるものについてだけ行われています。

MC68020 supervisor mode registers

VBR, SFC, DFCについてはMC68010と同一です。
MC68000/MC68010のスーパバイザスタックポインタに相当するものが、ISPとMSPの二つに分離しています。ISPは割り込みスタックポインタで、MC68000/MC68010のスーパバイザスタックポインタと同等のものです。MSPはマスタースタックポインタで、こちらが新設された結果、役割に応じて名前が変化したと考えられます。リセット直後に使用されるのはISPで、さらに割り込み例外が発生したときにも自動的にスタックポインタがISPに切り替わります。MSPは、多数のタスクを管理するオペレーティングシステムのために使われます。ユーザモードで動作するタスクは、それぞれに独立したスタック空間を割り当てられて、オペレーティングシステムによってUSPに適切な値が設定されています。さて、ユーザモードのタスクからシステムコールによってスーパバイザモードのオペレーティングシステム内ルーチンを呼び出す場合、呼び出したユーザモードタスクごとに独立したスーパバイザモードスタック空間を割り当てた方がオペレーティングシステムの側にとって便利なことがあります。そのためにMSPがあります。タスクディスパッチャでタスクに制御を渡す際、USPだけでなくMSPにもタスクごとに独立した値をロードしておきます。未実装命令などで例外を発生させてオペレーティングシステムを呼び出すと、自動的にスタックポインタがUSPからMSPに切り替わり、独立したスーパバイザモードスタックを実現できます。ただし、例外の中でも割り込み例外だけは、システムでただひとつの割り込み専用スタック空間と、それを指すISPが使われます。割り込みの場合には、特定のユーザタスクと関係するのではなく、システム全体の資源管理に関係するので、特定のスタックが必要というわけです。タスクディスパッチャもISPを使う状態で動作します。
CACRはキャッシュ制御レジスタで、CAARはキャッシュアドレスレジスタの略です。共にMC68020で新設された命令キャッシュの制御に使うためのレジスタです。Cache Control RegisterだからCCRかというと、コンデションコードレジスタの略になってしまうから余分のAが入ったようです。CACRもCAARも32 bit幅のレジスタとして定義されていますが、実際に有効なのはCACRで下位4 bitだけ、CAARでビット2からビット7までの6 bitだけです。
MC68020では命令専用の256 Byteのキャッシュメモリが内蔵されました。データをキャッシュすると書き込み時の制御が面倒なため、読み出ししかしない命令コードのキャッシュ回路になったのでしょう。それでも、プロセッサの内部動作の速度の向上の割に、バスのデータ転送サイクルも含めたメモリ読み出し速度の向上が進まなかったため、内蔵キャッシュは効果的でした。MC68020にはバースト転送サイクルなどの高速バスサイクルがありません。そのため、キャッシュへの命令のフィルも32 bit単位で行われ、256 Byteのキャッシュは64ラインに組織化されています。キャッシュアルゴリズムはダイレクトマッピングという、最も単純なものが採用されています。それでもMC68010のループモードよりは効率的に小さなループを高速実行できます。キャッシュはリセット時に使用禁止状態にあり、CACRの適切なビットを操作することにより、初めて使用可能になります。また、全ラインを無効化することも、特定のラインを無効化することも、同様にCACRの適切なビットを操作することにより、可能です。CAARは特定のラインを1本だけ無効化する場合に、そのラインの番号を指定するためだけに使われます。
ステータスレジスタのユーザバイト部分には変更はありませんが、システムバイト側に2 bit分の追加が行われています。T1ビットはビット位置も役割もMC68000/MC68010のTビットと同じものです。新たにT0ビットが加わったので、名称をTからT1に変更しただけですね。で、T0ビットですが、これもT1ビットと同様にトレースモードを指示するためのビットです。T1ビットが1でT0ビットが0になっていると、1命令実行後に例外が発生しますが、T0ビットが1でT1ビットが0になっていると、プログラムカウンタの内容に変更が加えられた場合にのみ(つまり分岐命令や命令トラップなどの場合だけ)、トレース例外が発生します。T0およびT1ビットが共に1にされた場合の動作は未定義です。トレース機能が強化されているわけで、後で触れるブレークポイント機能とともに、プログラムのデバッグ用の機能について留意されていることがわかります。
もうひとつのステータスレジスタの追加ビットがMビットで、マスター/割り込みステートの切り替えを行ないます。これはSビットで表されるユーザ/スーパバイザ状態の拡張で、要はスーパバイザ状態で使用されるスタックポインタがISPかMSPかを決めるためのビットです。リセット時にはMビットが0にされて、割り込みステートになってISPがスタックポインタとして使われます。Mビットは割り込み例外発生時に自動的にクリアされます。

MC68020で新たに強化された命令も多数あります。まず、まったくの新設命令は次の19種類があります。

BFCHG  ビットフィールドのテストおよび変更
BFCLR  ビットフィールドのテストおよびクリア
BFEXTS ビットフィールド抽出(符号付き)
BFEXTU ビットフィールド抽出(符号なし)
BFFFO  ビットフィールド内の最初の1検出
BFINS  ビットフィールド挿入
BFSET  ビットフィールドのテストおよびクリア
BFTST  ビットフィールドのテスト
BKPT   ブレークポイント
CALLM  モジュールコール
CAS    オペランドの比較および交換
CAS2   CASの2オペランド版
CHK2   レジスタ境界チェック(CHKの上下限値両方を指定できるもの)
CMP2   レジスタ限界チェック(CHK2で例外処理を生じないもの)
cp*    コプロセッサ命令
PACK   パック
RTM    モジュールからのリターン
TRAPcc 条件トラップ
UNPK   アンパックBCD

ビットフィールド関係が相当に強化されています。ビットマップディスプレイ関係の処理をソフトウェアで行なうときには便利でしょう。
BKPT命令はブレークポイント処理のための命令で、この命令の実行によってブレークポイントバスサイクルが行われます。ブレークポイントバスサイクルでは16 bitの命令コードを読み出し、正常に読み出せた場合にはBKPT命令の納められたメモリからその命令コードが読み出されたかのように読み出した命令コードを実行します。命令読み出し時にバスエラーが発生すると、専用の例外処理が起動されます。これによって、比較的簡単な外部回路でBKPT命令の実行を知ることができ、あらかじめ設定された任意の回数BKPT命令と置き換えられた命令が実行された後、デバッガに制御を渡すようなことが可能になります。MC68020では命令キャッシュがあって、キャッシュに取り込まれた命令は外部メモリからフェッチしませんから、特定の場所の命令が複数回実行された場合にプログラムの実行を中断しようと外部バスの信号を監視していても、検出できないことがあります。それをBKPT命令で回避できるようになっているわけです。
CALLMとRTM命令はモジュールサポート命令で、ユーザモードとスーパバイザモードという2レベルの保護よりも多種類の保護レベルをサポートする仕組みです。ただ、モジュールをサポートするメモリ管理ユニットなどの高度なハードウェアを必要とするため、あまり使われず、MC68030以降のプロセッサから、これらの命令は削除されてしまいました。
CAS, CAS2はマルチプロセッサ構成のときの同期命令で、MC68000/MC68010のTAS命令の拡張となっています。
CHK2とCMP2は配列の添字などに使用するレジスタの内容が、適切な範囲に収まっているか判定するための命令です。CHK命令では0以上指定定数以下の範囲という形で、下限が0に決まっていましたが、CHK2では下限も任意の定数にできます。
cp*はMMUやFPUなどのコプロセッサ制御命令です。
PACKとUNPKはCOBOLなどで使われるBCD表示データの操作を効率良く行なうための命令です。
TRAPccはフラグの状態によって例外を発生させる命令です。
オペランドの範囲などに拡張があった命令には、次のものがあります。

Bcc   32 bitディスプレースメント可
BRA   32 bitディスプレースメント可
BSR   32 bitディスプレースメント可
CHK   32 bitオペランド可
CMPI  プログラムカウンタ相対アドレッシングモード追加
DIVS  32/64 bitオペランド可
DIVU  32/64 bitオペランド可
EXTB  8 bitから32 bitへの符号拡張
LINK  32 bitディスプレースメント可
MOVEC 追加された制御レジスタのサポート
MULS  32 bitオペランド可
MULU  32 bitオペランド可
TST   プログラムカウンタ相対アドレッシングモード追加

総じて、完全32 bitプロセッサ化の結果、32 bitサポートが増えたといえるでしょう。

アドレッシングモードについては、MC68000/MC68010よりインデックス修飾関係が強化されています。
アドレスレジスタ間接モードは、MC68000/MC68010では8 bitディスプレースメント付きだけでしたが、そのモードですら、スケール値といってインデックスレジスタの内容に1, 2, 4, 8のいずれかの係数を掛けてからアドレス修飾に使えるようになっています。つまり、2 Byte幅や4 Byte幅のデータなんかには、インデックスレジスタの内容を高級言語の配列の添字のように扱うことができるわけです。
さらに同じアドレスレジスタ間接モードでも、ベースディスプレースメントという名称で16 bitや32 bitのディスプレースメントを指定できるモードも新設されました。しかも、このモードだとベースとなるアドレスレジスタを省略したり、インデックスレジスタを省略したり、ディスプレースメントを省略したりもできます。ベースディスプレースメントをbdと表記し、インデックスレジスタをXn、インデックスレジスタのサイズをSIZE(ワードならW、ロングワードならL)、スケール値をSCALEと表記すれば(bd, An, Xn.SIZE*SCALE)とアセンブラで表記されますが、bd, An, Xnの任意のものを省略できるわけで、(100, D0.L)のような形であたかもデータレジスタであるD0を用いたディスプレースメント付きアドレスレジスタ間接モード、いやディスプレースメント付きデータレジスタ間接ですか、単純なモードではあるけれどMC68000では無理だったモードも使えるようになります。MC68000でデータレジスタで複雑な計算を行ったものをポインタとして使用したい場合にはアドレスレジスタにいったん転送してからアドレスレジスタ間接を使うか、あるいは0を入れたアドレスレジスタを用意しておいてインデックス付きアドレスレジスタ間接を使用するしかなかったのが、便利になりました。
さらに強力なのがメモリ間接モードで、ポストインデックス付きメモリ間接とプリインデックス付きメモリ間接モードがあります。
ポストインデックス付きメモリ間接モードはアセンブラで([bd, An], Xn.SIZE*SCALE, od)と表記されます。ここでodは外付きディスプレースメントです。0 bitか16 bitか32 bit幅のベースディスプレースメントで修飾されたアドレスレジスタの指すアドレスからロングワードの値を読み出し、それをベースアドレスとして用いて、それにインデックスレジスタをスケールしたものと外付きディスプレースメントを加算して実効アドレスを求めます。外付きディスプレースメントも0, 16, 32 bit幅の任意のものを選べます。二つのディスプレースメント、アドレスレジスタ、インデックスレジスタは必要に応じて省略することもできます。
プリインデックス付きメモリ間接モードはインデックスレジスタが使われる場所がメモリからアドレス情報を読み出す前であるという点がポストインデックス付きメモリ間接モードと異なります。それにともなってアセンブラ表記も([bd, An, Xn.SIZE*SCALE], od)というように[]の位置が異なっています。やはり任意の要素を省略できます。これらのメモリ間接モードは何でもアリで、かえってディスプレースメントやインデックスレジスタなんかを省略しない使い方の方が珍しいかもしれません。
以上のアドレッシングモードの強化分はアドレスレジスタをベースにしたモードの他にプログラムカウンタをベースにしたモードでも同様に使えます。
アドレッシングモードに関してはMC68020はCISCらしくなってきていますね。

Return to IC Collection.