| ページ名 | 名前 | 行数 | .exeの大きさ | 説明 | 速度のめやす1 | 速度のめやす2 |
| [ a21_txt01 ] | HL-1~HL-9a | 49行~772行 | 6.0KB~20.0KB | 「10日くらいでできる!プログラミング言語自作入門」 | 1520倍~5.5倍 | 6.4倍 |
| a21_txt02_7 | HL-17 | 741行 | 25.0KB | x64に対応したJITコンパイラ第1号 | 計測不能 | 計測不能 |
| a21_txt02_7a | HL-17a | 756行 | 26.0KB | 簡単な演算もサポート | 計測不能 | 計測不能 |
| a21_txt02_8 | HL-18 | 795行 | 27.0KB | ループ速度の測定ができるところまで | 4.2倍 | 計測不能 |
| a21_txt02_8a | HL-18a | 816行 | 27.5KB | codedumpコマンドと、codeコマンドの追加 | 4.2倍 | 計測不能 |
| a21_txt02_9 | HL-19 | 893行 | 35.5KB | 配列以外は全部JITコンパイラ対応させる(mandel.cで速さを実感!) | 4.2倍 | 1.8倍 |
| a21_txt02_9a | HL-19a | 899行 | 36.0KB | 配列もJITコンパイラ対応させる(ついに機能的にはHL-9a相当に!) | 4.2倍 | 1.8倍 |
regVar(0, x); regVar(1, y); regVar(2, z);
regVar(0, x, y, z);
#define regVar(...)
#if (ABI_MSW64 != 0)
#define RegVarLen 7
int regVarNo[7] = { 3, 6, 7, 12, 13, 14, 15 }; // レジスタ変数番号から、レジスタ番号に変換.
#elif (ABI_SYSV64 != 0)
#define RegVarLen 5
int regVarNo[5] = { 3, 12, 13, 14, 15 }; // レジスタ変数番号から、レジスタ番号に変換.
#endif
IntP regVarTbl[RegVarLen]; // レジスタ変数の割り当て状況を記憶.
int regVar(IntP v) // もし変数vがレジスタに割り当てられていれば、0~7を返す. そうでなければ-1を返す.
{
int i;
for (i = 0; i < RegVarLen; i++) {
if (regVarTbl[i] == v)
return i;
}
return -1;
} if (s[i + 2] == 'm') { // mod r/m.
k = s[i + 3] - '0';
if (s[i + 3] >= 'a') { // もしかしたらこの記述は最後まで出番がないかも.
k = s[i + 3] - 'a' + 10;
}
+ if (k >= 8) {
+ *putIcX64_rex += 4;
+ k -= 8;
+ }
+ int rv = regVar(a[j]);
+ if (rv < 0) {
*icq = 0x85 + k * 8;
put32(icq + 1, (a[j] - var) * 8);
icq += 5;
+ } else {
+ rv = regVarNo[rv];
+ if (rv >= 8) {
+ *putIcX64_rex += 1;
+ rv -= 8;
+ }
+ *icq = 0xc0 + rv + k * 8;
+ icq++;
+ }
i += 4;
continue;
}enum { RvSave = 0x89, RvLoad = 0x8b };
void regVarSaveLoad(int op) // レジスタ変数を準備するor書き戻す.
{
int i, rv, rex;
for (i = 0; i < RegVarLen; i++) {
if (regVarTbl[i] != 0) {
rv = regVarNo[i];
rex = 0x48;
if (rv >= 8) {
rex = 0x48 + 4;
rv -= 8;
}
putIcX64("%0c_%1c_%2c_%3i;", (IntP) (AInt) rex, (IntP) (AInt) op, (IntP) (AInt) (0x85 + rv * 8), (IntP) (AInt) ((regVarTbl[i] - var) * 8));
}
}
} icq = ic;
jp = 0;
putIcX64("41_57; 41_56; 41_55; 41_54; 41_53; 41_52;", 0, 0, 0, 0);
putIcX64("41_51; 41_50; 57; 56; 55; 54; 53; 52; 51; 50;", 0, 0, 0, 0);
putIcX64("%R_81_ec_f8_01_00_00; %R_bd_%0q;", var, 0, 0, 0);
+ regVarSaveLoad(RvLoad);
dump0 = icq;+ } else if (phrCmp(37, "regVar(!!*0", pc)) {
+ i = tc[wpc[0]] - Tc0;
+ regVarSaveLoad(RvSave);
+ for (pc = ppc1; tc[pc] != TcBrCls; pc++) {
+ if (tc[pc] == TcComma) continue;
+ if (0 <= i && i < RegVarLen) {
+ regVarTbl[i] = &var[tc[pc]];
+ if (tc[pc] == Tc0)
+ regVarTbl[i] = 0;
+ }
+ i++;
+ }
+ regVarSaveLoad(RvLoad);
+ ppc1 = pc + 2; defLabel(toExit);
dump1 = icq;
+ regVarSaveLoad(RvSave);
putIcX64("%R_81_c4_f8_01_00_00;", 0, 0, 0, 0);
putIcX64("58; 59; 5a; 5b; 5c; 5d; 5e; 5f; 41_58; 41_59;", 0, 0, 0, 0);
putIcX64("41_5a; 41_5b; 41_5c; 41_5d; 41_5e; 41_5f; c3;", 0, 0, 0, 0);
icq1 = icq; if (s[i + 2] == 'm') { // mod r/m.
k = s[i + 3] - '0';
if (s[i + 3] >= 'a') { // もしかしたらこの記述は最後まで出番がないかも.
k = s[i + 3] - 'a' + 10;
}
+ if (k >= 8) {
+ *putIcX64_rex += 4;
+ k -= 8;
+ }
+ int rv = regVar(a[j]);
+ if (rv < 0) {
*icq = 0x85 + k * 8;
put32(icq + 1, (a[j] - var) * 8);
icq += 5;
+ } else {
+ rv = regVarNo[rv];
+ if (rv >= 8) {
+ *putIcX64_rex += 1;
+ rv -= 8;
+ }
+ *icq = 0xc0 + rv + k * 8;
+ icq++;
+ }
i += 4;
continue;
}| ページ名 | 名前 | 行数 | .exeの大きさ | 説明 | 速度のめやす1 | 速度のめやす2 |
| [ a21_txt01 ] | HL-1~HL-9a | 49行~772行 | 6.0KB~20.0KB | 「10日くらいでできる!プログラミング言語自作入門」 | 1520倍~5.5倍 | 6.4倍 |
| a21_txt02_7 | HL-17 | 741行 | 25.0KB | x64に対応したJITコンパイラ第1号 | 計測不能 | 計測不能 |
| a21_txt02_7a | HL-17a | 756行 | 26.0KB | 簡単な演算もサポート | 計測不能 | 計測不能 |
| a21_txt02_8 | HL-18 | 795行 | 27.0KB | ループ速度の測定ができるところまで | 4.2倍 | 計測不能 |
| a21_txt02_8a | HL-18a | 816行 | 27.5KB | codedumpコマンドと、codeコマンドの追加 | 4.2倍 | 計測不能 |
| a21_txt02_9 | HL-19 | 893行 | 35.5KB | 配列以外は全部JITコンパイラ対応させる(mandel.cで速さを実感!) | 4.2倍 | 1.8倍 |
| a21_txt02_9a | HL-19a | 899行 | 36.0KB | 配列もJITコンパイラ対応させる(ついに機能的にはHL-9a相当に!) | 4.2倍 | 1.8倍 |
| a21_txt02_10 | HL-20 | 964行 | 36.0KB | レジスタ変数の導入(65行しか増えない簡単な改造だけど、結構な効果がある) | 2.1倍 | 1.0倍 |
| コメント | お名前 | NameLink | |