「10日くらいでできる!プログラミング言語自作入門」の続編#1-11a

(1) HL-21a

void optimizerX64()
{
    int i;
    if (icq0 != icq) {
        if (icq0[0] == 0x0f && 0x90 <= icq0[1] && icq0[1] <= 0x9f) {	// SETcc
            icqSet = icq0;
        }
+       if (icq0[0] == 0x48 && icq0[1] == 0x8b && isConstM(&icq0[2])) { // 8b.
+           int reg = (icq0[1] >> 3) & 7, i = getConstM(&icq0[1]);
+           icq = icq0;
+           if (i == 0) { putIcX86("31_%0c", (IntP) (reg * 9 + 0xc0), 0, 0, 0); }
+           else        { putIcX86("%0c_%1i", (IntP) (reg + 0xb8), (IntP) i, 0, 0); }
+       }
+       if (icq0[0] <= 0x3f && (icq0[0] & 7) == 3 && isConstM(&icq0[1])) { // 03, 0b, 13, 1b, 23, 2b, 33, 3b.
+           int reg = (icq0[1] >> 3) & 7, i = getConstM(&icq0[1]);
+           icq = icq0;
+           if (-0x80 <= i && i <= 0x7f) { putIcX86("83_%0c_%1c", (IntP) ((icq0[0] & 0x38) + reg + 0xc0), (IntP) i, 0, 0); }
+           else                         { putIcX86("81_%0c_%1i", (IntP) ((icq0[0] & 0x38) + reg + 0xc0), (IntP) i, 0, 0); }
+       }
+       if (icq0[0] == 0x0f && icq0[1] == 0xaf && isConstM(&icq0[2])) { // 0f_af.
+           int reg = (icq0[2] >> 3) & 7, i = getConstM(&icq0[2]);
+           icq = icq0;
+           if (-0x80 <= i && i <= 0x7f) { putIcX86("6b_%0c_%1c", (IntP) (reg * 9 + 0xc0), (IntP) i, 0, 0); }
+           else                         { putIcX86("69_%0c_%1i", (IntP) (reg * 9 + 0xc0), (IntP) i, 0, 0); }
+       }
+       if (icq0[0] == 0x83 && (icq0[1] & 0xf8) == 0xc0 && icq0[2] == 1) { // ADD 1 → INC.
+           icq = icq0;
+           putIcX86("%0c", (IntP) ((icq0[1] & 7) + 0x40), 0, 0, 0);
+       }
+       if (icq0[0] == 0x83 && (icq0[1] & 0xf8) == 0xe8 && icq0[2] == 1) { // SUB 1 →DEC.
+           icq = icq0;
+           putIcX86("%0c", (IntP) ((icq0[1] & 7) + 0x48), 0, 0, 0);
+       }
+       if (icq0[0] == 0x83 && (icq0[1] & 0xf8) == 0xf8 && icq0[2] == 0) { // CMP 0 → TEST.
+           icq = icq0;
+           putIcX86("85_%0c", (IntP) ((icq0[1] & 7) * 9 + 0xc0), 0, 0, 0);
+       }
        if (icq0[0] == 0x8b && icq1 != 0 && icq1[0] == 0x89 && icq0[1] == 0x05 && icq1[1] == 0x05 && get32(icq0 + 2) == get32(icq1 + 2)) {
            icq = icq0;	// 	8b命令は削除.
            i = (IntP) get32(icq1 + 2) - var;
            if (TcTmp0 <= i && i <= TcTmp9) {
                icq = icq1;	// 89命令も削除.
            }
        }
        icq1 = icq0;
        icq0 = icq;
    }
    if (icqSet + 14 == icq && memcmp(&icqSet[2], "\xc0\x0f\xb6\xc0\x85\xc0\x0f", 7) == 0 && 0x84 <= icqSet[9] && icqSet[9] <= 0x85) {
        memcpy(&icqSet[2], &icqSet[10], 4);
        icqSet[1] -= 0x10;	// SETcc → Jcc.
        if (icqSet[9] == 0x84) {
            icqSet[1] ^= 1; // 条件反転.
        }
        icq0 = icq = icqSet + 6;
        icq1 = icqSet = 0;
        jmps[jp - 1] = icq - 4 - ic;
    }
}

(2) プログラムの説明#1


(3) プログラムの説明#2

1バイトのNOP90;
2バイトのNOP66_90;
3バイトのNOP0f_1f_00;
4バイトのNOP0f_1f_40_00;
5バイトのNOP0f_1f_44_00_00;
6バイトのNOP66_0f_1f_44_00_00;
7バイトのNOP0f_1f_80_00_00_00_00;
8バイトのNOP0f_1f_84_00_00_00_00_00;
9バイトのNOP66_0f_1f_84_00_00_00_00_00;

(4) 成果の比較

HL-13aHL-14HL-14aHL-15HL-15a
mandel.c10871007942768726
maze.c21922192219217701536
kcube.c46234623462336953495
invader.c32603260326027502399

次回に続く

こめんと欄


コメントお名前NameLink

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS