Remove dyngen ARM code, which did't build.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4501 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									811d4cf4b0
								
							
						
					
					
						commit
						a2a64a1f2d
					
				
							
								
								
									
										316
									
								
								dyngen.c
									
									
									
									
									
								
							
							
						
						
									
										316
									
								
								dyngen.c
									
									
									
									
									
								
							| @ -1284,161 +1284,6 @@ get_plt_index (const char *name, unsigned long addend) | |||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef HOST_ARM |  | ||||||
| 
 |  | ||||||
| int arm_emit_ldr_info(const char *name, unsigned long start_offset, |  | ||||||
|                       FILE *outfile, uint8_t *p_start, uint8_t *p_end, |  | ||||||
|                       ELF_RELOC *relocs, int nb_relocs) |  | ||||||
| { |  | ||||||
|     uint8_t *p; |  | ||||||
|     uint32_t insn; |  | ||||||
|     int offset, min_offset, pc_offset, data_size, spare, max_pool; |  | ||||||
|     uint8_t data_allocated[1024]; |  | ||||||
|     unsigned int data_index; |  | ||||||
|     int type; |  | ||||||
| 
 |  | ||||||
|     memset(data_allocated, 0, sizeof(data_allocated)); |  | ||||||
| 
 |  | ||||||
|     p = p_start; |  | ||||||
|     min_offset = p_end - p_start; |  | ||||||
|     spare = 0x7fffffff; |  | ||||||
|     while (p < p_start + min_offset) { |  | ||||||
|         insn = get32((uint32_t *)p); |  | ||||||
|         /* TODO: Armv5e ldrd.  */ |  | ||||||
|         /* TODO: VFP load.  */ |  | ||||||
|         if ((insn & 0x0d5f0000) == 0x051f0000) { |  | ||||||
|             /* ldr reg, [pc, #im] */ |  | ||||||
|             offset = insn & 0xfff; |  | ||||||
|             if (!(insn & 0x00800000)) |  | ||||||
|                 offset = -offset; |  | ||||||
|             max_pool = 4096; |  | ||||||
|             type = 0; |  | ||||||
|         } else if ((insn & 0x0e5f0f00) == 0x0c1f0100) { |  | ||||||
|             /* FPA ldf.  */ |  | ||||||
|             offset = (insn & 0xff) << 2; |  | ||||||
|             if (!(insn & 0x00800000)) |  | ||||||
|                 offset = -offset; |  | ||||||
|             max_pool = 1024; |  | ||||||
|             type = 1; |  | ||||||
|         } else if ((insn & 0x0fff0000) == 0x028f0000) { |  | ||||||
|             /* Some gcc load a doubleword immediate with
 |  | ||||||
|                add regN, pc, #imm |  | ||||||
|                ldmia regN, {regN, regM} |  | ||||||
|                Hope and pray the compiler never generates somethin like |  | ||||||
|                add reg, pc, #imm1; ldr reg, [reg, #-imm2]; */ |  | ||||||
|             int r; |  | ||||||
| 
 |  | ||||||
|             r = (insn & 0xf00) >> 7; |  | ||||||
|             offset = ((insn & 0xff) >> r) | ((insn & 0xff) << (32 - r)); |  | ||||||
|             max_pool = 1024; |  | ||||||
|             type = 2; |  | ||||||
|         } else { |  | ||||||
|             max_pool = 0; |  | ||||||
|             type = -1; |  | ||||||
|         } |  | ||||||
|         if (type >= 0) { |  | ||||||
|             /* PC-relative load needs fixing up.  */ |  | ||||||
|             if (spare > max_pool - offset) |  | ||||||
|                 spare = max_pool - offset; |  | ||||||
|             if ((offset & 3) !=0) |  | ||||||
|                 error("%s:%04x: pc offset must be 32 bit aligned", |  | ||||||
|                       name, start_offset + p - p_start); |  | ||||||
|             if (offset < 0) |  | ||||||
|                 error("%s:%04x: Embedded literal value", |  | ||||||
|                       name, start_offset + p - p_start); |  | ||||||
|             pc_offset = p - p_start + offset + 8; |  | ||||||
|             if (pc_offset <= (p - p_start) || |  | ||||||
|                 pc_offset >= (p_end - p_start)) |  | ||||||
|                 error("%s:%04x: pc offset must point inside the function code", |  | ||||||
|                       name, start_offset + p - p_start); |  | ||||||
|             if (pc_offset < min_offset) |  | ||||||
|                 min_offset = pc_offset; |  | ||||||
|             if (outfile) { |  | ||||||
|                 /* The intruction position */ |  | ||||||
|                 fprintf(outfile, "    arm_ldr_ptr->ptr = gen_code_ptr + %d;\n", |  | ||||||
|                         p - p_start); |  | ||||||
|                 /* The position of the constant pool data.  */ |  | ||||||
|                 data_index = ((p_end - p_start) - pc_offset) >> 2; |  | ||||||
|                 fprintf(outfile, "    arm_ldr_ptr->data_ptr = arm_data_ptr - %d;\n", |  | ||||||
|                         data_index); |  | ||||||
|                 fprintf(outfile, "    arm_ldr_ptr->type = %d;\n", type); |  | ||||||
|                 fprintf(outfile, "    arm_ldr_ptr++;\n"); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         p += 4; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* Copy and relocate the constant pool data.  */ |  | ||||||
|     data_size = (p_end - p_start) - min_offset; |  | ||||||
|     if (data_size > 0 && outfile) { |  | ||||||
|         spare += min_offset; |  | ||||||
|         fprintf(outfile, "    arm_data_ptr -= %d;\n", data_size >> 2); |  | ||||||
|         fprintf(outfile, "    arm_pool_ptr -= %d;\n", data_size); |  | ||||||
|         fprintf(outfile, "    if (arm_pool_ptr > gen_code_ptr + %d)\n" |  | ||||||
|                          "        arm_pool_ptr = gen_code_ptr + %d;\n", |  | ||||||
|                          spare, spare); |  | ||||||
| 
 |  | ||||||
|         data_index = 0; |  | ||||||
|         for (pc_offset = min_offset; |  | ||||||
|              pc_offset < p_end - p_start; |  | ||||||
|              pc_offset += 4) { |  | ||||||
| 
 |  | ||||||
|             ELF_RELOC *rel; |  | ||||||
|             int i, addend, type; |  | ||||||
|             const char *sym_name; |  | ||||||
|             char relname[1024]; |  | ||||||
| 
 |  | ||||||
|             /* data value */ |  | ||||||
|             addend = get32((uint32_t *)(p_start + pc_offset)); |  | ||||||
|             relname[0] = '\0'; |  | ||||||
|             for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { |  | ||||||
|                 if (rel->r_offset == (pc_offset + start_offset)) { |  | ||||||
|                     sym_name = get_rel_sym_name(rel); |  | ||||||
|                     /* the compiler leave some unnecessary references to the code */ |  | ||||||
|                     get_reloc_expr(relname, sizeof(relname), sym_name); |  | ||||||
|                     type = ELF32_R_TYPE(rel->r_info); |  | ||||||
|                     if (type != R_ARM_ABS32) |  | ||||||
|                         error("%s: unsupported data relocation", name); |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             fprintf(outfile, "    arm_data_ptr[%d] = 0x%x", |  | ||||||
|                     data_index, addend); |  | ||||||
|             if (relname[0] != '\0') |  | ||||||
|                 fprintf(outfile, " + %s", relname); |  | ||||||
|             fprintf(outfile, ";\n"); |  | ||||||
| 
 |  | ||||||
|             data_index++; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (p == p_start) |  | ||||||
|         goto arm_ret_error; |  | ||||||
|     p -= 4; |  | ||||||
|     insn = get32((uint32_t *)p); |  | ||||||
|     /* The last instruction must be an ldm instruction.  There are several
 |  | ||||||
|        forms generated by gcc: |  | ||||||
|         ldmib sp, {..., pc}  (implies a sp adjustment of +4) |  | ||||||
|         ldmia sp, {..., pc} |  | ||||||
|         ldmea fp, {..., pc} */ |  | ||||||
|     if ((insn & 0xffff8000) == 0xe99d8000) { |  | ||||||
|         if (outfile) { |  | ||||||
|             fprintf(outfile, |  | ||||||
|                     "    *(uint32_t *)(gen_code_ptr + %d) = 0xe28dd004;\n", |  | ||||||
|                     p - p_start); |  | ||||||
|         } |  | ||||||
|         p += 4; |  | ||||||
|     } else if ((insn & 0xffff8000) != 0xe89d8000 |  | ||||||
|         && (insn & 0xffff8000) != 0xe91b8000) { |  | ||||||
|     arm_ret_error: |  | ||||||
|         if (!outfile) |  | ||||||
|             printf("%s: invalid epilog\n", name); |  | ||||||
|     } |  | ||||||
|     return p - p_start; |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #define MAX_ARGS 3 | #define MAX_ARGS 3 | ||||||
| 
 | 
 | ||||||
| /* generate op code */ | /* generate op code */ | ||||||
| @ -1633,27 +1478,6 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | |||||||
| 
 | 
 | ||||||
|         copy_size = p - p_start; |         copy_size = p - p_start; | ||||||
|     } |     } | ||||||
| #elif defined(HOST_ARM) |  | ||||||
|     { |  | ||||||
|         uint32_t insn; |  | ||||||
| 
 |  | ||||||
|         if ((p_end - p_start) <= 16) |  | ||||||
|             error("%s: function too small", name); |  | ||||||
|         if (get32((uint32_t *)p_start) != 0xe1a0c00d || |  | ||||||
|             (get32((uint32_t *)(p_start + 4)) & 0xffff0000) != 0xe92d0000 || |  | ||||||
|             get32((uint32_t *)(p_start + 8)) != 0xe24cb004) |  | ||||||
|             error("%s: invalid prolog", name); |  | ||||||
|         p_start += 12; |  | ||||||
|         start_offset += 12; |  | ||||||
|         insn = get32((uint32_t *)p_start); |  | ||||||
|         if ((insn & 0xffffff00) == 0xe24dd000) { |  | ||||||
|             /* Stack adjustment.  Assume op uses the frame pointer.  */ |  | ||||||
|             p_start -= 4; |  | ||||||
|             start_offset -= 4; |  | ||||||
|         } |  | ||||||
|         copy_size = arm_emit_ldr_info(name, start_offset, NULL, p_start, p_end, |  | ||||||
|                                       relocs, nb_relocs); |  | ||||||
|     } |  | ||||||
| #elif defined(HOST_M68K) | #elif defined(HOST_M68K) | ||||||
|     { |     { | ||||||
|         uint8_t *p; |         uint8_t *p; | ||||||
| @ -1725,6 +1549,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | |||||||
|         } |         } | ||||||
|         copy_size = p - p_start; |         copy_size = p - p_start; | ||||||
|     } |     } | ||||||
|  | #elif defined(HOST_ARM) | ||||||
|  |     error("dyngen targets not supported on ARM"); | ||||||
| #else | #else | ||||||
| #error unsupported CPU | #error unsupported CPU | ||||||
| #endif | #endif | ||||||
| @ -2558,74 +2384,6 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| #elif defined(HOST_ARM) |  | ||||||
|             { |  | ||||||
|                 char relname[256]; |  | ||||||
|                 int type; |  | ||||||
|                 int addend; |  | ||||||
|                 int reloc_offset; |  | ||||||
|                 uint32_t insn; |  | ||||||
| 
 |  | ||||||
|                 insn = get32((uint32_t *)(p_start + 4)); |  | ||||||
|                 /* If prologue ends in sub sp, sp, #const then assume
 |  | ||||||
|                    op has a stack frame and needs the frame pointer.  */ |  | ||||||
|                 if ((insn & 0xffffff00) == 0xe24dd000) { |  | ||||||
|                     int i; |  | ||||||
|                     uint32_t opcode; |  | ||||||
|                     opcode = 0xe28db000; /* add fp, sp, #0.  */ |  | ||||||
| #if 0 |  | ||||||
| /* ??? Need to undo the extra stack adjustment at the end of the op.
 |  | ||||||
|    For now just leave the stack misaligned and hope it doesn't break anything |  | ||||||
|    too important.  */ |  | ||||||
|                     if ((insn & 4) != 0) { |  | ||||||
|                         /* Preserve doubleword stack alignment.  */ |  | ||||||
|                         fprintf(outfile, |  | ||||||
|                                 "    *(uint32_t *)(gen_code_ptr + 4)= 0x%x;\n", |  | ||||||
|                                 insn + 4); |  | ||||||
|                         opcode -= 4; |  | ||||||
|                     } |  | ||||||
| #endif |  | ||||||
|                     insn = get32((uint32_t *)(p_start - 4)); |  | ||||||
|                     /* Calculate the size of the saved registers,
 |  | ||||||
|                        excluding pc.  */ |  | ||||||
|                     for (i = 0; i < 15; i++) { |  | ||||||
|                         if (insn & (1 << i)) |  | ||||||
|                             opcode += 4; |  | ||||||
|                     } |  | ||||||
|                     fprintf(outfile, |  | ||||||
|                             "    *(uint32_t *)gen_code_ptr = 0x%x;\n", opcode); |  | ||||||
|                 } |  | ||||||
|                 arm_emit_ldr_info(relname, start_offset, outfile, p_start, p_end, |  | ||||||
|                                   relocs, nb_relocs); |  | ||||||
| 
 |  | ||||||
|                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { |  | ||||||
|                 if (rel->r_offset >= start_offset && |  | ||||||
| 		    rel->r_offset < start_offset + copy_size) { |  | ||||||
|                     sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; |  | ||||||
|                     /* the compiler leave some unnecessary references to the code */ |  | ||||||
|                     if (sym_name[0] == '\0') |  | ||||||
|                         continue; |  | ||||||
|                     get_reloc_expr(relname, sizeof(relname), sym_name); |  | ||||||
|                     type = ELF32_R_TYPE(rel->r_info); |  | ||||||
|                     addend = get32((uint32_t *)(text + rel->r_offset)); |  | ||||||
|                     reloc_offset = rel->r_offset - start_offset; |  | ||||||
|                     switch(type) { |  | ||||||
|                     case R_ARM_ABS32: |  | ||||||
|                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n", |  | ||||||
|                                 reloc_offset, relname, addend); |  | ||||||
|                         break; |  | ||||||
|                     case R_ARM_PC24: |  | ||||||
|                     case R_ARM_JUMP24: |  | ||||||
|                     case R_ARM_CALL: |  | ||||||
|                         fprintf(outfile, "    arm_reloc_pc24((uint32_t *)(gen_code_ptr + %d), 0x%x, %s);\n", |  | ||||||
|                                 reloc_offset, addend, relname); |  | ||||||
|                         break; |  | ||||||
|                     default: |  | ||||||
|                         error("unsupported arm relocation (%d)", type); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| #elif defined(HOST_M68K) | #elif defined(HOST_M68K) | ||||||
|             { |             { | ||||||
|                 char relname[256]; |                 char relname[256]; | ||||||
| @ -2810,6 +2568,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | |||||||
| 		    } | 		    } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | #elif defined(HOST_ARM) | ||||||
|  |     error("dyngen targets not supported on ARM"); | ||||||
| #else | #else | ||||||
| #error unsupported CPU | #error unsupported CPU | ||||||
| #endif | #endif | ||||||
| @ -2868,59 +2628,7 @@ int gen_file(FILE *outfile, int out_type) | |||||||
|         /* generate big code generation switch */ |         /* generate big code generation switch */ | ||||||
| 
 | 
 | ||||||
| #ifdef HOST_ARM | #ifdef HOST_ARM | ||||||
| #error broken |     error("dyngen targets not supported on ARM"); | ||||||
|         /* We need to know the size of all the ops so we can figure out when
 |  | ||||||
|            to emit constant pools.  This must be consistent with opc.h.  */ |  | ||||||
| fprintf(outfile, |  | ||||||
| "static const uint32_t arm_opc_size[] = {\n" |  | ||||||
| "  0,\n" /* end */ |  | ||||||
| "  0,\n" /* nop */ |  | ||||||
| "  0,\n" /* nop1 */ |  | ||||||
| "  0,\n" /* nop2 */ |  | ||||||
| "  0,\n"); /* nop3 */ |  | ||||||
|         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { |  | ||||||
|             const char *name; |  | ||||||
|             name = get_sym_name(sym); |  | ||||||
|             if (strstart(name, OP_PREFIX, NULL)) { |  | ||||||
|                 fprintf(outfile, "  %d,\n", sym->st_size); |  | ||||||
|             } |  | ||||||
| 	} |  | ||||||
| fprintf(outfile, |  | ||||||
| "};\n"); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifdef HOST_ARM |  | ||||||
| #error broken |  | ||||||
| /* Arm is tricky because it uses constant pools for loading immediate values.
 |  | ||||||
|    We assume (and require) each function is code followed by a constant pool. |  | ||||||
|    All the ops are small so this should be ok.  For each op we figure |  | ||||||
|    out how much "spare" range we have in the load instructions.  This allows |  | ||||||
|    us to insert subsequent ops in between the op and the constant pool, |  | ||||||
|    eliminating the neeed to jump around the pool. |  | ||||||
| 
 |  | ||||||
|    We currently generate: |  | ||||||
| 
 |  | ||||||
|    [ For this example we assume merging would move op1_pool out of range. |  | ||||||
|      In practice we should be able to combine many ops before the offset |  | ||||||
|      limits are reached. ] |  | ||||||
|    op1_code; |  | ||||||
|    op2_code; |  | ||||||
|    goto op3; |  | ||||||
|    op2_pool; |  | ||||||
|    op1_pool; |  | ||||||
| op3: |  | ||||||
|    op3_code; |  | ||||||
|    ret; |  | ||||||
|    op3_pool; |  | ||||||
| 
 |  | ||||||
|    Ideally we'd put op1_pool before op2_pool, but that requires two passes. |  | ||||||
|  */ |  | ||||||
| fprintf(outfile, |  | ||||||
| "    uint8_t *last_gen_code_ptr = gen_code_buf;\n" |  | ||||||
| "    LDREntry *arm_ldr_ptr = arm_ldr_table;\n" |  | ||||||
| "    uint32_t *arm_data_ptr = arm_data_table + ARM_LDR_TABLE_SIZE;\n" |  | ||||||
| /* Initialise the parmissible pool offset to an arbitary large value.  */ |  | ||||||
| "    uint8_t *arm_pool_ptr = gen_code_buf + 0x1000000;\n"); |  | ||||||
| #endif | #endif | ||||||
| #ifdef HOST_IA64 | #ifdef HOST_IA64 | ||||||
| #error broken | #error broken | ||||||
| @ -2981,20 +2689,6 @@ fprintf(outfile, | |||||||
|     } |     } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef HOST_ARM |  | ||||||
| #error broken |  | ||||||
| /* Generate constant pool if needed */ |  | ||||||
| fprintf(outfile, |  | ||||||
| "            if (gen_code_ptr + arm_opc_size[*opc_ptr] >= arm_pool_ptr) {\n" |  | ||||||
| "                gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, " |  | ||||||
| "arm_ldr_ptr, arm_data_ptr, arm_data_table + ARM_LDR_TABLE_SIZE, 1);\n" |  | ||||||
| "                last_gen_code_ptr = gen_code_ptr;\n" |  | ||||||
| "                arm_ldr_ptr = arm_ldr_table;\n" |  | ||||||
| "                arm_data_ptr = arm_data_table + ARM_LDR_TABLE_SIZE;\n" |  | ||||||
| "                arm_pool_ptr = gen_code_ptr + 0x1000000;\n" |  | ||||||
| "            }\n"); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { |         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { | ||||||
|             const char *name; |             const char *name; | ||||||
|             name = get_sym_name(sym); |             name = get_sym_name(sym); | ||||||
|  | |||||||
							
								
								
									
										103
									
								
								tcg/tcg-dyngen.c
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								tcg/tcg-dyngen.c
									
									
									
									
									
								
							| @ -143,109 +143,6 @@ void fix_bsr(void *p, int offset) { | |||||||
| 
 | 
 | ||||||
| #endif /* __alpha__ */ | #endif /* __alpha__ */ | ||||||
| 
 | 
 | ||||||
| #ifdef __arm__ |  | ||||||
| 
 |  | ||||||
| #define ARM_LDR_TABLE_SIZE 1024 |  | ||||||
| 
 |  | ||||||
| typedef struct LDREntry { |  | ||||||
|     uint8_t *ptr; |  | ||||||
|     uint32_t *data_ptr; |  | ||||||
|     unsigned type:2; |  | ||||||
| } LDREntry; |  | ||||||
| 
 |  | ||||||
| static LDREntry arm_ldr_table[1024]; |  | ||||||
| static uint32_t arm_data_table[ARM_LDR_TABLE_SIZE]; |  | ||||||
| 
 |  | ||||||
| extern char exec_loop; |  | ||||||
| 
 |  | ||||||
| static inline void arm_reloc_pc24(uint32_t *ptr, uint32_t insn, int val) |  | ||||||
| { |  | ||||||
|     *ptr = (insn & ~0xffffff) | ((insn + ((val - (int)ptr) >> 2)) & 0xffffff); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static uint8_t *arm_flush_ldr(uint8_t *gen_code_ptr, |  | ||||||
|                               LDREntry *ldr_start, LDREntry *ldr_end, |  | ||||||
|                               uint32_t *data_start, uint32_t *data_end, |  | ||||||
|                               int gen_jmp) |  | ||||||
| { |  | ||||||
|     LDREntry *le; |  | ||||||
|     uint32_t *ptr; |  | ||||||
|     int offset, data_size, target; |  | ||||||
|     uint8_t *data_ptr; |  | ||||||
|     uint32_t insn; |  | ||||||
|     uint32_t mask; |  | ||||||
| 
 |  | ||||||
|     data_size = (data_end - data_start) << 2; |  | ||||||
| 
 |  | ||||||
|     if (gen_jmp) { |  | ||||||
|         /* generate branch to skip the data */ |  | ||||||
|         if (data_size == 0) |  | ||||||
|             return gen_code_ptr; |  | ||||||
|         target = (long)gen_code_ptr + data_size + 4; |  | ||||||
|         arm_reloc_pc24((uint32_t *)gen_code_ptr, 0xeafffffe, target); |  | ||||||
|         gen_code_ptr += 4; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* copy the data */ |  | ||||||
|     data_ptr = gen_code_ptr; |  | ||||||
|     memcpy(gen_code_ptr, data_start, data_size); |  | ||||||
|     gen_code_ptr += data_size; |  | ||||||
| 
 |  | ||||||
|     /* patch the ldr to point to the data */ |  | ||||||
|     for(le = ldr_start; le < ldr_end; le++) { |  | ||||||
|         ptr = (uint32_t *)le->ptr; |  | ||||||
|         offset = ((unsigned long)(le->data_ptr) - (unsigned long)data_start) + |  | ||||||
|             (unsigned long)data_ptr - |  | ||||||
|             (unsigned long)ptr - 8; |  | ||||||
|         if (offset < 0) { |  | ||||||
|             fprintf(stderr, "Negative constant pool offset\n"); |  | ||||||
|             tcg_abort(); |  | ||||||
|         } |  | ||||||
|         switch (le->type) { |  | ||||||
|           case 0: /* ldr */ |  | ||||||
|             mask = ~0x00800fff; |  | ||||||
|             if (offset >= 4096) { |  | ||||||
|                 fprintf(stderr, "Bad ldr offset\n"); |  | ||||||
|                 tcg_abort(); |  | ||||||
|             } |  | ||||||
|             break; |  | ||||||
|           case 1: /* ldc */ |  | ||||||
|             mask = ~0x008000ff; |  | ||||||
|             if (offset >= 1024 ) { |  | ||||||
|                 fprintf(stderr, "Bad ldc offset\n"); |  | ||||||
|                 tcg_abort(); |  | ||||||
|             } |  | ||||||
|             break; |  | ||||||
|           case 2: /* add */ |  | ||||||
|             mask = ~0xfff; |  | ||||||
|             if (offset >= 1024 ) { |  | ||||||
|                 fprintf(stderr, "Bad add offset\n"); |  | ||||||
|                 tcg_abort(); |  | ||||||
|             } |  | ||||||
|             break; |  | ||||||
|           default: |  | ||||||
|             fprintf(stderr, "Bad pc relative fixup\n"); |  | ||||||
|             tcg_abort(); |  | ||||||
|           } |  | ||||||
|         insn = *ptr & mask; |  | ||||||
|         switch (le->type) { |  | ||||||
|           case 0: /* ldr */ |  | ||||||
|             insn |= offset | 0x00800000; |  | ||||||
|             break; |  | ||||||
|           case 1: /* ldc */ |  | ||||||
|             insn |= (offset >> 2) | 0x00800000; |  | ||||||
|             break; |  | ||||||
|           case 2: /* add */ |  | ||||||
|             insn |= (offset >> 2) | 0xf00; |  | ||||||
|             break; |  | ||||||
|           } |  | ||||||
|         *ptr = insn; |  | ||||||
|     } |  | ||||||
|     return gen_code_ptr; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #endif /* __arm__ */ |  | ||||||
| 
 |  | ||||||
| #ifdef __ia64 | #ifdef __ia64 | ||||||
| 
 | 
 | ||||||
| /* Patch instruction with "val" where "mask" has 1 bits. */ | /* Patch instruction with "val" where "mask" has 1 bits. */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 balrog
						balrog