修订版 | 43e8a7ba3c37c430d812263859883f2d1f4f5caf (tree) |
---|---|
时间 | 2014-06-22 19:52:53 |
作者 | hikarupsp <hikarupsp@user...> |
Commiter | hikarupsp |
LB,PLIMMを整備。
ちなみにテストコードは無限ループなので注意。
@@ -0,0 +1 @@ | ||
1 | +Breakpoints_v2.xcbkptlist |
@@ -11,6 +11,7 @@ | ||
11 | 11 | 17478CFE193E2DEB00293791 /* test.hex in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17478CFD193E2ADA00293791 /* test.hex */; }; |
12 | 12 | 17478D01193F3D0000293791 /* ch4.c in Sources */ = {isa = PBXBuildFile; fileRef = 17478D00193F3D0000293791 /* ch4.c */; }; |
13 | 13 | 17478D041940B66700293791 /* opcode.c in Sources */ = {isa = PBXBuildFile; fileRef = 17478D031940B66700293791 /* opcode.c */; }; |
14 | + 1786B0941956C18800FD4F7B /* label.c in Sources */ = {isa = PBXBuildFile; fileRef = 1786B0931956C18800FD4F7B /* label.c */; }; | |
14 | 15 | 17F95C01194C8DA70064E1B6 /* bios.c in Sources */ = {isa = PBXBuildFile; fileRef = 17F95C00194C8DA70064E1B6 /* bios.c */; }; |
15 | 16 | /* End PBXBuildFile section */ |
16 | 17 |
@@ -35,6 +36,7 @@ | ||
35 | 36 | 17478D00193F3D0000293791 /* ch4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ch4.c; sourceTree = "<group>"; usesTabs = 1; }; |
36 | 37 | 17478D02193F586100293791 /* ch4.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ch4.h; sourceTree = "<group>"; usesTabs = 1; }; |
37 | 38 | 17478D031940B66700293791 /* opcode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = opcode.c; sourceTree = "<group>"; usesTabs = 1; }; |
39 | + 1786B0931956C18800FD4F7B /* label.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = label.c; sourceTree = "<group>"; }; | |
38 | 40 | 17F95C00194C8DA70064E1B6 /* bios.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bios.c; sourceTree = "<group>"; }; |
39 | 41 | /* End PBXFileReference section */ |
40 | 42 |
@@ -76,6 +78,7 @@ | ||
76 | 78 | 17478CFD193E2ADA00293791 /* test.hex */, |
77 | 79 | 17478D031940B66700293791 /* opcode.c */, |
78 | 80 | 17F95C00194C8DA70064E1B6 /* bios.c */, |
81 | + 1786B0931956C18800FD4F7B /* label.c */, | |
79 | 82 | ); |
80 | 83 | path = chncpu; |
81 | 84 | sourceTree = "<group>"; |
@@ -131,6 +134,7 @@ | ||
131 | 134 | isa = PBXSourcesBuildPhase; |
132 | 135 | buildActionMask = 2147483647; |
133 | 136 | files = ( |
137 | + 1786B0941956C18800FD4F7B /* label.c in Sources */, | |
134 | 138 | 17F95C01194C8DA70064E1B6 /* bios.c in Sources */, |
135 | 139 | 17478D041940B66700293791 /* opcode.c in Sources */, |
136 | 140 | 17478CF4193E2A4900293791 /* chncpu.c in Sources */, |
@@ -9,6 +9,21 @@ | ||
9 | 9 | #include "chncpu.h" |
10 | 10 | #include <stdio.h> |
11 | 11 | |
12 | +CHNCPU_BIOS *CHNCPU_CreateBIOS(void) | |
13 | +{ | |
14 | + CHNCPU_BIOS *bios; | |
15 | + | |
16 | + bios = malloc(sizeof(CHNCPU_BIOS)); | |
17 | + if(!bios){ | |
18 | + puts("CHNCPU_CreateBIOS: malloc error, abort.\n"); | |
19 | + exit(EXIT_FAILURE); | |
20 | + } | |
21 | + | |
22 | + CHNCPU_BIOS_Init(bios); | |
23 | + | |
24 | + return bios; | |
25 | +} | |
26 | + | |
12 | 27 | int CHNCPU_BIOS_Init(CHNCPU_BIOS *bios) |
13 | 28 | { |
14 | 29 | int i; |
@@ -33,8 +48,8 @@ int CHNCPU_BIOS_Init(CHNCPU_BIOS *bios) | ||
33 | 48 | // putcReg |
34 | 49 | // |
35 | 50 | |
36 | -typedef struct CHNCPU_BIOS_OP_CACHE_LIMM CHNCPU_BIOS_OpCache_putcReg; | |
37 | -struct CHNCPU_BIOS_OP_CACHE_LIMM { | |
51 | +typedef struct _CHNCPU_BIOS_OP_CACHE_LIMM CHNCPU_BIOS_OpCache_putcReg; | |
52 | +struct _CHNCPU_BIOS_OP_CACHE_LIMM { | |
38 | 53 | ch4_uint r; |
39 | 54 | }; |
40 | 55 | int CHNCPU_BIOS_Op_putcReg_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix) |
@@ -102,36 +102,6 @@ int decodeHexString(char *src0, char *src1, unsigned char *dst0, unsigned char * | ||
102 | 102 | return wlen; |
103 | 103 | } |
104 | 104 | |
105 | -CHNCPU_OpTableSet *CHNCPU_CreateOpTableSet(void) | |
106 | -{ | |
107 | - CHNCPU_OpTableSet *opSet; | |
108 | - | |
109 | - opSet = malloc(sizeof(CHNCPU_OpTableSet)); | |
110 | - if(!opSet){ | |
111 | - puts("CHNCPU_CreateOpTableSet: malloc error, abort.\n"); | |
112 | - exit(EXIT_FAILURE); | |
113 | - } | |
114 | - | |
115 | - CHNCPU_Op_Init(opSet); | |
116 | - | |
117 | - return opSet; | |
118 | -} | |
119 | - | |
120 | -CHNCPU_BIOS *CHNCPU_CreateBIOS(void) | |
121 | -{ | |
122 | - CHNCPU_BIOS *bios; | |
123 | - | |
124 | - bios = malloc(sizeof(CHNCPU_BIOS)); | |
125 | - if(!bios){ | |
126 | - puts("CHNCPU_CreateBIOS: malloc error, abort.\n"); | |
127 | - exit(EXIT_FAILURE); | |
128 | - } | |
129 | - | |
130 | - CHNCPU_BIOS_Init(bios); | |
131 | - | |
132 | - return bios; | |
133 | -} | |
134 | - | |
135 | 105 | CHNCPU_RuntimeEnvironment *CHNCPU_CreateRuntimeEnvironment(CHNCPU_OpTableSet *opSet, CHNCPU_BIOS *bios) |
136 | 106 | { |
137 | 107 | CHNCPU_RuntimeEnvironment *env; |
@@ -154,6 +124,13 @@ CHNCPU_RuntimeEnvironment *CHNCPU_CreateRuntimeEnvironment(CHNCPU_OpTableSet *op | ||
154 | 124 | for(i = 0; i < CHNCPU_LENGTH_OF_MAIN_MEMORY; i++){ |
155 | 125 | env->mainmemory[i].opCode = CHNCPU_OPCODE_INVALID; |
156 | 126 | } |
127 | + for(i = 0; i < CHNCPU_NUMBER_OF_PREG; i++){ | |
128 | + env->pReg[i].type = 0; | |
129 | + env->pReg[i].mindex = 0; | |
130 | + } | |
131 | + | |
132 | + // ラベル管理初期化 | |
133 | + env->labelSet = CHNCPU_CreateLabelSet(); | |
157 | 134 | |
158 | 135 | // 実行バイナリ関連初期化 |
159 | 136 | env->appbin0 = malloc(CHNCPU_SIZE_APPBIN); |
@@ -199,47 +176,58 @@ int CHNCPU_LoadBinaryFromHexStringFilePath(CHNCPU_RuntimeEnvironment *env, const | ||
199 | 176 | int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env) |
200 | 177 | { |
201 | 178 | ch4_uint opcode = 0; |
202 | - int mindex; | |
203 | 179 | CHNCPU_OpTag *op; |
204 | 180 | unsigned int prefix = 0; |
205 | 181 | CHNCPU_OpTableSet *opSet = env->opSet; |
206 | 182 | |
207 | 183 | // env->appbinReaderから読み込んで、実行可能な状態にする。 |
208 | 184 | // これはコンパイラ版におけるコンパイルに相当する。 |
209 | - //printf("< Beginning of binary > \n"); | |
210 | - mindex = 0; | |
211 | - for(mindex = 0; mindex < CHNCPU_LENGTH_OF_MAIN_MEMORY; mindex++){ | |
185 | +#if DEBUG_PRINT_OP_EXECUTING | |
186 | + puts("< Start preparing for execution >"); | |
187 | +#endif | |
188 | + env->currentIndex = 0; | |
189 | + for(env->currentIndex = 0; env->currentIndex < CHNCPU_LENGTH_OF_MAIN_MEMORY; env->currentIndex++){ | |
212 | 190 | opcode = CH4Reader_ReadNextAsUINT(env->appbinReader); |
213 | 191 | if(CH4Reader_IsEndOfBinary(env->appbinReader)){ |
214 | 192 | break; |
215 | 193 | } |
216 | - //printf("(%02X) ", opcode); | |
217 | - | |
218 | - op = &env->mainmemory[mindex]; | |
219 | - op->opCode = opcode; | |
220 | - switch(opcode){ | |
194 | + switch(opcode){ | |
221 | 195 | case 0x00: |
222 | 196 | // NOP |
223 | - mindex--; // メモリには追加しない | |
197 | +#if DEBUG_PRINT_OP_BINDING | |
198 | + puts("NOP()"); | |
199 | +#endif | |
200 | + env->currentIndex--; // メモリには追加しない | |
224 | 201 | break; |
225 | 202 | case 0x2F: |
226 | 203 | // Prefix |
227 | 204 | opcode = CH4Reader_ReadNextAsUINT(env->appbinReader); |
228 | - //printf("Prefix-%X\n", opcode); | |
205 | +#if DEBUG_PRINT_OP_BINDING | |
206 | + printf("Prefix-%X\n", opcode); | |
207 | +#endif | |
229 | 208 | if(opcode > CHNCPU_PREFIX_MAX){ |
230 | 209 | env->errFlags |= CHNCPU_ERR_C_PREFIX; |
231 | 210 | break; |
232 | 211 | } |
233 | 212 | prefix |= (0x01 << opcode); |
234 | - mindex--; // メモリには追加しない | |
213 | + env->currentIndex--; // メモリには追加しない | |
235 | 214 | break; |
236 | 215 | default: |
237 | 216 | // ごく一部の特殊な命令以外は、命令テーブルを参照する |
217 | + op = &env->mainmemory[env->currentIndex]; | |
218 | + op->opCode = opcode; | |
238 | 219 | if(opcode <= CHNCPU_OPECODE_MAX && opSet->bindFuncTable[opcode]){ |
239 | 220 | opSet->bindFuncTable[opcode](env, op, prefix); |
240 | 221 | } else{ |
241 | 222 | env->errFlags |= CHNCPU_ERR_C_OPCODE; |
242 | 223 | } |
224 | +#if DEBUG_PRINT_OP_EXECUTING | |
225 | + if(op->opCode <= CHNCPU_OPECODE_MAX && opSet->printFuncTable[op->opCode]){ | |
226 | + opSet->printFuncTable[op->opCode](env, op, stdout); | |
227 | + } else{ | |
228 | + printf("Unknown op: 0x%X", op->opCode); | |
229 | + } | |
230 | +#endif | |
243 | 231 | prefix = 0; |
244 | 232 | break; |
245 | 233 | } |
@@ -250,11 +238,12 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env) | ||
250 | 238 | break; |
251 | 239 | } |
252 | 240 | } |
253 | - if(mindex >= CHNCPU_LENGTH_OF_MAIN_MEMORY && !CH4Reader_IsEndOfBinary(env->appbinReader)){ | |
241 | + if(env->currentIndex >= CHNCPU_LENGTH_OF_MAIN_MEMORY && !CH4Reader_IsEndOfBinary(env->appbinReader)){ | |
254 | 242 | env->errFlags |= CHNCPU_ERR_C_INTERNAL; |
255 | 243 | puts("INVALID-C: Internal error (low on memory)."); |
256 | 244 | } |
257 | 245 | if(env->errFlags){ |
246 | + printf(">>> Compile error in label:%d\n", env->currentLabel); | |
258 | 247 | if(env->errFlags & CHNCPU_ERR_C_REGNUM){ |
259 | 248 | puts("INVALID-C: Invalid register number."); |
260 | 249 | } |
@@ -273,7 +262,12 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env) | ||
273 | 262 | if(env->errFlags & CHNCPU_ERR_C_PREFIX){ |
274 | 263 | puts("INVALID-C: Invalid prefix."); |
275 | 264 | } |
265 | + if(env->errFlags & CHNCPU_ERR_C_DUPLICATED_LB){ | |
266 | + puts("INVALID-C: Duplicated LabelID."); | |
267 | + } | |
276 | 268 | } |
269 | + env->currentIndex = 0; | |
270 | + env->currentLabel = 0; | |
277 | 271 | return 0; |
278 | 272 | } |
279 | 273 |
@@ -286,8 +280,9 @@ int CHNCPU_Execute(CHNCPU_RuntimeEnvironment *env) | ||
286 | 280 | if(env->errFlags){ |
287 | 281 | puts(">>> Can't execute binary because of there is some error."); |
288 | 282 | } |
289 | - | |
290 | - //puts("< Beginning of execution >"); | |
283 | +#if DEBUG_PRINT_OP_EXECUTING | |
284 | + puts("< Start execution >"); | |
285 | +#endif | |
291 | 286 | for(; env->currentIndex < CHNCPU_LENGTH_OF_MAIN_MEMORY; env->currentIndex++){ |
292 | 287 | op = &env->mainmemory[env->currentIndex]; |
293 | 288 | if(op->opCode == CHNCPU_OPCODE_INVALID){ |
@@ -320,10 +315,13 @@ int CHNCPU_Execute(CHNCPU_RuntimeEnvironment *env) | ||
320 | 315 | if(env->errFlags & CHNCPU_ERR_X_TRUNCATED_VALUE){ |
321 | 316 | puts("INVALID-X: Truncated value without prefix 2F-0."); |
322 | 317 | } |
318 | + if(env->errFlags & CHNCPU_ERR_X_LABEL_NOT_FOUND){ | |
319 | + puts("INVALID-X: Label not found."); | |
320 | + } | |
323 | 321 | } |
324 | 322 | |
325 | 323 | #if DEBUG_PRINT_IREG_AFTER_EXECUTION |
326 | - puts("\n>>> End of execution"); | |
324 | + puts("\n< End of execution >"); | |
327 | 325 | CHNCPU_DumpIReg(env); |
328 | 326 | #endif |
329 | 327 |
@@ -25,6 +25,7 @@ | ||
25 | 25 | #define CHNCPU_BIOS_OP_MAX 0x00 |
26 | 26 | #define CHNCPU_BITS_MAX 32 |
27 | 27 | #define CHNCPU_NUMBER_OF_IREG 64 |
28 | +#define CHNCPU_NUMBER_OF_PREG 64 | |
28 | 29 | #define CHNCPU_LENGTH_OF_MAIN_MEMORY (64 * 1024) // per Op |
29 | 30 | #define CHNCPU_SIZE_APPBIN (1024 * 1024 * 1) |
30 | 31 | #define CHNCPU_OPCODE_INVALID (-1) |
@@ -38,20 +39,53 @@ | ||
38 | 39 | #define CHNCPU_ERR_C_INTERNAL 0x10 |
39 | 40 | #define CHNCPU_ERR_C_INVALID_BIN 0x20 |
40 | 41 | #define CHNCPU_ERR_C_PREFIX 0x40 |
42 | +#define CHNCPU_ERR_C_DUPLICATED_LB 0x80 | |
41 | 43 | |
42 | 44 | // ErrorCode in execution |
43 | 45 | #define CHNCPU_ERR_X_INTERNAL 0x01 |
44 | 46 | #define CHNCPU_ERR_X_TRUNCATED_VALUE 0x02 |
47 | +#define CHNCPU_ERR_X_LABEL_NOT_FOUND 0x04 | |
45 | 48 | |
46 | 49 | // (2F)Prefix |
47 | 50 | #define CHNCPU_PREFIX_ALLOW_TRUNCATE 0x01 |
48 | 51 | |
49 | 52 | #define CHNCPU_PREFIX_MASK_Op_TernaryRegBitwise (CHNCPU_PREFIX_ALLOW_TRUNCATE) |
50 | 53 | |
54 | +// Type of Pointer | |
55 | +#define CHNCPU_PType_Undefined 0 | |
56 | +#define CHNCPU_PType_Code (-1) | |
57 | +// type 型名 説明 | |
58 | +// -1 Code | |
59 | +// 0x00 Undefined | |
60 | +// 0x01 VPtr | |
61 | +// 0x02 SINT8 signed char. | |
62 | +// 0x03 UINT8 | |
63 | +// 0x04 SINT16 short. | |
64 | +// 0x05 UINT16 | |
65 | +// 0x06 SINT32 sint | |
66 | +// 0x07 UINT32 uint | |
67 | +// 0x08 SINT4 | |
68 | +// 0x09 UINT4 | |
69 | +// 0x0A SINT2 | |
70 | +// 0x0B UINT2 | |
71 | +// 0x0C SINT1 bool.代入できるのは0か-1のみ. | |
72 | +// 0x0D UINT1 | |
73 | +// 0x0E SINT12 | |
74 | +// 0x0F UINT12 | |
75 | +// 0x10 SINT20 | |
76 | +// 0x11 UINT20 | |
77 | +// 0x12 SINT24 | |
78 | +// 0x13 UINT24 | |
79 | +// 0x14 SINT28 | |
80 | +// 0x15 UINT28 | |
81 | + | |
51 | 82 | typedef struct _CHNCPU_OP_TAG CHNCPU_OpTag; |
52 | 83 | typedef struct _CHNCPU_BIOS CHNCPU_BIOS; |
53 | 84 | typedef struct _CHNCPU_OP_TABLE_SET CHNCPU_OpTableSet; |
54 | 85 | typedef struct _CHNCPU_RUN_TIME_ENVIRONMENT CHNCPU_RuntimeEnvironment; |
86 | +typedef struct _CHNCPU_LABEL_TAG CHNCPU_LabelTag; | |
87 | +typedef struct _CHNCPU_LABEL_SET CHNCPU_LabelSet; | |
88 | +typedef struct _CHNCPU_POINTER_TAG CHNCPU_PointerTag; | |
55 | 89 | |
56 | 90 | |
57 | 91 | struct _CHNCPU_OP_TAG { |
@@ -71,24 +105,40 @@ struct _CHNCPU_OP_TABLE_SET { | ||
71 | 105 | int (*printFuncTable[CHNCPU_OPECODE_MAX + 1])(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); |
72 | 106 | }; |
73 | 107 | |
108 | +struct _CHNCPU_LABEL_TAG { | |
109 | + int labelID; | |
110 | + int opt; // 0:local(R3F Only) 1:public(can be saved to memory, pRegs) | |
111 | + int mindex; | |
112 | + CHNCPU_LabelTag *next; | |
113 | +}; | |
114 | + | |
115 | +struct _CHNCPU_LABEL_SET { | |
116 | + CHNCPU_LabelTag top; | |
117 | +}; | |
118 | + | |
119 | +struct _CHNCPU_POINTER_TAG { | |
120 | + int type; // CHNCPU_PType_xx | |
121 | + int mindex; | |
122 | +}; | |
123 | + | |
74 | 124 | struct _CHNCPU_RUN_TIME_ENVIRONMENT { |
75 | 125 | CHNCPU_BIOS *bios; |
76 | 126 | CHNCPU_OpTableSet *opSet; |
127 | + CHNCPU_LabelSet *labelSet; | |
77 | 128 | int iReg[CHNCPU_NUMBER_OF_IREG]; |
78 | 129 | int iRegBits[CHNCPU_NUMBER_OF_IREG]; |
130 | + CHNCPU_PointerTag pReg[CHNCPU_NUMBER_OF_PREG]; | |
79 | 131 | CHNCPU_OpTag mainmemory[CHNCPU_LENGTH_OF_MAIN_MEMORY]; |
80 | 132 | unsigned char *appbin0; |
81 | 133 | int appbinsize; |
82 | 134 | CH4Reader *appbinReader; |
83 | 135 | unsigned int errFlags; |
84 | 136 | int currentIndex; |
85 | - | |
137 | + int currentLabel; | |
86 | 138 | }; |
87 | 139 | |
88 | 140 | // @chncpu.c |
89 | 141 | int decodeHexString(char *src0, char *src1, unsigned char *dst0, unsigned char *dst1); |
90 | -CHNCPU_OpTableSet *CHNCPU_CreateOpTableSet(void); | |
91 | -CHNCPU_BIOS *CHNCPU_CreateBIOS(void); | |
92 | 142 | CHNCPU_RuntimeEnvironment *CHNCPU_CreateRuntimeEnvironment(CHNCPU_OpTableSet *opSet, CHNCPU_BIOS *bios); |
93 | 143 | int CHNCPU_LoadBinaryFromHexStringFilePath(CHNCPU_RuntimeEnvironment *env, const char *path); |
94 | 144 | int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env); |
@@ -97,11 +147,19 @@ void CHNCPU_DumpAppBin(CHNCPU_RuntimeEnvironment *env); | ||
97 | 147 | void CHNCPU_DumpIReg(CHNCPU_RuntimeEnvironment *env); |
98 | 148 | int CHNCPU_CHK_IsAvailableBits(CHNCPU_RuntimeEnvironment *env, ch4_uint bits); |
99 | 149 | int CHNCPU_AdjustValueForBit(CHNCPU_RuntimeEnvironment *env, int *value, ch4_uint bit, int prefix); |
150 | + | |
100 | 151 | // @opcode.c |
152 | +CHNCPU_OpTableSet *CHNCPU_CreateOpTableSet(void); | |
101 | 153 | int CHNCPU_Op_Init(CHNCPU_OpTableSet *env); |
154 | +int CHNCPU_Op_LB_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix); | |
155 | +int CHNCPU_Op_LB_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); | |
156 | +int CHNCPU_Op_LB_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); | |
102 | 157 | int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix); |
103 | 158 | int CHNCPU_Op_LIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); |
104 | 159 | int CHNCPU_Op_LIMM_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); |
160 | +int CHNCPU_Op_PLIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix); | |
161 | +int CHNCPU_Op_PLIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); | |
162 | +int CHNCPU_Op_PLIMM_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); | |
105 | 163 | int CHNCPU_Op_CALLBIOS_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix); |
106 | 164 | int CHNCPU_Op_CALLBIOS_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); |
107 | 165 | int CHNCPU_Op_CALLBIOS_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); |
@@ -111,8 +169,15 @@ int CHNCPU_Op_TernaryRegArithmetic_Execute(CHNCPU_RuntimeEnvironment *env, CHNCP | ||
111 | 169 | int CHNCPU_Op_TernaryReg_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); |
112 | 170 | |
113 | 171 | // @bios.c |
172 | +CHNCPU_BIOS *CHNCPU_CreateBIOS(void); | |
114 | 173 | int CHNCPU_BIOS_Init(CHNCPU_BIOS *bios); |
115 | 174 | int CHNCPU_BIOS_Op_putcReg_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix); |
116 | 175 | int CHNCPU_BIOS_Op_putcReg_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op); |
117 | 176 | int CHNCPU_BIOS_Op_putcReg_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file); |
177 | + | |
178 | +// @label.c | |
179 | +CHNCPU_LabelSet *CHNCPU_CreateLabelSet(void); | |
180 | +int CHNCPU_Label_Add(CHNCPU_LabelSet *lbSet, int mindex, int labelID, int opt); | |
181 | +CHNCPU_LabelTag *CHNCPU_Label_GetTagFromLabelID(CHNCPU_LabelSet *lbSet, int labelID); | |
182 | + | |
118 | 183 | #endif |
@@ -0,0 +1,74 @@ | ||
1 | +// | |
2 | +// label.c | |
3 | +// chncpu | |
4 | +// | |
5 | +// Created by 西田 耀 on 2014/06/22. | |
6 | +// Copyright (c) 2014年 CHNOSProject. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#include "chncpu.h" | |
10 | + | |
11 | +CHNCPU_LabelSet *CHNCPU_CreateLabelSet(void) | |
12 | +{ | |
13 | + CHNCPU_LabelSet *lbSet; | |
14 | + | |
15 | + lbSet = malloc(sizeof(CHNCPU_LabelSet)); | |
16 | + if(!lbSet){ | |
17 | + puts("CHNCPU_CreateLabelSet: malloc error, abort.\n"); | |
18 | + exit(EXIT_FAILURE); | |
19 | + } | |
20 | + | |
21 | + lbSet->top.labelID = 0; | |
22 | + lbSet->top.opt = 0; | |
23 | + lbSet->top.mindex = 0; | |
24 | + lbSet->top.next = NULL; | |
25 | + | |
26 | + return lbSet; | |
27 | +} | |
28 | + | |
29 | +int CHNCPU_Label_Add(CHNCPU_LabelSet *lbSet, int mindex, int labelID, int opt) | |
30 | +{ | |
31 | + // retv: false:succeeded true:failed | |
32 | + CHNCPU_LabelTag *t = &lbSet->top; | |
33 | + for(;;){ | |
34 | + if(t->labelID == labelID){ | |
35 | + // 既に存在するラベルID | |
36 | + return -1; | |
37 | + } | |
38 | + if(t->next == NULL){ | |
39 | + // 最後のタグ | |
40 | + break; | |
41 | + } | |
42 | + t = t->next; | |
43 | + } | |
44 | + | |
45 | + t->next = malloc(sizeof(CHNCPU_LabelTag)); | |
46 | + if(t->next){ | |
47 | + t = t->next; | |
48 | + t->mindex = mindex; | |
49 | + t->labelID = labelID; | |
50 | + t->opt = opt; | |
51 | + t->next = NULL; | |
52 | + } else{ | |
53 | + return -1; | |
54 | + } | |
55 | + | |
56 | + return 0; | |
57 | +} | |
58 | + | |
59 | +CHNCPU_LabelTag *CHNCPU_Label_GetTagFromLabelID(CHNCPU_LabelSet *lbSet, int labelID) | |
60 | +{ | |
61 | + CHNCPU_LabelTag *t = &lbSet->top; | |
62 | + for(;;){ | |
63 | + if(t->labelID == labelID){ | |
64 | + return t; | |
65 | + } | |
66 | + if(t->next == NULL){ | |
67 | + // 最後のタグ | |
68 | + break; | |
69 | + } | |
70 | + t = t->next; | |
71 | + } | |
72 | + return NULL; | |
73 | +} | |
74 | + |
@@ -8,6 +8,21 @@ | ||
8 | 8 | |
9 | 9 | #include "chncpu.h" |
10 | 10 | |
11 | +CHNCPU_OpTableSet *CHNCPU_CreateOpTableSet(void) | |
12 | +{ | |
13 | + CHNCPU_OpTableSet *opSet; | |
14 | + | |
15 | + opSet = malloc(sizeof(CHNCPU_OpTableSet)); | |
16 | + if(!opSet){ | |
17 | + puts("CHNCPU_CreateOpTableSet: malloc error, abort.\n"); | |
18 | + exit(EXIT_FAILURE); | |
19 | + } | |
20 | + | |
21 | + CHNCPU_Op_Init(opSet); | |
22 | + | |
23 | + return opSet; | |
24 | +} | |
25 | + | |
11 | 26 | int CHNCPU_Op_Init(CHNCPU_OpTableSet *opSet) |
12 | 27 | { |
13 | 28 | int i; |
@@ -19,11 +34,21 @@ int CHNCPU_Op_Init(CHNCPU_OpTableSet *opSet) | ||
19 | 34 | opSet->printFuncTable[i] = NULL; |
20 | 35 | } |
21 | 36 | |
37 | + // LB | |
38 | + opSet->bindFuncTable[0x01] = CHNCPU_Op_LB_BindOperand; | |
39 | + opSet->execFuncTable[0x01] = CHNCPU_Op_LB_Execute; | |
40 | + opSet->printFuncTable[0x01] = CHNCPU_Op_LB_PrintCode; | |
41 | + | |
22 | 42 | // LIMM |
23 | 43 | opSet->bindFuncTable[0x02] = CHNCPU_Op_LIMM_BindOperand; |
24 | 44 | opSet->execFuncTable[0x02] = CHNCPU_Op_LIMM_Execute; |
25 | 45 | opSet->printFuncTable[0x02] = CHNCPU_Op_LIMM_PrintCode; |
26 | 46 | |
47 | + // LIMM | |
48 | + opSet->bindFuncTable[0x03] = CHNCPU_Op_PLIMM_BindOperand; | |
49 | + opSet->execFuncTable[0x03] = CHNCPU_Op_PLIMM_Execute; | |
50 | + opSet->printFuncTable[0x03] = CHNCPU_Op_PLIMM_PrintCode; | |
51 | + | |
27 | 52 | // CALLBIOS |
28 | 53 | opSet->bindFuncTable[0x05] = CHNCPU_Op_CALLBIOS_BindOperand; |
29 | 54 | opSet->execFuncTable[0x05] = CHNCPU_Op_CALLBIOS_Execute; |
@@ -51,11 +76,61 @@ int CHNCPU_Op_Init(CHNCPU_OpTableSet *opSet) | ||
51 | 76 | } |
52 | 77 | |
53 | 78 | // |
79 | +// 01 LB | |
80 | +// | |
81 | +typedef struct _CHNCPU_OP_CACHE_LB CHNCPU_OpCache_LB; | |
82 | +struct _CHNCPU_OP_CACHE_LB { | |
83 | + ch4_uint labelID; | |
84 | + ch4_uint opt; | |
85 | +}; | |
86 | +int CHNCPU_Op_LB_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix) | |
87 | +{ | |
88 | + CHNCPU_OpCache_LB *opCache; | |
89 | + | |
90 | + opCache = malloc(sizeof(CHNCPU_OpCache_LB)); | |
91 | + op->opCache = opCache; | |
92 | + | |
93 | + opCache->labelID = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
94 | + opCache->opt = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
95 | + | |
96 | + env->currentLabel = opCache->labelID; | |
97 | + | |
98 | + if(CHNCPU_Label_Add(env->labelSet, env->currentIndex, opCache->labelID, opCache->opt)){ | |
99 | + env->errFlags |= CHNCPU_ERR_C_DUPLICATED_LB; | |
100 | + } | |
101 | + | |
102 | + if(prefix != 0){ | |
103 | + env->errFlags |= CHNCPU_ERR_C_PREFIX; | |
104 | + return -1; | |
105 | + } | |
106 | + return 0; | |
107 | +} | |
108 | +int CHNCPU_Op_LB_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | |
109 | +{ | |
110 | + CHNCPU_OpCache_LB *opCache; | |
111 | + opCache = op->opCache; | |
112 | + | |
113 | + env->currentLabel = opCache->labelID; | |
114 | + | |
115 | + return 0; | |
116 | +} | |
117 | + | |
118 | +int CHNCPU_Op_LB_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file) | |
119 | +{ | |
120 | + CHNCPU_OpCache_LB *opCache; | |
121 | + opCache = op->opCache; | |
122 | + | |
123 | + fprintf(file, "LB(id:0x%X, opt:%d);\n", opCache->labelID, opCache->opt); | |
124 | + | |
125 | + return 0; | |
126 | +} | |
127 | + | |
128 | +// | |
54 | 129 | // 02 LIMM |
55 | 130 | // |
56 | 131 | |
57 | -typedef struct CHNCPU_OP_CACHE_LIMM CHNCPU_OpCache_LIMM; | |
58 | -struct CHNCPU_OP_CACHE_LIMM { | |
132 | +typedef struct _CHNCPU_OP_CACHE_LIMM CHNCPU_OpCache_LIMM; | |
133 | +struct _CHNCPU_OP_CACHE_LIMM { | |
59 | 134 | ch4_sint imm; |
60 | 135 | ch4_uint r; |
61 | 136 | ch4_uint bit; |
@@ -105,12 +180,76 @@ int CHNCPU_Op_LIMM_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, F | ||
105 | 180 | CHNCPU_OpCache_LIMM *opCache; |
106 | 181 | |
107 | 182 | opCache = op->opCache; |
108 | - fprintf(file, "LIMM(imm:0x%X, r:%d, bit:%d);\n", opCache->imm, opCache->r, opCache->bit); | |
183 | + fprintf(file, "LIMM(imm:0x%X, r:%02X, bit:%d);\n", opCache->imm, opCache->r, opCache->bit); | |
109 | 184 | |
110 | 185 | return 0; |
111 | 186 | } |
112 | 187 | |
113 | 188 | // |
189 | +// 02 PLIMM | |
190 | +// | |
191 | + | |
192 | +typedef struct _CHNCPU_OP_CACHE_PLIMM CHNCPU_OpCache_PLIMM; | |
193 | +struct _CHNCPU_OP_CACHE_PLIMM { | |
194 | + ch4_sint labelID; | |
195 | + ch4_uint r; | |
196 | +}; | |
197 | +int CHNCPU_Op_PLIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix) | |
198 | +{ | |
199 | + CHNCPU_OpCache_PLIMM *opCache; | |
200 | + | |
201 | + opCache = malloc(sizeof(CHNCPU_OpCache_PLIMM)); | |
202 | + op->opCache = opCache; | |
203 | + | |
204 | + opCache->labelID = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
205 | + opCache->r = CH4Reader_ReadNextAsUINT(env->appbinReader); | |
206 | + | |
207 | + if(opCache->r >= CHNCPU_NUMBER_OF_PREG){ | |
208 | + env->errFlags |= CHNCPU_ERR_C_REGNUM; | |
209 | + return -1; | |
210 | + } | |
211 | + if(prefix != 0){ | |
212 | + env->errFlags |= CHNCPU_ERR_C_PREFIX; | |
213 | + return -1; | |
214 | + } | |
215 | + return 0; | |
216 | +} | |
217 | +int CHNCPU_Op_PLIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op) | |
218 | +{ | |
219 | + CHNCPU_OpCache_PLIMM *opCache; | |
220 | + CHNCPU_LabelTag *label; | |
221 | + | |
222 | + opCache = op->opCache; | |
223 | + | |
224 | + label = CHNCPU_Label_GetTagFromLabelID(env->labelSet, opCache->labelID); | |
225 | + if(!label){ | |
226 | + env->errFlags |= CHNCPU_ERR_X_LABEL_NOT_FOUND; | |
227 | + return -1; | |
228 | + } | |
229 | + | |
230 | + env->pReg[opCache->r].mindex = label->mindex; | |
231 | + env->pReg[opCache->r].type = CHNCPU_PType_Code; | |
232 | + | |
233 | + if(opCache->r == 0x3F){ | |
234 | + if(env->pReg[0x3F].type == CHNCPU_PType_Code){ | |
235 | + env->currentIndex = env->pReg[0x3F].mindex - 1; | |
236 | + } | |
237 | + } | |
238 | + | |
239 | + return 0; | |
240 | +} | |
241 | + | |
242 | +int CHNCPU_Op_PLIMM_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file) | |
243 | +{ | |
244 | + CHNCPU_OpCache_PLIMM *opCache; | |
245 | + | |
246 | + opCache = op->opCache; | |
247 | + fprintf(file, "PLIMM(labelID:0x%X, r:%02X);\n", opCache->labelID, opCache->r); | |
248 | + | |
249 | + return 0; | |
250 | +} | |
251 | + | |
252 | +// | |
114 | 253 | // 05 CALLBIOS |
115 | 254 | // |
116 | 255 | int CHNCPU_Op_CALLBIOS_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix) |
@@ -191,8 +330,8 @@ int CHNCPU_Op_CALLBIOS_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *o | ||
191 | 330 | // 1A DIV |
192 | 331 | // 1B MOD |
193 | 332 | |
194 | -typedef struct CHNCPU_OP_CACHE_TERNARY_REG CHNCPU_OpCache_TernaryReg; | |
195 | -struct CHNCPU_OP_CACHE_TERNARY_REG { | |
333 | +typedef struct _CHNCPU_OP_CACHE_TERNARY_REG CHNCPU_OpCache_TernaryReg; | |
334 | +struct _CHNCPU_OP_CACHE_TERNARY_REG { | |
196 | 335 | ch4_uint r0; |
197 | 336 | ch4_uint r1; |
198 | 337 | ch4_uint r2; |
@@ -345,7 +484,7 @@ int CHNCPU_Op_TernaryReg_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag | ||
345 | 484 | fprintf(file, "(%02X)", op->opCode); |
346 | 485 | } |
347 | 486 | |
348 | - fprintf(file, "(r0:%d, r1:%d, r2:%d, bit:%d);\n", opCache->r0, opCache->r1, opCache->r2, opCache->bit); | |
487 | + fprintf(file, "(r0:%d, r1:%02X, r2:%02X, bit:%02X);\n", opCache->r0, opCache->r1, opCache->r2, opCache->bit); | |
349 | 488 | |
350 | 489 | return 0; |
351 | 490 | } |
@@ -1,5 +1,6 @@ | ||
1 | 1 | 2 a0 0 90 |
2 | 2 | 2 1 1 90 |
3 | - | |
3 | +1 1 0 | |
4 | 4 | 5 0 0 |
5 | -94 0 1 0 90 | |
\ No newline at end of file | ||
5 | +94 0 1 0 90 | |
6 | +3 1 bf |