Skip to content

Commit fc5a098

Browse files
committed
Add a "go-faster" integer register state primitive that replaces many Alien
invocations with one, and uses an integer array to avoid any store check.
1 parent 0f0b532 commit fc5a098

File tree

12 files changed

+329
-60
lines changed

12 files changed

+329
-60
lines changed

platforms/Cross/plugins/BochsIA32Plugin/BochsIA32Plugin.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* Bochs seems to use error code 1 for execution errors.
22
* So we use > 1 for various errors
33
*/
4+
#define NumIntegerRegisterStateFields 10 /* the 8 registers plus pc & flags */
5+
46
#define NoError 0
57
#define ExecutionError 1
68
#define BadCPUInstance 2
@@ -60,3 +62,9 @@ extern long errorAcorn();
6062
* The current log (if singleStep failed with SomethingLoggedError).
6163
*/
6264
extern char *getlog(long *len);
65+
66+
/*
67+
* Fill an integer array with the register state, including the pc and, if
68+
* appropriate, the condition code flags, etc.
69+
*/
70+
extern void storeIntegerRegisterStateOfinto(void *cpu, int *registerState);

platforms/Cross/plugins/BochsIA32Plugin/sqBochsIA32Plugin.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,22 @@ static bx_address last_read_address = (bx_address)-1; /* for RMW cycles */
233233
*len = blidx;
234234
return bochs_log;
235235
}
236+
237+
void
238+
storeIntegerRegisterStateOfinto(void *cpu, int *registerState)
239+
{
240+
/* N.B. EAX=0,ECX=1,EDX=2,EBX=3,ESP=4,EBP=5,ESI=6,EDI=7 */
241+
registerState[0] = bx_cpu.gen_reg[BX_32BIT_REG_EAX].dword.erx;
242+
registerState[1] = bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx;
243+
registerState[2] = bx_cpu.gen_reg[BX_32BIT_REG_ECX].dword.erx;
244+
registerState[3] = bx_cpu.gen_reg[BX_32BIT_REG_EDX].dword.erx;
245+
registerState[4] = bx_cpu.gen_reg[BX_32BIT_REG_ESP].dword.erx;
246+
registerState[5] = bx_cpu.gen_reg[BX_32BIT_REG_EBP].dword.erx;
247+
registerState[6] = bx_cpu.gen_reg[BX_32BIT_REG_EDI].dword.erx;
248+
registerState[7] = bx_cpu.gen_reg[BX_32BIT_REG_ESI].dword.erx;
249+
registerState[8] = bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx;
250+
registerState[9] = bx_cpu.eflags;
251+
}
236252
} // extern "C"
237253

238254
/*

platforms/Cross/plugins/BochsX64Plugin/BochsX64Plugin.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* Bochs seems to use error code 1 for execution errors.
22
* So we use > 1 for various errors
33
*/
4+
#define NumIntegerRegisterStateFields 18 /* the 16 registers plus pc & flags */
5+
46
#define NoError 0
57
#define ExecutionError 1
68
#define BadCPUInstance 2
@@ -61,3 +63,9 @@ extern long errorAcorn();
6163
* The current log (if singleStep failed with SomethingLoggedError).
6264
*/
6365
extern char *getlog(long *len);
66+
67+
/*
68+
* Fill an integer array with the register state, including the pc and, if
69+
* appropriate, the condition code flags, etc.
70+
*/
71+
extern void storeIntegerRegisterStateOfinto(void *cpu, long long *registerState);

platforms/Cross/plugins/BochsX64Plugin/sqBochsX64Plugin.cpp

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -81,23 +81,23 @@ static bx_address last_read_address = (bx_address)-1; /* for RMW cycles */
8181
bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.limit = 0xffff;
8282
bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled = 0xffffffff;
8383

