アプリケーションノート

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX)
プログラミング・テクニック編

R01AN4195JJ0100
Rev.1.0
2018.03.20

要旨
コードサイズ・実行速度・ROM データサイズに効果的なプログラミング方法を説明します。

動作確認リビジョンRX ファミリ

CC-RX V2.08.00

目次
要旨 1
1.

はじめに ...........................................................................................................................32.

オプション .......................................................................................................................4

2.1

コンパイル・オプション............................................................................................................... 4

2.1.1-instalign4/-instalign8 .............................................................................................................. 7

2.1.2-nouse_div_inst ....................................................................................................................... 9

2.1.3-stack_protector/-stack_protector_all .................................................................................... 10

2.1.4-avoid_cross_boundary_prefetch.......................................................................................... 12

2.1.5-optimize ................................................................................................................................ 13

2.1.6-speed/-size........................................................................................................................... 14

2.1.7-loop ...................................................................................................................................... 15

2.1.8-inline ..................................................................................................................................... 16

2.1.9-case ..................................................................................................................................... 18

2.1.10 -volatile .................................................................................................................................. 19
2.1.11 -const_copy ........................................................................................................................... 20
2.1.12 -const_div/-noconst_div ........................................................................................................ 21
2.1.13 -library ................................................................................................................................... 22
2.1.14 -scope/-noscope.................................................................................................................... 23
2.1.15 -schedule/-noschedule .......................................................................................................... 25
2.1.16 -map/-smap ........................................................................................................................... 26
2.1.17 -approxdiv ............................................................................................................................. 27
2.1.18 -simple_float_conv ................................................................................................................ 28
2.1.19 -nofpu .................................................................................................................................... 29
2.1.20 -alias ...................................................................................................................................... 30
2.1.21 -ip_optimize ........................................................................................................................... 31
2.1.22 -merge_files .......................................................................................................................... 32
2.1.23 -whole_program .................................................................................................................... 33
2.1.24 -dbl_size ................................................................................................................................ 34
2.1.25 -int_to_short .......................................................................................................................... 35
2.1.26 -auto_enum ........................................................................................................................... 36
2.1.27 -pack ..................................................................................................................................... 37

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 1 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.28 -fint_register .......................................................................................................................... 39
2.1.29 -branch .................................................................................................................................. 41
2.1.30 -base ..................................................................................................................................... 42
2.1.31 -nouse_pid_register .............................................................................................................. 43
2.1.32 -save_acc .............................................................................................................................. 44
2.1.33 -control_flow_integrity ........................................................................................................... 45
2.2

アセンブル・オプション............................................................................................................. 46

2.3

リンク・オプション .................................................................................................................... 47

2.3.1-optimize=symbol_delete ...................................................................................................... 48

2.3.2-optimize=same_code ........................................................................................................... 49

2.3.3-optimize=short_format ......................................................................................................... 50

2.3.4-optimize=branch .................................................................................................................. 51

拡張言語 ......................................................................................................................... 52

3.
3.1#pragma 指令 .............................................................................................................................. 52

3.1.1

4.

#pragma interrupt .................................................................................................................. 53

コーディングテクニック ................................................................................................ 54

4.1

データの構造体化 ....................................................................................................................... 55

4.2

変数と const 型............................................................................................................................ 56

4.3

局所変数と大域変数 .................................................................................................................... 57

4.4

構造体宣言のメンバオフセット .................................................................................................. 58

4.5

ビットフィールドの割り付け ..................................................................................................... 60

4.6ループ制御変数 ........................................................................................................................... 61

4.7関数のインタフェース ................................................................................................................ 62

4.8

ループ回数の削減 ....................................................................................................................... 63

4.9

テーブルの活用 ........................................................................................................................... 64

4.10 分岐 ............................................................................................................................................. 65
4.11 インライン展開 ........................................................................................................................... 66
4.12 条件分岐先の同一文は分岐前に移動する ................................................................................... 68
4.13 複雑な if 文を論理的に等しいものに置き換える ........................................................................ 70
4.14 short, char 型の変数は int 型にする ............................................................................................ 71
4.15 switch 文の共通な case の処理をまとめる ................................................................................. 72
4.16 for ループを do while ループに置き換える ................................................................................. 74
4.17 2 のべき乗の除算はシフト演算に置き換える ............................................................................. 75
4.18 2 ビット以上のビットフィールドは char 型に変更する............................................................. 76
4.19 定数参照の際には絶対値の小さい値を割り当てる ..................................................................... 77

ホームページとサポート窓口 ................................................................................................ 78

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 2 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
1.

はじめに

コードサイズ・実行速度・ROM データサイズに効果的なプログラミング方法として、以下の 3 つの項目に分けてそれぞれ説明します。


オプション



拡張言語



コーディングテクニック

本アプリケーションノート記載の測定結果、アセンブリ言語展開コードは CC-RX V2.08 を用いて取得しています。-isa/-cpu オプションの指定値は -isa=rxv2 です。また、最適化オプションのデフォルト設定は以下のようになります。
サイズ重視の最適化
最適化レベル
ループ展開
インライン展開
定数除算の乗算化
命令並び替えconst 修飾変数の定数伝播
最適化範囲分割
外部変数アクセス最適化
ポインタ指示先の型を考慮した最適化-size-optimize=2-loop=2-noinline-noconst_div-schedule-const_copy-scope-nomap-alias=noansi

なお、これらのプログラミング方法の効果は前後に存在するプログラムや、今後のコンパイラ改善などにより変わる可能性があります。

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 3 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.

オプション

CC-RX のオプション指定によるコードサイズ・ROM データサイズ・実行速度への影響を示します。な
お、効果の程度はソースプログラムの内容によって異なります。

2.1

コンパイル・オプション○…改善する×…劣化する△…改善することもあれば劣化することもある ―…変化しない( )…デフォルト設定
オプション

コード
サイズ

ROM
サイズ

サイクル
数

-instalign4

×

－

○

-instalign8

×

－

○

-nouse_div_inst

×

×

×

-stack_protector-stack_protector_all

×

－

×

-avoid_cross_boundary_prefetch

×

－

×

-optimize(-size オプション指定時)

○

△

△

-optimize(-speed オプション指定時)

△

△

○

-goptimize

○

○

○

×
( ○ )
×
×

－
－
－
－

○
( × )
○
○

-speed-size-loop-inlineR01AN4195JJ0100
2018.03.20

Rev.1.0

備考
命令キューが 32 ビットの CPU（主に RX200 シリーズ）向けに、分岐先の命令実行向け整合を行います。
命令キューが 64 ビットの CPU（主に RX600 シリーズ）向けに、分岐先の命令実行向け整合を行います。
除算命令の生成を抑止すること
で、割り込み関数の応答性を改善します。コードサイズや実行速度
は劣化します。
関数の入口・出口にスタック破壊
検出コードを生成します。検出
コードの分、コードサイズと実行速度は劣化します。
ストリング操作命令のデータプリ
フェッチで 4 バイト境界をまたぐ
読み出しを行わないようコードを生成します。コードサイズと実行速度は劣化します。
-size オプション指定時はコード
サイズを優先して最適化を実施します。反面、実行速度は劣化する場合があります。
-speed オプション指定時は実行
速度を優先して最適化を実施します。反面、コードサイズは劣化する場合があります。
本オプションを指定したファイル
は、リンク時にモジュール間最適化の対象になります。
リンク時の最適化については 2.3
リンク・オプション を参照くだ
さい。

効果はパラメータに依存します。
効果はパラメータに依存します。

Page 4 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編-case=ifthen

×

○

△

-case=table

○

×

△

-volatile

×－×-const_copy

( ○ )

－

( ○ )

-noconst_copy-const_div-noconst_div-library=intrinsic

×
×
( ○ )
○

－
－
－
－

×
○
( ○ )
○

-noscope○－○-schedule

－

－

( ○ )

-noschedule
-map
-smap

－
○
○

－
－
－

×
○
○

-approxdiv

－

－

○

-simple_float_conv

○

－

○

-nofpu-alias=ansi-ip_optimize-merge_files-whole_program

×
○
○
○
○

－
－
△
△
△

×
○
○
○
○

-dbl_size=8

×

×

×

-int_to_short

△

○

△

-auto_enum
-pack

△
×

○
○

△
×

-fint_register

△

－

△

-branch=16-branch=32

○
×

－
－

－
×

-base

△

－

△

-nouse_pid_register

×

－

×

-save_acc△－△

R01AN4195JJ0100
2018.03.20

Rev.1.0case ラベル数が多いほどコードサイズが増大します。
case ラベルが多いほど ROM
データサイズが増大しますが、サ
イクル数が常に一定です。
const 修飾型外部変数についても定数伝播を行い、コードサイズと実行速度を改善します。
-const_copy を無効にします。

大規模な関数に対しては性能が劣化する場合があります。
パイプライン処理を考慮した命令
並べ替えを行い、実行速度を改善します。
-schedule を無効にします。

演算の精度と演算の順序が変わる
場合があります。
-isa=rxv1 の場合に性能が改善します。

double 型を 8byte としてコンパイルします。
int 型を short 型に置き換えてコンパイルします。

高速割り込み関数でのみ使用する
汎用レジスタを指定します。割り込み関数の性能が改善しますが、対して通常関数の性能は劣化します。

プログラム全体で外部変数へのア
クセス回数が多い場合に効果的です。
PID レジスタを使用せずにコード生成するため、コードサイズと実行速度は劣化します。
割り込み関数に対して、アキュム
レータの退避・回復コードを生成
Page 5 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編-control_flow_integrity

R01AN4195JJ0100
2018.03.20

Rev.1.0×××

します。アキュムレータを用いる
命令を生成するようになりますが、割り込み関数の性能は劣化します。
間接関数呼び出しのチェック機能を生成します。チェック機能の分、コードサイズと実行速度、
ROM サイズは劣化します。

Page 6 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.1-instalign4/-instalign8

分岐先の命令実行向け整合を行うかどうかを指定します。整合を行った場合、CPU の命令キューを効率よく動作させ、プログラムの実行速度を向上させることができますが、コードサイズが増大します。
-instalign4 を指定した場合、4 バイト単位の命令キューを持つ CPU の仕様に合わせて、命令の配置アドレスを整合します。主に RX200 シリーズ向けのオプションです。
-instalign8 を指定した場合、8 バイト単位の命令キューを持つ CPU の仕様に合わせて、命令の配置アドレスを整合します。主に RX600 シリーズ向けのオプションです。
デバイスの命令キューの仕様は、ユーザーズマニュアルハードウェア編に記載されています。

