Commit ce11fedc6ecb6c6bedcff28e2a5ab3a864267245

Authored by bellard
1 parent 43d4145a

64 bit support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@76 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 124 additions and 145 deletions
dyngen.c
... ... @@ -22,25 +22,62 @@
22 22 #include <string.h>
23 23 #include <stdarg.h>
24 24 #include <inttypes.h>
25   -#include <elf.h>
26 25 #include <unistd.h>
27 26 #include <fcntl.h>
28 27  
29   -#include "thunk.h"
  28 +#include "config.h"
  29 +
  30 +/* elf format definitions. We use these macros to test the CPU to
  31 + allow cross compilation (this tool must be ran on the build
  32 + platform) */
  33 +#if defined(HOST_I386)
  34 +
  35 +#define ELF_CLASS ELFCLASS32
  36 +#define ELF_ARCH EM_386
  37 +#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
  38 +#undef ELF_USES_RELOCA
  39 +
  40 +#elif defined(HOST_PPC)
  41 +
  42 +#define ELF_CLASS ELFCLASS32
  43 +#define ELF_ARCH EM_PPC
  44 +#define elf_check_arch(x) ((x) == EM_PPC)
  45 +#define ELF_USES_RELOCA
  46 +
  47 +#elif defined(HOST_S390)
  48 +
  49 +#define ELF_CLASS ELFCLASS32
  50 +#define ELF_ARCH EM_S390
  51 +#define elf_check_arch(x) ((x) == EM_S390)
  52 +#define ELF_USES_RELOCA
30 53  
31   -/* temporary fix to make it compile with old elf headers (XXX: use
32   - included elf.h in all cases) */
33   -#ifndef EM_390
34   -#define EM_S390 22 /* IBM S390 */
35   -#define R_390_8 1 /* Direct 8 bit. */
36   -#define R_390_16 3 /* Direct 16 bit. */
37   -#define R_390_32 4 /* Direct 32 bit. */
  54 +#elif defined(HOST_ALPHA)
  55 +
  56 +#define ELF_CLASS ELFCLASS64
  57 +#define ELF_ARCH EM_ALPHA
  58 +#define elf_check_arch(x) ((x) == EM_ALPHA)
  59 +#define ELF_USES_RELOCA
  60 +
  61 +#else
  62 +#error unsupported CPU - please update the code
  63 +#endif
  64 +
  65 +#if ELF_CLASS == ELFCLASS32
  66 +typedef int32_t host_long;
  67 +typedef uint32_t host_ulong;
  68 +#else
  69 +typedef int64_t host_long;
  70 +typedef uint64_t host_ulong;
38 71 #endif
39 72  
  73 +#include "elf.h"
  74 +
  75 +#include "thunk.h"
  76 +
40 77 /* all dynamically generated functions begin with this code */
41 78 #define OP_PREFIX "op_"
42 79  
43   -int elf_must_swap(Elf32_Ehdr *h)
  80 +int elf_must_swap(struct elfhdr *h)
