@@ -22,6 +22,8 @@ int HEIGHT = 200;
2222#define WINDOW_WIDTH WIDTH*3
2323#define WINDOW_HEIGHT HEIGHT*3
2424
25+ static uint32_t * profiling_data = NULL ;
26+
2527// circular buffer of keypresses, so vm code can read them as it's ready
2628typedef struct {
2729 bool down ;
@@ -39,6 +41,29 @@ static int16_t audioBuffer[AUDIOBUFFER_LEN];
3941static int audioBufferWr = 0 ;
4042static int audioBufferRd = 0 ;
4143
44+ void profiling_init (uvm32_state_t * vmst ) {
45+ profiling_data = malloc (sizeof (uint32_t ) * UVM32_MEMORY_SIZE );
46+ memset (profiling_data , 0x00 , sizeof (uint32_t ) * UVM32_MEMORY_SIZE );
47+ }
48+
49+ void profiling_update (uvm32_state_t * vmst ) {
50+ uint32_t pc_rel = uvm32_getProgramCounter (vmst ) - 0x80000000 ;
51+ if (pc_rel > UVM32_MEMORY_SIZE ) {
52+ // don't handle PC being in extram
53+ printf ("pc > memory size! %08x\n" , pc_rel );
54+ } else {
55+ profiling_data [pc_rel ] += 1 ;
56+ }
57+ }
58+
59+ void profiling_dump (void ) {
60+ for (int i = 0 ;i < UVM32_MEMORY_SIZE ;i ++ ) {
61+ if (profiling_data [i ] > 0 ) {
62+ printf ("Addr %08x hit %d times\n" , 0x80000000 + i , profiling_data [i ]);
63+ }
64+ }
65+ }
66+
4267void key_enq (uint16_t scancode , bool down ) {
4368 keyBuffer [keyBufferWr ].scancode = scancode ;
4469 keyBuffer [keyBufferWr ].down = down ;
@@ -126,6 +151,7 @@ void usage(const char *name) {
126151 printf (" -h show help\n" );
127152 printf (" -i <num instructions> max instrs before requiring a syscall\n" );
128153 printf (" -e <extram size> numbers of bytes for extram\n" );
154+ printf (" -p enable profiling\n" );
129155 exit (1 );
130156}
131157
@@ -168,6 +194,7 @@ int main(int argc, char *argv[]) {
168194 SDL_Window * screen = NULL ;
169195 SDL_Event event ;
170196 SDL_Texture * render_target = NULL ;
197+ bool use_profiling = false;
171198
172199 // memory for vmst is very large, so allocate
173200 vmst = (uvm32_state_t * )malloc (sizeof (uvm32_state_t ));
@@ -177,7 +204,7 @@ int main(int argc, char *argv[]) {
177204 }
178205
179206 // parse commandline args
180- while ((c = getopt (argc , argv , "hi:e:W:H:" )) != -1 ) {
207+ while ((c = getopt (argc , argv , "hi:e:W:H:p " )) != -1 ) {
181208 switch (c ) {
182209 case 'h' :
183210 usage (argv [0 ]);
@@ -197,6 +224,9 @@ int main(int argc, char *argv[]) {
197224 case 'H' :
198225 HEIGHT = strtoll (optarg , NULL , 10 );
199226 break ;
227+ case 'p' :
228+ use_profiling = true;
229+ break ;
200230 }
201231 }
202232 if (optind < argc ) {
@@ -261,6 +291,10 @@ int main(int argc, char *argv[]) {
261291 }
262292 SDL_ResumeAudioStreamDevice (stream );
263293
294+ if (use_profiling ) {
295+ profiling_init (vmst );
296+ }
297+
264298 while (isrunning ) {
265299 SDL_PollEvent (& event );
266300
@@ -280,6 +314,10 @@ int main(int argc, char *argv[]) {
280314 break ;
281315 }
282316
317+ if (use_profiling ) {
318+ profiling_update (vmst );
319+ }
320+
283321 total_instrs += uvm32_run (vmst , & evt , max_instrs_per_run ); // num instructions before vm considered hung
284322 num_syscalls ++ ;
285323
@@ -396,6 +434,10 @@ int main(int argc, char *argv[]) {
396434
397435 printf ("Executed total of %lu instructions and %lu syscalls\n" , (unsigned long )total_instrs , (unsigned long )num_syscalls );
398436
437+ if (use_profiling ) {
438+ profiling_dump ();
439+ }
440+
399441 free (rom );
400442 if (extram_buf != NULL ) {
401443 free (extram_buf );
0 commit comments