C ソース
long a;int func1(int num){
return (num + 1);}
void func2(void){a += 1;a += a;}void main(void){
unsigned int i;for (i = 0; i < 10; ++i) {if (func1(i) < 10) {func2();}}
a += 1;}-cpu=rx200(命令キューが 32 ビットの CPU)
-instalign4
コードサイズ[バイト]サイクル数[サイクル]

57
278

オプション未指定
55297-cpu=rx600(命令キューが 64 ビットの CPU)
-instalign8
コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.061
259

オプション未指定55
278

Page 7 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
本機能は#pragma でも指定できます。オプションと#pragma の両方が指定された場合は、#pragma の指定を優先します。

例) –instalign4 指定時
void func1(void){}#pragma instalign8 func2
void func2(void){}/* 4 バイトで整合(オプション指定) *//* 8 バイトで整合 */#pragma noinstalign func3
void func3(void)/* 整合なし */{}例) -instalign8 指定時
void func1(void){}#pragma instalign4 func2
void func2(void){}/* 8 バイトで整合(オプション指定) *//* 4 バイトで整合 */#pragma noinstalign func3
void func3(void)/* 整合なし */{}R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 8 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.2-nouse_div_inst

プログラム中のすべての除算および剰余算を、DIV 命令、DIVU 命令および FDIV 命令を使わないコードを生成します。
DIV、DIVU および FDIV 命令を生成する代わりに、それぞれの命令に相当する処理を行うランタイム関数の呼び出しに置き換えます。このため、割り込み関数の応答性は 1～20 サイクル程度改善しますが、コードサイズや実行速度等のコード効率が劣化します。

C ソース
long a, b;
unsigned long c, d;float e, f;
const float cf= 11.0;
void main(void){a = a / b;c = c / d;e = e / f;
f = e / cf;}

オプション指定
オプション未指定85
69
コードサイズ[バイト]70159
サイクル数[サイクル]※オプション指定により ROM サイズも増大する可能性があります

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 9 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.3-stack_protector/-stack_protector_all

関数の入口・出口にスタック破壊検出コードを生成します。
検知コードの分、コードサイズと実行速度が劣化します。

C ソース#include <stdio.h>#include <stdlib.h>void func(void){
volatile char str[10];int i;for (i = 0; i <= 9; i++) {str[i] = i;}}void __stack_chk_fail(void){/* stack is broken! */__brk();}
void main(void){func();}-stack_protector
コードサイズ[バイト]サイクル数[サイクル]

44
75-stack_protector_all
65
82

オプション未指定2468

本機能は#pragma でも指定できます。オプションと#pragma の両方が指定された場合は、#pragma の指定を優先します。

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 10 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
例) -stack_protector/-stack_protector_all 指定時
struct DATA{
int a, b, c, d;};struct DATA func1(void)/* スタック破壊検出コードを生成する */{struct DATA data = {0, 1, 2, 3};
return data;}#pragma no_stack_protector (func2)
struct DATA func2(void)/* スタック破壊検出コードを生成しない */{struct DATA data = {0, 1, 2, 3};
return data;}例) -stack_protector/-stack_protector_all 未指定時
struct DATA{
int a, b, c, d;};struct DATA func1(void)/* スタック破壊検出コードを生成しない */{struct DATA data = {0, 1, 2, 3};
return data;}#pragma stack_protector (func2)
struct DATA func2(void)/* スタック破壊検出コードを生成する */{struct DATA data = {0, 1, 2, 3};
return data;}

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 11 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.4-avoid_cross_boundary_prefetch

ストリング操作命令のデータプリフェッチで 4 バイト境界をまたぐ読み出しを防止します。
文字列操作用ライブラリ関数 memchr()、strlen()、strcpy()、strncpy()、strcmp()、strncmp()、strcat()、strncat()
を-library=intrinsic を指定してコンパイルした際のコードサイズと実行速度が劣化します。

C ソース#include <string.h>
unsigned long len;void main(void){char str[] = "abcdefghijklmnopqrstuvwxyz";
len = strlen(str);}

オプション指定
コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.050
79

オプション未指定43
73

Page 12 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.5-optimize

最適化レベルを指定します。
デフォルト設定は-optimize=2 です。
-size/-speed オプションの選択と、最適化レベルの選択、及び入力ソースの種類(C/C++)によって、以下オプションのデフォルト指定が変化します。

項目
ループ展開
インライン展開
定数除算の乗算化
命令並び替えconst 修飾変数の定数伝播
最適化範囲分割
外部変数アクセス最適化
ポインタ指示先の型を考慮した最適化

オプション
-loop
-inline / -noinline-const_div / -noconst_div-schedule / -noschedule-const_copy / -noconst_copy-scope / -noscope-map / -smap / -nomap-alias=ansi / -alias=noansi

C ソース
int i = 0;
int x[10], y[10];static void sub(int* a, int* b, int i){
int temp;
temp = a[i];a[i] = b[i];b[i] = temp;}
void main(void){sub(x, y, i);}-optimize=0-optimize=1-optimize=263
37
35
コードサイズ[バイト]3620
14
サイクル数[サイクル]※オプション指定により ROM サイズも増大する可能性があります

R01AN4195JJ0100
2018.03.20

Rev.1.0-optimize=max
24
10Page 13 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.6-speed/-size

最適化で重視するポイントを設定します。
-speed オプションを指定した場合、実行速度重視の最適化を実施します。
-size オプションを指定した場合、コードサイズ重視の最適化を実施します。(デフォルト)

C ソース
long a;void main(void){
unsigned long i = 0;
unsigned long j = 0;
for (i = 0; i < 5; ++i) {for (j = 0; j < 5; ++j) {a += (i + j);a *= (i + j);}}}-speed
コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

70
226

-size
45
310

Page 14 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.7

-loop

ループ展開の最適化を行うかどうかを指定します。
ループ展開を行うとコードサイズは増大しますが、実行速度は向上します。

C ソース
long val;
void main(void){
unsigned long i, j, k, l;for (i = 1; i < 7; ++i) {for (j = 1; j < 6; ++j) {for (k = 1; k < 5; ++k) {for (l = 1; l < 4; ++l) {val += (i + j + k);
val *= (i + j + k);}}}
val += (i * 10);}}-loop=1-loop=2
154
204
コードサイズ[バイト]
4391
3424
サイクル数[サイクル]※-loop=8 は-optimize=max/-speed 指定時のデフォルト値です

R01AN4195JJ0100
2018.03.20

Rev.1.0-loop=83073069

Page 15 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.8-inline関数の自動インライン展開を行うかどうかを指定します。
-inline を指定した場合、関数の自動インライン展開を行います。
-noinline を指定した場合、関数の自動インライン展開を行いません。
オプション-inline はパラメータを指定することも可能です。パラメータで、関数サイズが何%増加するまでインライン展開を行うかを指定できます。例えば、inline=100 を指定した場合、コード全体サイズが 100%
増加するまで（2 倍まで）インライン展開を行います。また inine=0 を指定した場合はサイズが増えない、あるいは減る場合のみインライン展開を行います。

C ソース
long val;
long x[1000];
static void func1(void){++val;}
void func2(int a){
if (a) {x[a] = 0;}}
void main(void){
signed int i;
func2(val);for (i = 0; i < 10; ++i) {func2(i);func1();
func2(val);}
func2(val);}-inline=200
コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

93150

Rev.1.0-inline=058364-noinline
70465Page 16 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
尚、インライン展開の機能は#pragma でも指定できます。オプションと#pragma の両方が指定された場合
は、#pragma の指定を優先します。

例) -inline 指定時
void func1(void){}#pragma noinline(func2)
void func2(void){}/* 自動インライン展開を行います(オプション指定) *//* インライン展開されません */例) -noinline 指定時
void func1(void){}#pragma inline(func2)
void func2(void){}

R01AN4195JJ0100
2018.03.20

Rev.1.0/* 自動インライン展開を行いません(オプション指定) *//* インライン展開します */Page 17 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.9

-case

switch 文のコード展開方式を指定します。
-case=ifthen を指定した場合、if_then 方式で展開します。case ラベル数が多いほどコードサイズが増大します。case ラベルによって実行速度が変化します。
-case=table を指定した場合、テーブル方式で展開します。case ラベル数が多いほど ROM データサイズが増大しますが、実行速度が常に一定です。
-case=auto を指定した場合、if_then 方式とテーブル方式のどちらにするかコンパイラが自動的に選択します。(デフォルト設定)

C ソース
long val = 10;
void main(void){switch (val) {case 1:
val += 10;
break;
case 2:val *= 10;
break;
case 3:val /= 10;
break;
default:
val -= 10;
break;}}-case=ifthen-case=table
31
39
コードサイズ[バイト]4
7
ROM サイズ[バイト]1513
サイクル数[サイクル]※上記 C ソース例の場合 -case=auto では if_then 方式が選択されます

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 18 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.10-volatile

全ての外部変数を volatile 宣言したものとして扱うかどうか選択します。
-volatile を指定した場合、すべての外部変数を volatile 宣言したものとして扱います。したがって、外部変数のアクセス回数、アクセス順序は C/C++言語ソースファイルで記述した通りになりますが、外部変数に対する最適化が抑止されるため、コードサイズと実行速度は劣化します。

C ソース
long val = 0;
void main(void){
val += 1;
val -= 2;
val *= 3;
val /= 4;}

コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション指定33
22

オプション未指定19
12

Page 19 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.11-const_copy

const 修飾外部変数の定数伝播を行うかどうか選択します。定数伝播を行うと、実行速度が向上します。
-const_copy を指定した場合、const 修飾型外部変数についても定数伝播を行います。(デフォルト設定)-noconst_copy を指定した場合、const 修飾型外部変数の定数伝播を抑止します。

C ソース
const long val = 0;long result;void main(void){
result = val + 10;}-const_copy
コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

105-noconst_copy
198Page 20 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.12-const_div/-noconst_div

整数定数による除算や剰余算を、乗算やビット演算(シフトやビット論理積)を用いた命令列に変換するかどうか選択します。変換する場合、コードサイズが増大しますが、実行速度が向上します。
-const_div を指定した場合、ソースファイル中の整数型定数による除算および剰余算を、乗算やビット演算を用いた命令列に変換します。-size オプション指定時に本オプションを指定すると、-noconst_div を指定した場合に比べて実行速度が向上します。
-noconst_div を指定した場合、ソースファイル中の整数型定数による除算および剰余算に、それぞれに対応する除算命令および剰余算命令(2 のべき乗定数値による符号なし整数の除算および剰余算を除く)を用います。-speed オプション指定時に本オプションを指定すると、-const_div を指定した場合に比べてコードサ
イズを削減できます。

