修訂 | 07971b929785a6a08e42d3b0e0b70bf8334384e1 (tree) |
---|---|
時間 | 2014-06-10 17:21:10 |
作者 | hikarupsp <hikarupsp@user...> |
Commiter | hikarupsp |
BitwiseOperationと2F-0プレフィックスを実装
@@ -127,26 +127,27 @@ CHNCPU_RuntimeEnvironment *CHNCPU_CreateRuntimeEnvironment(void) | ||
127 | 127 | |
128 | 128 | env->appbinReader = malloc(sizeof(CH4Reader)); |
129 | 129 | |
130 | - // bindOpFuncTable | |
130 | + // FuncTables | |
131 | 131 | for(i = 0; i <= CHNCPU_OPECODE_MAX; i++){ |
132 | 132 | env->bindOpFuncTable[i] = NULL; |
133 | 133 | } |
134 | - env->bindOpFuncTable[0x02] = CHNCPU_Op_LIMM_BindOperand; | |
135 | - env->bindOpFuncTable[0x10] = CHNCPU_Op_TernaryReg_BindOperand; | |
136 | - | |
137 | - // execOpFuncTable | |
138 | - for(i = 0; i <= CHNCPU_OPECODE_MAX; i++){ | |
134 | + for(i = 0; i <= CHNCPU_OPECODE_MAX; i++){ | |
139 | 135 | env->execOpFuncTable[i] = NULL; |
140 | 136 | } |
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++){ | |
137 | + for(i = 0; i <= CHNCPU_OPECODE_MAX; i++){ | |
146 | 138 | env->printOpFuncTable[i] = NULL; |
147 | 139 | } |
148 | - env->printOpFuncTable[0x02] = CHNCPU_Op_LIMM_PrintCode; | |
149 | - env->printOpFuncTable[0x10] = CHNCPU_Op_TernaryReg_PrintCode; | |
140 | + // LIMM | |
141 | + env->bindOpFuncTable[0x02] = CHNCPU_Op_LIMM_BindOperand; | |
142 | + env->execOpFuncTable[0x02] = CHNCPU_Op_LIMM_Execute; | |
143 | + env->printOpFuncTable[0x02] = CHNCPU_Op_LIMM_PrintCode; | |
144 | + | |
145 | + // TernaryRegBitwise | |
146 | + for(i = 0x10; i <= 0x11; i++){ | |
147 | + env->bindOpFuncTable[i] = CHNCPU_Op_TernaryRegBitwise_BindOperand; | |
148 | + env->execOpFuncTable[i] = CHNCPU_Op_TernaryRegBitwise_Execute; | |
149 | + env->printOpFuncTable[i] = CHNCPU_Op_TernaryReg_PrintCode; | |
150 | + } | |
150 | 151 | |
151 | 152 | env->errFlags = 0; |
152 | 153 |
@@ -191,6 +192,7 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env) | ||
191 | 192 | CHNCPU_OpTag *op; |
192 | 193 | int breakFlag = 0; |
193 | 194 | int retv; |
195 | + unsigned int prefix = 0; | |
194 | 196 | |
195 | 197 | // env->appbinReaderから読み込んで、実行可能な状態にする。 |
196 | 198 | // これはコンパイラ版におけるコンパイルに相当する。 |
@@ -211,12 +213,26 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env) | ||
211 | 213 | case 0x00: |
212 | 214 | // NOP |
213 | 215 | puts("NOP();\n"); |
216 | + // メモリには追加しない | |
214 | 217 | mindex--; |
215 | 218 | break; |
219 | + case 0x2F: | |
220 | + // Prefix | |
221 | + opcode = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
222 | + printf("Prefix-%X\n", opcode); | |
223 | + if(opcode > CHNCPU_PREFIX_MAX){ | |
224 | + env->errFlags |= CHNCPU_ERR_C_PREFIX; | |
225 | + breakFlag = 1; | |
226 | + break; | |
227 | + } | |
228 | + prefix |= (0x01 << opcode); | |
229 | + // メモリには追加しない | |
230 | + mindex--; | |
231 | + break; | |
216 | 232 | default: |
217 | 233 | // ごく一部の特殊な命令以外は、命令テーブルを参照する |
218 | 234 | if(opcode <= CHNCPU_OPECODE_MAX && env->bindOpFuncTable[opcode]){ |
219 | - retv = env->bindOpFuncTable[opcode](env, op); | |
235 | + retv = env->bindOpFuncTable[opcode](env, op, prefix); | |
220 | 236 | if(retv){ |
221 | 237 | opcode = CHNCPU_OPCODE_INVALID; |
222 | 238 | } |
@@ -228,6 +244,7 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env) | ||
228 | 244 | op->opCode = CHNCPU_OPCODE_INVALID; |
229 | 245 | breakFlag = 1; |
230 | 246 | } |
247 | + prefix = 0; | |
231 | 248 | break; |
232 | 249 | } |
233 | 250 | if(env->appbinReader->errorFlags){ |
@@ -258,6 +275,9 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env) | ||
258 | 275 | if(env->errFlags & CHNCPU_ERR_C_INVALID_BIN){ |
259 | 276 | puts("INVALID-C: Invalid binary."); |
260 | 277 | } |
278 | + if(env->errFlags & CHNCPU_ERR_C_PREFIX){ | |
279 | + puts("INVALID-C: Invalid prefix."); | |
280 | + } | |
261 | 281 | } |
262 | 282 | return 0; |
263 | 283 | } |
@@ -296,6 +316,9 @@ int CHNCPU_Execute(CHNCPU_RuntimeEnvironment *env) | ||
296 | 316 | if(env->errFlags & CHNCPU_ERR_X_INTERNAL){ |
297 | 317 | puts("INVALID-X: Internal error."); |
298 | 318 | } |
319 | + if(env->errFlags & CHNCPU_ERR_X_TRUNCATED_VALUE){ | |
320 | + puts("INVALID-X: Truncated value without prefix 2F-0."); | |
321 | + } | |
299 | 322 | } |
300 | 323 | |
301 | 324 | CHNCPU_DumpIReg(env); |
@@ -348,4 +371,3 @@ int CHNCPU_CHK_IsAvailableBits(CHNCPU_RuntimeEnvironment *env, ch4_uint bits) | ||
348 | 371 | } |
349 | 372 | return 1; |
350 | 373 | } |
351 | - |
@@ -21,15 +21,25 @@ | ||
21 | 21 | #define CHNCPU_LENGTH_OF_MAIN_MEMORY (64 * 1024) // per Op |
22 | 22 | #define CHNCPU_SIZE_APPBIN (1024 * 1024 * 1) |
23 | 23 | #define CHNCPU_OPCODE_INVALID (-1) |
24 | +#define CHNCPU_PREFIX_MAX 31 | |
24 | 25 | |
25 | -#define CHNCPU_ERR_C_REGNUM 1 | |
26 | -#define CHNCPU_ERR_C_BITS 2 | |
27 | -#define CHNCPU_ERR_C_OPCODE 4 | |
28 | -#define CHNCPU_ERR_C_EXPRESSION 8 | |
29 | -#define CHNCPU_ERR_C_INTERNAL 16 | |
30 | -#define CHNCPU_ERR_C_INVALID_BIN 32 | |
26 | +// ErrorCode at compile | |
27 | +#define CHNCPU_ERR_C_REGNUM 0x01 | |
28 | +#define CHNCPU_ERR_C_BITS 0x02 | |
29 | +#define CHNCPU_ERR_C_OPCODE 0x04 | |
30 | +#define CHNCPU_ERR_C_EXPRESSION 0x08 | |
31 | +#define CHNCPU_ERR_C_INTERNAL 0x10 | |
32 | +#define CHNCPU_ERR_C_INVALID_BIN 0x20 | |
33 | +#define CHNCPU_ERR_C_PREFIX 0x40 | |
31 | 34 | |
32 | -#define CHNCPU_ERR_X_INTERNAL 1 | |
35 | +// ErrorCode in execution | |
36 | +#define CHNCPU_ERR_X_INTERNAL 0x01 | |
37 | +#define CHNCPU_ERR_X_TRUNCATED_VALUE 0x02 | |
38 | + | |
39 | +// (2F)Prefix | |
40 | +#define CHNCPU_PREFIX_ALLOW_TRUNCATE 0x01 | |
41 | + | |
42 | +#define CHNCPU_PREFIX_MASK_Op_TernaryRegBitwise (CHNCPU_PREFIX_ALLOW_TRUNCATE) | |
33 | 43 | |
34 | 44 | typedef struct CHNCPU_OP_TAG CHNCPU_OpTag; |
35 | 45 | struct CHNCPU_OP_TAG { |
@@ -39,7 +49,7 @@ struct CHNCPU_OP_TAG { | ||
39 | 49 | |
40 | 50 | typedef struct CHNCPU_RUN_TIME_ENVIRONMENT CHNCPU_RuntimeEnvironment; |
41 | 51 | struct CHNCPU_RUN_TIME_ENVIRONMENT { |
42 | - int (*bindOpFuncTable[CHNCPU_OPECODE_MAX])(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); | |
52 | + int (*bindOpFuncTable[CHNCPU_OPECODE_MAX])(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix); | |
43 | 53 | int (*execOpFuncTable[CHNCPU_OPECODE_MAX])(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); |
44 | 54 | int (*printOpFuncTable[CHNCPU_OPECODE_MAX])(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); |
45 | 55 | int iReg[CHNCPU_NUMBER_OF_IREG]; |
@@ -63,10 +73,10 @@ void CHNCPU_DumpIReg(CHNCPU_RuntimeEnvironment *env); | ||
63 | 73 | int CHNCPU_CHK_IsAvailableBits(CHNCPU_RuntimeEnvironment *env, ch4_uint bits); |
64 | 74 | |
65 | 75 | // @opcode.c |
66 | -int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); | |
76 | +int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix); | |
67 | 77 | int CHNCPU_Op_LIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); |
68 | 78 | 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); | |
79 | +int CHNCPU_Op_TernaryRegBitwise_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix); | |
80 | +int CHNCPU_Op_TernaryRegBitwise_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); | |
71 | 81 | int CHNCPU_Op_TernaryReg_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); |
72 | 82 | #endif |
@@ -18,7 +18,7 @@ struct CHNCPU_OP_CACHE_LIMM { | ||
18 | 18 | ch4_uint r; |
19 | 19 | ch4_uint bit; |
20 | 20 | }; |
21 | -int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | |
21 | +int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix) | |
22 | 22 | { |
23 | 23 | CHNCPU_OpCache_LIMM *opCache; |
24 | 24 |
@@ -30,7 +30,7 @@ int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | ||
30 | 30 | opCache->bit = CH4Reader_ReadNextAsUINT(env->appbinReader); |
31 | 31 | |
32 | 32 | CHNCPU_Op_LIMM_PrintCode(env, op, stdout); |
33 | - | |
33 | + | |
34 | 34 | if(opCache->r >= CHNCPU_NUMBER_OF_IREG){ |
35 | 35 | env->errFlags |= CHNCPU_ERR_C_REGNUM; |
36 | 36 | return -1; |
@@ -42,6 +42,10 @@ int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | ||
42 | 42 | env->errFlags |= CHNCPU_ERR_C_EXPRESSION; |
43 | 43 | return -1; |
44 | 44 | } |
45 | + if(prefix != 0){ | |
46 | + env->errFlags |= CHNCPU_ERR_C_PREFIX; | |
47 | + return -1; | |
48 | + } | |
45 | 49 | return 0; |
46 | 50 | } |
47 | 51 | int CHNCPU_Op_LIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) |
@@ -72,7 +76,10 @@ int CHNCPU_Op_LIMM_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, F | ||
72 | 76 | // Ternary Register Operation |
73 | 77 | // |
74 | 78 | |
75 | -// 10 CP/OR | |
79 | +// Bitwise | |
80 | +// 10 CP/OR | |
81 | +// 11 XOR | |
82 | +// 12 AND | |
76 | 83 | |
77 | 84 | typedef struct CHNCPU_OP_CACHE_TERNARY_REG CHNCPU_OpCache_TernaryReg; |
78 | 85 | struct CHNCPU_OP_CACHE_TERNARY_REG { |
@@ -80,8 +87,9 @@ struct CHNCPU_OP_CACHE_TERNARY_REG { | ||
80 | 87 | ch4_uint r1; |
81 | 88 | ch4_uint r2; |
82 | 89 | ch4_uint bit; |
90 | + unsigned int prefix; | |
83 | 91 | }; |
84 | -int CHNCPU_Op_TernaryReg_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | |
92 | +int CHNCPU_Op_TernaryRegBitwise_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix) | |
85 | 93 | { |
86 | 94 | CHNCPU_OpCache_TernaryReg *opCache; |
87 | 95 |
@@ -92,6 +100,7 @@ int CHNCPU_Op_TernaryReg_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTa | ||
92 | 100 | opCache->r2 = CH4Reader_ReadNextAsUINT(env->appbinReader); |
93 | 101 | opCache->r0 = CH4Reader_ReadNextAsUINT(env->appbinReader); |
94 | 102 | opCache->bit = CH4Reader_ReadNextAsUINT(env->appbinReader); |
103 | + opCache->prefix = prefix; | |
95 | 104 | |
96 | 105 | CHNCPU_Op_TernaryReg_PrintCode(env, op, stdout); |
97 | 106 |
@@ -104,36 +113,45 @@ int CHNCPU_Op_TernaryReg_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTa | ||
104 | 113 | if(!CHNCPU_CHK_IsAvailableBits(env, opCache->bit)){ |
105 | 114 | return -1; |
106 | 115 | } |
116 | + if((prefix | CHNCPU_PREFIX_MASK_Op_TernaryRegBitwise) != CHNCPU_PREFIX_MASK_Op_TernaryRegBitwise){ | |
117 | + env->errFlags |= CHNCPU_ERR_C_PREFIX; | |
118 | + return -1; | |
119 | + } | |
107 | 120 | return 0; |
108 | 121 | } |
109 | -int CHNCPU_Op_TernaryReg_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | |
122 | +int CHNCPU_Op_TernaryRegBitwise_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | |
110 | 123 | { |
111 | 124 | CHNCPU_OpCache_TernaryReg *opCache; |
125 | + int opCode; | |
126 | + ch4_sint result; | |
112 | 127 | |
113 | 128 | opCache = op->opCache; |
129 | + opCode = op->opCode; | |
114 | 130 | |
115 | 131 | CHNCPU_Op_TernaryReg_PrintCode(env, op, stdout); |
116 | 132 | |
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; | |
133 | + if(opCode == 0x10){ | |
134 | + if(opCache->r1 == opCache->r2){ | |
135 | + // CP | |
136 | + result = env->iReg[opCache->r1]; | |
137 | + } else{ | |
138 | + // OR | |
139 | + result = env->iReg[opCache->r1] | env->iReg[opCache->r2]; | |
140 | + } | |
141 | + } else if(opCode == 0x11){ | |
142 | + // XOR | |
143 | + result = env->iReg[opCache->r1] ^ env->iReg[opCache->r2]; | |
144 | + } else{ | |
145 | + env->errFlags |= CHNCPU_ERR_X_INTERNAL; | |
146 | + return -1; | |
132 | 147 | } |
133 | 148 | |
134 | - if(!CHNCPU_CHK_IsAvailableBits(env, opCache->bit)){ | |
135 | - return -1; | |
136 | - } | |
149 | + env->iReg[opCache->r0] = result & (0xFFFFFFFF >> (32 - opCache->bit)); | |
150 | + if(!(opCache->prefix & CHNCPU_PREFIX_ALLOW_TRUNCATE) && env->iReg[opCache->r0] != result){ | |
151 | + env->errFlags |= CHNCPU_ERR_X_TRUNCATED_VALUE; | |
152 | + return -1; | |
153 | + } | |
154 | + env->iRegBits[opCache->r0] = opCache->bit; | |
137 | 155 | |
138 | 156 | return 0; |
139 | 157 | } |
@@ -1 +1 @@ | ||
1 | -2 E123 0 4 2 E365 1 88 90 1 1 2 4 | |
\ No newline at end of file | ||
1 | +2 E123 0 90 2 E365 1 90 91 0 1 2 90 | |
\ No newline at end of file |