Check-in [6599dc94ff]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Remove long stuff in SummerCoat's NativeCPU; Make some adjustments to RatufaCoat (endianess issue still remains)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:6599dc94ffb234937725588f65b0f68aaa80c339
User & Date: stephanie.gawroriski 2019-06-13 13:02:04
Context
2019-06-13
15:45
Add tests for MIPS EB and MIPS EL. check-in: 3fc66ec256 user: stephanie.gawroriski tags: trunk
13:02
Remove long stuff in SummerCoat's NativeCPU; Make some adjustments to RatufaCoat (endianess issue still remains) check-in: 6599dc94ff user: stephanie.gawroriski tags: trunk
07:02
Backup developer notes. check-in: 4e02fc749f user: squirreljme tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ratufacoat/sjmerc.c.

737
738
739
740
741
742
743
744
745
746
747




748
749
750
751




















752
753
754
755
756
757
758
...
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
....
1012
1013
1014
1015
1016
1017
1018
1019
1020

1021
1022
1023
1024
1025
1026
1027
1028
....
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132

1133
1134
1135
1136
1137
1138
1139
1140
....
1190
1191
1192
1193
1194
1195
1196
1197
1198

1199
1200
1201
1202
1203
1204
1205
1206
....
1311
1312
1313
1314
1315
1316
1317
1318

1319
1320
1321
1322
1323
1324
1325
....
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
....
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364


1365
1366
1367
1368
1369
1370
1371
1372
....
1387
1388
1389
1390
1391
1392
1393







1394
1395
1396
1397
1398
1399
1400
	
	/* Read single byte value from pointer. */
	rv = (sjme_memjreadp(1, ptr) & SJME_JINT_C(0xFF));
	
	/* Encoded as a 15-bit value? */
	if ((rv & SJME_JINT_C(0x80)) != 0)
	{
		rv &= SJME_JINT_C(0x7F);
		rv <<= SJME_JINT_C(8);
		rv |= (sjme_memjreadp(1, ptr) & SJME_JINT_C(0xFF));
	}




	
	/* Use read value. */
	return rv;
}





















