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

Diff of /qemu/dyngen.c

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

revision 1.11 by bellard, Tue Apr 29 21:26:53 2003 UTC revision 1.12 by bellard, Sun May 11 12:27:31 2003 UTC
# Line 429  void gen_code(const char *name, host_ulo Line 429  void gen_code(const char *name, host_ulo
429          for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {          for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
430              if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {              if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
431                  sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                  sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
432                  if (!strstart(sym_name, "__op_param", &p)) {                  if (*sym_name && !strstart(sym_name, "__op_param", &p)) {
433  #if defined(HOST_SPARC)  #if defined(HOST_SPARC)
434                      if (sym_name[0] == '.') {                      if (sym_name[0] == '.') {
435                          fprintf(outfile,                          fprintf(outfile,
# Line 561  void gen_code(const char *name, host_ulo Line 561  void gen_code(const char *name, host_ulo
561                  for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {                  for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
562                      if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {                      if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
563                          int type;                          int type;
564                          sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;  
                           
565                          type = ELF64_R_TYPE(rel->r_info);                          type = ELF64_R_TYPE(rel->r_info);
566                            sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
567                          switch (type) {                          switch (type) {
568                          case R_ALPHA_GPDISP:                          case R_ALPHA_GPDISP:
569                              /* Instructions to set up the gp can be nopped, since we keep it current                              /* The gp is just 32 bit, and never changes, so it's easiest to emit it
570                                 all the time.  FIXME assert that target is really gp  */                                 as an immediate instead of constructing it from the pv or ra.  */
571                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = 0x2ffe0000; /* unop */\n",                              fprintf(outfile, "    immediate_ldah(gen_code_ptr + %ld, gp);\n",
572                                      rel->r_offset - offset);                                      rel->r_offset - offset);
573                                fprintf(outfile, "    immediate_lda(gen_code_ptr + %ld, gp);\n",
574                                        rel->r_offset - offset + rel->r_addend);
575                              break;                              break;
576                          case R_ALPHA_LITUSE:                          case R_ALPHA_LITUSE:
577                              /* 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 580  void gen_code(const char *name, host_ulo Line 582  void gen_code(const char *name, host_ulo
582                                 correct for in-function jumps.  */                                 correct for in-function jumps.  */
583                              break;                              break;
584                          case R_ALPHA_LITERAL:                          case R_ALPHA_LITERAL:
585                              /* Load a literal from the GOT relative to the gp.  Need to patch the                              /* Load a literal from the GOT relative to the gp.  Since there's only a
586                                 16-bit immediate offset.  */                                 single gp, nothing is to be done.  */
587                              fprintf(outfile, "    *(int16_t *)(gen_code_ptr + %d) = gp - (long)(&%s);\n",                              break;
588                                      rel->r_offset - offset, name);                          case R_ALPHA_GPRELHIGH:
589                                /* Handle fake relocations against __op_param symbol.  Need to emit the
590                                   high part of the immediate value instead.  Other symbols need no
591                                   special treatment.  */
592                                if (strstart(sym_name, "__op_param", &p))
593                                    fprintf(outfile, "    immediate_ldah(gen_code_ptr + %ld, param%s);\n",
594                                            rel->r_offset - offset, p);
595                                break;
596                            case R_ALPHA_GPRELLOW:
597                                if (strstart(sym_name, "__op_param", &p))
598                                    fprintf(outfile, "    immediate_lda(gen_code_ptr + %ld, param%s);\n",
599                                            rel->r_offset - offset, p);
600                                break;
601                            case R_ALPHA_BRSGP:
602                                /* PC-relative jump. Tweak offset to skip the two instructions that try to
603                                   set up the gp from the pv.  */
604                                fprintf(outfile, "    fix_bsr(gen_code_ptr + %ld, (uint8_t *) &%s - (gen_code_ptr + %ld) + 4);\n",
605                                        rel->r_offset - offset, sym_name, rel->r_offset - offset);
606                              break;                              break;
607                          default:                          default:
608                              error("unsupported Alpha relocation (%d)", type);                              error("unsupported Alpha relocation (%d)", type);
# Line 886  int load_elf(const char *filename, FILE Line 905  int load_elf(const char *filename, FILE
905      } else {      } else {
906          /* generate big code generation switch */          /* generate big code generation switch */
907  #ifdef HOST_ALPHA  #ifdef HOST_ALPHA
908          fprintf(outfile, "register long gp asm(\"%%$29\");\n");  fprintf(outfile,
909    "register int gp asm(\"$29\");\n"
910    "static inline void immediate_ldah(void *p, int val) {\n"
911    "    uint32_t *dest = p;\n"
912    "    long high = ((val >> 16) + ((val >> 15) & 1)) & 0xffff;\n"
913    "\n"
914    "    *dest &= ~0xffff;\n"
915    "    *dest |= high;\n"
916    "    *dest |= 31 << 16;\n"
917    "}\n"
918    "static inline void immediate_lda(void *dest, int val) {\n"
919    "    *(uint16_t *) dest = val;\n"
920    "}\n"
921    "void fix_bsr(void *p, int offset) {\n"
922    "    uint32_t *dest = p;\n"
923    "    *dest &= ~((1 << 21) - 1);\n"
924    "    *dest |= (offset >> 2) & ((1 << 21) - 1);\n"
925    "}\n");
926  #endif  #endif
927  fprintf(outfile,  fprintf(outfile,
928  "int dyngen_code(uint8_t *gen_code_buf,\n"  "int dyngen_code(uint8_t *gen_code_buf,\n"

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

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