a21_txt02_11a
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2021.05.13)
** (1) HL-21a
-HL-21まででは、整数の定数があってもそれはすべて変数扱い...
-[1]optimizerX64()関数を以下のものと差し替え
unsigned char *icq0, *icq1, *icqSet;
int isConst(int i)
{
if ('0' <= ts[i][0] && ts[i][0] <= '9') return 1;
return 0;
}
int isConstM(unsigned char *p)
{
if ((*p & 0xc7) != 0x85) return 0;
return isConst(get32(p + 1) / 8);
}
AInt getConstM(unsigned char *p)
{
return var[get32(p + 1) / 8];
}
int is32bit(AInt i)
{
if (-0x80000000LL <= i && i <= 0x7fffffffLL) return 1;
return 0;
}
void putIcX64(String s, IntP p0, IntP p1, IntP p2, IntP ...
void optimizerX64()
{
if (icq0 != icq) {
if (icq0[0] == 0x0f && 0x90 <= icq0[1] && icq0[1...
icqSet = icq0;
}
+ if (icq0[0] == 0x48 && icq0[1] == 0x8b && isCons...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (i == 0) { putIcX64("31_%0c", ...
+ else if (i >> 32 == 0) { putIcX64("%0c_%1i",...
+ else if (is32bit(i)) { putIcX64("48_c7_%0c...
+ else { putIcX64("48_%0c_%1...
+ }
+ if (icq0[0] == 0x4c && icq0[1] == 0x8b && isCons...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (i == 0) { putIcX64("4d_31_%0c...
+ else if (i >> 32 == 0) { putIcX64("41_%0c_%1...
+ else if (is32bit(i)) { putIcX64("49_c7_%0c...
+ else { putIcX64("49_%0c_%1...
+ }
+ if (icq0[0] == 0x48 && icq0[1] <= 0x3f && (icq0[...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
+ else { putIcX64("48_...
+ }
+ if (icq0[0] == 0x4c && icq0[1] <= 0x3f && (icq0[...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("49_...
+ else { putIcX64("49_...
+ }
+ if (icq0[0] == 0x48 && icq0[1] == 0x0f && icq0[2...
+ AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
+ else { putIcX64("48_...
+ }
+ if (icq0[0] == 0x4c && icq0[1] == 0x0f && icq0[2...
+ AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("4d_...
+ else { putIcX64("4d_...
+ }
+ if ((icq0[0] == 0x48 || icq0[0] == 0x49) && icq0...
+ icq = icq0;
+ putIcX64("%0c_ff_%1c", (IntP) (AInt) icq0[0]...
+ }
+ if ((icq0[0] == 0x48 || icq0[0] == 0x49) && icq0...
+ icq = icq0;
+ putIcX64("%0c_ff_%1c", (IntP) (AInt) icq0[0]...
+ }
+ if (icq0[0] == 0x48 && icq0[1] == 0x83 && (icq0[...
+ icq = icq0;
+ putIcX64("48_85_%0c", (IntP) (AInt) ((icq0[2...
+ }
+ if (icq0[0] == 0x49 && icq0[1] == 0x83 && (icq0[...
+ icq = icq0;
+ putIcX64("4d_85_%0c", (IntP) (AInt) ((icq0[2...
+ }
if (icq1 != 0 && memcmp(icq0, "\x48\x8b\x85", 3)...
icq = icq0; // 8b命令は削除.
i = get32(icq1 + 3) / 8;
if (TcTmp0 <= i && i <= TcTmp9) {
icq = icq1; // 89命令も削除.
}
}
icq1 = icq0;
icq0 = icq;
}
if (icqSet + 15 == icq && memcmp(&icqSet[2], "\xc0\x...
memcpy(&icqSet[2], &icqSet[11], 4);
icqSet[1] -= 0x10; // SETcc → Jcc.
if (icqSet[10] == 0x84) {
icqSet[1] ^= 1; // 条件反転.
}
icq0 = icq = icqSet + 6;
icq1 = icqSet = 0;
jmps[jp - 1] = icq - 4 - ic;
}
}
----
-以上すべての改造を終えると、プログラムは1151行になります。
** (2) プログラムの説明#1
-isConst()関数
int isConst(int i)
{
if ('0' <= ts[i][0] && ts[i][0] <= '9') return 1;
return 0;
}
--これは、トークンコード(トークン番号)を渡すと、それが...
-isConstM()関数
int isConstM(unsigned char *p)
{
if ((*p & 0xc7) != 0x85) return 0;
return isConst(get32(p + 1) / 8);
}
--これは%mの部分のポインタを渡すと、その引数が定数を指し...
-getConstM()関数
int getConstM(unsigned char *p)
{
return var[get32(p + 1) / 8];
}
--定数だった場合に、その定数値を受け取ります。
-is32bit()関数
int is32bit(AInt i)
{
if (-0x80000000LL <= i && i <= 0x7fffffffLL) return 1;
return 0;
}
--与えられた値が、32bitで表現可能な場合に1を返します。
----
-optimizerX64()関数の中(8b用)
+ if (icq0[0] == 0x48 && icq0[1] == 0x8b && isCons...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (i == 0) { putIcX64("31_%0c", ...
+ else if (i >> 32 == 0) { putIcX64("%0c_%1i",...
+ else if (is32bit(i)) { putIcX64("48_c7_%0c...
+ else { putIcX64("48_%0c_%1...
+ }
+ if (icq0[0] == 0x4c && icq0[1] == 0x8b && isCons...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (i == 0) { putIcX64("4d_31_%0c...
+ else if (i >> 32 == 0) { putIcX64("41_%0c_%1...
+ else if (is32bit(i)) { putIcX64("49_c7_%0c...
+ else { putIcX64("49_%0c_%1...
+ }
--これは例えば「a = 0;」をHL-21でコンパイルすると「48_8b_...
--[最適化対象例] 48_8b_85_18_00_00_00
--[最適化結果例#1] 31_c0 (定数=0の場合)
--[最適化結果例#2] b8_??_??_??_?? (それ以外の場合)
-optimizerX86()関数の中(03~3b用)
+ if (icq0[0] == 0x48 && icq0[1] <= 0x3f && (icq0[...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
+ else { putIcX64("48_...
+ }
+ if (icq0[0] == 0x4c && icq0[1] <= 0x3f && (icq0[...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("49_...
+ else { putIcX64("49_...
+ }
--これは例えば「a = b + 2;」をHL-21でコンパイルすると「48...
--[最適化対象例] 48_03_85_28_00_00_00
--[最適化結果例#1] 48_83_c0_?? (定数=-128~+127の場合)
--[最適化結果例#2] 48_81_c0_??_??_??_?? (それ以外の場合)
-optimizerX86()関数の中(0f_af用)
+ if (icq0[0] == 0x48 && icq0[1] == 0x0f && icq0[2...
+ AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
+ else { putIcX64("48_...
+ }
+ if (icq0[0] == 0x4c && icq0[1] == 0x0f && icq0[2...
+ AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("4d_...
+ else { putIcX64("4d_...
+ }
--これは例えば「a = b * 12;」をHL-21でコンパイルすると「4...
--[最適化対象例] 48_0f_af_85_28_03_00_00
--[最適化結果例#1] 48_6b_c0_?? (定数=-128~+127の場合)
--[最適化結果例#2] 48_69_c0_??_??_??_?? (それ以外の場合)
-optimizerX86()関数の中(さらに最適化)
+ if ((icq0[0] == 0x48 || icq0[0] == 0x49) && icq0...
+ icq = icq0;
+ putIcX64("%0c_ff_%1c", (IntP) (AInt) icq0[0]...
+ }
+ if ((icq0[0] == 0x48 || icq0[0] == 0x49) && icq0...
+ icq = icq0;
+ putIcX64("%0c_ff_%1c", (IntP) (AInt) icq0[0]...
+ }
+ if (icq0[0] == 0x48 && icq0[1] == 0x83 && (icq0[...
+ icq = icq0;
+ putIcX64("48_85_%0c", (IntP) (AInt) ((icq0[2...
+ }
+ if (icq0[0] == 0x49 && icq0[1] == 0x83 && (icq0[...
+ icq = icq0;
+ putIcX64("4d_85_%0c", (IntP) (AInt) ((icq0[2...
+ }
--これらは、以下のような最適化をします。
--「48_83_c0_01;」→「48_ff_c0;」(ADD 1 → INC)
--「48_83_e8_01;」→「48_ff_c8;」(SUB 1 → DEC)
--「48_83_f8_00;」→「48_85_c0;」(CMP 0 → TEST)
** (3) 成果の比較
-上記みたいなのはすごく特別でレアケースなのか、それともよ...
-サイズが小さくなったからいいとか悪いとかではなく、「サイ...
||HL-19a|HL-20|HL-20a|HL-20b|HL-21|HL-21a|
|mandel.c|RIGHT:1200|RIGHT:1088|RIGHT:989|RIGHT:989|RIGHT...
|maze.c|RIGHT:2331|RIGHT:2331|RIGHT:2331|RIGHT:2331|RIGHT...
|kcube.c|RIGHT:5207|RIGHT:5207|RIGHT:5207|RIGHT:5207|RIGH...
|invader.c|RIGHT:3567|RIGHT:3567|RIGHT:3567|RIGHT:3567|RI...
** 次回に続く
-次回: [[a21_txt02_12]]
*こめんと欄
#comment
終了行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2021.05.13)
** (1) HL-21a
-HL-21まででは、整数の定数があってもそれはすべて変数扱い...
-[1]optimizerX64()関数を以下のものと差し替え
unsigned char *icq0, *icq1, *icqSet;
int isConst(int i)
{
if ('0' <= ts[i][0] && ts[i][0] <= '9') return 1;
return 0;
}
int isConstM(unsigned char *p)
{
if ((*p & 0xc7) != 0x85) return 0;
return isConst(get32(p + 1) / 8);
}
AInt getConstM(unsigned char *p)
{
return var[get32(p + 1) / 8];
}
int is32bit(AInt i)
{
if (-0x80000000LL <= i && i <= 0x7fffffffLL) return 1;
return 0;
}
void putIcX64(String s, IntP p0, IntP p1, IntP p2, IntP ...
void optimizerX64()
{
if (icq0 != icq) {
if (icq0[0] == 0x0f && 0x90 <= icq0[1] && icq0[1...
icqSet = icq0;
}
+ if (icq0[0] == 0x48 && icq0[1] == 0x8b && isCons...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (i == 0) { putIcX64("31_%0c", ...
+ else if (i >> 32 == 0) { putIcX64("%0c_%1i",...
+ else if (is32bit(i)) { putIcX64("48_c7_%0c...
+ else { putIcX64("48_%0c_%1...
+ }
+ if (icq0[0] == 0x4c && icq0[1] == 0x8b && isCons...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (i == 0) { putIcX64("4d_31_%0c...
+ else if (i >> 32 == 0) { putIcX64("41_%0c_%1...
+ else if (is32bit(i)) { putIcX64("49_c7_%0c...
+ else { putIcX64("49_%0c_%1...
+ }
+ if (icq0[0] == 0x48 && icq0[1] <= 0x3f && (icq0[...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
+ else { putIcX64("48_...
+ }
+ if (icq0[0] == 0x4c && icq0[1] <= 0x3f && (icq0[...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("49_...
+ else { putIcX64("49_...
+ }
+ if (icq0[0] == 0x48 && icq0[1] == 0x0f && icq0[2...
+ AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
+ else { putIcX64("48_...
+ }
+ if (icq0[0] == 0x4c && icq0[1] == 0x0f && icq0[2...
+ AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("4d_...
+ else { putIcX64("4d_...
+ }
+ if ((icq0[0] == 0x48 || icq0[0] == 0x49) && icq0...
+ icq = icq0;
+ putIcX64("%0c_ff_%1c", (IntP) (AInt) icq0[0]...
+ }
+ if ((icq0[0] == 0x48 || icq0[0] == 0x49) && icq0...
+ icq = icq0;
+ putIcX64("%0c_ff_%1c", (IntP) (AInt) icq0[0]...
+ }
+ if (icq0[0] == 0x48 && icq0[1] == 0x83 && (icq0[...
+ icq = icq0;
+ putIcX64("48_85_%0c", (IntP) (AInt) ((icq0[2...
+ }
+ if (icq0[0] == 0x49 && icq0[1] == 0x83 && (icq0[...
+ icq = icq0;
+ putIcX64("4d_85_%0c", (IntP) (AInt) ((icq0[2...
+ }
if (icq1 != 0 && memcmp(icq0, "\x48\x8b\x85", 3)...
icq = icq0; // 8b命令は削除.
i = get32(icq1 + 3) / 8;
if (TcTmp0 <= i && i <= TcTmp9) {
icq = icq1; // 89命令も削除.
}
}
icq1 = icq0;
icq0 = icq;
}
if (icqSet + 15 == icq && memcmp(&icqSet[2], "\xc0\x...
memcpy(&icqSet[2], &icqSet[11], 4);
icqSet[1] -= 0x10; // SETcc → Jcc.
if (icqSet[10] == 0x84) {
icqSet[1] ^= 1; // 条件反転.
}
icq0 = icq = icqSet + 6;
icq1 = icqSet = 0;
jmps[jp - 1] = icq - 4 - ic;
}
}
----
-以上すべての改造を終えると、プログラムは1151行になります。
** (2) プログラムの説明#1
-isConst()関数
int isConst(int i)
{
if ('0' <= ts[i][0] && ts[i][0] <= '9') return 1;
return 0;
}
--これは、トークンコード(トークン番号)を渡すと、それが...
-isConstM()関数
int isConstM(unsigned char *p)
{
if ((*p & 0xc7) != 0x85) return 0;
return isConst(get32(p + 1) / 8);
}
--これは%mの部分のポインタを渡すと、その引数が定数を指し...
-getConstM()関数
int getConstM(unsigned char *p)
{
return var[get32(p + 1) / 8];
}
--定数だった場合に、その定数値を受け取ります。
-is32bit()関数
int is32bit(AInt i)
{
if (-0x80000000LL <= i && i <= 0x7fffffffLL) return 1;
return 0;
}
--与えられた値が、32bitで表現可能な場合に1を返します。
----
-optimizerX64()関数の中(8b用)
+ if (icq0[0] == 0x48 && icq0[1] == 0x8b && isCons...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (i == 0) { putIcX64("31_%0c", ...
+ else if (i >> 32 == 0) { putIcX64("%0c_%1i",...
+ else if (is32bit(i)) { putIcX64("48_c7_%0c...
+ else { putIcX64("48_%0c_%1...
+ }
+ if (icq0[0] == 0x4c && icq0[1] == 0x8b && isCons...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (i == 0) { putIcX64("4d_31_%0c...
+ else if (i >> 32 == 0) { putIcX64("41_%0c_%1...
+ else if (is32bit(i)) { putIcX64("49_c7_%0c...
+ else { putIcX64("49_%0c_%1...
+ }
--これは例えば「a = 0;」をHL-21でコンパイルすると「48_8b_...
--[最適化対象例] 48_8b_85_18_00_00_00
--[最適化結果例#1] 31_c0 (定数=0の場合)
--[最適化結果例#2] b8_??_??_??_?? (それ以外の場合)
-optimizerX86()関数の中(03~3b用)
+ if (icq0[0] == 0x48 && icq0[1] <= 0x3f && (icq0[...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
+ else { putIcX64("48_...
+ }
+ if (icq0[0] == 0x4c && icq0[1] <= 0x3f && (icq0[...
+ AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("49_...
+ else { putIcX64("49_...
+ }
--これは例えば「a = b + 2;」をHL-21でコンパイルすると「48...
--[最適化対象例] 48_03_85_28_00_00_00
--[最適化結果例#1] 48_83_c0_?? (定数=-128~+127の場合)
--[最適化結果例#2] 48_81_c0_??_??_??_?? (それ以外の場合)
-optimizerX86()関数の中(0f_af用)
+ if (icq0[0] == 0x48 && icq0[1] == 0x0f && icq0[2...
+ AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
+ else { putIcX64("48_...
+ }
+ if (icq0[0] == 0x4c && icq0[1] == 0x0f && icq0[2...
+ AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ icq = icq0;
+ if (-0x80 <= i && i <= 0x7f) { putIcX64("4d_...
+ else { putIcX64("4d_...
+ }
--これは例えば「a = b * 12;」をHL-21でコンパイルすると「4...
--[最適化対象例] 48_0f_af_85_28_03_00_00
--[最適化結果例#1] 48_6b_c0_?? (定数=-128~+127の場合)
--[最適化結果例#2] 48_69_c0_??_??_??_?? (それ以外の場合)
-optimizerX86()関数の中(さらに最適化)
+ if ((icq0[0] == 0x48 || icq0[0] == 0x49) && icq0...
+ icq = icq0;
+ putIcX64("%0c_ff_%1c", (IntP) (AInt) icq0[0]...
+ }
+ if ((icq0[0] == 0x48 || icq0[0] == 0x49) && icq0...
+ icq = icq0;
+ putIcX64("%0c_ff_%1c", (IntP) (AInt) icq0[0]...
+ }
+ if (icq0[0] == 0x48 && icq0[1] == 0x83 && (icq0[...
+ icq = icq0;
+ putIcX64("48_85_%0c", (IntP) (AInt) ((icq0[2...
+ }
+ if (icq0[0] == 0x49 && icq0[1] == 0x83 && (icq0[...
+ icq = icq0;
+ putIcX64("4d_85_%0c", (IntP) (AInt) ((icq0[2...
+ }
--これらは、以下のような最適化をします。
--「48_83_c0_01;」→「48_ff_c0;」(ADD 1 → INC)
--「48_83_e8_01;」→「48_ff_c8;」(SUB 1 → DEC)
--「48_83_f8_00;」→「48_85_c0;」(CMP 0 → TEST)
** (3) 成果の比較
-上記みたいなのはすごく特別でレアケースなのか、それともよ...
-サイズが小さくなったからいいとか悪いとかではなく、「サイ...
||HL-19a|HL-20|HL-20a|HL-20b|HL-21|HL-21a|
|mandel.c|RIGHT:1200|RIGHT:1088|RIGHT:989|RIGHT:989|RIGHT...
|maze.c|RIGHT:2331|RIGHT:2331|RIGHT:2331|RIGHT:2331|RIGHT...
|kcube.c|RIGHT:5207|RIGHT:5207|RIGHT:5207|RIGHT:5207|RIGH...
|invader.c|RIGHT:3567|RIGHT:3567|RIGHT:3567|RIGHT:3567|RI...
** 次回に続く
-次回: [[a21_txt02_12]]
*こめんと欄
#comment
ページ名: