countersince January 6, 2001X68000 LIBRARYEnglish
更新日: 2023 年 7 月 10 日
X68000 LIBRARY > ソフトウェアライブラリ > プログラミング > アセンブラ > HAS060.X > 動作マニュアル

動作マニュアル

説明

HAS060.X の添付マニュアルです。

HAS060.DOC
────────────────────────────────────
                  High-speed Assembler ─ 68060 対応版
                        HAS060.X version 3.09+91

                          < 動作マニュアル >

                               2023/07/07
                                M.Kamada
────────────────────────────────────


━< HAS.X v3.09 について >━━━━━━━━━━━━━━━━━━━━━━

 HAS.X v3.09 のドキュメントおよびマニュアルを参照して下さい。

 このドキュメントでは HAS.X v3.09 からの変更部分について説明します。



━< 凡例 >━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 このドキュメントの中で使用しているニモニックなどの表記方法は、Motorola
の Syntax に準じています。


●記号(Motorola の Syntax に含まれないもの)

        a|b     a または b

        bw      B|W
        bwl     B|W|L
        sw      S|W
        swl     S|W|L
        wl      W|L

        <d3>    1〜8
        <d8>    -128〜127
        <d16>   -32768〜32767

        〜;〜   本来は複数の行に分けて書くものを詰めて記述したもの
                (この場合は“;”の右側も注釈ではありません)


●ディスプレースメント付きのアドレッシングモードの表記

 ディスプレースメント付きのアドレッシングモードの表記には、d16(An) のよ
うにディスプレースメントを括弧の外側に書く方法と、(d16,An) のように括弧
の内側に書く方法の 2 通りがあります。このドキュメントでは 68020 以上の
Syntax に合わせて、(d16,An) のようにディスプレースメントを括弧の内側に書
く方法に統一しています。ただし、アセンブラはどちらも同じアドレッシングモ
ードとして解釈します。



━< 68060 と ColdFire への対応 >━━━━━━━━━━━━━━━━━━━

 68060 と ColdFire への対応に関連する新しい機能をまとめて説明します。


●新設されたコマンドラインスイッチ

 次のコマンドラインスイッチに対応しています。

        -m68060         アセンブル対象のCPUを68060にする
        -m5200          アセンブル対象のCPUをColdFire V2にする
        -m5300          アセンブル対象のCPUをColdFire V3にする
        -m5400          アセンブル対象のCPUをColdFire V4にする


●新設された疑似命令

 次の疑似命令に対応しています。

        .CPU 68060      アセンブル対象のCPUを68060にする
        .CPU 5200       アセンブル対象のCPUをColdFire V2にする
        .CPU 5300       アセンブル対象のCPUをColdFire V3にする
        .CPU 5400       アセンブル対象のCPUをColdFire V4にする
        .68060          アセンブル対象のCPUを68060にする
        .5200           アセンブル対象のCPUをColdFire V2にする
        .5300           アセンブル対象のCPUをColdFire V3にする
        .5400           アセンブル対象のCPUをColdFire V4にする


●新設された命令

 次の命令は 68060 で新設されたものです。アセンブル対象の CPU が 68060
のとき、これらの命令を記述できます。

        LPSTOP.W #<data>
        PLPAR (An)
        PLPAW (An)

 次の命令は ColdFire で新設されたものです。アセンブル対象の CPU が 5200
〜5400 のとき、これらの命令を記述できます。

        一般命令
                MOV3Q.L #<data>,<ea>                    5400
                MVS.bw <ea>,Dn                          5400
                MVZ.bw <ea>,Dn                          5400
                SATS.L Dn                               5400

        特権命令
                HALT                                    5200/5300/5400
                PULSE                                   5200/5300/5400
                WDDATA.wl <ea>                          5200/5300/5400
                WDEBUG.L <ea>                           5200/5300/5400

        MAC 命令
                MAC.wl Ry.ul,Rx.ul                      5200/5300/5400
                MAC.wl Ry.ul,Rx.ul,<shift>              5200/5300/5400
                MACL.wl Ry.ul,Rx.ul,<ea>,Rw             5200/5300/5400
                MACL.wl Ry.ul,Rx.ul,<shift>,<ea>,Rw     5200/5300/5400
                MACL.wl Ry.ul,Rx.ul,<ea>&,Rw            5200/5300/5400
                MACL.wl Ry.ul,Rx.ul,<shift>,<ea>&,Rw    5200/5300/5400
                MSAC.wl Ry.ul,Rx.ul                     5200/5300/5400
                MSAC.wl Ry.ul,Rx.ul,<shift>             5200/5300/5400
                MSACL.wl Ry.ul,Rx.ul,<ea>,Rw            5200/5300/5400
                MSACL.wl Ry.ul,Rx.ul,<shift>,<ea>,Rw    5200/5300/5400
                MSACL.wl Ry.ul,Rx.ul,<ea>&,Rw           5200/5300/5400
                MSACL.wl Ry.ul,Rx.ul,<shift>,<ea>&,Rw   5200/5300/5400
                MOVE.L ACC,Rn                           5200/5300/5400
                MOVE.L MACSR,Rn                         5200/5300/5400
                MOVE.L MASK,Rn                          5200/5300/5400
                MOVE.L Rn,ACC                           5200/5300/5400
                MOVE.L Rn,MACSR                         5200/5300/5400
                MOVE.L Rn,MASK                          5200/5300/5400
                MOVE.L MACSR,CCR                        5200/5300/5400


●新設された制御レジスタ

 次の命令は 68060 で新設された制御レジスタを使用しています。アセンブル
対象の CPU が 68060 のとき、これらの命令を記述できます。

        MOVEC.L BUSCR,Rn
        MOVEC.L Rn,BUSCR
        MOVEC.L PCR,Rn
        MOVEC.L Rn,PCR

 次の命令は ColdFire で新設された制御レジスタまたは既存の制御レジスタと
は異なる表記を使用しています。アセンブル対象の CPU が 5200〜5400 のとき、
これらの命令を記述できます。

        MOVEC.L PC,Rn
        MOVEC.L Rn,PC
        MOVEC.L ACR0,Rn
        MOVEC.L Rn,ACR0
        MOVEC.L ACR1,Rn
        MOVEC.L Rn,ACR1
        MOVEC.L ACR2,Rn
        MOVEC.L Rn,ACR2
        MOVEC.L ACR3,Rn
        MOVEC.L Rn,ACR3
        MOVEC.L ROMBAR,Rn
        MOVEC.L Rn,ROMBAR
        MOVEC.L RAMBAR,Rn
        MOVEC.L Rn,RAMBAR
        MOVEC.L RAMBAR0,Rn
        MOVEC.L Rn,RAMBAR0
        MOVEC.L RAMBAR1,Rn
        MOVEC.L Rn,RAMBAR1
        MOVEC.L MBAR,Rn
        MOVEC.L Rn,MBAR


●未実装整数命令

 次の整数命令は 68060 に実装されておらず、68060 ではソフトウェアエミュ
レーションによって処理されます。アセンブル対象の CPU が 68060 のとき、こ
れらの未実装整数命令を記述するとワーニングで通知されます。

        CAS2.wl Dc1:Dc2,Du1:Du2,(Rn1):(Rn2)
        CHK2.bwl <ea>,Rn
        CMP2.bwl <ea>,Rn
        DIVS.L <ea>,Dr:Dq
        DIVU.L <ea>,Dr:Dq
        MOVEP.wl Dx,(d,Ay)
        MOVEP.wl (d,Ay),Dx
        MULS.L <ea>,Dh:Dl
        MULU.L <ea>,Dh:Dl

 なお、CAS.wl Dc,Du,<ea> の misaligned <ea> のチェックはしていません。


●未実装浮動小数点命令

 次の浮動小数点命令は 68040 および 68060 に実装されておらず、これらの
CPU ではソフトウェアエミュレーションによって処理されます。アセンブル対象
の CPU が 68040 または 68060 のとき、これらの未実装浮動小数点命令を記述
するとワーニングで通知されます。

        未実装浮動小数点単項演算命令
                FACOS
                FASIN
                FATAN
                FATANH
                FCOS
                FCOSH
                FETOX
                FETOXM1
                FGETEXP
                FGETMAN
                FINT            (68040のみ通知)
                FINTRZ          (68040のみ通知)
                FLOG10
                FLOG2
                FLOGN
                FLOGNP1
                FSIN
                FSINCOS
                FSINH
                FTAN
                FTANH
                FTENTOX
                FTWOTOX

        未実装浮動小数点 2 項演算命令
                FMOD
                FREM
                FSCALE
                FSGLDIV         (68040のみ通知)
                FSGLMUL         (68040のみ通知)

        条件付き未実装浮動小数点命令
                FDBcc           (68060のみ通知)
                FScc            (68060のみ通知)
                FTRAPcc         (68060のみ通知)

        その他の未実装浮動小数点命令
                FMOVECR

        未実装浮動小数点実効アドレス
                FMOVEM.X Dn,<ea>
                FMOVEM.X <ea>,Dn
                FMOVEM.L #<data>,#<data>,FPcr/FPcr
                FMOVEM.L #<data>,#<data>,#<data>,FPCR/FPSR/FPIAR
                F<op>.X #<data>,FPn
                F<op>.P #<data>,FPn

        未実装浮動小数点データ型
                F<op>.P         (未実装浮動小数点実効アドレスを除く)

 なお、浮動小数点数の denormalized(.S/.D/.X)および unnormalized(.X)
のチェックはしていません。


● ColdFire で削除された命令

 次の命令は ColdFire で削除されました。アセンブル対象の CPU が
5200〜5400 のとき、これらの命令を記述するとエラーになります。

        BCD 命令
                ABCD    SBCD    PACK    UNPK

        ビットフィールド命令
                BFCHG   BFCLR   BFEXTS  BFEXTU  BFFFO   BFINS   BFSET
                BFTST

        ブレークポイント命令
                BKPT

        比較命令
                CAS     CAS2    CHK     CHK2    CMPM

        コプロセッサ命令
                すべて

        デクリメントブランチ命令
                DBRA    DBcc

        レジスタ交換命令
                EXG

        FPU 関連の命令
                すべて

        転送命令
                MOVE16  MOVEP

        MMU 関連の命令
                すべて

        ローテート命令
                ROL     ROR     ROXL    ROXR

        復帰命令
                RTD     RTR

        テストアンドセット命令
                TAS     (5200/5300のみ通知)

        トラップ命令
                TRAPcc  (TRAPF以外)
                TRAPV

        キャッシュ関連の命令
                CPUSHA  CPUSHP

        リセット命令
                RESET


● ColdFire で制限されたオペレーションサイズ

 次の命令のオペレーションサイズは ColdFire でロングワードのみに制限され
ました。アセンブル対象の CPU が 5200〜5400 のとき、これらの命令でロング
ワード以外のサイズ(バイトサイズまたはワードサイズ)を指定するとエラーに
なります。

        ADD     ADDA    ADDI    ADDQ    ADDX
        SUB     SUBA    SUBI    SUBQ    SUBX
        NEG     NEGX
        AND     ANDI    EOR     EORI    OR      ORI     NOT
        ASL     ASR     LSL     LSR
        CMP     CMPA    CMPI    (5200/5300のみ通知)
        MOVEM

 次の命令のオペレーションサイズは ColdFire でロングワードが指定できなく
なりました。アセンブル対象の CPU が 5200〜5400 のとき、これらの命令でロ
ングワードサイズを指定するとエラーになります。

        Bcc     BRA     BSR     (5200/5300のみ通知)
        LINK


● ColdFire で制限されたアドレッシング

 次の命令のデスティネーションオペランドの実効アドレスモードは ColdFire
で Dn のみに制限されました。アセンブル対象の CPU が 5200〜5400 のとき、
これらの命令のデスティネーションオペランドに Dn 以外を指定するとエラーに
なります。

        ADDI    SUBI
        ANDI    EORI    ORI
        ASL     ASR     LSL     LSR
        MOVE from CCR
        MOVE from SR
        NOT     NEG     NEGX
        Scc

 次の命令のデスティネーションオペランドの実効アドレスモードは ColdFire
で Dn が指定できなくなりました。アセンブル対象の CPU が 5200〜5400 のと
き、これらの命令のデスティネーションオペランドに Dn を指定するとエラーに
なります。

        TAS

 次の命令のソースオペランドの実効アドレスモードは ColdFire で Dn または
#<data> のみに制限されました。アセンブル対象の CPU が 5200〜5400 のとき、
これらの命令のソースオペランドに Dn または #<data> 以外を指定するとエラ
ーになります。

        MOVE to CCR
        MOVE to SR


● 68060 のエラッタの対策

 HAS060.X には 68060(F43G および G65V マスクセット)の不具合(エラッタ)
の幾つかを回避するための対策が施されており、68060 のエラッタを回避するた
めにプログラム中に必要最小限のコードが自動的に挿入されることがあります。
エラッタとその対策の内容については、後述の<68060 のエラッタとその対策>
を参照して下さい。



━< メッセージの日本語化と細分化 >━━━━━━━━━━━━━━━━━━

 従来、アセンブラのワーニングやエラーメッセージは簡単な英語で表示されて
いました。HAS060.X ではこれを日本語化し、さらに細分化することで、エラー
の内容をなるべく具体的な表現で表示します。

 実際に通知されるワーニングおよびエラーメッセージの個々の意味については、
後述の<ワーニングメッセージ一覧>および<エラーメッセージ一覧>を参照し
て下さい。



━< 新設されたワーニング >━━━━━━━━━━━━━━━━━━━━━━

 HAS060.X では、次のワーニングが新設されています。

  ・レベル 1 のワーニング

        「%s はソフトウェアエミュレーションで実行されます」

        「浮動小数点命令の直後に NOP を挿入しました (エラッタ対策)」

        「MOVE to USP の直前に MOVEA.L A0,A0 を挿入しました (エラッタ対策)」

        「CCR/SR の未定義のビットを操作しています」

        「シンボル %s を set(=) で上書きしました」

        「シンボル %s を offsym で上書きしました」

        「.offsym の中に %s は指定できません」

        「.ds の引数が負数です」

        「整数を浮動小数点数の内部表現とみなします」


●「%s はソフトウェアエミュレーションで実行されます」(レベル1)

 %s の所には命令のニモニックが入ります。アセンブル対象の CPU が 68040
または 68060 のとき、ソフトウェアエミュレーションによって処理される命令
であることを通知します。

 ソフトウェアエミュレーションによって処理される命令については、前述の
<68060 への対応>の「未実装整数命令」および「未実装浮動小数点命令」の項
目を参照して下さい。


●「浮動小数点命令の直後に NOP を挿入しました (エラッタ対策)」(レベル1)

 68060 の F43G マスクセットに存在する FPU の不具合(エラッタ F6)を回避
するために、5 命令からなる命令列の 1 番目の浮動小数点命令の直後に NOP 命
令を挿入したことを通知します。

 このエラッタの対策によって、5 命令からなる命令列の 1 番目の浮動小数点
命令の見掛けの命令長が 1 ワード長くなるので注意して下さい。

 なお、このエラッタの対策はアセンブル対象の CPU が 68060 かどうかに関わ
らず施されます。この機能を禁止したいときは、スイッチ -k[1] を指定して下
さい。

 このエラッタの詳細については、後述の<68060 のエラッタとその対策>を参
照して下さい。


●「MOVE to USP の直前に MOVEA.L A0,A0 を挿入しました (エラッタ対策)」
(レベル1)

 68060 の F43G および G65V マスクセットに存在する不具合(エラッタ I11)
を回避するために、行頭にラベルが定義されている MOVE to USP 命令の直前に
MOVEA.L A0,A0 命令を挿入したことを通知します。

 このエラッタの対策によって、MOVE to USP 命令の見掛けの命令長が 1 ワー
ド長くなるので注意して下さい。

 行頭にラベルが定義されていない MOVE to USP 命令は変化しません。また、
データセクションに記述した MOVE to USP 命令も変化しません。

 なお、このエラッタの対策はアセンブル対象の CPU が 68060 かどうかに関わ
らず施されます。この機能を禁止したいときは、スイッチ -k[1] を指定して下
さい。

 このエラッタの詳細については、後述の<68060 のエラッタとその対策>を参
照して下さい。


●「CCR/SR の未定義のビットを操作しています」(レベル1)

 このワーニングは、CCR または SR を操作する命令で、イミディエイトオペラ