44 81 {
45 82 union {
46 83 uint32_t i;
... ... @@ -62,19 +99,25 @@ void swab32s(uint32_t *p)
62 99 *p = bswap32(*p);
63 100 }
64 101  
65   -void swab64s(uint32_t *p)
  102 +void swab64s(uint64_t *p)
66 103 {
67 104 *p = bswap64(*p);
68 105 }
69 106  
70   -void elf_swap_ehdr(Elf32_Ehdr *h)
  107 +#if ELF_CLASS == ELFCLASS32
  108 +#define swabls(x) swab32s(x)
  109 +#else
  110 +#define swabls(x) swab64s(x)
  111 +#endif
  112 +
  113 +void elf_swap_ehdr(struct elfhdr *h)
71 114 {
72 115 swab16s(&h->e_type); /* Object file type */
73 116 swab16s(&h-> e_machine); /* Architecture */
74 117 swab32s(&h-> e_version); /* Object file version */
75   - swab32s(&h-> e_entry); /* Entry point virtual address */
76   - swab32s(&h-> e_phoff); /* Program header table file offset */
77   - swab32s(&h-> e_shoff); /* Section header table file offset */
  118 + swabls(&h-> e_entry); /* Entry point virtual address */
  119 + swabls(&h-> e_phoff); /* Program header table file offset */
  120 + swabls(&h-> e_shoff); /* Section header table file offset */
78 121 swab32s(&h-> e_flags); /* Processor-specific flags */
79 122 swab16s(&h-> e_ehsize); /* ELF header size in bytes */
80 123 swab16s(&h-> e_phentsize); /* Program header table entry size */
... ... @@ -84,34 +127,33 @@ void elf_swap_ehdr(Elf32_Ehdr *h)
84 127 swab16s(&h-> e_shstrndx); /* Section header string table index */
85 128 }
86 129  
87   -void elf_swap_shdr(Elf32_Shdr *h)
  130 +void elf_swap_shdr(struct elf_shdr *h)
88 131 {
89 132 swab32s(&h-> sh_name); /* Section name (string tbl index) */
90 133 swab32s(&h-> sh_type); /* Section type */
91   - swab32s(&h-> sh_flags); /* Section flags */
92   - swab32s(&h-> sh_addr); /* Section virtual addr at execution */
93   - swab32s(&h-> sh_offset); /* Section file offset */
94   - swab32s(&h-> sh_size); /* Section size in bytes */
  134 + swabls(&h-> sh_flags); /* Section flags */
  135 + swabls(&h-> sh_addr); /* Section virtual addr at execution */
  136 + swabls(&h-> sh_offset); /* Section file offset */
  137 + swabls(&h-> sh_size); /* Section size in bytes */
95 138 swab32s(&h-> sh_link); /* Link to another section */
96 139 swab32s(&h-> sh_info); /* Additional section information */
97   - swab32s(&h-> sh_addralign); /* Section alignment */
98   - swab32s(&h-> sh_entsize); /* Entry size if section holds table */
  140 + swabls(&h-> sh_addralign); /* Section alignment */
  141 + swabls(&h-> sh_entsize); /* Entry size if section holds table */
99 142 }
100 143  
101   -void elf_swap_phdr(Elf32_Phdr *h)
  144 +void elf_swap_phdr(struct elf_phdr *h)
102 145 {
103 146 swab32s(&h->p_type); /* Segment type */
104   - swab32s(&h->p_offset); /* Segment file offset */
105   - swab32s(&h->p_vaddr); /* Segment virtual address */
106   - swab32s(&h->p_paddr); /* Segment physical address */
107   - swab32s(&h->p_filesz); /* Segment size in file */
108   - swab32s(&h->p_memsz); /* Segment size in memory */
  147 + swabls(&h->p_offset); /* Segment file offset */
  148 + swabls(&h->p_vaddr); /* Segment virtual address */
  149 + swabls(&h->p_paddr); /* Segment physical address */
  150 + swabls(&h->p_filesz); /* Segment size in file */
  151 + swabls(&h->p_memsz); /* Segment size in memory */
109 152 swab32s(&h->p_flags); /* Segment flags */
110   - swab32s(&h->p_align); /* Segment alignment */
  153 + swabls(&h->p_align); /* Segment alignment */
111 154 }
112 155  
113 156 int do_swap;
114   -int e_machine;
115 157  
116 158 uint16_t get16(uint16_t *p)
117 159 {
... ... @@ -157,12 +199,12 @@ void __attribute__((noreturn)) error(const char *fmt, ...)
157 199 }
158 200  
159 201  
160   -Elf32_Shdr *find_elf_section(Elf32_Shdr *shdr, int shnum, const char *shstr,
161   - const char *name)
  202 +struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr,
  203 + const char *name)
