お世話になります。
CS+ for CA,CX(V4.07)を使ってRL78/G14のプログラムを書いています。
最適化は標準(-qx2)を使用しているのですが、レジスタ設定待ちの後に__asm("nop")が使えなくて悩んでいます。
過去のソースではタイマーRJのTRJCR0レジスタ設定後の3ステップ待ちの時に__asm("nop")を3つ書いて待っていたのですが、
最適化を入れるとNOP部分が削除されるようで、どう実装するか迷っています。
最適化されない3ステップ程度の意味のないコードを入れるか、関数があるファイル毎最適化を外すかと思ったのですが、
どれも素直じゃない気がしました。
みなさんならどの様な手段を使いますでしょうか?
chikamaさん、こんにちは。NoMaYと申します。CA78K0Rについては殆ど忘れてしまっているのですけれども、とっさに書いた以下のソースでは削除されませんでした。そちらではどのような記述をされているのか、もう少し具体的なソースを教えて頂けませんか?ソース
void main(void){ R_MAIN_UserInit(); /* Start user code. Do not edit comment…
chikamaさん、こんにちは。NoMaYです。たぶん大抵の人は__asm("nop");では無くNOP();を記述されていると思うのです。それであれば最適化に影響無いです。ソース
#pragma NOP /* 記述出来る場所にちょっと制約があるのでヘルプで確認して下さい。なおコード生成機能使用時はフレームワーク側で記述されています。 */void main(void){ R_MAIN_UserInit…
void main(void){ R_MAIN_UserInit(); /* Start user code. Do not edit comment generated here */ __asm("nop"); __asm("nop"); __asm("nop"); while (1U) { ; } /* End user code. Do not edit comment generated here */}
リストファイル
ALNO STNO ADRS OBJECT M I SOURCE STATEMENT 1 1 ; 78K0R C Compiler V2.72 Assembler Source Date:24 Feb 2023 Time:23:51:32 2 2 3 3 ; Command : -cf104ml -yC:\Renesas\CS+\CACX\Device\RL78\Devicefile r_main.c -o 4 4 ; DefaultBuild -_msgoff -qx2 -i. -w2 -zps -mm -mi0 -aDefaultBuild - 5 5 ; no -g2 6 6 ; In-file : r_main.c 7 7 ; Asm-file : DefaultBuild\r_main.asm 8 8 ; Para-file : 9 9 10 10 $PROCESSOR(F104ML) 11 11 $DEBUG 12 12 $NODEBUGA 13 13 $KANJICODE SJIS 14 14 $TOL_INF 03FH, 0272H, 02H, 04000H, 00H, 00H, 00H途中省略 52 52 PUBLIC _main 53 53 PUBLIC _R_MAIN_UserInit 54 54 55 55 ----- @@BITS BSEG 56 56 57 57 ----- @@CNST CSEG MIRRORP 58 58 59 59 ----- @@R_INIT CSEG UNIT64KP 60 60 61 61 ----- @@INIT DSEG BASEP 62 62 63 63 ----- @@DATA DSEG BASEP 64 64 65 65 ----- @@R_INIS CSEG UNIT64KP 66 66 67 67 ----- @@INIS DSEG SADDRP 68 68 69 69 ----- @@DATS DSEG SADDRP 70 70 71 71 ----- @@CNSTL CSEG PAGE64KP 72 72 73 73 ----- @@RLINIT CSEG UNIT64KP 74 74 75 75 ----- @@INITL DSEG UNIT64KP 76 76 77 77 ----- @@DATAL DSEG UNIT64KP 78 78 79 79 ----- @@CALT CSEG CALLT0途中省略 95 95 ----- @@CODEL CSEG 96 96 00000 _main: 97 97 $DGL 1,19 98 98 00000 ??bf_main: 99 99 ; line 60 100 100 $DGL 0,2 101 101 00000 RFC0A0000 call !!_R_MAIN_UserInit ;[INF] 4, 3 102 102 ; line 63 103 103 $DGL 0,5 104 104 00004 00 nop 105 105 ; line 64 106 106 $DGL 0,6 107 107 00005 00 nop 108 108 ; line 65 109 109 $DGL 0,7 110 110 00006 00 nop 111 111 ; line 67 112 112 00007 ?L0003: 113 113 ; line 68 114 114 00007 ??bb00_main: 115 115 ; line 69 116 116 00007 ??eb00_main: 117 117 ; line 70 118 118 $DGL 0,12 119 119 00007 EFFE br $?L0003 ;[INF] 2, 3 120 120 00009 ?L0004: 121 121 ; line 73 122 122 $DGL 0,15 123 123 00009 ??ef_main: 124 124 00009 D7 ret ;[INF] 1, 6 125 125 0000A ??ee_main:
すいません、私の早とちりによる勘違いでした。 ※新規にプロジェクトを設定したところ出力されることを確認、 現状のプロジェクトから該当部分を取り出したものを作成しても出力されることを確認、 実際のプロジェクトのasmファイル見て出力されることを確認、 何を元に私が出力されていないと信じたのか不明ですが、多分、後述のワーニングメッセージを読み間違えたと思います。
実際に出ていたワーニングは以下。
CC78K0R warning W0915: Asm statement found. skip to jump optimize this function 'DelayUs'
最適化が抑制される旨のワーニングでした。
なのでアセンブラ部分だけ別関数にするか、該当の関数の最適化をあきらめることにしました。 大変申し訳ございませんでした。
ちなみにこの関数はuSecオーダーのDelayの関数なので、誤差を減らすためあまり処理に時間をかけたくないのですが、 その場合は皆さんは3step待ちはどの様に実装されますでしょうか? nopを別関数にするとそれはそれでオーバーヘッドが大きくなりそうで・・・
#pragma NOP /* 記述出来る場所にちょっと制約があるのでヘルプで確認して下さい。なおコード生成機能使用時はフレームワーク側で記述されています。 */void main(void){ R_MAIN_UserInit(); /* Start user code. Do not edit comment generated here */ NOP(); NOP(); NOP(); while (1U) { ; } /* End user code. Do not edit comment generated here */}
ALNO STNO ADRS OBJECT M I SOURCE STATEMENT 1 1 ; 78K0R C Compiler V2.72 Assembler Source Date:28 Feb 2023 Time:00:57:27 2 2 3 3 ; Command : -cf104ml -yC:\Renesas\CS+\CACX\Device\RL78\Devicefile r_main.c -o 4 4 ; DefaultBuild -_msgoff -qx2 -i. -w2 -zps -mm -mi0 -aDefaultBuild - 5 5 ; no -g2 6 6 ; In-file : r_main.c 7 7 ; Asm-file : DefaultBuild\r_main.asm 8 8 ; Para-file : 9 9 10 10 $PROCESSOR(F104ML) 11 11 $DEBUG 12 12 $NODEBUGA 13 13 $KANJICODE SJIS 14 14 $TOL_INF 03FH, 0272H, 00H, 04000H, 00H, 00H, 00H途中省略 52 52 PUBLIC _main 53 53 PUBLIC _R_MAIN_UserInit 54 54 55 55 ----- @@BITS BSEG 56 56 57 57 ----- @@CNST CSEG MIRRORP 58 58 59 59 ----- @@R_INIT CSEG UNIT64KP 60 60 61 61 ----- @@INIT DSEG BASEP 62 62 63 63 ----- @@DATA DSEG BASEP 64 64 65 65 ----- @@R_INIS CSEG UNIT64KP 66 66 67 67 ----- @@INIS DSEG SADDRP 68 68 69 69 ----- @@DATS DSEG SADDRP 70 70 71 71 ----- @@CNSTL CSEG PAGE64KP 72 72 73 73 ----- @@RLINIT CSEG UNIT64KP 74 74 75 75 ----- @@INITL DSEG UNIT64KP 76 76 77 77 ----- @@DATAL DSEG UNIT64KP 78 78 79 79 ----- @@CALT CSEG CALLT0途中省略 95 95 ----- @@CODEL CSEG 96 96 00000 _main: 97 97 $DGL 1,19 98 98 00000 ??bf_main: 99 99 ; line 60 100 100 $DGL 0,2 101 101 00000 RFC0A0000 call !!_R_MAIN_UserInit ;[INF] 4, 3 102 102 ; line 63 103 103 $DGL 0,5 104 104 00004 00 nop ;[INF] 1, 1 105 105 ; line 64 106 106 $DGL 0,6 107 107 00005 00 nop ;[INF] 1, 1 108 108 ; line 65 109 109 $DGL 0,7 110 110 00006 00 nop ;[INF] 1, 1 111 111 ; line 67 112 112 00007 ?L0003: 113 113 ; line 68 114 114 00007 ??bb00_main: 115 115 ; line 69 116 116 00007 ??eb00_main: 117 117 ; line 70 118 118 $DGL 0,12 119 119 00007 EFFE br $?L0003 ;[INF] 2, 3 120 120 ; line 73 121 121 $DGL 0,15 122 122 00009 ??ef_main: 123 123 00009 D7 ret ;[INF] 1, 6 124 124 0000A ??ee_main:
[追記]CS+のヘルプを見てみると以下の記載となっていましたけれども、文面的には、全面的に最適化が行われなくなるのでは無く、ジャンプ最適化と呼ばれる最適化だけが行われなくなる、ようにも受け取れました。
W0915 [メッセージ]Asm statement found. skip to jump optimize this function'関数名' [説明]#asmブロック,または__asm文が検出されました。 この関数はジャンプ最適化を行いません。W0837の処置を行ってください。
ジャンプ最適化と呼ばれる最適化は、以下のように記載されていました。
B. 1. 2 機 能 (1) 最適化手法 CA78K0Rでは,効率のよいオブジェクト・モジュール・ファイルを生成するために,最適化を行います。 サポートする最適化手法を,次に示します。表B―2 最適化手法構文解析部(a)定数計算のコンパイル時実行 a=3 * 5 ; → a=15 ;途中省略オプティマイザ(q)ジャンプ最適化(-qjオプション)連続するジャンプ命令を1つにまとめるなど。以後省略
回答ありがとうございました。
NOP()があるのを知りませんでした。#pragmaは見てたはずなのに。