OSDN Git Service

コメント付加
authorttwilb <ttwilb@users.sourceforge.jp>
Mon, 10 Mar 2014 07:29:32 +0000 (16:29 +0900)
committerttwilb <ttwilb@users.sourceforge.jp>
Mon, 10 Mar 2014 07:29:32 +0000 (16:29 +0900)
jitc.c
main.c
osecpu.h

diff --git a/jitc.c b/jitc.c
index 98c4ec8..ffb9370 100644 (file)
--- a/jitc.c
+++ b/jitc.c
@@ -63,7 +63,7 @@ struct JitCompWork {
 #if (jitCompA0001_USE_R3F_IMM32 != 0)
        int r3f;
 #endif
-       char prefix;
+       char prefix;    //CND命令の値を記録(初期値=0)
 };
 
 #define        jitCompPutByte1(p, c0)                          *p++ = c0
@@ -304,6 +304,13 @@ void funcf7(char *ebp, int pxx, int typ, int len); // typとlenはダミーで
 
 void errHndl(struct Regs *r);
 
+/*
+ * dst : 現在の書き込みアドレス。
+ * dst1 : 書き込みアドレスの最大値
+ * src : 現在の読み込みアドレス(ヘッダ部は飛ばしてある
+ * src1 : 読み込みアドレスの最大値
+ * src0 : 読み込みバイナリのアドレス
+ */
 int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *src, const unsigned char *src1, const unsigned char *src0, struct LabelTable *label, int maxLabels, int level, int debugInfo1, int flags)
 /* IA-32用 */
 /* 本来ならこのレイヤでは文法チェックしない */
@@ -316,6 +323,7 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
        w.dst = w.dst0 = dst;
        w.err = 0;
        w.maxLabels = maxLabels;
+
        if ((flags & JITC_NOSTARTUP) == 0) {
                jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */
                jitCompA000_loadRegCacheAll(&w); /* start-up */
@@ -329,30 +337,44 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */
        }
        while (src < src1) {
-               w.prefix = 0;
-               if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; goto err_w; }
+               w.prefix = 0;   //0x04 CND 命令で変更される
+               if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; goto err_w; }  // 書き込み領域が残り256バイト未満ならエラー
                timecount++;
                if (timecount >= 64) {
                        timecount -= 64;
                        /* 未完成(timeoutチェックコードを入れる) */
                }
-       prefix_continue:
+       prefix_continue:        // CND命令実行後ここに戻る
                switch (*src) {
 
                case 0x00:      /* NOP */
-                       if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }
+                       if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }     // 「条件付きでNOPを実行」するなんて、矛盾している!
                        break;
 
                case 0x01:      /* LB */