C ソース
long a = 0x7FFFFFFF;
void main(void){a = a / 1000;}

コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0-const_div (-size)-const_div (-speed)

26
13

27
12

-noconst_div(-size/-speed)
1623Page 21 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.13-library

一部の標準ライブラリ関数のコード展開方式を指定します。
-library=function を指定した場合、ライブラリ関数をすべて関数呼び出しします。コードサイズと実行速度が劣化します。
-library=intrinsic を指定した場合、abs()、fabsf()およびストリング操作命令が使用できるライブラリ関数を命令展開します。(デフォルトの指定) また、-library=intrinsic とともに-isa=rxv2 が指定されている場合は、
sqrtf()または-dbl_size=4 指定時の sqrt()のそれぞれの呼び出しを FSQRT 命令に置き換えます。ただし、本オ
プションで命令に展開された場合は、変数 errno の内容を変更しません。

C ソース#include <stdlib.h>
int a;
void main(void){a = abs(a);}コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0-library=function
19
16-library=intrinsic
13
8Page 22 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.14-scope/-noscope

コンパイル時の最適化範囲を分割するかどうか選択します。

-noscope を指定した場合、最適化範囲を分割せずにコンパイルします。最適化範囲が広がることによりコンパイル速度は遅くなりますが、一般的にはオブジェクト性能が改善します。
大規模な関数をコンパイルする場合には、プログラム中で必要な汎用レジスタの数が著しく増加し、オブジェクト性能が劣化する場合がありますが、-scope を使用すると、大規模な関数を複数の範囲に分割して最適化を実施します。そのため、大規模な関数をコンパイルする場合には、-scope を使用する
ことで、-noscope 使用時よりもオブジェクト性能が改善する場合があります。
C ソース
long array[40];long val = 10;
void main(void){
int i;for (i = 0; i < 40; ++i) {array[i] = val * i;}for (i = 0; i < 40; ++i) {if (array[i] > i) {array[i] += val + i;}else if (array[i] > (i * 2)) {array[i] += val + (i * 2);}else if (array[i] > (i * 3)) {array[i] += val + (i * 3);}else if (array[i] > (i * 4)) {array[i] += val + (i * 4);}else if (array[i] > (i * 5)) {array[i] += val + (i * 5);}else if (array[i] > (i * 6)) {array[i] += val + (i * 6);}else if (array[i] > (i * 7)) {array[i] += val + (i * 7);}else if (array[i] > (i * 8)) {array[i] += val + (i * 8);}else if (array[i] > (i * 9)) {array[i] += val + (i * 9);}else {
array[i] += val + (i * 10);}}}

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 23 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編-scope318
コードサイズ[バイト]1089
サイクル数[サイクル]※ループ展開(-loop=2)を指定

R01AN4195JJ0100
2018.03.20

Rev.1.0-noscope
312
1046

Page 24 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.15-schedule/-noschedule

パイプライン処理を考慮した命令並べ替えを行うかどうかを選択します。並べ替えを行う場合、実行速度の向上が期待できます。
-schedule を指定した場合、パイプライン処理を考慮した命令並べ替えを行います。-optimize=2 またはoptimize=max オプションを指定した場合は-schedule です。
-noschedule を指定した場合、命令並べ替えを行いません。基本的に C/C++言語ソースファイルで記述した順番で処理を行います。-optimize=1 または-optimize=0 オプションを指定した場合は-noschedule です。

C ソース
long a, b;
unsigned long c, d;float e, f;
void main(void){a = a + b;
c = c + d;e = e + f;}

-schedule
コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

58
24-noschedule
58
25

Page 25 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.16-map/-smap

外部変数アクセス最適化を行うかどうか選択します。本最適化を行うとコードサイズや実行速度といったコード効率が改善します。
-map を指定した場合、外部変数アクセス最適化を行います。最適化リンケージエディタが生成する外部
シンボル割り付け情報を元にベースアドレスを設定し、外部変数もしくは静的変数のアクセスをベースアド
レス相対で行うコードを生成します。 なお、-map は-output の指定により使い方が異なります。
(1) -output=obj または src の場合
最初に本オプションを指定しないでコンパイルし、リンク時に-map=<ファイル名>を指定して外部シンボ
ル割り付け情報ファイル(.bls)を作成してください。
ccrx -isa=rxv2 -output=obj tp1.c tp2.c
rlink tp1.obj tp2.obj -map=out.bls
再度コンパイル時に -map=<外部シンボル割り付け情報ファイル> を指定することで外部変数アクセス最適化を行ったコードを生成します。
ccrx -isa=rxv2 -output=obj -map=out.bls tp1.c tp2.c
rlink tp1.obj tp2.obj -output=out.abs(2) -output=abs または hex、sty の場合
パラメータなしで -map のみを指定してください。自動的にコンパイル・リンクを 2 回行い、外部変数アクセス最適化を行ったコードを生成します。
ccrx -isa=rxv2 -output=abs -map tp1.c tp2.c-smap を指定した場合、コンパイル対象ファイル内で定義された外部変数もしくは静的変数についてベースアドレスを設定し、アクセスをベースアドレス相対で行うコードを生成します。

C ソース [tp1.c]long a, b, c;
extern long d, e, f;
void main(void){a = d;
b = e;
c = f;}
C ソース [tp2.c]long d = 10;
long e = 10;
long f = 10;-map
コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

21
13

-smap
33
14

オプション未指定43
16

Page 26 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.17-approxdiv

浮動小数点定数除算を、定数の逆数の乗算に変換します。浮動小数点定数除算の実行速度は向上します
が、演算の精度と順序が変わる場合がありますので注意が必要です。

C ソース
float a;void main(void){a /= 1.1;}

コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション指定18
9

オプション未指定18
23

Page 27 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.18-simple_float_conv

浮動小数点型の型変換処理の一部を省略します。生成する命令コードの命令セットアーキテクチャがRXv1 の時に効果を期待できます。
次の場合において、浮動小数点の型変換を行う生成コードが変化します。
a) 32bit 浮動小数点型から符号無し整数型への変換b) 符号無し整数型から 32bit 浮動小数点型への変換
c) 32bit 浮動小数点型を経由した、整数型から 64bit 浮動小数点型への変換(-optimize=0 のときは無効)
コードサイズや実行速度といったコード効率は改善しますが、変換結果が C/C++言語規格と異なる場合がありますので、ご注意ください。

C ソース
unsigned long isrc = 2;
float fsrc = 2.0;
unsigned long idst;
float fdst;
void main(void){
idst = (unsigned long)fsrc;
fdst = (float)isrc;}

コードサイズ[バイト]サイクル数[サイクル]※RXv1(-isa=rxv1)を指定

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション指定36
17

オプション未指定73
23

Page 28 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.19-nofpuFPU 命令を使用したコードを生成するかどうかを選択します。
-nofpu を指定した場合、FPU 命令を使用しないコード生成を行います。
-fpu を指定した場合、FPU 命令を使用したコード生成を行います。
デフォルトの指定は-fpu です。ただし、-cpu=rx200 を指定した場合は-nofpu が指定されます。-cpu=rx200と-fpu を同時に指定することはできません。

C ソース
float a, b;
const float c = 11.0;
void main(void){a /= b;b /= c;}-fpu
コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

31
40-nofpu45
97

Page 29 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.20-alias

ポインタ指示先の型を考慮した最適化を実施するかどうかを選択します。最適化を行うと、コードサイズ
や実行速度といったコード効率が改善します。但し、ISO/IEC 9899 に則った C ソースでない場合、実行結果が期待した値とならない可能性があります。
-alias=ansi を指定した場合、ISO/IEC 9899 に基づき、ポインタ指示先の型を考慮した最適化を行います。
一般には、-alias=noansi を指定した場合よりもオブジェクト性能が向上しますが、-alias=ansi と-alias=noansi とで実行結果が異なる場合があります。
-alias=noansi を指定した場合、ISO/IEC 9899 に基づくポインタ指示先の型を考慮した最適化を行いませ
ん。

C ソース
long a, b;
short* ps;void main(void){a = 1;*ps = 2;b = a + *ps;}-alias=ansi
コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.030
10-alias=noansi
3616Page 30 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.21-ip_optimize

大域最適化(手続き間別名解析を利用した最適化や引数・戻り値の定数伝播など)を実施するかどうかを選
択します。

C ソース
long result;static long func(long x, long y, long z){
return (x - y + z);}
void main(void){
result = func(3, 4, 5);}

コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション指定21
17

オプション未指定23
18

Page 31 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.22-merge_files

複数の C ソースファイルをマージしてコンパイルすることにより、1 つのオブジェクトファイルを出力します。
-merge_files は-ip_optimize と同時に指定すると相乗効果を得ることが出来ます。

C ソース [tp1.c]long result;void main(void){
result = func(3, 4, 5);}
C ソース [tp2.c]#pragma inline (func)
long func(long x, long y, long z){
return (x - y + z);}

オプション指定122
コードサイズ[バイト]5
サイクル数[サイクル]※ROM サイズも改善する場合があります※サイズはスタートアップを含みます

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション未指定131
19

Page 32 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.23-whole_program

コンパイル対象ファイルがプログラム全体であることを仮定し、コンパイル対象ファイル全てをマージして大域最適化を実施します。
本オプションを指定した場合、コンパイラは以下の条件を満たすことを前提にコンパイルを行います。条件を満たさない場合の動作は保証しません。
(条件 1) コンパイル対象ファイル内で定義された extern 変数の内容及びアドレスが、コンパイル対象ファ
イル以外で設定及び参照されることはない。
(条件 2) コンパイル対象ファイル内からコンパイル対象ファイル以外の関数を呼び出したとしても、呼び出された関数からコンパイル対象ファイル内の関数が呼ばれることはない。

C ソース [tp1.c]
extern const int c;
int result;int func(void);void main(void){
result = c;
result += func();}
C ソース [tp2.c]
const int c = 1;
int x = 10;
int *p;int func(void){
int i;for (i = 0; i < x; ++i) {(*p) += c;}return (*p);}

