■ポイント
レジスタの退避/回復方法を工夫することにより実行速度が向上できます。
■説明
末端の関数の出入口で行われるレジスタ変数用レジスタの退避/回復を削除することで実行速 度及びROM効率の向上が図れます。ただし、以下のいずれかの処理が必要となり逆効果になる 場合があるので、適用する箇所は良く検討してください。
(1) レジスタの退避/回復を削除した関数の呼び出し元の関数でレジスタ変数用レジスタの 退避/回復をする。
(2)関数呼び出しを越えてレジスタ変数用レジスタを割り付けないオブジェクトにする。
■使用例
スタックの退避/回復を関数tableで一括して行わせます。
改善前ソースコード typedef
int ARRAY[LISTMAX][LISTMAX][LISTMAX];
ARRAY ary1, ary2, ary3;
void table (void) {
init(74755, ary1);
copy(ary1, ary2);
sum(ary1, ary2, ary3);
}
void init (int seed, ARRAY p) {
int i, j, k;
for ( i = 0; i < LISTMAX; i++ ) for ( j = 0; j < LISTMAX; j++ ) for ( k = 0; k < LISTMAX; k++ ){
seed = ( seed * 1309 ) & 16383;
p[i][j][k] = seed;
} }
void copy (ARRAY p, ARRAY q) {
int i, j, k;
for ( i = 0; i < LISTMAX; i++ ) for ( j = 0; j < LISTMAX; j++ ) for ( k = 0; k < LISTMAX; k++ ) q[k][i][j] = p[i][j][k];
}
void sum (ARRAY p, ARRAY q, ARRAY r)
改善後ソースコード
#pragma regsave (table)
#pragma noregalloc (table)
#pragma noregsave (init, copy, sum) typedef
int ARRAY[LISTMAX][LISTMAX][LISTMAX];
ARRAY ary1, ary2, ary3;
void table (void) {
init(74755, ary1);
copy(ary1, ary2);
sum(ary1, ary2, ary3);
}
void init (int seed, ARRAY p) {
int i, j, k;
for ( i = 0; i < LISTMAX; i++ ) for ( j = 0; j < LISTMAX; j++ ) for ( k = 0; k < LISTMAX; k++ ){
seed = ( seed * 1309 ) & 16383;
p[i][j][k] = seed;
} }
void copy (ARRAY p, ARRAY q) {
int i, j, k;
for ( i = 0; i < LISTMAX; i++ ) for ( j = 0; j < LISTMAX; j++ ) for ( k = 0; k < LISTMAX; k++ ) q[k][i][j] = p[i][j][k];
改善前アセンブリ展開コード _table:
MOV. R14,@-R15 STS.L PR,@-R15 MOV.L L250+6,R14 MOV.L L250+10,R4 BSR _init MOV R14,R5 MOV.L L250+14,R5 BSR _copy MOV R14,R4 MOV R14,R4 LDS.L @R15+,PR MOV.L L250+18,R6 MOV.L L250+14,R5 BRA _sum
MOV.L @R15+,R14 _init:
MOV #0,R7 MOV.L R12,@-R15 MOV #2,R6 MOV.L R11,@-R15 MOV #0,R11 MOV.L R10,@-R15 ADD R5,R11 MOV.L R9,@-R15 MOV.L R8,@-R15 STS.L MACL,@-R15 MOV R7,R8 MOV.W L250,R9 MOV.W L250+2,R10 L241:
MOV R7,R12 MOV #0,R1 ADD R11,R1 L242:
MOV R7,R0 MOV #0,R5 ADD R1,R5 L243:
MUL.L R9,R4 ADD #1,R0 STS MACL,R3 MOV R3,R4 AND R10,R4 CMP/GE R6,R0 MOV.L R4,@R5 BF/S L243 ADD #4,R5 ADD #1,R12 CMP/GE R6,R12 BF/S L242 ADD #8,R1 ADD #1,R8 CMP/GE R6,R8 BF/S L241 ADD #16,R11 LDS.L @R15+,MACL
r[i][j][k] = p[i][j][k] + q[i][j][j];
}
改善後アセンブリ展開コード _table:
MOV.L R14,@-R15 MOV.L R13,@-R15 MOV.L R12,@-R15 MOV.L R11,@-R15 MOV.L R10,@-R15 MOV.L R9,@-R15 MOV.L R8,@-R15 STS.L PR,@-R15 STS.L MACH,@-R15 STS.L MACL,@-R15 MOV.L L250+6,R5 MOV.L L250+10,R4 BSR _init NOP
MOV.L L250+14,R5 MOV.L L250+6,R4 BSR _copy NOP
MOV.L L250+18,R6 MOV.L L250+14,R5 MOV.L L250+6,R4 BSR _sum NOP
LDS.L @R15+,MACL LDS.L @R15+,MACH LDS.L @R15+,PR MOV.L @R15+,R8 MOV.L @R15+,R9 MOV.L @R15+,R10 MOV.L @R15+,R11 MOV.L @R15+,R12 MOV.L @R15+,R13 RTS
MOV.L @R15+,R14 _init:
MOV.W L250,R9 MOV #2,R6 MOV.W L250+2,R10 MOV #0,R11 MOV #0,R7 MOV R7,R8 ADD R5,R11 L241:
MOV R7,R12 MOV #0,R1 ADD R11,R1 L242:
MOV R7,R0 MOV #0,R5 ADD R1,R5 L243:
ADD #1,R0 MUL.L R9,R4 CMP/GE R6,R0 STS MACL,R3 MOV R3,R4
MOV.L @R15+,R8 MOV.L @R15+,R9 MOV.L @R15+,R10 MOV.L @R15+,R11 RTS
MOV.L @R15+,R12 _copy:
MOV.L R14,@-R15 MOV #2,R7 MOV.L R13,@-R15 MOV.L R12,@-R15 MOV.L R11,@-R15 MOV #0,R12 MOV.L R10,@-R15 MOV R12,R11 MOV.L R8,@-R15 ADD #-4,R15 L244:
MOV R12,R14 MOV R11,R8 SHLL2 R8 SHLL R8 MOV R11,R3 SHLL2 R3 SHLL2 R3 ADD R4,R3 MOV.L R3,@R15 L245:
MOV R12,R13 MOV.L @R15,R3 MOV #0,R6 MOV R14,R10 SHLL2 R10 SHLL R10 ADD R3,R10 ADD R5,R6 MOV R14,R1 SHLL2 R1
L246:
MOV R6,R0 MOV.L @R10+,R3 ADD #1,R13 ADD R8,R0 CMP/GE R7,R13 MOV.L R3,@(R0,R1) BF/S L246
ADD #16,R6 ADD #1,R14 CMP/GE R7,R14 BF L245 ADD #1,R11 CMP/GE R7,R11 BF L244 ADD #4,R15 MOV.L @R15+,R8
AND R10,R4 MOV.L R4,@R5 BF/S L243 ADD #4,R5 ADD #1,R12 CMP/GE R6,R12 BF/S L242 ADD #8,R1 ADD #1,R8 CMP/GE R6,R8 BF/S L241 ADD #16,R11 RTS
NOP _copy:
ADD #-4,R15 MOV #0,R12 MOV #2,R7 MOV R12,R11 L244:
MOV R12,R14 MOV R11,R8 SHLL2 R8 SHLL R8 MOV R11,R3 SHLL2 R3 SHLL2 R3 ADD R4,R3 MOV.L R3,@R15 L245:
MOV R12,R13 MOV.L @R15,R3 MOV #0,R6 MOV R14,R10 SHLL2 R10 SHLL R10 ADD R3,R10 ADD R5,R6 MOV R14,R1 SHLL2 R1
L246:
MOV R6,R0 MOV.L @R10+,R3 ADD #1,R13 ADD R8,R0 CMP/GE R7,R13 MOV.L R3,@(R0,R1) BF/S L246
ADD #16,R6 ADD #1,R14 CMP/GE R7,R14 BF L245 ADD #1,R11 CMP/GE R7,R11 BF L244
.DATA.W H'3FFF .RES.W 1 .DATA.L _ary1 .DATA.L H'00012403 .DATA.L _ary2 .DATA.L _ary3 _sum:
MOV.L R14,@-R15 MOV.L R13,@-R15 MOV.L R12,@-R15 MOV #0,R12 MOV.L R11,@-R15 MOV #2,R11 MOV.L R10,@-R15 MOV.L R9,@-R15 MOV.L R8,@-R15 ADD #-4,R15 MOV R12,R8 L247:
MOV R12,R10 MOV R8,R13 SHLL2 R13 SHLL2 R13 L248:
MOV R12,R9 MOV R12,R7 MOV R10,R14 SHLL2 R14 SHLL R14 MOV R10,R3 SHLL2 R3 MOV.L R3,@R15 L249:
MOV R13,R0 ADD R6,R0 ADD R14,R0 ADD R7,R0 MOV R13,R3 MOV.L R0,@-R15 MOV R13,R2 MOV.L @(4,R15),R0 ADD #1,R9 ADD R5,R3 ADD R14,R3 MOV.L @(R0,R3),R3 ADD R4,R2 ADD R14,R2 ADD R7,R2 MOV.L @R2,R1 CMP/GE R11,R9 MOV.L @R15+,R2 ADD R1,R3 MOV.L R3,@R2 BF/S L249 ADD #4,R7 ADD #1,R10 CMP/GE R11,R10 BF L248 ADD #1,R8 CMP/GE R11,R8 BF L247 ADD #4,R15 MOV.L @R15+,R8
MOV R12,R10 MOV R8,R13 SHLL2 R13 SHLL2 R13
L248:
MOV R12,R9 MOV R12,R7 MOV R10,R14 SHLL2 R14 SHLL R14 MOV R10,R3 SHLL2 R3 MOV.L R3,@R15 L249:
MOV R13,R0 ADD R6,R0 ADD R14,R0 ADD R7,R0 MOV R13,R3 MOV.L R0,@-R15 MOV R13,R2 MOV.L @(4,R15),R0 ADD #1,R9 ADD R5,R3 ADD R14,R3 MOV.L @(R0,R3),R3 ADD R4,R2 ADD R14,R2 ADD R7,R2 MOV.L @R2,R1 CMP/GE R11,R9 MOV.L @R15+,R2 ADD R1,R3 MOV.L R3,@R2 BF/S L249 ADD #4,R7 ADD #1,R10 CMP/GE R11,R10 BF L248 ADD #1,R8 CMP/GE R11,R8 BF L247 RTS
ADD #4,R15 L250:
.DATA.W H'051D .DATA.W H'3FFF .RES.W 1 .DATA.L _ary1 .DATA.L H'00012403 .DATA.L _ary2 .DATA.L _ary3
MOV.L @R15+,R9 MOV.L @R15+,R10 MOV.L @R15+,R11 MOV.L @R15+,R12 MOV.L @R15+,R13 RTS
MOV.L @R15+,R14
■改善前後のコードサイズと実行速度
改善前 改善後
コードサイズ 360byte 324byte
実行速度 656cycle 641cycle
3.8 2 バイトアドレスの指定
■ポイント
変数及び関数のアドレスを2バイトで表現することによりROM効率の向上ができます。
■説明
変数または関数が2バイトで表現できるアドレスに配置されている場合、参照する側のコード を2バイトにすることによりコードサイズを縮小できます。
■使用例
変数xの値が1のとき、外部関数gを呼び出します。
改善前ソースコード extern int x;
extern void g(void);
void f (void) {
if (x == 1) g();
}
改善前アセンブリ展開コード _f:
MOV.L L218+2,R3 MOV.L @R3,R0 CMP/EQ #1,R0 BF L219
MOV.L L218+6,R2 JMP @R2
NOP
L219:
RTS NOP
L218:
.RES.W 1 .DATA.L _x .DATA.L _g
改善後ソースコード
#pragma abs16(x,g) extern int x;
extern void g(void);
void f (void) {
if (x == 1) g();
}
改善後アセンブリ展開コード _f:
MOV.W L218,R3 MOV.L @R3,R0 CMP/EQ #1,R0 BF L219
MOV.W L218+2,R2 JMP @R2
NOP
L219:
RTS NOP
L218:
.DATA.W _x .DATA.W _g
■改善前後のコードサイズと実行速度
改善前 改善後
コードサイズ 28byte 22byte
実行速度 20cycle 20cycle
【注】(1) x=1,関数gがvoid g( ){ }のとき (2) SH-3にて測定