162 204 {
163 205 int i;
164 206 const char *shname;
165   - Elf32_Shdr *sec;
  207 + struct elf_shdr *sec;
166 208  
167 209 for(i = 0; i < shnum; i++) {
168 210 sec = &shdr[i];
... ... @@ -209,20 +251,21 @@ int strstart(const char *str, const char *val, const char **ptr)
209 251 #define MAX_ARGS 3
210 252  
211 253 /* generate op code */
212   -void gen_code(const char *name, unsigned long offset, unsigned long size,
213   - FILE *outfile, uint8_t *text, void *relocs, int nb_relocs, int reloc_sh_type,
214   - Elf32_Sym *symtab, char *strtab, int gen_switch)
  254 +void gen_code(const char *name, host_ulong offset, host_ulong size,
  255 + FILE *outfile, uint8_t *text, ELF_RELOC *relocs, int nb_relocs, int reloc_sh_type,
  256 + ElfW(Sym) *symtab, char *strtab, int gen_switch)
215 257 {
216 258 int copy_size = 0;
217 259 uint8_t *p_start, *p_end;
218   - int nb_args, i;
  260 + int nb_args, i, n;
219 261 uint8_t args_present[MAX_ARGS];
220 262 const char *sym_name, *p;
  263 + ELF_RELOC *rel;
221 264  
222 265 /* compute exact size excluding return instruction */
223 266 p_start = text + offset;
224 267 p_end = p_start + size;
225   - switch(e_machine) {
  268 + switch(ELF_ARCH) {
226 269 case EM_386:
227 270 {
228 271 uint8_t *p;
... ... @@ -256,40 +299,20 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
256 299 copy_size = p - p_start;
257 300 }
258 301 break;
259   - default:
260   - error("unsupported CPU (%d)", e_machine);
261 302 }
262 303  
263 304 /* compute the number of arguments by looking at the relocations */
264 305 for(i = 0;i < MAX_ARGS; i++)
265 306 args_present[i] = 0;
266 307  
267   - if (reloc_sh_type == SHT_REL) {
268   - Elf32_Rel *rel;
269   - int n;
270   - for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
271   - if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
272   - sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
273   - if (strstart(sym_name, "__op_param", &p)) {
274   - n = strtoul(p, NULL, 10);
275   - if (n >= MAX_ARGS)
276   - error("too many arguments in %s", name);
277   - args_present[n - 1] = 1;
278   - }
279   - }
280   - }
281   - } else {
282   - Elf32_Rela *rel;
283   - int n;
284   - for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
285   - if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
286   - sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
287   - if (strstart(sym_name, "__op_param", &p)) {
288   - n = strtoul(p, NULL, 10);
289   - if (n >= MAX_ARGS)
290   - error("too many arguments in %s", name);
291   - args_present[n - 1] = 1;
292   - }
  308 + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
  309 + if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
  310 + sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
  311 + if (strstart(sym_name, "__op_param", &p)) {
  312 + n = strtoul(p, NULL, 10);
  313 + if (n >= MAX_ARGS)
  314 + error("too many arguments in %s", name);
  315 + args_present[n - 1] = 1;
293 316 }
294 317 }
295 318 }
... ... @@ -319,24 +342,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
319 342 }
320 343 fprintf(outfile, " extern void %s();\n", name);
321 344  
322   - if (reloc_sh_type == SHT_REL) {
323   - Elf32_Rel *rel;
324   - for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
325   - if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
326   - sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
327   - if (!strstart(sym_name, "__op_param", &p)) {
328   - fprintf(outfile, "extern char %s;\n", sym_name);
329   - }
330   - }
331   - }
332   - } else {
333   - Elf32_Rela *rel;
334   - for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
335   - if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
336   - sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
337   - if (!strstart(sym_name, "__op_param", &p)) {
338   - fprintf(outfile, "extern char %s;\n", sym_name);
339   - }
  345 + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
  346 + if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
  347 + sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
  348 + if (!strstart(sym_name, "__op_param", &p)) {
  349 + fprintf(outfile, "extern char %s;\n", sym_name);
340 350 }
341 351 }
342 352 }
... ... @@ -347,13 +357,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
347 357 }
348 358  
349 359 /* patch relocations */
350   - switch(e_machine) {
351   - case EM_386:
  360 +#if defined(HOST_I386)
352 361 {
353   - Elf32_Rel *rel;
354 362 char name[256];
355 363 int type;
356   - long addend;
  364 + int addend;
357 365 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
358 366 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
359 367 sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
... ... @@ -366,11 +374,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
366 374 addend = get32((uint32_t *)(text + rel->r_offset));
367 375 switch(type) {
368 376 case R_386_32:
369   - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
  377 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
370 378 rel->r_offset - offset, name, addend);
371 379 break;
372 380 case R_386_PC32:
373   - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s - (long)(gen_code_ptr + %ld) + %ld;\n",
  381 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
374 382 rel->r_offset - offset, name, rel->r_offset - offset, addend);
375 383 break;
376 384 default:
... ... @@ -379,13 +387,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
379 387 }
380 388 }
381 389 }
382   - break;
383   - case EM_PPC:
  390 +#elif defined(HOST_PPC)
