/[qemu]/qemu/dyngen.c
ViewVC logotype

Diff of /qemu/dyngen.c

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

revision 1.12 by bellard, Sun May 11 12:27:31 2003 UTC revision 1.13 by bellard, Tue May 13 18:59:59 2003 UTC
# Line 274  void gen_code(const char *name, host_ulo Line 274  void gen_code(const char *name, host_ulo
274  {  {
275      int copy_size = 0;      int copy_size = 0;
276      uint8_t *p_start, *p_end;      uint8_t *p_start, *p_end;
277        host_ulong start_offset;
278      int nb_args, i, n;      int nb_args, i, n;
279      uint8_t args_present[MAX_ARGS];      uint8_t args_present[MAX_ARGS];
280      const char *sym_name, *p;      const char *sym_name, *p;
281      ELF_RELOC *rel;      ELF_RELOC *rel;
282    
283      /* compute exact size excluding return instruction */      /* Compute exact size excluding prologue and epilogue instructions.
284         * Increment start_offset to skip epilogue instructions, then compute
285         * copy_size the indicate the size of the remaining instructions (in
286         * bytes).
287         */
288      p_start = text + offset;      p_start = text + offset;
289      p_end = p_start + size;      p_end = p_start + size;
290        start_offset = offset;
291      switch(ELF_ARCH) {      switch(ELF_ARCH) {
292      case EM_386:      case EM_386:
293          {          {
# Line 343  void gen_code(const char *name, host_ulo Line 349  void gen_code(const char *name, host_ulo
349      case EM_SPARC:      case EM_SPARC:
350      case EM_SPARC32PLUS:      case EM_SPARC32PLUS:
351          {          {
352                uint32_t start_insn, end_insn1, end_insn2, skip_insn;
353              uint8_t *p;              uint8_t *p;
354              p = (void *)(p_end - 8);              p = (void *)(p_end - 8);
355              if (p <= p_start)              if (p <= p_start)
356                  error("empty code for %s", name);                  error("empty code for %s", name);
357              if (get32((uint32_t *)(p_start + 0x0)) != 0x9de3bf98)              start_insn = get32((uint32_t *)(p_start + 0x0));
358                  error("save %%sp,-104,%%sp expected at the start of %s "              end_insn1 = get32((uint32_t *)(p + 0x0));
359                        "found [%08x]",              end_insn2 = get32((uint32_t *)(p + 0x4));
360                        name, get32((uint32_t *)(p_start + 0x0)));              if ((start_insn & ~0x1fff) == 0x9de3a000) {
361              if (get32((uint32_t *)(p + 0x0)) != 0x81c7e008 ||                  p_start += 0x4;
362                  get32((uint32_t *)(p + 0x4)) != 0x81e80000)                  start_offset += 0x4;
363                  error("ret; restore; expected at the end of %s found [%08x:%08x]",                  if ((int)(start_insn | ~0x1fff) < -128)
364                        name,                      error("Found bogus save at the start of %s", name);
365                        get32((uint32_t *)(p + 0x0)),                  if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000)
366                        get32((uint32_t *)(p + 0x4)));                      error("ret; restore; not found at end of %s", name);
367                } else {
368                    error("No save at the beginning of %s", name);
369                }
370    
371                /* Skip a preceeding nop, if present.  */
372                if (p > p_start) {
373                    skip_insn = get32((uint32_t *)(p - 0x4));
374                    if (skip_insn == 0x01000000)
375                        p -= 4;
376                }
377    
378              copy_size = p - p_start;              copy_size = p - p_start;
379          }          }
380          break;          break;
381      case EM_SPARCV9:      case EM_SPARCV9:
382          {          {
383                uint32_t start_insn, end_insn1, end_insn2, skip_insn;
384              uint8_t *p;              uint8_t *p;
385              p = (void *)(p_end - 8);              p = (void *)(p_end - 8);
386              if (p <= p_start)              if (p <= p_start)
387                  error("empty code for %s", name);                  error("empty code for %s", name);
388              if (get32((uint32_t *)(p_start + 0x0)) != 0x9de3bf40)              start_insn = get32((uint32_t *)(p_start + 0x0));
389                  error("save %%sp,-192,%%sp expected at the start of %s "              end_insn1 = get32((uint32_t *)(p + 0x0));
390                        "found [%08x]",              end_insn2 = get32((uint32_t *)(p + 0x4));
391                        name, get32((uint32_t *)(p_start + 0x0)));              if ((start_insn & ~0x1fff) == 0x9de3a000) {
392              if (get32((uint32_t *)(p + 0x0)) != 0x81cfe008 ||                  p_start += 0x4;
393                  get32((uint32_t *)(p + 0x4)) != 0x01000000)                  start_offset += 0x4;
394                  error("rett %%i7+8; nop; expected at the end of %s "                  if ((int)(start_insn | ~0x1fff) < -256)
395                        "found [%08x:%08x]",                      error("Found bogus save at the start of %s", name);
396                        name,                  if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000)
397                        get32((uint32_t *)(p + 0x0)),                      error("ret; restore; not found at end of %s", name);
398                        get32((uint32_t *)(p + 0x4)));              } else {
399                    error("No save at the beginning of %s", name);
400                }
401    
402                /* Skip a preceeding nop, if present.  */
403                if (p > p_start) {
404                    skip_insn = get32((uint32_t *)(p - 0x4));
405                    if (skip_insn == 0x01000000)
406                        p -= 4;
407                }
408    
409              copy_size = p - p_start;              copy_size = p - p_start;
410          }          }
411          break;          break;
# Line 390  void gen_code(const char *name, host_ulo Line 418  void gen_code(const char *name, host_ulo
418          args_present[i] = 0;          args_present[i] = 0;
419    
420      for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {      for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
421          if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {          if (rel->r_offset >= start_offset &&
422                rel->r_offset < start_offset + copy_size) {
423              sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;              sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
424              if (strstart(sym_name, "__op_param", &p)) {              if (strstart(sym_name, "__op_param", &p)) {
425                  n = strtoul(p, NULL, 10);                  n = strtoul(p, NULL, 10);
# Line 427  void gen_code(const char *name, host_ulo Line 456  void gen_code(const char *name, host_ulo
456          fprintf(outfile, "    extern void %s();\n", name);          fprintf(outfile, "    extern void %s();\n", name);
457    
458          for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {          for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
459              if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {              if (rel->r_offset >= start_offset &&
460                    rel->r_offset < start_offset + copy_size) {
461                  sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                  sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
462                  if (*sym_name && !strstart(sym_name, "__op_param", &p)) {                  if (*sym_name && !strstart(sym_name, "__op_param", &p)) {
463  #if defined(HOST_SPARC)  #if defined(HOST_SPARC)
# Line 443  void gen_code(const char *name, host_ulo Line 473  void gen_code(const char *name, host_ulo
473              }              }
474          }          }
475    
476          fprintf(outfile, "    memcpy(gen_code_ptr, &%s, %d);\n", name, copy_size);          fprintf(outfile, "    memcpy(gen_code_ptr, (void *)((char *)&%s+%d), %d);\n", name, start_offset - offset, copy_size);
477          for(i = 0; i < nb_args; i++) {          for(i = 0; i < nb_args; i++) {
478              fprintf(outfile, "    param%d = *opparam_ptr++;\n", i + 1);              fprintf(outfile, "    param%d = *opparam_ptr++;\n", i + 1);
479          }          }
# Line 455  void gen_code(const char *name, host_ulo Line 485  void gen_code(const char *name, host_ulo
485                  int type;                  int type;
486                  int addend;                  int addend;
487                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
488                  if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {                  if (rel->r_offset >= start_offset &&
489                        rel->r_offset < start_offset + copy_size) {
490                      sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                      sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
491                      if (strstart(sym_name, "__op_param", &p)) {                      if (strstart(sym_name, "__op_param", &p)) {
492                          snprintf(name, sizeof(name), "param%s", p);                          snprintf(name, sizeof(name), "param%s", p);
# Line 467  void gen_code(const char *name, host_ulo Line 498  void gen_code(const char *name, host_ulo
498                      switch(type) {                      switch(type) {
499                      case R_386_32:                      case R_386_32:
500                          fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                          fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
501                                  rel->r_offset - offset, name, addend);                                  rel->r_offset - start_offset, name, addend);
502                          break;                          break;
503                      case R_386_PC32:                      case R_386_PC32:
504                          fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",                          fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
505                                  rel->r_offset - offset, name, rel->r_offset - offset, addend);                                  rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
506                          break;                          break;
507                      default:                      default:
508                          error("unsupported i386 relocation (%d)", type);                          error("unsupported i386 relocation (%d)", type);
# Line 485  void gen_code(const char *name, host_ulo Line 516  void gen_code(const char *name, host_ulo
516                  int type;                  int type;
517                  int addend;                  int addend;
518                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
519                      if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {                      if (rel->r_offset >= start_offset &&
520                            rel->r_offset < start_offset + copy_size) {
521                          sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                          sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
522                          if (strstart(sym_name, "__op_param", &p)) {                          if (strstart(sym_name, "__op_param", &p)) {
523                              snprintf(name, sizeof(name), "param%s", p);                              snprintf(name, sizeof(name), "param%s", p);
# Line 497  void gen_code(const char *name, host_ulo Line 529  void gen_code(const char *name, host_ulo
529                          switch(type) {                          switch(type) {
530                          case R_PPC_ADDR32:                          case R_PPC_ADDR32:
531                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
532                                      rel->r_offset - offset, name, addend);                                      rel->r_offset - start_offset, name, addend);
533                              break;                              break;
534                          case R_PPC_ADDR16_LO:                          case R_PPC_ADDR16_LO:
535                              fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",                              fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
536                                      rel->r_offset - offset, name, addend);                                      rel->r_offset - start_offset, name, addend);
537                              break;                              break;
538                          case R_PPC_ADDR16_HI:                          case R_PPC_ADDR16_HI:
539                              fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",                              fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
540                                      rel->r_offset - offset, name, addend);                                      rel->r_offset - start_offset, name, addend);
541                              break;                              break;
542                          case R_PPC_ADDR16_HA:                          case R_PPC_ADDR16_HA:
543                              fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",                              fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
544                                      rel->r_offset - offset, name, addend);                                      rel->r_offset - start_offset, name, addend);
545                              break;                              break;
546                          case R_PPC_REL24:                          case R_PPC_REL24:
547                              /* warning: must be at 32 MB distancy */                              /* warning: must be at 32 MB distancy */
548                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
549                                      rel->r_offset - offset, rel->r_offset - offset, name, rel->r_offset - offset, addend);                                      rel->r_offset - start_offset, rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
550                              break;                              break;
551                          default:                          default:
552                              error("unsupported powerpc relocation (%d)", type);                              error("unsupported powerpc relocation (%d)", type);
# Line 528  void gen_code(const char *name, host_ulo Line 560  void gen_code(const char *name, host_ulo
560                  int type;                  int type;
561                  int addend;                  int addend;
562                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
563                      if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {                      if (rel->r_offset >= start_offset &&
564                            rel->r_offset < start_offset + copy_size) {
565                          sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                          sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
566                          if (strstart(sym_name, "__op_param", &p)) {                          if (strstart(sym_name, "__op_param", &p)) {
567                              snprintf(name, sizeof(name), "param%s", p);                              snprintf(name, sizeof(name), "param%s", p);
# Line 540  void gen_code(const char *name, host_ulo Line 573  void gen_code(const char *name, host_ulo
573                          switch(type) {                          switch(type) {
574                          case R_390_32:                          case R_390_32:
575                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
576                                      rel->r_offset - offset, name, addend);                                      rel->r_offset - start_offset, name, addend);
577                              break;                              break;
578                          case R_390_16:                          case R_390_16:
579                              fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",                              fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",
580                                      rel->r_offset - offset, name, addend);                                      rel->r_offset - start_offset, name, addend);
581                              break;                              break;
582                          case R_390_8:                          case R_390_8:
583                              fprintf(outfile, "    *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",                              fprintf(outfile, "    *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
584                                      rel->r_offset - offset, name, addend);                                      rel->r_offset - start_offset, name, addend);
585                              break;                              break;
586                          default:                          default:
587                              error("unsupported s390 relocation (%d)", type);                              error("unsupported s390 relocation (%d)", type);
# Line 559  void gen_code(const char *name, host_ulo Line 592  void gen_code(const char *name, host_ulo
592  #elif defined(HOST_ALPHA)  #elif defined(HOST_ALPHA)
593              {              {
594                  for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {                  for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
595                      if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {                      if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
596                          int type;                          int type;
597    
598                          type = ELF64_R_TYPE(rel->r_info);                          type = ELF64_R_TYPE(rel->r_info);
# Line 569  void gen_code(const char *name, host_ulo Line 602  void gen_code(const char *name, host_ulo
602                              /* The gp is just 32 bit, and never changes, so it's easiest to emit it                              /* The gp is just 32 bit, and never changes, so it's easiest to emit it
603                                 as an immediate instead of constructing it from the pv or ra.  */                                 as an immediate instead of constructing it from the pv or ra.  */
604                              fprintf(outfile, "    immediate_ldah(gen_code_ptr + %ld, gp);\n",                              fprintf(outfile, "    immediate_ldah(gen_code_ptr + %ld, gp);\n",
605                                      rel->r_offset - offset);                                      rel->r_offset - start_offset);
606                              fprintf(outfile, "    immediate_lda(gen_code_ptr + %ld, gp);\n",                              fprintf(outfile, "    immediate_lda(gen_code_ptr + %ld, gp);\n",
607                                      rel->r_offset - offset + rel->r_addend);                                      rel->r_offset - start_offset + rel->r_addend);
608                              break;                              break;
609                          case R_ALPHA_LITUSE:                          case R_ALPHA_LITUSE:
610                              /* jsr to literal hint. Could be used to optimize to bsr. Ignore for                              /* jsr to literal hint. Could be used to optimize to bsr. Ignore for
# Line 591  void gen_code(const char *name, host_ulo Line 624  void gen_code(const char *name, host_ulo
624                                 special treatment.  */                                 special treatment.  */
625                              if (strstart(sym_name, "__op_param", &p))                              if (strstart(sym_name, "__op_param", &p))
626                                  fprintf(outfile, "    immediate_ldah(gen_code_ptr + %ld, param%s);\n",                                  fprintf(outfile, "    immediate_ldah(gen_code_ptr + %ld, param%s);\n",
627                                          rel->r_offset - offset, p);                                          rel->r_offset - start_offset, p);
628                              break;                              break;
629                          case R_ALPHA_GPRELLOW:                          case R_ALPHA_GPRELLOW:
630                              if (strstart(sym_name, "__op_param", &p))                              if (strstart(sym_name, "__op_param", &p))
631                                  fprintf(outfile, "    immediate_lda(gen_code_ptr + %ld, param%s);\n",                                  fprintf(outfile, "    immediate_lda(gen_code_ptr + %ld, param%s);\n",
632                                          rel->r_offset - offset, p);                                          rel->r_offset - start_offset, p);
633                              break;                              break;
634                          case R_ALPHA_BRSGP:                          case R_ALPHA_BRSGP:
635                              /* PC-relative jump. Tweak offset to skip the two instructions that try to                              /* PC-relative jump. Tweak offset to skip the two instructions that try to
636                                 set up the gp from the pv.  */                                 set up the gp from the pv.  */
637                              fprintf(outfile, "    fix_bsr(gen_code_ptr + %ld, (uint8_t *) &%s - (gen_code_ptr + %ld) + 4);\n",                              fprintf(outfile, "    fix_bsr(gen_code_ptr + %ld, (uint8_t *) &%s - (gen_code_ptr + %ld) + 4);\n",
638                                      rel->r_offset - offset, sym_name, rel->r_offset - offset);                                      rel->r_offset - start_offset, sym_name, rel->r_offset - start_offset);
639                              break;                              break;
640                          default:                          default:
641                              error("unsupported Alpha relocation (%d)", type);                              error("unsupported Alpha relocation (%d)", type);
# Line 616  void gen_code(const char *name, host_ulo Line 649  void gen_code(const char *name, host_ulo
649                  int type;                  int type;
650                  int addend;                  int addend;
651                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
652                      if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {                      if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
653                          sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;                          sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
654                          if (strstart(sym_name, "__op_param", &p)) {                          if (strstart(sym_name, "__op_param", &p)) {
655                              snprintf(name, sizeof(name), "param%s", p);                              snprintf(name, sizeof(name), "param%s", p);
# Line 642  void gen_code(const char *name, host_ulo Line 675  void gen_code(const char *name, host_ulo
675                  int type;                  int type;
676                  int addend;                  int addend;
677                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
678                      if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {                      if (rel->r_offset >= start_offset &&
679                            rel->r_offset < start_offset + copy_size) {
680                          sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;                          sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
681                          if (strstart(sym_name, "__op_param", &p)) {                          if (strstart(sym_name, "__op_param", &p)) {
682                              snprintf(name, sizeof(name), "param%s", p);                              snprintf(name, sizeof(name), "param%s", p);
# Line 660  void gen_code(const char *name, host_ulo Line 694  void gen_code(const char *name, host_ulo
694                          switch(type) {                          switch(type) {
695                          case R_SPARC_32:                          case R_SPARC_32:
696                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
697                                      rel->r_offset - offset, name, addend);                                      rel->r_offset - start_offset, name, addend);
698                              break;                              break;
699                          case R_SPARC_HI22:                          case R_SPARC_HI22:
700                              fprintf(outfile,                              fprintf(outfile,
701                                      "    *(uint32_t *)(gen_code_ptr + %d) = "                                      "    *(uint32_t *)(gen_code_ptr + %d) = "
702                                      "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
703                                      " & ~0x3fffff) "                                      " & ~0x3fffff) "
704                                      " | ((%s + %d) & 0x3fffff);\n",                                      " | (((%s + %d) >> 10) & 0x3fffff);\n",
705                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
706                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
707                                      name, addend);                                      name, addend);
708                              break;                              break;
709                          case R_SPARC_LO10:                          case R_SPARC_LO10:
# Line 678  void gen_code(const char *name, host_ulo Line 712  void gen_code(const char *name, host_ulo
712                                      "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
713                                      " & ~0x3ff) "                                      " & ~0x3ff) "
714                                      " | ((%s + %d) & 0x3ff);\n",                                      " | ((%s + %d) & 0x3ff);\n",
715                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
716                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
717                                      name, addend);                                      name, addend);
718                              break;                              break;
719                          case R_SPARC_WDISP30:                          case R_SPARC_WDISP30:
# Line 687  void gen_code(const char *name, host_ulo Line 721  void gen_code(const char *name, host_ulo
721                                      "    *(uint32_t *)(gen_code_ptr + %d) = "                                      "    *(uint32_t *)(gen_code_ptr + %d) = "
722                                      "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
723                                      " & ~0x3fffffff) "                                      " & ~0x3fffffff) "
724                                      " | ((((%s + %d) - (long)gen_code_ptr)>>2) "                                      " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
725                                      "    & 0x3fffffff);\n",                                      "    & 0x3fffffff);\n",
726                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
727                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
728                                      name, addend);                                      name, addend,
729                                        rel->r_offset - start_offset);
730                              break;                              break;
731                          default:                          default:
732                              error("unsupported sparc relocation (%d)", type);                              error("unsupported sparc relocation (%d)", type);
# Line 705  void gen_code(const char *name, host_ulo Line 740  void gen_code(const char *name, host_ulo
740                  int type;                  int type;
741                  int addend;                  int addend;
742                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
743                      if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {                      if (rel->r_offset >= start_offset &&
744                            rel->r_offset < start_offset + copy_size) {
745                          sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;                          sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
746                          if (strstart(sym_name, "__op_param", &p)) {                          if (strstart(sym_name, "__op_param", &p)) {
747                              snprintf(name, sizeof(name), "param%s", p);                              snprintf(name, sizeof(name), "param%s", p);
# Line 717  void gen_code(const char *name, host_ulo Line 753  void gen_code(const char *name, host_ulo
753                          switch(type) {                          switch(type) {
754                          case R_SPARC_32:                          case R_SPARC_32:
755                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
756                                      rel->r_offset - offset, name, addend);                                      rel->r_offset - start_offset, name, addend);
757                              break;                              break;
758                          case R_SPARC_HI22:                          case R_SPARC_HI22:
759                              fprintf(outfile,                              fprintf(outfile,
760                                      "    *(uint32_t *)(gen_code_ptr + %d) = "                                      "    *(uint32_t *)(gen_code_ptr + %d) = "
761                                      "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
762                                      " & ~0x3fffff) "                                      " & ~0x3fffff) "
763                                      " | ((%s + %d) & 0x3fffff);\n",                                      " | (((%s + %d) >> 10) & 0x3fffff);\n",
764                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
765                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
766                                      name, addend);                                      name, addend);
767                              break;                              break;
768                          case R_SPARC_LO10:                          case R_SPARC_LO10:
# Line 735  void gen_code(const char *name, host_ulo Line 771  void gen_code(const char *name, host_ulo
771                                      "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
772                                      " & ~0x3ff) "                                      " & ~0x3ff) "
773                                      " | ((%s + %d) & 0x3ff);\n",                                      " | ((%s + %d) & 0x3ff);\n",
774                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
775                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
776                                      name, addend);                                      name, addend);
777                              break;                              break;
778                          case R_SPARC_WDISP30:                          case R_SPARC_WDISP30:
# Line 744  void gen_code(const char *name, host_ulo Line 780  void gen_code(const char *name, host_ulo
780                                      "    *(uint32_t *)(gen_code_ptr + %d) = "                                      "    *(uint32_t *)(gen_code_ptr + %d) = "
781                                      "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
782                                      " & ~0x3fffffff) "                                      " & ~0x3fffffff) "
783                                      " | ((((%s + %d) - (long)gen_code_ptr)>>2) "                                      " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
784                                      "    & 0x3fffffff);\n",                                      "    & 0x3fffffff);\n",
785                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
786                                      rel->r_offset - offset,                                      rel->r_offset - start_offset,
787                                      name, addend);                                      name, addend,
788                                        rel->r_offset - start_offset);
789                              break;                              break;
790                          default:                          default:
791                              error("unsupported sparc64 relocation (%d)", type);                              error("unsupported sparc64 relocation (%d)", type);
# Line 933  fprintf(outfile, Line 970  fprintf(outfile,
970  "    const uint32_t *opparam_ptr;\n"  "    const uint32_t *opparam_ptr;\n"
971  "    gen_code_ptr = gen_code_buf;\n"  "    gen_code_ptr = gen_code_buf;\n"
972  "    opc_ptr = opc_buf;\n"  "    opc_ptr = opc_buf;\n"
973  "    opparam_ptr = opparam_buf;\n"  "    opparam_ptr = opparam_buf;\n");
974    
975            /* Generate prologue, if needed. */
976            switch(ELF_ARCH) {
977            case EM_SPARC:
978                    fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x9c23a080; /* sub %%sp, 128, %%sp */\n");
979                    fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0xbc27a080; /* sub %%fp, 128, %%fp */\n");
980                    break;
981    
982            case EM_SPARCV9:
983                    fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x9c23a100; /* sub %%sp, 256, %%sp */\n");
984                    fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0xbc27a100; /* sub %%fp, 256, %%fp */\n");
985                    break;
986            };
987    
988    fprintf(outfile,
989  "    for(;;) {\n"  "    for(;;) {\n"
990  "        switch(*opc_ptr++) {\n"  "        switch(*opc_ptr++) {\n"
991  );  );
# Line 961  fprintf(outfile, Line 1013  fprintf(outfile,
1013  " the_end:\n"  " the_end:\n"
1014  );  );
1015    
1016  /* generate a return */  /* generate epilogue */
1017      switch(ELF_ARCH) {      switch(ELF_ARCH) {
1018      case EM_386:      case EM_386:
1019          fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n");          fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n");
# Line 980  fprintf(outfile, Line 1032  fprintf(outfile,
1032          break;          break;
1033      case EM_SPARC:      case EM_SPARC:
1034      case EM_SPARC32PLUS:      case EM_SPARC32PLUS:
1035            fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0xbc07a080; /* add %%fp, 256, %%fp */\n");
1036            fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x81c62008; /* jmpl %%i0 + 8, %%g0 */\n");
1037            fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x9c03a080; /* add %%sp, 256, %%sp */\n");
1038            break;
1039      case EM_SPARCV9:      case EM_SPARCV9:
1040          /* Fill the delay slot. */          fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x81c7e008; /* ret */\n");
1041          fprintf(outfile, "*((uint32_t *)gen_code_ptr) = *((uint32_t *)gen_code_ptr - 1); /* delay slot */\n");          fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x81e80000; /* restore */\n");
         fprintf(outfile, "*((uint32_t *)gen_code_ptr - 1) = 0x81c3e008; /* retl */\n");  
         fprintf(outfile, "gen_code_ptr++;\n");  
1042          break;          break;
1043      default:      default:
1044          error("unknown ELF architecture");          error("unknown ELF architecture");

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26