ンドで CCR や SR の未定義のビットをセットまたはクリアしようとした場合に
通知されます。これは、文法的には問題がなくても、プログラマがそのような記
述を意図していない可能性が高いためです。

 具体的には、以下のような条件でこのワーニングが通知されます。

      ┏━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━┓
      ┃        命令        │                通知条件                ┃
      ┠──────────┼────────────────────┨
      ┃ANDI.B  #<data>,CCR │・#<data> のビット 5,6,7 のいずれかが 0 ┃
      ┃                    │  のとき                                ┃
      ┠──────────┼────────────────────┨
      ┃EORI.B  #<data>,CCR │・#<data> のビット 5,6,7 のいずれかが 1 ┃
      ┃MOVE.W  #<data>,CCR │  のとき                                ┃
      ┃ORI.B   #<data>,CCR │                                        ┃
      ┠──────────┼────────────────────┨
      ┃ANDI.W  #<data>,SR  │・#<data> のビット 5,6,7,11 のいずれかが┃
      ┃                    │  0 のとき                              ┃
      ┃                    │・アセンブル対象の CPU が 68000 または  ┃
      ┃                    │  68010 で、#<data> のビット 12,14 のい ┃
      ┃                    │  ずれかが 0 のとき                     ┃
      ┃                    │・アセンブル対象の CPU が 68060 または  ┃
      ┃                    │  5200〜5400 のいずれかで、#<data> のビ ┃
      ┃                    │  ット 14 が 0 のとき                   ┃
      ┠──────────┼────────────────────┨
      ┃EORI.W  #<data>,SR  │・#<data> のビット 5,6,7,11 のいずれかが┃
      ┃LPSTOP.W #<data>    │  1 のとき                              ┃
      ┃MOVE.W  #<data>,SR  │・アセンブル対象の CPU が 68000 または  ┃
      ┃ORI.W   #<data>,SR  │  68010 で、#<data> のビット 12,14 のい ┃
      ┃STOP    #<data>     │  ずれかが 1 のとき                     ┃
      ┃                    │・アセンブル対象の CPU が 68060 または  ┃
      ┃                    │  5200〜5400 のいずれかで、#<data> のビ ┃
      ┃                    │  ット 14 が 1 のとき                   ┃
      ┗━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━┛

 例えば、MOVE #%01111,CCR を MOVE #$01111,CCR と書き間違えたときなどに、
このワーニングが通知されます。

 MOVE #%00011,CCR を MOVE #$00011,CCR と書き間違えたときは、上記の条件
に該当しないので、ワーニングは通知されません。


●「シンボル %s を set(=) で上書きしました」(レベル1)

 %s の所にはシンボル名が入ります。-j を指定していないとき、疑似命令 set
以外で定義されたシンボルを set で再定義しようとしたときに通知されます。

 疑似命令 set は、set 以外で定義されたシンボルでも上書きすることができ
てしまうので、使用中のシンボルを間違って指定してしまっても二重定義エラー
にならず、間違いを見つけるのが大変です。そこで、set 以外で定義されたシン
ボルを set で上書きしようとしたときにワーニングで通知するようになってい
ます。

 -j を指定すると、このワーニングはエラーに格上げされます。


●「シンボル %s を offsym で上書きしました」(レベル1)

 %s の所にはシンボル名が入ります。-j を指定していないとき、疑似命令
offsym 以外で定義されたシンボルを offsym で再定義しようとしたときに通知
されます。

 疑似命令 offsym も set と同様にシンボルの上書きができるので、offsym 以
外で定義されたシンボルを offsym で上書きしようとしたときにワーニングで通
知するようになっています。

 -j を指定すると、このワーニングはエラーに格上げされます。


●「.offsym の中に %s は指定できません」(レベル1)

 %s の所には .even/.quad/.align のいずれかが入ります。現在、.offsym で
初期値を与えるシンボルを指定して開始した abs セクションでは、アラインメ
ントの整合を行うことができません。このワーニングは、それが可能になるまで
の暫定処置です。


●「.ds の引数が負数です」(レベル1)

 .text/.data 以外のセクションで .ds の引数に負数を指定すると、このワー
ニングが通知されます。

 .ds の引数に負数を指定した場合、.text または .data セクションのときだ
けエラーを通知してそれ以外のセクションのときはワーニングに留めてあります
が、本来は .ds の引数はセクションに関係なく正数でなければなりません。


●「整数を単精度浮動小数点数の内部表現と見なします」(レベル1)

 単精度浮動小数点数を書く所に整数を書くと単精度浮動小数点数の内部表現と
見なされますが、「整数を書くと浮動小数点数に変換されるはず」と思い込んで
整数を書いてしまうと間違いに気付きにくいので、確認を促すためにこのワーニ
ングが通知されます。



━< 新設されたエラー >━━━━━━━━━━━━━━━━━━━━━━━━

 HAS060.X では、次のエラーが追加されました。

        「シンボル %s は set(=) 以外で定義されています」

        「シンボル %s は offsym 以外で定義されています」

        「"〜" が閉じていません」

        「'〜' が閉じていません」

        「<〜> が閉じていません」

        「整数の記述が間違っています」

        「1 つのマクロの中のローカルシンボルが多すぎます」

        「.ds の引数が負数です」


●「シンボル %s は set(=) 以外で定義されています」

 %s の所にはシンボル名が入ります。-j を指定しているとき、疑似命令 set
以外で定義されたシンボルを set で再定義しようとしたときに通知されます。


●「シンボル %s は offsym 以外で定義されています」

 %s の所にはシンボル名が入ります。-j を指定しているとき、疑似命令
offsym 以外で定義されたシンボルを offsym で再定義しようとしたときに通知
されます。


●「"〜" が閉じていません」
●「'〜' が閉じていません」
●「<〜> が閉じていません」

 これらはいずれもワーニングから格上げされたエラーです。文字列を囲むクォ
ートなどが閉じていないときに通知されます。


●「整数の記述が間違っています」

 ソースリストに直接記述された 10 進数、16 進数、8 進数、2 進数の整数を
文字列から数値に変換するとき、値が 64 ビットの整数の範囲で表現できなくな
ったときに通知されます。


●「.ds の引数が負数です」

 .text/.data セクションで .ds の引数に負数を指定すると、このエラーが通
知されます。

 .ds の引数に負数を指定した場合、.text または .data セクションのときだ
けエラーを通知してそれ以外のセクションのときはワーニングに留めてあります
が、本来は .ds の引数はセクションに関係なく正数でなければなりません。


●「1 つのマクロの中のローカルシンボルが多すぎます」

 1 つのマクロの中のローカルシンボルが多すぎるとき、HAS.X v3.09 ではハン
グアップしてしまっていましたが、HAS060.X ではエラーとして通知します。

 このエラーが発生すると、その時点でアセンブルが強制的に中止されます。



━< 削除されたワーニング >━━━━━━━━━━━━━━━━━━━━━━

 HAS060.X では、次のワーニングが削除されました。

  ・レベル 1 のワーニング

        「Warning: terminator not found」
                「終止符が見つかりません」


●「Warning: terminator not found」(レベル 1)

 このワーニングはエラーに格上げしたため削除されました。



━< 追加・変更されたコマンドラインスイッチ >━━━━━━━━━━━━━

 以下のコマンドラインスイッチは HAS.X v3.09 にないか、HAS060.X で機能が
追加されたものです。


●コマンドラインスイッチ -1(絶対ロングを optional PC 間接にする)

 コマンドラインスイッチ -1 を指定すると、次のようにサイズ指定のない定数
でない絶対ロングアドレッシングを optional PC 間接アドレッシングと見なし
て処理します。

        JMP <label>  →  JMP (<label>,OPC)

 次のように、オペランドにロングワードサイズが明記されている場合は
optional PC 間接と見なされません。

        JMP (<label>).L

コマンドラインスイッチ -1 を指定したいが絶対ロングアドレッシングでなけれ
ば困る場所があるときは、そのオペランドだけサイズを明記して下さい。

 -1 を指定すると、自動的に -b[1] と -e も同時に指定されたものと見なされ
ます。


●コマンドラインスイッチ -b0

 -b0 は、手前に指定された -b[1]/-b2/-b3/-b4/-b5 をキャンセルします。


●コマンドラインスイッチ -b[1]

 -b[1] は -b と同じです。つまり、PC 間接アドレッシングのディスプレース
メント(相対分岐命令を含む)のサイズがロングワードになってしまうとき、こ
れを絶対ロングアドレッシングに変換します。言い換えると、68000 では実行で
きないプログラムを、68000 でも実行できるように変換します。

 -b[1] を指定すると、次のようにサイズ指定のない定数でない PC 間接アドレ
ッシングのディスプレースメントがロングワードになってしまうとき、絶対ロン
グアドレッシングに変換されます。

        MOVE.L (<label>,PC),D0  →  MOVE.L (<label>).L,D0

 また、-b[1] を指定すると、BRA/BSR/Bcc がそれぞれ JBRA/JBSR/JBcc と見な
されます。


●コマンドラインスイッチ -b2

 -b2 を指定すると、サイズ指定のない定数でないディスプレースメントを伴っ
た (<label>,PC) を (<label>).L に変換します。ただし、LEA/PEA/JMP/JSR の
各命令のオペランドは変換しません。

 キャッシュを搭載している 68030 以上の機種では、(<label>,PC) の実効アド
レスのアクセスには命令キャッシュが使用され、(<label>).L はデータキャッシ
ュが使用されます。-b2 を指定すると、可変データ領域を (<label>,PC) でアク
セスしているプログラムでキャッシュの効率が多少改善される可能性があります。
ただし、68000 で実行した場合は遅くなってしまいます。デメリットが大きく、
メリットが小さいので、常用するべきではないと思います。

 なお、-b2 を指定すると -b[1] と -b4 はキャンセルされます。-b[1] と -b2
を同時に指定したい場合は -b3 を使用して下さい。


●コマンドラインスイッチ -b3

 -b3 には -b1 と -b2 の両方の効果があります。


●コマンドラインスイッチ -b4

 -b4 を指定すると、サイズ指定のない定数でないディスプレースメントが指定
された (<label>,PC) をすべて (<label>).L に変換します。-b2 との違いは、
-b4 はすべての命令に有効であるということです。

 プログラムをデバッガでデバッグするとき、シンボルが付いていない実効アド
レスを PC 間接アドレッシングで参照していると、アドレスがわかりにくく、デ
バッグしにくいことがあります。そこで、(<label>,PC) をすべて (<label>).L
にしてしまうスイッチを付けてみました。

 なお、-b4 を指定すると -b[1] はキャンセルされます。-b[1] と -b4 を同時
に指定したい場合は -b5 を使用して下さい。


●コマンドラインスイッチ -b5

 -b5 には -b1 と -b4 の両方の効果があります。


●コマンドラインスイッチ -c0(すべての最適化を禁止する)

 コマンドラインスイッチ -c0 を指定すると、HAS060.X が対応しているすべて
の最適化が禁止されます。これには、-n(パス 1 で確定できないサイズの最適
化の省略)も含まれます。

 -c0 よりも手前に指定された -a/-c2/-c3/-c4 はすべて無効になります。また、
-c0 は、後から -c3 や -c4 などを指定することで無効化できます。

 パス 1 で確定できないサイズの最適化を行わないと 68060 のエラッタ対策が
できないため、-c0 を指定すると自動的に -k[1] が指定されたものと見なされ
ます。すなわち、-c0 を指定すると 68060 のエラッタ対策が行われなくなりま
す。


●コマンドラインスイッチ -c1((d,An) の最適化の禁止)

 コマンドラインスイッチ -c1 を指定すると、(d,An) の最適化が禁止されます。
これは HAS060.X が HAS.X v3.09 と同様に (d,An) の d が 0 でも (An) に置
き換えられない場合に対応していないために設けたスイッチです。この不具合に
ついては、KNOWNBUG.DOC を参照して下さい。

 -c1 は、後から -c3 や -c4 などを指定することで無効化できます。


●コマンドラインスイッチ -c2(HAS.X v2 と互換の最適化を行う)

 コマンドラインスイッチ -c2 は -c と同じ意味です。

 -c2 を指定すると、HAS.X v2 と互換の最適化が行われます。これには -c1 の
(d,An) の最適化の禁止も含まれます。また、-c と同様にコマンドラインスイッ
チ -a および -q が有効になります(-a は絶対ショートアドレッシングへの変
換の許可、-q はクイックイミディエイト命令への変換の禁止です)。

 -c2 よりも手前に指定された -c0/-c3/-c4 はすべて無効になります。また、
-c2 は、後から -c3 や -c4 などを指定することで無効化できます。


●コマンドラインスイッチ -c3(HAS.X v3.09 と互換の最適化を行う)

 コマンドラインスイッチ -c3 を指定すると、HAS.X v3.09 と互換の最適化が
行われます。デフォルトで HAS.X v3.09 と互換の最適化が行われますので、通
常は指定する必要はありません。

 -c3 よりも手前に指定された -c0/-c1/-c2/-c4/-q はすべて無効になります。
また、-c3 は、後から -c2 や -c4 などを指定することで無効化できます。


●コマンドラインスイッチ -c4(追加された最適化を含むすべての最適化を行う)

 コマンドラインスイッチ -c4 を指定すると、HAS060.X で追加された最適化を
含むすべての最適化が行われます。HAS060.X で追加された最適化については、
後述の<単一命令の最適化>の「追加された単一命令の最適化」の項目を参照し
て下さい。

 -c4 よりも手前に指定された -c0/-c1/-c2/-c3/-n/-q はすべて無効になりま
す。また、-c4 は、後から -c2 や -c3 などを指定することで無効化できます。

 -c4 を指定するときは -e(外部参照オフセットのデフォルトをロングワード
にする)も併せて指定する必要が出てくることがあります。この詳細については、
後述の<単一命令の最適化>の「追加された単一命令の最適化」の項目を参照し
て下さい。


●コマンドラインスイッチ -c<mnemonic>[=6](software emulation の命令を展
開する)

 コマンドラインスイッチ -c<mnemonic>[=6] を指定すると、mnemonic で指定
された命令を software emulation が発生しない命令列に置き換えます。
software emulation の命令の展開については、後述の< software emulation
の命令の展開>を参照して下さい。

 mnemonic[=6] は“,”(コンマ)で区切って複数指定できます。

 今のところ、-cfscc[=6] と -cmovep[=6] が指定できます。また、-call[=6]
を指定すると、対応しているすべての置き換えを行います。


●コマンドラインスイッチ -f[f,m,w,p,c]

 -f はリストファイルのフォーマットを指定するスイッチです。5 番目の引数
c を追加しました。

 -f の 1 番目の引数 f はリストファイルを改ページするとき 1、改ページし
ないとき 0 です。デフォルトは 1 です。

 -f の 2 番目の引数 m はリストファイルにマクロの内容を展開するとき 1、
展開しないとき 0 です。デフォルトは 0 です。

 -f の 3 番目の引数 w はリストファイルの幅です。デフォルトは 136 です。

 -f の 4 番目の引数 p はリストファイルのページの行数です。デフォルトは
58 です。

 -f の 5 番目の引数 c はリストファイルのコード部の幅です。デフォルトは
16 です。MC68020〜MC68060 用のプログラムで使われるフルフォーマットの拡張
ワードやイミディエイトの浮動小数点数を伴う命令は 8 バイトに収まらず、命
令の途中でコード部が改行されて読みにくくなることが多いので、コード部の幅
を広げられるようにしました。コード部の幅だけ変更したいときは -f,,,,32 の
ように書きます。


●コマンドラインスイッチ -j[n]

 通常、.SET および .OFFSYM(新設された疑似命令(後述))では、シンボル
の上書き(二重定義)が、プレデファインシンボルや異種のシンボルと重複して
いない限り、エラーにならないことになっています。

 コマンドラインスイッチ -j[n] を使うと、.SET および .OFFSYM におけるシ
ンボルの上書きの禁止条件を強化することができます。

 具体的には、.SET では .SET 以外で定義されたシンボルの上書きが禁止され、
.OFFSYM では .OFFSYM 以外で定義されたシンボルの上書きが禁止されます。

 -j[n] の n によって、内容が異なります。

        -j1     .SET の条件を強化、.OFFSYM の条件は通常
        -j2     .SET の条件は通常、.OFFSYM の条件を強化
        -j[3]   .SET と .OFFSYM の条件を強化


●コマンドラインスイッチ -k0

 -k0 は、手前に指定された -k[1] をキャンセルします。すなわち、68060 の
エラッタ対策を行います。

 パス 1 で確定できないサイズの最適化を行わないと 68060 のエラッタ対策が
できないため、-k0 を指定するとそれ以前に指定された -n(または -c0 の効果
の一部)が無効になります。


●コマンドラインスイッチ -k[1](68060 のエラッタ対策を禁止する)

 コマンドラインスイッチ -k[1] を指定すると、68060 のエラッタ対策が禁止
されます。68060 のエラッタ対策はデフォルトで有効になっていますが、どうし
ても禁止しなければならない場合は -k[1] を指定して下さい。

 パス 1 で確定できないサイズの最適化を行わないと 68060 のエラッタ対策が
できないため、-c0 を指定すると自動的に -k[1] が指定されたものと見なされ
ます。

 なお、-k[1] の効果は、-k0 で取り消すことができます。