384 391 {
385   - Elf32_Rela *rel;
386 392 char name[256];
387 393 int type;
388   - long addend;
  394 + int addend;
389 395 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
390 396 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
391 397 sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
... ... @@ -398,24 +404,24 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
398 404 addend = rel->r_addend;
399 405 switch(type) {
400 406 case R_PPC_ADDR32:
401   - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
  407 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
402 408 rel->r_offset - offset, name, addend);
403 409 break;
404 410 case R_PPC_ADDR16_LO:
405   - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld);\n",
  411 + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
406 412 rel->r_offset - offset, name, addend);
407 413 break;
408 414 case R_PPC_ADDR16_HI:
409   - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld) >> 16;\n",
  415 + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
410 416 rel->r_offset - offset, name, addend);
411 417 break;
412 418 case R_PPC_ADDR16_HA:
413   - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld + 0x8000) >> 16;\n",
  419 + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
414 420 rel->r_offset - offset, name, addend);
415 421 break;
416 422 case R_PPC_REL24:
417 423 /* warning: must be at 32 MB distancy */
418   - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = (*(uint32_t *)(gen_code_ptr + %ld) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %ld) + %ld) & 0x03fffffc);\n",
  424 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
419 425 rel->r_offset - offset, rel->r_offset - offset, name, rel->r_offset - offset, addend);
420 426 break;
421 427 default:
... ... @@ -424,13 +430,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
424 430 }
425 431 }
426 432 }
427   - break;
428   - case EM_S390:
  433 +#elif defined(HOST_S390)
429 434 {
430   - Elf32_Rela *rel;
431 435 char name[256];
432 436 int type;
433   - long addend;
  437 + int addend;
434 438 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
435 439 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
436 440 sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
... ... @@ -443,15 +447,15 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
443 447 addend = rel->r_addend;
444 448 switch(type) {
445 449 case R_390_32:
446   - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
  450 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
447 451 rel->r_offset - offset, name, addend);
448 452 break;
449 453 case R_390_16:
450   - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
  454 + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",
451 455 rel->r_offset - offset, name, addend);
452 456 break;
453 457 case R_390_8:
454   - fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
  458 + fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
455 459 rel->r_offset - offset, name, addend);
456 460 break;
457 461 default:
... ... @@ -460,10 +464,9 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
460 464 }
461 465 }
462 466 }
463   - break;
464   - default:
465   - error("unsupported CPU for relocations (%d)", e_machine);
466   - }
  467 +#else
  468 +#error unsupported CPU
  469 +#endif