84-
bx_cpu.gen_reg[BX_64BIT_REG_RAX].dword.erx = 0;
85-
bx_cpu.gen_reg[BX_64BIT_REG_RBX].dword.erx = 0;
86-
bx_cpu.gen_reg[BX_64BIT_REG_RCX].dword.erx = 0;
87-
bx_cpu.gen_reg[BX_64BIT_REG_RDX].dword.erx = 0;
88-
bx_cpu.gen_reg[BX_64BIT_REG_RSP].dword.erx = 0;
89-
bx_cpu.gen_reg[BX_64BIT_REG_RBP].dword.erx = 0;
90-
bx_cpu.gen_reg[BX_64BIT_REG_RSI].dword.erx = 0;
91-
bx_cpu.gen_reg[BX_64BIT_REG_RDI].dword.erx = 0;
92-
bx_cpu.gen_reg[BX_64BIT_REG_R8].dword.erx = 0;
93-
bx_cpu.gen_reg[BX_64BIT_REG_R9].dword.erx = 0;
94-
bx_cpu.gen_reg[BX_64BIT_REG_R10].dword.erx = 0;
95-
bx_cpu.gen_reg[BX_64BIT_REG_R11].dword.erx = 0;
96-
bx_cpu.gen_reg[BX_64BIT_REG_R12].dword.erx = 0;
97-
bx_cpu.gen_reg[BX_64BIT_REG_R13].dword.erx = 0;
98-
bx_cpu.gen_reg[BX_64BIT_REG_R14].dword.erx = 0;
99-
bx_cpu.gen_reg[BX_64BIT_REG_R15].dword.erx = 0;
100-
bx_cpu.gen_reg[BX_64BIT_REG_RIP].dword.erx = 0;
84+
bx_cpu.gen_reg[BX_64BIT_REG_RAX].rrx = 0;
85+
bx_cpu.gen_reg[BX_64BIT_REG_RBX].rrx = 0;
86+
bx_cpu.gen_reg[BX_64BIT_REG_RCX].rrx = 0;
87+
bx_cpu.gen_reg[BX_64BIT_REG_RDX].rrx = 0;
88+
bx_cpu.gen_reg[BX_64BIT_REG_RSP].rrx = 0;
89+
bx_cpu.gen_reg[BX_64BIT_REG_RBP].rrx = 0;
90+
bx_cpu.gen_reg[BX_64BIT_REG_RSI].rrx = 0;
91+
bx_cpu.gen_reg[BX_64BIT_REG_RDI].rrx = 0;
92+
bx_cpu.gen_reg[BX_64BIT_REG_R8 ].rrx = 0;
93+
bx_cpu.gen_reg[BX_64BIT_REG_R9 ].rrx = 0;
94+
bx_cpu.gen_reg[BX_64BIT_REG_R10].rrx = 0;
95+
bx_cpu.gen_reg[BX_64BIT_REG_R11].rrx = 0;
96+
bx_cpu.gen_reg[BX_64BIT_REG_R12].rrx = 0;
97+
bx_cpu.gen_reg[BX_64BIT_REG_R13].rrx = 0;
98+
bx_cpu.gen_reg[BX_64BIT_REG_R14].rrx = 0;
99+
bx_cpu.gen_reg[BX_64BIT_REG_R15].rrx = 0;
100+
bx_cpu.gen_reg[BX_64BIT_REG_RIP].rrx = 0;
101101
bx_cpu.efer.set_LMA(1); /* Hack. The old version we use have doesn't support set_EFER */
102102
bx_cpu.SetCR0(0x80000101); // Enter protected mode
103103
return bx_cpu.cpu_mode == BX_MODE_LONG_64
@@ -119,7 +119,7 @@ static bx_address last_read_address = (bx_address)-1; /* for RMW cycles */
119119
minReadAddress = minAddr;
120120
minWriteAddress = minWriteMaxExecAddr;
121121
if ((theErrorAcorn = setjmp(anx64->jmp_buf_env)) != 0) {
122-
anx64->gen_reg[BX_64BIT_REG_RIP].dword.erx = anx64->prev_rip;
122+
anx64->gen_reg[BX_64BIT_REG_RIP].rrx = anx64->prev_rip;
123123
return theErrorAcorn;
124124
}
125125

@@ -151,7 +151,7 @@ static bx_address last_read_address = (bx_address)-1; /* for RMW cycles */
151151
minReadAddress = minAddr;
152152
minWriteAddress = minWriteMaxExecAddr;
153153
if ((theErrorAcorn = setjmp(anx64->jmp_buf_env)) != 0) {
154-
anx64->gen_reg[BX_64BIT_REG_RIP].dword.erx = anx64->prev_rip;
154+
anx64->gen_reg[BX_64BIT_REG_RIP].rrx = anx64->prev_rip;
155155
return theErrorAcorn;
156156
}
157157