オプション指定170
コードサイズ[バイト]93
サイクル数[サイクル]※ROM サイズも改善する場合があります※サイズはスタートアップを含みます

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション未指定
171
163

Page 33 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.24-dbl_size

double 型および long double 型を float 型に変更するかどうかを指定します。
-dbl_size=4 を指定した場合、float 型に変更します。(デフォルト指定)-dbl_size=8 を指定した場合、float 型に変更しません。

C ソース
double a, b;
const double c = 11.0;
void main(void){a = a / b;b = b / c;}-dbl_size=4
コードサイズ[バイト]ROM サイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.031440-dbl_size=8
63
8
107

Page 34 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.25-int_to_short

ソースファイル内の int を short に、unsigned int を unsigned short に置換してコンパイルを行います。
int、unsigned int のサイズを 32bit と仮定した移植性のないプログラムでは、実行結果が変化する可能性が
あります。

C ソース
int x;
long y;const int imm = 1;
void main(void){x += imm;
y += x;}

コードサイズ[バイト]ROM サイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション指定26
2
13

オプション未指定24
4
12

Page 35 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.26-auto_enum

enum 宣言した列挙型のデータを、列挙値が収まる最小型として処理します。
ROM データサイズが小さくなりますが、enum の値を long 型等に拡張して使用する場合、コードサイズと実行速度が変化する場合もあります。

C ソース
enum number {
one
= 1,
two
= 2,
three = 3};
int x;
enum number num;const enum number DATA = one;void main(void){num += num;x += num;}

コードサイズ[バイト]ROM サイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション指定26
1
13

オプション未指定24
4
12

Page 36 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.27-pack

構造体メンバ、クラスメンバのアライメント数を指定します。
-pack を指定した場合、構造体、クラスのアライメント数が 1 になり、ROM データサイズが小さくなりま
すが、アライメント調整が必要になる場合、コードサイズと実行速度が劣化します。
-unpack を指定した場合、構造体、クラスのアライメント数が、メンバの最大のアライメント数と同じになります。(デフォルト設定)

C ソース
struct DATA{
char c;long l;};struct DATA data = {1, 2};long result;long func(void){
return (data.l);}void main(void){
result = func();}-pack
コードサイズ[バイト]ROM サイズ[バイト]サイクル数[サイクル]

23
5
17

-unpack
21
816

本機能は#pragma でも指定できます。オプションと#pragma の両方が指定された場合は、#pragma の指定を優先します。

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 37 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編例) -pack 指定時
struct DATA1{char a;long b;short c;} data1;/* pack 処理はオプション指定に従う *//* バイトオフセット = 0 *//* バイトオフセット = 1 *//* バイトオフセット = 5 *//* 合計サイズ 7 バイト */#pragma unpack
struct DATA2/* pack 処理を行わない */{char a;/* バイトオフセット = 0 */long b;/* バイトオフセット = 4 */short c;/* バイトオフセット = 8 */} data2;/* 合計サイズ 12 バイト */#pragma packoption
struct DATA3/* pack 処理はオプション指定に従う */{char a;/* バイトオフセット = 0 */long b;/* バイトオフセット = 1 */short c;/* バイトオフセット = 5 */} data3;/* 合計サイズ 7 バイト */例) -unpack 指定時
struct DATA1{char a;long b;short c;} data1;#pragma packstruct DATA2{char a;long b;short c;} data2;/* pack 処理はオプション指定に従う *//* バイトオフセット = 0 *//* バイトオフセット = 4 *//* バイトオフセット = 8 *//* 合計サイズ 12 バイト *//* pack 処理を行う *//* バイトオフセット = 0 *//* バイトオフセット = 1 *//* バイトオフセット = 5 *//* 合計サイズ 7 バイト */#pragma packoption
struct DATA3/* pack 処理はオプション指定に従う */{char a;/* バイトオフセット = 0 */long b;/* バイトオフセット = 4 */short c;/* バイトオフセット = 8 */} data3;/* 合計サイズ 12 バイト */R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 38 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.28-fint_register

高速割り込み関数（#pragma interrupt で割り込み仕様に高速割り込み指定（fint）のある関数）でのみ使用する汎用レジスタを指定します。拡張言語仕様 #pragma interrupt については、3.1.1 を参照ください。高速
割り込み関数以外では、指定されたレジスタは使用しません。高速割り込み(fint)は、本オプションで指定したレジスタを退避、回復せずに割り込み関数で使用できます。このため、割り込み関数の性能は改善します
が、割り込み関数以外で使用可能なレジスタが減るため、プログラム全体の性能が劣化する場合があります。
オプション
fint_register=0 (デフォルト設定)
fint_register=1
fint_register=2
fint_register=3
fint_register=4

高速割り込み専用レジスタなし
R13
R12、R13
R11、R12、R13
R10、R11、R12、R13

C ソース [通常関数]
long val[40];long tmp = 10;
void main(void){
int i;for (i = 0; i < 40; ++i) {if (tmp > i) {val[i] = tmp + i;}else if (tmp > (i * 2)) {val[i] = tmp + (i * 2);}else if (tmp > (i * 3)) {val[i] = tmp + (i * 3);}else if (tmp > (i * 4)) {val[i] = tmp + (i * 4);}else if (tmp > (i * 5)) {val[i] = tmp + (i * 5);}else if (tmp > (i * 6)) {val[i] = tmp + (i * 6);}else if (tmp > (i * 7)) {val[i] = tmp + (i * 7);}else if (tmp > (i * 8)) {val[i] = tmp + (i * 8);}else if (tmp > (i * 9)) {val[i] = tmp + (i * 9);}else {
val[i] = tmp + (i * 10);}}}

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 39 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編

コードサイズ[バイト]サイクル数[サイクル]

fint_register=
0
153
1654

fint_register=
1
153
1654

fint_register=
2
153
1654

fint_register=
3
161
1734

fint_register=
4
170
1873

fint_register=2
14
8

fint_register=3
14
8

fint_register=4
14
8

C ソース [割り込み関数]
volatile int count;#pragma interrupt int_func(vect=10, fint)
void int_func(void){
count++;}

コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

fint_register=
0
18
12

fint_register=
1
18
10

Page 40 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.29-branch

別セクション、別ファイルに定義した関数への分岐幅を指定します。
-branch=16 を指定した場合、分岐幅が 16bit 以内であるとしてコンパイルします。
-branch=24 を指定した場合、分岐幅が 24bit 以内であるとしてコンパイルします。(デフォルト設定)-branch=32 を指定した場合、分岐幅を指定しません。

C ソース
void sub(void);void main(void){sub();}#pragma section ResetPRG
void sub(void){}-branch=16
コードサイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.03
6-branch=24
46-branch=32
87Page 41 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.30-base

プログラム全体で、ベースアドレスとして固定で使用する汎用レジスタを指定します。
プログラム全体で外部変数へのアクセス回数が多い場合等に、コードサイズや実行速度といったコード効率が改善する可能性があります。

C ソース
long val[40];long tmp = 10;
void main(void){
int i;for (i = 0; i < 40; ++i) {if (tmp > i) {val[i] = tmp + i;}else if (tmp > (i * 2)) {val[i] = tmp + (i * 2);}else if (tmp > (i * 3)) {val[i] = tmp + (i * 3);}else if (tmp > (i * 4)) {val[i] = tmp + (i * 4);}else if (tmp > (i * 5)) {val[i] = tmp + (i * 5);}else if (tmp > (i * 6)) {val[i] = tmp + (i * 6);}else if (tmp > (i * 7)) {val[i] = tmp + (i * 7);}else if (tmp > (i * 8)) {val[i] = tmp + (i * 8);}else if (tmp > (i * 9)) {val[i] = tmp + (i * 9);}else {
val[i] = tmp + (i * 10);}}}

コードサイズ[バイト]ROM サイズ[バイト]サイクル数[サイクル]

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション指定(-base=ram=R8)
165
4
1533

オプション未指定
166
4
1540

Page 42 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.31-nouse_pid_register

PID レジスタを使用せずにコード生成を行います。
コードサイズと実行速度が劣化する可能性があります。

C ソース
long val[40];long tmp = 10;
void main(void){
int i;for (i = 0; i < 40; ++i) {if (tmp > i) {val[i] = tmp + i;}else if (tmp > (i * 2)) {val[i] = tmp + (i * 2);}else if (tmp > (i * 3)) {val[i] = tmp + (i * 3);}else if (tmp > (i * 4)) {val[i] = tmp + (i * 4);}else if (tmp > (i * 5)) {val[i] = tmp + (i * 5);}else if (tmp > (i * 6)) {val[i] = tmp + (i * 6);}else if (tmp > (i * 7)) {val[i] = tmp + (i * 7);}else if (tmp > (i * 8)) {val[i] = tmp + (i * 8);}else if (tmp > (i * 9)) {val[i] = tmp + (i * 9);}else {
val[i] = tmp + (i * 10);}}}

コードサイズ[バイト]サイクル数[サイクル]※-fint_register=3 で測定

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション指定167
1823

オプション未指定158
1674

Page 43 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.32-save_acc

割り込み関数に対して、アキュムレータ（ACC, ACC0, ACC1）の退避・回復コードを生成します。
本オプション指定時は、割り込み時でもアキュムレータの値が保持されるため、C/C++の演算式に対して
MACLO 命令などのアキュムレータを用いる命令を生成することがあります。

C ソース [通常関数]
short src1[3] = {10, 11, 12};short src2[3] = {20, 21, 22};
int result;int func(const short* src1, const short* src2){
return (src1[0] * src2[0]) + (src1[1] * src2[1]) + (src1[2] * src2[2]);}void main(void){
result = func(src1, src2);}

コードサイズ[バイト]サイクル数[サイクル]※オプション-speed を指定

オプション指定49
25

オプション未指定49
27

C ソース [割り込み関数]#include <machine.h>long src1 = 10;
long src2 = 20;
long result;#pragma interrupt func(vect=10)void func(void){
result = src1 * src2;}
void main(void){
int_exception(10);nop();}

オプション指定53
コードサイズ[バイト]32
サイクル数[サイクル]※割り込み関数のみのサイズ・サイクル数

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション未指定31
18

Page 44 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.1.33-control_flow_integrity

間接関数呼び出しに対して、呼び出し先関数のチェックを行います。
チェックのためのコードとデータが追加されるため、コードサイズ、ROM データサイズ、実行速度が劣
化します。

