/[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

Annotation of /trunk/src/cpu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 38 - (hide annotations)
Mon Oct 8 16:21:53 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 15000 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1515 2007/04/14 05:39:46 debug Exp $
20070324	Adding a "--debug" option to the configure script, to disable
		optimizations in unstable development builds.
		Moving out SCSI-specific stuff from diskimage.c into a new
		diskimage_scsicmd.c.
		Applying Hĺvard Eidnes' patch for SCSICDROM_READ_DISKINFO and
		SCSICDROM_READ_TRACKINFO. (Not really tested yet.)
		Implementing disk image "overlays" (to allow simple roll-back
		to previous disk state). Adding a 'V' disk flag for this, and
		updating the man page and misc.html.
20070325	Stability fix to cpu_dyntrans.c, when multiple physical pages
		share the same initial table entry. (The ppp == NULL check
		should be physpage_ofs == 0.) Bug found by analysing GXemul
		against a version patched for Godson.
		Fixing a second occurance of the same problem (also in
		cpu_dyntrans.c).
		Fixing a MAJOR physical page leak in cpu_dyntrans.c; pages
		weren't _added_ to the set of translated pages, they _replaced_
		all previous pages. It's amazing that this bug has been able
		to live for this long. (Triggered when emulating >128MB RAM.)
20070326	Removing the GDB debugging stub support; it was too hackish
		and ugly.
20070328	Moving around some native code generation skeleton code.
20070329	The -lm check in the configure script now also checks for sin()
		in addition to sqrt(). (Thanks to Nigel Horne for noticing that
		sqrt was not enough on Fedora Core 6.) (Not verified yet.)
20070330	Fixing an indexing bug in dev_sh4.c, found by using gcc version
		4.3.0 20070323.
20070331	Some more experimentation with native code generation.
20070404	Attempting to fix some more SH4 SCIF interrupt bugs; rewriting
		the SH interrupt assertion/deassertion code somewhat.
20070410	Splitting src/file.c into separate files in src/file/.
		Cleanup: Removing the dummy TS7200, Walnut, PB1000, and
		Meshcube emulation modes, and dev_epcom and dev_au1x00.
		Removing the experimental CHIP8/RCA180x code; it wasn't really
		working much lately, anyway. It was fun while it lasted.
		Also removing the experimental Transputer CPU support.
20070412	Moving the section about how the dynamic translation system
		works from intro.html to a separate translation.html file.
		Minor SH fixes; attempting to get OpenBSD/landisk to run
		without randomly bugging out, but no success yet.
20070413	SH SCI (serial bit interface) should now work together with a
		(new) RS5C313 clock device (for Landisk emulation).
20070414	Moving Redhat/MIPS down from supported to experimental, in
		guestoses.html.
		Preparing for a new release; doing some regression testing etc.

==============  RELEASE 0.4.5  ==============


1 dpavlin 2 /*
2 dpavlin 34 * Copyright (C) 2005-2007 Anders Gavare. All rights reserved.
3 dpavlin 2 *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28 dpavlin 38 * $Id: cpu.c,v 1.374 2007/04/10 17:26:19 debug Exp $
29 dpavlin 2 *
30     * Common routines for CPU emulation. (Not specific to any CPU type.)
31     */
32    
33     #include <stdio.h>
34     #include <stdlib.h>
35     #include <sys/types.h>
36 dpavlin 22 #include <sys/mman.h>
37 dpavlin 2 #include <string.h>
38    
39     #include "cpu.h"
40     #include "machine.h"
41 dpavlin 12 #include "memory.h"
42 dpavlin 2 #include "misc.h"
43 dpavlin 32 #include "settings.h"
44 dpavlin 2
45    
46 dpavlin 34 extern size_t dyntrans_cache_size;
47     extern int native_code_translation_enabled;
48    
49 dpavlin 2 static struct cpu_family *first_cpu_family = NULL;
50    
51    
52     /*
53     * cpu_new():
54     *
55     * Create a new cpu object. Each family is tried in sequence until a
56     * CPU family recognizes the cpu_type_name.
57 dpavlin 32 *
58     * If there was no match, NULL is returned. Otherwise, a pointer to an
59     * initialized cpu struct is returned.
60 dpavlin 2 */
61     struct cpu *cpu_new(struct memory *mem, struct machine *machine,
62     int cpu_id, char *name)
63     {
64 dpavlin 10 struct cpu *cpu;
65 dpavlin 2 struct cpu_family *fp;
66     char *cpu_type_name;
67 dpavlin 32 char tmpstr[30];
68 dpavlin 2
69     if (name == NULL) {
70     fprintf(stderr, "cpu_new(): cpu name = NULL?\n");
71     exit(1);
72     }
73    
74     cpu_type_name = strdup(name);
75     if (cpu_type_name == NULL) {
76     fprintf(stderr, "cpu_new(): out of memory\n");
77     exit(1);
78     }
79    
80 dpavlin 12 cpu = zeroed_alloc(sizeof(struct cpu));
81 dpavlin 10
82 dpavlin 34 cpu->path = malloc(strlen(machine->path) + 15);
83     if (cpu->path == NULL) {
84     fprintf(stderr, "cpu_new(): out of memory\n");
85     exit(1);
86     }
87     snprintf(cpu->path, strlen(machine->path) + 15,
88     "%s.cpu[%i]", machine->path, cpu_id);
89    
90 dpavlin 32 cpu->memory_rw = NULL;
91     cpu->name = cpu_type_name;
92     cpu->mem = mem;
93     cpu->machine = machine;
94     cpu->cpu_id = cpu_id;
95     cpu->byte_order = EMUL_UNDEFINED_ENDIAN;
96     cpu->running = 0;
97 dpavlin 10
98 dpavlin 32 /* Create settings, and attach to the machine: */
99     cpu->settings = settings_new();
100     snprintf(tmpstr, sizeof(tmpstr), "cpu[%i]", cpu_id);
101     settings_add(machine->settings, tmpstr, 1,
102     SETTINGS_TYPE_SUBSETTINGS, 0, cpu->settings);
103    
104     settings_add(cpu->settings, "name", 0, SETTINGS_TYPE_STRING,
105     SETTINGS_FORMAT_STRING, (void *) &cpu->name);
106     settings_add(cpu->settings, "running", 0, SETTINGS_TYPE_INT,
107     SETTINGS_FORMAT_YESNO, (void *) &cpu->running);
108    
109 dpavlin 12 cpu_create_or_reset_tc(cpu);
110    
111 dpavlin 2 fp = first_cpu_family;
112    
113     while (fp != NULL) {
114     if (fp->cpu_new != NULL) {
115 dpavlin 10 if (fp->cpu_new(cpu, mem, machine, cpu_id,
116     cpu_type_name)) {
117     /* Sanity check: */
118     if (cpu->memory_rw == NULL) {
119     fatal("\ncpu_new(): memory_rw == "
120     "NULL\n");
121 dpavlin 2 exit(1);
122     }
123 dpavlin 26 break;
124 dpavlin 2 }
125     }
126    
127     fp = fp->next;
128     }
129    
130 dpavlin 26 if (fp == NULL) {
131     fatal("\ncpu_new(): unknown cpu type '%s'\n", cpu_type_name);
132     return NULL;
133     }
134    
135     fp->init_tables(cpu);
136    
137 dpavlin 32 if (cpu->byte_order == EMUL_UNDEFINED_ENDIAN) {
138     fatal("\ncpu_new(): Internal bug: Endianness not set.\n");
139     exit(1);
140     }
141    
142 dpavlin 26 return cpu;
143 dpavlin 2 }
144    
145    
146     /*
147 dpavlin 32 * cpu_destroy():
148     *
149     * Destroy a cpu object.
150     */
151     void cpu_destroy(struct cpu *cpu)
152     {
153     settings_remove(cpu->settings, "name");
154     settings_remove(cpu->settings, "running");
155    
156     /* Remove any remaining level-1 settings: */
157     settings_remove_all(cpu->settings);
158    
159     settings_destroy(cpu->settings);
160    
161 dpavlin 34 if (cpu->path != NULL)
162     free(cpu->path);
163    
164 dpavlin 32 /* TODO: This assumes that zeroed_alloc() actually succeeded
165     with using mmap(), and not malloc()! */
166     munmap((void *)cpu, sizeof(struct cpu));
167     }
168    
169    
170     /*
171 dpavlin 2 * cpu_tlbdump():
172     *
173     * Called from the debugger to dump the TLB in a readable format.
174     * x is the cpu number to dump, or -1 to dump all CPUs.
175     *
176     * If rawflag is nonzero, then the TLB contents isn't formated nicely,
177     * just dumped.
178     */
179     void cpu_tlbdump(struct machine *m, int x, int rawflag)
180     {
181     if (m->cpu_family == NULL || m->cpu_family->tlbdump == NULL)
182     fatal("cpu_tlbdump(): NULL\n");
183     else
184     m->cpu_family->tlbdump(m, x, rawflag);
185     }
186    
187    
188     /*
189     * cpu_disassemble_instr():
190     *
191     * Convert an instruction word into human readable format, for instruction
192     * tracing.
193     */
194     int cpu_disassemble_instr(struct machine *m, struct cpu *cpu,
195 dpavlin 24 unsigned char *instr, int running, uint64_t addr)
196 dpavlin 2 {
197     if (m->cpu_family == NULL || m->cpu_family->disassemble_instr == NULL) {
198     fatal("cpu_disassemble_instr(): NULL\n");
199     return 0;
200     } else
201     return m->cpu_family->disassemble_instr(cpu, instr,
202 dpavlin 24 running, addr);
203 dpavlin 2 }
204    
205    
206     /*
207     * cpu_register_dump():
208     *
209     * Dump cpu registers in a relatively readable format.
210     *
211 dpavlin 18 * gprs: set to non-zero to dump GPRs. (CPU dependent.)
212     * coprocs: set bit 0..x to dump registers in coproc 0..x. (CPU dependent.)
213 dpavlin 2 */
214     void cpu_register_dump(struct machine *m, struct cpu *cpu,
215     int gprs, int coprocs)
216     {
217     if (m->cpu_family == NULL || m->cpu_family->register_dump == NULL)
218     fatal("cpu_register_dump(): NULL\n");
219     else
220     m->cpu_family->register_dump(cpu, gprs, coprocs);
221     }
222    
223    
224     /*
225 dpavlin 12 * cpu_functioncall_trace():
226     *
227     * This function should be called if machine->show_trace_tree is enabled, and
228     * a function call is being made. f contains the address of the function.
229     */
230     void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
231     {
232     int i, n_args = -1;
233     char *symbol;
234     uint64_t offset;
235    
236     if (cpu->machine->ncpus > 1)
237     fatal("cpu%i:\t", cpu->cpu_id);
238    
239     cpu->trace_tree_depth ++;
240 dpavlin 14 if (cpu->trace_tree_depth > 100)
241     cpu->trace_tree_depth = 100;
242 dpavlin 12 for (i=0; i<cpu->trace_tree_depth; i++)
243     fatal(" ");
244    
245     fatal("<");
246     symbol = get_symbol_name_and_n_args(&cpu->machine->symbol_context,
247     f, &offset, &n_args);
248     if (symbol != NULL)
249     fatal("%s", symbol);
250     else {
251     if (cpu->is_32bit)
252 dpavlin 24 fatal("0x%"PRIx32, (uint32_t) f);
253 dpavlin 12 else
254 dpavlin 24 fatal("0x%"PRIx64, (uint64_t) f);
255 dpavlin 12 }
256     fatal("(");
257    
258     if (cpu->machine->cpu_family->functioncall_trace != NULL)
259     cpu->machine->cpu_family->functioncall_trace(cpu, f, n_args);
260    
261     fatal(")>\n");
262 dpavlin 24
263     #ifdef PRINT_MEMORY_CHECKSUM
264     /* Temporary hack for finding bugs: */
265     fatal("call chksum=%016"PRIx64"\n", memory_checksum(cpu->mem));
266     #endif
267 dpavlin 12 }
268    
269    
270     /*
271     * cpu_functioncall_trace_return():
272     *
273     * This function should be called if machine->show_trace_tree is enabled, and
274     * a function is being returned from.
275     *
276     * TODO: Print return value? This could be implemented similar to the
277     * cpu->functioncall_trace function call above.
278     */
279     void cpu_functioncall_trace_return(struct cpu *cpu)
280     {
281     cpu->trace_tree_depth --;
282     if (cpu->trace_tree_depth < 0)
283     cpu->trace_tree_depth = 0;
284     }
285    
286    
287     /*
288     * cpu_create_or_reset_tc():
289     *
290     * Create the translation cache in memory (ie allocate memory for it), if
291     * necessary, and then reset it to an initial state.
292     */
293     void cpu_create_or_reset_tc(struct cpu *cpu)
294     {
295 dpavlin 34 size_t s = dyntrans_cache_size + DYNTRANS_CACHE_MARGIN;
296 dpavlin 12
297 dpavlin 34 if (cpu->translation_cache == NULL) {
298 dpavlin 24 cpu->translation_cache = zeroed_alloc(s);
299 dpavlin 22
300 dpavlin 34 #ifdef NATIVE_CODE_GENERATION
301     if (native_code_translation_enabled) {
302     mprotect(cpu->translation_cache, s,
303     PROT_READ | PROT_WRITE | PROT_EXEC);
304     }
305     #endif
306     }
307    
308 dpavlin 38 #ifdef NATIVE_CODE_GENERATION
309     if (native_code_translation_enabled && cpu->inr.inr_entries == NULL)
310     cpu->inr.inr_entries = zeroed_alloc(
311     sizeof(struct inr_entry) * INR_MAX_ENTRIES);
312 dpavlin 34
313 dpavlin 38 cpu->inr.nr_inr_entries_used = 0;
314     #endif
315    
316 dpavlin 12 /* Create an empty table at the beginning of the translation cache: */
317     memset(cpu->translation_cache, 0, sizeof(uint32_t)
318     * N_BASE_TABLE_ENTRIES);
319    
320     cpu->translation_cache_cur_ofs =
321     N_BASE_TABLE_ENTRIES * sizeof(uint32_t);
322    
323     /*
324     * There might be other translation pointers that still point to
325     * within the translation_cache region. Let's invalidate those too:
326     */
327 dpavlin 14 if (cpu->invalidate_code_translation != NULL)
328     cpu->invalidate_code_translation(cpu, 0, INVALIDATE_ALL);
329 dpavlin 12 }
330    
331    
332     /*
333 dpavlin 2 * cpu_dumpinfo():
334     *
335     * Dumps info about a CPU using debug(). "cpu0: CPUNAME, running" (or similar)
336 dpavlin 18 * is outputed, and it is up to CPU dependent code to complete the line.
337 dpavlin 2 */
338     void cpu_dumpinfo(struct machine *m, struct cpu *cpu)
339     {
340     debug("cpu%i: %s, %s", cpu->cpu_id, cpu->name,
341     cpu->running? "running" : "stopped");
342    
343     if (m->cpu_family == NULL || m->cpu_family->dumpinfo == NULL)
344     fatal("cpu_dumpinfo(): NULL\n");
345     else
346     m->cpu_family->dumpinfo(cpu);
347     }
348    
349    
350     /*
351     * cpu_list_available_types():
352     *
353     * Print a list of available CPU types for each cpu family.
354     */
355     void cpu_list_available_types(void)
356     {
357     struct cpu_family *fp;
358 dpavlin 22 int iadd = DEBUG_INDENTATION;
359 dpavlin 2
360     fp = first_cpu_family;
361    
362     if (fp == NULL) {
363     debug("No CPUs defined!\n");
364     return;
365     }
366    
367     while (fp != NULL) {
368     debug("%s:\n", fp->name);
369     debug_indentation(iadd);
370     if (fp->list_available_types != NULL)
371     fp->list_available_types();
372     else
373     debug("(internal error: list_available_types"
374     " = NULL)\n");
375     debug_indentation(-iadd);
376    
377     fp = fp->next;
378     }
379     }
380    
381    
382     /*
383     * cpu_run_deinit():
384     *
385     * Shuts down all CPUs in a machine when ending a simulation. (This function
386     * should only need to be called once for each machine.)
387     */
388 dpavlin 12 void cpu_run_deinit(struct machine *machine)
389 dpavlin 2 {
390     int te;
391    
392     /*
393 dpavlin 28 * Two last ticks of every hardware device. This will allow e.g.
394     * framebuffers to draw the last updates to the screen before halting.
395     *
396     * TODO: This should be refactored when redesigning the mainbus
397     * concepts!
398 dpavlin 2 */
399     for (te=0; te<machine->n_tick_entries; te++) {
400     machine->tick_func[te](machine->cpus[0],
401     machine->tick_extra[te]);
402     machine->tick_func[te](machine->cpus[0],
403     machine->tick_extra[te]);
404     }
405    
406 dpavlin 28 if (machine->show_nr_of_instructions)
407 dpavlin 10 cpu_show_cycles(machine, 1);
408 dpavlin 2
409     fflush(stdout);
410     }
411    
412    
413     /*
414     * cpu_show_cycles():
415     *
416 dpavlin 32 * If show_nr_of_instructions is on, then print a line to stdout about how
417     * many instructions/cycles have been executed so far.
418 dpavlin 2 */
419 dpavlin 10 void cpu_show_cycles(struct machine *machine, int forced)
420 dpavlin 2 {
421     uint64_t offset, pc;
422     char *symbol;
423 dpavlin 12 int64_t mseconds, ninstrs, is, avg;
424 dpavlin 2 struct timeval tv;
425 dpavlin 32 struct cpu *cpu = machine->cpus[machine->bootstrap_cpu];
426 dpavlin 2
427     static int64_t mseconds_last = 0;
428     static int64_t ninstrs_last = -1;
429    
430 dpavlin 32 pc = cpu->pc;
431 dpavlin 2
432     gettimeofday(&tv, NULL);
433 dpavlin 10 mseconds = (tv.tv_sec - machine->starttime.tv_sec) * 1000
434     + (tv.tv_usec - machine->starttime.tv_usec) / 1000;
435 dpavlin 2
436     if (mseconds == 0)
437     mseconds = 1;
438    
439     if (mseconds - mseconds_last == 0)
440     mseconds ++;
441    
442 dpavlin 28 ninstrs = machine->ninstrs_since_gettimeofday;
443 dpavlin 2
444     /* RETURN here, unless show_nr_of_instructions (-N) is turned on: */
445     if (!machine->show_nr_of_instructions && !forced)
446     goto do_return;
447    
448 dpavlin 28 printf("[ %"PRIi64" instrs", (int64_t)machine->ninstrs);
449 dpavlin 2
450     /* Instructions per second, and average so far: */
451 dpavlin 12 is = 1000 * (ninstrs-ninstrs_last) / (mseconds-mseconds_last);
452     avg = (long long)1000 * ninstrs / mseconds;
453     if (is < 0)
454     is = 0;
455     if (avg < 0)
456     avg = 0;
457 dpavlin 2
458 dpavlin 32 if (cpu->has_been_idling) {
459     printf("; idling");
460     cpu->has_been_idling = 0;
461     } else
462     printf("; i/s=%"PRIi64" avg=%"PRIi64, is, avg);
463    
464 dpavlin 2 symbol = get_symbol_name(&machine->symbol_context, pc, &offset);
465    
466 dpavlin 12 if (machine->ncpus == 1) {
467 dpavlin 32 if (cpu->is_32bit)
468 dpavlin 24 printf("; pc=0x%08"PRIx32, (uint32_t) pc);
469 dpavlin 12 else
470 dpavlin 24 printf("; pc=0x%016"PRIx64, (uint64_t) pc);
471 dpavlin 12 }
472 dpavlin 2
473 dpavlin 10 if (symbol != NULL)
474     printf(" <%s>", symbol);
475     printf(" ]\n");
476 dpavlin 2
477     do_return:
478     ninstrs_last = ninstrs;
479     mseconds_last = mseconds;
480     }
481    
482    
483     /*
484     * cpu_run_init():
485     *
486     * Prepare to run instructions on all CPUs in this machine. (This function
487     * should only need to be called once for each machine.)
488     */
489 dpavlin 12 void cpu_run_init(struct machine *machine)
490 dpavlin 2 {
491 dpavlin 28 machine->ninstrs_flush = 0;
492     machine->ninstrs = 0;
493     machine->ninstrs_show = 0;
494 dpavlin 2
495     /* For performance measurement: */
496     gettimeofday(&machine->starttime, NULL);
497 dpavlin 28 machine->ninstrs_since_gettimeofday = 0;
498 dpavlin 2 }
499    
500    
501     /*
502     * add_cpu_family():
503     *
504     * Allocates a cpu_family struct and calls an init function for the
505     * family to fill in reasonable data and pointers.
506     */
507     static void add_cpu_family(int (*family_init)(struct cpu_family *), int arch)
508     {
509     struct cpu_family *fp, *tmp;
510     int res;
511    
512     fp = malloc(sizeof(struct cpu_family));
513     if (fp == NULL) {
514     fprintf(stderr, "add_cpu_family(): out of memory\n");
515     exit(1);
516     }
517     memset(fp, 0, sizeof(struct cpu_family));
518    
519     /*
520     * family_init() returns 1 if the struct has been filled with
521     * valid data, 0 if suppor for the cpu family isn't compiled
522     * into the emulator.
523     */
524     res = family_init(fp);
525     if (!res) {
526     free(fp);
527     return;
528     }
529     fp->arch = arch;
530     fp->next = NULL;
531    
532     /* Add last in family chain: */
533     tmp = first_cpu_family;
534     if (tmp == NULL) {
535     first_cpu_family = fp;
536     } else {
537     while (tmp->next != NULL)
538     tmp = tmp->next;
539     tmp->next = fp;
540     }
541     }
542    
543    
544     /*
545     * cpu_family_ptr_by_number():
546     *
547     * Returns a pointer to a CPU family based on the ARCH_* integers.
548     */
549     struct cpu_family *cpu_family_ptr_by_number(int arch)
550     {
551     struct cpu_family *fp;
552     fp = first_cpu_family;
553    
554     /* YUCK! This is too hardcoded! TODO */
555    
556     while (fp != NULL) {
557     if (arch == fp->arch)
558     return fp;
559     fp = fp->next;
560     }
561    
562     return NULL;
563     }
564    
565    
566     /*
567     * cpu_init():
568     *
569     * Should be called before any other cpu_*() function.
570 dpavlin 32 *
571     * TODO: Make this nicer by moving out the conditional stuff to
572     * an automagically generated file? Or a define in config.h?
573 dpavlin 2 */
574     void cpu_init(void)
575     {
576     /* Note: These are registered in alphabetic order. */
577 dpavlin 12
578     #ifdef ENABLE_ALPHA
579     add_cpu_family(alpha_cpu_family_init, ARCH_ALPHA);
580     #endif
581    
582     #ifdef ENABLE_ARM
583 dpavlin 6 add_cpu_family(arm_cpu_family_init, ARCH_ARM);
584 dpavlin 12 #endif
585    
586 dpavlin 14 #ifdef ENABLE_AVR
587     add_cpu_family(avr_cpu_family_init, ARCH_AVR);
588     #endif
589    
590 dpavlin 12 #ifdef ENABLE_M68K
591     add_cpu_family(m68k_cpu_family_init, ARCH_M68K);
592     #endif
593    
594     #ifdef ENABLE_MIPS
595 dpavlin 2 add_cpu_family(mips_cpu_family_init, ARCH_MIPS);
596 dpavlin 12 #endif
597    
598     #ifdef ENABLE_PPC
599 dpavlin 2 add_cpu_family(ppc_cpu_family_init, ARCH_PPC);
600 dpavlin 12 #endif
601    
602 dpavlin 14 #ifdef ENABLE_SH
603     add_cpu_family(sh_cpu_family_init, ARCH_SH);
604     #endif
605    
606 dpavlin 12 #ifdef ENABLE_SPARC
607     add_cpu_family(sparc_cpu_family_init, ARCH_SPARC);
608     #endif
609 dpavlin 2 }
610    

  ViewVC Help
Powered by ViewVC 1.1.26