●コマンドラインスイッチ -s<n>(数字ローカルラベルの最大桁数の指定)

 コマンドラインスイッチ -s<n> で、数字ローカルラベルの最大桁数を指定す
ることができます。n は 1 から 4 までで、デフォルトは -s4(最大 4 桁)で
す。

        -s1     数字ローカルラベルを 1 桁だけ許可(1:〜9:)
        -s2     数字ローカルラベルを 2 桁まで許可(1:〜99:)
        -s3     数字ローカルラベルを 3 桁まで許可(1:〜999:)
        -s4     数字ローカルラベルを 4 桁まで許可(1:〜9999:)


●コマンドラインスイッチ -y0

 -y0 は、手前に指定された -y[1] をキャンセルします。


●コマンドラインスイッチ -y[1](プレデファインシンボルを使う)

 コマンドラインスイッチ -y[1] を指定すると、プレデファインシンボルが使
えるようになります。プレデファインシンボルについては、後述の<プレデファ
インシンボル>を参照して下さい。

 なお、-y[1] の効果は、-y0 で取り消すことができます。



━< software emulation の命令の展開>━━━━━━━━━━━━━━━━━

 HAS060.X は、68040 や 68060 において software emulation によって実行さ
れる命令の一部を、個別に software emulation が発生しない命令列に置き換え
ることができます。この機能は HAS.X v3.09 にはなく、HAS060.X で追加された
ものです。

 software emulation の命令の展開は、コマンドラインスイッチ
-c<mnemonic>[=6] を指定することで有効になります。ここで、mnemonic の部分
には展開したい命令のニモニックを個別に指定します。また、=6 はアセンブル
対象の CPU が 68060 のときだけ展開することを意味しています。

 展開できる命令は以下の通りです。

        -cfscc[=6] を指定したとき

                FScc.B  Dn

        -cmovep[=6] を指定したとき

                MOVEP.W (d,An),Dn
                MOVEP.L (d,An),Dn
                MOVEP.W Dn,(d,An)
                MOVEP.L Dn,(d,An)


● software emulation の命令を展開する際の注意事項

 68040 や 68060 において software emulation が発生する命令を software
emulation が発生しない命令列に置き換えると、これらの CPU で実行した場合
の所要時間が大幅に短縮されます。ただし、展開しなくても最初から software
emulation が発生しない CPU で実行した場合は、この置き換えによって実行時
間が大幅に増加してしまいます。software emulation になるとは言っても動か
ないわけではありません(IPL や OS を書く場合は別ですが)。デメリットが大
きいので、メリットが小さい場合は展開しないほうがよいでしょう。

 software emulation の命令を展開すると、命令長がかなり長くなります。プ
ログラムの記述の仕方によっては、命令長が長くなると正常に動作しなくなる場
合があるので注意する必要があります。例えば、MOVEP 命令の並びの途中に飛び
込むようなプログラムは、MOVEP 命令が展開されると正常に動作しません。他の
命令を展開する場合も同様です。なお、展開後の命令長は不定ですので、それぞ
れの命令の位置を参照したい場合は必ずその命令の行にラベルを定義して参照す
るようにして下さい。

 software emulation の命令の実行中は割り込みが禁止されません。HAS060.X
で展開した場合も、割り込みを禁止するためのコードは出力されません。

 software emulation の命令の展開は、アセンブル対象の CPU によって展開が
行われなかったり展開結果が異なることがあります。詳細は個別に説明します。


● FScc 命令の展開

 コマンドラインスイッチ -cfscc[=6] を指定すると、FScc 命令が展開されま
す。ただし、データレジスタ直接以外のアドレッシングモードの場合は展開しま
せん。

 -cfscc=6 とすると、アセンブル対象が 68060 の場合だけ FScc 命令が展開さ
れます。-cfscc だけのときはアセンブル対象の CPU に関係なく展開されます。
FScc 命令を展開するかどうかを個別に選択したい場合は、展開したい場所だけ
アセンブル対象の CPU を 68060 にして、-cfscc=6 を指定してアセンブルして
下さい。

 FScc 命令の展開結果は、BSUN の処理を伴う条件かどうかによって異なります。
また、FSF と FST は特別扱いになっています。

        ○ BSUN の処理を伴わない条件のとき

                FSEQ/FSOGT/FSOGE/FSOLT/FSOLE/FSOGL/FSOR/FSUN/
                FSUEQ/FSUGT/FSUGE/FSULT/FSULE/FSNE 命令の展開
      ┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
      ┃            展開前            │            展開後            ┃
      ┠───────────────┼───────────────┨
      ┃        FScc.B  Dn            │        ST.B    Dn            ┃
      ┃                              │        FBcc.W  @F            ┃
      ┃                              │        SF.B    Dn            ┃
      ┃                              │@@:                           ┃
      ┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛

        ○ BSUN の処理を伴う条件のとき

              FSSF/FSSEQ/FSGT/FSGE/FSLT/FSLE/FSGL/FSGLE/FSNGLE/
             FSNGL/FSNLE/FSNLT/FSNGE/FSNGT/FSSNE/FSST 命令の展開
      ┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
      ┃            展開前            │            展開後            ┃
      ┠───────────────┼───────────────┨
      ┃        FScc.B  Dn            │        FBUN.W  1F            ┃
      ┃                              │        ST.B    Dn            ┃
      ┃                              │        FBcc.W  2F            ┃
      ┃                              │        SF.B    Dn            ┃
      ┃                              │        .DC.W   $51FB       ※┃
      ┃                              │1:      FScc.B  Dn            ┃
      ┃                              │2:                            ┃
      ┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛
        ※展開後の $51FB は TRAPF.L #<data> の opecode です。これによっ
          て直後の FScc 命令を飛び越えています。

        ○その他

                              FSF/FST 命令の展開
      ┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
      ┃            展開前            │            展開後            ┃
      ┠───────────────┼───────────────┨
      ┃        FSF.B   Dn            │        SF.B    Dn            ┃
      ┠───────────────┼───────────────┨
      ┃        FST.B   Dn            │        ST.B    Dn            ┃
      ┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛

注意:
         上記の展開後のコードで使用しているローカルラベルは、説
        明のために記述したものであって、実際にローカルラベルが消
        費されるわけではありません(マクロ展開とは異なります)。


● MOVEP 命令の展開

 コマンドラインスイッチ -cmovep[=6] を指定すると、MOVEP 命令が展開され
ます。ただし、MOVEP 命令の実効アドレスのディスプレースメントが定数でない
場合と、アドレスレジスタが A7(SP)の場合は展開しません。

 -cmovep=6 とすると、アセンブル対象が 68060 の場合だけ MOVEP 命令が展開
されます。-cmovep だけのときはアセンブル対象の CPU に関係なく展開されま
す。MOVEP 命令を展開するかどうかを個別に選択したい場合は、展開したい場所
だけアセンブル対象の CPU を 68060 にして、-cmovep=6 を指定してアセンブル
して下さい。

 MOVEP 命令の展開結果は、アセンブル対象の CPU によって異なります。

                          MOVEP 命令の展開(基本形)
      ┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
      ┃            展開前            │            展開後            ┃
      ┠───────────────┼───────────────┨
      ┃        MOVEP.W (d,An),Dn     │        MOVE.W  CCR,-(SP)     ┃
      ┃                              │        MOVE.B  (d,An),Dn     ┃
      ┃                              │        LSL.W   #8,Dn         ┃
      ┃                              │        MOVE.B  (d+2,An),Dn   ┃
      ┃                              │        MOVE.W  (SP)+,CCR     ┃
      ┠───────────────┼───────────────┨
      ┃        MOVEP.L (d,An),Dn     │        MOVE.W  CCR,-(SP)     ┃
      ┃                              │        MOVE.B  (d,An),Dn     ┃
      ┃                              │        LSL.W   #8,Dn         ┃
      ┃                              │        MOVE.B  (d+2,An),Dn   ┃
      ┃                              │        SWAP.W  Dn            ┃
      ┃                              │        MOVE.B  (d+4,An),Dn   ┃
      ┃                              │        LSL.W   #8,Dn         ┃
      ┃                              │        MOVE.B  (d+6,An),Dn   ┃
      ┃                              │        MOVE.W  (SP)+,CCR     ┃
      ┠───────────────┼───────────────┨
      ┃        MOVEP.W Dn,(d,An)     │        MOVE.W  CCR,-(SP)     ┃
      ┃                              │        ROL.W   #8,Dn         ┃
      ┃                              │        MOVE.B  Dn,(d,An)     ┃
      ┃                              │        ROL.W   #8,Dn         ┃
      ┃                              │        MOVE.B  Dn,(d+2,An)   ┃
      ┃                              │        MOVE.W  (SP)+,CCR     ┃
      ┠───────────────┼───────────────┨
      ┃        MOVEP.L Dn,(d,An)     │        MOVE.W  CCR,-(SP)     ┃
      ┃                              │        ROL.L   #8,Dn         ┃
      ┃                              │        MOVE.B  Dn,(d,An)     ┃
      ┃                              │        ROL.L   #8,Dn         ┃
      ┃                              │        MOVE.B  Dn,(d+2,An)   ┃
      ┃                              │        ROL.L   #8,Dn         ┃
      ┃                              │        MOVE.B  Dn,(d+4,An)   ┃
      ┃                              │        ROL.L   #8,Dn         ┃
      ┃                              │        MOVE.B  Dn,(d+6,An)   ┃
      ┃                              │        MOVE.W  (SP)+,CCR     ┃
      ┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛

 68000 には MOVE from CCR 命令が存在しないので、アセンブル対象の CPU が
68000 の場合は MOVE from CCR 命令の代わりに MOVE from SR 命令が使用され
ます。MOVE from SR 命令は 68010 以上の CPU で特権命令になっていますが、
Human 上では特権違反例外が発生しても自動的に MOVE from CCR 命令に書き換
えられて実行されるので、通常は問題なく実行できます(ユーザモードで参照で
きる ROM のコードを書く場合などは注意する必要があります)。一度書き換え
られれば以降は MOVE from CCR 命令を実行するだけですから、繰り返し使用す
る場合の動作速度には大きな影響が出ない場合が多いと思われます。

 展開後の (d+?,An) は、d+? が 0 ならば (An) に、d+? が符号つき 1 ワード
におさまらなければ (bd,An) になります。ただし、(bd,An) は 68020 以上の
CPU でなければ使用できないので、アセンブル対象の CPU が 68020 以上でなけ
れば d+? が符号つき 1 ワードにおさまらなくなった時点で An を 8 増やして
ディスプレースメントを 8 減らします。

例(アセンブル対象の CPU が 68000 のとき MOVEP.L D0,($7FFF,A0) を展開し
た結果):

      ┌────────────────────────────
      │        MOVE.W  SR,-(SP)        *MOVE from CCRは不可
      │        ROL.L   #8,D0
      │        MOVE.B  D0,($7FFF,A0)
      │        ROL.L   #8,D0
      │        ADDQ.L  #8,A0           *ベースレジスタを増やす
      │        MOVE.B  D0,($7FF9,A0)   *ディスプレースメントを減らす
      │        ROL.L   #8,D0
      │        MOVE.B  D0,($7FFB,A0)
      │        ROL.L   #8,D0
      │        MOVE.B  D0,($7FFD,A0)
      │        SUBQ.L  #8,A0           *ベースレジスタを復元する
      │        MOVE.W  (SP)+,CCR



━< 68060 のエラッタと対策 >━━━━━━━━━━━━━━━━━━━━━

 HAS060.X には、68060(F43G および G65V マスクセット)の一部の不具合
(エラッタ)を回避するための対策が施されています。ここでは、HAS060.X に
よって対策が施されているエラッタとその対策の内容を説明します。

 HAS060.X による 68060 のエラッタ対策は、アセンブル対象の CPU が 68060
かどうかに関わらず施されます。この機能を禁止したいときは、スイッチ -k[1]
を指定して下さい。

 HAS060.X では 68060 のエラッタ対策の実装にパス 1 で確定できないサイズ
の最適化を用いているため、パス 1 で確定できないサイズの最適化を禁止(-n
または -c0 を指定)すると(自動的に -k[1] が指定されたものと見なされ)エ
ラッタ対策が行われません。

 HAS060.X が対応しているエラッタは、実際に誤動作することを確認していま
す。ここに挙げていない(HAS060.X が対応していない)エラッタについては、
Motorola の公開資料を参照して下さい。


● Motorola の公開資料について

 エラッタの内容は Motorola の公開資料『68060 ERRATA Rev 4.0』を参考にし
ており、エラッタ F6 や I11 といった記号もこの資料によるものです。エラッ
タを含めた 68060 の情報は Motorola のホームページで入手できます。URL は
以下の通りです。

        http://www.mot.com/SPS/HPESD/prod/0X0/frames/68060.html
                                                        (98-01-10 現在)


●エラッタ F6(FPU の不具合)

・エラッタの内容

 68060(F43G マスクセット)において、以下のような 5 つの命令からなる命
令列が正常に動作しないことがあります。その結果、浮動小数点レジスタに誤っ
たデータが転送されたり、場合によっては予期しない浮動小数点例外が発生する
可能性があります。

        エラッタ F6 を発生させる命令列
      ┌────────────────────────────
   (1)│        F<op.A>
   (2)│        MOVEA.L <mem>,Ax
   (3)│        MOVEA.L <mem>,Ay
   (4)│        F<op.B> (Ax)
   (5)│        <op.C> (Ay)

 個々の命令の具体的な条件は以下の通りです。

(1) F<op.A>
 浮動小数点データレジスタをデスティネーションとする浮動小数点命令で、メ
モリオペランドが FPU に転送された後 3 サイクル以上かかるもの。具体的には、
        FADD    FSADD   FDADD
        FSUB    FSSUB   FDSUB
        FMUL    FSMUL   FDMUL   FSGLMUL
        FDIV    FSDIV   FDDIV   FSGLDIV
        FSQRT   FSSQRT  FDSQRT
        FINT    FINTRZ
および、以下の命令でソースオペランドが整数であるもの、つまり、浮動小数点
数への変換を必要とするもの。
        FABS
        FCMP
        FMOVE to FPn
        FNEG
        FTST

(2) MOVEA.L <mem>,Ax
 (4) F<op.B> で使用されているアドレスレジスタに、ロングワードサイズのデ
ータを、メモリからロードする MOVEA 命令。

(3) MOVEA.L <mem>,Ay
 (5) <op.C> で使用されているアドレスレジスタに、ロングワードサイズのデ
ータを、メモリからロードする MOVEA 命令。

(4) F<op.B> (Ax)
 アドレスレジスタ間接アドレッシングモードを使用してオペランドを read ま
たは write する浮動小数点命令。

(5) <op.C> (Ay)
 アドレスレジスタ間接アドレッシングモードを使用してオペランドを read ま
たは write する整数命令または浮動小数点命令。

 以上の条件が満たされると、(4) F<op.B> (Ax) で Ax の代わりに Ay を使用
してしまう可能性があり、その結果として、浮動小数点レジスタに誤ったデータ
が転送されたり、場合によっては予期しない浮動小数点例外が発生する可能性が
あります。

 このエラッタは 68060 の F43G マスクセットに特有のもので、G65V 以降のマ
スクセットには存在しません。

 Motorola は、このエラッタを回避する手段として (1) F<op.A> の直後に NOP
命令を挿入してパイプラインを一掃することを推奨しています。

・HAS060.X における対策

 HAS060.X は上記の条件に合う命令列を自動的かつなるべく正確に検出し、推
奨に従って (1) F<op.A> の直後に NOP 命令を挿入します((1) F<op.A> の命令
長が 1 ワード長くなります)。同時に、エラッタの対策のために NOP 命令が挿
入されたことをワーニングで通知します。

 このエラッタの対策によって、5 命令からなる命令列の 1 番目の浮動小数点
命令の見掛けの命令長が 1 ワード長くなるので注意して下さい。

・サンプル

        foo.c
      ┌────────────────────────────
     1│double x, a=2.0, c=5.0, d=7.0;
     2│int b=3;
     3│double *pa=&a, *pc=&c, *pd=&d;
     4│int *pb=&b;
     5│void main()
     6│{
     7│  x=(double)*pb**pa+*pc**pd;
     8│}

 このプログラムを、真里子版の GCC.X(gcc version 1.30 Tool#2(X680x0))
を用いて以下の手順でコンパイルします。最適化は行いません。

        > set 真里子= AB
        > set GCC_OPTION= LFIAMWGTO+
        > gcc -S -m68020 -m68881 foo.c

 すると、次のようなソースリスト(抜粋)が生成されます。この中にエラッタ
F6 に該当する命令列が存在します。

        foo.s(抜粋)
      ┌────────────────────────────
    51│        fmovem.x fp2/fp3,-(sp)
    52│        move.l _pb,a0
    53│        move.l (a0),d0
    54│        fmove.l d0,fp0
    55│        move.l _pa,a0
    56│        fmove.d (a0),fp1
    57│        fmul.x fp1,fp0          }
    58│        move.l _pc,a0           } エラッタの影響を受ける
    59│        move.l _pd,a1           } 可能性がある部分
    60│        fmove.d (a0),fp1        }
    61│        fmove.d (a1),fp2        }
    62│        fmul.x fp2,fp1
    63│        fmove.x fp0,fp3
    64│        fadd.x fp1,fp3
    65│        fmove.d fp3,_x
    66│?2:
    67│        fmovem.x -24(a6),fp2/fp3
    68│        unlk a6
    69│        rts

 これを HAS060.X でアセンブルします。

        > has060 -p foo.s

 すると、以下のようなアセンブルリストが得られます。ワーニングの下の