C ソース
void __control_flow_chk_fail(void) {}void func1(char a) {}void func2(long b) {}void func3(void){}void (*p1)(char a) = func1;
void (*p2)(long b) = func2;
void func4(void){
func3();}
void main(void){p1(1);
p2(1);
func4();}

オプション指定
オプション未指定147
コードサイズ[バイト] 192
188
65
ROM サイズ[バイト]36
サイクル数[サイクル] 81※コードサイズおよび ROM サイズはスタートアップを含みます

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 45 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.2

アセンブル・オプション○…改善する×…劣化する

オプション

コード
サイズ

○

-goptimize

R01AN4195JJ0100
2018.03.20△…状況に依存する ―…変化しない

Rev.1.0

ROM
サイズ

○

サイクル
数

備考

○

本オプションを指定したファイル
は、リンク時にモジュール間最適化の対象になります。
リンク時の最適化については 2.3
リンク・オプション を参照ください。

Page 46 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.3

リンク・オプション

リンカの最適化オプション指定によるコードサイズ・ROM データサイズ・実行速度の影響を示します。
コンパイル、アセンブル時に-goptimize を指定したファイルに対して最適化を行います。
-section_forbid で指定したセクションの最適化を抑止することができます。
また、-absolute_forbid で指定したアドレス＋サイズの範囲の最適化を抑止することができます。

○…改善する×…劣化する△…状況に依存する ―…変化しない

コード
サイクル
ROM
備考
サイズ
サイズ
数
-optimize=symbol_delete○○－-optimize=same_code○－
×-optimize=short_format○－－-optimize=branch○－－※コマンドラインから起動した場合、デフォルトでは全ての最適化を実行します。
オプション

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 47 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.3.1-optimize=symbol_delete

1 度も参照のない変数/関数を削除します。必ずコンパイル時に#pragma entry を指定するか、リンカのentry で entry シンボルを指定してください。
-symbol_forbid で指定した変数/関数の削除を抑止することができます。

C ソース
int value1 = 0;
int value2 = 0;
void func1(void){
value1++;}
void func2(void){
value2++;}
void main(void){
func1();}

オプション指定
オプション未指定59
135
コードサイズ[バイト]5664
ROM サイズ[バイト]※コードサイズおよび ROM サイズはスタートアップを含みます

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 48 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.3.2-optimize=same_code

複数の同一命令列をサブルーチン化します。
サブルーチン化によりコードサイズは改善しますが、実行速度は劣化します。
-samesize で最適化対象となる最小コードサイズを指定できます。(デフォルトは-samesize=1E)

C ソース
volatile int value = 0;
int v1;
int v2;
int v3;int v4;int v5;void sub(void){
value += v1;
value += v2;
value += v3;
value += v4;
value += v5;}
void main(void){
value += v1;
value += v2;
value += v3;
value += v4;
value += v5;
sub();}

オプション指定116
コードサイズ[バイト]91
サイクル数[サイクル]※コードサイズはスタートアップを含みます

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション未指定253
74

Page 49 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.3.3-optimize=short_format

ディスプレースメント/イミディエートのコードサイズを短縮可能な場合、コードサイズがより小さくなる
命令に置き換えます。

C ソース
volatile int value = 0;
int v1;
int v2;
int v3;int v4;int v5;void main(void){
value += v1;
value += v2;
value += v3;
value += v4;
value += v5;}

オプション指定157
コードサイズ[バイト]※コードサイズはスタートアップを含みます

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション未指定
179

Page 50 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
2.3.4-optimize=branch

プログラムの配置情報に基づいて、分岐命令サイズを最適化します。

C ソース
extern void sub(void);void main(void){sub();
sub();
sub();
sub();
sub();}

オプション指定116
コードサイズ[バイト]※コードサイズはスタートアップを含みます

R01AN4195JJ0100
2018.03.20

Rev.1.0

オプション未指定
135

Page 51 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
3.

拡張言語

拡張言語の中で#pragma 指令によるコードサイズ・ROM データサイズ・実行速度への影響を示します。

3.1#pragma 指令○…改善する×…劣化する#pragma 指令

コード
サイズ
△

#pragma interrupt

R01AN4195JJ0100
2018.03.20△…状況に依存する ―…変化しない

Rev.1.0

ROM サイズ

－

サイクル
数
△

備考
割り込み仕様(fint など)を変更することで、割り込み関数の性能が改善する場合があります。

Page 52 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
3.1.1#pragma interrupt

割り込み関数となる関数を宣言します。割り込み仕様を変更することで、割り込み関数の速度・サイズが改善する場合があります。

割り込み仕様高速割り込み形式
fint

割り込み関数レジスタ制限指定

save

多重割り込み許可指定

enableアキュムレータ保存指定

acc

指定内容
高速割り込みに使用する関数を指定します。
割り込み関数内で使用するレジスタの本数を R1～R5、および R14～R15 の 7 本に制限します。これらの退避回
復コードを生成しない代わりに割り込み関数内で使用もしないため、劣化する場合があります。
割り込み関数の先頭で PSW の I フラグを 1 にし、多重割り込みを許可します。
アキュムレータを退避および回復する命令を生成しま
す。

C ソース
long count;long l1, l2;#pragma interrupt int_func
void int_func(void){
count = l1 * l2;}

この C ソースに対して、割り込み仕様を指定しない場合と、fint/save/enable/acc のそれぞれを指定した場
合を比較すると次の表の通りになります。
未指定
コードサイズ[バイト]サイクル数[サイクル]

31
18

save

fint
27
11

31
18

enable
33
19

acc
53
32

高速割り込み（fint）は、コンパイル・オプション-fint_register を指定することでさらなる高速化が見込まれます。-fint_register については 2.1.28 を参照ください。

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 53 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.

コーディングテクニック

本章では、ユーザプログラムのコーディング方法によりコードサイズ・ROM データサイズ・実行速度を改善する方法を説明します。

○…改善する×…劣化する△…状況に依存する ―…変化しない

項目
データの構造変数と const 型
局所変数と大域変数
ビットフィールドの割り付け
ループ制御変数関数のインタフェース
ループ回数の削減
テーブルの活用分岐
インライン展開
switch 文の代わりに if～else 文を使う
複数箇所にある外部変数アクセスをテン
ポラリ変数により 1 箇所にまとめる
条件分岐先の同一文は分岐前に移動する
複雑な if 文を論理的に等しいものに置き換える
short, char 型の変数は int 型にする
switch 文の共通な case の処理をまとめる
for ループを do while ループに置き換える
2 のべき乗の除算はシフト演算に置き換
える
2 ビット以上のビットフィールドは char型に変更する
定数参照の際には絶対値の小さい値を割り当てる

R01AN4195JJ0100
2018.03.20

Rev.1.0

コード
サイズ
○
－
○
○
×
○
×
○
－
△
△

ROM
サイズ
－
○
○
○
－
－
－
×
－
－
－

サイクル
数
○
－
○
○
○
○
○
○
○
○
×

○

－

○

○

－

○

○

－

○

○
○
○

－
－
―

○
○
○

○

－

○

○

×

○

○

－

－

備考

Page 54 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.1

データの構造体化

関連するデータを構造体で宣言すると、実行速度を向上できる場合があります。
関連するデータを同一関数の中で何度も参照している場合、構造体を用いると相対アクセスを利用したコードが生成され易くなり、コードサイズや実行速度といったコード効率の改善が期待できます。また、引数として渡す場合もコード効率が改善します。相対アクセスにはアクセス範囲に制限があるため、頻繁にアクセスするデータは構造体の先頭に集めると効果的です。
データを構造体化すると、データの表現を変更するようなチューニングが容易になります。

変更前

変更後

C ソース

C ソース

int a, b, c;

struct s{
int a;
int b;
int c;} s1;

void func(void){a = 1;
b = 2;
c = 3;}

void func(void){
struct s *p = &s1;
p->a = 1;
p->b = 2;
p->c = 3;}

アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
MOV.L #_a, R14
MOV.L #00000001H, [R14]
MOV.L #_b, R14
MOV.L #00000002H, [R14]
MOV.L #_c, R14
MOV.L #00000003H, [R14]RTS_func:.STACK_func=4
MOV.L #_s1, R1
MOV.L #00000001H, [R1]
MOV.L #00000002H, 04H[R1]
MOV.L #00000003H, 08H[R1]
RTS

コードサイズ:28 バイト
サイクル数:9 サイクル

コードサイズ:15 バイト
サイクル数:7 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 55 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.2

変数と const 型

値を変更しない変数は、const 修飾で宣言してください。
大域変数を宣言と同時に初期化するプログラムを書くと、初期値は ROM に、大域変数は RAM にそれぞれ配置されます。大域変数の初期化は、プログラムの開始時に ROM から RAM に初期値を転送することにより実現されています。初期値のある変数を const 修飾しておくと、変数を書き換えるおそれがなくなるため、コンパイラは RAM を確保しません。その結果、RAM を節約することができ、ROM から RAM への転送処理も省略することができます。
また、初期値は変更しない、というルールでプログラムを作成すると、ROM 化が容易になります。

変更前

変更後

C ソース

C ソース

char a[] ={1, 2, 3, 4, 5};const char a[] ={1, 2, 3, 4, 5};

ROM サイズ:5 バイト
RAM サイズ:5 バイト

ROM サイズ:5 バイト
RAM サイズ:0 バイト

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 56 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.3

局所変数と大域変数

一時変数、ループのカウンタなど、局所的に用いる変数は、関数の中で局所変数として宣言すると実行速度が向上します。
局所変数として使用できるものは、大域変数として宣言しないで必ず局所変数として宣言してください。
大域変数は、関数呼び出しやポインタ操作によって値が変化してしまう可能性があるため、最適化がかかりにくくなります。

変更前

変更後

C ソース

C ソース

int tmp;void func(int* a, int* b){
int tmp;
tmp = *a;*a = *b;*b = tmp;}

void func(int* a, int* b){
tmp = *a;*a = *b;*b = tmp;}
アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
MOV.L #_tmp, R14
MOV.L [R1], [R14]
MOV.L [R2], [R1]
MOV.L [R14], [R2]RTS

_func:.STACK_func=4
MOV.L [R1], R14
MOV.L [R2], [R1]
MOV.L R14, [R2]
RTS

コードサイズ:12 バイト
サイクル数:13 サイクル

コードサイズ:8 バイト
サイクル数:8 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 57 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.4

構造体宣言のメンバオフセット構造体の中でよく使用するメンバは、先頭に宣言するようにするとサイズが改善する場合があります。

