こんにちは。NoMaYです。e2 studio v6.3.0がリリースされていたので、インストールして幾つかプロジェクトを作成して、いつものようにe2 studioのインストールフォルダを眺めていたら、CCRXmachine.hとCCRXmachine.cというファイルがあることに気付きました。中を見てみると、概ねファイル名から予想される通りのソースファイルでした。(今までのe2 studioのインストールフォルダを見直してみたところ、以前からあったことが分かりましたが、今まで気付きませんでした。) ただ、一部コメントアウトされているものがあったり、以前に別スレッド『GUNRX用プロジェクトのスマートコンフィグレータのBSPを見ていて気付いた変な移植コード』で話題にしたことと同じ元のコードの意図を理解していない書き換えがあったり、ちょっと惜しいような気もしました。e2 studioインストールフォルダ\internal\projectgen\rx\Generate\CCRXConversion\inc\CCRXmachine.he2 studioインストールフォルダ\internal\projectgen\rx\Generate\CCRXConversion\inc\CCRXmachine.c
こんにちは。NoMaYです。e2 studio v7.6.0のバグリストを見ていたら、以下のバグ修正の記載に気付きました。このスレッドでmacl, macw1, macw2に関して調べたことを見返していて、はて?エンディアンに関するようなバグって発生するのだろうか?と思い、v7.5.0とv7.6.0とでソースを比較してみました。比較結果は以下の画面コピーの通り、エンディアンに関したバグ修正があったことはあったのですが、私は、これって配列の範囲を超えてリードしてしまっていることがそもそも駄目である(赤文字箇所)のでは?と思いました。(範囲を超えてリードしてしまった部分のデータは使われないので演算結果には影響しないとは言え。) (それと、別の行ですが、ワーニングレベルを上げるとwarning: 'register' is not at beginning of declaration [-Wold-style-declaration]というワーニングが出ます(橙文字箇所)。)更に、これに関して(所謂、一匹いたら十匹いると思え、的に)RX Driver Package V1.20/R_BSP Module V5.20のmacl, macw1, macw2相当処理のソースを見たところ、このスレッドでe2 studioのプロジェクトコンバータ生成した実装にはバグがあると指摘したコードが流用されていました。これは誤動作します。私が気になったe2 studio v7.6.0のバグリストのバグ修正の記載e²studio 7.6 Known Issues ListList generated on 02/10/2019 17:40:14www2.renesas.eu/_custom/software/ree_eclipse/e2studio7/docs/releasenotes/7.6.0/openissues.htm「IDE-29329Defect embedded function in CCRXmachine.hCCRX to GCC ConverterThe embedded function in CCRXmachine.h has a problem. When converting a CC-RX (big endian) project to GCC, the return value for macl, macw1, and macw2 of embedded functions differs from the expected value.」バグが修正されたe2 studio v7.6.0のソースであるが配列の範囲を超えてリードしてしまう箇所がある(赤文字箇所)(あと、ワーニングレベルを上げるとワーニングが出る箇所がある(橙文字箇所))e2studioインストールフォルダ/internal/projectgen/rx/Generate/CCRXConversion/inc/CCRXmachine.h
static __inline__ long __macl(short* data1, short* data2, unsigned long count){ signed long register *ldata1 = (signed long *)data1; signed long register *ldata2 = (signed long *)data2; /* this is much more then an "intrinsic", no inline asm because of loop */ /* will implement this.. interesting function as described in ccrx manual */ __builtin_rx_mullo(0, 0); while (count > 1) { __builtin_rx_maclo(*ldata1, *ldata2); __builtin_rx_machi(*ldata1, *ldata2); ldata1++; ldata2++; count -= 2; } #ifdef __RX_BIG_ENDIAN__ if (count != 0) __builtin_rx_machi(*ldata1, *ldata2); #else if (count != 0) __builtin_rx_maclo(*ldata1, *ldata2); #endif return __builtin_rx_mvfacmi();}
適切には以下のようなコードへ書き換えるべきだと思う
register signed long *ldata1 = (signed long *)data1; register signed long *ldata2 = (signed long *)data2;
// #ifdef __RX_BIG_ENDIAN__// if (count != 0) __builtin_rx_machi(*ldata1, *ldata2);// #else// if (count != 0) __builtin_rx_maclo(*ldata1, *ldata2);// #endif if (count != 0) __builtin_rx_maclo(*(short*)ldata1, *(short*)ldata2);
v7.5.0(左ペイン)とv7.6.0(右ペイン)とでソースを比較範囲を超えてリードしてしまった部分のデータは使われないので演算結果には影響しない(期待値の14と同じ)RX Driver Package V1.20/R_BSP Module V5.20のGNURX向け処理は昔のe2 studioのバグ有りソースを流用しているプロジェクトフォルダ/src/smc_gen/r_bsp/mcu/all/r_rx_intrinsic_functions.c
#if defined(__GNUC__)long R_BSP_MulAndAccOperation_2byte(short* data1, short* data2, unsigned long count){ unsigned long index; __builtin_rx_mullo(0, 0); for(index = 0; index < count; index++) { __builtin_rx_maclo(data1[index], data2[index]); __builtin_rx_machi(data1[index], data2[index]); } return (long)(R_BSP_GetACC() >> 16);}#endif /* defined(__GNUC__) */以下省略
プロジェクトフォルダ/src/smc_gen/r_bsp/mcu/all/r_rx_intrinsic_functions.h
#elif defined(__GNUC__)/* long R_BSP_MulAndAccOperation_2byte(short *data1, short *data2, unsigned long count) (This macro uses API function of BSP.) */#define R_BSP_MACL(x, y, z) R_BSP_MulAndAccOperation_2byte((short *)(x), (short *)(y), (unsigned long)(z))以下省略
バグ再現プロジェクトのファイル一式issue_20191013.zip誤動作して正しくない演算結果を返す(期待値の14と異なる)