@@ -168,7 +168,7 @@ static bx_address last_read_address = (bx_address)-1; /* for RMW cycles */
168168
bx_pc_system.kill_bochs_request = 0;
169169
anx64->cpu_loop(0 /* = "run forever" until exception or interupt */);
170170
if (anx64->stop_reason != STOP_NO_REASON) {
171-
anx64->gen_reg[BX_64BIT_REG_RIP].dword.erx = anx64->prev_rip;
171+
anx64->gen_reg[BX_64BIT_REG_RIP].rrx = anx64->prev_rip;
172172
if (theErrorAcorn == NoError)
173173
theErrorAcorn = ExecutionError;
174174
return theErrorAcorn;
@@ -247,6 +247,29 @@ static bx_address last_read_address = (bx_address)-1; /* for RMW cycles */
247247
*len = blidx;
248248
return bochs_log;
249249
}
250+
void
251+
storeIntegerRegisterStateOfinto(void *cpu, long long *registerState)
252+
{
253+
/* N.B. RAX=0,RCX=1,RDX=2,RBX=3,RSP=4,RBP=5,RSI=6,RDI=7 */
254+
registerState[0] = bx_cpu.gen_reg[BX_64BIT_REG_RAX].rrx;
255+
registerState[1] = bx_cpu.gen_reg[BX_64BIT_REG_RBX].rrx;
256+
registerState[2] = bx_cpu.gen_reg[BX_64BIT_REG_RCX].rrx;
257+
registerState[3] = bx_cpu.gen_reg[BX_64BIT_REG_RDX].rrx;
258+
registerState[4] = bx_cpu.gen_reg[BX_64BIT_REG_RSP].rrx;
259+
registerState[5] = bx_cpu.gen_reg[BX_64BIT_REG_RBP].rrx;
260+
registerState[6] = bx_cpu.gen_reg[BX_64BIT_REG_RDI].rrx;
261+
registerState[7] = bx_cpu.gen_reg[BX_64BIT_REG_RSI].rrx;
262+
registerState[8] = bx_cpu.gen_reg[BX_64BIT_REG_R8 ].rrx;
263+
registerState[9] = bx_cpu.gen_reg[BX_64BIT_REG_R9 ].rrx;
264+
registerState[10] = bx_cpu.gen_reg[BX_64BIT_REG_R10].rrx;
265+
registerState[11] = bx_cpu.gen_reg[BX_64BIT_REG_R11].rrx;
266+
registerState[12] = bx_cpu.gen_reg[BX_64BIT_REG_R12].rrx;
267+
registerState[13] = bx_cpu.gen_reg[BX_64BIT_REG_R13].rrx;
268+
registerState[14] = bx_cpu.gen_reg[BX_64BIT_REG_R14].rrx;
269+
registerState[15] = bx_cpu.gen_reg[BX_64BIT_REG_R15].rrx;
270+
registerState[16] = bx_cpu.gen_reg[BX_64BIT_REG_RIP].rrx;
271+
registerState[17] = bx_cpu.eflags;
272+
}
250273
} // extern "C"
251274

252275
/*

platforms/Cross/plugins/GdbARMPlugin/GdbARMPlugin.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* Include file for the ARMv6/ARM32 processor simulator plugin, GdbARMPlugin */
22
/* heavily based on BochsIA32Plugin.h */
33

4+
#define NumIntegerRegisterStateFields 17 /* the 16 registers plus the flags */
5+
46
#define NoError 0
57
#define ExecutionError 1
68
#define BadCPUInstance 2
@@ -68,3 +70,9 @@ extern long errorAcorn();
6870
* The current log (if singleStep failed with SomethingLoggedError).
6971
*/
7072
extern char *getlog(long *len);
73+
74+
/*
75+
* Fill an integer array with the register state, including the pc and, if
76+
* appropriate, the condition code flags, etc.
77+
*/
78+
extern void storeIntegerRegisterStateOfinto(void *cpu, int *registerState);

platforms/Cross/plugins/GdbARMPlugin/sqGdbARMPlugin.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,18 @@ getlog(long *len)
212212
return gdb_log;
213213
}
214214

215+
void
216+
storeIntegerRegisterStateOfinto(void *cpu, int *registerState)
217+
{
218+
for (int n = -1; ++n < 16;)
219+
registerState[n] = ((ARMul_State *)cpu)->Reg[n];
220+
#if 1
221+
registerState[16] = ((ARMul_State *)cpu)->Cpsr;
222+
#else
223+
registerState[16] = ((((ARMul_State *)cpu)->NFlag & 1) << 5)
224+
+ ((((ARMul_State *)cpu)->ZFlag & 1) << 4)
225+
+ ((((ARMul_State *)cpu)->CFlag & 1) << 3)
226+
+ ((((ARMul_State *)cpu)->VFlag & 1) << 2)
227+
+ (((ARMul_State *)cpu)->IFFlags & 3);
228+
#endif
229+
}