変更前

変更後

C ソース

C ソース

struct str {long l1[8];char c1;};

struct str {char c1;long l1[8];};struct str str1;
char x;struct str str1;
char x;void func(void){x = str1.c1;}
アセンブリ展開コード

void func(void){x = str1.c1;}
アセンブリ展開コード_func:.STACK_func=4
MOV.L #_x, R14
MOV.L #_str1, R15
MOV.B 20H[R15], [R14]
RTS
コードサイズ:16 バイト
サイクル数:8 サイクル

_func:.STACK_func=4
MOV.L #_x, R14
MOV.L #_str1, R15
MOV.B [R15], [R14]
RTS
コードサイズ:15 バイト
サイクル数:8 サイクル

構造体を定義する際には、アライメントを意識してメンバの宣言をおこなってください。アライメントとは、変数を効率よくアクセスするために、変数の配置アドレスに制約を設けることです。
例えば、long 型のアライメント数は 4 バイトであり、long 型の変数は 4 の倍数アドレスに配置する必要があります。構造体変数では、メンバと構造体変数の両方にアライメントが設定されます。メンバのアライメ
ント数は、メンバでない変数のアライメント数と同じです。構造体変数のアライメント数は、メンバのアラ
イメント数の最大値です。構造体変数の中のメンバを隙間なく配置するとアライメントに違反してしまう場
合、隙間を作って配置アドレスを調整します。この隙間のことをパディングと言います。また、構造体変数のサイズがアライメント数の倍数でない場合もパディングが生じます。パディングが増えるとメモリの利用効率が下がってしまいます。

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 58 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
変更前

変更後

C ソース

C ソース

/* 最大メンバが long 型の為、アライメント数は 4byte */struct str {char c1;/* 1byte *//* パディング分 3byte */long l1;/* 4byte */char c2;/* 1byte */char c3;/* 1byte */char c4;/* 1byte *//* パディング分 1byte */} str1;
アセンブリ展開コード/* 最大メンバが long 型の為、アライメント数は 4byte */struct str {char c1; /* 1byte */char c2; /* 1byte */char c3; /* 1byte */char c4; /* 1byte */long l1; /* 4byte */} str1;.SECTION B,DATA,ALIGN=4_str1:.blkl 3

.SECTION B,DATA,ALIGN=4_str1:.blkl 2

R01AN4195JJ0100
2018.03.20

Rev.1.0

アセンブリ展開コード

Page 59 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.5

ビットフィールドの割り付け

ビットフィールドで、連続して値を設定されるものは、同じ構造体内に割り付けるようにしてください。
異なる構造体内にあるビットフィールドのメンバを設定するためには、構造体ごとに分けてアクセスしな
ければなりません。関連するビットフィールドを同じ構造体内にまとめて割り付けることによって、このアクセスを一度で済ませることができます。
以下は同じ構造体に関連するビットフィールドを割り付けることによってサイズが改善する例です。

変更前

変更後

C ソース

C ソース

struct str{
int flag1:1;} b1, b2, b3;

struct str{
int flag1:1;
int flag2:1;
int flag3:1;} a1;

void func(void){b1.flag1 = 1;b2.flag1 = 1;
b3.flag1 = 1;}

void func(void){a1.flag1 = 1;
a1.flag2 = 1;
a1.flag3 = 1;}

アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
MOV.L #_b1, R14
BSET #00H, [R14].B
MOV.L #_b2, R14
BSET #00H, [R14].B
MOV.L #_b3, R14
BSET #00H, [R14].B
RTS_func:.STACK_func=4
MOV.L #_a1, R14
BSET #00H, [R14].B
BSET #01H, [R14].B
BSET #02H, [R14].B
RTS

コードサイズ:25 バイト
サイクル数:13 サイクル

コードサイズ:13 バイト
サイクル数:13 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 60 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.6

ループ制御変数

ループ制御変数は符号付き 4 バイト整数型(signed int/signed long)で宣言すると、ループ内で各種最適化が適用され易くなり、コードサイズの削減、実行速度の向上が期待できます。

変更前

変更後

C ソース

C ソース

unsigned long n = 50;
signed short array[100];

unsigned long n = 50;
signed short array[100];void func(void){
signed short i;for (i = 0; i < n; i++) {array[i+5] = 0;}}

void func(void){
signed long i;for (i = 0; i < n; i++) {array[i+5] = 0;}}

アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
MOV.L #00000000H, R15
MOV.L #_n, R14
MOV.L [R14], R14
MOV.L #_array, R5
L11: ; bb7
MOV.W R15, R15
CMP R14, R15
BGEU L13
L12: ; bb
SHLL #01H, R15, R1
ADD R5, R1
ADD #01H, R15
MOV.W #0000H, 0AH[R1]
BRA L11
L13: ; return
RTS
コードサイズ:35 バイト
サイクル数:511 サイクル

_func:.STACK_func=4
MOV.L #00000000H, R5
MOV.L #_n, R15
MOV.L [R15], R15
MOV.L #_array, R14
ADD #0AH, R14
MOV.L #00000000H, R4
L11: ; bb6
CMP R15, R5
BEQ L13
L12: ; bb
MOV.W R4, [R14+]
ADD #01H, R5
BRA L11
L13: ; return
RTS

R01AN4195JJ0100
2018.03.20

Rev.1.0

コードサイズ:31 バイト
サイクル数:362 サイクル

Page 61 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.7

関数のインタフェース

関数の引数を工夫することにより RAM 容量を削減でき、実行速度も向上できます。
引数がすべてレジスタに割りつくように（4 個まで）引数の数を厳選してください。引数が多い場合は、構造体にしてポインタで渡してください。もし、構造体のポインタではなく、構造体そのものを受け渡すとレジスタに乗らない場合があります。引数がレジスタに乗れば、呼び出し、関数の出入り口の処理が簡単になります。また、スタック領域も節約できます。
関数のインタフェース仕様は、コンパイラユーザーズマニュアルに記載されています。

変更前

変更後

C ソース

C ソース

void func(char a, char b, char c,char d, char e, char f,char g, char h) {}struct str{
char a;char b;char c;char d;char e;char f;char g;char h;};void call_func(void){func(1,2,3,4,5,6,7,8);}

void func(struct str* str_arg) {}void call_func(void){
struct str arg ={1,2,3,4,5,6,7,8};
func(&arg);}
アセンブリ展開コード

アセンブリ展開コード_call_func:.STACK_call_func=8
SUB #04H, R0
MOV.L #00000004H, R4
MOV.B #05H, [R0]
MOV.L #00000003H, R3
MOV.L #00000002H, R2
MOV.B #08H, 03H[R0]
MOV.L #00000001H, R1
MOV.B #07H, 02H[R0]
MOV.B #06H, 01H[R0]
BSR _func
ADD #04H, R0
RTS_call_func:.STACK_call_func=12
SUB #08H, R0
MOV.L R0, R1
MOV.L #04030201H, [R0]
MOV.L #08070605H, 04H[R0]
BSR _func
RTSD #08H

コードサイズ:28 バイト
サイクル数:21 サイクル

コードサイズ:22 バイト
サイクル数:15 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 62 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.8

ループ回数の削減

ループを展開すると、実行速度は大幅に向上します。
ループの展開は特に内側のループが有効です。ループの展開によりプログラムサイズは増大するので、プ
ログラムサイズを犠牲にしても実行速度を向上させたい場合に適用してください。

変更前

変更後

C ソース

C ソース

int a[100];

int a[100];void func(void){
int i;for (i = 0; i < 100; i++) {a[i] = 0;}}

void func(void){
int i;for (i = 0; i < 100; i += 2) {a[i] = 0;a[i+1] = 0;}}
アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
MOV.L #00000064H, R15
MOV.L #_a, R14
MOV.L #00000000H, R5
L11: ; bb
SUB #01H, R15
MOV.L R5, [R14+]
BNE L11
L12: ; returnRTS_func:.STACK_func=4
MOV.L #00000032H, R14
MOV.L #_a, R1
L11: ; bb
MOV.L #00000000H, [R1]
MOV.L #00000000H, 04H[R1]
ADD #08H, R1
SUB #01H, R14
BNE L11
L12: ; return
RTS

コードサイズ:19 バイト
サイクル数::603 サイクル

コードサイズ:22 バイト
サイクル数:353 サイクル

なお、-loop オプションを指定すると、ループ展開最適化が行われます。使用例の改善前ソースコードにloop オプションを指定しコンパイルすると、改善後ソースコードのアセンブリ展開コードと同じアセンブリ
展開コードが出力されます。ループ内の処理を全て展開した場合は、ループの判定式も削除されます。例えばループ回数が 8 回の場合は、-loop=8 を指定するとループの判定式も削除されます。

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 63 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.9

テーブルの活用

switch 文による分岐の代わりにテーブルを用いることで実行速度を向上できます。
switch 文の各 case の処理がほぼ同じ場合は、テーブルを使用できないか検討してください。
以下の例では、変数 i の値により変数 ch に代入する文字定数を変えます。

変更前

変更後

C ソース

C ソース

char func(int i){char ch;switch (i){case 0:ch = 'a'; break;case 1:ch = 'x'; break;case 2:ch = 'b'; break;default:ch = 0; break;}return (ch);}const char chbuf[] ={'a', 'x', 'b'};

アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
CMP #00H, R1
BEQ L14
L11: ; entry
CMP #01H, R1
BEQ L15
L12: ; entry
CMP #02H, R1
BEQ L16
L13: ; switch_clause_bb5
MOV.L #00000000H, R1
RTS
L14: ; switch_break_bb
MOV.L #00000061H, R1
RTS
L15: ; switch_clause_bb3
MOV.L #00000078H, R1
RTS
L16: ; switch_clause_bb4
MOV.L #00000062H, R1
RTS_func:.STACK_func=4
CMP #02H, R1
BGTU L12
L11: ; if_then_bb
MOV.L #_chbuf, R14
MOVU.B [R14,R1], R1
RTS
L12: ; bb8
MOV.L #00000000H, R1
RTS

コードサイズ：27 バイト
サイクル数:7 サイクル

コードサイズ：17 バイト
サイクル数:5 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0char func(int i){
if ((unsigned int)i < 3) {return (chbuf[i]);}return (0);}Page 64 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.10

分岐

分岐するケースの位置を変更することで実行速度が向上します。else if 文のように上から順に比較をする
場合、場合分けが増えると末端のケースの実行速度は低下します。頻繁に分岐するケースは先頭近くに配置
してください。

