Revision | 92d1db095aeae3fb149fe6e11e06f650bb702ea1 (tree) |
---|---|
Zeit | 2014-06-09 23:27:22 |
Autor | hikarupsp <hikarupsp@user...> |
Commiter | hikarupsp |
CPと0-32bit対応を実装
@@ -33,7 +33,7 @@ | ||
33 | 33 | 17478CFD193E2ADA00293791 /* test.hex */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test.hex; sourceTree = "<group>"; }; |
34 | 34 | 17478D00193F3D0000293791 /* ch4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ch4.c; sourceTree = "<group>"; usesTabs = 1; }; |
35 | 35 | 17478D02193F586100293791 /* ch4.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ch4.h; sourceTree = "<group>"; usesTabs = 1; }; |
36 | - 17478D031940B66700293791 /* opcode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = opcode.c; sourceTree = "<group>"; }; | |
36 | + 17478D031940B66700293791 /* opcode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = opcode.c; sourceTree = "<group>"; usesTabs = 1; }; | |
37 | 37 | /* End PBXFileReference section */ |
38 | 38 | |
39 | 39 | /* Begin PBXFrameworksBuildPhase section */ |
@@ -54,6 +54,7 @@ | ||
54 | 54 | 17478CF1193E2A4900293791 /* Products */, |
55 | 55 | ); |
56 | 56 | sourceTree = "<group>"; |
57 | + usesTabs = 1; | |
57 | 58 | }; |
58 | 59 | 17478CF1193E2A4900293791 /* Products */ = { |
59 | 60 | isa = PBXGroup; |
@@ -78,6 +78,7 @@ ch4_uint CH4Reader_ReadBodyAtIndexAsUINT(CH4Reader *reader, int index, int *retR | ||
78 | 78 | readIndex = 0; |
79 | 79 | if(tmp == -1){ |
80 | 80 | // error |
81 | + value = 0; | |
81 | 82 | } else if((tmp & 8) == 0){ |
82 | 83 | // 4bit or prefix_ext |
83 | 84 | if(tmp == 7){ |
@@ -105,7 +105,7 @@ int decodeHexString(char *src0, char *src1, unsigned char *dst0, unsigned char * | ||
105 | 105 | CHNCPU_RuntimeEnvironment *CHNCPU_CreateRuntimeEnvironment(void) |
106 | 106 | { |
107 | 107 | CHNCPU_RuntimeEnvironment *env; |
108 | - int i, j; | |
108 | + int i; | |
109 | 109 | |
110 | 110 | env = malloc(sizeof(CHNCPU_RuntimeEnvironment)); |
111 | 111 | if(!env){ |
@@ -118,11 +118,8 @@ CHNCPU_RuntimeEnvironment *CHNCPU_CreateRuntimeEnvironment(void) | ||
118 | 118 | env->iRegBits[i] = 0; |
119 | 119 | } |
120 | 120 | |
121 | - for(i = 0; i < CHNCPU_NUMBER_OF_MEMORY_PAGE; i++){ | |
122 | - for(j = 0; j < CHNCPU_NUMBER_OF_OP_TAG; j++){ | |
123 | - env->mainmemory[i].data[j].opCode = CHNCPU_OPCODE_INVALID; | |
124 | - } | |
125 | - env->mainmemory[i].labelNumber = 0; | |
121 | + for(i = 0; i < CHNCPU_LENGTH_OF_MAIN_MEMORY; i++){ | |
122 | + env->mainmemory[i].opCode = CHNCPU_OPCODE_INVALID; | |
126 | 123 | } |
127 | 124 | |
128 | 125 | env->appbin0 = malloc(CHNCPU_SIZE_APPBIN); |
@@ -135,12 +132,21 @@ CHNCPU_RuntimeEnvironment *CHNCPU_CreateRuntimeEnvironment(void) | ||
135 | 132 | env->bindOpFuncTable[i] = NULL; |
136 | 133 | } |
137 | 134 | env->bindOpFuncTable[0x02] = CHNCPU_Op_LIMM_BindOperand; |
135 | + env->bindOpFuncTable[0x10] = CHNCPU_Op_TernaryReg_BindOperand; | |
138 | 136 | |
139 | 137 | // execOpFuncTable |
140 | 138 | for(i = 0; i <= CHNCPU_OPECODE_MAX; i++){ |
141 | 139 | env->execOpFuncTable[i] = NULL; |
142 | 140 | } |
143 | 141 | env->execOpFuncTable[0x02] = CHNCPU_Op_LIMM_Execute; |
142 | + env->execOpFuncTable[0x10] = CHNCPU_Op_TernaryReg_Execute; | |
143 | + | |
144 | + // printOpFuncTable | |
145 | + for(i = 0; i <= CHNCPU_OPECODE_MAX; i++){ | |
146 | + env->printOpFuncTable[i] = NULL; | |
147 | + } | |
148 | + env->printOpFuncTable[0x02] = CHNCPU_Op_LIMM_PrintCode; | |
149 | + env->printOpFuncTable[0x10] = CHNCPU_Op_TernaryReg_PrintCode; | |
144 | 150 | |
145 | 151 | env->errFlags = 0; |
146 | 152 |
@@ -181,7 +187,7 @@ int CHNCPU_LoadBinaryFromHexStringFilePath(CHNCPU_RuntimeEnvironment *env, const | ||
181 | 187 | int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env) |
182 | 188 | { |
183 | 189 | ch4_uint opcode; |
184 | - int index, page; | |
190 | + int mindex; | |
185 | 191 | CHNCPU_OpTag *op; |
186 | 192 | int breakFlag = 0; |
187 | 193 | int retv; |
@@ -189,53 +195,54 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env) | ||
189 | 195 | // env->appbinReaderから読み込んで、実行可能な状態にする。 |
190 | 196 | // これはコンパイラ版におけるコンパイルに相当する。 |
191 | 197 | printf("< Beginning of binary > \n"); |
192 | - page = 0; | |
193 | - index = 0; | |
194 | - for(page = 0; page < CHNCPU_NUMBER_OF_MEMORY_PAGE; page++){ | |
195 | - for(index = 0; index < CHNCPU_NUMBER_OF_OP_TAG; index++){ | |
196 | - opcode = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
197 | - if(CH4Reader_IsEndOfBinary(env->appbinReader)){ | |
198 | - puts("< End of binary >"); | |
199 | - breakFlag = 1; | |
198 | + mindex = 0; | |
199 | + for(mindex = 0; mindex < CHNCPU_LENGTH_OF_MAIN_MEMORY; mindex++){ | |
200 | + opcode = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
201 | + if(CH4Reader_IsEndOfBinary(env->appbinReader)){ | |
202 | + puts("< End of binary >"); | |
203 | + breakFlag = 1; | |
204 | + break; | |
205 | + } | |
206 | + printf("(%02X) ", opcode); | |
207 | + | |
208 | + op = &env->mainmemory[mindex]; | |
209 | + op->opCode = opcode; | |
210 | + switch(opcode){ | |
211 | + case 0x00: | |
212 | + // NOP | |
213 | + puts("NOP();\n"); | |
214 | + mindex--; | |
200 | 215 | break; |
201 | - } | |
202 | - printf("(%02X) ", opcode); | |
203 | - | |
204 | - op = &env->mainmemory[page].data[index]; | |
205 | - op->opCode = opcode; | |
206 | - switch(opcode){ | |
207 | - case 0x00: | |
208 | - // NOP | |
209 | - puts("NOP();\n"); | |
210 | - index--; | |
211 | - break; | |
212 | - default: | |
213 | - // ごく一部の特殊な命令以外は、命令テーブルを参照する | |
214 | - if(opcode <= CHNCPU_OPECODE_MAX && env->bindOpFuncTable[opcode]){ | |
215 | - retv = env->bindOpFuncTable[opcode](env, op); | |
216 | - if(retv){ | |
217 | - opcode = CHNCPU_OPCODE_INVALID; | |
218 | - } | |
219 | - } else{ | |
216 | + default: | |
217 | + // ごく一部の特殊な命令以外は、命令テーブルを参照する | |
218 | + if(opcode <= CHNCPU_OPECODE_MAX && env->bindOpFuncTable[opcode]){ | |
219 | + retv = env->bindOpFuncTable[opcode](env, op); | |
220 | + if(retv){ | |
220 | 221 | opcode = CHNCPU_OPCODE_INVALID; |
221 | - env->errFlags |= CHNCPU_ERR_C_OPCODE; | |
222 | 222 | } |
223 | - if(opcode == CHNCPU_OPCODE_INVALID){ | |
224 | - op->opCode = CHNCPU_OPCODE_INVALID; | |
225 | - breakFlag = 1; | |
226 | - } | |
227 | - break; | |
228 | - } | |
229 | - if(breakFlag == 1){ | |
223 | + } else{ | |
224 | + opcode = CHNCPU_OPCODE_INVALID; | |
225 | + env->errFlags |= CHNCPU_ERR_C_OPCODE; | |
226 | + } | |
227 | + if(opcode == CHNCPU_OPCODE_INVALID){ | |
228 | + op->opCode = CHNCPU_OPCODE_INVALID; | |
229 | + breakFlag = 1; | |
230 | + } | |
230 | 231 | break; |
231 | - } | |
232 | 232 | } |
233 | - if(breakFlag){ | |
233 | + if(env->appbinReader->errorFlags){ | |
234 | + env->errFlags |= CHNCPU_ERR_C_INVALID_BIN; | |
235 | + break; | |
236 | + } | |
237 | + if(breakFlag == 1){ | |
234 | 238 | break; |
235 | 239 | } |
236 | 240 | } |
241 | + if(mindex >= CHNCPU_LENGTH_OF_MAIN_MEMORY && !CH4Reader_IsEndOfBinary(env->appbinReader)){ | |
242 | + env->errFlags |= CHNCPU_ERR_C_INTERNAL; | |
243 | + puts("INVALID-C: Internal error (low on memory)."); | |
244 | + } | |
237 | 245 | if(env->errFlags){ |
238 | - putchar('\n'); | |
239 | 246 | if(env->errFlags & CHNCPU_ERR_C_REGNUM){ |
240 | 247 | puts("INVALID-C: Invalid register number."); |
241 | 248 | } |
@@ -248,14 +255,15 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env) | ||
248 | 255 | if(env->errFlags & CHNCPU_ERR_C_EXPRESSION){ |
249 | 256 | puts("INVALID-C: Invalid expression."); |
250 | 257 | } |
258 | + if(env->errFlags & CHNCPU_ERR_C_INVALID_BIN){ | |
259 | + puts("INVALID-C: Invalid binary."); | |
260 | + } | |
251 | 261 | } |
252 | - | |
253 | 262 | return 0; |
254 | 263 | } |
255 | 264 | |
256 | 265 | int CHNCPU_Execute(CHNCPU_RuntimeEnvironment *env) |
257 | 266 | { |
258 | - int breakFlag = 0; | |
259 | 267 | int count = 0; |
260 | 268 | int retv; |
261 | 269 | CHNCPU_OpTag *op; |
@@ -265,42 +273,26 @@ int CHNCPU_Execute(CHNCPU_RuntimeEnvironment *env) | ||
265 | 273 | } |
266 | 274 | |
267 | 275 | puts("< Beginning of execution >"); |
268 | - for(; env->currentPage < CHNCPU_NUMBER_OF_MEMORY_PAGE; env->currentPage++){ | |
269 | - op = &env->mainmemory[env->currentPage].data[0]; | |
276 | + for(; env->currentIndex < CHNCPU_LENGTH_OF_MAIN_MEMORY; env->currentIndex++){ | |
277 | + op = &env->mainmemory[env->currentIndex]; | |
270 | 278 | if(op->opCode == CHNCPU_OPCODE_INVALID){ |
271 | - // 空白のメモリページ:バイナリの末端 | |
272 | - puts(">>> Control reached end of binary."); | |
273 | - breakFlag = 1; | |
279 | + // End of Binary | |
274 | 280 | break; |
275 | 281 | } |
276 | - for(; env->currentIndex < CHNCPU_NUMBER_OF_OP_TAG; env->currentIndex++){ | |
277 | - op = &env->mainmemory[env->currentPage].data[env->currentIndex]; | |
278 | - if(op->opCode == CHNCPU_OPCODE_INVALID){ | |
279 | - // このページはここでおしまい | |
280 | - break; | |
281 | - } | |
282 | - if(op->opCode <= CHNCPU_OPECODE_MAX && env->bindOpFuncTable[op->opCode]){ | |
283 | - retv = env->execOpFuncTable[op->opCode](env, op); | |
284 | - } else{ | |
285 | - // すでにチェックしたはずなのに不明な命令が来た | |
286 | - env->errFlags |= CHNCPU_ERR_X_INTERNAL; | |
287 | - breakFlag = 1; | |
288 | - break; | |
289 | - } | |
290 | - if(retv){ | |
291 | - breakFlag = 1; | |
292 | - break; | |
293 | - } | |
294 | - | |
282 | + if(op->opCode <= CHNCPU_OPECODE_MAX && env->bindOpFuncTable[op->opCode]){ | |
283 | + retv = env->execOpFuncTable[op->opCode](env, op); | |
284 | + } else{ | |
285 | + // ロード時にチェックしたはずなのに不明な命令が来た | |
286 | + env->errFlags |= CHNCPU_ERR_X_INTERNAL; | |
287 | + break; | |
295 | 288 | } |
296 | - if(breakFlag){ | |
289 | + if(retv){ | |
290 | + // 命令実行時にエラーが発生 | |
297 | 291 | break; |
298 | 292 | } |
299 | - count++; | |
300 | - env->currentIndex = 0; | |
293 | + | |
301 | 294 | } |
302 | 295 | if(env->errFlags){ |
303 | - putchar('\n'); | |
304 | 296 | if(env->errFlags & CHNCPU_ERR_X_INTERNAL){ |
305 | 297 | puts("INVALID-X: Internal error."); |
306 | 298 | } |
@@ -350,7 +342,7 @@ void CHNCPU_DumpIReg(CHNCPU_RuntimeEnvironment *env) | ||
350 | 342 | |
351 | 343 | int CHNCPU_CHK_IsAvailableBits(CHNCPU_RuntimeEnvironment *env, ch4_uint bits) |
352 | 344 | { |
353 | - if(bits != 0 && bits != 32){ | |
345 | + if(bits > 32){ | |
354 | 346 | env->errFlags |= CHNCPU_ERR_C_BITS; |
355 | 347 | return 0; |
356 | 348 | } |
@@ -17,10 +17,8 @@ | ||
17 | 17 | |
18 | 18 | #define CHNCPU_OPECODE_MAX 0xFF |
19 | 19 | #define CHNCPU_BITS_MAX 32 |
20 | -#define CHNCPU_BITS_DEFAULT 32 | |
21 | 20 | #define CHNCPU_NUMBER_OF_IREG 64 |
22 | -#define CHNCPU_NUMBER_OF_MEMORY_PAGE 1024 | |
23 | -#define CHNCPU_NUMBER_OF_OP_TAG 64 | |
21 | +#define CHNCPU_LENGTH_OF_MAIN_MEMORY (64 * 1024) // per Op | |
24 | 22 | #define CHNCPU_SIZE_APPBIN (1024 * 1024 * 1) |
25 | 23 | #define CHNCPU_OPCODE_INVALID (-1) |
26 | 24 |
@@ -28,6 +26,8 @@ | ||
28 | 26 | #define CHNCPU_ERR_C_BITS 2 |
29 | 27 | #define CHNCPU_ERR_C_OPCODE 4 |
30 | 28 | #define CHNCPU_ERR_C_EXPRESSION 8 |
29 | +#define CHNCPU_ERR_C_INTERNAL 16 | |
30 | +#define CHNCPU_ERR_C_INVALID_BIN 32 | |
31 | 31 | |
32 | 32 | #define CHNCPU_ERR_X_INTERNAL 1 |
33 | 33 |
@@ -37,24 +37,19 @@ struct CHNCPU_OP_TAG { | ||
37 | 37 | void *opCache; |
38 | 38 | }; |
39 | 39 | |
40 | -typedef struct CHNCPU_MEMORY_PAGE CHNCPU_MemoryPage; | |
41 | -struct CHNCPU_MEMORY_PAGE { | |
42 | - int labelNumber; | |
43 | - CHNCPU_OpTag data[CHNCPU_NUMBER_OF_OP_TAG]; | |
44 | -}; | |
45 | - | |
46 | 40 | typedef struct CHNCPU_RUN_TIME_ENVIRONMENT CHNCPU_RuntimeEnvironment; |
47 | 41 | struct CHNCPU_RUN_TIME_ENVIRONMENT { |
48 | 42 | int (*bindOpFuncTable[CHNCPU_OPECODE_MAX])(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); |
49 | 43 | int (*execOpFuncTable[CHNCPU_OPECODE_MAX])(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); |
44 | + int (*printOpFuncTable[CHNCPU_OPECODE_MAX])(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); | |
50 | 45 | int iReg[CHNCPU_NUMBER_OF_IREG]; |
51 | 46 | int iRegBits[CHNCPU_NUMBER_OF_IREG]; |
52 | - CHNCPU_MemoryPage mainmemory[CHNCPU_NUMBER_OF_MEMORY_PAGE]; | |
47 | + CHNCPU_OpTag mainmemory[CHNCPU_LENGTH_OF_MAIN_MEMORY]; | |
53 | 48 | unsigned char *appbin0; |
54 | 49 | int appbinsize; |
55 | 50 | CH4Reader *appbinReader; |
56 | 51 | unsigned int errFlags; |
57 | - int currentPage, currentIndex; | |
52 | + int currentIndex; | |
58 | 53 | }; |
59 | 54 | |
60 | 55 | // @chncpu.c |
@@ -70,5 +65,8 @@ int CHNCPU_CHK_IsAvailableBits(CHNCPU_RuntimeEnvironment *env, ch4_uint bits); | ||
70 | 65 | // @opcode.c |
71 | 66 | int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); |
72 | 67 | int CHNCPU_Op_LIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); |
73 | - | |
68 | +int CHNCPU_Op_LIMM_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); | |
69 | +int CHNCPU_Op_TernaryReg_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); | |
70 | +int CHNCPU_Op_TernaryReg_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); | |
71 | +int CHNCPU_Op_TernaryReg_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); | |
74 | 72 | #endif |
@@ -8,6 +8,10 @@ | ||
8 | 8 | |
9 | 9 | #include "chncpu.h" |
10 | 10 | |
11 | +// | |
12 | +// 02 LIMM | |
13 | +// | |
14 | + | |
11 | 15 | typedef struct CHNCPU_OP_CACHE_LIMM CHNCPU_OpCache_LIMM; |
12 | 16 | struct CHNCPU_OP_CACHE_LIMM { |
13 | 17 | ch4_sint imm; |
@@ -25,7 +29,7 @@ int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | ||
25 | 29 | opCache->r = CH4Reader_ReadNextAsUINT(env->appbinReader); |
26 | 30 | opCache->bit = CH4Reader_ReadNextAsUINT(env->appbinReader); |
27 | 31 | |
28 | - printf("LIMM(imm:0x%X r:%d bit:%d);\n", opCache->imm, opCache->r, opCache->bit); | |
32 | + CHNCPU_Op_LIMM_PrintCode(env, op, stdout); | |
29 | 33 | |
30 | 34 | if(opCache->r >= CHNCPU_NUMBER_OF_IREG){ |
31 | 35 | env->errFlags |= CHNCPU_ERR_C_REGNUM; |
@@ -46,66 +50,125 @@ int CHNCPU_Op_LIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | ||
46 | 50 | |
47 | 51 | opCache = op->opCache; |
48 | 52 | |
49 | - printf("LIMM(imm:0x%X r:%d bit:%d);\n", opCache->imm, opCache->r, opCache->bit); | |
53 | + CHNCPU_Op_LIMM_PrintCode(env, op, stdout); | |
50 | 54 | |
51 | - env->iReg[opCache->r] = opCache->imm; | |
52 | - if(opCache->bit){ | |
53 | - env->iRegBits[opCache->r] = opCache->bit; | |
54 | - } else{ | |
55 | - env->iRegBits[opCache->r] = CHNCPU_BITS_DEFAULT; | |
56 | - } | |
55 | + env->iReg[opCache->r] = opCache->imm & (0xFFFFFFFF >> (32 - opCache->bit)); | |
56 | + env->iRegBits[opCache->r] = opCache->bit; | |
57 | 57 | |
58 | 58 | return 0; |
59 | 59 | } |
60 | -/* | |
61 | -typedef struct CHNCPU_OP_CACHE_U_LOGICAL CHNCPU_OpCache_UnsignedLogical; | |
62 | -struct CHNCPU_OP_CACHE_U_LOGICAL { | |
63 | - ch4_sint imm; | |
64 | - ch4_uint r; | |
65 | - ch4_uint bit; | |
66 | -}; | |
67 | -int CHNCPU_Op_UnsignedLogical_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | |
60 | + | |
61 | +int CHNCPU_Op_LIMM_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file) | |
68 | 62 | { |
69 | 63 | CHNCPU_OpCache_LIMM *opCache; |
70 | 64 | |
71 | - opCache = malloc(sizeof(CHNCPU_OpCache_LIMM)); | |
72 | - op->opCache = opCache; | |
65 | + opCache = op->opCache; | |
66 | + fprintf(file, "LIMM(imm:0x%X, r:%d, bit:%d);\n", opCache->imm, opCache->r, opCache->bit); | |
67 | + | |
68 | + return 0; | |
69 | +} | |
70 | + | |
71 | +// | |
72 | +// Ternary Register Operation | |
73 | +// | |
74 | + | |
75 | +// 10 CP/OR | |
76 | + | |
77 | +typedef struct CHNCPU_OP_CACHE_TERNARY_REG CHNCPU_OpCache_TernaryReg; | |
78 | +struct CHNCPU_OP_CACHE_TERNARY_REG { | |
79 | + ch4_uint r0; | |
80 | + ch4_uint r1; | |
81 | + ch4_uint r2; | |
82 | + ch4_uint bit; | |
83 | +}; | |
84 | +int CHNCPU_Op_TernaryReg_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | |
85 | +{ | |
86 | + CHNCPU_OpCache_TernaryReg *opCache; | |
73 | 87 | |
74 | - opCache->imm = (ch4_sint)CH4Reader_ReadNextAsUINT(env->appbinReader); | |
75 | - opCache->r = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
76 | - opCache->bit = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
88 | + opCache = malloc(sizeof(CHNCPU_OpCache_TernaryReg)); | |
89 | + op->opCache = opCache; | |
77 | 90 | |
78 | - printf("LIMM(imm:0x%X r:%d bit:%d);\n", opCache->imm, opCache->r, opCache->bit); | |
91 | + opCache->r1 = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
92 | + opCache->r2 = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
93 | + opCache->r0 = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
94 | + opCache->bit = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
79 | 95 | |
80 | - if(opCache->r >= CHNCPU_NUMBER_OF_IREG){ | |
96 | + CHNCPU_Op_TernaryReg_PrintCode(env, op, stdout); | |
97 | + | |
98 | + if(opCache->r0 >= CHNCPU_NUMBER_OF_IREG || | |
99 | + opCache->r1 >= CHNCPU_NUMBER_OF_IREG || | |
100 | + opCache->r2 >= CHNCPU_NUMBER_OF_IREG){ | |
81 | 101 | env->errFlags |= CHNCPU_ERR_C_REGNUM; |
82 | 102 | return -1; |
83 | 103 | } |
84 | 104 | if(!CHNCPU_CHK_IsAvailableBits(env, opCache->bit)){ |
85 | 105 | return -1; |
86 | 106 | } |
87 | - if(opCache->bit == 0 && opCache->imm != 0){ | |
88 | - env->errFlags |= CHNCPU_ERR_C_EXPRESSION; | |
89 | - return -1; | |
90 | - } | |
91 | 107 | return 0; |
92 | 108 | } |
93 | -int CHNCPU_Op_UnsignedLogical_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | |
109 | +int CHNCPU_Op_TernaryReg_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | |
94 | 110 | { |
95 | - CHNCPU_OpCache_LIMM *opCache; | |
111 | + CHNCPU_OpCache_TernaryReg *opCache; | |
96 | 112 | |
97 | 113 | opCache = op->opCache; |
98 | 114 | |
99 | - printf("LIMM(imm:0x%X r:%d bit:%d);\n", opCache->imm, opCache->r, opCache->bit); | |
100 | - | |
101 | - env->iReg[opCache->r] = opCache->imm; | |
102 | - if(opCache->bit){ | |
103 | - env->iRegBits[opCache->r] = opCache->bit; | |
104 | - } else{ | |
105 | - env->iRegBits[opCache->r] = CHNCPU_BITS_DEFAULT; | |
115 | + CHNCPU_Op_TernaryReg_PrintCode(env, op, stdout); | |
116 | + | |
117 | + switch (op->opCode) { | |
118 | + case 0x10: // CP/OR | |
119 | + if(opCache->r1 == opCache->r2){ | |
120 | + // CP | |
121 | + env->iReg[opCache->r0] = env->iReg[opCache->r1] & (0xFFFFFFFF >> (32 - opCache->bit)); | |
122 | + env->iRegBits[opCache->r0] = opCache->bit; | |
123 | + } else{ | |
124 | + // OR | |
125 | + env->errFlags |= CHNCPU_ERR_X_INTERNAL; | |
126 | + return -1; | |
127 | + } | |
128 | + break; | |
129 | + default: | |
130 | + env->errFlags |= CHNCPU_ERR_X_INTERNAL; | |
131 | + return -1; | |
132 | + } | |
133 | + | |
134 | + if(!CHNCPU_CHK_IsAvailableBits(env, opCache->bit)){ | |
135 | + return -1; | |
106 | 136 | } |
137 | + | |
138 | + return 0; | |
139 | +} | |
140 | +char *CHNCPU_Op_TernaryReg_MnemonicList0[12] = { | |
141 | + // 10 - 1B | |
142 | + "OR", | |
143 | + "XOR", | |
144 | + "AND", | |
145 | + "SBX", | |
146 | + "ADD", | |
147 | + "SUB", | |
148 | + "MUL", | |
149 | + "(Reserved)", | |
150 | + "SHL", | |
151 | + "SAR", | |
152 | + "DIV", | |
153 | + "MOD" | |
154 | +}; | |
155 | +int CHNCPU_Op_TernaryReg_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file) | |
156 | +{ | |
157 | + CHNCPU_OpCache_TernaryReg *opCache; | |
158 | + | |
159 | + opCache = op->opCache; | |
107 | 160 | |
161 | + if(op->opCode == 0x10 && (opCache->r1 == opCache->r2)){ | |
162 | + // CP | |
163 | + fprintf(file, "CP"); | |
164 | + } else if(0x10 <= op->opCode && op->opCode <= 0x1B){ | |
165 | + fprintf(file, "%s", CHNCPU_Op_TernaryReg_MnemonicList0[op->opCode - 0x10]); | |
166 | + } else{ | |
167 | + fprintf(file, "(%02X)", op->opCode); | |
168 | + } | |
169 | + | |
170 | + fprintf(file, "(r0:%d, r1:%d, r2:%d, bit:%d);\n", opCache->r0, opCache->r1, opCache->r2, opCache->bit); | |
171 | + | |
108 | 172 | return 0; |
109 | 173 | } |
110 | -*/ | |
111 | 174 |
@@ -1 +1 @@ | ||
1 | -2 E123 0 A0 2 E365 1 A0 | |
\ No newline at end of file | ||
1 | +2 E123 0 4 2 E365 1 88 90 1 1 2 4 | |
\ No newline at end of file |