platforms/Cross/plugins/GdbARMv8Plugin/GdbARMv8Plugin.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* Include file for the ARMv8/ARM64 processor simulator plugin, GdbARMv8Plugin */
22
/* heavily based on BochsIA32Plugin.h */
33

4+
#define NumIntegerRegisterStateFields 34 /* the 32 registers plus pc & flags */
5+
46
#define NoError 0
57
#define ExecutionError 1
68
#define BadCPUInstance 2
@@ -67,3 +69,9 @@ extern long errorAcorn();
6769
* The current log (if singleStep failed with SomethingLoggedError).
6870
*/
6971
extern char *getlog(long *len);
72+
73+
/*
74+
* Fill an integer array with the register state, including the pc and, if
75+
* appropriate, the condition code flags, etc.
76+
*/
77+
extern void storeIntegerRegisterStateOfinto(void *cpu, long long *registerState);

platforms/Cross/plugins/GdbARMv8Plugin/sqGdbARMv8Plugin.c

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,9 @@ runOnCPU(sim_cpu *cpu, void *memory,
9898
minWriteAddress = minWriteMaxExecAddr;
9999
theErrorAcorn = 0;
100100

101-
if ((theErrorAcorn = setjmp(error_abort)) != 0) {
102-
#if 0
103-
anx64->gen_reg[BX_64BIT_REG_RIP].dword.erx = anx64->prev_rip;
104-
#endif
101+
if ((theErrorAcorn = setjmp(error_abort)) != 0)
105102
return theErrorAcorn;
106-
}
103+
107104
assert(lastCPU->base.engine.jmpbuf = error_abort);
108105
gdblog_index = 0;
109106

@@ -231,27 +228,21 @@ getlog(long *len)
231228
return gdb_log;
232229
}
233230

231+
void
232+
storeIntegerRegisterStateOfinto(void *cpu, long long *registerState)
233+
{
234+
for (int n = -1; ++n < 32;)
235+
registerState[n] = ((sim_cpu *)cpu)->gr[n].u64;
236+
registerState[32] = ((sim_cpu *)cpu)->pc;
237+
registerState[33] = ((sim_cpu *)cpu)->CPSR;
238+
}
239+
234240
/* Adapted from sim/aarch64/memory.c -- Memory accessor functions for the AArch64 simulator
235241
236242
Copyright (C) 2015-2019 Free Software Foundation, Inc.
237243
238244
*/
239245

240-
#if 0
241-
#include "config.h"
242-
#include <sys/types.h>
243-
#include <stdio.h>
244-
#include <stdlib.h>
245-
#include <string.h>
246-
247-
#include "libiberty.h"
248-
249-
#include "memory.h"
250-
#include "simulator.h"
251-
252-
#include "sim-core.h"
253-
#endif
254-
255246
/* FIXME: AArch64 requires aligned memory access if SCTRLR_ELx.A is set,
256247
but we are not implementing that here. */
257248
#define FETCH_FUNC(RETURN_TYPE, ACCESS_TYPE, NAME, N) \

src/plugins/BochsIA32Plugin/BochsIA32Plugin.c

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/* Automatically generated by
2-
SmartSyntaxPluginCodeGenerator VMMaker.oscog-eem.2589 uuid: 5beddd90-a4e7-4e3d-95de-550f911e96b4
2+
SmartSyntaxPluginCodeGenerator VMMaker.oscog-eem.2660 uuid: 328ecbd4-9050-425b-9214-849fae63a95b
33
from
4-
BochsIA32Plugin Cog-eem.369 uuid: f98a0c3b-0dbe-42ae-8210-d628f7f84b98
4+
BochsIA32Plugin Cog-eem.389 uuid: aec9c8bf-988e-4ed0-8caa-ab2608f8abb6
55
*/
6-
static char __buildInfo[] = "BochsIA32Plugin Cog-eem.369 uuid: f98a0c3b-0dbe-42ae-8210-d628f7f84b98 " __DATE__ ;
6+
static char __buildInfo[] = "BochsIA32Plugin Cog-eem.389 uuid: aec9c8bf-988e-4ed0-8caa-ab2608f8abb6 " __DATE__ ;
77

88

99

