この節では,CC-RHがサポートする命令セットについて説明します。
次表に,以降で用いる記号の意味を示します。
|
|
CMD
|
命令
|
CMDi
|
命令(addi, mulhi, satsubi, andi, ori, またはxori)
|
reg,reg1,reg2
|
レジスタ
|
r0,R0
|
ゼロ・レジスタ
|
R1
|
アセンブラ予約レジスタ(r1)
|
gp
|
グローバル・ポインタ(r4)
|
ep
|
エレメント・ポインタ(r30)
|
[reg]
|
ベース・レジスタ
|
disp
|
ディスプレースメント(アドレスからの偏位)
特に記述のない場合32ビット幅を持ちます。
|
dispn
|
nビットのディスプレースメント
|
imm
|
イミーディエト(即値)
特に記述のない場合32ビット幅を持ちます。
|
immn
|
nビットのイミーディエト
|
bit#3
|
ビット・ナンバ指定用3ビット・データ
|
cc#3
|
浮動小数点システム・レジスタFPSRのCC0〜CC7(24〜31ビット)指定用3ビット・データ
|
#label
|
ラベルの絶対アドレス参照
|
label
|
ラベルのセクション内オフセット参照,またはPCオフセット参照
|
$label
|
ラベルのgpオフセット参照
|
!label
|
ラベルの絶対アドレス参照(命令展開なし)
|
%label
|
ラベルのepオフセット参照(命令展開なし)
|
HIGHW(value)
|
valueの上位16ビット
|
LOWW(value)
|
valueの下位16ビット
|
HIGHW1(value)
|
valueの上位16ビット + valueのビット番号15のビット値注
|
HIGH(value)
|
valueの下位16ビット中の上位8ビット
|
LOW(value)
|
valueの下位8ビット
|
addr
|
アドレス
|
PC
|
プログラム・カウンタ
|
PSW
|
プログラム・ステータス・ワード
|
regID
|
システム・レジスタ番号(0〜31)
|
selID
|
グループ番号(0〜31)
|
注 | LSB(Least Significant Bit)はビット番号0です。 |
以下に,アセンブラにおけるオペランドの記述形式について説明します。アセンブラでは,命令,および疑似命令に対するオペランドとして,レジスタ,定数,シンボル,ラベル参照,および定数,シンボル,ラベル参照,演算子,かっこで構成した式を指定できます。
アセンブラにおいて指定できるレジスタを次に示します。注
r0,zero,r1,r2,hp,r3,sp,r4,gp,r5,tp,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,ep,r31,lp
注 | PSW,およびシステム・レジスタは,ldsr/stsr命令において,番号で指定します。なお,アセンブラでは,PCをオペランドに指定する方法はありません。 |
r0とzero(ゼロ・レジスタ),r2とhp(ハンドラ・スタック・ポインタ),r3とsp(スタック・ポインタ),r4とgp(グローバル・ポインタ),r5とtp(テキスト・ポインタ),r30とep(エレメント・ポインタ),r31とlp(リンク・ポインタ)は同じレジスタを示します。
r0は,常に0の値を持つレジスタです。したがって,デスティネーション・レジスタとして指定した場合にも,結果の代入は行われません。なお,機械語命令がオペランドとしてr0を指定することを禁止している場合,メッセージを出力して,アセンブルが中止されます。
mov 0x10, r0
↓
E0550240:RH850コア指定時には、デスティネーション・オペランドにr0を指定することはできません。
|
アセンブラ予約レジスタ(r1)は,アセンブラにおいて,命令展開を行う際のテンポラリ・レジスタとして用いられるレジスタです。なお,r1をソース・レジスタ,またはデスティネーション・レジスタとして指定した場合,次のメッセージが出力され注,アセンブルが続行されます。
注 | このメッセージの出力は,アセンブラの起動時に警告メッセージ抑止オプション(-Xno_warning)を指定することにより抑止できます。 |
mov 0x10, r1
↓
W0550013 : r1がレジスタとしてオペランドに指定されています。
|
命令展開を行う際にr1を使用する命令を次に示します。
ld.b,ld.h,ld.w,ld.bu,ld.hu,st.b,st.h,st.w,add,addi,sub,subr,mulh,mulhi,mul,mulu,divh,div,divhu,divu,cmp,movea,cmov,satadd,satsub,satsubi,satsubr,or,ori,xor,xori,and,andi,not,tst,set1,clr1,not1,tst1,prepare,dispose
アセンブラでは,命令,および疑似命令のオペランド指定で使用可能な絶対値式,または相対値式の構成要素として,整定数,および文字定数を用いることができます。
また,.float疑似命令および.double疑似命令のオペランド指定には浮動小数点定数を用いることができます。
アセンブラでは,命令,および疑似命令のオペランド指定で使用可能な絶対値式,または相対値式の構成要素として,シンボルを用いることができます。
アセンブラでは,次に示した命令/疑似命令のオペランド指定で,使用可能な相対値式の構成要素として,ラベル参照を用いることができます。
- | メモリ参照命令(ロード/ストア命令,およびビット操作命令) |
- | 演算命令(算術演算命令,飽和演算命令,および論理演算命令) |
アセンブラでは,ラベル参照は参照方法の違い,およびそのラベル参照を用いている命令/疑似命令の違いにより次に示すように異なる意味を持ちます。
|
|
|
#label
|
メモリ参照命令,演算命令,jmp命令
|
ラベルlabel定義の存在する位置の絶対アドレス(アドレス0からのオフセット注1)。
32ビットのアドレスを持ち,ld23,st23,mov, jmp命令命令以外は,命令展開されます。
|
領域確保疑似命令
|
ラベルlabel定義の存在する位置の絶対アドレス(アドレス0からのオフセット注1)。
ただし,32ビットのアドレスを,確保した領域の大きさに準じてマスクした値。
|
!label
|
メモリ参照命令,演算命令
|
ラベルlabel定義の存在する位置の絶対アドレス(アドレス0からのオフセット注1)。
16ビットのアドレスを持ち,16ビット・ディスプレースメント,またはイミーディエトをもつ命令に指定した場合,命令展開は行われません。
その他の命令に指定した場合,命令展開されます。
ラベルlabelの定義したアドレスが,16ビットで表現できる範囲でない場合,リンク時にエラーになります。
|
領域確保疑似命令
|
ラベルlabel定義の存在する位置の絶対アドレス(アドレス0からのオフセット注1)。
ただし,32ビットのアドレスを,確保した領域の大きさに準じてマスクした値。
|
label
|
メモリ参照命令,演算命令
|
ラベルlabel定義の存在する位置のセクション内オフセット(ラベルlabel定義の存在するセクションの先頭アドレスからのオフセット注2)。
32ビットのオフセットを持ち,ld23,st23,mov命令以外は,命令展開されます。
|
jmp命令を除く分岐命令
|
ラベルlabel定義の存在する位置のPCオフセット(ラベルlabel参照を用いている命令の先頭アドレスからのオフセット)。
|
領域確保疑似命令
|
ラベルlabel定義の存在する位置のセクション内オフセット(ラベルlabel定義の存在するセクションの先頭アドレスからのオフセット注2)。
ただし,32ビットのオフセットを,確保した領域の大きさに準じてマスクした値。
|
%label
|
メモリ参照命令,演算命令
|
16ビットのオフセットを持ち,16ビット・ディスプレースメント,またはイミーディエトをもつ命令に指定した場合,命令展開は行われません。
その他の命令に指定した場合,命令展開されます。
ラベルlabelの定義したアドレスが,16ビットで表現できる範囲でない場合,リンク時にエラーになります。
|
領域確保疑似命令
|
ラベルlabel定義の存在する位置のepオフセット(エレメント・ポインタの示すアドレスからのオフセット)。
ただし,32ビットのオフセットを,確保した領域の大きさに準じてマスクした値。
|
$label
|
メモリ参照命令,演算命令
|
ラベルlabel定義の存在する位置のgpオフセット(グローバル・ポインタの指すアドレスからのオフセット)。
|
注 1. | リンク後のオブジェクト・ファイルにおけるアドレス0からのオフセットです。 |
注 2. | リンク後のオブジェクト・ファイルにおいて,ラベルlabel定義の存在するセクションが割り当てられたセクション(出力セクション)の先頭アドレスからのオフセットです。 |
次に,メモリ参照命令,演算命令,分岐命令,および領域確保疑似命令におけるラベル参照の意味を示します。
|
|
#label[reg]
|
ラベルlabelの絶対アドレスがディスプレースメントとして扱われます。
32ビットの値を持ち,ld23,st23命令以外は,命令展開されます。#label[r0]とすることにより絶対アドレスによる参照を指定できます。
[reg]の部分が省略でき,省略した場合,アセンブラでは,[r0]が指定されたものとみなされます。
|
label[reg]
|
ラベルlabelのセクション内オフセットがディスプレースメントして扱われます。32ビットの値を持ち,ld23,st23命令以外は,命令展開されます。regに対象とするセクションの先頭アドレスを指すレジスタを指定し,label[reg]とすることにより,一般的なレジスタ相対の参照が指定できます。
|
$label[reg]
|
ラベルlabelのgpオフセットがディスプレースメントとして扱われます。ラベルlabelの定義されたセクションにより,32,または16ビットの値を持ち,命令展開のパターンが変化します注。16ビットの値を持つ命令展開が行われた場合,ラベルlabelの定義したアドレスより算出されたオフセットが16ビットで表現できる範囲でない場合,リンク時にエラーになります。$label[gp]とすることによりgpレジスタ相対の参照(gpオフセット参照と呼ぶ)が指定できます。[reg]の部分が省略でき,省略した場合,アセンブラでは,[gp]が指定されたものとみなされます。
|
!label[reg]
|
ラベルlabelの絶対アドレスがディスプレースメントとして扱われます。16ビットの値を持ち,命令展開は行われません。ラベルlabelに定義したアドレスが16ビットで表現できない場合,リンク時にエラーになります。!label[r0]とすることにより絶対アドレスによる参照が指定できます。
[reg]の部分が省略でき,省略した場合は[r0]が指定されたものとみなされます。
ただし,#label[reg]参照とは異なり,命令展開は行われません。
|
%label[reg]
|
ラベルlabel定義の存在する位置のepシンボルからのオフセットがディスプレースメントとして扱われます。
16ビット,または命令によってはそれ以下の値を持ち,その範囲で表現できる値でない場合,リンク時にエラーになります。
[reg]の部分が省略でき,省略した場合,アセンブラでは,[ep]が指定されたものとみなされます。
|
|
|
#label
|
ラベルlabelの絶対アドレスがイミーディエトとして扱われます。
32ビットの値を持ち,mov命令以外は,命令展開されます。
|
label
|
ラベルlabelのセクション内オフセットがイミーディエトとして扱われます。
32ビットの値を持ち,mov命令以外は,命令展開されます。
|
$label
|
ラベルlabelのgpオフセットがイミーディエトとして扱われます。
ラベルlabelの定義されたセクションにより,32,または16ビットの値を持ち,命令のパターンが変化します注1。16ビットの値を持つ展開をされた場合,ラベルlabelの定義したアドレスより算出されたオフセットが16ビットで表現できる範囲でない場合,リンク時にエラーになります。
|
!label
|
ラベルlabelの絶対アドレスがイミーディエトとして扱われます。
16ビットの値を持ち,イミーディエトとして16ビットの値を指定できるアーキテクチャの演算命令に指定した場合,命令展開は行われません。16ビットで表現できる範囲でない場合,リンク時にエラーになります。
|
%label
|
ラベルlabel定義の存在する位置のepシンボルからのオフセットがイミーディエトとして扱われます。
16ビットの値を持ち,イミーディエトとして16ビットの値を指定できるアーキテクチャの演算命令に指定した場合,命令展開は行われません。
16ビットで表現できる範囲でない場合,リンク時にエラーになります
|
|
|
#label
|
jmp命令において,ラベルlabelの絶対アドレスが飛び先アドレスとして扱われます。
32ビットの値を持ち,命令展開されます。
|
label
|
jmp命令以外の分岐命令において,ラベルlabelのPCオフセットがディスプレースメントとして扱われます。
22ビットの値を持ち,表現できない範囲である場合,リンク時にエラーになります。
|
|
|
#label
!label
|
.db4/.db2/.db疑似命令において,ラベルlabelの絶対アドレスを値として扱われます。
32ビットの値を持ちますが,各疑似命令のビット幅に応じてマスクされます。
|
label
|
.db4/.db2/.db疑似命令において,ラベルlabel定義の定義されたセクション内オフセットを値として扱われます。
32ビットの値を持ちますが,各疑似命令のビット幅に応じてマスクされます。
|
%label
|
.db4/.db2/.db疑似命令において,ラベルlabelのepオフセットを値として扱われます。
32ビットの値を持ちますが,各疑似命令のビット幅に応じてマスクされます。
|
$label
|
.db4/.db2/.db疑似命令において,ラベルlabelのgpオフセットを値として扱われます。
32ビットの値を持ちますが,各疑似命令のビット幅に応じてマスクされます。
|
ここでは,epオフセット参照について説明します。CC-RHでは,以下に示す再配置属性のセクションに置かれるデータについては,基本的に,次のことが想定されています。
エレメント・ポインタ(ep)の指すアドレスからのオフセットによって参照する
|
- | TDATA/TDATA4/TBSS4/TDATA5/TBSS5/TDATA7/TBSS7/TDATA8/TBSS8セクション(コード・サイズが小さいメモリ参照命令(sld/sst)で参照するデータ) |
- | EDATA/EBSSセクション(コード・サイズが大きいメモリ参照命令(ld/st)で参照するデータ) |
- | EDATA23/EBSS23セクション(コード・サイズが大きいメモリ参照命令(ld23/st23)で参照するデータ) |
図 5.2 | epオフセット参照セクションのメモリ配置イメージ |
epオフセット参照セクションへのデータの割り当ては,次の方法で行います。
“#pragma section”指令により,“ep_”で始まる属性指定文字を指定してデータを割り当てます。
セクション定義疑似命令により,再配置属性tdata,tdata4,tbss4,tdata5,tbss5,tdata7,tbss7,tdata8,tbss8,edata,ebss,edata23,またはebss23のセクションへデータを割り当てます。
%labelによる参照に対しては,epオフセット参照を行う機械語命令列が生成されます。
.dseg EDATA
sdata: .db2 0xFFF0
.dseg DATA
data: .db2 0xFFF0
.cseg TEXT
ld.h %sdata, r20 ; (1)
ld.h %data, r20 ; (2)
|
アセンブラでは,%labelによる参照に対して,(1),(2)の両方ともep オフセット参照とみなし,機械語の命令列を生成します。
なお,アセンブラでは,データが配置されたセクションが正しいものとして処理が行われます。このため,データの配置に誤りがある場合でも,検出できません。
ここでは,gpオフセット参照について説明します。CC-RHでは,以下に示す再配置属性のセクションに置かれるデータについては,基本的に次のことが想定されています。
グローバル・ポインタ(gp)の指すアドレスからのオフセットによって参照する
|
- | SDATA/SBSSセクション(16ビットのディスプレースメントをとるメモリ参照命令(ld/st)で参照するデータ) |
- | SDATA23/SBSS23セクション(23ビットのディスプレースメントをとるメモリ参照命令(ld23/st23)で参照するデータ) |
また,C言語における“#pragma section”指令や,アセンブリ言語におけるセクション定義疑似命令による,内蔵ROM/内蔵RAMなどのr0相対のメモリ割り当てを行わない場合,すべてのデータがgpオフセット参照となります。
図 5.3 | gpオフセット参照セクションのメモリ配置イメージ |
備考 | sdataセクションとsbssセクションをあわせて64Kバイトです。gpはsdataセクションとsbssセクションの中心の位置です。 |
- | プログラムでデータを割り当てるセクションを指定する場合
参照頻度の高いデータを,明示的にsdata/sbss/sdata23/sbss23セクションへ割り当てます。アセンブリ言語の場合,セクション定義疑似命令で,C言語の場合,#pragma section 指令で割り当てられます。 |
- | そのデータが,指定したファイル内に定義を持つ場合 |
- | sdata/sbssセクションに割り付けるデータである場合注 |
16ビットのディスプレースメントを用いた参照を行う機械語命令が生成されます。
- | sdata/sbssセクションに割り付けるデータでない場合 |
32ビットのディスプレースメントを用いた参照を行う機械語命令列が生成されます。
- | そのデータが,指定したファイル内に定義を持たない場合 |
sdata/sbssセクションに割り当てるデータである(gpオフセット参照されているラベルがsdata/sbssセクションに定義を持つ)とみなされ,16ビットのディスプレースメントを用いた参照を行う機械語命令が生成されます。
(i) | HIGH/LOW/HIGHW/LOWW/HIGHW1演算子について |
<1> | 32ビットのディスプレースメントを用いてメモリを参照する場合 |
アセンブラでは,32ビットのディスプレースメントを用いてメモリを参照する場合,命令展開が行われ,movhi命令とメモリ参照命令が用いられて,32ビットのディスプレースメントの上位16ビットと,下位16ビットから,32ビットのディスプレースメントが構成されて参照を行う命令列が生成されます。
ld.w 0x18000[r11], r12
|
movhi HIGHW1(0x18000), r11, r1
ld.w LOWW(0x18000)[r1], r12
|
この際,下位16ビットをディスプレースメントとして用いる機械語のメモリ参照命令は,指定された16ビットのディスプレースメントを符号拡張し,32ビットの値として扱います。この符号拡張された部分を補正するために,アセンブラでは,movhi命令を用いて上位16ビットのディスプレースメントを構成する際,ただ単に上位16ビットのディスプレースメントを構成するのではなく,次のディスプレースメントを構成します。
上位16ビット + 下位16ビットの最上位ビット(ビット番号15のビット)
|
<2> | HIGHW/LOWW/HIGHW1/HIGH/LOW |
次表のようにアセンブラでは,HIGHW, LOWW, HIGHW1, HIGH,およびLOW演算子を用いることにより,32ビットの値の上位16ビット,32ビットの値の下位16ビット,および32ビットの値の上位16ビット + ビット番号15のビット値,16ビットの値の上位8ビット値,16ビットの値の下位8ビット値を指定できます。注
注 | アセンブラ内部では解決できない場合,この情報はリロケーション情報に反映されリンク・エディタにおいて解決されます。 |
|
|
HIGHW (value)
|
valueの上位16ビット
|
LOWW (value)
|
valueの下位16ビット
|
HIGHW1 (value)
|
valueの上位16ビット + valueのビット番号15のビット値
|
HIGH (value)
|
valueの下位16ビット中の上位8ビット
|
LOW (value)
|
valueの下位8ビット
|
.dseg DATA
L1:
:
.cseg TEXT
movhi HIGHW ($L1), r0, r10 ;L1のgpオフセットの値の上位16ビットを
;r10の上位16ビットに格納し,
;位16ビットに0を格納する。
movea LOWW ($L1), r0, r10 ;L1のgpオフセットの値の下位16ビットを
;符号拡張しr10に格納する。
:
|