467 470 fprintf(outfile, " gen_code_ptr += %d;\n", copy_size);
468 471 fprintf(outfile, "}\n");
469 472 fprintf(outfile, "break;\n\n");
... ... @@ -492,11 +495,10 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
492 495 int load_elf(const char *filename, FILE *outfile, int do_print_enum)
493 496 {
494 497 int fd;
495   - Elf32_Ehdr ehdr;
496   - Elf32_Shdr *sec, *shdr, *symtab_sec, *strtab_sec, *text_sec;
  498 + struct elfhdr ehdr;
  499 + struct elf_shdr *sec, *shdr, *symtab_sec, *strtab_sec, *text_sec;
497 500 int i, j, nb_syms;
498   - Elf32_Sym *symtab, *sym;
499   - const char *cpu_name;
  501 + ElfW(Sym) *symtab, *sym;
500 502 char *shstr, *strtab;
501 503 uint8_t *text;
502 504 void *relocs;
... ... @@ -515,7 +517,6 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
515 517 || ehdr.e_ident[EI_MAG1] != ELFMAG1
516 518 || ehdr.e_ident[EI_MAG2] != ELFMAG2
517 519 || ehdr.e_ident[EI_MAG3] != ELFMAG3
518   - || ehdr.e_ident[EI_CLASS] != ELFCLASS32
519 520 || ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
520 521 error("bad ELF header");
521 522 }
... ... @@ -523,14 +524,17 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
523 524 do_swap = elf_must_swap(&ehdr);
524 525 if (do_swap)
525 526 elf_swap_ehdr(&ehdr);
  527 + if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
  528 + error("Unsupported ELF class");
526 529 if (ehdr.e_type != ET_REL)
527 530 error("ELF object file expected");
528 531 if (ehdr.e_version != EV_CURRENT)
529 532 error("Invalid ELF version");
530   - e_machine = ehdr.e_machine;
  533 + if (!elf_check_arch(ehdr.e_machine))
  534 + error("Unsupported CPU (e_machine=%d)", ehdr.e_machine);
531 535  
532 536 /* read section headers */
533   - shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(Elf32_Shdr));
  537 + shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(struct elf_shdr));
534 538 if (do_swap) {
535 539 for(i = 0; i < ehdr.e_shnum; i++) {
536 540 elf_swap_shdr(&shdr[i]);
... ... @@ -590,35 +594,12 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
590 594 if (do_swap) {
591 595 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
592 596 swab32s(&sym->st_name);
593   - swab32s(&sym->st_value);
594   - swab32s(&sym->st_size);
  597 + swabls(&sym->st_value);
  598 + swabls(&sym->st_size);
595 599 swab16s(&sym->st_shndx);
596 600 }
597 601 }
598 602  
599   - switch(e_machine) {
600   - case EM_386:
601   - cpu_name = "i386";
602   - break;
603   - case EM_PPC:
604   - cpu_name = "ppc";
605   - break;
606   - case EM_MIPS:
607   - cpu_name = "mips";
608   - break;
609   - case EM_ARM:
610   - cpu_name = "arm";
611   - break;
612   - case EM_SPARC:
613   - cpu_name = "sparc";
614   - break;
615   - case EM_S390:
616   - cpu_name = "s390";
617   - break;
618   - default:
619   - error("unsupported CPU (e_machine=%d)", e_machine);
620   - }
621   -
622 603 if (do_print_enum) {
623 604 fprintf(outfile, "DEF(end, 0)\n");
624 605 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
... ... @@ -669,7 +650,7 @@ fprintf(outfile,
669 650 );
670 651  
671 652 /* generate a return */
672   - switch(e_machine) {
  653 + switch(ELF_ARCH) {
673 654 case EM_386:
674 655 fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n");
675 656 break;
... ... @@ -679,8 +660,6 @@ fprintf(outfile,
679 660 case EM_S390:
680 661 fprintf(outfile, "*((uint16_t *)gen_code_ptr)++ = 0x07fe; /* br %%r14 */\n");
681 662 break;
682   - default:
683   - error("no return generation for cpu '%s'", cpu_name);
684 663 }
685 664  
686 665 fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n");
... ...