@@ -77,6 +77,7 @@ EXPORT(const char*) getModuleName(void);
7777
EXPORT(sqInt) primitiveDisassembleAtInMemory(void);
7878
EXPORT(sqInt) primitiveErrorAndLog(void);
7979
EXPORT(sqInt) primitiveFlushICacheFromTo(void);
80+
EXPORT(sqInt) primitiveIntegerRegisterState(void);
8081
EXPORT(sqInt) primitiveNewCPU(void);
8182
EXPORT(sqInt) primitiveResetCPU(void);
8283
EXPORT(sqInt) primitiveRunInMemoryMinAddressMaxAddressReadWrite(void);
@@ -162,9 +163,9 @@ extern
162163
struct VirtualMachine* interpreterProxy;
163164
static const char *moduleName =
164165
#ifdef SQUEAK_BUILTIN_PLUGIN
165-
"BochsIA32Plugin Cog-eem.369 (i)"
166+
"BochsIA32Plugin Cog-eem.389 (i)"
166167
#else
167-
"BochsIA32Plugin Cog-eem.369 (e)"
168+
"BochsIA32Plugin Cog-eem.389 (e)"
168169
#endif
169170
;
170171

@@ -328,6 +329,51 @@ primitiveFlushICacheFromTo(void)
328329
return null;
329330
}
330331

332+
333+
/* Answer an IntegerArray of the processor's integer register state, ending
334+
with, if these are not otherwise
335+
included in the register state, the pc and the flags (if the processor has
336+
flags). The integer array will be an
337+
instance of the class argument, which must be large enough for the natural
338+
word size of the processor.
339+
340+
This primitive is unnecessary; it exists only to speed up single
341+
stepping.
342+
*/
343+
344+
/* ProcessorSimulatorPlugin>>#primitiveIntegerRegisterState: */
345+
EXPORT(sqInt)
346+
primitiveIntegerRegisterState(void)
347+
{
348+
void *cpu;
349+
sqInt cpuAlien;
350+
sqInt integerArrayClass;
351+
sqInt registerStateVector;
352+
353+
integerArrayClass = stackValue(0);
354+
cpuAlien = stackValue(1);
355+
if (failed()) {
356+
return null;
357+
}
358+
if (((cpu = ((void *) (((longAt(cpuAlien + BaseHeaderSize)) > 0
359+
? (cpuAlien + BaseHeaderSize) + BytesPerOop
360+
: longAt((cpuAlien + BaseHeaderSize) + BytesPerOop)))))) == 0) {
361+
return primitiveFailFor(PrimErrBadReceiver);
362+
}
363+
registerStateVector = instantiateClassindexableSize(integerArrayClass, NumIntegerRegisterStateFields);
364+
if (registerStateVector == 0) {
365+
return primitiveFailFor(PrimErrNoMemory);
366+
}
367+
if ((byteSizeOf(registerStateVector)) != (NumIntegerRegisterStateFields * (sizeof(int)))) {
368+
return primitiveFailFor(PrimErrBadArgument);
369+
}
370+
storeIntegerRegisterStateOfinto(cpu, firstIndexableField(registerStateVector));
371+
if (!(failed())) {
372+
popthenPush(2, registerStateVector);
373+
}
374+
return null;
375+
}
376+
331377
/* ProcessorSimulatorPlugin>>#primitiveNewCPU */
332378
EXPORT(sqInt)
333379
primitiveNewCPU(void)
@@ -705,6 +751,7 @@ void* BochsIA32Plugin_exports[][3] = {
705751
{(void*)_m, "primitiveDisassembleAtInMemory\000\000", (void*)primitiveDisassembleAtInMemory},
706752
{(void*)_m, "primitiveErrorAndLog\000\377", (void*)primitiveErrorAndLog},
707753
{(void*)_m, "primitiveFlushICacheFromTo\000\000", (void*)primitiveFlushICacheFromTo},
754+
{(void*)_m, "primitiveIntegerRegisterState\000\000", (void*)primitiveIntegerRegisterState},
708755
{(void*)_m, "primitiveNewCPU\000\377", (void*)primitiveNewCPU},
709756
{(void*)_m, "primitiveResetCPU\000\000", (void*)primitiveResetCPU},
710757
{(void*)_m, "primitiveRunInMemoryMinAddressMaxAddressReadWrite\000\000", (void*)primitiveRunInMemoryMinAddressMaxAddressReadWrite},
@@ -719,6 +766,7 @@ void* BochsIA32Plugin_exports[][3] = {
719766

720767
signed char primitiveDisassembleAtInMemoryAccessorDepth = 0;
721768
signed char primitiveFlushICacheFromToAccessorDepth = 0;
769+
signed char primitiveIntegerRegisterStateAccessorDepth = 0;
722770
signed char primitiveResetCPUAccessorDepth = 0;
723771
signed char primitiveRunInMemoryMinAddressMaxAddressReadWriteAccessorDepth = 0;
724772
signed char primitiveRunInMemoryMinimumAddressReadWriteAccessorDepth = 0;

0 commit comments

Comments
 (0)