
|
 |
MAEC TOOL NEWS:
MAECT-M3T-CC32R-011201D
M32Rファミリ用クロスツールキットM3T-CC32Rの使用上の注意事項を連絡します。
- 引数を4個以上持つ関数から引数を1~3個持つの関数を呼び出す場合の最適化に関する注意事項
- 該当製品
M3T-CC32R V.1.00 Release 1 ~ V.3.10 Release 1
- 内容
引数を4個以上持つ関数から引数を1~3個持つの関数を呼び出すプログラムに対して-O4を含む最適化を行うと、呼び出し側の関数の第4引数の処理が不正になる場合があります。
- 2.1 発生条件
- 以下6点の条件をすべて満たす場合に発生することがあります。
- (1) -O4を含む最適化オプションを指定している (-O4, -O5, -O6, -O7, -Otimeのみ、または-Ospaceのみを指定している)。
- (2) 引数を4個以上持つ関数があり、その第1~4引数までがレジスタ渡しされる可能性のある値(整数、ポインタまたはfloat型(*1)のいずれか)である。
- (3) (2)の関数内で、次のいずれかの変数を動的に初期化している。または変数への値の代入を行っている。
- (a) 構造体全体
- (b) double型変数
- (c) 配列
- (4) (2)の関数内で、(3)の操作の後に引数が1~3個の関数を呼び出している。
- (5) (4)の関数呼び出しの後、(2)の関数の第4引数を参照している。
- (6) (3)の動的初期化または代入が、_100_builtin_memcopy関数に置換されている(*2)。
- *1) V.2.10以前のCC32Rでは、float型がレジスタ渡しになることはありませんので、該当しません。
- *2) 条件(6)の確認は、-S オプションを使って生成されるアセンブリ言語のソースから 「_100_builtin_memcopy」 という文字列を探すことで確認できます(具体的な方法は 2.2 発生例 をご覧ください。)
- 2.2 発生例
[ソースファイル例1: sample1.c]
--------------------------------------------------------------------
extern int foo1(int, int, int);
struct {int a; int b[30]; int c;} A, B;
int
func1(int a, int b, int c, int d) /* 条件(2) */
{
A = B; /* 条件(3)(a) 構造体の代入 */
foo1(a, b, c); /* 条件(4) */
return d; /* 条件(5) */
}
--------------------------------------------------------------------
[ソースファイル例2: sample2.c]
--------------------------------------------------------------------
extern int foo2(int, int, int)
int
func2(int a,int b,int c,int d) /* 条件(2) */
{
int x[3] = {193,156,119}; /* 条件(3)(c) */
foo2(x[a], b, c); /* 条件(4) */
return d; /* 条件(5) */
}
--------------------------------------------------------------------
[ソースファイルに対するM3T-CC32Rのコマンド操作例
(%はプロンプトを表します)]
--------------------------------------------------------------------
[sample1.cの場合]
% cc32R -S -O4 sample1.c ; 条件(1)
% find "_100_builtin_memcopy" sample1.ms ; 条件(6)の確認
<< 条件(6)に該当していた場合 >>
---------------------------------------
---------- sample1.ms
.IMPORT $_100_builtin_memcopy
BL $_100_builtin_memcopy
<< 条件(6)に該当しなかった場合 >>
---------------------------------------
---------- sample1.ms ; 何も表示されません
[sample2.cの場合]
% cc32R -S -Ospace sample2.c ; 条件(1)
% find "_100_builtin_memcopy" sample2.ms ; 条件(6)の確認
<< 条件(6)に該当していた場合 >>
---------------------------------------
---------- sample2.ms
.IMPORT $_100_builtin_memcopy
BL $_100_builtin_memcopy
<< 条件(6)に該当しなかった場合 >>
---------------------------------------
---------- sample2.ms ; 何も表示されません
--------------------------------------------------------------------
※ EWS(UNIX)上の場合は、findコマンドの代わりにgrepコマンドを使用してください。
- 回避策
- 次の(1)~(3)のいずれかの方法で回避してください。
- (1) -O4を含む最適化を抑止する。
※-O4を含む最適化は、-O5, -O6, -O7, -Otimeのみ、または-Ospaceのみを指定しているときにも行われます。
-Otimeまたは-Ospaceを使用する場合は、同時に-O0,-O1,-O2,-O3のいずれかを指定してください。
- (2) 変数の動的初期化および代入を、同じ結果になるmemcpy関数の呼び出しに変更する。
[sample1.cの変更例]
--------------------------------------------------------------------
#include <string.h> /* memcpy関数を呼び出すために追加 */
extern int foo1(int, int, int);
struct {int a; int b[30]; int c;} A, B;
int
func1(int a, int b, int c, int d)
{
memcpy(&A, &B, sizeof(A)); /* 構造体の代入をmemcpy関数の呼び出しに変更 */
foo1(a, b, c);
return d;
}
--------------------------------------------------------------------
[sample2.cの変更例]
--------------------------------------------------------------------
#include <string.h> /* memcpy関数を呼び出すために追加 */
extern int foo2(int, int, int)
int
func2(int a,int b,int c,int d)
{
int x[3]; /* 初期化無しに変更 */
static int x_init[3] = {193,156,119}; /* 配列x_unitを初期化して宣言するために追加 */
memcpy(x, x_init, sizeof(x)); /* memcpy関数で配列xを初期化するために追加 */
foo2(x[a], b, c);
return d;
}
--------------------------------------------------------------------
- (3) 動的初期化を静的初期化に変更する。
※ 動的初期化が前提でプログラミングされている場合は使えません。
[sample2.cの変更例]
--------------------------------------------------------------------
extern int foo2(int, int, int)
int
func2(int a,int b,int c,int d)
{
static int x[3] = {193,156,119}; /* 静的初期化(static)に変更 */
foo2(x[a], b, c);
return d;
}
--------------------------------------------------------------------
- 恒久対策
本内容は、次期バージョンアップの際に改修する予定です。
|