4E71 が、エラッタ F6 の対策のために挿入された NOP 命令です。

        foo.prn(抜粋)
      ┌────────────────────────────
    77│   50 0000002E 4E560000                 link a6,#0
    78│   51 00000032 F227E00C                 fmovem.x fp2/fp3,-(sp)
    79│   52 00000036 2079(02)00000028         move.l _pb,a0
    80│   53 0000003C 2010                     move.l (a0),d0
    81│   54 0000003E F2004000                 fmove.l d0,fp0
    82│   55 00000042 2079(02)0000001C         move.l _pa,a0
    83│   56 00000048 F2105480                 fmove.d (a0),fp1
    84│foo.s               57: Warning: 浮動小数点命令の直後に NOP を挿入しました (エラッタ対策)
    85│   57 0000004C F20004234E71             fmul.x fp1,fp0
    86│   58 00000052 2079(02)00000020         move.l _pc,a0
    87│   59 00000058 2279(02)00000024         move.l _pd,a1
    88│   60 0000005E F2105480                 fmove.d (a0),fp1
    89│   61 00000062 F2115500                 fmove.d (a1),fp2
    90│   62 00000066 F20008A3                 fmul.x fp2,fp1
    91│   63 0000006A F2000180                 fmove.x fp0,fp3
    92│   64 0000006E F20005A2                 fadd.x fp1,fp3
    93│   65 00000072 F2397580????????         fmove.d fp3,_x
    94│   66 0000007A                  ?2:
    95│   67 0000007A F22ED030FFE8             fmovem.x -24(a6),fp2/fp3
    96│   68 00000080 4E5E                     unlk a6
    97│   69 00000082 4E75                     rts


●エラッタ I11(MOVE to USP 命令の不具合)

・エラッタの内容

 68060(F43G および G65V マスクセット)において、0 サイクルの分岐命令で
分岐キャッシュがヒットしたが分岐予測が間違っていたとき、間違って予測され
た分岐先の先頭が MOVE to USP 命令だとそれが誤って実行されてしまいます。

 Motorola は、このエラッタを回避する手段として次の 2 つの方法を挙げてい
ます。

        (1) MOVE to USP 命令の代わりに MOVEC 命令を使う
        (2) MOVE to USP 命令を条件分岐命令の分岐先の先頭に置かない

・HAS060.X における対策

 上記の (1) の方法ではアセンブル対象の CPU が 68000 の場合に対応できな
いので、HAS060.X では (2) の方法でエラッタ I11 を回避します。

 具体的には、テキストセクションで MOVE to USP 命令が使用されたとき、行
頭にラベルがあるならば、ラベルと MOVE to USP 命令の間に MOVEA.L A0,A0 命
令を挟みます。同時に、エラッタの対策のために MOVEA.L A0,A0 命令が挿入さ
れたことをワーニングで通知します。

 行頭にラベルが定義されていない MOVE to USP 命令は変化しません。また、
データセクションに記述した MOVE to USP 命令も変化しません。

 このエラッタの対策によって、MOVE to USP 命令の見掛けの命令長が 1 ワー
ド長くなるので注意して下さい。

・サンプル

        foo.s
      ┌────────────────────────────
     1│main::
     2│        movea.l #4,a0
     3│loop:
     4│        move.l  a0,usp
     5│        bsr     sub
     6│        cmpa.l  #0,a0
     7│        bne     loop
     8│        rts
     9│
    10│sub:
    11│        move.l  usp,a0
    12│        subq.l  #2,a0
    13│        rts

 このプログラムの main はスーパーバイザモードで呼び出されます。main か
ら復帰したとき、USP の値は 2 になっているはずですが、実際にこれを HAS.X
v3.09 でアセンブルして 68060 の F43G または G65V マスクセットで実行して
みると、USP の値が 0 になった状態で復帰してしまいます。これは、エラッタ
I11 の影響です。具体的には、A0 レジスタの値が 4→2→0 と減って最後に 7
行目の条件分岐命令を通過するとき、分岐予測が 4 行目の MOVE to USP 命令を
指しており、それをエラッタの影響で誤って実行してしまうため、USP が 0 に
なってしまうのです。

 これを HAS060.X でアセンブルします。

        > has060 -p foo.s

 すると、以下のようなアセンブルリストが得られます。アセンブルリストの
11 行目の 2048 が、エラッタ I11 の対策のために挿入された MOVEA.L A0,A0
命令です。

        foo.prn(抜粋)
      ┌────────────────────────────
     6│foo.s                4: Warning: MOVE to USP の直前に MOVEA.L A0,A0 を挿入しました (エラッタ対策)
     7│<foo.s>
     8│    1 00000000                  main::
     9│    2 00000000 207C00000004             movea.l #4,a0
    10│    3 00000006                  loop:
    11│    4 00000006 20484E60                 move.l  a0,usp
    12│    5 0000000A 610A_00000016            bsr     sub
    13│    6 0000000C B1FC00000000             cmpa.l  #0,a0
    14│    7 00000012 66F2_00000006            bne     loop
    15│    8 00000014 4E75                     rts
    16│    9 00000016                  
    17│   10 00000016                  sub:
    18│   11 00000016 4E68                     move.l  usp,a0
    19│   12 00000018 5588                     subq.l  #2,a0
    20│   13 0000001A 4E75                     rts



━< ローカルラベルの拡張 >━━━━━━━━━━━━━━━━━━━━━━

●ローカルラベル 10:〜9999:

 HAS.X v3.09 ではローカルラベルとして @@: および 1:〜9: が使用可能でし
たが、HAS060.X では 10:〜9999: も使えるようになっています。使い方は
1:〜9: と同じです。

        例: 2 桁のローカルラベル
      ┌────────────────────────────
      │                :
      │        BRA     37F             ────────┐
      │29:                             ←───┐      │
      │                :                       │      │
      │                :                       │      │
      │37:                             ←───┼───┘
      │        DBRA    D0,29B          ────┘
      │                :

※ローカルラベルは大変便利ですが、広範囲に渡って使用するとメンテナンス効
率の悪いプログラムになってしまいますから注意しましょう。


補足:
         HAS.X v3.09 のマニュアルには明記されていませんでしたが、
        HAS.X v3.09 では @@B や @@@F などのローカルラベル参照が
        可能です。@@B は「2 つ前の @@:」、@@@F は「3 つ後の @@:」
        を意味しています。勿論、HAS060.X でも同様です。

        例: ローカルラベルの参照
      ┌────────────────────────────
      │        MOVEQ.L #16-1,D1
      │@@:     MOVEQ.L #16-1,D0        ←───────┐
      │@@:                             ←───┐      │
      │                :                       │      │
      │        DBRA    D0,@B           ────┘      │
      │        DBRA    D1,@@B          ────────┘



━< 単一命令の最適化 >━━━━━━━━━━━━━━━━━━━━━━━━

 単一命令の最適化とは、1 つの命令を SR の変化も含めて同じ結果を得られる
別の命令列に置き換えることで、その命令の実行に必要なクロックサイクル数や
命令長を減らす機能です。

 HAS.X v3.09 でも数種類の最適化が行われていましたが、HAS060.X ではコマ
ンドラインスイッチ -c4 を指定することで HAS.X v3.09 よりも多種の最適化を
行うことができます。

 最適化が行われた場合、ソースリストに記述された命令とは異なる命令が出力
されたり、命令が削除されることがあります。この結果、必要に応じて適した方
法で最適化を抑制しなければ正常に動作しないオブジェクトが生成される可能性
があります。特に自己書き換えを行うプログラムや、単純計算で求めたインデッ
クスを使って命令の並びの途中に飛び込むようなプログラムに対して最適化機能
を使用する場合は、十分な注意が必要です。


●単一命令の最適化の抑制

 最適化の対象となるイミディエイトオペランドやディスプレースメントにサイ
ズを付加すると、その命令は最適化されません。

 一部の最適化は、アセンブル対象の CPU によって抑制されます。

 分岐命令の最適化はオペレーションサイズを明記することで抑制できます。

 コマンドラインスイッチ -c0 を指定すると、すべての最適化が禁止されます。


●従来から行われていた単一命令の最適化

 以下の最適化は HAS.X v3.09 でサポートされていたものです。HAS060.X も標
準でこれらの最適化を行います。

        最適化前                  最適化後                      *備考

        ADD.bwl #<d3>,Dn      →  ADDQ.bwl #<d3>,Dn

        Bcc <label>           →  削除                          *直後への条件付きジャンプ

        BRA <label>           →  削除                          *直後への無条件ジャンプ

        FBcc <label>          →  削除                          *直後への条件付きジャンプ

        JBcc <label>          →  削除                          *直後への条件付きジャンプ

        JBRA <label>          →  削除                          *直後への無条件ジャンプ

        MOVE.L #<d8>,Dn       →  MOVEQ.L #<d8>,Dn

        PBcc <label>          →  削除                          *直後への条件付きジャンプ

        SUB.bwl #<d3>,Dn      →  SUBQ.bwl #<d3>,Dn

 これらの最適化は、コマンドラインスイッチ -c0(すべての最適化の禁止)を
指定することで禁止できます。


●追加された単一命令の最適化

 以下の最適化は HAS.X v3.09 ではサポートされておらず、HAS060.X で追加さ
れたものです。これらの最適化は、コマンドラインスイッチ -c4 を指定するこ
とで有効になります。

        最適化前                  最適化後              *備考

        ADDA.wl #0,An         →  削除
        ADDA.wl #<d3>,An      →  ADDQ.W #<d3>,An
        ADDA.wl #-<d3>,An     →  SUBQ.W #<d3>,An
        ADDA.wl #<d16>,An     →  LEA.L (<d16>,An),An   *0,<d3>,-<d3>を除く
        ADDA.L #32768,An      →  SUBA.W #-32768,An

        ADDI.bwl #<d3>,<ea>   →  ADDQ.bwl #<d3>,<ea>

        ASL.bwl #1,Dn         →  ADD.bwl Dn,Dn         *68060を除く

        BSR <label>           →  PEA.L (2,PC)          *直後へのサブルーチンコール

        CLR.L Dn              →  MOVEQ.L #0,Dn         *68020以上を除く

        CMP.bwl #0,Dn         →  TST.bwl Dn

        CMPA.wl #0,An         →  TST.L An              *68020以上
        CMPA.L #<d16>,An      →  CMPA.W #<d16>,An      *68020以上では0を除く

        CMPI.bwl #0,<ea>      →  TST.bwl <ea>

        JBSR <label>          →  PEA.L (2,PC)          *直後へのサブルーチンコール

        JMP (2,PC)            →  削除
        JMP (<label>,PC)      →  削除                  *直後へのジャンプ
        JMP (<label>,PC)      →  JBRA <label>          *直後へのジャンプを除く
        JMP <label>           →  削除                  *直後へのジャンプ
        JMP <label>           →  JBRA <label>          *直後へのジャンプを除く

        JSR (2,PC)            →  PEA.L (2,PC)
        JSR (<label>,PC)      →  PEA.L (2,PC)          *直後へのサブルーチンコール
        JSR (<label>,PC)      →  JBSR <label>          *直後へのサブルーチンコールを除く
        JSR <label>           →  PEA.L (2,PC)          *直後へのサブルーチンコール
        JSR <label>           →  JBSR <label>          *直後へのサブルーチンコールを除く

        LEA.L 0,An            →  SUBA.L An,An
        LEA.L (An),An         →  削除
        LEA.L (0,An),An       →  削除
        LEA.L (<d3>,An),An    →  ADDQ.W #<d3>,An
        LEA.L (-<d3>,An),An   →  SUBQ.W #<d3>,An

        MOVE.bw #0,Dn         →  CLR.bw Dn

        MOVEA.L An,An         →  削除
        MOVEA.wl #0,An        →  SUBA.L An,An
        MOVEA.L #<d16>,An     →  MOVEA.W #<d16>,An     *0を除く

        SUBA.wl #0,An         →  削除
        SUBA.wl #<d3>,An      →  SUBQ.W #<d3>,An
        SUBA.wl #-<d3>,An     →  ADDQ.W #<d3>,An
        SUBA.wl #-<d16>,An    →  LEA.L (<d16>,An),An   *0,<d3>,-<d3>を除く
        SUBA.L #-32768,An     →  SUBA.W #-32768,An

        SUBI.bwl #<d3>,<ea>   →  SUBQ.bwl #<d3>,<ea>

注意:
         JSR <label> → JBSR <label> の最適化は、JSR <label> が
        BSR.W <label> に変化する可能性があることを意味しています。
        特に JSR <label> の <label> が外部参照だった場合は、-e
        (外部参照オフセットのデフォルトをロングワードにする)ま
        たは -1(絶対ロング→PC間接(-b1と-eを伴う))を指定しない
        と JSR <label> が BSR.W <label> に変化します。これでは大
        きな実行ファイルを作ろうとしたときにリンカでエラーが出て
        しまうので、-c4 を指定するときは必要に応じて -e も指定
        する必要があります。特にライブラリを生成するときは、実行
        ファイルのサイズが不確定ですから、-c4 を指定するときは必
        ず -e も指定するようにして下さい。



━< 存在しない命令の解釈 >━━━━━━━━━━━━━━━━━━━━━━

 HAS.X v3.09 では、本来は存在しない命令であっても記述が許されているもの
がありました。以下に、そのような存在しない命令がどのように解釈されるかを
まとめておきます。これらの解釈は HAS060.X でも同様です。


●存在しない条件の解釈

        記述                      解釈                          *備考

        BHS.swl <label>       →  BCC.swl <label>
        BLO.swl <label>       →  BCS.swl <label>
        BNZ.swl <label>       →  BNE.swl <label>
        BZE.swl <label>       →  BEQ.swl <label>

        DBHS.W Dn,<label>     →  DBCC.W Dn,<label>
        DBLO.W Dn,<label>     →  DBCS.W Dn,<label>
        DBNZ.W Dn,<label>     →  DBNE.W Dn,<label>
        DBZE.W Dn,<label>     →  DBEQ.W Dn,<label>

        JBHS <label>          →  JBCC <label>
        JBLO <label>          →  JBCS <label>
        JBNZ <label>          →  JBNE <label>
        JBZE <label>          →  JBEQ <label>

        SHS.B <ea>            →  SCC.B <ea>
        SLO.B <ea>            →  SCS.B <ea>
        SNZ.B <ea>            →  SNE.B <ea>
        SZE.B <ea>            →  SEQ.B <ea>

        TRAPHS                →  TRAPCC
        TRAPLO                →  TRAPCS
        TRAPNZ                →  TRAPNE
        TRAPZE                →  TRAPEQ


●存在しない分岐命令の解釈

 68000/68010 では相対分岐命令のディスプレースメントが符号つき 16bit ま
でしか許されていないため、ディスプレースメントが 16bit に入り切らなくな
ったら自動的に絶対分岐命令に切り替わる分岐命令が用意されています。

        ┏━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
        ┃            表記            │             解釈             ┃
        ┠──────────────┼───────────────┨
        ┃      JBRA    <label>       │ショート/ワードで届くとき     ┃
        ┃                            │        BRA.sw  <label>       ┃
        ┠──────────────┼───────────────┨
        ┃      JBRA    <label>       │ショート/ワードで届かないとき ┃
        ┃                            │        JMP     <label>.L     ┃
        ┠──────────────┼───────────────┨
        ┃      JBSR    <label>       │ショート/ワードで届くとき     ┃
        ┃                            │        BSR.sw  <label>       ┃
        ┠──────────────┼───────────────┨
        ┃      JBSR    <label>       │ショート/ワードで届かないとき ┃
        ┃                            │        JSR     <label>.L     ┃
        ┠──────────────┼───────────────┨
        ┃      JBcc    <label>       │ショート/ワードで届くとき     ┃
        ┃                            │        Bcc.sw  <label>       ┃
        ┠──────────────┼───────────────┨
        ┃      JBcc    <label>       │ショート/ワードで届かないとき ┃
        ┃                            │        BNcc.S  @f          ※┃
        ┃                            │        JMP     <label>.L     ┃
        ┃                            │@@:                           ┃
        ┗━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛

        ※ BNcc は Bcc の条件を逆にした条件分岐命令