変更前

変更後

C ソース

C ソース

int func(int a){
if (a == 1) {a = 2;}
else if (a == 2) {a = 4;}
else if (a == 3) {a = 8;}
else {
a = 0;}
return (a);}int func(int a){
if (a == 3) {a = 8;}
else if (a == 2) {a = 4;}
else if (a == 1) {a = 2;}
else {
a = 0;}
return (a);}アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
CMP #01H, R1
STZ #02H, R1
BEQ L13
L11: ; if_else_bb
CMP #02H, R1
STZ #04H, R1
BEQ L13
L12: ; if_else_bb9
CMP #03H, R1
SCEQ.L R1
SHLL #03H, R1
L13: ; if_break_bb17
RTS_func:.STACK_func=4
CMP #03H, R1
STZ #08H, R1
BEQ L13
L11: ; if_else_bb
CMP #02H, R1
STZ #04H, R1
BEQ L13
L12: ; if_else_bb9
CMP #01H, R1
SCEQ.L R1
SHLL #01H, R1
L13: ; if_break_bb17
RTS

サイクル数：12 サイクル
(a=3 の場合)

R01AN4195JJ0100
2018.03.20

Rev.1.0

サイクル数：7 サイクル
(a=3 の場合)

Page 65 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.11

インライン展開

頻繁に呼び出される関数をインライン展開すると実行速度を向上できます。#pragma inline でインライン展
開する関数を指定することができます。一方、インライン展開をした場合、一般的にはプログラムサイズが増大する傾向にあります。
インライン展開する関数が他のソースファイルから参照されていない場合、static 関数にしておくと関数本体のコードが削除されコードサイズが小さくなる可能性があります。

変更前

変更後

C ソース

C ソース

int x[10], y[10];int x[10], y[10];static void sub(int* a, int* b,
int i){
int temp;
temp = a[i];a[i] = b[i];b[i] = temp;}#pragma inline (sub)static void sub(int* a, int* b,
int i){
int temp;
temp = a[i];a[i] = b[i];b[i] = temp;}

void func(void){
int i;for (i = 0; i < 10; i++) {sub(x, y, i);}}

R01AN4195JJ0100
2018.03.20

Rev.1.0

void func(void){
int i;for (i = 0; i < 10; i++) {sub(x, y, i);}}Page 66 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
アセンブリ展開コード

アセンブリ展開コード__$sub:.STACK__$sub=4
MOV.L [R3,R2], R14
MOV.L [R3,R1], R15
MOV.L R14, [R3,R1]
MOV.L R15, [R3,R2]
RTS_func:.STACK_func=16
PUSHM R6-R8
MOV.L #_y, R7
MOV.L #_x, R8
MOV.L #00000000H, R6
L12: ; bb
MOV.L R8, R1
MOV.L R7, R2
MOV.L R6, R3
BSR __$sub
ADD #01H, R6
CMP #0AH, R6
BNE L12
L13: ; return
RTSD #0CH, R6-R8_func:.STACK_func=4
MOV.L #0000000AH, R5
MOV.L #_y, R14
MOV.L #_x, R15
L11: ; bb
SUB #01H, R5
MOV.L [R14], R4
MOV.L [R15], R3
MOV.L R4, [R15+]
MOV.L R3, [R14+]
BNE L11
L12: ; return
RTS

コードサイズ：47 バイト
サイクル数：189 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

コードサイズ：29 バイト
サイクル数：84 サイクル

Page 67 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.12

条件分岐先の同一文は分岐前に移動する

条件分岐の各々の分岐先に同一の文がある場合、条件分岐の前に移動して 1 箇所にまとめてください。

変更前

変更後

C ソース

C ソース

int s;

int s;

int func(int a, int b, int c){
return (a + b + c);}

int func(int a, int b, int c){
return (a + b + c);}

int call_func(int x){
if (x >= 0) {if (x > func(0, 1, 2)) {s++;}}else {
if (x < -func(0, 1, 2)) {s--;}}return (0);}int call_func(int x){
int tmp = func(0, 1, 2);
if (x >= 0) {if (x > tmp) {s++;}}else {
if (x < -tmp) {s--;}}return 0;}

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 68 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
アセンブリ展開コード

アセンブリ展開コード_call_func:.STACK_call_func=12
PUSHM R6-R7
ADD #00H, R1, R6
BN L17
L12: ; if_then_bb
MOV.L #00000002H, R3
MOV.L #00000001H, R2
MOV.L #00000000H, R1
BSR _func
CMP R6, R1
MOV.L #_s, R7
BGE L14
L13: ; if_then_bb9
MOV.L [R7], R14
MOV.L #00000000H, R1
ADD #01H, R14
MOV.L R14, [R7]
BRA L16
L14: ; if_else_bb
MOV.L #00000002H, R3
MOV.L #00000001H, R2
MOV.L #00000000H, R1
BSR _func
NEG R1CMP R1, R6
BGE L17
L15: ; if_then_bb18
MOV.L [R7], R14
MOV.L #00000000H, R1
SUB #01H, R14
MOV.L R14, [R7]
L16: ; if_then_bb18
BRA L18
L17: ; if_break_bb22
MOV.L #00000000H, R1
L18: ; if_break_bb22
RTSD #08H, R6-R7_call_func:.STACK_call_func=8
PUSH.L R6
MOV.L R1, R6
MOV.L #00000002H, R3
MOV.L #00000001H, R2
MOV.L #00000000H, R1
BSR _func
CMP #00H, R6
BN L17
L12: ; if_then_bb
CMP R6, R1
MOV.L #_s, R14
BGE L14
L13: ; if_then_bb12
MOV.L #00000000H, R1
MOV.L [R14], R15
ADD #01H, R15
MOV.L R15, [R14]
BRA L16
L14: ; if_else_bb
NEG R1CMP R1, R6
BGE L17
L15: ; if_then_bb21
MOV.L #00000000H, R1
MOV.L [R14], R15
SUB #01H, R15
MOV.L R15, [R14]
L16: ; if_then_bb21
BRA L18
L17: ; if_break_bb25
MOV.L #00000000H, R1
L18: ; if_break_bb25
RTSD #04H, R6-R6

コードサイズ：65 バイト
サイクル数：42 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

コードサイズ：57 バイト
サイクル数：30 サイクル

Page 69 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.13

複雑な if 文を論理的に等しいものに置き換える

if 文の条件式が複雑である場合、等しい意味の簡単な式に置き換えてください。

変更前

変更後

C ソース

C ソース

int x;

int x;

int func(int s, int t){
s &= 1;t &= 1;
if (!s) {if (t) {x = 1;}}
else {
if (!t) {x = 1;}}
return (0);}int func(int s, int t){
s &= 1;t &= 1;
if (! (s ^ t)) {x = 1;}
return (0);}アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
AND #01H, R2
BTST #00H, R1
MOV.L #_x, R14
BNE L12
L11: ; if_then_bb
CMP #00H, R2
BNE L13
BRA L14
L12: ; if_else_bb
CMP #00H, R2
BNE L14
L13: ; if_then_bb28
MOV.L #00000001H, [R14]
L14: ; if_break_bb30
MOV.L #00000000H, R1
RTS_func:.STACK_func=4
XOR R1, R2
BTST #00H, R2
BNE L12
L11: ; if_then_bb
MOV.L #_x, R14
MOV.L #00000001H, [R14]
L12: ; if_break_bb
MOV.L #00000000H, R1
RTS

コードサイズ：24 バイト
サイクル数：12 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

コードサイズ：18 バイト
サイクル数：8 サイクル

Page 70 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.14

short, char 型の変数は int 型にする

CC-RX は ANSI-C の仕様により、short、char 型の演算を演算前に int 型に型変換してから演算するコードを生成します。また int 型の値を short、char 型の変数に代入するときにも型変換が発生します。あらかじめ
int 型で変数定義しておくことで余分な型変換処理を削減できます。
注意：int 型に変更することで、変数や演算結果がとり得る値の範囲が変わります。型を変更する場合はプ
ログラムの動作に影響が無いように注意してください。

変更前

変更後

C ソース

C ソース

char func(char a, char b, char c){char t = a + b;
return (t >> c);}

int func(int a, int b, int c){
int t = a + b;
return (t >> c);}

アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
ADD R1, R2
MOVU.B R2, R14
SHLR R3, R14
MOVU.B R14, R1
RTS
コードサイズ：10 バイト
サイクル数：7 サイクル

_func:.STACK_func=4
ADD R1, R2
MOV.L R2, R1
SHAR R3, R1
RTS

R01AN4195JJ0100
2018.03.20

Rev.1.0

コードサイズ：8 バイト
サイクル数：6 サイクル

Page 71 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.15

switch 文の共通な case の処理をまとめる

複数の case ラベルの分岐先の処理が同一である場合、case ラベルを移動して処理を 1 箇所にまとめてく
ださい。

変更前

変更後

C ソース

C ソース

int x;

int x;

void func(void){switch(x) {case 0:dummy1();break;
case 1:dummy1();break;
case 2:dummy1();break;
case 3:dummy2();
break;
case 4:dummy2();
break;
default:
break;}}

void func(void){switch(x) {case 0:case 1:case 2:dummy1();break;
case 3:case 4:dummy2();
break;
default:
break;}}

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 72 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
MOV.L #_x, R14
MOV.L [R14], R14
CMP #00H, R14
BEQ L18
L13: ; entry
CMP #01H, R14
BEQ L18
L14: ; entry
CMP #02H, R14
BEQ L18
L15: ; entry
CMP #03H, R14
BEQ L19
L16: ; entry
CMP #04H, R14
BEQ L19
L17: ; return
RTS
L18: ; switch_clause_bb2
BRA _dummy1
L19: ; switch_clause_bb4
BRA _dummy2_func:.STACK_func=4
MOV.L #_x, R14
MOV.L [R14], R14
CMP #03H, R14
BLTU L15
L13: ; entry
SUB #03H, R14
CMP #02H, R14
BLTU L16
L14: ; return
RTS
L15: ; switch_clause_bb
BRA _dummy1
L16: ; switch_clause_bb1
BRA _dummy2

コードサイズ：30 バイト
サイクル数：20 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

コードサイズ：23 バイト
サイクル数：15 サイクル

Page 73 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.16

for ループを do while ループに置き換える