/**
 * Handles system calls.
 *
 * @param jvm The JVM.
 * @param cpu The CPU.
 * @param error Error state.
................................................................................
			case SJME_ENC_IF_ICMP:
				{
					/* Values to compare. */
					ia = r[sjme_opdecodeui(&nextpc)];
					ib = r[sjme_opdecodeui(&nextpc)];
					
					/* Target PC address. */
					ic = sjme_opdecodeui(&nextpc);
					if ((ic & SJME_JINT_C(0x00004000)) != 0)
						ic |= SJME_JINT_C(0xFFFF8000);
					tempp = SJME_POINTER_OFFSET(cpu->pc, ic);
					
					/* Check depends. */
					ic = 0;
					switch (op & SJME_ENC_COMPARE_MASK)
					{
						case SJME_COMPARETYPE_EQUALS:
................................................................................
			case SJME_ENC_MATH_REG_INT:
			case SJME_ENC_MATH_CONST_INT:
				{
					/* A Value. */
					ia = r[sjme_opdecodeui(&nextpc)];
					
					/* B value. */
					ib = (enc == SJME_ENC_MATH_CONST_INT ?
						sjme_memjreadp(4, &nextpc) :

						r[sjme_opdecodeui(&nextpc)]);
					
					/* Perform the math. */
					switch (op & SJME_ENC_MATH_MASK)
					{
						case SJME_MATH_ADD:
							ic = ia + ib;
							break;
................................................................................
				/* Memory (native byte order). */
			case SJME_ENC_MEMORY_OFF_REG:
			case SJME_ENC_MEMORY_OFF_ICONST:
				{
					/* Destination/source register. */
					ic = sjme_opdecodeui(&nextpc);
					
					/* The address to access. */
					ia = r[sjme_opdecodeui(&nextpc)];
					ib = (enc >= SJME_ENC_MEMORY_OFF_ICONST ?
						sjme_memjreadp(4, &nextpc) :

						r[sjme_opdecodeui(&nextpc)]);
					tempp = SJME_JINT_TO_POINTER(ia);
					
					/* Load value */
					if ((op & SJME_MEM_LOAD_MASK) != 0)
					{
						switch (op & SJME_MEM_DATATYPE_MASK)
						{
................................................................................
			case SJME_ENC_MEMORY_OFF_ICONST_JAVA:
				{
					/* Destination/source register. */
					ic = sjme_opdecodeui(&nextpc);
					
					/* The address to access. */
					ia = r[sjme_opdecodeui(&nextpc)];
					ib = (enc >= SJME_ENC_MEMORY_OFF_ICONST ?
						sjme_memjreadp(4, &nextpc) :

						r[sjme_opdecodeui(&nextpc)]);
					tempp = SJME_JINT_TO_POINTER(ia);
					
					/* Load value */
					if ((op & SJME_MEM_LOAD_MASK) != 0)
					{
						switch (op & SJME_MEM_DATATYPE_MASK)
						{
................................................................................
			case SJME_OP_DEBUG_EXIT:
				break;
				
				/* Debug point. */
			case SJME_OP_DEBUG_POINT:
				{
					cpu->debugline = sjme_opdecodeui(&nextpc);
					cpu->debugjop = sjme_opdecodeui(&nextpc);

					cpu->debugjpc = sjme_opdecodeui(&nextpc);
				}
				break;
				
				/* If equal to constant? */
			case SJME_OP_IFEQ_CONST:
				{
................................................................................
					/* A value. */
					ia = r[sjme_opdecodeui(&nextpc)];
					
					/* B value. */
					ib = sjme_memjreadp(4, &nextpc);
					
					/* Target PC address. */
					ic = sjme_opdecodeui(&nextpc);
					if ((ic & SJME_JINT_C(0x00004000)) != 0)
						ic |= SJME_JINT_C(0xFFFF8000);
					tempp = SJME_POINTER_OFFSET(cpu->pc, ic);
					
					/* Jump on equals? */
					if (ia == ib)
						nextpc = tempp;
				}
				break;
................................................................................
					}
					
					/* Copy and store state. */
					*oldcpu = *cpu;
					cpu->parent = oldcpu;
					
					/* Setup CPU state for invoke run, move pool up. */
					for (ia = SJME_ARGBASE_REGISTER;
						ia < SJME_MAX_REGISTERS; ia++)
						r[ia] = 0;


					r[SJME_POOL_REGISTER] = r[SJME_NEXT_POOL_REGISTER];
					
					/* The address to execute. */
					ia = oldcpu->r[sjme_opdecodeui(&nextpc)];
					
					/* Load in register list (wide). */
					ib = sjme_memjreadp(1, &nextpc);
					if ((ib & SJME_JINT_C(0x80)) != 0)
................................................................................
					{
						/* Read values. */
						for (ic = 0; ic < ib; ic++)
							r[SJME_ARGBASE_REGISTER + ic] =
								oldcpu->r[sjme_memjreadp(1, &nextpc)];
					}
					







					/* Old PC address resumes where this read ended. */
					oldcpu->pc = nextpc;
					
					/* Our next PC becomes the target address. */
					nextpc = SJME_JINT_TO_POINTER(ia);
					cpu->pc = nextpc;
				}







|
<


>
>
>
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
<
<







 







|
|
>
|







 







|

|
|
>
|







 







|
|
>
|







 







|
>







 







|
<
<







 







|


>
>
|







 







>
>
>
>
>
>
>







737
738
739
740
741
742
743
744

745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
...
973
974
975
976
977
978
979
980


981
982
983
984
985
986
987
....
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
....
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
....
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
....
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
....
1351
1352
1353
1354
1355
1356
1357
1358


1359
1360
1361
1362
1363
1364
1365
....
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
....
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
	
	/* Read single byte value from pointer. */
	rv = (sjme_memjreadp(1, ptr) & SJME_JINT_C(0xFF));
	
	/* Encoded as a 15-bit value? */
	if ((rv & SJME_JINT_C(0x80)) != 0)
	{
		rv = (rv & SJME_JINT_C(0x7F)) << SJME_JINT_C(8);

		rv |= (sjme_memjreadp(1, ptr) & SJME_JINT_C(0xFF));
	}

#if 0
	fprintf(stderr, "Decode: %d 0x%X\n", (int)rv, (unsigned)rv);
#endif
	
	/* Use read value. */
	return rv;
}

/**
 * Decodes a relative jump offset.
 *
 * @param ptr The pointer to read from.
 * @return The resulting relative jump.
 * @since 2019/06/13
 */
sjme_jint sjme_opdecodejmp(void** ptr)
{
	sjme_jint rv;
	
	/* Decode value. */
	rv = sjme_opdecodeui(ptr);
	
	/* Negative branch? */
	if ((rv & SJME_JINT_C(0x00004000)) != 0)
		return rv | SJME_JINT_C(0xFFFF8000);
	return rv;
}

/**
 * Handles system calls.
 *
 * @param jvm The JVM.
 * @param cpu The CPU.
 * @param error Error state.
................................................................................
			case SJME_ENC_IF_ICMP:
				{
					/* Values to compare. */
					ia = r[sjme_opdecodeui(&nextpc)];
					ib = r[sjme_opdecodeui(&nextpc)];
					
					/* Target PC address. */
					ic = sjme_opdecodejmp(&nextpc);


					tempp = SJME_POINTER_OFFSET(cpu->pc, ic);
					
					/* Check depends. */
					ic = 0;
					switch (op & SJME_ENC_COMPARE_MASK)
					{
						case SJME_COMPARETYPE_EQUALS:
................................................................................
			case SJME_ENC_MATH_REG_INT:
			case SJME_ENC_MATH_CONST_INT:
				{
					/* A Value. */
					ia = r[sjme_opdecodeui(&nextpc)];
					
					/* B value. */
					if (enc == SJME_ENC_MATH_CONST_INT)
						ib = sjme_memjreadp(4, &nextpc);
					else
						ib = r[sjme_opdecodeui(&nextpc)];
					
					/* Perform the math. */
					switch (op & SJME_ENC_MATH_MASK)
					{
						case SJME_MATH_ADD:
							ic = ia + ib;
							break;
................................................................................
				/* Memory (native byte order). */
			case SJME_ENC_MEMORY_OFF_REG:
			case SJME_ENC_MEMORY_OFF_ICONST:
				{
					/* Destination/source register. */
					ic = sjme_opdecodeui(&nextpc);
					
					/* The address and offset to access. */
					ia = r[sjme_opdecodeui(&nextpc)];
					if (enc == SJME_ENC_MEMORY_OFF_ICONST)
						ib = sjme_memjreadp(4, &nextpc);
					else
						ib = r[sjme_opdecodeui(&nextpc)];
					tempp = SJME_JINT_TO_POINTER(ia);
					
					/* Load value */
					if ((op & SJME_MEM_LOAD_MASK) != 0)
					{
						switch (op & SJME_MEM_DATATYPE_MASK)
						{
................................................................................
			case SJME_ENC_MEMORY_OFF_ICONST_JAVA:
				{
					/* Destination/source register. */
					ic = sjme_opdecodeui(&nextpc);
					
					/* The address to access. */
					ia = r[sjme_opdecodeui(&nextpc)];
					if (enc == SJME_ENC_MEMORY_OFF_ICONST_JAVA)
						ib = sjme_memjreadp(4, &nextpc);
					else
						ib = r[sjme_opdecodeui(&nextpc)];
					tempp = SJME_JINT_TO_POINTER(ia);
					
					/* Load value */
					if ((op & SJME_MEM_LOAD_MASK) != 0)
					{
						switch (op & SJME_MEM_DATATYPE_MASK)
						{
................................................................................
			case SJME_OP_DEBUG_EXIT:
				break;
				
				/* Debug point. */
			case SJME_OP_DEBUG_POINT:
				{
					cpu->debugline = sjme_opdecodeui(&nextpc);
					cpu->debugjop = (sjme_opdecodeui(&nextpc) &
						SJME_JINT_C(0xFF));
					cpu->debugjpc = sjme_opdecodeui(&nextpc);
				}
				break;
				
				/* If equal to constant? */
			case SJME_OP_IFEQ_CONST:
				{
................................................................................
					/* A value. */
					ia = r[sjme_opdecodeui(&nextpc)];
					
					/* B value. */
					ib = sjme_memjreadp(4, &nextpc);
					
					/* Target PC address. */
					ic = sjme_opdecodejmp(&nextpc);


					tempp = SJME_POINTER_OFFSET(cpu->pc, ic);
					
					/* Jump on equals? */
					if (ia == ib)
						nextpc = tempp;
				}
				break;
................................................................................
					}
					
					/* Copy and store state. */
					*oldcpu = *cpu;
					cpu->parent = oldcpu;
					
					/* Setup CPU state for invoke run, move pool up. */
					for (ia = SJME_LOCAL_REGISTER_BASE;
						ia < SJME_MAX_REGISTERS; ia++)
						r[ia] = 0;
					r[SJME_POOL_REGISTER] =
						oldcpu->r[SJME_NEXT_POOL_REGISTER];
					r[SJME_NEXT_POOL_REGISTER] = 0;
					
					/* The address to execute. */
					ia = oldcpu->r[sjme_opdecodeui(&nextpc)];
					
					/* Load in register list (wide). */
					ib = sjme_memjreadp(1, &nextpc);
					if ((ib & SJME_JINT_C(0x80)) != 0)
................................................................................
					{
						/* Read values. */
						for (ic = 0; ic < ib; ic++)
							r[SJME_ARGBASE_REGISTER + ic] =
								oldcpu->r[sjme_memjreadp(1, &nextpc)];
					}
					
#if 0
					fprintf(stderr, "Invoke: %08lx\n", (long)ia);
					for (ic = 0; ic < ib; ic++)
						fprintf(stderr, "A%d: %d\n",
							(int)ic, (int)r[SJME_ARGBASE_REGISTER + ic]);
#endif
					
					/* Old PC address resumes where this read ended. */
					oldcpu->pc = nextpc;
					
					/* Our next PC becomes the target address. */
					nextpc = SJME_JINT_TO_POINTER(ia);
					cpu->pc = nextpc;
				}

Changes to runt/libs/summercoat-vm/cc/squirreljme/vm/summercoat/NativeCPU.java.

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
...
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
...
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
...
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
		Frame nowframe = null;
		int[] lr = null;
		int pc = -1,
			rp = -1;
		
		// Per operation handling
		final int[] args = new int[6];
		final long[] largs = new long[6];
		
		// Method cache to reduce tons of method reads
		final byte[] icache = new byte[METHOD_CACHE];
		int lasticache = -(METHOD_CACHE_SPILL + 1);
		
		// Execution is effectively an infinite loop
		LinkedList<Frame> frames = this._frames;
................................................................................
			
			// Read operation
			nowframe._lastpc = pc;
			int op = icache[bpc] & 0xFF;
			
			// Reset all input arguments
			for (int i = 0, n = args.length; i < n; i++)
			{
				args[i] = 0;
				largs[i] = 0;
			}
			
			// Register list, just one is used everywhere
			int[] reglist = null;
			
			// Load arguments for this instruction
			ArgumentFormat[] af = NativeInstruction.argumentFormat(op);
			int rargp = bpc + 1;
................................................................................
					case FLOAT32:
						args[i] = ((icache[rargp++] & 0xFF) << 24) |
							((icache[rargp++] & 0xFF) << 16) |
							((icache[rargp++] & 0xFF) << 8) |
							((icache[rargp++] & 0xFF));
						break;
					
					// 64-bit long/double
					case INT64:
					case FLOAT64:
						largs[i] = ((icache[rargp++] & 0xFFL) << 56L) |
							((icache[rargp++] & 0xFFL) << 48L) |
							((icache[rargp++] & 0xFFL) << 40L) |
							((icache[rargp++] & 0xFFL) << 32L) |
							((icache[rargp++] & 0xFFL) << 24L) |
							((icache[rargp++] & 0xFFL) << 16L) |
							((icache[rargp++] & 0xFFL) << 8L) |
							((icache[rargp++] & 0xFFL));
						break;
					
					default:
						throw new todo.OOPS(af[i].name());
				}
			
			// Print CPU debug info
			int encoding = NativeInstruction.encoding(op);
			if (ENABLE_DEBUG &&
				encoding != NativeInstructionType.DEBUG_ENTRY &&
				encoding != NativeInstructionType.DEBUG_EXIT &&
				encoding != NativeInstructionType.DEBUG_POINT)
				this.__cpuDebugPrint(nowframe, op, af, args, largs, reglist);
			
			// By default the next instruction is the address after all
			// arguments have been read
			int nextpc = lasticache + rargp;
			
			// Handle the operation
			switch (encoding)
			{
					// CPU Breakpoint
				case NativeInstructionType.BREAKPOINT:
					this.__cpuDebugPrint(nowframe, op, af, args, largs,
						reglist);
					
					// {@squirreljme.error AE04 CPU breakpoint hit.}
					throw new VMException("AE04");
				
					// Debug entry point of method
				case NativeInstructionType.DEBUG_ENTRY:
					this.__debugEntry(nowframe, args[0], args[1], args[2]);
					
					// Trace it!
					if (ENABLE_DEBUG)
						this.__cpuDebugPrint(nowframe, op, af, args, largs,
							reglist);
					break;
					
					// Debug exit of method
				case NativeInstructionType.DEBUG_EXIT:
					break;
					
					// Debug point in method.
................................................................................
	/**
	 * Performs some nice printing of CPU information.
	 *
	 * @param __nf The current frame.
	 * @param __op The operation.
	 * @param __af The argument format.
	 * @param __args Argument values.
	 * @param __largs Long argument values.
	 * @param __reglist The register list.
	 * @since 2019/04/23
	 */
	private final void __cpuDebugPrint(Frame __nf, int __op,
		ArgumentFormat[] __af, int[] __args, long[] __largs, int[] __reglist)
	{
		PrintStream out = System.err;
		
		// Limit class name
		CallTraceElement trace = this.trace(__nf);
		String cname = "" + trace.className();
		int nl;







<







 







<

<
<







 







<
<
<
<
<
<
<
<
<
<
<
<
<










|










|
<










|
<







 







<




|







170
171
172
173
174
175
176

177
178
179
180
181
182
183
...
231
232
233
234
235
236
237

238


239
240
241
242
243
244
245
...
303
304
305
306
307
308
309













310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
...
717
718
719
720
721
722
723

724
725
726
727
728
729
730
731
732
733
734
735
		Frame nowframe = null;
		int[] lr = null;
		int pc = -1,
			rp = -1;
		
		// Per operation handling
		final int[] args = new int[6];

		
		// Method cache to reduce tons of method reads
		final byte[] icache = new byte[METHOD_CACHE];
		int lasticache = -(METHOD_CACHE_SPILL + 1);
		
		// Execution is effectively an infinite loop
		LinkedList<Frame> frames = this._frames;
................................................................................
			
			// Read operation
			nowframe._lastpc = pc;
			int op = icache[bpc] & 0xFF;
			
			// Reset all input arguments
			for (int i = 0, n = args.length; i < n; i++)

				args[i] = 0;


			
			// Register list, just one is used everywhere
			int[] reglist = null;
			
			// Load arguments for this instruction
			ArgumentFormat[] af = NativeInstruction.argumentFormat(op);
			int rargp = bpc + 1;
................................................................................
					case FLOAT32:
						args[i] = ((icache[rargp++] & 0xFF) << 24) |
							((icache[rargp++] & 0xFF) << 16) |
							((icache[rargp++] & 0xFF) << 8) |
							((icache[rargp++] & 0xFF));
						break;
					













					default:
						throw new todo.OOPS(af[i].name());
				}
			
			// Print CPU debug info
			int encoding = NativeInstruction.encoding(op);
			if (ENABLE_DEBUG &&
				encoding != NativeInstructionType.DEBUG_ENTRY &&
				encoding != NativeInstructionType.DEBUG_EXIT &&
				encoding != NativeInstructionType.DEBUG_POINT)
				this.__cpuDebugPrint(nowframe, op, af, args, reglist);
			
			// By default the next instruction is the address after all
			// arguments have been read
			int nextpc = lasticache + rargp;
			
			// Handle the operation
			switch (encoding)
			{
					// CPU Breakpoint
				case NativeInstructionType.BREAKPOINT:
					this.__cpuDebugPrint(nowframe, op, af, args, reglist);

					
					// {@squirreljme.error AE04 CPU breakpoint hit.}
					throw new VMException("AE04");
				
					// Debug entry point of method
				case NativeInstructionType.DEBUG_ENTRY:
					this.__debugEntry(nowframe, args[0], args[1], args[2]);
					
					// Trace it!
					if (ENABLE_DEBUG)
						this.__cpuDebugPrint(nowframe, op, af, args, reglist);

					break;
					
					// Debug exit of method
				case NativeInstructionType.DEBUG_EXIT:
					break;
					
					// Debug point in method.
................................................................................
	/**
	 * Performs some nice printing of CPU information.
	 *
	 * @param __nf The current frame.
	 * @param __op The operation.
	 * @param __af The argument format.
	 * @param __args Argument values.

	 * @param __reglist The register list.
	 * @since 2019/04/23
	 */
	private final void __cpuDebugPrint(Frame __nf, int __op,
		ArgumentFormat[] __af, int[] __args, int[] __reglist)
	{
		PrintStream out = System.err;
		
		// Limit class name
		CallTraceElement trace = this.trace(__nf);
		String cname = "" + trace.className();
		int nl;