●その他の存在しない命令や文法の解釈

        記述                      解釈                          *備考

        ADD.wl <ea>,An        →  ADDA.wl <ea>,An
        ADD.bwl #<data>,<ea>  →  ADDI.bwl #<data>,<ea>         *<ea>はメモリ

        AND.bwl #<data>,<ea>  →  ANDI.bwl #<data>,<ea>         *<ea>はメモリ

        ASL.bwl Dn            →  ASL.bwl #1,Dn

        ASR.bwl Dn            →  ASR.bwl #1,Dn

        CLR.wl An             →  SUBA.wl An,An

        CMP.wl <ea>,An        →  CMPA.wl <ea>,An
        CMP.bwl #<data>,<ea>  →  CMPI.bwl #<data>,<ea>         *<ea>はメモリ
        CMP.bwl (Am)+,(An)+   →  CMPM.bwl (Am)+,(An)+

        DEC.bwl <ea>          →  SUBQ.bwl #1,<ea>

        EOR.bwl #<data>,<ea>  →  EORI.bwl #<data>,<ea>

        FBRA.wl <label>       →  FBT.wl <label>

        FDBRA Dn,<label>      →  FDBF Dn,<label>

        INC.bwl <ea>          →  ADDQ.bwl #1,<ea>

        LSL.bwl Dn            →  LSL.bwl #1,Dn

        LSR.bwl Dn            →  LSR.bwl #1,Dn

        MOVE.wl <ea>,An       →  MOVEA.wl <ea>,An

        OR.bwl #<data>,<ea>   →  ORI.bwl #<data>,<ea>          *<ea>はメモリ

        ROL.bwl Dn            →  ROL.bwl #1,Dn

        ROR.bwl Dn            →  ROR.bwl #1,Dn

        ROXL.bwl Dn           →  ROXL.bwl #1,Dn

        ROXR.bwl Dn           →  ROXR.bwl #1,Dn

        SUB.wl <ea>,An        →  SUBA.wl <ea>,An
        SUB.bwl #<data>,<ea>  →  SUBI.bwl #<data>,<ea>         *<ea>はメモリ



━< 新設された疑似命令 >━━━━━━━━━━━━━━━━━━━━━━━

 HAS060.X では、以下の疑似命令が新設されています。


●疑似命令 .OFFSYM(特定のシンボルを基準としたオフセットセクション)

 疑似命令 .OFFSYM は、疑似命令 .OFFSET を拡張したものです。.OFFSET では
後続のオフセットセクションの先頭のオフセット(ロケーションカウンタ)を指
定していましたが、.OFFSYM では後続のオフセットセクションの任意の位置に記
述しされた特定のシンボルの値を指定することが可能です。値を指定したシンボ
ルよりも手前に記述されたシンボルの値は、アセンブラが自動的に逆算して決定
します。

 従来は .OFFSET でスタックフレームを記述するためには .OFFSET のパラメー
タを個別に指定しなければならず、フレームを変更したときに .OFFSET のパラ
メータの更新を忘れるミスの原因になっていました。.OFFSYM を使用することで
そのようなミスを防ぐことができます。

 また、.OFFSYM で開始したオフセットセクションは .OFFSET で開始したオフ
セットセクションとは異なり、シンボルの二重定義がエラーになりません。この
ため、多数のサブルーチンのスタックフレームを記述する場合に共通のシンボル
を繰り返し使うことができます。

 なお、スイッチ -j を使用することで、.OFFSYM の中でシンボルを定義すると
きに .OFFSYM 以外で定義されたシンボルの上書きを禁止することができます。

        文法: .OFFSYM
      ┌────────────────────────────
      │        .OFFSYM 初期値[,初期値を与えるシンボル]

 初期値を与えるシンボルを指定しなければ、.OFFSET と同様に初期値が先頭の
ロケーションカウンタになります。

 初期値を与えるシンボルを指定した場合、そのシンボルが初期値に一致するよ
うに自動的にロケーションカウンタが調整されます。初期値を与えるシンボルは、
それを指定した .OFFSYM から次のセクションの変更までに定義されなければな
りません。

        例: .OFFSYM によるスタックフレームの構築
      ┌────────────────────────────
      │regs    reg     d0-d7/a0-a5
      │        .offsym 0,_a6                   ;_a6=0になるようにする
      │frmsiz:
      │buf:    .ds.b   256
      │_regs:  .ds.b   .sizeof.(regs)          ;レジスタリストのサイズを
      │_a6:    .ds.l   1                       ;       .SIZEOF.で求める
      │_pc:    .ds.l   1
      │param1: .ds.l   1
      │param2: .ds.l   1
      │        .text
      │        link.w  a6,#frmsiz              ;スタックフレームを確保
      │        movem.l regs,(_regs,a6)         ;汎用レジスタをプッシュ
      │        movem.l (param1,a6),a0-a1       ;引数を取り出す
      │        lea.l   (buf,a6),a2             ;ローカルバッファを参照する
      │                :
      │        movem.l (_regs,a6),regs         ;汎用レジスタをポップ
      │        unlk    a6                      ;スタックフレームを開放
      │        rts                             ;復帰


●疑似命令 .SIZEM(マクロのサイズ指定と引数の個数を受け取るローカルシン
ボルの定義)

 疑似命令 .SIZEM は、マクロの定義中に限って使用することができます。

 .SIZEM の文法は以下の通りです。

        文法: 疑似命令 .SIZEM
      ┌────────────────────────────
      │        .SIZEM  <サイズのシンボル>[,<引数の個数のシンボル>]

 .SIZEM は、マクロに指定されたオペレーションサイズと、マクロに渡された
引数の個数を、それぞれ受け取るためのローカルシンボルを定義するための疑似
命令です。この疑似命令を使うことで、マクロに指定されたオペレーションサイ
ズや、マクロに渡された引数の個数を、マクロの中で使用することができます。

 .SIZEM で定義されたシンボルは、定義中のマクロの中だけで使用できるロー
カルシンボルになります。従って、疑似命令 .LOCAL と同様に、.SIZEM はマク
ロの定義の先頭に記述する必要があります。

 マクロに渡された引数の個数を受け取るシンボルは、マクロを展開したときに
マクロの引数の個数を表す 10 進数の文字列に置き換えられるので、そのまま使
えば定数として解釈されます。また、“&”を使って別のシンボルや文字列に連
結することも可能です。

        例: マクロに渡された引数の個数を使う
      ┌────────────────────────────
      │; not <src>,<dst> のような記述ができるようにするマクロ
      │not     .macro  src,dst
      │                .sizem  sz,cnt
      │                .if     cnt=1
      │                        .not&sz src
      │                .else
      │                        move&sz src,dst
      │                        .not&sz dst
      │                .endm
      │        .endm
      │                                ;展開結果
      │        not.w   d0
      │                                ;       .not.w  d0
      │        not.l   d0,d1
      │                                ;       move.l  d0,d1
      │                                ;       .not.l  d1
      │
      │;単語の個数を書いてからデータを書くマクロ
      │words   .macro  word1,word2,word3
      │                .sizem  sz,cnt
      │                .dc.b   cnt
      │                .if     cnt>=1
      │                        .dc.b   '&word1',0
      │                .if     cnt>=2
      │                        .dc.b   '&word2',0
      │                .if     cnt>=3
      │                        .dc.b   '&word3',0
      │                        .fail   cnt>=4
      │                .endif
      │                .endif
      │                .endif
      │                .dc.b   0
      │        .endm
      │                                ;展開結果
      │        words
      │                                ;       .dc.b   0
      │                                ;       .dc.b   0
      │        words   one
      │                                ;       .dc.b   1
      │                                ;       .dc.b   'one',0
      │                                ;       .dc.b   0
      │        words   one,two
      │                                ;       .dc.b   2
      │                                ;       .dc.b   'one',0
      │                                ;       .dc.b   'two',0
      │                                ;       .dc.b   0

 マクロのオペレーションサイズの指定については、後述の<マクロのオペレー
ションサイズ>の項目を参照して下さい。


●疑似命令 .INSERT(任意のファイルをオブジェクトに取り込む)

 疑似命令 .INSERT は、例えば PCM データのように、ソースリストとは別のフ
ァイルで用意された任意のデータを直接オブジェクトに埋め込みたいときに使い
ます。

 .INSERT の文法は以下の通りです。

        文法: 疑似命令 .INSERT
      ┌────────────────────────────
      │        .INSERT <ファイル名>[,<オフセット>[,<サイズ>]]…

 オフセットは、ファイルの先頭から取り込みを開始する位置までのオフセット
です。

 サイズは、実際に取り込むデータのバイト数です。

 オフセットとサイズのペアは“,”で区切って複数指定できます。

 オフセットとサイズのペアが 1 つも指定されなかったときは、ファイルの全
体を取り込みます。

 サイズが省略された場合、または、サイズに -1 が指定された場合は、ファイ
ルの末尾まで取り込みます。

        例: SAMPLE.PCM を埋め込む
      ┌────────────────────────────
      │PCM_DATA:
      │        .INSERT SAMPLE.PCM

        例: HUMAN.SYS の 65 バイト目から末尾まで取り込む
      ┌────────────────────────────
      │X_FILE_IMAGE:
      │        .INSERT HUMAN.SYS,64

        例: NORMAL.FON の先頭から 4096 バイトを取り込む
      ┌────────────────────────────
      │FONT_DATA:
      │        .INSERT NORMAL.FON,0,4096

        例: NORMAL.FON の 16*'A'+1 バイト目から 16 バイトと
            16*'a'+1 バイト目から 16 バイトを続けて取り込む
      ┌────────────────────────────
      │FONT_Aa:
      │        .INSERT NORMAL.FON,16*'A',16,16*'a',16



━< 新設された演算子 >━━━━━━━━━━━━━━━━━━━━━━━━

 HAS060.X では、以下の演算子が新設されています。


● .SIZEOF.(〜)(レジスタリストや文字列の占有バイト数を求める)

 .SIZEOF.(〜) は、括弧内に記述したレジスタリストまたは文字列の占有バイ
ト数を求める演算子です。

 .SIZEOF.(〜) の括弧内には、以下の引数を指定できます。

      ┏━━━━━━━━━━━━━━┯━━━━━━━━┯━━━━━━━┓
      ┃         引数の種類         │     表記例     │ .SIZEOF.の値 ┃
      ┠──────────────┼────────┼───────┨
      ┃汎用レジスタリスト          │D0-D7/A0-A7     │レジスタ数*4  ┃
      ┃浮動小数点レジスタリスト    │FP0-FP7         │レジスタ数*12 ┃
      ┃浮動小数点制御レジスタリスト│FPCR/FPSR/FPIAR │レジスタ数*4  ┃
      ┃文字列                      │'〜',"〜"       │文字列の長さ  ┃
      ┗━━━━━━━━━━━━━━┷━━━━━━━━┷━━━━━━━┛

 .SIZEOF.(〜) の値は、データの最大のバイト数になっています。例えば、汎
用レジスタならば、ロングワードサイズで転送する場合の転送バイト数を示して
います。汎用レジスタをワードサイズで転送するときの転送バイト数は、
.SIZEOF.(〜) の結果を 2 で割って求める必要があります。浮動小数点レジスタ
をシングルサイズやダブルサイズで転送する場合も同様です。

 レジスタリストや文字列は“,”(コンマ)で区切って複数指定できます。ま
た、疑似命令 .DC と同様に、複数の文字列を“,”(コンマ)で区切らずに直接
連結して記述することができます。

        例: .SIZEOF.(〜) によるレジスタリストのサイズの計算
      ┌────────────────────────────
      │regs    reg     d0-d7/a0-a5
      │        .offsym 0,_a6                   ;_a6=0になるようにする
      │frmsiz:
      │buf:    .ds.b   256
      │_regs:  .ds.b   .sizeof.(regs)          ;レジスタリストのサイズを
      │_a6:    .ds.l   1                       ;       .SIZEOF.で求める
      │_pc:    .ds.l   1
      │param1: .ds.l   1
      │param2: .ds.l   1
      │        .text
      │        link.w  a6,#frmsiz              ;スタックフレームを確保
      │        movem.l regs,(_regs,a6)         ;汎用レジスタをプッシュ
      │        movem.l (param1,a6),a0-a1       ;引数を取り出す
      │        lea.l   (buf,a6),a2             ;ローカルバッファを参照する
      │                :
      │        movem.l (_regs,a6),regs         ;汎用レジスタをポップ
      │        unlk    a6                      ;スタックフレームを開放
      │        rts                             ;復帰

        例: .SIZEOF. における文字列の連結
      ┌────────────────────────────
      │version reg     '15'
      │        .dc.b   .sizeof.('2.'version),'2.'version,0


● .DEFINED.(シンボルが定義されているかどうかを調べる)

 .DEFINED. は、シンボルが定義されているかどうかを調べる演算子です。次の
いずれかの形式で使用します。

        .DEFINE.<symbol>
        .DEFINE.(<symbol>)

 .DEFINED. は、シンボルが定義されていれば -1、定義されていなければ 0 を
返します。

 .DEFINED. を使うと、疑似命令 .IFDEF では記述しにくいアセンブル条件が記
述できるようになります。

        例: 「シンボル __68030__ と __68040__ の少なくともどちら
            か一方でも定義されている」という条件
      ┌────────────────────────────
      │        .if (.defined.__68030__).or.(.defined.__68040__)
      │                :
      │        .endif


● .NOTB./.NOTW.(.NOT.の結果のサイズを制限する)

 .NOTB. と .NOTW. は .NOT. の変化形です。それぞれ、次のように定義されて
います。

        .NOTB.<式> ::= (.NOT.<式>).AND.$FF
        .NOTW.<式> ::= (.NOT.<式>).AND.$FFFF

 従来、バイトサイズまたはワードサイズのデータを .NOT. を使ってビット単
位で論理否定しようとすると、本来のデータのサイズに含まれない上位のビット
がセットされてしまって不便でした。

        例: .NOT. が期待通りに働かない例
      ┌────────────────────────────
      │foo     equ     %10000000
      │        .dc.b   .not.foo

 上の例では、プログラムを書いた本人は .not.foo の部分が %01111111 にな
ることを期待しているのですが、実際には
.not.%10000000=%11111111_11111111_11111111_01111111 ですから、結果がバイ
トサイズに収まっていないのでエラーになってしまいます。そのため、次のよう
に冗長に記述しなければなりませんでした。

        例: .NOT. が冗長になる例
      ┌────────────────────────────
      │foo     equ     %10000000
      │        .dc.b   (.not.foo).and.$FF
または、
      │        .dc.b   foo.xor.$FF

 そこで、HAS060.X では、ビット単位で論理否定した上で上位の不要なビット
をクリアする演算子を新設しました。それが .NOTB. と .NOTW. です。上の例は
次のように記述できます。

        例: .NOTB. の例
      ┌────────────────────────────
      │foo     equ     %10000000
      │        .dc.b   .notb.foo

 .NOT.W も同様です。

        例: .NOTW. の例
      ┌────────────────────────────
      │foo     equ     %10000000_00000000
      │        .dc.w   .notw.foo

補足:
         リンカが .NOTB./.NOTW. に相当する演算機能を持っていな
        いので、式に外部参照シンボルが含まれていて演算をリンカに
        委ねなければならない場合は、.NOTB./.NOTW. を前述の定義通
        りの式に展開した上でオブジェクトファイルに出力されます。



━< 演算子のまとめ >━━━━━━━━━━━━━━━━━━━━━━━━━

 HAS060.X で使用できる演算子をまとめておきます。前述の<新設された演算
