/[dynamips]/upstream/dynamips-0.2.7-RC2/ppc32_jit.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/dynamips-0.2.7-RC2/ppc32_jit.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Sat Oct 6 16:24:54 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 18718 byte(s)
dynamips-0.2.7-RC2

1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4 *
5 * PPC32 JIT compiler.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <sys/mman.h>
15 #include <signal.h>
16 #include <fcntl.h>
17 #include <assert.h>
18
19 #include "cpu.h"
20 #include "device.h"
21 #include "ppc32.h"
22 #include "ppc32_exec.h"
23 #include "ppc32_jit.h"
24 #include "insn_lookup.h"
25 #include "memory.h"
26 #include "ptask.h"
27
28 #include PPC32_ARCH_INC_FILE
29
30 /* Instruction Lookup Table */
31 static insn_lookup_t *ilt = NULL;
32
33 static void *ppc32_jit_get_insn(int index)
34 {
35 return(&ppc32_insn_tags[index]);
36 }
37
38 static int ppc32_jit_chk_lo(struct ppc32_insn_tag *tag,int value)
39 {
40 return((value & tag->mask) == (tag->value & 0xFFFF));
41 }
42
43 static int ppc32_jit_chk_hi(struct ppc32_insn_tag *tag,int value)
44 {
45 return((value & (tag->mask >> 16)) == (tag->value >> 16));
46 }
47
48 /* Initialize instruction lookup table */
49 void ppc32_jit_create_ilt(void)
50 {
51 int i,count;
52
53 for(i=0,count=0;ppc32_insn_tags[i].emit;i++)
54 count++;
55
56 ilt = ilt_create("ppc32j",count,
57 (ilt_get_insn_cbk_t)ppc32_jit_get_insn,
58 (ilt_check_cbk_t)ppc32_jit_chk_lo,
59 (ilt_check_cbk_t)ppc32_jit_chk_hi);
60 }
61
62 /* Initialize the JIT structure */
63 int ppc32_jit_init(cpu_ppc_t *cpu)
64 {
65 insn_exec_page_t *cp;
66 u_char *cp_addr;
67 u_int area_size;
68 size_t len;
69 int i;
70
71 /* JIT mapping for executable pages */
72 len = PPC_JIT_IA_HASH_SIZE * sizeof(void *);
73 cpu->exec_blk_map = m_memalign(4096,len);
74 memset(cpu->exec_blk_map,0,len);
75
76 /* Physical mapping for executable pages */
77 len = PPC_JIT_PHYS_HASH_SIZE * sizeof(void *);
78 cpu->exec_phys_map = m_memalign(4096,len);
79 memset(cpu->exec_phys_map,0,len);
80
81 /* Get area size */
82 if (!(area_size = cpu->vm->exec_area_size))
83 area_size = PPC_EXEC_AREA_SIZE;
84
85 /* Create executable page area */
86 cpu->exec_page_area_size = area_size * 1048576;
87 cpu->exec_page_area = mmap(NULL,cpu->exec_page_area_size,
88 PROT_EXEC|PROT_READ|PROT_WRITE,
89 MAP_SHARED|MAP_ANONYMOUS,-1,(off_t)0);
90
91 if (!cpu->exec_page_area) {
92 fprintf(stderr,
93 "ppc32_jit_init: unable to create exec area (size %lu)\n",
94 (u_long)cpu->exec_page_area_size);
95 return(-1);
96 }
97
98 /* Carve the executable page area */
99 cpu->exec_page_count = cpu->exec_page_area_size / PPC_JIT_BUFSIZE;
100
101 cpu->exec_page_array = calloc(cpu->exec_page_count,
102 sizeof(insn_exec_page_t));
103
104 if (!cpu->exec_page_array) {
105 fprintf(stderr,"ppc32_jit_init: unable to create exec page array\n");
106 return(-1);
107 }
108
109 for(i=0,cp_addr=cpu->exec_page_area;i<cpu->exec_page_count;i++) {
110 cp = &cpu->exec_page_array[i];
111
112 cp->ptr = cp_addr;
113 cp_addr += PPC_JIT_BUFSIZE;
114
115 cp->next = cpu->exec_page_free_list;
116 cpu->exec_page_free_list = cp;
117 }
118
119 printf("CPU%u: carved JIT exec zone of %lu Mb into %lu pages of %u Kb.\n",
120 cpu->gen->id,
121 (u_long)(cpu->exec_page_area_size / 1048576),
122 (u_long)cpu->exec_page_count,PPC_JIT_BUFSIZE / 1024);
123 return(0);
124 }
125
126 /* Flush the JIT */
127 u_int ppc32_jit_flush(cpu_ppc_t *cpu,u_int threshold)
128 {
129 ppc32_jit_tcb_t *p,*next;
130 m_uint32_t ia_hash;
131 u_int count = 0;
132
133 if (!threshold)
134 threshold = (u_int)(-1); /* UINT_MAX not defined everywhere */
135
136 for(p=cpu->tcb_list;p;p=next) {
137 next = p->next;
138
139 if (p->acc_count <= threshold) {
140 ia_hash = ppc32_jit_get_ia_hash(p->start_ia);
141 ppc32_jit_tcb_free(cpu,p,TRUE);
142
143 if (cpu->exec_blk_map[ia_hash] == p)
144 cpu->exec_blk_map[ia_hash] = NULL;
145 count++;
146 }
147 }
148
149 cpu->compiled_pages -= count;
150 return(count);
151 }
152
153 /* Shutdown the JIT */
154 void ppc32_jit_shutdown(cpu_ppc_t *cpu)
155 {
156 ppc32_jit_tcb_t *p,*next;
157
158 /* Flush the JIT */
159 ppc32_jit_flush(cpu,0);
160
161 /* Free the instruction blocks */
162 for(p=cpu->tcb_free_list;p;p=next) {
163 next = p->next;
164 free(p);
165 }
166
167 /* Unmap the executable page area */
168 if (cpu->exec_page_area)
169 munmap(cpu->exec_page_area,cpu->exec_page_area_size);
170
171 /* Free the exec page array */
172 free(cpu->exec_page_array);
173
174 /* Free JIT block mapping */
175 free(cpu->exec_blk_map);
176
177 /* Free physical mapping for executable pages */
178 free(cpu->exec_phys_map);
179 }
180
181 /* Allocate an exec page */
182 static inline insn_exec_page_t *exec_page_alloc(cpu_ppc_t *cpu)
183 {
184 insn_exec_page_t *p;
185 u_int count;
186
187 /* If the free list is empty, flush JIT */
188 if (unlikely(!cpu->exec_page_free_list))
189 {
190 if (cpu->jit_flush_method) {
191 cpu_log(cpu->gen,
192 "JIT","flushing data structures (compiled pages=%u)\n",
193 cpu->compiled_pages);
194 ppc32_jit_flush(cpu,0);
195 } else {
196 count = ppc32_jit_flush(cpu,100);
197 cpu_log(cpu->gen,"JIT","partial JIT flush (count=%u)\n",count);
198
199 if (!cpu->exec_page_free_list)
200 ppc32_jit_flush(cpu,0);
201 }
202
203 /* Use both methods alternatively */
204 cpu->jit_flush_method = 1 - cpu->jit_flush_method;
205 }
206
207 if (unlikely(!(p = cpu->exec_page_free_list)))
208 return NULL;
209
210 cpu->exec_page_free_list = p->next;
211 cpu->exec_page_alloc++;
212 return p;
213 }
214
215 /* Free an exec page and returns it to the pool */
216 static inline void exec_page_free(cpu_ppc_t *cpu,insn_exec_page_t *p)
217 {
218 if (p) {
219 p->next = cpu->exec_page_free_list;
220 cpu->exec_page_free_list = p;
221 cpu->exec_page_alloc--;
222 }
223 }
224
225 /* Find the JIT code emitter for the specified PowerPC instruction */
226 static struct ppc32_insn_tag *insn_tag_find(ppc_insn_t ins)
227 {
228 struct ppc32_insn_tag *tag = NULL;
229 int index;
230
231 index = ilt_lookup(ilt,ins);
232 tag = ppc32_jit_get_insn(index);
233 return tag;
234 }
235
236 /* Fetch a PowerPC instruction */
237 static forced_inline ppc_insn_t insn_fetch(ppc32_jit_tcb_t *b)
238 {
239 return(vmtoh32(b->ppc_code[b->ppc_trans_pos]));
240 }
241
242 /* Emit a breakpoint if necessary */
243 #if BREAKPOINT_ENABLE
244 static void insn_emit_breakpoint(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b)
245 {
246 m_uint32_t ia;
247 int i;
248
249 ia = b->start_ia+((b->ppc_trans_pos-1)<<2);
250
251 for(i=0;i<PPC32_MAX_BREAKPOINTS;i++)
252 if (ia == cpu->breakpoints[i]) {
253 ppc32_emit_breakpoint(b);
254 break;
255 }
256 }
257 #endif /* BREAKPOINT_ENABLE */
258
259 /* Fetch a PowerPC instruction and emit corresponding translated code */
260 struct ppc32_insn_tag *ppc32_jit_fetch_and_emit(cpu_ppc_t *cpu,
261 ppc32_jit_tcb_t *block)
262 {
263 struct ppc32_insn_tag *tag;
264 ppc_insn_t code;
265
266 code = insn_fetch(block);
267 tag = insn_tag_find(code);
268 assert(tag);
269
270 block->jit_insn_ptr[block->ppc_trans_pos] = block->jit_ptr;
271 block->ppc_trans_pos++;
272
273 #if DEBUG_INSN_PERF_CNT
274 ppc32_inc_perf_counter(block);
275 #endif
276
277 #if BREAKPOINT_ENABLE
278 if (cpu->breakpoints_enabled)
279 insn_emit_breakpoint(cpu,block);
280 #endif
281
282 tag->emit(cpu,block,code);
283 return tag;
284 }
285
286 /* Add end of JIT block */
287 static void ppc32_jit_tcb_add_end(ppc32_jit_tcb_t *b)
288 {
289 ppc32_set_ia(b,b->start_ia+(b->ppc_trans_pos<<2));
290 ppc32_jit_tcb_push_epilog(b);
291 }
292
293 /* Record a patch to apply in a compiled block */
294 int ppc32_jit_tcb_record_patch(ppc32_jit_tcb_t *block,u_char *jit_ptr,
295 m_uint32_t vaddr)
296 {
297 struct ppc32_jit_patch_table *ipt = block->patch_table;
298 struct ppc32_insn_patch *patch;
299
300 /* pc must be 32-bit aligned */
301 if (vaddr & 0x03) {
302 fprintf(stderr,"Block 0x%8.8x: trying to record an invalid IA "
303 "(0x%8.8x) - ppc_trans_pos=%d.\n",
304 block->start_ia,vaddr,block->ppc_trans_pos);
305 return(-1);
306 }
307
308 if (!ipt || (ipt->cur_patch >= PPC32_INSN_PATCH_TABLE_SIZE))
309 {
310 /* full table or no table, create a new one */
311 ipt = malloc(sizeof(*ipt));
312 if (!ipt) {
313 fprintf(stderr,"Block 0x%8.8x: unable to create patch table.\n",
314 block->start_ia);
315 return(-1);
316 }
317
318 memset(ipt,0,sizeof(*ipt));
319 ipt->next = block->patch_table;
320 block->patch_table = ipt;
321 }
322
323 #if DEBUG_BLOCK_PATCH
324 printf("Block 0x%8.8x: recording patch [JIT:%p->ppc:0x%8.8x], "
325 "MTP=%d\n",block->start_ia,jit_ptr,vaddr,block->ppc_trans_pos);
326 #endif
327
328 patch = &ipt->patches[ipt->cur_patch];
329 patch->jit_insn = jit_ptr;
330 patch->ppc_ia = vaddr;
331 ipt->cur_patch++;
332 return(0);
333 }
334
335 /* Apply all patches */
336 static int ppc32_jit_tcb_apply_patches(cpu_ppc_t *cpu,
337 ppc32_jit_tcb_t *block)
338 {
339 struct ppc32_jit_patch_table *ipt;
340 struct ppc32_insn_patch *patch;
341 u_char *jit_dst;
342 int i;
343
344 for(ipt=block->patch_table;ipt;ipt=ipt->next)
345 for(i=0;i<ipt->cur_patch;i++)
346 {
347 patch = &ipt->patches[i];
348 jit_dst = ppc32_jit_tcb_get_host_ptr(block,patch->ppc_ia);
349
350 if (jit_dst) {
351 #if DEBUG_BLOCK_PATCH
352 printf("Block 0x%8.8x: applying patch "
353 "[JIT:%p->ppc:0x%8.8x=JIT:%p]\n",
354 block->start_ia,patch->jit_insn,patch->ppc_ia,jit_dst);
355 #endif
356 ppc32_jit_tcb_set_patch(patch->jit_insn,jit_dst);
357 }
358 }
359
360 return(0);
361 }
362
363 /* Free the patch table */
364 static void ppc32_jit_tcb_free_patches(ppc32_jit_tcb_t *block)
365 {
366 struct ppc32_jit_patch_table *p,*next;
367
368 for(p=block->patch_table;p;p=next) {
369 next = p->next;
370 free(p);
371 }
372
373 block->patch_table = NULL;
374 }
375
376 /* Adjust the JIT buffer if its size is not sufficient */
377 static int ppc32_jit_tcb_adjust_buffer(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block)
378 {
379 insn_exec_page_t *new_buffer;
380
381 if ((block->jit_ptr - block->jit_buffer->ptr) <= (PPC_JIT_BUFSIZE - 512))
382 return(0);
383
384 #if DEBUG_BLOCK_CHUNK
385 printf("Block 0x%8.8x: adjusting JIT buffer...\n",block->start_ia);
386 #endif
387
388 if (block->jit_chunk_pos >= PPC_JIT_MAX_CHUNKS) {
389 fprintf(stderr,"Block 0x%8.8x: too many JIT chunks.\n",block->start_ia);
390 return(-1);
391 }
392
393 if (!(new_buffer = exec_page_alloc(cpu)))
394 return(-1);
395
396 /* record the new exec page */
397 block->jit_chunks[block->jit_chunk_pos++] = block->jit_buffer;
398 block->jit_buffer = new_buffer;
399
400 /* jump to the new exec page (link) */
401 ppc32_jit_tcb_set_jump(block->jit_ptr,new_buffer->ptr);
402 block->jit_ptr = new_buffer->ptr;
403 return(0);
404 }
405
406 /* Allocate an instruction block */
407 static inline ppc32_jit_tcb_t *ppc32_jit_tcb_alloc(cpu_ppc_t *cpu)
408 {
409 ppc32_jit_tcb_t *p;
410
411 if (cpu->tcb_free_list) {
412 p = cpu->tcb_free_list;
413 cpu->tcb_free_list = p->next;
414 } else {
415 if (!(p = malloc(sizeof(*p))))
416 return NULL;
417 }
418
419 memset(p,0,sizeof(*p));
420 return p;
421 }
422
423 /* Free an instruction block */
424 void ppc32_jit_tcb_free(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block,
425 int list_removal)
426 {
427 int i;
428
429 if (block) {
430 if (list_removal) {
431 /* Remove the block from the linked list */
432 if (block->next)
433 block->next->prev = block->prev;
434 else
435 cpu->tcb_last = block->prev;
436
437 if (block->prev)
438 block->prev->next = block->next;
439 else
440 cpu->tcb_list = block->next;
441
442 /* Remove the block from the physical mapping hash table */
443 if (block->phys_pprev) {
444 if (block->phys_next)
445 block->phys_next->phys_pprev = block->phys_pprev;
446
447 *(block->phys_pprev) = block->phys_next;
448
449 block->phys_pprev = NULL;
450 block->phys_next = NULL;
451 }
452 }
453
454 /* Free the patch tables */
455 ppc32_jit_tcb_free_patches(block);
456
457 /* Free code pages */
458 for(i=0;i<PPC_JIT_MAX_CHUNKS;i++)
459 exec_page_free(cpu,block->jit_chunks[i]);
460
461 /* Free the current JIT buffer */
462 exec_page_free(cpu,block->jit_buffer);
463
464 /* Free the PowerPC-to-native code mapping */
465 free(block->jit_insn_ptr);
466
467 block->next = cpu->tcb_free_list;
468 cpu->tcb_free_list = block;
469 }
470 }
471
472 /* Create an instruction block */
473 static ppc32_jit_tcb_t *ppc32_jit_tcb_create(cpu_ppc_t *cpu,m_uint32_t vaddr)
474 {
475 ppc32_jit_tcb_t *block = NULL;
476 m_uint32_t phys_page;
477
478 if (unlikely(cpu->translate(cpu,cpu->ia,PPC32_MTS_ICACHE,&phys_page)))
479 return NULL;
480
481 if (!(block = ppc32_jit_tcb_alloc(cpu)))
482 goto err_block_alloc;
483
484 block->start_ia = vaddr;
485 block->phys_page = phys_page;
486 block->phys_hash = ppc32_jit_get_phys_hash(phys_page);
487
488 /* Allocate the first JIT buffer */
489 if (!(block->jit_buffer = exec_page_alloc(cpu)))
490 goto err_jit_alloc;
491
492 block->jit_ptr = block->jit_buffer->ptr;
493 block->ppc_code = cpu->mem_op_lookup(cpu,block->start_ia,PPC32_MTS_ICACHE);
494
495 if (!block->ppc_code) {
496 fprintf(stderr,"%% No memory map for code execution at 0x%8.8x\n",
497 block->start_ia);
498 goto err_lookup;
499 }
500
501 #if DEBUG_BLOCK_TIMESTAMP
502 block->tm_first_use = block->tm_last_use = jit_jiffies;
503 #endif
504 return block;
505
506 err_lookup:
507 err_jit_alloc:
508 ppc32_jit_tcb_free(cpu,block,FALSE);
509 err_block_alloc:
510 fprintf(stderr,"%% Unable to create instruction block for vaddr=0x%8.8x\n",
511 vaddr);
512 return NULL;
513 }
514
515 /* Compile a PowerPC instruction page */
516 static inline
517 ppc32_jit_tcb_t *ppc32_jit_tcb_compile(cpu_ppc_t *cpu,m_uint32_t vaddr)
518 {
519 ppc32_jit_tcb_t *block;
520 struct ppc32_insn_tag *tag;
521 m_uint32_t page_addr;
522 size_t len;
523
524 page_addr = vaddr & ~PPC32_MIN_PAGE_IMASK;
525
526 if (unlikely(!(block = ppc32_jit_tcb_create(cpu,page_addr)))) {
527 fprintf(stderr,"insn_page_compile: unable to create JIT block.\n");
528 return NULL;
529 }
530
531 /* Allocate the array used to convert PPC code ptr to native code ptr */
532 len = PPC32_MIN_PAGE_SIZE / sizeof(ppc_insn_t);
533
534 if (!(block->jit_insn_ptr = calloc(len,sizeof(u_char *)))) {
535 fprintf(stderr,"insn_page_compile: unable to create JIT mappings.\n");
536 goto error;
537 }
538
539 /* Emit native code for each instruction */
540 block->ppc_trans_pos = 0;
541
542 while(block->ppc_trans_pos < (PPC32_MIN_PAGE_SIZE/sizeof(ppc_insn_t)))
543 {
544 if (unlikely(!(tag = ppc32_jit_fetch_and_emit(cpu,block)))) {
545 fprintf(stderr,"insn_page_compile: unable to fetch instruction.\n");
546 goto error;
547 }
548
549 #if DEBUG_BLOCK_COMPILE
550 printf("Page 0x%8.8x: emitted tag 0x%8.8x/0x%8.8x\n",
551 block->start_ia,tag->mask,tag->value);
552 #endif
553
554 ppc32_jit_tcb_adjust_buffer(cpu,block);
555 }
556
557 ppc32_jit_tcb_add_end(block);
558 ppc32_jit_tcb_apply_patches(cpu,block);
559 ppc32_jit_tcb_free_patches(block);
560
561 /* Add the block to the linked list */
562 block->next = cpu->tcb_list;
563 block->prev = NULL;
564
565 if (cpu->tcb_list)
566 cpu->tcb_list->prev = block;
567 else
568 cpu->tcb_last = block;
569
570 cpu->tcb_list = block;
571
572 /* Add the block to the physical mapping hash table */
573 block->phys_next = cpu->exec_phys_map[block->phys_hash];
574 block->phys_pprev = &cpu->exec_phys_map[block->phys_hash];
575
576 if (cpu->exec_phys_map[block->phys_hash] != NULL)
577 cpu->exec_phys_map[block->phys_hash]->phys_pprev = &block->phys_next;
578
579 cpu->exec_phys_map[block->phys_hash] = block;
580
581 cpu->compiled_pages++;
582 return block;
583
584 error:
585 ppc32_jit_tcb_free(cpu,block,FALSE);
586 return NULL;
587 }
588
589 /* Run a compiled PowerPC instruction block */
590 static forced_inline
591 void ppc32_jit_tcb_run(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block)
592 {
593 if (unlikely(cpu->ia & 0x03)) {
594 fprintf(stderr,"ppc32_jit_tcb_run: Invalid IA 0x%8.8x.\n",cpu->ia);
595 ppc32_dump_regs(cpu->gen);
596 ppc32_dump_mmu(cpu->gen);
597 cpu_stop(cpu->gen);
598 return;
599 }
600
601 /* Execute JIT compiled code */
602 ppc32_jit_tcb_exec(cpu,block);
603 }
604
605 /* Execute compiled PowerPC code */
606 void *ppc32_jit_run_cpu(cpu_gen_t *gen)
607 {
608 cpu_ppc_t *cpu = CPU_PPC32(gen);
609 pthread_t timer_irq_thread;
610 ppc32_jit_tcb_t *block;
611 m_uint32_t ia_hash;
612 int timer_irq_check = 0;
613
614 if (pthread_create(&timer_irq_thread,NULL,(void *)ppc32_timer_irq_run,cpu))
615 {
616 fprintf(stderr,
617 "VM '%s': unable to create Timer IRQ thread for CPU%u.\n",
618 cpu->vm->name,gen->id);
619 cpu_stop(cpu->gen);
620 return NULL;
621 }
622
623 gen->cpu_thread_running = TRUE;
624
625 start_cpu:
626 gen->idle_count = 0;
627
628 for(;;) {
629 if (unlikely(gen->state != CPU_STATE_RUNNING))
630 break;
631
632 #if DEBUG_BLOCK_PERF_CNT
633 cpu->perf_counter++;
634 #endif
635 /* Handle virtual idle loop */
636 if (unlikely(cpu->ia == cpu->idle_pc)) {
637 if (++gen->idle_count == gen->idle_max) {
638 cpu_idle_loop(gen);
639 gen->idle_count = 0;
640 }
641 }
642
643 /* Handle the virtual CPU clock */
644 if (++timer_irq_check == cpu->timer_irq_check_itv) {
645 timer_irq_check = 0;
646
647 if (cpu->timer_irq_pending && !cpu->irq_disable &&
648 (cpu->msr & PPC32_MSR_EE))
649 {
650 cpu->timer_irq_armed = 0;
651 cpu->timer_irq_pending--;
652
653 vm_set_irq(cpu->vm,0);
654 }
655 }
656
657 /* Check IRQs */
658 if (unlikely(cpu->irq_check))
659 ppc32_trigger_irq(cpu);
660
661 /* Get the JIT block corresponding to IA register */
662 ia_hash = ppc32_jit_get_ia_hash(cpu->ia);
663 block = cpu->exec_blk_map[ia_hash];
664
665 /* No block found, compile the page */
666 if (unlikely(!block) || unlikely(!ppc32_jit_tcb_match(cpu,block)))
667 {
668 if (block != NULL) {
669 ppc32_jit_tcb_free(cpu,block,TRUE);
670 cpu->exec_blk_map[ia_hash] = NULL;
671 }
672
673 block = ppc32_jit_tcb_compile(cpu,cpu->ia);
674
675 if (unlikely(!block)) {
676 fprintf(stderr,
677 "VM '%s': unable to compile block for CPU%u IA=0x%8.8x\n",
678 cpu->vm->name,gen->id,cpu->ia);
679 cpu_stop(gen);
680 break;
681 }
682
683 cpu->exec_blk_map[ia_hash] = block;
684 }
685
686 #if DEBUG_BLOCK_TIMESTAMP
687 block->tm_last_use = jit_jiffies++;
688 #endif
689 block->acc_count++;
690 ppc32_jit_tcb_run(cpu,block);
691 }
692
693 if (!cpu->ia) {
694 cpu_stop(gen);
695 cpu_log(gen,"JIT","IA=0, halting CPU.\n");
696 }
697
698 /* Check regularly if the CPU has been restarted */
699 while(gen->cpu_thread_running) {
700 gen->seq_state++;
701
702 switch(gen->state) {
703 case CPU_STATE_RUNNING:
704 gen->state = CPU_STATE_RUNNING;
705 goto start_cpu;
706
707 case CPU_STATE_HALTED:
708 gen->cpu_thread_running = FALSE;
709 pthread_join(timer_irq_thread,NULL);
710 break;
711 }
712
713 /* CPU is paused */
714 usleep(200000);
715 }
716
717 return NULL;
718 }

  ViewVC Help
Powered by ViewVC 1.1.26