-                       if (enter0 == NULL && (src[6] == 0x3c || (src[6] == 0xfe && src[7] == 0x01 && src[9] == 0x3c))) {
-                               jitCompPutByte1(w.dst, 0xe9);
+                       
+                       /*
+                        * LB : ラベル設置命令。(6byte)
+                        * ・prefex = 1にする
+                        * ・timecount++し、timecountのチェックをする。
+                        * ・ラベル位置を登録する。
+                        * ・割り込みがある場合、このタイミングで割り込みを発生させる。
+                        *
+                        *  1   2       3       456
+                        *      LB      01      opt     imm32
+                        *
+                        */
+                       
+                       if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) {       //beginFunc()中のLB
+                               // LB命令の後に0x3C命令・・・beginFunc()
+                               jitCompPutByte1(w.dst, 0xe9);   // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする
                                enter0 = w.dst;
-                               jitCompPutImm32(&w, 0);
+                               jitCompPutImm32(&w, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ??
                        }
-                       if (src[6] == 0x34) {
+                       if (src[6] == 0x34) {   // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令
                                tmp_ucp = w.dst;
-                               jitCompPutByte1(w.dst, 0xe9);
-                               i = jitCompGetImm32(&src[7]);
+                               jitCompPutByte1(w.dst, 0xe9);   // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする
+                               i = jitCompGetImm32(&src[7]);   // type32 を取得
                                j = 32;
                                if (i != 1) {
                                        i = jitCompA000_convTyp(i);
@@ -409,16 +431,30 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                        /* 未完成(timeoutチェックコードを入れる) */
                        break;
 
-               case 0x02:      /* LIMM */
-                       if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX;
+               case 0x02:      /* LIMM */      
+                       
+                       /*
+                        * LIMM : 定数即値代入命令(6byte)
+                        * 
+                        *      1       2               3456
+                        *      02      reg0R   imm32
+                        *
+                        * ・reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。
+                        */
+                       
+                       if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX;   // CND命令の直後でR3Fを書き換えるなんて変だよね
+
 #if (jitCompA0001_USE_R3F_IMM32 != 0)
-                       if (src[1] == 0x3f) {
+                       if (src[1] == 0x3f) {           // R3Fへの代入は例外敵に、 w.r3f を使用
                                w.r3f = jitCompGetImm32(src + 2);
                                break;
                        }
 #endif
-                       i = jitCompGetImm32(src + 2);
+                       i = jitCompGetImm32(src + 2);   // 与えられた即値(第二引数)を取得
+
+                       /* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */
                        reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
+
 #if (jitCompA0001_OPTIMIZE_MOV != 0)
                        if (i == 0) {
                                jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0);  /* XOR(reg0, reg0); */
@@ -426,32 +462,58 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                                break;
                        }
 #endif
-                       jitCompPutByte1(w.dst, 0xb8 | reg0);    /* MOV(reg0, ?); */
+                       
+                       /* reg0 のレジスタに対応したMOV命令を発行 */
+                       jitCompPutByte1(w.dst, 0xb8 | reg0);    /* MOV(reg0, ?);  == 10111000b+wr imm32 */
                        jitCompPutImm32(&w, i);
-                       if (reg0 == 0)
+
+                       if (reg0 == 0)  // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合
+                               
                                jitCompA0001_movRxxEax(&w, src[1]);
                        break;
 
                case 0x03:      /* PLIMM */     /* 未完成(plsまで対応) */
-                       i = jitCompGetLabelNum(&w, src + 2);
-                       if ((flags & JITC_PHASE1) != 0 && w.err == 0) {
-                               if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; }
-                               if (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; }
-                               if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; }
+
+                       /*
+                       * PLIMM : ラベル番号代入命令(6byte)
+                       *
+                       *       1       2       3456
+                       *       03      PXX     imm32
+                       *
+                       * ・P28 はAPI用
+                       * ・P3F はプログラムカウンタ
+                       */
+
+                       i = jitCompGetLabelNum(&w, src + 2);    // Pxxに代入するラベルの番号(第二引数)
+                       if ((flags & JITC_PHASE1) != 0 && w.err == 0) { // Phase 1であるならば
+                               if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; }             // 指定されたラベル番号は存在しない
+                               if (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; }     // 
+                               if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; } // プログラムカウンタに TYP_CODEでない値は代入できない
                        }
-                       if (src[1] == 0x3f) {
-                               if (w.prefix == 0) {
+                       if (src[1] == 0x3f) {   // プログラムカウンタへの代入なら
+                               if (w.prefix == 0) {    // CND命令による条件付きでなければ、即座に移動
                                        jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */
                                }
-                               else {
+                               else {  // 直前はCND命令。
+                                       
+                                       /*
+                                        * CND命令
+                                        *      1       2       
+                                        *      04      reg0R
+                                        *
+                                        * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd
+                                        */
+
+                                        // JZのとび先アドレスの書き換え?
                                        w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */
                                        w.dst[-2] = 0x0f;
+
                                        w.prefix = 0;
                                }
                                j = 0;
-                               if ((flags & JITC_PHASE1) != 0 || ((flags & JITC_PHASE1) == 0) && label[i].opt != 0)
-                                       j = label[i].p - (w.dst + 4);
-                               jitCompPutImm32(&w, j);
+                               if ((flags & JITC_PHASE1) != 0 || ((flags & JITC_PHASE1) == 0) && label[i].opt != 0)    // label番号iが確保されていれば (このif文は意味をなさない)
+                                       j = label[i].p - (w.dst + 4);   // j はとび先の相対番地 
+                               jitCompPutImm32(&w, j); // JMP もしくは JZ 命令のアドレス部を記述
 #if (jitCompA0001_OPTIMIZE_JMP != 0)
                                if (-128 - 3 <= j && j < 0) {
                                        if (w.dst[-5] == 0xe9) {
@@ -468,12 +530,17 @@ int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *sr
                                }
 #endif
                        }
-                       else {
+                       else {  // プログラムカウンタ以外への代入
+                               
+                               // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定
                                reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */);
                                jitCompPutByte1(w.dst, 0xb8 | reg0);    /* MOV(reg0, ?); */
-                               jitCompPutImm32(&w, (int)label[i].p);
+                               jitCompPutImm32(&w, (int)label[i].p);   // ラベルのパスを各レジスタに代入
+
+                               // レジスタへの代入をメモリでエミュレーションする場合は、スタックに積む。
                                if (reg0 == 0)
                                        jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32, 0); /* MOV([EBP+?], EAX); */
+
                                if (level < JITC_LV_FASTEST) {
                                        jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 8, reg0); /* MOV([EBP+?], reg0); */ /* p0 */
                                        jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
@@ -1547,6 +1614,8 @@ void errHndl(struct Regs *r)
 }
 
 /*
+ * jitcの出力コードをひとまとめにする関数を作成しその中身をjitCompile()で生成
+ *
  * qq : 出力バイナリの書き込み位置のアドレスへの参照(書き込み位置を呼び出しに反映させるため参照渡しにする)
  * q1 : 出力バイナリの書き込み位置のアドレスの最大値
  * p0 : (*.ose)バイナリの読み込み位置のアドレス(ヘッダ部除去済)
@@ -1568,6 +1637,7 @@ int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const
        for (i = 0; i < JITC_MAXLABELS; i++)
                label[i].opt = 0;
 
+       // 以下のjitCompile()呼び出しでは第二引数をq1-2にした方がよいのではないか?
        i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, 0);
        if (i != 0) return 2;
        i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, JITC_PHASE1 + 0);
diff --git a/main.c b/main.c
index 20869ed..4b17520 100644 (file)
--- a/main.c
+++ b/main.c
@@ -76,6 +76,10 @@ int osecpuMain(int argc, char **argv)
                syslib[1] = 0x1b;
        }
 
+       FILE *fp2 = fopen("syslib_dbg.ose", "wb");
+       fwrite(syslib, 1, SYSLIBSIZ1, fp2);
+       fclose(fp2);
+
        // jutc.cのerrHndl()をCALLするネィティブコードを挿入。
        // sysjitの値は次の書き込み位置へずらされる。
        // 元々のsysjitはsysjit00へ保存されている。
index a38c77f..38925f0 100644 (file)
--- a/osecpu.h
+++ b/osecpu.h
@@ -31,7 +31,14 @@ struct Ptr { /* 32バイト(=256bit!) */
 
 struct LabelTable {
        unsigned char *p, *p1;
-       int opt, typ;
+       int opt;
+       
+       /*
+        * default = -1
+        * TYP_CODE = 0
+        * T_UINT8 = 3
+        */
+       int typ;
 };
 
 struct Regs {