子>で説明したもの以外は、すべて HAS.X v3.09 でも使えるものです。

        単項演算子
        ┏━━━━━━━┯━━━━━━━━━━━━━━━━━━━┓
        ┃     記述     │                 意味                 ┃
        ┣━━━━━━━┿━━━━━━━━━━━━━━━━━━━┫
        ┃.neg.X        │符号反転 (-X)                         ┃
        ┃-X            │                                      ┃
        ┠───────┼───────────────────┨
        ┃.pos.X        │Xをそのまま返す (+X)                  ┃
        ┃+X            │                                      ┃
        ┠───────┼───────────────────┨
        ┃.not.X        │Xのビット単位の論理否定               ┃
        ┠───────┼───────────────────┨
        ┃.notb.X       │Xのビット単位の論理否定の最下位バイト ┃
        ┃              │((.not.X)&$FF)                        ┃
        ┠───────┼───────────────────┨
        ┃.notw.X       │Xのビット単位の論理否定の下位ワード   ┃
        ┃              │((.not.X)&$FFFF)                      ┃
        ┠───────┼───────────────────┨
        ┃.high.X       │Xの下位ワードの上位バイトを取り出す   ┃
        ┃              │((X>>8)&$FF)                          ┃
        ┠───────┼───────────────────┨
        ┃.low.X        │Xの最下位バイトを取り出す (X&$FF)     ┃
        ┠───────┼───────────────────┨
        ┃.highw.X      │Xの上位ワードを取り出す               ┃
        ┃              │((X>>16)&$FFFF)                       ┃
        ┠───────┼───────────────────┨
        ┃.loww.X       │Xの下位ワードを取り出す (X&$FFFF)     ┃
        ┠───────┼───────────────────┨
        ┃.nul.X        │Xに関係なく常に0を返す                ┃
        ┗━━━━━━━┷━━━━━━━━━━━━━━━━━━━┛

        二項演算子
        ┏━━━━━━━┯━━━━━━━━━━━━━━━━━━━┓
        ┃     記述     │                 意味                 ┃
        ┣━━━━━━━┿━━━━━━━━━━━━━━━━━━━┫
        ┃X.mul.Y       │乗算 (XにYを掛けた結果)               ┃
        ┃X*Y           │                                      ┃
        ┠───────┼───────────────────┨
        ┃X.div.Y       │除算 (XをYで割った結果の商)           ┃
        ┃X/Y           │                                      ┃
        ┠───────┼───────────────────┨
        ┃X.mod.Y       │剰余算 (XをYで割った結果の余り)       ┃
        ┠───────┼───────────────────┨
        ┃X.shr.Y       │Xを右にYビットシフト                  ┃
        ┃X>>Y          │                      (符号なしシフト)┃
        ┠───────┼───────────────────┨
        ┃X.shl.Y       │Xを左にYビットシフト                  ┃
        ┃X.<<.Y        │                                      ┃
        ┃X<<Y          │                                      ┃
        ┠───────┼───────────────────┨
        ┃X.asr.Y       │Xを右にYビットシフト                  ┃
        ┃X.>>.Y        │                      (符号ありシフト)┃
        ┠───────┼───────────────────┨
        ┃X.sub.Y       │減算 (XからYを引いた結果)             ┃
        ┃X-Y           │                                      ┃
        ┠───────┼───────────────────┨
        ┃X.add.Y       │加算 (XにYを加えた結果)               ┃
        ┃X+Y           │                                      ┃
        ┠───────┼───────────────────┨
        ┃X.eq.Y        │XとYが等しければ-1,異なれば0          ┃
        ┃X=Y           │                                      ┃
        ┃X==Y          │                                      ┃
        ┠───────┼───────────────────┨
        ┃X.ne.Y        │XとYが異なれば-1,等しければ0          ┃
        ┃X<>Y          │                                      ┃
        ┃X!=Y          │                                      ┃
        ┠───────┼───────────────────┨
        ┃X.lt.Y        │XがYよりも小さければ-1,               ┃
        ┃X<Y           │大きいか等しければ0     (符号なし比較)┃
        ┠───────┼───────────────────┨
        ┃X.le.Y        │XがYよりも小さいか等しければ-1,       ┃
        ┃X<=Y          │大きければ0             (符号なし比較)┃
        ┠───────┼───────────────────┨
        ┃X.gt.Y        │XがYよりも大きければ-1,               ┃
        ┃X>Y           │小さいか等しければ0     (符号なし比較)┃
        ┠───────┼───────────────────┨
        ┃X.ge.Y        │XがYよりも大きいか等しければ-1,       ┃
        ┃X>=Y          │小さければ0             (符号なし比較)┃
        ┠───────┼───────────────────┨
        ┃X.slt.Y       │XがYよりも小さければ-1,               ┃
        ┃X.<.Y         │大きいか等しければ0     (符号あり比較)┃
        ┠───────┼───────────────────┨
        ┃X.sle.Y       │XがYよりも小さいか等しければ-1,       ┃
        ┃X.<=.Y        │大きければ0             (符号あり比較)┃
        ┠───────┼───────────────────┨
        ┃X.sgt.Y       │XがYよりも大きければ-1,               ┃
        ┃X.>.Y         │小さいか等しければ0     (符号あり比較)┃
        ┠───────┼───────────────────┨
        ┃X.sge.Y       │XがYよりも大きいか等しければ-1,       ┃
        ┃X.>=.Y        │小さければ0             (符号あり比較)┃
        ┠───────┼───────────────────┨
        ┃X.and.Y       │XとYのビット単位の論理積              ┃
        ┃X&Y           │                                      ┃
        ┠───────┼───────────────────┨
        ┃X.xor.Y       │XとYのビット単位の排他的論理和        ┃
        ┃X.eor.Y       │                                      ┃
        ┃X^Y           │                                      ┃
        ┠───────┼───────────────────┨
        ┃X.or.Y        │XとYのビット単位の論理和              ┃
        ┃X|Y           │                                      ┃
        ┗━━━━━━━┷━━━━━━━━━━━━━━━━━━━┛



━< 追加・変更された命令と疑似命令 >━━━━━━━━━━━━━━━━━

 HAS060.X では、一部の命令や疑似命令について、まったく同じ意味を持つ別
の名前が定義されています。


● Bcc/JBcc/DBcc/Scc/TRAPcc の別名

 Bcc/JBcc/DBcc/Scc/TRAPcc の cc の部分を Ncc と記述することによって、逆
の条件の命令として解釈されます。Ncc と cc の対応は以下の通りです。

                ┏━━━━━━━┯━━━━━━━┓
                ┃      Ncc     │      cc      ┃
                ┠───────┼───────┨
                ┃      NCC     │      CS      ┃
                ┃      NCS     │      CC      ┃
                ┃      NEQ     │      NE      ┃
                ┃      NF      │      T       ┃
                ┃      NGE     │      LT      ┃
                ┃      NGT     │      LE      ┃
                ┃      NHI     │      LS      ┃
                ┃      NHS     │      CS      ┃
                ┃      NLE     │      GT      ┃
                ┃      NLO     │      CC      ┃
                ┃      NLS     │      HI      ┃
                ┃      NLT     │      GE      ┃
                ┃      NMI     │      PL      ┃
                ┃      NNE     │      EQ      ┃
                ┃      NNZ     │      EQ      ┃
                ┃      NPL     │      MI      ┃
                ┃      NT      │      F       ┃
                ┃      NVC     │      VS      ┃
                ┃      NVS     │      VC      ┃
                ┃      NZE     │      NE      ┃
                ┗━━━━━━━┷━━━━━━━┛

 この機能は、マクロの定義で機械的に条件を逆にしたいときに便利です。

        例: 条件を逆にして使うマクロ
      ┌────────────────────────────
      │        .irp %cc,t,f,hi,ls,cc,hs,cs,lo,ne,nz,eq,ze,vc,vs,pl,mi,ge,lt,gt,le
      │if%cc           .macro  op
      │                        .sizem  sz
      │                        bn%cc&&sz       @skip
      │                        op
      │@skip:
      │                .endm
      │        .endm
      │                                        ;展開結果
      │        subq.w  #1,d0                   ;       subq.w  #1,d0
      │        ifeq.s  <moveq.l #10,d0>
      │                                        ;       bneq.s  ??0001
      │                                        ;       moveq.l #10,d0
      │                                        ;??0001:


● TRAPcc を TPcc と記述できる

 TRAPcc を TPcc と表記することができます。


● JBRA/JBSR/JBcc にサイズを指定できる

 HAS060.X では、JBcc.L という表記が可能です。つまり、68000 用のプログラ
ムで条件分岐命令にロングワードサイズを強制的に指定することができます。
JBcc.L 命令の長さは 8 バイト、命令の先頭からオペランドまでのオフセットは
+4 です。

        ┏━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
        ┃            表記            │             解釈             ┃
        ┠──────────────┼───────────────┨
        ┃      JBRA.sw <label>       │        BRA.sw  <label>       ┃
        ┠──────────────┼───────────────┨
        ┃      JBRA.L  <label>       │        JMP     <label>.L     ┃
        ┠──────────────┼───────────────┨
        ┃      JBSR.sw <label>       │        BSR.sw  <label>       ┃
        ┠──────────────┼───────────────┨
        ┃      JBSR.L  <label>       │        JSR     <label>.L     ┃
        ┠──────────────┼───────────────┨
        ┃      JBcc.sw <label>       │        Bcc.sw  <label>       ┃
        ┠──────────────┼───────────────┨
        ┃      JBcc.L  <label>       │        BNcc.S  @f            ┃
        ┃                            │        JMP     <label>.L     ┃
        ┃                            │@@:                           ┃
        ┠──────────────┼───────────────┨
        ┃      JBNcc.sw <label>      │        BNcc.sw <label>       ┃
        ┠──────────────┼───────────────┨
        ┃      JBNcc.L <label>       │        Bcc.S   @f            ┃
        ┃                            │        JMP     <label>.L     ┃
        ┃                            │@@:                           ┃
        ┗━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛

注意:
         上記の展開後のコードで使用しているローカルラベルは、説
        明のために記述したものであって、実際にローカルラベルが消
        費されるわけではありません(マクロ展開とは異なります)。


● .ELSEIF の別名

 .ELSEIF を .ELIF と記述できます。


●疑似命令 .DC のデータに個別にサイズを指定できる

 HAS060.X では疑似命令 .DC で記述するデータに個別にサイズを指定できるの
で、サイズの異なるデータが混在しているテーブルを見やすい形で書くことがで
きます。

 個々のデータのサイズ指定が優先されますが、サイズが指定されなかったデー
タのサイズは従来通り .DC のサイズに従います。

        例: .DC のデータに個別にサイズを指定する
      ┌────────────────────────────
      │code1:
      │                :
      │
      │code2:
      │                :
      │
      │base:
      │        .dc.w   name1-base,code1.l      ;2+4=6バイトのデータ
      │        .dc.w   name2-base,code2.l
      │                :
      │        .dc.w   0
      │
      │name1:  .dc.b   'one',0
      │name2:  .dc.b   'two',0
      │                :

 なお、この機能は整数(.B/.W/.L)の場合に限ります。.DC.B/.DC.W/.DC.L の
データに浮動小数点数のサイズ(.S/.D/.X/.P)を指定することはできません。

 .DC.S/.DC.D/.DC.X/.DC.P のデータにサイズを指定した場合は浮動小数点数の
丸め処理が行われ、データのサイズは変化しません。この動作については、後述
の<浮動小数点数のオペランドのサイズ指定>を参照して下さい。



━< マクロのオペレーションサイズ >━━━━━━━━━━━━━━━━━━

 HAS060.X では、マクロに指定されたオペレーションサイズをマクロの中で使
用することができます。マクロにオペレーションサイズが使えるようになったこ
とで、従来よりも命令に近い形式のマクロや、命令の解釈を変更するためのマク
ロを記述できるようになっています。

参考:
         HAS.X v3.09 では、マクロにサイズを指定すると、無視され
        る場合と、無条件にエラーになってしまう場合があります。

 マクロに指定されたオペレーションサイズを使用するには、新設された疑似命
令 .SIZEM をマクロの定義の先頭に記述して、オペレーションサイズを受け取る
ためのシンボルを指定しなければなりません。.SIZEM の文法については、前述
の<新設された疑似命令>の項目を参照して下さい。

 マクロの展開時に、.SIZEM で定義したシンボルが記述されている行があると、
そのシンボルの部分が、マクロに指定されたオペレーションサイズを示す文字列
に変換されます。具体的には、以下のように変換されます。

                ┏━━━━━━━┯━━━━━━━┓
                ┃  サイズ指定  │   展開結果   ┃
                ┣━━━━━━━┿━━━━━━━┫
                ┃     なし     │     '  '     ┃
                ┃      .B      │     '.b'     ┃
                ┃      .W      │     '.w'     ┃
                ┃      .L      │     '.l'     ┃
                ┃      .S      │     '.s'     ┃
                ┃      .D      │     '.d'     ┃
                ┃      .X      │     '.x'     ┃
                ┃      .P      │     '.p'     ┃
                ┃      .Q      │     '.q'     ┃
                ┗━━━━━━━┷━━━━━━━┛

注意:
         上記の展開結果は '〜' で囲まれていますが、これは説明の
        ためにクォートで囲って記述したもので、実際にはクォートは
        生成されません。

 マクロに指定されたオペレーションサイズを使用する例を示します。

        例: マクロに指定されたオペレーションサイズを使用する
      ┌────────────────────────────
      │copy    .macro  src,dst
      │        .sizem  sz
      │                move&sz src,dst
      │        .endm
      │                                ;       展開結果
      │        copy    (a0)+,(a1)+
      │                                ;       move    (a0)+,(a1)+
      │        copy.b  (a0)+,(a1)+
      │                                ;       move.b  (a0)+,(a1)+
      │        copy.w  (a0)+,(a1)+
      │                                ;       move.w  (a0)+,(a1)+
      │        copy.l  (a0)+,(a1)+
      │                                ;       move.l  (a0)+,(a1)+

        例: マクロに指定されたオペレーションサイズを使用する
      ┌────────────────────────────
      │inc     .macro  an
      │        .sizem  sz
      │                .if     '&sz'='.b'
      │                        addq.l  #1,an
      │                .elseif ('&sz'='  ').or.('&sz'='.w')
      │                        addq.l  #2,an
      │                .elseif ('&sz'='.l').or.('&sz'='.s')
      │                        addq.l  #4,an
      │                .elseif ('&sz'='.d').or.('&sz'='.q')
      │                        addq.l  #8,an
      │                .elseif ('&sz'='.x').or.('&sz'='.p')
      │                        lea.l   (12,an),an
      │                .endif
      │        .endm
      │                                ;       展開結果
      │        inc     a0
      │                                ;       addq.l  #2,a0
      │        inc.b   a0
      │                                ;       addq.l  #1,a0
      │        inc.w   a0
      │                                ;       addq.l  #2,a0
      │        inc.l   a0
      │                                ;       addq.l  #4,a0
      │        inc.s   a0
      │                                ;       addq.l  #4,a0
      │        inc.d   a0
      │                                ;       addq.l  #8,a0
      │        inc.q   a0
      │                                ;       addq.l  #8,a0
      │        inc.x   a0
      │                                ;       lea.l   (12,a0),a0
      │        inc.p   a0
      │                                ;       lea.l   (12,a0),a0

 HAS060.X ではマクロにサイズを指定してもエラーにならないという特徴を利
用すると、命令のサイズを無視させたり、強制的にサイズを変更させるためのマ
クロも作れます。

注意:
         特に命令と同名のマクロを定義するとき、マクロが再帰的に
        展開されてしまわないように注意して下さい(下の例を参照)。

        例: BRA/BSR/Bcc のサイズ指定を強制的に除去する
      ┌────────────────────────────
      │        .irp %cc,ra,sr,hi,ls,cc,hs,cs,lo,ne,nz,eq,ze,vc,vs,pl,mi,ge,lt,gt,le
      │b%cc            .macro  label
      │                        .b%cc   label   ;マクロよりも命令を優先させるため
      │                                        ;命令の手前に'.'が必要
      │                .endm
      │        .endm
      │                                ;       展開結果
      │        bra.w   loop
      │                                ;       .bra    loop
      │        bsr.w   loop
      │                                ;       .bsr    loop
      │        bhi.w   loop
      │                                ;       .bhi    loop



━< マクロの中のローカルシンボルの拡張 >━━━━━━━━━━━━━━━

 HAS060.X では、マクロの中で @ で始まるシンボル(@loop や @exit など)
を使うと、それが自動的にそのマクロの中だけで使えるローカルシンボルになり
ます。つまり、@ で始まるシンボルが .LOCAL で宣言されたように振る舞います。

        例: マクロの中のローカルシンボル
      ┌────────────────────────────
      │wait    .macro  time
      │        .if     time>0
      │        move.w  #time-1,d0
      │@loop:
      │        dbra    d0,@loop
      │        .endif
      │        .endm
      │                                展開結果
      │                              ┌────────────────
      │        wait    1000          │        .if     1000>0
      │                              │        move.w  #1000-1,d0
      │                              │??0001:
      │                              │        dbra    d0,??0001
      │                              │        .endif

 次のようなシンボルは、マクロの中のローカルシンボルとして使えません。

        ・@@ で始まるシンボル(@@ など)
        ・@B と @b、@F と @f



━< プレデファインシンボル >━━━━━━━━━━━━━━━━━━━━━

 プレデファインシンボルは、アセンブラによって自動的に定義および更新され
るシンボルです。これは HAS.X v3.09 には存在せず、HAS060.X で追加された機
能です。

 プレデファインシンボルは、コマンドラインスイッチ -y[1] を指定したとき
だけ有効になります。なお、-y[1] は、-y0 で取り消すことができます。

 プレデファインシンボルを疑似命令 .SET などで更新することはできません。
