
|
 |
MAEC TOOL NEWS:
MAECT-M3T-NC308WA-020901D
M3T-NC308WA V.5.00 Release 1
ご使用上のお願い
|
M32C/80, M16C/80, M16C/70シリーズ用Cコンパイラ(アセンブラ・統合化開発環境付き) M3T-NC308WA V.5.00 Release 1 の使用上の注意事項を連絡します。
- volatile修飾された構造体のビットフィールドに関する注意事項
- 約6200個以上の初期値並びを持つ配列の定義に関する注意事項
- 割り込み処理関数に関する注意事項
- ビットフィールドおよび_Bool型変数に関する注意事項
- volatile修飾された構造体のビットフィールドに関する注意事項
- 1.1 内容
- volatile修飾された構造体のビットフィールドに定数を代入するソースプログラムをコンパイルすると、代入が行われないコードが生成されることがあります。
- 1.2 発生条件
- 以下3点の条件をすべて満たす場合に発生します。
| (1) | volatile修飾付きで構造体を宣言している。 |
| (2) | (1)の構造体が、符号なしの2ビット以上のビットフィールドを含んでいる。
※ M3T-NC308WAでは、型指定子 "signed" を明記していないビットフィールドは符号なしとなります。 |
| (3) | (2)のビットフィールドに、以下のいずれでもない定数を代入している。
・代入先のビットフィールドのビット数で表現できる最大の符号なし整定数 (例えば3ビットなら7)
・ゼロ |
- 1.3 発生例
[C言語ソース]
-----------------------------------------------------------------------
volatile struct { /* 発生条件(1) */
int m:3; /* 発生条件(2) */
} vs;
void func(void)
{
vs.m = 5; /* 発生条件(3) */
}
-----------------------------------------------------------------------
[誤った生成コード]
-----------------------------------------------------------------------
mov.w _vs:16,R0
and.w #0ffffH,R0 ; 代入の効果がありません。
mov.w R0,_vs:16
-----------------------------------------------------------------------
[本来生成されるべきコード]
-----------------------------------------------------------------------
mov.w _vs:16,R0
and.w #0fff8H,R0
or.w #05H,R0
mov.w R0,_vs:16
-----------------------------------------------------------------------
- 1.4 回避策
- 以下のいずれかの方法で回避してください。
| (1) |
volatileでない同じ型のテンポラリ構造体を宣言して、書き込む対象の構造体全体をテンポラリ構造体に代入し、
テンポラリ構造体上でビットフィールドへの代入を行った後、テンポラリ構造体全体を元の構造体に代入してください。 |
| (2) | 可能であれば、ビットフィールドを符号付きで宣言してください。 |
| (3) |
代入する定数を、一度整数型のテンポラリ変数に代入し、その変数からビットフィールドに代入してください。このとき、変数への代入の後にダミーのasm関数を挿入してください。 |
[回避策(1)の例]
-----------------------------------------------------------------------
volatile struct tagA {
int m:3;
} vs;
void func(void)
{
struct tagA tmp = vs; /* テンポラリの構造体に代入 */
tmp.m = 5; /* テンポラリの構造体上でビットフィールドへ代入 */
vs = tmp; /* テンポラリの構造体から書き戻す */
}
-----------------------------------------------------------------------
[回避策(2)の例]
-----------------------------------------------------------------------
volatile struct {
signed int m:3; /* 宣言に signed を付加する */
} vs;
-----------------------------------------------------------------------
[回避策(3)の例]
-----------------------------------------------------------------------
volatile struct {
int m:3;
} vs;
void func(void)
{
unsigned int tmp = 5; /* 定数をテンポラリ変数に代入 */
asm(); /* ダミーのasm関数 */
vs.m = tmp; /* テンポラリ変数からビットフィールドへ代入 */
}
-----------------------------------------------------------------------
- 1.5 恒久対策
- 本内容は、次期バージョンアップにて改修する予定です。
M3T-NC308WA V.5.00 Release 1 ご使用上のお願い
MAECT-M3T-NC308WA-020901D
- 約6200個以上の初期値並びを持つ配列の定義に関する注意事項
- 2.1 内容
- 約6200個以上の初期値並びを持つ配列を定義するソースプログラムをコンパイルすると、コンパイルが強制終了することがあります。
- 2.2 発生条件
- 以下2点の条件をすべて満たす場合に発生します。
| (1) | 外部変数として初期値ありの配列を定義している。 |
| (2) | 初期値が波括弧{}の組の中に連続して約6200個以上記述されている。
(Windows版以外では、メモリ容量やOSバージョンなど動作環境により発生する下限の個数が異なり、約6200個では発生しないこともあります。弊社の動作確認環境では、solaris版では約37000個以上で発生することを確認しています。) |
- 2.3 発生例
-----------------------------------------------------------------------
/* 1次元配列の例 */
const unsigned int array1[] = {
0, 1, 2, (中略), 6199 /* 6200個の初期値 */
};
/* 2次元配列の例 */
const unsigned int dim2[5000][3] = {
0, 1, 2, 3, 4, (中略), 14999 /* 15000個の初期値 */
};
-----------------------------------------------------------------------
- 2.4 回避策
| (1) | 1次元配列の場合、配列を要素5000個程度で分割してください。
要素の型が同じであれば、分割しても連続して定義することにより、連続に配置されます。 |
| (2) |
多次元配列の場合、最後の添字で示される要素数が5000個以下であれば、初期値の並びを、その添字の要素数に対応する分ごとに波括弧で括ってください。
最後の添字で示される要素数が上記個数を越えている場合、(1)と同様に分割してください。 |
[回避策(1)の例]
-----------------------------------------------------------------------
const unsigned int array1[] = {
0, 1, 2, (中略), 4999 /* 個数を5000個で分割 */
};
const unsigned int array1_2[] = {
5000, 5001, (中略), 6200 /* 5000個で分割した残り */
};
-----------------------------------------------------------------------
[回避策(2)の例]
-----------------------------------------------------------------------
const unsigned int dim2[5000][3] = {
{ 0, 1, 2 }, /* 最も内側の{}の中が5000個を越えないようにする */
{ 3, 4, 5 },
(中略),
{ 14997, 14998, 14999 }
}
-----------------------------------------------------------------------
- 2.5 恒久対策
- 本内容は、次期バージョンアップにて改修する予定です。
M3T-NC308WA V.5.00 Release 1 ご使用上のお願い
MAECT-M3T-NC308WA-020901D
- 割り込み処理関数に関する注意事項
- 3.1 内容
- 割り込み処理関数の入口処理と出口処理において、R0レジスタの退避と復旧が必要にもかかわらず行われないことがあります。
- 3.2 発生条件
- 以下のいずれかに該当する関数において発生することがあります。
- (1) #pragma INTERRUPT (/B指定なし) で指定された関数
- (2) #pragma INTHANDLER で指定された関数
- (3) #pragma HANDLER で指定された関数
- (4) M3T-MR308 のコンフィグレーションファイルで、割り込みベクタ定義(interrupt_vector) に登録された関数
- 3.3 発生例
[C言語ソース]
-----------------------------------------------------------------------
#pragma INTERRUPT intfunc
int i, j;
void intfunc(void)
{
if (i == 0)
i = i << j;
}
-----------------------------------------------------------------------
[コンパイル結果のアセンブリ語出力]
-----------------------------------------------------------------------
.glb _intf
_intf:
pushm R1 ; R0 の退避が行われていない
mov.w _i:16,R0 ; R0 への書込みが行われている
jne L1
mov.b _j:16,R1H
neg.b R1H
sha.w R1H,_i:16
L1:
popm R1 ; R0 の復旧が行われていない
reit
-----------------------------------------------------------------------
- 3.4 回避策
- この問題が発生した場合には、"-fSARII(-fsave_all_register_in_interrupt)" オプションを追加してコンパイルしてください。このオプションはマニュアルには記載されておりませんが、従来バージョンと同様、割り込み処理ですべてのレジスタの退避と復旧を行います。
このため、割り込み処理の速度が遅くなりますので、本件の回避の必要があるとき以外は使用しないでください。
- 3.5 恒久対策
- 本内容は、次期バージョンアップにて改修する予定です。
M3T-NC308WA V.5.00 Release 1 ご使用上のお願い
MAECT-M3T-NC308WA-020901D
- ビットフィールドおよび_Bool型変数に関する注意事項
- 4.1 内容
- ビットフィールドまたは_Bool型変数に定数を代入してから、他の関数を呼び出した後でその変数を参照すると、呼び出した関数でその変数の値が変更されていてもその値を正しく参照できないことがあります。
- 4.2 発生条件
- 以下6点の条件をすべて満たす場合に発生することがあります。
| (1) | 最適化オプション -O, -O[1-5], -OR, -OS のいずれかを使用している。 |
| (2) |
外部変数としてビットフィールドを含む構造体、または_Bool型の変数を、volatile修飾なしで宣言している。 |
| (3) | (2)の変数に、定数を代入している。 |
| (4) | (3)の定数の代入の後、他の関数を呼び出している。 |
| (5) | (4)の関数呼び出しの後、(3)で定数を代入した変数を参照している。 |
| (6) |
(2)の変数の値は、(3)の定数代入から(5)の参照までの間に、(4)の関数またはその下位の関数でのみ書き換えられ、それ以外に書き換えることがない。 |
- 4.3 発生例
-----------------------------------------------------------------------
struct { /* 発生条件(2) */
char bf:3;
} s;
int i;
void sub(void)
{
s.bf = 0; /* 発生条件(6) */
}
void func(void)
{
s.bf = 5; /* 発生条件(3) */
sub(); /* 発生条件(4) sub()内でsが書き換えられる */
if (s.bf == 5) { /* 発生条件(5) */
i = 0;
}
}
-----------------------------------------------------------------------
- 4.4 回避策
- 以下のいずれかの方法で回避してください。
- (1) 発生条件(5)の参照の直前にダミーのasm関数を挿入してください。
- (2) 該当する構造体、_Bool型変数をvolatile修飾して宣言してください。
- 4.5 恒久対策
- 本内容は、次期バージョンアップにて改修する予定です。
|