1 回以上ループを実行することが分かっている for 文の場合、do while 文に置き換えることでコードサイズが小さくなる可能性があります。また、条件式を等価比較に置き換えることでもコードサイズが小さくなる可能性があります。

変更前

変更後

C ソース

C ソース

int array[10][10];int array[10][10];void func(int nsize, int msize){
int i;
int *p;int s;
p = &array[0][0];s = nsize * msize;for (i = 0; i < s; i++) {*p++ = 0;}}

void func(int nsize, int msize){
int i;
int *p;int s;
p = &array[0][0];s = nsize * msize;
i = 0;
do {*p++ = 0;i++;} while (i != s);}アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
MUL R1, R2
MOV.L #_array, R15
MOV.L #00000000H, R14
MOV.L #00000000H, R5
L11: ; bb13
CMP R2, R14
BGE L13
L12: ; bb
MOV.L R5, [R15+]
ADD #01H, R14
BRA L11
L13: ; returnRTS_func:.STACK_func=4
MUL R1, R2
MOV.L #_array, R15
MOV.L #00000000H, R14
MOV.L #00000000H, R5
L11: ; bb
ADD #01H, R14
CMP R2, R14
MOV.L R5, [R15+]
BLT L11
L12: ; return
RTS

コードサイズ：24 バイト
サイクル数：458 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

コードサイズ：18 バイト
サイクル数：324 サイクル

Page 74 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.17

2 のべき乗の除算はシフト演算に置き換える

除算の除数が 2 のべき乗であり、被除数が正の値と分かっている場合は、除算をシフト演算に置き換えて
ください。

変更前

変更後

C ソース

C ソース

int s;

int s;

void func(void){s = s / 2;}void func(void){s = s >> 1;}

アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
MOV.L #_s, R14
MOV.L [R14], R15
DIV #02H, R15
MOV.L R15, [R14]RTS_func:.STACK_func=4
MOV.L #_s, R14
MOV.L [R14], R15
SHAR #01H, R15
MOV.L R15, [R14]
RTS

コードサイズ：15 バイト
サイクル数：10 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

コードサイズ：11 バイト
サイクル数：8 サイクル

Page 75 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.18

2 ビット以上のビットフィールドは char 型に変更する

ビットフィールドのメンバのサイズが 2 ビット以上の場合は、ビットフィールドは使用せずに char 型に変更してください。ただし、ROM データサイズは増加します。

変更前

変更後

C ソース

C ソース

struct {unsigned char b0:1;
unsigned char b1:2;} dw;

struct {unsigned char b0:1;
unsigned char b1;} db;

unsigned char dummy;

unsigned char dummy;

int func(void){if (dw.b1) {dummy++;}
return (0);}int func(void){if (db.b1) {dummy++;}
return (0);}アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
MOV.L #00000006H, R15
MOV.L #_dw, R14
TST [R14].UB, R15
BNE L12
L11: ; if_break_bb
MOV.L #00000000H, R1
RTS
L12: ; if_then_bb
MOV.L #00000000H, R1
MOV.L #_dummy, R14
MOVU.B [R14], R15
ADD #01H, R15
MOV.B R15, [R14]RTS_func:.STACK_func=4
MOV.L #_db, R1
MOVU.B 01H[R1], R1
CMP #00H, R1
BNE L12
L11: ; if_break_bb
MOV.L #00000000H, R1
RTS
L12: ; if_then_bb
MOV.L #00000000H, R1
MOV.L #_dummy, R14
MOVU.B [R14], R15
ADD #01H, R15
MOV.B R15, [R14]
RTS

コードサイズ：30 バイト
ROM サイズ：1 バイト
サイクル数：10 サイクル

R01AN4195JJ0100
2018.03.20

Rev.1.0

コードサイズ：29 バイト
ROM サイズ：2 バイト
サイクル数：9 サイクル

Page 76 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編
4.19

定数参照の際には絶対値の小さい値を割り当てる

定数参照は絶対値が小さい値の方がコードサイズは小さくなる可能性があります。ID の割り当てなどで定数値を使用する際には、小さい値を割り当てるようにしてください。

変更前
C ソース

変更後
C ソース

#define ID_1

(1000)#define ID_1

(1)

int id;void func(void){
id = ID_1;}

int id;void func(void){
id = ID_1;}

アセンブリ展開コード

アセンブリ展開コード_func:.STACK_func=4
MOV.L #_id, R14
MOV.L #000003E8H, [R14]RTS_func:.STACK_func=4
MOV.L #_id, R14
MOV.L #00000001H, [R14]
RTS

コードサイズ：11 バイト

R01AN4195JJ0100
2018.03.20

Rev.1.0

コードサイズ：10 バイト

Page 77 of 78

RX ファミリ用 C/C++コンパイラパッケージ(CC-RX) プログラミング・テクニック編

ホームページとサポート窓口
ルネサス エレクトロニクスホームページ
https://www.renesas.com/
お問合せ先
https://www.renesas.com/contact/

すべての商標および登録商標は，それぞれの所有者に帰属します。

R01AN4195JJ0100
2018.03.20

Rev.1.0

Page 78 of 78

改訂記録
Rev.
1.00

発行日
2018.3.20

改訂内容
ポイント

ページ
新規発行

ご注意書き1. 本資料に記載された回路、ソフトウェアおよびこれらに関連する情報は、半導体製品の動作例、応用例を説明するものです。お客様の機器・システムの設計において、回路、ソフトウェアおよびこれらに関連する情報を使用する場合には、お客様の責任において行ってください。これらの使用に起因して生じた損害（お客様または第三者いずれに生じた損害も含みます。以下同じです。）に関し、当社は、一切その責任を負いません。
2. 当社製品、本資料に記載された製品デ－タ、図、表、プログラム、アルゴリズム、応用回路例等の情報の使用に起因して発生した第三者の特許権、著作権その他の知的財産権に対する侵害またはこれらに関する紛争について、当社は、何らの保証を行うものではなく、また責任を負うものではありません。
3. 当社は、本資料に基づき当社または第三者の特許権、著作権その他の知的財産権を何ら許諾するものではありません。
4. 当社製品を、全部または一部を問わず、改造、改変、複製、リバースエンジニアリング、その他、不適切に使用しないでください。かかる改造、改変、複製、リバースエンジニアリング等により生じた損害に関し、当社は、一切その責任を負いません。
5. 当社は、当社製品の品質水準を「標準水準」および「高品質水準」に分類しており、各品質水準は、以下に示す用途に製品が使用されることを意図しております。
標準水準：

コンピュータ、OA機器、通信機器、計測機器、AV機器、家電、工作機械、パーソナル機器、産業用ロボット等

高品質水準： 輸送機器（自動車、電車、船舶等）、交通制御（信号）、大規模通信機器、金融端末基幹システム、各種安全制御装置等
当社製品は、データシート等により高信頼性、Harsh environment向け製品と定義しているものを除き、直接生命・身体に危害を及ぼす可能性のある機器・システ
ム（生命維持装置、人体に埋め込み使用するもの等）、もしくは多大な物的損害を発生させるおそれのある機器・システム（宇宙機器と、海底中継器、原子力制御システム、航空機制御システム、プラント基幹システム、軍事機器等）に使用されることを意図しておらず、これらの用途に使用することは想定していません。たとえ、当社が想定していない用途に当社製品を使用したことにより損害が生じても、当社は一切その責任を負いません。
6. 当社製品をご使用の際は、最新の製品情報（データシート、ユーザーズマニュアル、アプリケーションノート、信頼性ハンドブックに記載の「半導体デバイスの使用上の一般的な注意事項」等）をご確認の上、当社が指定する最大定格、動作電源電圧範囲、放熱特性、実装条件その他指定条件の範囲内でご使用ください。指定条件の範囲を超えて当社製品をご使用された場合の故障、誤動作の不具合および事故につきましては、当社は、一切その責任を負いません。
7. 当社は、当社製品の品質および信頼性の向上に努めていますが、半導体製品はある確率で故障が発生したり、使用条件によっては誤動作したりする場合があります。また、当社製品は、データシート等において高信頼性、Harsh environment向け製品と定義しているものを除き、耐放射線設計を行っておりません。仮に当社製品の故障または誤動作が生じた場合であっても、人身事故、火災事故その他社会的損害等を生じさせないよう、お客様の責任において、冗長設計、延焼対策設
計、誤動作防止設計等の安全設計およびエージング処理等、お客様の機器・システムとしての出荷保証を行ってください。特に、マイコンソフトウェアは、単独での検証は困難なため、お客様の機器・システムとしての安全検証をお客様の責任で行ってください。
8. 当社製品の環境適合性等の詳細につきましては、製品個別に必ず当社営業窓口までお問合せください。ご使用に際しては、特定の物質の含有・使用を規制するRoHS
指令等、適用される環境関連法令を十分調査のうえ、かかる法令に適合するようご使用ください。かかる法令を遵守しないことにより生じた損害に関して、当社は、一切その責任を負いません。
9. 当社製品および技術を国内外の法令および規則により製造・使用・販売を禁止されている機器・システムに使用することはできません。当社製品および技術を輸
出、販売または移転等する場合は、「外国為替及び外国貿易法」その他日本国および適用される外国の輸出管理関連法規を遵守し、それらの定めるところに従い必要な手続きを行ってください。
10. お客様が当社製品を第三者に転売等される場合には、事前に当該第三者に対して、本ご注意書き記載の諸条件を通知する責任を負うものといたします。
11. 本資料の全部または一部を当社の文書による事前の承諾を得ることなく転載または複製することを禁じます。
12. 本資料に記載されている内容または当社製品についてご不明な点がございましたら、当社の営業担当者までお問合せください。
注1. 本資料において使用されている「当社」とは、ルネサス エレクトロニクス株式会社およびルネサス エレクトロニクス株式会社が直接的、間接的に支配する会
社をいいます。
注2. 本資料において使用されている「当社製品」とは、注1において定義された当社の開発、製造製品をいいます。

(Rev.4.0-1 2017.11)

http://www.renesas.com■営業お問合せ窓口※営業お問合せ窓口の住所は変更になることがあります。最新情報につきましては、弊社ホームページをご覧ください。

ルネサス エレクトロニクス株式会社 〒135-0061 東京都江東区豊洲3-2-24（豊洲フォレシア）■技術的なお問合せおよび資料のご請求は下記へどうぞ。
総合お問合せ窓口：https://www.renesas.com/contact/© 2018 Renesas Electronics Corporation. All rights reserved.
Colophon 6.0