Revisión | 7f45df1bd32716f08f1392326b36dbe5bcd6254f (tree) |
---|---|
Tiempo | 2014-05-14 20:06:38 |
Autor | hikarupsp <hikarupsp@user...> |
Commiter | hikarupsp |
osecpu105a
@@ -23,7 +23,7 @@ void jitcStep_checkFxxNotF3F(int *pRC, int fxx) | ||
23 | 23 | |
24 | 24 | void jitcStep_checkBitsF(int *pRC, int bit) |
25 | 25 | { |
26 | - if (bit != 32 && bit != 64) | |
26 | + if (bit != 0 && bit != 32 && bit != 64) | |
27 | 27 | jitcSetRetCode(pRC, JITC_BAD_BITS); |
28 | 28 | return; |
29 | 29 | } |
@@ -44,7 +44,9 @@ int jitcStepFloat(OsecpuJitc *jitc) | ||
44 | 44 | f = ip[3]; bit = ip[4]; |
45 | 45 | jitcStep_checkBitsF(pRC, bit); |
46 | 46 | jitcStep_checkFxx(pRC, f); |
47 | - } else if (ip[1] == 1) { | |
47 | + goto fin; | |
48 | + } | |
49 | + if (ip[1] == 1) { | |
48 | 50 | ip[2] = hh4ReaderGet4Nbit(&jitc->hh4r, 32 / 4); // imm |
49 | 51 | ip[3] = hh4ReaderGetUnsigned(&jitc->hh4r); // f |
50 | 52 | ip[4] = hh4ReaderGetUnsigned(&jitc->hh4r); // bit |
@@ -52,7 +54,9 @@ int jitcStepFloat(OsecpuJitc *jitc) | ||
52 | 54 | f = ip[3]; bit = ip[4]; |
53 | 55 | jitcStep_checkBitsF(pRC, bit); |
54 | 56 | jitcStep_checkFxx(pRC, f); |
55 | - } else if (ip[1] == 2) { | |
57 | + goto fin; | |
58 | + } | |
59 | + if (ip[1] == 2) { | |
56 | 60 | ip[2] = hh4ReaderGet4Nbit(&jitc->hh4r, 32 / 4); // imm-high |
57 | 61 | ip[3] = hh4ReaderGet4Nbit(&jitc->hh4r, 32 / 4); // imm-low |
58 | 62 | ip[4] = hh4ReaderGetUnsigned(&jitc->hh4r); // f |
@@ -61,8 +65,9 @@ int jitcStepFloat(OsecpuJitc *jitc) | ||
61 | 65 | f = ip[4]; bit = ip[5]; |
62 | 66 | jitcStep_checkBitsF(pRC, bit); |
63 | 67 | jitcStep_checkFxx(pRC, f); |
64 | - } else | |
65 | - jitcSetRetCode(pRC, JITC_BAD_FLIMM_MODE); | |
68 | + goto fin; | |
69 | + } | |
70 | + jitcSetRetCode(pRC, JITC_BAD_FLIMM_MODE); | |
66 | 71 | goto fin; |
67 | 72 | } |
68 | 73 | if (opecode == 0x41) { // FCP |
@@ -205,18 +210,12 @@ void execStepFloat(OsecpuVm *vm) | ||
205 | 210 | jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS); |
206 | 211 | goto fin; |
207 | 212 | } |
208 | - if (opecode == 0x48) | |
209 | - i = vm->f[f1] == vm->f[f2]; | |
210 | - if (opecode == 0x49) | |
211 | - i = vm->f[f1] != vm->f[f2]; | |
212 | - if (opecode == 0x4a) | |
213 | - i = vm->f[f1] < vm->f[f2]; | |
214 | - if (opecode == 0x4b) | |
215 | - i = vm->f[f1] >= vm->f[f2]; | |
216 | - if (opecode == 0x4c) | |
217 | - i = vm->f[f1] <= vm->f[f2]; | |
218 | - if (opecode == 0x4d) | |
219 | - i = vm->f[f1] > vm->f[f2]; | |
213 | + if (opecode == 0x48) i = vm->f[f1] == vm->f[f2]; | |
214 | + if (opecode == 0x49) i = vm->f[f1] != vm->f[f2]; | |
215 | + if (opecode == 0x4a) i = vm->f[f1] < vm->f[f2]; | |
216 | + if (opecode == 0x4b) i = vm->f[f1] >= vm->f[f2]; | |
217 | + if (opecode == 0x4c) i = vm->f[f1] <= vm->f[f2]; | |
218 | + if (opecode == 0x4d) i = vm->f[f1] > vm->f[f2]; | |
220 | 219 | if (i != 0) |
221 | 220 | i = -1; |
222 | 221 | vm->r[r] = i; |
@@ -230,14 +229,10 @@ void execStepFloat(OsecpuVm *vm) | ||
230 | 229 | jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS); |
231 | 230 | goto fin; |
232 | 231 | } |
233 | - if (opecode == 0x50) | |
234 | - vm->f[f0] = vm->f[f1] + vm->f[f2]; | |
235 | - if (opecode == 0x51) | |
236 | - vm->f[f0] = vm->f[f1] - vm->f[f2]; | |
237 | - if (opecode == 0x52) | |
238 | - vm->f[f0] = vm->f[f1] * vm->f[f2]; | |
239 | - if (opecode == 0x53) | |
240 | - vm->f[f0] = vm->f[f1] / vm->f[f2]; | |
232 | + if (opecode == 0x50) vm->f[f0] = vm->f[f1] + vm->f[f2]; | |
233 | + if (opecode == 0x51) vm->f[f0] = vm->f[f1] - vm->f[f2]; | |
234 | + if (opecode == 0x52) vm->f[f0] = vm->f[f1] * vm->f[f2]; | |
235 | + if (opecode == 0x53) vm->f[f0] = vm->f[f1] / vm->f[f2]; | |
241 | 236 | vm->bitF[f0] = bit; |
242 | 237 | ip += 5; |
243 | 238 | goto fin; |
@@ -1,3 +1,7 @@ | ||
1 | +参考資料: | |
2 | + page0072 : バックエンド命令セットの仕様 | |
3 | + page0078 : bitについての説明 | |
4 | + | |
1 | 5 | 2014.05.01木: |
2 | 6 | ソースはTAB=4想定で書いています |
3 | 7 |
@@ -19,4 +23,8 @@ | ||
19 | 23 | 0は「未設定」や「初期化済み」や「未使用」などを意味する |
20 | 24 | gotoを結構よく使っているのは、インデントがむやみに深くなるのを避けるため。 |
21 | 25 | |
26 | +2014.05.08木: | |
27 | + OSECPU-VMではfloatの精度は32bitまでを保証する。 | |
28 | + 倍精度である64bitをサポートするかは処理系依存。 | |
29 | + floatのサポートそのものがない場合も許す。 | |
22 | 30 |
@@ -109,6 +109,44 @@ Int32 hh4ReaderGet4Nbit(Hh4Reader *hh4r, int n) | ||
109 | 109 | return value; |
110 | 110 | } |
111 | 111 | |
112 | +// bitReader関係. | |
113 | + | |
114 | +void bitReaderInit(BitReader *br, Hh4Reader *hh4r) | |
115 | +{ | |
116 | + br->hh4r = hh4r; | |
117 | + br->bitBuf = 0; | |
118 | + br->bufLen = 0; | |
119 | + return; | |
120 | +} | |
121 | + | |
122 | +int bitReaderGet(BitReader *br) | |
123 | +{ | |
124 | + int b; | |
125 | + if (br->bufLen <= 0) { | |
126 | + br->bitBuf = hh4ReaderGet4bit(br->hh4r); | |
127 | + br->bufLen = 4; | |
128 | + } | |
129 | + br->bufLen--; | |
130 | + b = (br->bitBuf >> br->bufLen) & 1; | |
131 | + return b; | |
132 | +} | |
133 | + | |
134 | +int bitReaderGetNbitUnsigned(BitReader *br, int n) | |
135 | +{ | |
136 | + int i, value = 0; | |
137 | + for (i = 0; i < n; i++) | |
138 | + value = value << 1 | bitReaderGet(br); | |
139 | + return value; | |
140 | +} | |
141 | + | |
142 | +int bitReaderGetNbitSigned(BitReader *br, int n) | |
143 | +{ | |
144 | + int value = bitReaderGetNbitUnsigned(br, n); | |
145 | + if (n <= 31 && ((value >> (n - 1)) & 1) != 0) | |
146 | + value |= -1 << n; | |
147 | + return value; | |
148 | +} | |
149 | + | |
112 | 150 | // jitc関係. |
113 | 151 | |
114 | 152 | void jitcInitDstLogSetPhase(OsecpuJitc *jitc, int phase) |
@@ -176,6 +214,7 @@ int jitcAll(OsecpuJitc *jitc) | ||
176 | 214 | { |
177 | 215 | Hh4ReaderPointer src0 = jitc->hh4r.p; |
178 | 216 | Int32 *dst0 = jitc->dst; |
217 | + definesInit(jitc->defines); | |
179 | 218 | jitcInitDstLogSetPhase(jitc, 0); |
180 | 219 | for (;;) { |
181 | 220 | // 理想は適当な上限を決めて、休み休みでやるべきかもしれない. |
@@ -224,10 +263,10 @@ int execStep(OsecpuVm *vm) | ||
224 | 263 | { |
225 | 264 | const Int32 *ip = vm->ip; |
226 | 265 | vm->errorCode = 0; |
227 | - execStepInteger(vm); if (ip != vm->ip) goto fin; | |
228 | - execStepPointer(vm); if (ip != vm->ip) goto fin; | |
229 | - execStepFloat(vm); if (ip != vm->ip) goto fin; | |
230 | - execStepExtend(vm); if (ip != vm->ip) goto fin; | |
266 | + execStepInteger(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin; | |
267 | + execStepPointer(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin; | |
268 | + execStepFloat(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin; | |
269 | + execStepExtend(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin; | |
231 | 270 | if (*ip == -1) { |
232 | 271 | vm->errorCode = EXEC_ABORT_OPECODE_M1; // デバッグ用. |
233 | 272 | goto fin; |
@@ -30,6 +30,11 @@ typedef struct _Hh4Reader { | ||
30 | 30 | int length, errorCode; |
31 | 31 | } Hh4Reader; |
32 | 32 | |
33 | +typedef struct _BitReader { | |
34 | + Hh4Reader *hh4r; | |
35 | + int bitBuf, bufLen; | |
36 | +} BitReader; | |
37 | + | |
33 | 38 | #define JITC_DSTLOG_SIZE 16 |
34 | 39 | |
35 | 40 | typedef struct _OsecpuJitc { |
@@ -68,6 +73,11 @@ Int32 hh4ReaderGetUnsigned(Hh4Reader *hh4r); | ||
68 | 73 | Int32 hh4ReaderGetSigned(Hh4Reader *hh4r); |
69 | 74 | Int32 hh4ReaderGet4Nbit(Hh4Reader *hh4r, int n); |
70 | 75 | |
76 | +void bitReaderInit(BitReader *br, Hh4Reader *hh4r); | |
77 | +int bitReaderGet(BitReader *br); | |
78 | +int bitReaderGetNbitUnsigned(BitReader *br, int n); | |
79 | +int bitReaderGetNbitSigned(BitReader *br, int n); | |
80 | + | |
71 | 81 | void jitcInitDstLogSetPhase(OsecpuJitc *jitc, int phase); |
72 | 82 | void jitcSetRetCode(int *pRC, int value); |
73 | 83 | void jitcSetHh4BufferSimple(OsecpuJitc *jitc, int length); |
@@ -89,6 +99,7 @@ int jitcAll(OsecpuJitc *jitc); | ||
89 | 99 | #define JITC_LABEL_REDEFINED 13 |
90 | 100 | #define JITC_BAD_LABEL_TYPE 14 |
91 | 101 | #define JITC_LABEL_UNDEFINED 15 |
102 | +#define JITC_BAD_TYPE 16 | |
92 | 103 | |
93 | 104 | void jitcStep_checkBits32(int *pRC, int bits); |
94 | 105 | void jitcStep_checkRxx(int *pRC, int rxx); |
@@ -14,12 +14,27 @@ void jitcStep_checkPxx(int *pRC, int pxx) | ||
14 | 14 | return; |
15 | 15 | } |
16 | 16 | |
17 | +void getTypSize(int typ, int *typSize0, int *typSize1, int *typSign) | |
18 | +{ | |
19 | + *typSize0 = *typSize1 = -1; | |
20 | + if (2 <= typ && typ <= 21) { | |
21 | + static unsigned char table[10] = { 8, 16, 32, 4, 2, 1, 12, 20, 24, 28 }; | |
22 | + if ((typ & 1) == 0) | |
23 | + *typSign = -1; // typが偶数なら符号あり. | |
24 | + else | |
25 | + *typSign = 0; // typが奇数なら符号なし. | |
26 | + *typSize0 = table[(typ - 2) / 2]; | |
27 | + *typSize1 = (*typSize0 + 7) / 8; | |
28 | + } | |
29 | + return; | |
30 | +} | |
31 | + | |
17 | 32 | int jitcStepPointer(OsecpuJitc *jitc) |
18 | 33 | { |
19 | 34 | Int32 *ip = jitc->hh4Buffer; |
20 | 35 | Int32 opecode = ip[0], imm; |
21 | 36 | int retcode = -1, *pRC = &retcode; |
22 | - int i, opt, p; | |
37 | + int i, j, opt, p, typ, len, typSign, typSize0, typSize1; | |
23 | 38 | if (opecode == 0x01) { /* LB(opt, uimm); */ |
24 | 39 | jitcSetHh4BufferSimple(jitc, 3); |
25 | 40 | i = ip[1]; opt = ip[2]; |
@@ -58,6 +73,70 @@ int jitcStepPointer(OsecpuJitc *jitc) | ||
58 | 73 | jitcSetRetCode(pRC, JITC_BAD_LABEL_TYPE); // P3Fにデータラベルを代入できない. |
59 | 74 | goto fin; |
60 | 75 | } |
76 | + if (opecode == 0x2e) { // data | |
77 | + BitReader br; | |
78 | + typ = hh4ReaderGetUnsigned(&jitc->hh4r); | |
79 | + len = hh4ReaderGetUnsigned(&jitc->hh4r); | |
80 | + getTypSize(typ, &typSize0, &typSize1, &typSign); | |
81 | + if (typSize0 < 0) { | |
82 | + jitcSetRetCode(pRC, JITC_BAD_TYPE); | |
83 | + goto fin; | |
84 | + } | |
85 | + jitc->instrLength = 0; // 自前で処理するので、この値は0にする. | |
86 | + if (jitc->dst + 3 + (typSize1 * len + 3) / 4 > jitc->dst1) { | |
87 | + jitcSetRetCode(pRC, JITC_DST_OVERRUN); | |
88 | + goto fin; | |
89 | + } | |
90 | + ip = jitc->dst; | |
91 | + ip[0] = 0x2e; | |
92 | + ip[1] = typ; | |
93 | + ip[2] = len; | |
94 | + jitc->dst += 3; | |
95 | + if (typ != 1) { | |
96 | + bitReaderInit(&br, &jitc->hh4r); | |
97 | + // 以下は構造体サポートに配慮できてない. | |
98 | + if (typSize1 == 1 && typSign == 0) { | |
99 | + unsigned char *puc = (unsigned char *) jitc->dst; | |
100 | + for (i = 0; i < len; i++) | |
101 | + puc[i] = bitReaderGetNbitUnsigned(&br, typSize0); | |
102 | + } | |
103 | + if (typSize1 == 1 && typSign != 0) { | |
104 | + signed char *psc = (signed char *) jitc->dst; | |
105 | + for (i = 0; i < len; i++) | |
106 | + psc[i] = bitReaderGetNbitSigned(&br, typSize0); | |
107 | + } | |
108 | + if (typSize1 == 2 && typSign == 0) { | |
109 | + unsigned short *pus = (unsigned short *) jitc->dst; | |
110 | + for (i = 0; i < len; i++) | |
111 | + pus[i] = bitReaderGetNbitUnsigned(&br, typSize0); | |
112 | + } | |
113 | + if (typSize1 == 2 && typSign != 0) { | |
114 | + signed short *pss = (signed short *) jitc->dst; | |
115 | + for (i = 0; i < len; i++) | |
116 | + pss[i] = bitReaderGetNbitSigned(&br, typSize0); | |
117 | + } | |
118 | + if (typSize1 == 4 && typSign == 0) { | |
119 | + unsigned int *pui = (unsigned int *) jitc->dst; | |
120 | + for (i = 0; i < len; i++) | |
121 | + pui[i] = bitReaderGetNbitUnsigned(&br, typSize0); | |
122 | + } | |
123 | + if (typSize1 == 4 && typSign != 0) { | |
124 | + signed int *psi = (signed int *) jitc->dst; | |
125 | + for (i = 0; i < len; i++) | |
126 | + psi[i] = bitReaderGetNbitSigned(&br, typSize0); | |
127 | + } | |
128 | + jitc->dst += (typSize1 * len + 3) / 4; | |
129 | + jitc->dst += (len + 3) / 4; | |
130 | + } | |
131 | + for (j = 0; j < JITC_DSTLOG_SIZE; j++) { | |
132 | + Int32 *dstLog = jitc->dstLog[jitc->dstLogIndex + JITC_DSTLOG_SIZE - 1 - j]; | |
133 | + if (dstLog == NULL) break; | |
134 | + if (dstLog[0] != 0x01) break; | |
135 | + i = dstLog[1]; | |
136 | + jitc->defines->label[i].typ = typ; | |
137 | + jitc->defines->label[i].dst = ip; | |
138 | + } | |
139 | + } | |
61 | 140 | goto fin1; |
62 | 141 | fin: |
63 | 142 | if (retcode == -1) |
@@ -75,7 +154,7 @@ void execStepPointer(OsecpuVm *vm) | ||
75 | 154 | { |
76 | 155 | const Int32 *ip = vm->ip; |
77 | 156 | Int32 opecode = ip[0]; |
78 | - int i, p; | |
157 | + int i, p, typ, len, typSign, typSize0, typSize1; | |
79 | 158 | if (opecode == 0x01) { /* LB(opt, uimm); */ |
80 | 159 | ip += 3; |
81 | 160 | goto fin; |
@@ -88,6 +167,12 @@ void execStepPointer(OsecpuVm *vm) | ||
88 | 167 | ip += 3; |
89 | 168 | goto fin; |
90 | 169 | } |
170 | + if (opecode == 0x2e) { // data | |
171 | + typ = ip[1]; len = ip[2]; | |
172 | + getTypSize(typ, &typSize0, &typSize1, &typSign); | |
173 | + ip += 3 + (typSize1 * len + 3) / 4; | |
174 | + goto fin; | |
175 | + } | |
91 | 176 | fin: |
92 | 177 | vm->ip = ip; |
93 | 178 | return; |
@@ -1,13 +1,14 @@ | ||
1 | 1 | #include "osecpu-vm.h" |
2 | 2 | |
3 | +#define BUFFER_SIZE 256 | |
4 | + | |
3 | 5 | int main(int argc, const char **argv) |
4 | 6 | { |
5 | 7 | Defines defs; |
6 | 8 | OsecpuJitc jitc; |
7 | 9 | OsecpuVm vm; |
8 | - unsigned char hh4src[256], *hh4src1; | |
9 | - Int32 i32buf[256], j32buf[256]; | |
10 | - definesInit(&defs); | |
10 | + unsigned char hh4src[BUFFER_SIZE], *hh4src1; | |
11 | + Int32 i32buf[BUFFER_SIZE], j32buf[BUFFER_SIZE]; | |
11 | 12 | jitc.defines = &defs; |
12 | 13 | vm.defines = &defs; |
13 | 14 |
@@ -45,19 +46,23 @@ int main(int argc, const char **argv) | ||
45 | 46 | "c40 0 767fffff bf c40" // FLIMM64(F3F, 0x7fffff); |
46 | 47 | "c49 5 bf c40 bf a0" // FCMPNE32_64(R3F, F05, F3F); |
47 | 48 | "4 bf" // CND(R3F); |
48 | - "3 1 bf", // PLIMM(P3F, 1); | |
49 | - NULL, hh4src, &hh4src[256] | |
49 | + "3 1 bf" // PLIMM(P3F, 1); | |
50 | + | |
51 | + "2 0 3 0" // LIMM0(R03, 0); | |
52 | + "90 3 3 3 a0", // CP32(R03, R03); // ここでエラーコード1になる. | |
53 | + NULL, hh4src, &hh4src[BUFFER_SIZE] | |
50 | 54 | ); |
51 | 55 | |
52 | 56 | if (hh4src1 == NULL) { |
53 | 57 | printf("hh4src1 == NULL\n"); |
54 | 58 | return 1; |
55 | 59 | } |
60 | + printf("hh4src1 - hh4src = %d\n", hh4src1 - hh4src); | |
56 | 61 | |
57 | 62 | // jitcAll()を使って、hh4src[]内のプログラムをj32buf[]に変換する. |
58 | - hh4ReaderInit(&jitc.hh4r, hh4src, 0, hh4src1, 1); | |
63 | + hh4ReaderInit(&jitc.hh4r, hh4src, 0, hh4src1, 0); | |
59 | 64 | jitc.dst = j32buf; |
60 | - jitc.dst1 = &j32buf[256]; | |
65 | + jitc.dst1 = &j32buf[BUFFER_SIZE]; | |
61 | 66 | printf("jitcAll()=%d\n", jitcAll(&jitc)); // 0なら成功. |
62 | 67 | *jitc.dst = -1; // デバッグ用の特殊opecode. |
63 | 68 | vm.ip = j32buf; |