.SET などで更新しようとするとエラーになります。つまり、プレデファインシ
ンボルを有効にすると、それらと同名のシンボルをユーザが自由に使えなくなる
という欠点があります。

 プレデファインシンボルを疑似命令 .GLOBAL などで外部宣言(外部定義また
は外部参照)することはできません。.GLOBAL などで外部宣言しようとするとエ
ラーになります。

 HAS060.X では、以下のプレデファインシンボルが定義されています。

      ┏━━━━━━━┯━━━━━━━━━━━━━━━━━━━━┓
      ┃   シンボル   │                  内容                  ┃
      ┠───────┼────────────────────┨
      ┃CPU           │現在のアセンブル対象の CPU              ┃
      ┃              │            (68000〜68060、5200〜5400)┃
      ┃__HAS__       │HAS.X のバージョン(309)               ┃
      ┃__HAS060__    │HAS060.X のバージョン(91)             ┃
      ┃__DATE__      │アセンブル開始時の日付                  ┃
      ┃              │      (曜日<<28)+(西暦年<<16)+(月<<8)+日┃
      ┃__TIME__      │アセンブル開始時の時刻                  ┃
      ┃              │                     (時<<16)+(分<<8)+秒┃
      ┗━━━━━━━┷━━━━━━━━━━━━━━━━━━━━┛


●プレデファインシンボル CPU

 プレデファインシンボル CPU は、現在のアセンブル対象の CPU を数値で保持
しており、疑似命令 .CPU によって自動的に更新されます。アセンブル対象の
CPU に応じてプログラムを変化させたい場合などに便利です。プレデファインシ
ンボル CPU の内容は以下の通りです。

        CPU = 68000 … アセンブル対象の CPU が 68000 のとき
        CPU = 68010 … アセンブル対象の CPU が 68010 のとき
        CPU = 68020 … アセンブル対象の CPU が 68020 のとき
        CPU = 68030 … アセンブル対象の CPU が 68030 のとき
        CPU = 68040 … アセンブル対象の CPU が 68040 のとき
        CPU = 68060 … アセンブル対象の CPU が 68060 のとき
        CPU = 5200  … アセンブル対象の CPU が 5200 のとき
        CPU = 5300  … アセンブル対象の CPU が 5300 のとき
        CPU = 5400  … アセンブル対象の CPU が 5400 のとき

        例: プレデファインシンボル CPU
      ┌────────────────────────────
      │*ロングワード絶対アドレスのテーブルを用いたサブルーチンコール
      │        .if     CPU<68020
      │*68000〜68010のとき
      │                asl.l   #2,d0
      │                movea.l (jump_table,pc,d0.l),a0
      │                jsr     (a0)
      │        .else
      │*68020〜68060のとき
      │                jsr     ([jump_table,pc,d0.l*4])
      │        .endif


●プレデファインシンボル __DATE__

 プレデファインシンボル __DATE__ は、アセンブル開始時の曜日と日付を数値
で保持しています。この数値は、1 つのソースファイルの全体で同じ値を持ちま
す。数値のフォーマットは以下の通りです。

        __DATE__ = (曜日<<28)+(西暦年<<16)+(月<<8)+日

                曜日:0=日,1=月,2=火,3=水,4=木,5=金,6=土
                西暦年:1980〜2079
                月:1〜12
                日:1〜31

        例: プレデファインシンボル __DATE__
      ┌────────────────────────────
      │*アセンブルした日付の文字列を埋め込む
      │year:= (.highw.__DATE__).and.$0FFF
      │month:= .high.__DATE__
      │day:= .low.__DATE__
      │        .dc.b   (year/1000).mod.10+'0',(year/100).mod.10+'0'
      │        .dc.b   (year/10).mod.10+'0',year.mod.10+'0'
      │        .dc.b   '-'
      │        .dc.b   month/10+'0',month.mod.10+'0'
      │        .dc.b   '-'
      │        .dc.b   day/10+'0',day.mod.10+'0'

 __DATE__ を使用すると、同じソースリストでもアセンブルする度に異なるオ
ブジェクトが生成されることになるので注意が必要です。


●プレデファインシンボル __TIME__

 プレデファインシンボル __TIME__ は、アセンブル開始時の時刻を数値で保持
しています。この数値は、1 つのソースファイルの全体で同じ値を持ちます。数
値のフォーマットは以下の通りです。

        __TIME__ = (時<<16)+(分<<8)+秒

                時:0〜23
                分:0〜59
                秒:0〜59

        例: プレデファインシンボル __TIME__
      ┌────────────────────────────
      │*アセンブルした時刻の文字列を埋め込む
      │hour:= .highw.__TIME__
      │minute:= .high.__TIME__
      │second:= .low.__TIME__
      │        .dc.b   hour/10+'0',hour.mod.10+'0'
      │        .dc.b   ':'
      │        .dc.b   minute/10+'0',minute.mod.10+'0'
      │        .dc.b   ':'
      │        .dc.b   second/10+'0',second.mod.10+'0'

 __TIME__ を使用すると、同じソースリストでもアセンブルする度に異なるオ
ブジェクトが生成されることになるので注意が必要です。


●プレデファインシンボル __HAS__

 プレデファインシンボル __HAS__ は、HAS060.X のベースになっている HAS.X
のバージョン×100 の値(309)を保持しています。

注意:
         HAS.X v3.09 にはプレデファインシンボルはありません。


●プレデファインシンボル __HAS060__

 プレデファインシンボル __HAS060__ は、HAS060.X のバージョンのサフィク
ス(HAS060.X v3.09+91 ならば +91 の部分)の値(91)を保持しています。

        例: プレデファインシンボル __HAS060__
      ┌────────────────────────────
      │*HAS060.X の v3.09+69 以上でアセンブルしなければエラーにする
      │.ifndef __HAS060__
      │        .fail   1       *HAS060.X でない,または,
      │                        *HAS060.X だが -y が指定されていない
      │.elseif __HAS060__<69
      │        .fail   1       *HAS060.X のバージョンが古い
      │.endif



━< 整数の記述 >━━━━━━━━━━━━━━━━━━━━━━━━━━━

 HAS060.X は、ソースリストに直接記述された整数を、符号なし 64 ビットの
整数の範囲(0〜18446744073709551615)まで認識します。

参考:
         HAS.X v3.09 では、ソースリストに直接記述された整数(符
        号を含まない)が符号なし 32 ビットの整数の範囲(0〜
        4294967295)で表現できないとき、上位に溢れた部分が常に無
        視されていました。

 HAS060.X で 64 ビットの整数の記述が有効なのは、オペレーションサイズが
.Q または .D の PMOVE 命令と、オペレーションサイズが .S/.D/.X/.P のいず
れかの浮動小数点命令のイミディエイトオペランドの部分です。ただし、浮動小
数点命令のイミディエイトオペランドでも、整数式と解釈できる場合は内部表現
の分割表記と見なされます。

 上記以外の場所に 32 ビットの整数の範囲(-2147483648〜4294967295)に入
らない整数を記述するとエラーになります。

 なお、整数演算の結果のオーバーフローは従来通り無視されます。

注意:
         HAS060.X では、記述された整数が 32 ビットの整数の範囲
        に入っているかどうかを厳密にチェックするため、HAS.X
        v3.09 ではエラーにならなかった記述が HAS060.X ではエラー
        になることがあります。

        例:
                MOVE.L  #$100000000,D0
                        HAS.X v3.09 の場合 … #0
                        HAS060.X の場合 … エラー


● PMOVE 命令のイミディエイトオペランド

 PMOVE 命令はオペレーションサイズに .Q または .D があり、アセンブル対象
の CPU が 68020 のときはイミディエイトオペランドに 64 ビットの整数を直接
記述することができます。ただし、整数演算は 32 ビットまでなので、32 ビッ
トに入り切らない整数を記述する場合は演算子(符号や括弧を含む)を伴うこと
ができません。

 PMOVE 命令の 64 ビットのイミディエイトオペランドの部分に 32 ビット分し
かデータがないときは、そのデータは下位 32 ビットとして使用され、上位 32
ビットは下位 32 ビットの符号拡張によって求められます。

 PMOVE 命令では、オペレーションサイズが .Q または .D の場合に限って、浮
動小数点数の場合と同様の内部表現を使用することができます。

例:
    (1) PMOVE.D #$81000003_00BF0000,CRP
         このように 64 ビットの整数を直接記述することができます。

    (2) PMOVE.D #$81000003,#$00BF0000,CRP
         浮動小数点数のように 2 つの整数に分けて記述することも
        できます。

    (3) PMOVE.D #$81000003,$00BF0000,CRP
         (2) と同じで、これも有効です。

    (4) PMOVE.D #!81000003_00BF0000,CRP
         内部表現を使用した記述方法です。

    (5) PMOVE.D #$00BF0000+$20,CRP
         データが 32 ビット分しかありませんが、これも有効です。
         上位 32 ビットは下位からの符号拡張で決定されます。

        補足:
                 (5) は命令の文法としては有効ですが、実際にルー
                トポインタの上位 32 ビットを 0 にする命令を実行
                しようとすると MMU Configuration Error が発生し
                てしまいます。

    (6) PMOVE.D #$81000003_00BF0000+$20,CRP
         これは正しいように見えますが、加算を行うために 64 ビッ
        トの整数を 32 ビットの整数に変換しようとした時点でエラー
        になります。

補足:
         PMOVE.D の .D は Double precision ではなくて Double
        long なので、イミディエイトオペランドを浮動小数点数で記
        述しても 32 ビットの整数に変換されます。


●浮動小数点命令のイミディエイトオペランド

 浮動小数点命令でオペレーションサイズが .S/.D/.X/.P のとき、イミディエ
イトオペランドに直接記述された整数(符号を含まない)は、符号なし 64 ビッ
トの整数の範囲で解釈されます。ただし、単なる整数式として解釈できる場合は
内部表現の分割表記と見なされるので、その場合はオペランドにサイズを指定す
るなどして整数でないことを明確にして下さい。

例:
    (1) FMOVE.X #$80000000,FP0
         これは整数は浮動小数点数の先頭の 4 バイトと判断され、
        データが足りないためにエラーになります。
         HAS060.X でこれを整数として認識させるためには、
        #$80000000.X や #$80000000.Q のように記述して、分割表記
        の先頭の 4 バイトではないことを明確にする必要があります。

    (2) FMOVE.X #$1_00000000+0.5,FP0
         これは +0.5 があるため整数とは判断されませんが、
        HAS060.X と HAS.X v3.09 とで挙動が異なります。
         HAS.X v3.09 では、$1_00000000 は 32 ビットからはみ出し
        た部分が無視されて $00000000 となり、結果としてイミディ
        エイトオペランドに #0.5 が指定されたことになります。
         HAS060.X では、$1_00000000 が 64 ビットの整数の範囲で
        解釈され、イミディエイトオペランドは #4294967296.5 にな
        ります。

    (3) FMOVE.X #$10000000,FP0
         HAS.X v3.09 と HAS060.X のいずれでも浮動小数点数の先頭
        の 4 バイトと判断され、データが足りないためにエラーにな
        ります。
         HAS060.X でこれを整数として認識させるためには、
        #$10000000.X や #$10000000.Q のように記述して、先頭の 4
        バイトではないことを明確にする必要があります。

    (4) FMOVE.S #$10000000,FP0
         これはオペレーションサイズが .S なのでエラーにはなりま
        せんが、浮動小数点数の先頭の 4 バイトとして処理されるこ
        とに変わりありません。つまり、整数から浮動小数点数への変
        換が行われません。
         HAS060.X でこれを整数として認識させるためには、
        #$10000000.X や #$10000000.Q のように記述して、分割表記
        の先頭の 4 バイトではないことを明確にする必要があります。



━< 浮動小数点数のオペランドのサイズ指定 >━━━━━━━━━━━━━━

 HAS060.X では浮動小数点数のオペランドの途中や最後に .B/.W/.L/.S/.D/.X/
.Q のいずれかのサイズ指定を書くことで、直前の浮動小数点数を適当な精度に
丸めることができます。

参考:
         HAS.X v3.09 では、浮動小数点数のオペランドの途中や最後
        にサイズ指定を書くとエラーになります。

 オペランド中のサイズ指定による丸め動作は FPU や FPCP の RN(round to
nearest, even)に合わせてあります。これはいわゆる四捨五入と若干異なり、
小数部が 0.5 になっているときは整数部分が偶数になる方向に丸めます(倍精
度や単精度に丸める場合は丸めた後の精度の最下位のビットを 1 として考えま
す)。

例(整数に丸める場合):
         端数の 0.5 を偶数になるように丸めるので、0.5 は切り捨てて 0 に、
        1.5 は繰り上げて 2 にします。

        -1.7 -1.5 -1.2 -0.7 -0.5 -0.2  0.2  0.5  0.7  1.2  1.5  1.7
          ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓
        -2.0 -2.0 -1.0 -1.0 -0.0 -0.0  0.0  0.0  1.0  1.0  2.0  2.0

注意:
         拡張精度で計算された浮動小数点数のオペランドはオブジェ
        クトになる段階でオペレーションサイズに合わせて変換されま
        すが、このときの丸め処理が HAS060.X でも HAS.X v3.09と同
        様に RN(round to nearest, even)と異なります。
         具体的には、拡張精度から倍精度や単精度への変換はいわゆ
        る四捨五入(符号は無視)で、0.5 も常に 0 と逆の方向に丸
        めるようになっています。また、浮動小数点数から整数への変
        換は小数部を常に切り捨てています。
         つまり、オペレーションサイズの指定による丸め処理とオペ
        ランドにサイズを指定した場合の丸め処理が異なります。注意
        して下さい。


●整数に丸める

 浮動小数点数の直後に .B/.W/.L/.Q のいずれかが指定されると、浮動小数点
数を指定されたサイズの整数になるように丸めます。これは処理中の浮動小数点
数の小数の部分を 0 にするだけなので、オペランドを整数として扱えるように
なるわけではありません。

 浮動小数点数が、指定されたサイズの符号つき整数の範囲に入り切らないとき
はエラーになります。

例:
    (1) FMOVE.S #(fa+fb).Q,FP0
         シンボル fa と fb の内容を拡張精度で加算してから、整数
        に丸めます。符号つき 64 ビットの整数の範囲を超えていたら
        エラーです。

    (2) FMOVE.X #1.5.L,FP0
         この命令のイミディエイトオペランドは拡張精度の 2.0 で
        す。次の命令と結果が異なることに注意して下さい。

                FMOVE.L #1.5,FP0        *FP0 に 1 を転送する


●浮動小数点数に丸める

 浮動小数点数は内部で拡張精度で演算されますが、その結果を強制的に単精度
や倍精度に落としたいときには、その浮動小数点数の直後に .S または .D とい
うサイズ指定を書いて下さい。これも精度が落ちるだけで、データが短くなるわ
けではありません。

例:
    (1) FMOVE.X #(fa+fb).D,FP0
         シンボル fa と fb の内容を拡張精度で加算してから、倍精
        度に丸めます。オーバーフローはエラーになりません。



━< 浮動小数点数の演算 >━━━━━━━━━━━━━━━━━━━━━━━

 HAS.X v3.09 では、浮動小数点数を含む式では、加減乗除以外の演算子が使え
ませんでした。HAS060.X では、浮動小数点数を含む式で、比較や整数演算の演
算子が使えるようになっています。

 HAS060.X において、浮動小数点数を含む式で使える演算子は、以下の通りで
す。演算子の優先順位は整数演算の場合と同じです。

        浮動小数点数を含む式で浮動小数点演算が行われる演算子
                *
                /
                -
                +
                .eq.    =       ==
                .ne.    <>      !=
                .lt.    <       .slt.
                .le.    <=      .sle.
                .gt.    >       .sgt.
                .ge.    >=      .sge.

        引数が浮動小数点数のとき整数に変換されてから演算が行われる演算子
                .not.
                .notb.
                .notw.
                .high.
                .low.
                .highw.
                .loww.
                .nul.
                .shr.   >>
                .shl.   <<
                .asr.
                .and.   &
                .xor.   ^
                .or.    |

注意:
         今のところ、浮動小数点数を含む式に .mod. 演算子を含め
        ることはできません。



━< その他の変更点 >━━━━━━━━━━━━━━━━━━━━━━━━━

 上記以外にも、HAS060.X には HAS.X v3.09 と異なる動作をする部分がありま
す。


●アセンブル対象の CPU のデフォルトは常に 68000

 アセンブル対象の CPU のデフォルトは、アセンブル時の CPU に因らず常に
68000 になります。

 HAS.X v3.09 は、CPU が 68020 以上の機種でアセンブルした場合は 68030 を、
それ以外ならば 68000 をアセンブル対象の CPU のデフォルトとしています。し
かし、アセンブルする機種によってアセンブラの挙動が異なると困る場合がある
ので、HAS060.X ではデフォルトのアセンブル対象の CPU を 68000 に固定する
ことにしました。

 アセンブルする機種によって挙動が変化すると困るのは、例えば次のプログラ
