修訂 | e22a783b2c4a38d213d4a7fc534ebbd0c8769cb3 (tree) |
---|---|
時間 | 2014-05-08 01:21:18 |
作者 | hikarupsp <hikarupsp@user...> |
Commiter | hikarupsp |
2014-05-04 (日) 12:08:08 のコメントでの自分の提案を実装してみた。
動作が同一であることは確認した。
@@ -13,10 +13,12 @@ int instrLengthExtend(const Int32 *src, const Int32 *src1) | ||
13 | 13 | return 0; |
14 | 14 | } |
15 | 15 | |
16 | -Int32 *hh4DecodeExtend(OsecpuJitc *jitc, Int32 opecode) | |
16 | +const char *instrTypesExtend(OsecpuJitc *jitc, Int32 opecode) | |
17 | 17 | // instrLengthSimpleInitTool()で登録していないものだけに反応すればよい. |
18 | 18 | { |
19 | - return jitc->dst; | |
19 | + char *retstr = NULL; | |
20 | + | |
21 | + return retstr; | |
20 | 22 | } |
21 | 23 | |
22 | 24 | int jitcStepExtend(OsecpuJitc *jitc) |
@@ -25,55 +25,18 @@ int instrLengthFloat(const Int32 *src, const Int32 *src1) | ||
25 | 25 | return retcode; |
26 | 26 | } |
27 | 27 | |
28 | -Int32 *hh4DecodeFloat(OsecpuJitc *jitc, Int32 opecode) | |
29 | -// instrLengthSimpleInitTool()で登録していないものだけに反応すればよい. | |
28 | +const char *instrTypesFloat(OsecpuJitc *jitc, Int32 opecode) | |
30 | 29 | { |
31 | - HH4Reader *hh4r = jitc->hh4r; | |
32 | - Int32 *dst = jitc->hh4dst, *dst1 = jitc->hh4dst1; | |
33 | - int i; | |
30 | + char *retstr = NULL; | |
34 | 31 | if (opecode == 0x40) { |
35 | - i = hh4GetUnsigned(hh4r); | |
36 | - if (i == 0) { | |
37 | - if (dst + 5 > dst1) | |
38 | - goto err; | |
39 | - *dst = opecode; | |
40 | - dst[1] = i; // imm-typ(0) | |
41 | - dst[2] = hh4GetSigned(hh4r); // imm | |
42 | - dst[3] = hh4GetUnsigned(hh4r); // f | |
43 | - dst[4] = hh4GetUnsigned(hh4r); // bit | |
44 | - dst += 5; | |
45 | - goto fin; | |
46 | - } | |
47 | - if (i == 1) { | |
48 | - if (dst + 5 > dst1) | |
49 | - goto err; | |
50 | - *dst = opecode; | |
51 | - dst[1] = i; // imm-typ(1) | |
52 | - dst[2] = hh4Get4Nbit(hh4r, 32 / 4); // imm | |
53 | - dst[3] = hh4GetUnsigned(hh4r); // f | |
54 | - dst[4] = hh4GetUnsigned(hh4r); // bit | |
55 | - dst += 5; | |
56 | - goto fin; | |
57 | - } | |
58 | - if (i == 2) { | |
59 | - if (dst + 6 > dst1) | |
60 | - goto err; | |
61 | - *dst = opecode; | |
62 | - dst[1] = i; // imm-typ(2) | |
63 | - dst[2] = hh4Get4Nbit(hh4r, 32 / 4); // imm-high | |
64 | - dst[3] = hh4Get4Nbit(hh4r, 32 / 4); // imm-low | |
65 | - dst[4] = hh4GetUnsigned(hh4r); // f | |
66 | - dst[5] = hh4GetUnsigned(hh4r); // bit | |
67 | - dst += 6; | |
68 | - goto fin; | |
69 | - } | |
32 | + // このhh4rで読み進めても元のhh4rは進まない | |
33 | + HH4Reader hh4r = *jitc->hh4r; | |
34 | + Int32 mod = hh4GetUnsigned(&hh4r); | |
35 | + if (mod == 0) retstr = "usuu"; // 40, imm-typ(0), imm, f, bit. | |
36 | + if (mod == 1) retstr = "ufuu"; // 40, imm-typ(1), imm-f32, f, bit. | |
37 | + if (mod == 2) retstr = "uduu"; // 40, imm-typ(2), imm-f64, f, bit. | |
70 | 38 | } |
71 | -fin: | |
72 | - jitc->dst = dst; | |
73 | - return dst; | |
74 | -err: | |
75 | - jitc->errorCode = JITC_HH4_DST_OVERRUN; | |
76 | - return dst; | |
39 | + return retstr; | |
77 | 40 | } |
78 | 41 | |
79 | 42 | void jitcStep_checkFxx(int *pRC, int fxx) |
@@ -82,44 +82,92 @@ Int32 hh4Get4Nbit(HH4Reader *hh4r, int n) | ||
82 | 82 | |
83 | 83 | Int32 *hh4Decode(OsecpuJitc *jitc) |
84 | 84 | { |
85 | + // hh4バイナリを内部形式に変換する | |
86 | + // instrLengthSimpleに登録されている命令の引数はすべてunsignedとして扱う | |
87 | + // そうでない場合はそれぞれのinstrTypesから得られる文字列を元にデコードする | |
88 | + // instrTypesの書式: | |
89 | + // u: hh4GetUnsigned | |
90 | + // s: hh4GetSigned | |
91 | + // f: hh4Get4Nbit (float) | |
92 | + // d: hh4Get4Nbit, hh4Get4Nbit (double) | |
85 | 93 | HH4Reader *hh4r = jitc->hh4r; |
86 | 94 | Int32 *dst = jitc->hh4dst, *dst1 = jitc->hh4dst1; |
87 | 95 | |
88 | 96 | jitc->errorCode = 0; |
89 | 97 | for (;;) { |
90 | - if (hh4r->p >= hh4r->p1) | |
98 | + if (hh4r->p >= hh4r->p1){ | |
99 | + // 読み込みが末端を超えた | |
91 | 100 | break; |
92 | - if (hh4r->errorCode != 0) | |
93 | - goto err1; | |
101 | + } | |
102 | + if (hh4r->errorCode != 0){ | |
103 | + // hh4エラー | |
104 | + goto err_hh4_too_long_bit; | |
105 | + } | |
94 | 106 | Int32 opecode = hh4GetUnsigned(hh4r); |
95 | 107 | int len = instrLengthSimple(opecode), i; |
96 | 108 | if (len > 0) { |
97 | - if (dst + len > dst1) | |
98 | - goto err; | |
109 | + // すべてunsignedな引数 | |
110 | + if (dst + len > dst1){ | |
111 | + goto err_write_overrun; | |
112 | + } | |
99 | 113 | *dst = opecode; |
100 | - for (i = 1; i < len; i++) | |
114 | + for (i = 1; i < len; i++){ | |
101 | 115 | dst[i] = hh4GetUnsigned(hh4r); |
116 | + } | |
102 | 117 | dst += len; |
118 | + // 次の命令へ | |
103 | 119 | continue; |
104 | 120 | } |
105 | - jitc->hh4dst = dst; | |
106 | - dst = hh4DecodeInteger(jitc, opecode); | |
107 | - if (dst != jitc->hh4dst) continue; // 何か処理できたようなので次へ. | |
108 | - dst = hh4DecodePointer(jitc, opecode); | |
109 | - if (dst != jitc->hh4dst) continue; | |
110 | - dst = hh4DecodeFloat(jitc, opecode); | |
111 | - if (dst != jitc->hh4dst) continue; | |
112 | - dst = hh4DecodeExtend(jitc, opecode); | |
113 | - if (dst != jitc->hh4dst) continue; | |
114 | - | |
121 | + // 複雑な引数を持つ命令かも…instrTypesを確認 | |
122 | + const char *instrTypes = NULL; | |
123 | + instrTypes = instrTypesInteger(jitc, opecode); | |
124 | + if(instrTypes) goto read_args; | |
125 | + instrTypes = instrTypesFloat(jitc, opecode); | |
126 | + if(instrTypes) goto read_args; | |
127 | + | |
128 | +internal_error: | |
129 | + // どうやら命令番号ではないみたい | |
115 | 130 | fprintf(stderr, "Error: hh4Decode: opecode=0x%02X\n", opecode); // 内部エラー. |
116 | 131 | exit(1); |
132 | + | |
133 | +read_args: | |
134 | + // 複雑な引数を持つ命令を読み込む | |
135 | + *dst = opecode; | |
136 | + dst++; | |
137 | + for(; *instrTypes != '\0'; instrTypes++){ | |
138 | + if(dst >= dst1){ | |
139 | + // 1バイト共通チェック | |
140 | + goto err_write_overrun; | |
141 | + } | |
142 | + if(*instrTypes == 'u'){ | |
143 | + dst[0] = hh4GetUnsigned(hh4r); | |
144 | + dst++; | |
145 | + } else if(*instrTypes == 's'){ | |
146 | + dst[0] = hh4GetSigned(hh4r); | |
147 | + dst++; | |
148 | + } else if(*instrTypes == 'f'){ | |
149 | + dst[0] = hh4Get4Nbit(hh4r, 32 / 4); | |
150 | + dst++; | |
151 | + } else if(*instrTypes == 'd'){ | |
152 | + if(dst + 2 > dst1){ | |
153 | + // 2バイトチェック | |
154 | + goto err_write_overrun; | |
155 | + } | |
156 | + dst[0] = hh4Get4Nbit(hh4r, 32 / 4); | |
157 | + dst[1] = hh4Get4Nbit(hh4r, 32 / 4); | |
158 | + dst += 2; | |
159 | + } else{ | |
160 | + // 存在しない引数タイプなので内部エラー | |
161 | + goto internal_error; | |
162 | + } | |
163 | + } | |
164 | + // 次の命令へ... | |
117 | 165 | } |
118 | 166 | return dst; |
119 | -err: | |
167 | +err_write_overrun: | |
120 | 168 | jitc->errorCode = JITC_HH4_DST_OVERRUN; |
121 | 169 | return dst; |
122 | -err1: | |
170 | +err_hh4_too_long_bit: | |
123 | 171 | jitc->errorCode = JITC_HH4_BITLENGTH_OVER; |
124 | 172 | return dst; |
125 | 173 | } |
@@ -25,39 +25,12 @@ int instrLengthInteger(const Int32 *src, const Int32 *src1) | ||
25 | 25 | return retcode; |
26 | 26 | } |
27 | 27 | |
28 | -Int32 *hh4DecodeInteger(OsecpuJitc *jitc, Int32 opecode) | |
29 | -// instrLengthSimpleInitTool()で登録していないものだけに反応すればよい. | |
28 | +const char *instrTypesInteger(OsecpuJitc *jitc, Int32 opecode) | |
30 | 29 | { |
31 | - HH4Reader *hh4r = jitc->hh4r; | |
32 | - Int32 *dst = jitc->hh4dst, *dst1 = jitc->hh4dst1; | |
33 | - int i, v; | |
34 | - if (opecode == 0x02) { | |
35 | - if (dst + 4 > dst1) | |
36 | - goto err; | |
37 | - *dst = opecode; | |
38 | - dst[1] = hh4GetSigned(hh4r); | |
39 | - dst[2] = hh4GetUnsigned(hh4r); | |
40 | - dst[3] = hh4GetUnsigned(hh4r); | |
41 | - dst += 4; | |
42 | - goto fin; | |
43 | - } | |
44 | - if (opecode == 0xfd) { | |
45 | - if (dst + 3 > dst1) | |
46 | - goto err; | |
47 | - *dst = opecode; | |
48 | - dst[1] = v = hh4GetUnsigned(hh4r); | |
49 | - dst[2] = i = hh4GetUnsigned(hh4r); | |
50 | - if (0 <= i && i <= 3) | |
51 | - jitc->dr[i] = v; | |
52 | - dst += 3; | |
53 | - goto fin; | |
54 | - } | |
55 | -fin: | |
56 | - jitc->dst = dst; | |
57 | - return dst; | |
58 | -err: | |
59 | - jitc->errorCode = JITC_HH4_DST_OVERRUN; | |
60 | - return dst; | |
30 | + char *retstr = NULL; | |
31 | + if (opecode == 0x02) retstr = "suu"; | |
32 | + if (opecode == 0xfd) retstr = "uu"; | |
33 | + return retstr; | |
61 | 34 | } |
62 | 35 | |
63 | 36 | int jitcStepInteger(OsecpuJitc *jitc) |
@@ -108,28 +108,28 @@ unsigned char *hh4StrToBin(char *src, char *src1, unsigned char *dst, unsigned c | ||
108 | 108 | // integer.c : 整数命令 |
109 | 109 | void osecpuInitInteger(); |
110 | 110 | int instrLengthInteger(const Int32 *src, const Int32 *src1); |
111 | -Int32 *hh4DecodeInteger(OsecpuJitc *jitc, Int32 opecode); | |
111 | +const char *instrTypesInteger(OsecpuJitc *jitc, Int32 opecode); | |
112 | 112 | int jitcStepInteger(OsecpuJitc *jitc); |
113 | 113 | void execStepInteger(OsecpuVm *vm); |
114 | 114 | |
115 | 115 | // pointer.c : ポインタ命令 |
116 | 116 | void osecpuInitPointer(); |
117 | 117 | int instrLengthPointer(const Int32 *src, const Int32 *src1); |
118 | -Int32 *hh4DecodePointer(OsecpuJitc *jitc, Int32 opecode); | |
118 | +const char *instrTypesPointer(OsecpuJitc *jitc, Int32 opecode); | |
119 | 119 | int jitcStepPointer(OsecpuJitc *jitc); |
120 | 120 | void execStepPointer(OsecpuVm *vm); |
121 | 121 | |
122 | 122 | // float.c : 浮動小数点命令 |
123 | 123 | void osecpuInitFloat(); |
124 | 124 | int instrLengthFloat(const Int32 *src, const Int32 *src1); |
125 | -Int32 *hh4DecodeFloat(OsecpuJitc *jitc, Int32 opecode); | |
125 | +const char *instrTypesFloat(OsecpuJitc *jitc, Int32 opecode); | |
126 | 126 | int jitcStepFloat(OsecpuJitc *jitc); |
127 | 127 | void execStepFloat(OsecpuVm *vm); |
128 | 128 | |
129 | 129 | // extend.c : 拡張命令関係. |
130 | 130 | void osecpuInitExtend(); |
131 | 131 | int instrLengthExtend(const Int32 *src, const Int32 *src1); |
132 | -Int32 *hh4DecodeExtend(OsecpuJitc *jitc, Int32 opecode); | |
132 | +const char *instrTypesExtend(OsecpuJitc *jitc, Int32 opecode); | |
133 | 133 | int jitcStepExtend(OsecpuJitc *jitc); |
134 | 134 | void execStepExtend(OsecpuVm *vm); |
135 | 135 |
@@ -19,17 +19,11 @@ int instrLengthPointer(const Int32 *src, const Int32 *src1) | ||
19 | 19 | return retcode; |
20 | 20 | } |
21 | 21 | |
22 | -Int32 *hh4DecodePointer(OsecpuJitc *jitc, Int32 opecode) | |
23 | -// instrLengthSimpleInitTool()で登録していないものだけに反応すればよい. | |
22 | +const char *instrTypesPointer(OsecpuJitc *jitc, Int32 opecode) | |
24 | 23 | { |
25 | - HH4Reader *hh4r = jitc->hh4r; | |
26 | - Int32 *dst = jitc->hh4dst, *dst1 = jitc->hh4dst1; | |
27 | -fin: | |
28 | - jitc->dst = dst; | |
29 | - return dst; | |
30 | -err: | |
31 | - jitc->errorCode = JITC_HH4_DST_OVERRUN; | |
32 | - return dst; | |
24 | + char *retstr = NULL; | |
25 | + | |
26 | + return retstr; | |
33 | 27 | } |
34 | 28 | |
35 | 29 | void jitcStep_checkPxx(int *pRC, int pxx) |