/[gxemul]/trunk/src/cpu.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

Diff of /trunk/src/cpu.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu.c,v 1.291 2005/03/13 09:36:08 debug Exp $   *  $Id: cpu.c,v 1.361 2006/10/25 09:24:05 debug Exp $
29   *   *
30   *  Common routines for CPU emulation. (Not specific to any CPU type.)   *  Common routines for CPU emulation. (Not specific to any CPU type.)
31   */   */
# Line 33  Line 33 
33  #include <stdio.h>  #include <stdio.h>
34  #include <stdlib.h>  #include <stdlib.h>
35  #include <sys/types.h>  #include <sys/types.h>
36    #include <sys/mman.h>
37  #include <string.h>  #include <string.h>
38    
39  #include "cpu.h"  #include "cpu.h"
40  #include "machine.h"  #include "machine.h"
41    #include "memory.h"
42  #include "misc.h"  #include "misc.h"
43    #include "settings.h"
   
 extern int quiet_mode;  
 extern int show_opcode_statistics;  
44    
45    
46  static struct cpu_family *first_cpu_family = NULL;  static struct cpu_family *first_cpu_family = NULL;
# Line 52  static struct cpu_family *first_cpu_fami Line 51  static struct cpu_family *first_cpu_fami
51   *   *
52   *  Create a new cpu object.  Each family is tried in sequence until a   *  Create a new cpu object.  Each family is tried in sequence until a
53   *  CPU family recognizes the cpu_type_name.   *  CPU family recognizes the cpu_type_name.
54     *
55     *  If there was no match, NULL is returned. Otherwise, a pointer to an
56     *  initialized cpu struct is returned.
57   */   */
58  struct cpu *cpu_new(struct memory *mem, struct machine *machine,  struct cpu *cpu_new(struct memory *mem, struct machine *machine,
59          int cpu_id, char *name)          int cpu_id, char *name)
60  {  {
61          struct cpu *c;          struct cpu *cpu;
62          struct cpu_family *fp;          struct cpu_family *fp;
63          char *cpu_type_name;          char *cpu_type_name;
64            char tmpstr[30];
65    
66          if (name == NULL) {          if (name == NULL) {
67                  fprintf(stderr, "cpu_new(): cpu name = NULL?\n");                  fprintf(stderr, "cpu_new(): cpu name = NULL?\n");
# Line 71  struct cpu *cpu_new(struct memory *mem, Line 74  struct cpu *cpu_new(struct memory *mem,
74                  exit(1);                  exit(1);
75          }          }
76    
77            cpu = zeroed_alloc(sizeof(struct cpu));
78    
79            cpu->memory_rw  = NULL;
80            cpu->name       = cpu_type_name;
81            cpu->mem        = mem;
82            cpu->machine    = machine;
83            cpu->cpu_id     = cpu_id;
84            cpu->byte_order = EMUL_UNDEFINED_ENDIAN;
85            cpu->running    = 0;
86    
87            /*  Create settings, and attach to the machine:  */
88            cpu->settings = settings_new();
89            snprintf(tmpstr, sizeof(tmpstr), "cpu[%i]", cpu_id);
90            settings_add(machine->settings, tmpstr, 1,
91                SETTINGS_TYPE_SUBSETTINGS, 0, cpu->settings);
92    
93            settings_add(cpu->settings, "name", 0, SETTINGS_TYPE_STRING,
94                SETTINGS_FORMAT_STRING, (void *) &cpu->name);
95            settings_add(cpu->settings, "running", 0, SETTINGS_TYPE_INT,
96                SETTINGS_FORMAT_YESNO, (void *) &cpu->running);
97    
98            cpu_create_or_reset_tc(cpu);
99    
100          fp = first_cpu_family;          fp = first_cpu_family;
101    
102          while (fp != NULL) {          while (fp != NULL) {
103                  if (fp->cpu_new != NULL) {                  if (fp->cpu_new != NULL) {
104                          c = fp->cpu_new(mem, machine, cpu_id, cpu_type_name);                          if (fp->cpu_new(cpu, mem, machine, cpu_id,
105                          if (c != NULL) {                              cpu_type_name)) {
106                                  /*  Some sanity-checks:  */                                  /*  Sanity check:  */
107                                  if (c->memory_rw == NULL) {                                  if (cpu->memory_rw == NULL) {
108                                          fatal("No memory_rw?\n");                                          fatal("\ncpu_new(): memory_rw == "
109                                                "NULL\n");
110                                          exit(1);                                          exit(1);
111                                  }                                  }
112                                    break;
                                 return c;  
113                          }                          }
114                  }                  }
115    
116                  fp = fp->next;                  fp = fp->next;
117          }          }
118    
119          fprintf(stderr, "cpu_new(): unknown cpu type '%s'\n", cpu_type_name);          if (fp == NULL) {
120          exit(1);                  fatal("\ncpu_new(): unknown cpu type '%s'\n", cpu_type_name);
121                    return NULL;
122            }
123    
124            fp->init_tables(cpu);
125    
126            if (cpu->byte_order == EMUL_UNDEFINED_ENDIAN) {
127                    fatal("\ncpu_new(): Internal bug: Endianness not set.\n");
128                    exit(1);
129            }
130    
131            return cpu;
132  }  }
133    
134    
135  /*  /*
136   *  cpu_show_full_statistics():   *  cpu_destroy():
137   *   *
138   *  Show detailed statistics on opcode usage on each cpu.   *  Destroy a cpu object.
139   */   */
140  void cpu_show_full_statistics(struct machine *m)  void cpu_destroy(struct cpu *cpu)
141  {  {
142          if (m->cpu_family == NULL ||          settings_remove(cpu->settings, "name");
143              m->cpu_family->show_full_statistics == NULL)          settings_remove(cpu->settings, "running");
144                  fatal("cpu_show_full_statistics(): NULL\n");  
145          else          /*  Remove any remaining level-1 settings:  */
146                  m->cpu_family->show_full_statistics(m);          settings_remove_all(cpu->settings);
147    
148            settings_destroy(cpu->settings);
149    
150            /*  TODO: This assumes that zeroed_alloc() actually succeeded
151                with using mmap(), and not malloc()!  */
152            munmap((void *)cpu, sizeof(struct cpu));
153  }  }
154    
155    
# Line 129  void cpu_tlbdump(struct machine *m, int Line 172  void cpu_tlbdump(struct machine *m, int
172    
173    
174  /*  /*
  *  cpu_register_match():  
  *  
  *  Used by the debugger.  
  */  
 void cpu_register_match(struct machine *m, char *name,  
         int writeflag, uint64_t *valuep, int *match_register)  
 {  
         if (m->cpu_family == NULL || m->cpu_family->register_match == NULL)  
                 fatal("cpu_register_match(): NULL\n");  
         else  
                 m->cpu_family->register_match(m, name, writeflag,  
                     valuep, match_register);  
 }  
   
   
 /*  
175   *  cpu_disassemble_instr():   *  cpu_disassemble_instr():
176   *   *
177   *  Convert an instruction word into human readable format, for instruction   *  Convert an instruction word into human readable format, for instruction
178   *  tracing.   *  tracing.
179   */   */
180  int cpu_disassemble_instr(struct machine *m, struct cpu *cpu,  int cpu_disassemble_instr(struct machine *m, struct cpu *cpu,
181          unsigned char *instr, int running, uint64_t addr, int bintrans)          unsigned char *instr, int running, uint64_t addr)
182  {  {
183          if (m->cpu_family == NULL || m->cpu_family->disassemble_instr == NULL) {          if (m->cpu_family == NULL || m->cpu_family->disassemble_instr == NULL) {
184                  fatal("cpu_disassemble_instr(): NULL\n");                  fatal("cpu_disassemble_instr(): NULL\n");
185                  return 0;                  return 0;
186          } else          } else
187                  return m->cpu_family->disassemble_instr(cpu, instr,                  return m->cpu_family->disassemble_instr(cpu, instr,
188                      running, addr, bintrans);                      running, addr);
189  }  }
190    
191    
# Line 167  int cpu_disassemble_instr(struct machine Line 194  int cpu_disassemble_instr(struct machine
194   *   *
195   *  Dump cpu registers in a relatively readable format.   *  Dump cpu registers in a relatively readable format.
196   *   *
197   *  gprs: set to non-zero to dump GPRs. (CPU dependant.)   *  gprs: set to non-zero to dump GPRs. (CPU dependent.)
198   *  coprocs: set bit 0..x to dump registers in coproc 0..x. (CPU dependant.)   *  coprocs: set bit 0..x to dump registers in coproc 0..x. (CPU dependent.)
199   */   */
200  void cpu_register_dump(struct machine *m, struct cpu *cpu,  void cpu_register_dump(struct machine *m, struct cpu *cpu,
201          int gprs, int coprocs)          int gprs, int coprocs)
# Line 181  void cpu_register_dump(struct machine *m Line 208  void cpu_register_dump(struct machine *m
208    
209    
210  /*  /*
211     *  cpu_gdb_stub():
212     *
213     *  Execute a "remote GDB" command. Return value is a pointer to a newly
214     *  allocated response string, if the command was successfully executed. If
215     *  there was an error, NULL is returned.
216     */
217    char *cpu_gdb_stub(struct cpu *cpu, char *cmd)
218    {
219            if (cpu->machine->cpu_family == NULL ||
220                cpu->machine->cpu_family->gdb_stub == NULL) {
221                    fatal("cpu_gdb_stub(): NULL\n");
222                    return NULL;
223            } else
224                    return cpu->machine->cpu_family->gdb_stub(cpu, cmd);
225    }
226    
227    
228    /*
229   *  cpu_interrupt():   *  cpu_interrupt():
230   *   *
231   *  Assert an interrupt.   *  Assert an interrupt.
# Line 215  int cpu_interrupt_ack(struct cpu *cpu, u Line 260  int cpu_interrupt_ack(struct cpu *cpu, u
260    
261    
262  /*  /*
263   *  cpu_run():   *  cpu_functioncall_trace():
264   *   *
265   *  Run instructions on all CPUs in this machine, for a "medium duration"   *  This function should be called if machine->show_trace_tree is enabled, and
266   *  (or until all CPUs have halted).   *  a function call is being made. f contains the address of the function.
267     */
268    void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
269    {
270            int i, n_args = -1;
271            char *symbol;
272            uint64_t offset;
273    
274            if (cpu->machine->ncpus > 1)
275                    fatal("cpu%i:\t", cpu->cpu_id);
276    
277            cpu->trace_tree_depth ++;
278            if (cpu->trace_tree_depth > 100)
279                    cpu->trace_tree_depth = 100;
280            for (i=0; i<cpu->trace_tree_depth; i++)
281                    fatal("  ");
282    
283            fatal("<");
284            symbol = get_symbol_name_and_n_args(&cpu->machine->symbol_context,
285                f, &offset, &n_args);
286            if (symbol != NULL)
287                    fatal("%s", symbol);
288            else {
289                    if (cpu->is_32bit)
290                            fatal("0x%"PRIx32, (uint32_t) f);
291                    else
292                            fatal("0x%"PRIx64, (uint64_t) f);
293            }
294            fatal("(");
295    
296            if (cpu->machine->cpu_family->functioncall_trace != NULL)
297                    cpu->machine->cpu_family->functioncall_trace(cpu, f, n_args);
298    
299            fatal(")>\n");
300    
301    #ifdef PRINT_MEMORY_CHECKSUM
302            /*  Temporary hack for finding bugs:  */
303            fatal("call chksum=%016"PRIx64"\n", memory_checksum(cpu->mem));
304    #endif
305    }
306    
307    
308    /*
309     *  cpu_functioncall_trace_return():
310   *   *
311   *  Return value is 1 if anything happened, 0 if all CPUs are stopped.   *  This function should be called if machine->show_trace_tree is enabled, and
312     *  a function is being returned from.
313     *
314     *  TODO: Print return value? This could be implemented similar to the
315     *  cpu->functioncall_trace function call above.
316   */   */
317  int cpu_run(struct emul *emul, struct machine *m)  void cpu_functioncall_trace_return(struct cpu *cpu)
318  {  {
319          if (m->cpu_family == NULL || m->cpu_family->run == NULL) {          cpu->trace_tree_depth --;
320                  fatal("cpu_run(): NULL\n");          if (cpu->trace_tree_depth < 0)
321                  return 0;                  cpu->trace_tree_depth = 0;
322          } else  }
323                  return m->cpu_family->run(emul, m);  
324    
325    /*
326     *  cpu_create_or_reset_tc():
327     *
328     *  Create the translation cache in memory (ie allocate memory for it), if
329     *  necessary, and then reset it to an initial state.
330     */
331    void cpu_create_or_reset_tc(struct cpu *cpu)
332    {
333            size_t s = DYNTRANS_CACHE_SIZE + DYNTRANS_CACHE_MARGIN;
334    
335            if (cpu->translation_cache == NULL)
336                    cpu->translation_cache = zeroed_alloc(s);
337    
338            /*  Create an empty table at the beginning of the translation cache:  */
339            memset(cpu->translation_cache, 0, sizeof(uint32_t)
340                * N_BASE_TABLE_ENTRIES);
341    
342            cpu->translation_cache_cur_ofs =
343                N_BASE_TABLE_ENTRIES * sizeof(uint32_t);
344    
345            /*
346             *  There might be other translation pointers that still point to
347             *  within the translation_cache region. Let's invalidate those too:
348             */
349            if (cpu->invalidate_code_translation != NULL)
350                    cpu->invalidate_code_translation(cpu, 0, INVALIDATE_ALL);
351  }  }
352    
353    
# Line 236  int cpu_run(struct emul *emul, struct ma Line 355  int cpu_run(struct emul *emul, struct ma
355   *  cpu_dumpinfo():   *  cpu_dumpinfo():
356   *   *
357   *  Dumps info about a CPU using debug(). "cpu0: CPUNAME, running" (or similar)   *  Dumps info about a CPU using debug(). "cpu0: CPUNAME, running" (or similar)
358   *  is outputed, and it is up to CPU dependant code to complete the line.   *  is outputed, and it is up to CPU dependent code to complete the line.
359   */   */
360  void cpu_dumpinfo(struct machine *m, struct cpu *cpu)  void cpu_dumpinfo(struct machine *m, struct cpu *cpu)
361  {  {
# Line 258  void cpu_dumpinfo(struct machine *m, str Line 377  void cpu_dumpinfo(struct machine *m, str
377  void cpu_list_available_types(void)  void cpu_list_available_types(void)
378  {  {
379          struct cpu_family *fp;          struct cpu_family *fp;
380          int iadd = 4;          int iadd = DEBUG_INDENTATION;
381    
382          fp = first_cpu_family;          fp = first_cpu_family;
383    
# Line 288  void cpu_list_available_types(void) Line 407  void cpu_list_available_types(void)
407   *  Shuts down all CPUs in a machine when ending a simulation. (This function   *  Shuts down all CPUs in a machine when ending a simulation. (This function
408   *  should only need to be called once for each machine.)   *  should only need to be called once for each machine.)
409   */   */
410  void cpu_run_deinit(struct emul *emul, struct machine *machine)  void cpu_run_deinit(struct machine *machine)
411  {  {
412          int te;          int te;
413    
414          /*          /*
415           *  Two last ticks of every hardware device.  This will allow           *  Two last ticks of every hardware device.  This will allow e.g.
416           *  framebuffers to draw the last updates to the screen before           *  framebuffers to draw the last updates to the screen before halting.
417           *  halting.           *
418             *  TODO: This should be refactored when redesigning the mainbus
419             *        concepts!
420           */           */
421          for (te=0; te<machine->n_tick_entries; te++) {          for (te=0; te<machine->n_tick_entries; te++) {
422                  machine->tick_func[te](machine->cpus[0],                  machine->tick_func[te](machine->cpus[0],
# Line 304  void cpu_run_deinit(struct emul *emul, s Line 425  void cpu_run_deinit(struct emul *emul, s
425                      machine->tick_extra[te]);                      machine->tick_extra[te]);
426          }          }
427    
428          debug("cpu_run_deinit(): All CPUs halted.\n");          if (machine->show_nr_of_instructions)
429                    cpu_show_cycles(machine, 1);
         if (machine->show_nr_of_instructions || !quiet_mode)  
                 cpu_show_cycles(machine, &machine->starttime,  
                     machine->ncycles, 1);  
   
         if (show_opcode_statistics)  
                 cpu_show_full_statistics(machine);  
430    
431          fflush(stdout);          fflush(stdout);
432  }  }
# Line 320  void cpu_run_deinit(struct emul *emul, s Line 435  void cpu_run_deinit(struct emul *emul, s
435  /*  /*
436   *  cpu_show_cycles():   *  cpu_show_cycles():
437   *   *
438   *  If automatic adjustment of clock interrupts is turned on, then recalculate   *  If show_nr_of_instructions is on, then print a line to stdout about how
439   *  emulated_hz.  Also, if show_nr_of_instructions is on, then print a   *  many instructions/cycles have been executed so far.
  *  line to stdout about how many instructions/cycles have been executed so  
  *  far.  
440   */   */
441  void cpu_show_cycles(struct machine *machine,  void cpu_show_cycles(struct machine *machine, int forced)
         struct timeval *starttime, int64_t ncycles, int forced)  
442  {  {
443          uint64_t offset, pc;          uint64_t offset, pc;
         int is_32bit = 0, instrs_per_cycle;  
444          char *symbol;          char *symbol;
445          int64_t mseconds, ninstrs;          int64_t mseconds, ninstrs, is, avg;
446          struct timeval tv;          struct timeval tv;
447          int h, m, s, ms, d;          struct cpu *cpu = machine->cpus[machine->bootstrap_cpu];
448    
449          static int64_t mseconds_last = 0;          static int64_t mseconds_last = 0;
450          static int64_t ninstrs_last = -1;          static int64_t ninstrs_last = -1;
451    
452          if (machine->arch != ARCH_MIPS) {          pc = cpu->pc;
                 fatal("cpu_show_cycles(): not yet for !MIPS\n");  
                 return;  
         }  
   
         if (machine->cpus[machine->bootstrap_cpu]->cd.mips.cpu_type.isa_level  
             < 3 || machine->cpus[machine->bootstrap_cpu]->cd.mips.cpu_type.  
             isa_level == 32)  
                 is_32bit = 1;  
         pc = machine->cpus[machine->bootstrap_cpu]->pc;  
         instrs_per_cycle = machine->cpus[machine->bootstrap_cpu]->  
             cd.mips.cpu_type.instrs_per_cycle;  
453    
454          gettimeofday(&tv, NULL);          gettimeofday(&tv, NULL);
455          mseconds = (tv.tv_sec - starttime->tv_sec) * 1000          mseconds = (tv.tv_sec - machine->starttime.tv_sec) * 1000
456                   + (tv.tv_usec - starttime->tv_usec) / 1000;                   + (tv.tv_usec - machine->starttime.tv_usec) / 1000;
457    
458          if (mseconds == 0)          if (mseconds == 0)
459                  mseconds = 1;                  mseconds = 1;
# Line 361  void cpu_show_cycles(struct machine *mac Line 461  void cpu_show_cycles(struct machine *mac
461          if (mseconds - mseconds_last == 0)          if (mseconds - mseconds_last == 0)
462                  mseconds ++;                  mseconds ++;
463    
464          ninstrs = ncycles * instrs_per_cycle;          ninstrs = machine->ninstrs_since_gettimeofday;
   
         if (machine->automatic_clock_adjustment) {  
                 static int first_adjustment = 1;  
   
                 /*  Current nr of cycles per second:  */  
                 int64_t cur_cycles_per_second = 1000 *  
                     (ninstrs-ninstrs_last) / (mseconds-mseconds_last)  
                     / instrs_per_cycle;  
   
                 if (cur_cycles_per_second < 1000000)  
                         cur_cycles_per_second = 1000000;  
   
                 if (first_adjustment) {  
                         machine->emulated_hz = cur_cycles_per_second;  
                         first_adjustment = 0;  
                 } else {  
                         machine->emulated_hz = (15 * machine->emulated_hz +  
                             cur_cycles_per_second) / 16;  
                 }  
   
                 debug("[ updating emulated_hz to %lli Hz ]\n",  
                     (long long)machine->emulated_hz);  
         }  
   
465    
466          /*  RETURN here, unless show_nr_of_instructions (-N) is turned on:  */          /*  RETURN here, unless show_nr_of_instructions (-N) is turned on:  */
467          if (!machine->show_nr_of_instructions && !forced)          if (!machine->show_nr_of_instructions && !forced)
468                  goto do_return;                  goto do_return;
469    
470            printf("[ %"PRIi64" instrs", (int64_t)machine->ninstrs);
         printf("[ ");  
   
         if (!machine->automatic_clock_adjustment) {  
                 d = machine->emulated_hz / 1000;  
                 if (d < 1)  
                         d = 1;  
                 ms = ncycles / d;  
                 h = ms / 3600000;  
                 ms -= 3600000 * h;  
                 m = ms / 60000;  
                 ms -= 60000 * m;  
                 s = ms / 1000;  
                 ms -= 1000 * s;  
   
                 printf("emulated time = %02i:%02i:%02i.%03i; ", h, m, s, ms);  
         }  
   
         printf("cycles=%lli", (long long) ncycles);  
   
         if (instrs_per_cycle > 1)  
                 printf(" (%lli instrs)", (long long) ninstrs);  
471    
472          /*  Instructions per second, and average so far:  */          /*  Instructions per second, and average so far:  */
473          printf("; i/s=%lli avg=%lli",          is = 1000 * (ninstrs-ninstrs_last) / (mseconds-mseconds_last);
474              (long long) ((long long)1000 * (ninstrs-ninstrs_last)          avg = (long long)1000 * ninstrs / mseconds;
475                  / (mseconds-mseconds_last)),          if (is < 0)
476              (long long) ((long long)1000 * ninstrs / mseconds));                  is = 0;
477            if (avg < 0)
478                    avg = 0;
479    
480            if (cpu->has_been_idling) {
481                    printf("; idling");
482                    cpu->has_been_idling = 0;
483            } else
484                    printf("; i/s=%"PRIi64" avg=%"PRIi64, is, avg);
485    
486          symbol = get_symbol_name(&machine->symbol_context, pc, &offset);          symbol = get_symbol_name(&machine->symbol_context, pc, &offset);
487    
488          if (is_32bit)          if (machine->ncpus == 1) {
489                  printf("; pc=%08x", (int)pc);                  if (cpu->is_32bit)
490          else                          printf("; pc=0x%08"PRIx32, (uint32_t) pc);
491                  printf("; pc=%016llx", (long long)pc);                  else
492                            printf("; pc=0x%016"PRIx64, (uint64_t) pc);
493            }
494    
495          printf(" <%s> ]\n", symbol? symbol : "no symbol");          if (symbol != NULL)
496                    printf(" <%s>", symbol);
497            printf(" ]\n");
498    
499  do_return:  do_return:
500          ninstrs_last = ninstrs;          ninstrs_last = ninstrs;
# Line 441  do_return: Line 508  do_return:
508   *  Prepare to run instructions on all CPUs in this machine. (This function   *  Prepare to run instructions on all CPUs in this machine. (This function
509   *  should only need to be called once for each machine.)   *  should only need to be called once for each machine.)
510   */   */
511  void cpu_run_init(struct emul *emul, struct machine *machine)  void cpu_run_init(struct machine *machine)
512  {  {
513          int ncpus = machine->ncpus;          machine->ninstrs_flush = 0;
514          int te;          machine->ninstrs = 0;
515            machine->ninstrs_show = 0;
         machine->a_few_cycles = 1048576;  
         machine->ncycles_flush = 0;  
         machine->ncycles = 0;  
         machine->ncycles_show = 0;  
   
         /*  
          *  Instead of doing { one cycle, check hardware ticks }, we  
          *  can do { n cycles, check hardware ticks }, as long as  
          *  n is at most as much as the lowest number of cycles/tick  
          *  for any hardware device.  
          */  
         for (te=0; te<machine->n_tick_entries; te++) {  
                 if (machine->ticks_reset_value[te] < machine->a_few_cycles)  
                         machine->a_few_cycles = machine->ticks_reset_value[te];  
         }  
   
         machine->a_few_cycles >>= 1;  
         if (machine->a_few_cycles < 1)  
                 machine->a_few_cycles = 1;  
   
         if (ncpus > 1 && machine->max_random_cycles_per_chunk == 0)  
                 machine->a_few_cycles = 1;  
   
         /*  debug("cpu_run_init(): a_few_cycles = %i\n",  
             machine->a_few_cycles);  */  
516    
517          /*  For performance measurement:  */          /*  For performance measurement:  */
518          gettimeofday(&machine->starttime, NULL);          gettimeofday(&machine->starttime, NULL);
519            machine->ninstrs_since_gettimeofday = 0;
520  }  }
521    
522    
# Line 546  struct cpu_family *cpu_family_ptr_by_num Line 589  struct cpu_family *cpu_family_ptr_by_num
589   *  cpu_init():   *  cpu_init():
590   *   *
591   *  Should be called before any other cpu_*() function.   *  Should be called before any other cpu_*() function.
592     *
593     *  TODO: Make this nicer by moving out the conditional stuff to
594     *  an automagically generated file? Or a define in config.h?
595   */   */
596  void cpu_init(void)  void cpu_init(void)
597  {  {
598          /*  Note: These are registered in alphabetic order.  */          /*  Note: These are registered in alphabetic order.  */
599    
600    #ifdef ENABLE_ALPHA
601          add_cpu_family(alpha_cpu_family_init, ARCH_ALPHA);          add_cpu_family(alpha_cpu_family_init, ARCH_ALPHA);
602    #endif
603    
604    #ifdef ENABLE_ARM
605            add_cpu_family(arm_cpu_family_init, ARCH_ARM);
606    #endif
607    
608    #ifdef ENABLE_AVR
609            add_cpu_family(avr_cpu_family_init, ARCH_AVR);
610    #endif
611    
612    #ifdef ENABLE_AVR32
613            add_cpu_family(avr32_cpu_family_init, ARCH_AVR32);
614    #endif
615    
616    #ifdef ENABLE_RCA180X
617            add_cpu_family(rca180x_cpu_family_init, ARCH_RCA180X);
618    #endif
619    
620    #ifdef ENABLE_HPPA
621          add_cpu_family(hppa_cpu_family_init, ARCH_HPPA);          add_cpu_family(hppa_cpu_family_init, ARCH_HPPA);
622    #endif
623    
624    #ifdef ENABLE_I960
625            add_cpu_family(i960_cpu_family_init, ARCH_I960);
626    #endif
627    
628    #ifdef ENABLE_IA64
629            add_cpu_family(ia64_cpu_family_init, ARCH_IA64);
630    #endif
631    
632    #ifdef ENABLE_M68K
633            add_cpu_family(m68k_cpu_family_init, ARCH_M68K);
634    #endif
635    
636    #ifdef ENABLE_MIPS
637          add_cpu_family(mips_cpu_family_init, ARCH_MIPS);          add_cpu_family(mips_cpu_family_init, ARCH_MIPS);
638    #endif
639    
640    #ifdef ENABLE_PPC
641          add_cpu_family(ppc_cpu_family_init, ARCH_PPC);          add_cpu_family(ppc_cpu_family_init, ARCH_PPC);
642    #endif
643    
644    #ifdef ENABLE_SH
645            add_cpu_family(sh_cpu_family_init, ARCH_SH);
646    #endif
647    
648    #ifdef ENABLE_SPARC
649          add_cpu_family(sparc_cpu_family_init, ARCH_SPARC);          add_cpu_family(sparc_cpu_family_init, ARCH_SPARC);
650          add_cpu_family(urisc_cpu_family_init, ARCH_URISC);  #endif
651    
652    #ifdef ENABLE_TRANSPUTER
653            add_cpu_family(transputer_cpu_family_init, ARCH_TRANSPUTER);
654    #endif
655    
656    #ifdef ENABLE_X86
657            add_cpu_family(x86_cpu_family_init, ARCH_X86);
658    #endif
659  }  }
660    

Legend:
Removed from v.2  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26