/[dynamips]/trunk/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

Annotation of /trunk/ppc32_jit.c

Parent Directory Parent Directory | Revision Log Revision Log


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

1 dpavlin 7 /*
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 dpavlin 8 ilt = ilt_create("ppc32j",count,
57 dpavlin 7 (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 dpavlin 8 /* 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 dpavlin 7 /* Physical mapping for executable pages */
77 dpavlin 8 len = PPC_JIT_PHYS_HASH_SIZE * sizeof(void *);
78 dpavlin 7 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 dpavlin 8 m_uint32_t ia_hash;
131 dpavlin 7 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 dpavlin 8 ia_hash = ppc32_jit_get_ia_hash(p->start_ia);
141 dpavlin 7 ppc32_jit_tcb_free(cpu,p,TRUE);
142 dpavlin 8
143     if (cpu->exec_blk_map[ia_hash] == p)
144     cpu->exec_blk_map[ia_hash] = NULL;
145 dpavlin 7 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 dpavlin 8 /* Free JIT block mapping */
175     free(cpu->exec_blk_map);
176    
177 dpavlin 7 /* Free physical mapping for executable pages */
178 dpavlin 8 free(cpu->exec_phys_map);
179 dpavlin 7 }
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 dpavlin 8 static int ppc32_jit_tcb_adjust_buffer(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block)
378 dpavlin 7 {
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 dpavlin 8
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 dpavlin 7 }
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 dpavlin 8
467 dpavlin 7 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 dpavlin 8 m_uint32_t phys_page;
477 dpavlin 7
478 dpavlin 8 if (unlikely(cpu->translate(cpu,cpu->ia,PPC32_MTS_ICACHE,&phys_page)))
479     return NULL;
480    
481 dpavlin 7 if (!(block = ppc32_jit_tcb_alloc(cpu)))
482     goto err_block_alloc;
483    
484     block->start_ia = vaddr;
485 dpavlin 8 block->phys_page = phys_page;
486     block->phys_hash = ppc32_jit_get_phys_hash(phys_page);
487 dpavlin 7
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 dpavlin 8 /* 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 dpavlin 7 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 dpavlin 8 m_uint32_t ia_hash;
612 dpavlin 7 int timer_irq_check = 0;
613    
614 dpavlin 8 if (pthread_create(&timer_irq_thread,NULL,(void *)ppc32_timer_irq_run,cpu))
615 dpavlin 7 {
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 dpavlin 8 /* Check IRQs */
658     if (unlikely(cpu->irq_check))
659     ppc32_trigger_irq(cpu);
660 dpavlin 7
661 dpavlin 8 /* 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 dpavlin 7
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 dpavlin 8 cpu->exec_blk_map[ia_hash] = NULL;
671 dpavlin 7 }
672    
673     block = ppc32_jit_tcb_compile(cpu,cpu->ia);
674 dpavlin 8
675 dpavlin 7 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 dpavlin 8 cpu->exec_blk_map[ia_hash] = block;
684 dpavlin 7 }
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