From: Randolph C. <ta...@us...> - 2007-03-04 15:03:27
|
Update of /cvsroot/hppaqemu/hppaqemu In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv6947 Modified Files: Makefile.target configure cpu-all.h cpu-exec.c disas.c dyngen-exec.h dyngen.c dyngen.h exec-all.h exec.c Log Message: host support for hppa, mostly works :) Index: dyngen-exec.h =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/dyngen-exec.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** dyngen-exec.h 23 Feb 2007 21:44:02 -0000 1.1.1.1 --- dyngen-exec.h 4 Mar 2007 15:03:22 -0000 1.2 *************** *** 124,127 **** --- 124,133 ---- #define AREG3 "r6" #endif + #ifdef __hppa__ + #define AREG0 "r17" + #define AREG1 "r14" + #define AREG2 "r15" + #define AREG3 "r16" + #endif #ifdef __mips__ #define AREG0 "s3" *************** *** 276,279 **** --- 282,291 ---- #define EXIT_TB() asm volatile ("rts") #endif + #ifdef __hppa__ + #define EXIT_TB() asm volatile ("ldil L'exec_loop, %r1\n" \ + "ldo R'exec_loop(%r1), %r1\n" \ + "bv,n %r0(%r1)\n") + #define GOTO_LABEL_PARAM(n) asm volatile ("b,n " ASM_NAME(__op_gen_label) #n) + #endif #endif /* !defined(__DYNGEN_EXEC_H__) */ Index: dyngen.h =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/dyngen.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** dyngen.h 23 Feb 2007 21:44:03 -0000 1.1.1.1 --- dyngen.h 4 Mar 2007 15:03:22 -0000 1.2 *************** *** 81,84 **** --- 81,100 ---- #endif + #ifdef __hppa__ + static inline void flush_icache_range(unsigned long start, unsigned long stop) + { + start &= ~31; + while (start < stop) + { + asm volatile ("fdc 0(%0)\n" + "sync\n" + "fic 0(%%sr4, %0)\n" + "sync\n" + : : "r"(start) : "memory"); + start += 32; + } + } + #endif + #ifdef __alpha__ static inline void flush_icache_range(unsigned long start, unsigned long stop) *************** *** 247,250 **** --- 263,395 ---- #endif /* __arm__ */ + #ifdef __hppa__ + + /* Field selection types defined by hppa */ + #define rnd(x) (((x)+0x1000)&~0x1fff) + /* lsel: select left 21 bits */ + #define lsel(v,a) (((v)+(a))>>11) + /* rsel: select right 11 bits */ + #define rsel(v,a) (((v)+(a))&0x7ff) + /* lrsel with rounding of addend to nearest 8k */ + #define lrsel(v,a) (((v)+rnd(a))>>11) + /* rrsel with rounding of addend to nearest 8k */ + #define rrsel(v,a) ((((v)+rnd(a))&0x7ff)+((a)-rnd(a))) + + #define mask(x,sz) ((x) & ~((1<<(sz))-1)) + + static inline int reassemble_14(int as14) + { + return (((as14 & 0x1fff) << 1) | + ((as14 & 0x2000) >> 13)); + } + + static inline int reassemble_17(int as17) + { + return (((as17 & 0x10000) >> 16) | + ((as17 & 0x0f800) << 5) | + ((as17 & 0x00400) >> 8) | + ((as17 & 0x003ff) << 3)); + } + + static inline int reassemble_21(int as21) + { + return (((as21 & 0x100000) >> 20) | + ((as21 & 0x0ffe00) >> 8) | + ((as21 & 0x000180) << 7) | + ((as21 & 0x00007c) << 14) | + ((as21 & 0x000003) << 12)); + } + + struct hppa_branch_stub { + uint32_t *location; + long target; + struct hppa_branch_stub *next; + }; + + #define HPPA_RECORD_BRANCH(LIST, LOC, TARGET) \ + do { \ + struct hppa_branch_stub *stub = alloca(sizeof(struct hppa_branch_stub)); \ + stub->location = LOC; \ + stub->target = TARGET; \ + stub->next = LIST; \ + LIST = stub; \ + } while (0) + + static inline void hppa_patch21l(uint32_t *insn, int val, int addend) + { + val = lrsel(val, addend); + *insn = mask(*insn, 21) | reassemble_21(val); + } + + static inline void hppa_patch14r(uint32_t *insn, int val, int addend) + { + val = rrsel(val, addend); + *insn = mask(*insn, 14) | reassemble_14(val); + } + + static inline void hppa_patch17r(uint32_t *insn, int val, int addend) + { + val = rrsel(val, addend); + *insn = (*insn & ~0x1f1ffd) | reassemble_17(val); + } + + + static inline void hppa_patch21l_dprel(uint32_t *insn, int val, int addend) + { + register unsigned int dp asm("r27"); + hppa_patch21l(insn, val - dp, addend); + } + + static inline void hppa_patch14r_dprel(uint32_t *insn, int val, int addend) + { + register unsigned int dp asm("r27"); + hppa_patch14r(insn, val - dp, addend); + } + + static inline void hppa_patch17f(uint32_t *insn, int val, int addend) + { + int dot = (int)insn & ~0x3; + int v = ((val + addend) - dot - 8) / 4; + if (v > (1 << 16) || v < -(1 << 16)) { + printf("cannot fit branch to offset %d [%08x->%08x]\n", v, dot, val); + abort(); + } + *insn = (*insn & ~0x1f1ffd) | reassemble_17(v); + } + + static inline void hppa_load_imm21l(uint32_t *insn, int val, int addend) + { + /* Transform addil L'sym(%dp) to ldil L'val, %r1 */ + *insn = 0x20200000 | reassemble_21(lrsel(val, 0)); + } + + static inline void hppa_load_imm14r(uint32_t *insn, int val, int addend) + { + /* Transform ldw R'sym(%r1), %rN to ldo R'sym(%r1), %rN */ + hppa_patch14r(insn, val, addend); + /* HACK */ + if (addend == 0) + *insn = (*insn & ~0xfc000000) | (0x0d << 26); + } + + static inline void hppa_process_stubs(struct hppa_branch_stub *stub, uint8_t **gen_code_pp) + { + uint32_t *p = (uint32_t *)*gen_code_pp; + for (; stub != NULL; stub = stub->next) + { + unsigned long l = (unsigned long)p; + /* stub: + * ldil L'target, %r1 + * be,n R'target(%r1) + */ + *p++ = 0x20200000 | reassemble_21(lrsel(stub->target, 0)); + *p++ = 0xe0200002 | reassemble_17(rrsel(stub->target, 0) >> 2); + hppa_patch17f(stub->location, l, 0); + } + *gen_code_pp = (uint8_t *)p; + } + + #endif + #ifdef __ia64 Index: configure =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/configure,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** configure 23 Feb 2007 21:44:02 -0000 1.1.1.1 --- configure 4 Mar 2007 15:03:22 -0000 1.2 *************** *** 48,51 **** --- 48,54 ---- cpu="powerpc" ;; + parisc|parisc64) + cpu="hppa" + ;; mips) cpu="mips" *************** *** 455,459 **** # if cross compiling, cannot launch a program, so make a static guess ! if test "$cpu" = "powerpc" -o "$cpu" = "mips" -o "$cpu" = "s390" -o "$cpu" = "sparc" -o "$cpu" = "sparc64" -o "$cpu" = "m68k" -o "$cpu" = "armv4b"; then bigendian="yes" fi --- 458,462 ---- # if cross compiling, cannot launch a program, so make a static guess ! if test "$cpu" = "powerpc" -o "$cpu" = "mips" -o "$cpu" = "s390" -o "$cpu" = "sparc" -o "$cpu" = "sparc64" -o "$cpu" = "m68k" -o "$cpu" = "armv4b" -o "$cpu" = "hppa"; then bigendian="yes" fi *************** *** 677,680 **** --- 680,686 ---- echo "ARCH=ppc" >> $config_mak echo "#define HOST_PPC 1" >> $config_h + elif test "$cpu" = "hppa" ; then + echo "ARCH=hppa" >> $config_mak + echo "#define HOST_HPPA 1" >> $config_h elif test "$cpu" = "mips" ; then echo "ARCH=mips" >> $config_mak Index: dyngen.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/dyngen.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** dyngen.c 23 Feb 2007 21:44:03 -0000 1.1.1.1 --- dyngen.c 4 Mar 2007 15:03:22 -0000 1.2 *************** *** 118,121 **** --- 118,128 ---- #define ELF_USES_RELOCA + #elif defined(HOST_HPPA) + + #define ELF_CLASS ELFCLASS32 + #define ELF_ARCH EM_PARISC + #define elf_check_arch(x) ((x) == EM_PARISC) + #define ELF_USES_RELOCA + #else #error unsupported CPU - please update the code *************** *** 1207,1211 **** snprintf(name, name_size, "gen_labels[param%s]", p); } else { ! #ifdef HOST_SPARC if (sym_name[0] == '.') snprintf(name, name_size, --- 1214,1218 ---- snprintf(name, name_size, "gen_labels[param%s]", p); } else { ! #if defined(HOST_SPARC) || defined(HOST_HPPA) if (sym_name[0] == '.') snprintf(name, name_size, *************** *** 1642,1645 **** --- 1649,1689 ---- copy_size = p - p_start; } + #elif defined(HOST_HPPA) + { + uint8_t *p; + p = p_start; + while (p < p_end) { + uint32_t insn = get32((uint32_t *)p); + if (insn == 0x6bc23fd9 || + insn == 0x08030241 || + insn == 0x081e0243 || + (insn & 0x37de0000) == 0x37de0000 || + (insn & 0xffffc000) == 0x6fc10000) + p += 4; + else + break; + } + start_offset += p - p_start; + p_start = p; + p = p_end - 4; + + while (p > p_start) { + uint32_t insn = get32((uint32_t *)p); + if ((insn & 0xffffc000) == 0x347e0000 || + (insn & 0x0fc010e0) == 0x0fc01080 || + (insn & 0x37de0000) == 0x37de0000 || + insn == 0x48623fd9 || + insn == 0xe840c000 || + insn == 0xe840c002) + p -= 4; + else + break; + } + p += 4; + if (p <= p_start) + error("empty code for %s", name); + + copy_size = p - p_start; + } #else #error unsupported CPU *************** *** 1707,1711 **** !strstart(sym_name, "__op_jmp", NULL) && !strstart(sym_name, "__op_gen_label", NULL)) { ! #if defined(HOST_SPARC) if (sym_name[0] == '.') { fprintf(outfile, --- 1751,1755 ---- !strstart(sym_name, "__op_jmp", NULL) && !strstart(sym_name, "__op_gen_label", NULL)) { ! #if defined(HOST_SPARC) || defined(HOST_HPPA) if (sym_name[0] == '.') { fprintf(outfile, *************** *** 1734,1739 **** --- 1778,1790 ---- } + #ifndef __hppa__ fprintf(outfile, " memcpy(gen_code_ptr, (void *)((char *)&%s+%d), %d);\n", name, (int)(start_offset - offset), copy_size); + #else + fprintf(outfile, " memcpy(gen_code_ptr, (void *)((char *)__canonicalize_funcptr_for_compare(%s)+%d), %d);\n", + name, (int)(start_offset - offset), copy_size); + + + #endif /* emit code offset information */ *************** *** 2457,2460 **** --- 2508,2578 ---- } } + #elif defined(HOST_HPPA) + { + char name[256]; + int type; + int addend; + int reloc_offset; + 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 = get_rel_sym_name(rel); + sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; + get_reloc_expr(name, sizeof(name), sym_name); + type = ELF32_R_TYPE(rel->r_info); + addend = rel->r_addend; + reloc_offset = rel->r_offset - start_offset; + + switch(type) { + case R_PARISC_DIR21L: + fprintf(outfile, + " hppa_patch21l((uint32_t *)(gen_code_ptr + %d), %s, %d);\n", + reloc_offset, name, addend); + break; + case R_PARISC_DIR14R: + fprintf(outfile, + " hppa_patch14r((uint32_t *)(gen_code_ptr + %d), %s, %d);\n", + reloc_offset, name, addend); + break; + case R_PARISC_DIR17R: + fprintf(outfile, + " hppa_patch17r((uint32_t *)(gen_code_ptr + %d), %s, %d);\n", + reloc_offset, name, addend); + break; + case R_PARISC_PCREL17F: + if (strstart(sym_name, "__op_gen_label", NULL)) { + fprintf(outfile, + " hppa_patch17f((uint32_t *)(gen_code_ptr + %d), %s, %d);\n", + reloc_offset, name, addend); + } else { + fprintf(outfile, + " HPPA_RECORD_BRANCH(hppa_stubs, (uint32_t *)(gen_code_ptr + %d), %s);\n", + reloc_offset, name); + } + break; + case R_PARISC_DPREL21L: + if (strstart(sym_name, "__op_param", &p)) + fprintf(outfile, " hppa_load_imm21l((uint32_t *)(gen_code_ptr + %d), param%s, %d);\n", + reloc_offset, p, addend); + else + fprintf(outfile, + " hppa_patch21l_dprel((uint32_t *)(gen_code_ptr + %d), %s, %d);\n", + reloc_offset, name, addend); + break; + case R_PARISC_DPREL14R: + if (strstart(sym_name, "__op_param", &p)) + fprintf(outfile, " hppa_load_imm14r((uint32_t *)(gen_code_ptr + %d), param%s, %d);\n", + reloc_offset, p, addend); + else + fprintf(outfile, + " hppa_patch14r_dprel((uint32_t *)(gen_code_ptr + %d), %s, %d);\n", + reloc_offset, name, addend); + break; + default: + error("unsupported hppa relocation (%d)", type); + } + } + } + } #else #error unsupported CPU *************** *** 2640,2643 **** --- 2758,2765 ---- #endif + #ifdef HOST_HPPA + fprintf(outfile, " struct hppa_branch_stub *hppa_stubs = NULL;\n"); + #endif + fprintf(outfile, "\n" *************** *** 2721,2724 **** --- 2843,2851 ---- "arm_ldr_ptr, arm_data_ptr, arm_data_table + ARM_LDR_TABLE_SIZE, 0);\n"); #endif + + #ifdef HOST_HPPA + fprintf(outfile, "hppa_process_stubs(hppa_stubs, &gen_code_ptr);\n"); + #endif + /* flush instruction cache */ fprintf(outfile, "flush_icache_range((unsigned long)gen_code_buf, (unsigned long)gen_code_ptr);\n"); Index: cpu-exec.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/cpu-exec.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** cpu-exec.c 23 Feb 2007 21:44:02 -0000 1.1.1.1 --- cpu-exec.c 4 Mar 2007 15:03:22 -0000 1.2 *************** *** 653,656 **** --- 653,665 ---- : "r" (gen_func) : "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14"); + #elif defined(__hppa__) + asm volatile ("bv %%r0(%0)\n" + "nop\n" + ".global exec_loop\n" + "exec_loop:\n" + : /* no outputs */ + : "r" (gen_func) + : "r1", "r20", "r21", "r22", "r23", + "r24", "r25", "r27", "r28"); #elif defined(TARGET_I386) && defined(USE_CODE_COPY) { *************** *** 1479,1482 **** --- 1488,1509 ---- } + #elif defined(__hppa__) + + int cpu_signal_handler(int host_signum, void *pinfo, + void *puc) + { + struct siginfo *info = pinfo; + struct ucontext *uc = puc; + unsigned long pc; + int is_write; + + pc = uc->uc_mcontext.sc_iaoq[0]; + /* FIXME: compute is_write */ + is_write = 0; + return handle_cpu_signal(pc, (unsigned long)info->si_addr, + is_write, + &uc->uc_sigmask, puc); + } + #else Index: exec.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/exec.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** exec.c 23 Feb 2007 21:44:03 -0000 1.1.1.1 --- exec.c 4 Mar 2007 15:03:23 -0000 1.2 *************** *** 70,73 **** --- 70,77 ---- #endif + #ifdef __hppa__ + unsigned int hppa_lock[4] = {1, 1, 1, 1}; + #endif + TranslationBlock tbs[CODE_GEN_MAX_BLOCKS]; TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; Index: Makefile.target =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/Makefile.target,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** Makefile.target 23 Feb 2007 21:43:58 -0000 1.1.1.1 --- Makefile.target 4 Mar 2007 15:03:22 -0000 1.2 *************** *** 144,147 **** --- 144,151 ---- endif + ifeq ($(ARCH),hppa) + OP_CFLAGS=-O1 -fno-delayed-branch + endif + ifeq ($(ARCH),ia64) BASE_CFLAGS+=-mno-sdata *************** *** 304,307 **** --- 308,314 ---- LIBOBJS+=sh4-dis.o endif + ifeq ($(findstring hppa, $(TARGET_ARCH) $(ARCH)),hppa) + LIBOBJS+=hppa-dis.o + endif ifdef CONFIG_GDBSTUB Index: exec-all.h =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/exec-all.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** exec-all.h 23 Feb 2007 21:44:03 -0000 1.1.1.1 --- exec-all.h 4 Mar 2007 15:03:23 -0000 1.2 *************** *** 344,351 **** #define GOTO_TB(opname, tbparam, n)\ do {\ ! static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\ ! static void __attribute__((unused)) *__op_label ## n \ __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\ ! goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\ label ## n: ;\ dummy_label ## n: ;\ --- 344,351 ---- #define GOTO_TB(opname, tbparam, n)\ do {\ ! static volatile void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\ ! static volatile void __attribute__((unused)) *__op_label ## n \ __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\ ! goto *(void *)(((volatile TranslationBlock *)tbparam)->tb_next[n]);\ label ## n: ;\ dummy_label ## n: ;\ *************** *** 473,476 **** --- 473,522 ---- #endif + #ifdef __hppa__ + + #if 0 + #define __ldcw(a) ({ \ + unsigned __ret; \ + __asm__ __volatile__("ldcw 0(%1),%0" \ + : "=r" (__ret) : "r" (a)); \ + __ret; \ + }) + + #define __PA_LDCW_ALIGNMENT 16 + #define __ldcw_align(a) ({ \ + unsigned long __ret = (unsigned long) &(a); \ + __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \ + & ~(__PA_LDCW_ALIGNMENT - 1); \ + (volatile unsigned int *) __ret; \ + }) + + static inline int testandset (int *p) + { + extern unsigned int hppa_lock[4]; + volatile unsigned int *lock = __ldcw_align(hppa_lock[0]); + int old; + + while (__ldcw(lock)) + while (__ldcw(lock)) + /* spin */; + + old = *p; + *p = 1; + + *lock = 1; + + return old != 0; + } + #endif + static inline int testandset (int *p) + { + int old; + old = *p; + *p = 1; + return old != 0; + } + + #endif + #ifdef __ia64 #include <ia64intrin.h> Index: disas.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/disas.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** disas.c 23 Feb 2007 21:44:02 -0000 1.1.1.1 --- disas.c 4 Mar 2007 15:03:22 -0000 1.2 *************** *** 264,267 **** --- 264,269 ---- #elif defined(__m68k__) print_insn = print_insn_m68k; + #elif defined(__hppa__) + print_insn = print_insn_hppa; #else fprintf(out, "0x%lx: Asm output not supported on this arch\n", Index: cpu-all.h =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/cpu-all.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** cpu-all.h 23 Feb 2007 21:44:02 -0000 1.1.1.1 --- cpu-all.h 4 Mar 2007 15:03:22 -0000 1.2 *************** *** 963,966 **** --- 963,975 ---- } + #elif defined(__hppa__) + + static inline int64_t cpu_get_real_ticks(void) + { + int val; + asm volatile ("mfctl %%cr16, %0" : "=r"(val)); + return val; + } + #elif defined(__ia64) |