a21_txt02_3
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2021.04.16)
** (1) HL-13
-さてなんだかんだとJITコンパイラ対応をしているうちに、あ...
-[1]sub_関数群の宣言を以下の記述と差し替え
clock_t t0;
AWindow *win;
int toExit;
void sub_print(int i) { printf("%d\n", ...
void sub_time() { printf("time: %...
int sub_aRgb8(int r, int g, int b) { return aRgb8(r,...
int sub_XorShift() { return aXorShif...
int sub_aGetPix(int x, int y) { return aGetPix(...
int sub_f16Sin(int x) { return (int) (s...
int sub_f16Cos(int x) { return (int) (c...
int sub_aInkey(int opt) { return aInkey(w...
void sub_prints(char *s) { printf("%s\n", ...
void sub_aSetPix0(int x, int y, int c) { aSetPix0(win, x...
void sub_aFilRct0(int xsz, int ysz, int x0, int y0, int ...
void sub_aDrwStr0(int x, int y, int c, int b, char *s) ...
void sub_gprDec(int x, int y, int w, int c, int b, int i...
int sub_OpnWin(int xsz, int ysz, char *s)
{
if (win != 0) {
if (win->xsiz < xsz || win->ysiz < ysz) {
printf("openWin error\n");
return 1;
}
} else
win = aOpenWin(xsz, ysz, s, 0);
return 0;
}
int sub_aWait(int msec)
{
if (msec == -1) {
if (win != 0) {
aFlushAll(win);
}
return 1;
}
aWait(msec);
return 0;
}
void sub_bitblt(int xsz, int ysz, int x0, int y0, int *a)
{
AInt32 *p32 = &win->buf[x0 + y0 * win->xsiz];
int i, j;
for (j = 0; j < ysz; j++) {
for (i = 0; i < xsz; i++) {
p32[i] = a[i];
}
a += xsz;
p32 += win->xsiz;
}
}
-[2]exprSub1()関数の直前のプロトタイプ宣言に、以下の行を...
int phrCmpPutIcX86(int pid, String phr, int pc, int *pi,...
-[3]exprSub()関数内の記述を差し替え
! } else if (phrCmp(72, "mul64shr(!!**0, !!**1, !!**2)...
+ e0 = expr(0);
+ e1 = expr(1);
+ int e2 = expr(2);
+ i = tmpAlloc();
+ putIcX86("8b_%2m1; 8b_%0m0; f7_%1m5; 0f_ad_d0; 8...
+ tmpFree(e2);
+ if (e2 < 0) {
+ e0 = -1;
+ }
! } else if (phrCmpPutIcX86(73, "aRgb8(!!**0, !!**1, !...
! } else if (phrCmpPutIcX86(74, "aOpenWin(!!**0, !!**1...
+ putIcX86("85_c0; 0f_85_%0l;", &var[toExit], 0, 0...
i = Tc0;
! } else if (phrCmpPutIcX86(75, "aXorShift32()", ...
! } else if (phrCmpPutIcX86(76, "aGetPix(!!**8, !!**0,...
! } else if (phrCmpPutIcX86(77, "ff16sin(!!**0)", ...
! } else if (phrCmpPutIcX86(78, "ff16cos(!!**0)", ...
! } else if (phrCmpPutIcX86(79, "aInkey(!!***8 , !!**0...
-[4]ifgoto()関数を以下の記述と交換
int condCode[6] = { 0x84, 0x85, 0x8c, 0x8d, 0x8e, 0x8f }...
void ifgoto(int i, int not, int label)
{
int j = wpc[i];
if (j + 3 == wpc1[i] && TcEEq <= tc[j + 1] && tc[j +...
! putIcX86("8b_%2m0; 3b_%3m0; 0f_%0c_%1l;", (IntP)...
} else {
i = expr(i);
! putIcX86("8b_%2m0; 85_c0; 0f_%0c_%1l;", (IntP) (...
tmpFree(i);
}
}
-[5]compile()関数に1行追加(1)
tmpLabelNo = 0;
bd = lbd = 0;
+ toExit = tmpLabelAlloc();
for (pc = 0; pc < pc1; ) { // コンパイル開始.
-[6]compile()関数内の記述を差し替え(1)
} else if (phrCmp( 5, "goto !!*0;", pc)) { // g...
! putIcX86("e9_%0l;", &var[tc[wpc[0]]], 0, 0, ...
-[7]compile()関数内の記述を差し替え(2)
} else if (phrCmp(12, "} else {", pc) && binf[bd...
binf[bd + IfLabel1] = tmpLabelAlloc(); // el...
! putIcX86("e9_%0l;", &var[binf[bd + IfLabel1]...
! defLabel(binf[bd + IfLabel0]); // ラベルに対...
} else if (phrCmp( 13, "}", pc) && binf[bd] == B...
if (binf[bd + IfLabel1] == 0) {
! defLabel(binf[bd + IfLabel0]); // ラベル...
} else {
! defLabel(binf[bd + IfLabel1]); // ラベル...
}
bd -= BInfSiz;
} else if (phrCmp(14, "for (!!***0; !!***1; !!**...
bd += BInfSiz;
binf[bd] = BlkFor; // ブロックのタイプ.
binf[bd + ForLopBgn] = tmpLabelAlloc(); // ...
binf[bd + ForCont ] = tmpLabelAlloc(); // c...
binf[bd + ForBrk ] = tmpLabelAlloc(); // b...
binf[bd + ForLbd0 ] = lbd; // 古い値を保存.
binf[bd + ForWpc01 ] = wpc [1];
binf[bd + ForWpc11 ] = wpc1[1];
binf[bd + ForWpc02 ] = wpc [2];
binf[bd + ForWpc12 ] = wpc1[2];
lbd = bd;
e0 = expr(0);
if (wpc[1] < wpc1[1]) { // !!***1に何らかの...
ifgoto(1, IfFalse, binf[bd + ForBrk]); /...
}
! defLabel(binf[bd + ForLopBgn]); // ラベルに...
} else if (phrCmp(15, "}", pc) && binf[bd] == Bl...
! defLabel(binf[bd + ForCont]); // ラベルに対...
i = binf[bd + ForWpc01];
j = binf[bd + ForWpc02];
if (i + 3 == binf[bd + ForWpc11] && j + 2 ==...
// !!***1が「i < ?」かつ、!!***2が「i++...
! putIcX86("8b_%1m0; 40; 89_%1m0; 3b_%2m0;...
} else {
wpc [1] = binf[bd + ForWpc01];
wpc1[1] = binf[bd + ForWpc11];
wpc [2] = binf[bd + ForWpc02];
wpc1[2] = binf[bd + ForWpc12];
e2 = expr(2);
if (wpc[1] < wpc1[1]) { // !!***1に何ら...
ifgoto(1, 0, binf[bd + ForLopBgn]);
} else {
! putIcX86("e9_%0l;", &var[binf[bd + F...
}
}
! defLabel(binf[bd + ForBrk]); // ラベルに対応...
lbd = binf[bd+ ForLbd0]; // 以前の値を復元.
bd -= BInfSiz;
} else if (phrCmp(16, "continue;", pc) && lbd > ...
! putIcX86("e9_%0l;", &var[binf[lbd + ForCont]...
} else if (phrCmp(17, "break;", pc) && lbd > 0) {
! putIcX86("e9_%0l;", &var[binf[lbd + ForBrk ]...
-[8]compile()関数内の記述を差し替え(3)
! } else if (phrCmpPutIcX86(20, "prints !!**0;", p...
-[9]compile()関数内の記述を差し替え(4)
! } else if (phrCmpPutIcX86(23, "aSetPix0(!!***8, ...
! } else if (phrCmpPutIcX86(24, "aWait(!!**0);", ...
+ putIcX86("85_c0; 0f_85_%0l;", &var[toExit], ...
! } else if (phrCmpPutIcX86(25, "aFillRect0(!!***8...
! } else if (phrCmpPutIcX86(26, "aDrawStr0(!!***8,...
! } else if (phrCmpPutIcX86(27, "gprintDec(!!***8,...
! } else if (phrCmpPutIcX86(28, "bitblt(!!***8, !!...
! } else if (phrCmpPutIcX86(29, "printTime();", ...
-[10]compile()関数に1行追加(2)
if (bd > 0) {
printf("block nesting error (bd=%d, lbd=%d, pc=%...
return -1;
}
! defLabel(toExit);
dump1 = icq;
putIcX86("83_c4_7c; 61; c3;", 0, 0, 0, 0); // ADD(ES...
icq1 = icq;
for (i = 0; i < jp; i++) { // ジャンプ命令の最適化.
-[11]run()関数に3行追加
int run(String s)
{
if (compile(s) < 0)
return 1;
if (codedump == 0) {
void (*func)() = (void (*)()) ic;
t0 = clock();
func();
+ if (win != 0) {
+ aFlushAll(win);
+ }
} else {
int i, i1 = dump1 - dump0;
for (i = 0; i < i1; i++) {
printf("%02x ", dump0[i]);
}
printf("\n(len=%d)\n", i1);
}
return 0;
}
----
-以上すべての改造を終えると、プログラムは827行になります。
-これで[[a21_txt01_9a]]で紹介した、mandel.cやmaze.cが動く...
-特にmandel.cはすごいです。HL-9aのころと比べて3.2倍くらい...
** (2) 今回新出の機械語
|f7_%m/5|EAXに%mで指定した値を掛け算して、結果をEDX:EAXに...
|0f_ad_d0|EDX:EAXの64bitをECXだけ右シフトする。でもEAXし...
|0f_80_%l ~ 0f_8f_%l|条件分岐命令。|アセンブラではJcc命令|
|85_c0|EAXを0と比較。|アセンブラではTEST命令|
** (3) HL-9aとHL-13を比較してみる
-これがあれば、何が何に対応しているかわかりやすいでしょう...
単純代入:
(HL-9a) putIc (OpCpy, &var[tc[wpc[0]]]...
(HL-13) putIcX86("8b_%1m0; 89_%0m0;", &var[tc[wpc[0]]]...
print命令:
(HL-9a) phrCmpPutIc ( 4, "print !!**0;", pc, 0, 1, O...
(HL-13) phrCmpPutIcX86( 4, "print !!**0;", pc, 0, 1, s...
+1する命令:
(HL-9a) putIc (OpAdd1, &var[tc[wpc[...
(HL-13) putIcX86("8b_%0m0; 40; 89_%0m0;", &var[tc[wpc[...
各種二項演算子:
いずれも基本形は以下の通り
(HL-9a) putIc (op, &var[tc[wpc[0]]], &var[tc[wpc[1...
(HL-13) putIcX86(op, &var[tc[wpc[0]]], &var[tc[wpc[1...
演算子 (HL-9a) (HL-13)
+ OpAdd "8b_%1m0; 03_%2m0; 89_%0m0;"
- OpSub "8b_%1m0; 2b_%2m0; 89_%0m0;"
* OpMul "8b_%1m0; 0f_af_%2m0; 89_%0m0;"
/ OpDiv "8b_%1m0; 99; f7_%2m7; 89_%0m0;"
% OpMod "8b_%1m0; 99; f7_%2m7; 89_%0m2;"
& OpAnd "8b_%1m0; 23_%2m0; 89_%0m0;"
>> OpShr "8b_%1m0; 8b_%2m1; d3_f8; 89_%0m0;"
== OpCeq "8b_%1m0; 3b_%2m0; 0f_94_c0; 83_e0_01...
!= OpCne "8b_%1m0; 3b_%2m0; 0f_95_c0; 83_e0_01...
< OpClt "8b_%1m0; 3b_%2m0; 0f_9c_c0; 83_e0_01...
>= OpCge "8b_%1m0; 3b_%2m0; 0f_9d_c0; 83_e0_01...
<= OpCle "8b_%1m0; 3b_%2m0; 0f_9e_c0; 83_e0_01...
> OpCgt "8b_%1m0; 3b_%2m0; 0f_9f_c0; 83_e0_01...
ループ命令:
(HL-9a) putIc (OpLop, ...
(HL-13) putIcX86("8b_%1m0; 40; 89_%1m0; 3b_%2m0; 0f_8c...
-(未完成)
** 次回に続く
-次回: [[a21_txt02_3a]]
*こめんと欄
#comment
終了行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2021.04.16)
** (1) HL-13
-さてなんだかんだとJITコンパイラ対応をしているうちに、あ...
-[1]sub_関数群の宣言を以下の記述と差し替え
clock_t t0;
AWindow *win;
int toExit;
void sub_print(int i) { printf("%d\n", ...
void sub_time() { printf("time: %...
int sub_aRgb8(int r, int g, int b) { return aRgb8(r,...
int sub_XorShift() { return aXorShif...
int sub_aGetPix(int x, int y) { return aGetPix(...
int sub_f16Sin(int x) { return (int) (s...
int sub_f16Cos(int x) { return (int) (c...
int sub_aInkey(int opt) { return aInkey(w...
void sub_prints(char *s) { printf("%s\n", ...
void sub_aSetPix0(int x, int y, int c) { aSetPix0(win, x...
void sub_aFilRct0(int xsz, int ysz, int x0, int y0, int ...
void sub_aDrwStr0(int x, int y, int c, int b, char *s) ...
void sub_gprDec(int x, int y, int w, int c, int b, int i...
int sub_OpnWin(int xsz, int ysz, char *s)
{
if (win != 0) {
if (win->xsiz < xsz || win->ysiz < ysz) {
printf("openWin error\n");
return 1;
}
} else
win = aOpenWin(xsz, ysz, s, 0);
return 0;
}
int sub_aWait(int msec)
{
if (msec == -1) {
if (win != 0) {
aFlushAll(win);
}
return 1;
}
aWait(msec);
return 0;
}
void sub_bitblt(int xsz, int ysz, int x0, int y0, int *a)
{
AInt32 *p32 = &win->buf[x0 + y0 * win->xsiz];
int i, j;
for (j = 0; j < ysz; j++) {
for (i = 0; i < xsz; i++) {
p32[i] = a[i];
}
a += xsz;
p32 += win->xsiz;
}
}
-[2]exprSub1()関数の直前のプロトタイプ宣言に、以下の行を...
int phrCmpPutIcX86(int pid, String phr, int pc, int *pi,...
-[3]exprSub()関数内の記述を差し替え
! } else if (phrCmp(72, "mul64shr(!!**0, !!**1, !!**2)...
+ e0 = expr(0);
+ e1 = expr(1);
+ int e2 = expr(2);
+ i = tmpAlloc();
+ putIcX86("8b_%2m1; 8b_%0m0; f7_%1m5; 0f_ad_d0; 8...
+ tmpFree(e2);
+ if (e2 < 0) {
+ e0 = -1;
+ }
! } else if (phrCmpPutIcX86(73, "aRgb8(!!**0, !!**1, !...
! } else if (phrCmpPutIcX86(74, "aOpenWin(!!**0, !!**1...
+ putIcX86("85_c0; 0f_85_%0l;", &var[toExit], 0, 0...
i = Tc0;
! } else if (phrCmpPutIcX86(75, "aXorShift32()", ...
! } else if (phrCmpPutIcX86(76, "aGetPix(!!**8, !!**0,...
! } else if (phrCmpPutIcX86(77, "ff16sin(!!**0)", ...
! } else if (phrCmpPutIcX86(78, "ff16cos(!!**0)", ...
! } else if (phrCmpPutIcX86(79, "aInkey(!!***8 , !!**0...
-[4]ifgoto()関数を以下の記述と交換
int condCode[6] = { 0x84, 0x85, 0x8c, 0x8d, 0x8e, 0x8f }...
void ifgoto(int i, int not, int label)
{
int j = wpc[i];
if (j + 3 == wpc1[i] && TcEEq <= tc[j + 1] && tc[j +...
! putIcX86("8b_%2m0; 3b_%3m0; 0f_%0c_%1l;", (IntP)...
} else {
i = expr(i);
! putIcX86("8b_%2m0; 85_c0; 0f_%0c_%1l;", (IntP) (...
tmpFree(i);
}
}
-[5]compile()関数に1行追加(1)
tmpLabelNo = 0;
bd = lbd = 0;
+ toExit = tmpLabelAlloc();
for (pc = 0; pc < pc1; ) { // コンパイル開始.
-[6]compile()関数内の記述を差し替え(1)
} else if (phrCmp( 5, "goto !!*0;", pc)) { // g...
! putIcX86("e9_%0l;", &var[tc[wpc[0]]], 0, 0, ...
-[7]compile()関数内の記述を差し替え(2)
} else if (phrCmp(12, "} else {", pc) && binf[bd...
binf[bd + IfLabel1] = tmpLabelAlloc(); // el...
! putIcX86("e9_%0l;", &var[binf[bd + IfLabel1]...
! defLabel(binf[bd + IfLabel0]); // ラベルに対...
} else if (phrCmp( 13, "}", pc) && binf[bd] == B...
if (binf[bd + IfLabel1] == 0) {
! defLabel(binf[bd + IfLabel0]); // ラベル...
} else {
! defLabel(binf[bd + IfLabel1]); // ラベル...
}
bd -= BInfSiz;
} else if (phrCmp(14, "for (!!***0; !!***1; !!**...
bd += BInfSiz;
binf[bd] = BlkFor; // ブロックのタイプ.
binf[bd + ForLopBgn] = tmpLabelAlloc(); // ...
binf[bd + ForCont ] = tmpLabelAlloc(); // c...
binf[bd + ForBrk ] = tmpLabelAlloc(); // b...
binf[bd + ForLbd0 ] = lbd; // 古い値を保存.
binf[bd + ForWpc01 ] = wpc [1];
binf[bd + ForWpc11 ] = wpc1[1];
binf[bd + ForWpc02 ] = wpc [2];
binf[bd + ForWpc12 ] = wpc1[2];
lbd = bd;
e0 = expr(0);
if (wpc[1] < wpc1[1]) { // !!***1に何らかの...
ifgoto(1, IfFalse, binf[bd + ForBrk]); /...
}
! defLabel(binf[bd + ForLopBgn]); // ラベルに...
} else if (phrCmp(15, "}", pc) && binf[bd] == Bl...
! defLabel(binf[bd + ForCont]); // ラベルに対...
i = binf[bd + ForWpc01];
j = binf[bd + ForWpc02];
if (i + 3 == binf[bd + ForWpc11] && j + 2 ==...
// !!***1が「i < ?」かつ、!!***2が「i++...
! putIcX86("8b_%1m0; 40; 89_%1m0; 3b_%2m0;...
} else {
wpc [1] = binf[bd + ForWpc01];
wpc1[1] = binf[bd + ForWpc11];
wpc [2] = binf[bd + ForWpc02];
wpc1[2] = binf[bd + ForWpc12];
e2 = expr(2);
if (wpc[1] < wpc1[1]) { // !!***1に何ら...
ifgoto(1, 0, binf[bd + ForLopBgn]);
} else {
! putIcX86("e9_%0l;", &var[binf[bd + F...
}
}
! defLabel(binf[bd + ForBrk]); // ラベルに対応...
lbd = binf[bd+ ForLbd0]; // 以前の値を復元.
bd -= BInfSiz;
} else if (phrCmp(16, "continue;", pc) && lbd > ...
! putIcX86("e9_%0l;", &var[binf[lbd + ForCont]...
} else if (phrCmp(17, "break;", pc) && lbd > 0) {
! putIcX86("e9_%0l;", &var[binf[lbd + ForBrk ]...
-[8]compile()関数内の記述を差し替え(3)
! } else if (phrCmpPutIcX86(20, "prints !!**0;", p...
-[9]compile()関数内の記述を差し替え(4)
! } else if (phrCmpPutIcX86(23, "aSetPix0(!!***8, ...
! } else if (phrCmpPutIcX86(24, "aWait(!!**0);", ...
+ putIcX86("85_c0; 0f_85_%0l;", &var[toExit], ...
! } else if (phrCmpPutIcX86(25, "aFillRect0(!!***8...
! } else if (phrCmpPutIcX86(26, "aDrawStr0(!!***8,...
! } else if (phrCmpPutIcX86(27, "gprintDec(!!***8,...
! } else if (phrCmpPutIcX86(28, "bitblt(!!***8, !!...
! } else if (phrCmpPutIcX86(29, "printTime();", ...
-[10]compile()関数に1行追加(2)
if (bd > 0) {
printf("block nesting error (bd=%d, lbd=%d, pc=%...
return -1;
}
! defLabel(toExit);
dump1 = icq;
putIcX86("83_c4_7c; 61; c3;", 0, 0, 0, 0); // ADD(ES...
icq1 = icq;
for (i = 0; i < jp; i++) { // ジャンプ命令の最適化.
-[11]run()関数に3行追加
int run(String s)
{
if (compile(s) < 0)
return 1;
if (codedump == 0) {
void (*func)() = (void (*)()) ic;
t0 = clock();
func();
+ if (win != 0) {
+ aFlushAll(win);
+ }
} else {
int i, i1 = dump1 - dump0;
for (i = 0; i < i1; i++) {
printf("%02x ", dump0[i]);
}
printf("\n(len=%d)\n", i1);
}
return 0;
}
----
-以上すべての改造を終えると、プログラムは827行になります。
-これで[[a21_txt01_9a]]で紹介した、mandel.cやmaze.cが動く...
-特にmandel.cはすごいです。HL-9aのころと比べて3.2倍くらい...
** (2) 今回新出の機械語
|f7_%m/5|EAXに%mで指定した値を掛け算して、結果をEDX:EAXに...
|0f_ad_d0|EDX:EAXの64bitをECXだけ右シフトする。でもEAXし...
|0f_80_%l ~ 0f_8f_%l|条件分岐命令。|アセンブラではJcc命令|
|85_c0|EAXを0と比較。|アセンブラではTEST命令|
** (3) HL-9aとHL-13を比較してみる
-これがあれば、何が何に対応しているかわかりやすいでしょう...
単純代入:
(HL-9a) putIc (OpCpy, &var[tc[wpc[0]]]...
(HL-13) putIcX86("8b_%1m0; 89_%0m0;", &var[tc[wpc[0]]]...
print命令:
(HL-9a) phrCmpPutIc ( 4, "print !!**0;", pc, 0, 1, O...
(HL-13) phrCmpPutIcX86( 4, "print !!**0;", pc, 0, 1, s...
+1する命令:
(HL-9a) putIc (OpAdd1, &var[tc[wpc[...
(HL-13) putIcX86("8b_%0m0; 40; 89_%0m0;", &var[tc[wpc[...
各種二項演算子:
いずれも基本形は以下の通り
(HL-9a) putIc (op, &var[tc[wpc[0]]], &var[tc[wpc[1...
(HL-13) putIcX86(op, &var[tc[wpc[0]]], &var[tc[wpc[1...
演算子 (HL-9a) (HL-13)
+ OpAdd "8b_%1m0; 03_%2m0; 89_%0m0;"
- OpSub "8b_%1m0; 2b_%2m0; 89_%0m0;"
* OpMul "8b_%1m0; 0f_af_%2m0; 89_%0m0;"
/ OpDiv "8b_%1m0; 99; f7_%2m7; 89_%0m0;"
% OpMod "8b_%1m0; 99; f7_%2m7; 89_%0m2;"
& OpAnd "8b_%1m0; 23_%2m0; 89_%0m0;"
>> OpShr "8b_%1m0; 8b_%2m1; d3_f8; 89_%0m0;"
== OpCeq "8b_%1m0; 3b_%2m0; 0f_94_c0; 83_e0_01...
!= OpCne "8b_%1m0; 3b_%2m0; 0f_95_c0; 83_e0_01...
< OpClt "8b_%1m0; 3b_%2m0; 0f_9c_c0; 83_e0_01...
>= OpCge "8b_%1m0; 3b_%2m0; 0f_9d_c0; 83_e0_01...
<= OpCle "8b_%1m0; 3b_%2m0; 0f_9e_c0; 83_e0_01...
> OpCgt "8b_%1m0; 3b_%2m0; 0f_9f_c0; 83_e0_01...
ループ命令:
(HL-9a) putIc (OpLop, ...
(HL-13) putIcX86("8b_%1m0; 40; 89_%1m0; 3b_%2m0; 0f_8c...
-(未完成)
** 次回に続く
-次回: [[a21_txt02_3a]]
*こめんと欄
#comment
ページ名: