clock_t t0;
AWindow *win;
int toExit;
void sub_print(AInt i) { printf("%d\n", (int) i); }
void sub_time() { printf("time: %.3f[sec]\n", (clock() - t0) / (double) CLOCKS_PER_SEC); }
AInt sub_aRgb8(AInt r, AInt g, AInt b) { return aRgb8(r, g, b); }
AInt sub_XorShift() { return aXorShift32(); }
AInt sub_aGetPix(AInt x, AInt y) { return aGetPix(win, x, y); }
AInt sub_f16Sin(AInt x) { return (AInt) (sin(x * (2 * 3.14159265358979323 / 65536)) * 65536); }
AInt sub_f16Cos(AInt x) { return (AInt) (cos(x * (2 * 3.14159265358979323 / 65536)) * 65536); }
AInt sub_aInkey(AInt opt) { return aInkey(win, opt); }
void sub_prints(char *s) { printf("%s\n", s); }
void sub_aSetPix0(AInt x, AInt y, AInt c) { aSetPix0(win, x, y, c); }
void sub_aFilRct0(AInt xsz, AInt ysz, AInt x0, AInt y0, AInt c) { aFillRect0(win, xsz, ysz, x0, y0, c); }
void sub_aDrwStr0(AInt x, AInt y, AInt c, AInt b, char *s) { aDrawStr0(win, x, y, c, b, s); }
void sub_gprDec(AInt x, AInt y, AInt w, AInt c, AInt b, AInt i) { char s[100]; sprintf(s, "%*d", w, i); aDrawStr0(win, x, y, c, b, s); }
AInt sub_OpnWin(AInt xsz, AInt 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;
}
AInt sub_aWait(AInt msec)
{
if (msec == -1) {
if (win != 0) {
aFlushAll(win);
}
return 1;
}
aWait(msec);
return 0;
}
void sub_bitblt(AInt xsz, AInt ysz, AInt x0, AInt y0, AInt *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;
}
}
void initTcSub()
{
var[TcSubPrint] = (AInt) sub_print;
var[TcSubTime] = (AInt) sub_time;
var[TcSubRgb8] = (AInt) sub_aRgb8;
var[TcSubXorShift] = (AInt) sub_XorShift;
var[TcSubGetPix] = (AInt) sub_aGetPix;
var[TcSubF16Sin] = (AInt) sub_f16Sin;
var[TcSubF16Cos] = (AInt) sub_f16Cos;
var[TcSubInkey] = (AInt) sub_aInkey;
var[TcSubPrints] = (AInt) sub_prints;
var[TcSubSetPix0] = (AInt) sub_aSetPix0;
var[TcSubFilRct0] = (AInt) sub_aFilRct0;
var[TcSubDrwStr0] = (AInt) sub_aDrwStr0;
var[TcSubGprDec] = (AInt) sub_gprDec;
var[TcSubOpnWin] = (AInt) sub_OpnWin;
var[TcSubWait] = (AInt) sub_aWait;
var[TcSubBitBlt] = (AInt) sub_bitblt;
}int phrCmpPutIcX64(int pid, String phr, int pc, int *pi, int lenExpr, int sub, int *err);
! } else if (phrCmp(72, "mul64shr(!!**0, !!**1, !!**2)", epc)) {
+ e0 = expr(0);
+ e1 = expr(1);
+ int e2 = expr(2);
+ i = tmpAlloc();
+ putIcX64("%R_8b_%2m1; %R_8b_%0m0; %R_0f_af_%1m0; %R_d3_f8; %R_89_%3m0;", &var[e0], &var[e1], &var[e2], &var[i]);
+ tmpFree(e2);
+ if (e2 < 0) {
+ e0 = -1;
+ }
! } else if (phrCmpPutIcX64(73, "aRgb8(!!**0, !!**1, !!**2)", epc, &i, 3, TcSubRgb8, &e0)) {
! } else if (phrCmpPutIcX64(74, "aOpenWin(!!**0, !!**1, !!***2, !!***8)", epc, 0, 3, TcSubOpnWin, &e0)) {
+ putIcX64("%R_85_c0; 0f_85_%0l;", &var[toExit], 0, 0, 0); // 関数の戻り値によっては終了する.
i = Tc0;
! } else if (phrCmpPutIcX64(75, "aXorShift32()", epc, &i, 0, TcSubXorShift, &e0)) {
! } else if (phrCmpPutIcX64(76, "aGetPix(!!**8, !!**0, !!**1)", epc, &i, 2, TcSubGetPix, &e0)) {
! } else if (phrCmpPutIcX64(77, "ff16sin(!!**0)", epc, &i, 1, TcSubF16Sin, &e0)) {
! } else if (phrCmpPutIcX64(78, "ff16cos(!!**0)", epc, &i, 1, TcSubF16Cos, &e0)) {
! } else if (phrCmpPutIcX64(79, "aInkey(!!***8 , !!**0)", epc, &i, 1, TcSubInkey, &e0)) {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 + 1] <= TcGt) { // 条件式の長さが3トークンで、真ん中が比較演算子だったら.
! putIcX64("%R_8b_%2m0; %R_3b_%3m0; 0f_%0c_%1l;", (IntP) (AInt) condCode[(tc[j + 1] - TcEEq) ^ not], &var[label], &var[tc[j]], &var[tc[j + 2]]);
} else {
i = expr(i);
! putIcX64("%R_8b_%2m0; %R_85_c0; 0f_%0c_%1l;", (IntP) (AInt) (0x85 - not), &var[label], &var[i], 0);
tmpFree(i);
}
} tmpLabelNo = 0;
bd = lbd = 0;
+ toExit = tmpLabelAlloc();
for (pc = 0; pc < pc1; ) { // コンパイル開始. } else if (phrCmp( 5, "goto !!*0;", pc)) { // goto.
! putIcX64("e9_%0l;", &var[tc[wpc[0]]], 0, 0, 0); } else if (phrCmp(12, "} else {", pc) && binf[bd] == BlkIf) {
binf[bd + IfLabel1] = tmpLabelAlloc(); // else節の終端.
! putIcX64("e9_%0l;", &var[binf[bd + IfLabel1]], 0, 0, 0);
! defLabel(binf[bd + IfLabel0]); // ラベルに対応するicqを記録しておく.
} else if (phrCmp( 13, "}", pc) && binf[bd] == BlkIf) {
if (binf[bd + IfLabel1] == 0) {
! defLabel(binf[bd + IfLabel0]); // ラベルに対応するicqを記録しておく.
} else {
! defLabel(binf[bd + IfLabel1]); // ラベルに対応するicqを記録しておく.
}
bd -= BInfSiz;
} else if (phrCmp(14, "for (!!***0; !!***1; !!***2) {", pc)) { // for文
bd += BInfSiz;
binf[bd] = BlkFor; // ブロックのタイプ.
binf[bd + ForLopBgn] = tmpLabelAlloc(); // ループの頭に戻る用.
binf[bd + ForCont ] = tmpLabelAlloc(); // continue用.
binf[bd + ForBrk ] = tmpLabelAlloc(); // break用.
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]); // 最初から条件不成立ならbreakへ.
}
! defLabel(binf[bd + ForLopBgn]); // ラベルに対応するicqを記録しておく.
} else if (phrCmp(15, "}", pc) && binf[bd] == BlkFor) {
! defLabel(binf[bd + ForCont]); // ラベルに対応するicqを記録しておく.
i = binf[bd + ForWpc01];
j = binf[bd + ForWpc02];
if (i + 3 == binf[bd + ForWpc11] && j + 2 == binf[bd + ForWpc12] && tc[i] == tc[j] && tc[i + 1] == TcLt && tc[j + 1] == TcPlPlus) {
// !!***1が「i < ?」かつ、!!***2が「i++」だったら(変数名はiじゃなくてもいいけど、共通である必要がある).
! putIcX64("%R_8b_%1m0; %R_ff_c0; %R_89_%1m0; %R_3b_%2m0; 0f_8c_%0l;", &var[binf[bd + ForLopBgn]], &var[tc[i]], &var[tc[i + 2]], 0);
} 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 {
! putIcX64("e9_%0l;", &var[binf[bd + ForLopBgn]], 0, 0, 0);
}
}
! defLabel(binf[bd + ForBrk]); // ラベルに対応するicqを記録しておく.
lbd = binf[bd+ ForLbd0]; // 以前の値を復元.
bd -= BInfSiz;
} else if (phrCmp(16, "continue;", pc) && lbd > 0) {
! putIcX64("e9_%0l;", &var[binf[lbd + ForCont]], 0, 0, 0);
} else if (phrCmp(17, "break;", pc) && lbd > 0) {
! putIcX64("e9_%0l;", &var[binf[lbd + ForBrk ]], 0, 0, 0);! } else if (phrCmpPutIcX64(20, "prints !!**0;", pc, 0, 1, TcSubPrints, &e0)) { // prints.! } else if (phrCmpPutIcX64(23, "aSetPix0(!!***8, !!**0, !!**1, !!**2);", pc, 0, 3, TcSubSetPix0, &e0)) {
! } else if (phrCmpPutIcX64(24, "aWait(!!**0);", pc, 0, 1, TcSubWait, &e0)) {
+ putIcX64("%R_85_c0; 0f_85_%0l;", &var[toExit], 0, 0, 0);
! } else if (phrCmpPutIcX64(25, "aFillRect0(!!***8, !!**0, !!**1, !!**2, !!**3, !!**4);", pc, 0, 5, TcSubFilRct0, &e0)) {
! } else if (phrCmpPutIcX64(26, "aDrawStr0(!!***8, !!**0, !!**1, !!**2, !!**3, !!**4);", pc, 0, 5, TcSubDrwStr0, &e0)) {
! } else if (phrCmpPutIcX64(27, "gprintDec(!!***8, !!**0, !!**1, !!**2, !!**3, !!**4, !!**5);", pc, 0, 6, TcSubGprDec, &e0)) {
! } else if (phrCmpPutIcX64(28, "bitblt(!!***8, !!**0, !!**1, !!**2, !!**3, !!**4);", pc, 0, 5, TcSubBitBlt, &e0)) {
! } else if (phrCmpPutIcX64(29, "printTime();", pc, 0, 0, TcSubTime, &e0)) { // time;と同じ(C言語っぽく書けるようにした) if (bd > 0) {
printf("block nesting error (bd=%d, lbd=%d, pc=%d, pc1=%d\n", bd, lbd, pc, pc1);
return -1;
}
! defLabel(toExit);
dump1 = icq;
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;
for (i = 0; i < jp; i++) { // ジャンプ命令の最適化.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;
}| 32bit | 64bit | |
| gcc-O3 | 3.71秒 | 3.25秒 |
| HL-9a | 25.63秒 | 25.25秒 |
| HL-13 | 7.56秒 | |
| HL-19 | 6.54秒 |
| 0f_80_%l ~ 0f_8f_%l | 条件分岐命令。 | アセンブラではJcc命令 |
| %R_85_c0 | RAXを0と比較。 | アセンブラではTEST命令 |
単純代入:
(HL-9a) putIc (OpCpy, &var[tc[wpc[0]]], &var[tc[wpc[1]]], 0, 0);
(HL-19) putIcX64("%R_8b_%1m0; %R_89_%0m0;", &var[tc[wpc[0]]], &var[tc[wpc[1]]], 0, 0);
print命令:
(HL-9a) phrCmpPutIc ( 4, "print !!**0;", pc, 0, 1, OpPrint, &e0)
(HL-19) phrCmpPutIcX64( 4, "print !!**0;", pc, 0, 1, TcSubPrint, &e0)
+1する命令:
(HL-9a) putIc (OpAdd1, &var[tc[wpc[0]]], 0, 0, 0);
(HL-19) putIcX646("%R_8b_%0m0; %R_ff_c0; %R_89_%0m0;", &var[tc[wpc[0]]], 0, 0, 0);
各種二項演算子:
いずれも基本形は以下の通り
(HL-9a) putIc (op, &var[tc[wpc[0]]], &var[tc[wpc[1]]], &var[tc[wpc[3]]], 0);
(HL-19) putIcX64(op, &var[tc[wpc[0]]], &var[tc[wpc[1]]], &var[tc[wpc[3]]], 0);
演算子 (HL-9a) (HL-19)
+ OpAdd "%R_8b_%1m0; %R_03_%2m0; %R_89_%0m0;"
- OpSub "%R_8b_%1m0; %R_2b_%2m0; %R_89_%0m0;"
* OpMul "%R_8b_%1m0; %R_0f_af_%2m0; %R_89_%0m0;"
/ OpDiv "%R_8b_%1m0; %R_99; %R_f7_%2m7; %R_89_%0m0;"
% OpMod "%R_8b_%1m0; %R_99; %R_f7_%2m7; %R_89_%0m2;"
& OpAnd "%R_8b_%1m0; %R_23_%2m0; %R_89_%0m0;"
>> OpShr "%R_8b_%1m0; %R_8b_%2m1; %R_d3_f8; %R_89_%0m0;"
== OpCeq "%R_8b_%1m0; %R_3b_%2m0; 0f_94_c0; 0f_b6_c0; %R_89_%0m0;"
!= OpCne "%R_8b_%1m0; %R_3b_%2m0; 0f_95_c0; 0f_b6_c0; %R_89_%0m0;"
< OpClt "%R_8b_%1m0; %R_3b_%2m0; 0f_9c_c0; 0f_b6_c0; %R_89_%0m0;"
>= OpCge "%R_8b_%1m0; %R_3b_%2m0; 0f_9d_c0; 0f_b6_c0; %R_89_%0m0;"
<= OpCle "%R_8b_%1m0; %R_3b_%2m0; 0f_9e_c0; 0f_b6_c0; %R_89_%0m0;"
> OpCgt "%R_8b_%1m0; %R_3b_%2m0; 0f_9f_c0; 0f_b6_c0; %R_89_%0m0;"
ループ命令:
(HL-9a) putIc (OpLop, &var[tc[wpc[4]]], &var[tc[wpc[0]]], &var[tc[wpc[3]]], 0);
(HL-19) putIcX64("%R_8b_%1m0; %R_ff_c0; %R_89_%1m0; %R_3b_%2m0; 0f_8c_%0l;", &var[tc[wpc[4]]], &var[tc[wpc[0]]], &var[tc[wpc[3]]], 0);| コメント | お名前 | NameLink | |