ムをアセンブル対象の CPU を指定せずに CPU が 68020 以上の機種でアセンブ
ルしようとした場合です。

        例: アセンブルする機種によって挙動が変化すると困る例
      ┌────────────────────────────
      │        LEA.L   (BASE,PC),A0
      │        TST.B   (FOO-BASE,A0,D0.W)
      │                :
      │BASE:   .DS.B   96
      │BOO:    .DS.B   32
      │FOO:    .DS.B   16

 上の例は、HAS.X v3.09 では問題なくアセンブルできてしまいますが、生成さ
れるオブジェクトは 68000 で正常に動作しません。なぜなら、FOO-BASE=128 な
ので、2 行目の拡張ワードが 68020 以上でしか許されないフルフォーマットに
なってしまっているからです。68020 では問題なく動作するので、プログラムを
作った本人は 68000 で動かないことに気付かない可能性があります。

 HAS060.X では、アセンブル対象の CPU のデフォルトが常に 68000 ですから、
上の例ではアセンブルしようとした時点でエラーになります。


●環境変数 HAS がコマンドラインの手前に挿入される

 HAS.X v3.09 では環境変数 HAS の内容がコマンドラインの最後に追加されま
すが、これを手前に挿入するようにしました。矛盾するコマンドラインスイッチ
を指定すると後に書いた方が有効になりますから、あらかじめ環境変数にデフォ
ルトの設定を書いておいて、コマンドラインでそれを否定するという使い方が可
能になります。

 例えば、アセンブル対象の CPU のデフォルトを 68030 にしたければ、

        > set HAS=-m68030

としておいて、普段は、

        > has060 foo.s

で 68030 用のオブジェクトを生成します。デフォルトを 68000 としてアセンブ
ルしたいときだけ、

        > has060 -m68000 foo.s

のように指定することで 68000 用のオブジェクトを生成できます(これを
HAS.X v3.09 でやると無条件に 68030 が指定されたことになってしまいます)。

 -i <path> は例外で、コマンドラインの -i <path> の後に環境変数 HAS の
-i <path> が追加されます。


●インクルードファイルの検索はカレントディレクトリを優先

 HAS.X v3.09 におけるインクルードファイルの検索順序は、

        -i <path>  →  カレントディレクトリ  →  環境変数 include

でした。

 HAS060.X では、カレントディレクトリを優先して、

        カレントディレクトリ  →  -i <path>  →  環境変数 include

となっています。

 -i <path> でインクルードパスを指定したいが、一部のインクルードファイル
はカレントディレクトリのもので差し換えたい、という場合に便利です。ただし、
逆にカレントディレクトリのインクルードファイルを無視させる目的で -i を使
用することができなくなっていますので注意して下さい。


●ソースファイル名を複数指定するとエラーになる

 HAS.X v3.09 ではソースファイル名を複数指定すると後から指定した方が有効
になっていましたが、HAS060.X ではソースファイル名が複数指定された時点で
エラー(使用法を表示)になります。


● -w[n] および -f[f,m,w,p] について数値の手前の空白を認めない

 コマンドラインスイッチ -w[n] および -f[f,m,w,p] について、「-w 1」のよ
うに数値の手前に空白を入れることができなくなりました。なお、「-m 68030」
は従来通り認められます。


●疑似命令 .DC における文字列の連結

 疑似命令 .DC で文字列を記述するとき、複数の文字列を“,”(コンマ)で区
切らずに直接連結して記述できます。

        例: 疑似命令 .DC における文字列の連結
      ┌────────────────────────────
      │        .DC.B   'ABC''DEF'


●疑似命令の数値引数の制限の緩和

 .DCB、.DS、.REPT などの疑似命令の数値引数に文字定数を含んだ式を指定し
てもエラーになりません。

        例: .DCB 疑似命令の数値引数に文字定数を含める
      ┌────────────────────────────
      │*文字コード→16進数変換テーブル
      │        .DCB.B  '0',-1
      │        .DC.B   0,1,2,3,4,5,6,7,8,9
      │        .DCB.B  'A'-('9'+1),-1
      │        .DC.B   10,11,12,13,14,15
      │        .DCB.B  'a'-('F'+1),-1
      │        .DC.B   10,11,12,13,14,15
      │        .DCB.B  256-('f'+1),-1

 この変更の影響を受けている疑似命令は次の通りです。変更する意味がないも
のもあります。

                .ALIGN
                .CPU
                .DCB
                .DS
                .FPID
                .LINE
                .LN
                .OFFSET
                .ORG
                .REPT
                .SCL
                .SIZE
                .TYPE
                .WIDTH


●マクロ内ローカルシンボルを外部定義にしない

 コマンドラインスイッチ -d を指定しても、“??”で始まるシンボルを外部定
義にしません。これは、マクロ内ローカルシンボルを使用しているモジュール同
士をリンクしようとしたときに、アセンブラがローカルシンボルの代わりに生成
した“??”で始まるシンボルが衝突するのを避けるためです。

 ユーザが“??”で始まるシンボルを外部定義にしたい場合は、.XDEF、.ENTRY、
.PUBLIC のいずれかで定義して下さい(.GLOBL、.GLOBAL は無効です)。



━<ワーニングメッセージ一覧>━━━━━━━━━━━━━━━━━━━━━

 HAS060.X のワーニングメッセージは、以下の通りです。字面通りの意味のも
のについては説明を省いています。


●「絶対アドレッシングです」(レベル4)
         絶対アドレッシング (xxx).L を使用しました。

●「絶対ショートアドレッシングです」(レベル4)
         絶対ショートアドレッシング (xxx).W を使用しました。

●「アドレスレジスタを %s.w で更新しています」(レベル3)
         %s は命令。オペレーションサイズはワードですが、ソース
        オペランドがロングワードに符号拡張されてアドレスレジスタ
        の全体(ロングワード)が更新されます。

●「アドレスレジスタを %s.w で比較しています」(レベル3)
         %s は命令。オペレーションサイズはワードですが、ソース
        オペランドがロングワードに符号拡張されてアドレスレジスタ
        の全体(ロングワード)が比較されます。

●「絶対ショートアドレスが -$8000〜$7FFF の範囲外です」(レベル3)
         (xxx).W で $8000〜$FFFF の範囲の値が指定されています。
        符号拡張されて $FFFF8000〜$FFFFFFFF として解釈されます。

●「オフセットが -32768〜32767 の範囲外です」(レベル3)
         (d16,An) の d16 が 32768〜65535 の範囲の値になっていま
        す。符号拡張されて -32768〜-1 の範囲の値として解釈されま
        す。

●「オフセットが -128〜127 の範囲外です」(レベル3)
         (d8,An,Xn) の d8 が 128〜255 の範囲の値になっています。
        符号拡張されて -128〜-1 の範囲の値として解釈されます。

●「レジスタリストの表記が不正です」(レベル1)
         レジスタの順序が降順になっているか、同じレジスタが複数
        回指定されています。

●「%s のデータのアラインメントが不正です」(レベル1)
         %s は疑似命令。.DC.W などで、偶数サイズのデータが奇数
        アドレスに配置されています。68000 での実行時にアドレスエ
        ラーが発生する可能性があります。

●「命令が奇数アドレスに配置されました」(レベル1)
         命令が奇数アドレスに配置されています。実行時にアドレス
        エラーが発生すると思われます。

●「%s はソフトウェアエミュレーションで実行されます」(レベル1)
         %s は命令。アセンブル対象の CPU が 68040/68060 で、ア
        センブル対象の CPU ではソフトウェアエミュレーションで実
        行される命令です。

●「浮動小数点命令の直後に NOP を挿入しました (エラッタ対策)」(レベル1)
         68060 のエラッタ F6 を回避するために、浮動小数点命令の
        直後に NOP が挿入されました。

●「MOVE to USP の直前に MOVEA.L A0,A0 を挿入しました (エラッタ対策)」
(レベル1)
         68060 のエラッタ I11 を回避するために、ラベルと MOVE
        to USP の間に MOVEA.L A0,A0 が挿入されました。

●「CCR/SR の未定義のビットを操作しています」(レベル1)
         CCR または SR の未定義のビットを操作しています。

●「インデックスのサイズが指定されていません」(レベル1)
         インデックス付きの実効アドレッシングモードで、インデッ
        クスレジスタのサイズが指定されていません。インデックスの
        サイズを省略した場合はワードサイズになります(符号拡張さ
        れてからスケールファクタが掛けられます)。

●「シンボル %s を set(=) で上書きしました」(レベル1)
         %s はシンボル名。-j を指定していないとき、set 以外で定
        義されたシンボルを set で再定義しようとしています。

●「シンボル %s を offsym で上書きしました」(レベル1)
         %s はシンボル名。-j を指定していないとき、offsym 以外
        で定義されたシンボルを offsym で再定義しようとしています。

●「.ds の引数が負数です」(レベル1)
         .TEXT/.DATA 以外のセクションで .DS の引数に負数を指定するとワ
        ーニングで通知されます。

●「整数を単精度浮動小数点数の内部表現と見なします」(レベル1)
         単精度浮動小数点数を書く所に整数を書くと通知されます。



━<エラーメッセージ一覧>━━━━━━━━━━━━━━━━━━━━━━━

 HAS060.X のエラーメッセージは、以下の通りです。字面通りの意味のものに
ついては説明を省いています。


●「.fail によるエラー」
         .FAIL の引数が 0 以外のとき。

●「シンボル %s は既に定義されています」
         %s はシンボル名。シンボルの二重定義。

●「プレデファインシンボル %s を再定義しようとしました」
         %s はプレデファインシンボル名。-y を指定しているとき、
        プレデファインシンボルを何らかの方法で再定義しようとして
        います。

●「シンボル %s は set(=) 以外で定義されています」
         %s はシンボル名。-j を指定しているとき、set 以外で定義
        されたシンボルを set で再定義しようとしています。

●「シンボル %s は offsym 以外で定義されています」
         %s はシンボル名。-j を指定しているとき、offsym 以外で
        定義されたシンボルを offsym で再定義しようとしています。

●「命令が解釈できません」

●「ローカルラベルの記述が不正です」

●「シンボル %s は種類が異なるので使えません」
         定義済みのシンボルに異なる種類のデータを上書きしようとしたとき
        など。

●「シンボル %s はレジスタ名なので使えません」
         レジスタ名と同名のシンボルに値を定義しようとしたときなど。

●「プレデファインシンボル %s は外部定義宣言できません」

●「プレデファインシンボル %s は外部参照宣言できません」

●「プレデファインシンボル %s はグローバル宣言できません」

●「シンボル %s の定義が参照方法と矛盾しています」
         前方参照したシンボルを fequ で定義しようとしたときなど。

●「記述が間違っています」

●「実効アドレスが解釈できません」

●「スケールファクタは指定できません」
         68000/68010 でスケールファクタを指定しようとしました。

●「スケールファクタの指定が間違っています」
         スケールファクタが定数で指定されていないか、1,2,4,8
        (ColdFire は 1,2,4)の範囲外です。

●「フルフォーマットのアドレッシングは使えません」
         68000/68010 や ColdFire でフルフォーマットのアドレッシ
        ングが指定されました。

●「イミディエイトデータが解釈できません」
         # で始まるオペランドがイミディエイトデータとして解釈で
        きません。

●「指定できないレジスタです」
         制御レジスタを記述できない場所に記述した場合など。

●「このアドレッシングでは opc は使えません」
         (<label>,OPC,Xn) など。

●「指定できないアドレッシングです」
         命令で許されていないアドレッシングモードが指定されてい
        ます。

●「命令 %s には指定できないサイズです」

●「擬似命令 %s には指定できないサイズです」

●「MOVE USP はロングワードサイズのみ指定可能です」

●「MOVE ACC はロングワードサイズのみ指定可能です」

●「浮動小数点レジスタ直接アドレッシングは拡張サイズのみ指定可能です」

●「汎用レジスタ直接アドレッシングはロングワードサイズのみ指定可能です」

●「FPCR/FPIAR/FPSR はロングワードサイズのみ指定可能です」

●「FMOVEM FPn は拡張サイズのみ指定可能です」

●「FMOVEM FPcr はロングワードサイズのみ指定可能です」

●「5200/5300 ではロングワードサイズのみ指定可能です」

●「5200/5300 ではロングワードサイズの相対分岐はできません」

●「指定できないサイズです」

●「%s にはサイズを指定できません」
         %s は命令または疑似命令。

●「%s to CCR はバイトサイズのみ指定可能です」
         %s は ANDI、EORI、ORI のいずれか。

●「%s to SR はワードサイズのみ指定可能です」
         %s は ANDI、EORI、ORI のいずれか。

●「アドレスレジスタはバイトサイズでアクセスできません」

●「MOVE to CCR/SR はワードサイズのみ指定可能です」

●「MOVE from CCR/SR はワードサイズのみ指定可能です」

●「68000/68010 ではロングワードサイズは指定できません」

●「メモリに対するシフト・ローテートはワードサイズのみ指定可能です」

●「メモリに対するビット操作はバイトサイズのみ指定可能です」

●「データレジスタに対するビット操作はロングワードサイズのみ指定可能です」

●「68000/68010 ではロングワードサイズの相対分岐はできません」

●「オペランドのない TRAPcc にはサイズを指定できません」

●「不正なオペランドです」

●「引数が確定していません」

●「%s のオペランドが多すぎます」
         %s は命令。命令のオペランドが多すぎます。

●「%s の引数が多すぎます」
         %s は疑似命令。疑似命令の引数が多すぎます。

●「ローカルラベルの参照が不正です」

●「.ds の引数が負数です」
 .TEXT/.DATA セクションで .DS の引数に負数を指定するとエラーになります。

●「.end に外部参照値は指定できません」

●「浮動小数点数の内部表現の長さが合いません」
         浮動小数点数を書く所に整数を書くと内部表現と見なされます。単精
        度は 1 個、倍精度は 2 個、拡張精度は 3 個の整数が必要です。

●「シンボル %s が未定義です」
         %s はシンボル名。

●「ローカルラベルが未定義です」

●「値を確定できません」
         .OFFSYM で初期値を設定するシンボルがオフセットセクショ
        ンが終了するまでに現れなかったとき、そのオフセットセクシ
        ョンでロケーションカウンタをシンボルに設定しようとしてい
        る行で通知されます。

●「0 で除算しました」

●「オフセットが範囲外です」

●「定数ではなくアドレス値が必要です」
        相対分岐命令のオペランドに定数が指定された場合など。

●「オーバーフローしました」

●「不正な値です」

●「データが 1〜8 の範囲外です」
         ADDQ/SUBQ のイミディエイトデータが範囲外です。

●「データが -128〜127 の範囲外です」
         MOVEQ のイミディエイトデータが範囲外です。

●「データが -1,1〜7 の範囲外です」
         MOV3Q のイミディエイトデータが範囲外です。

●「シフト・ローテートのカウントが 1〜8 の範囲外です」
         ASL/ASR/LSL/LSR/ROL/ROR/ROXL/ROXR のイミディエイトデー
        タが範囲外です。

●「未対応の cpu です」
         .CPU の引数がおかしい。

●「外部参照値の埋め込みはできません」
         ADDQ などの命令埋め込みタイプのイミディエイトデータが
        外部参照になっています。

●「マクロ名がありません」
         .MACRO の行にシンボルがありません。

●「%s で定義するシンボルがありません」
         EQU などの行頭のシンボルを定義する疑似命令の行の行頭に
        シンボルがありません。

●「.include のネストが深すぎます」

●「%s するファイルが見つかりません」
         %s は疑似命令。include や insert などでファイルが見つ
        かりません。

●「マクロ展開中ではないのに %s があります」
         %s は疑似命令。マクロ展開中以外で .EXITM しようとした
        ときなど。

●「マクロ定義中ではないのに %s があります」
         %s は疑似命令。.LOCAL や .SIZEM をマクロ定義中以外に現
        れたときなど。

●「.endm が足りません」
         マクロや .REPT などのネストが完全に閉じる前にソースフ
        ァイルが終わってしまいました。

●「1 つのマクロの中のローカルシンボルが多すぎます」

●「マクロのネストが深すぎます」

●「%s に対応する .if がありません」
         %s は .else/.elseif/.endif。

●「.else の後に .elseif があります」

●「.endif が足りません」
         .IF〜.ENDIF のネストが完全に閉じる前にソースファイルが
        終わってしまいました。

●「"〜" が閉じていません」

●「'〜' が閉じていません」

●「<〜> が閉じていません」

●「整数の記述が間違っています」
         整数が 64 ビットを越えている場合など。

●「.offsym 中に %s は指定できません」
         %s は .even/.quad/.align。



━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

(EOF)