HPPA (PA-RISC) host support [v2]
PATCH 1/1 HPPA (PA-RISC) host support [v2]
Hi,
The attached patch adds partially working HPPA (PA-RISC) Linux host support. As hppa-dis.c is quite large, and is unchanged, I haven't attached it. It was attached separately with the initial version of this patch, submitted on 2008-03-23.
Changes from the initial version of the patch include the following:
* The instruction masks and values for dyngen prologue/epilogue removal have been corrected and are now properly commented.
* tcg/hppa/relocs.h has been moved into tcg/hppa/tcg-target.h, as there seemed to be no real benefit in having an extra header.
* hppa_process_stubs() and related code has been moved from tcg-target.h into tcg-dyngen.c, as that is the only place in which it is used.
* tcg_out_call() has been implemented.
* tcg_out_qemu_ld() and tcg_out_qemu_st() have been partially implemented. Unaligned loads/stores are not yet handled for linux-user targets, and 64-bit loads/stores and loads/stores with 64-bit target addresses need testing.
* op_sar_i32 had the source/target registers for VEXTRS swapped.
* r3 is now marked as reserved, as it is used as the frame pointer.
* r1, r3 and r18 have been removed from tcg_target_reg_alloc_order[] as they are reserved, and r17, r14, r15, r16 (the dyngen 'AREG' registers) have been added to the end.
* r20 is now used as a temporary register instead of r26, as r26 is used to pass the first argument in a helper call.
* tcg_out_mov() now uses the OR insn instead of LDO, as hppa-dis.c only disassembles the OR form into the COPY psuedo-insn.
Unfortunately, I have found that mips-softmmu emulation only works with this patch if MIPS_SINGLE_STEP is defined. I do not yet understand how this could make a difference.
The i386-softmmu target now starts booting the linux-0.2.img test, but it crashes when entering userspace. Strangely, upon examining the core dump and comparing this to the -d out_asm output in /tmp/qemu.log, it seems that a small section of code is sometimes 'cut out' of the code buffer -- I am not sure why this is happening, but I should probably try the ARM target to eliminate any problems involving dyngen.
I had previously forgotten to mention that sparc32plus-linux-user, sparc64-linux-user and ppc64-softmmu do not yet build, due to problems regarding GCC (and possibly binutils).
Once again, thanks to Randolph Chung for a lot of the dyngen work.
Here's a diffstat of the changes:
Makefile.target | 8 configure | 7 cpu-all.h | 11 cpu-exec.c | 29 + dis-asm.h | 4 disas.c | 2 dyngen-exec.h | 7 dyngen.c | 129 ++++++ hppa.ld | 214 ++++++++++ tcg/hppa/tcg-target.c | 980 ++++++++++++++++++++++++++++++++++++++++++++++++ tcg/hppa/tcg-target.h | 204 +++++++++ tcg/i386/tcg-target.c | 3 tcg/sparc/tcg-target.c | 3 tcg/tcg-dyngen.c | 50 ++ tcg/tcg.c | 30 + tcg/x86_64/tcg-target.c | 3 16 files changed, 1671 insertions(+), 13 deletions(-)
Cheers,
Signature · 1 line
Stuart Brady
configure +7 -0
@@ -50,6 +50,9 @@ case "$cpu" in cris) cpu="cris" ;; + parisc|parisc64) + cpu="hppa" + ;; ia64) cpu="ia64" ;;
@@ -576,6 +579,7 @@ else # if cross compiling, cannot launch a program, so make a static guess if test "$cpu" = "armv4b" \ + -o "$cpu" = "hppa" \ -o "$cpu" = "m68k" \ -o "$cpu" = "mips" \ -o "$cpu" = "mips64" \
@@ -865,6 +869,9 @@ elif test "$cpu" = "armv4l" ; then elif test "$cpu" = "cris" ; then echo "ARCH=cris" >> $config_mak echo "#define HOST_CRIS 1" >> $config_h +elif test "$cpu" = "hppa" ; then + echo "ARCH=hppa" >> $config_mak + echo "#define HOST_HPPA 1" >> $config_h elif test "$cpu" = "ia64" ; then echo "ARCH=ia64" >> $config_mak echo "#define HOST_IA64 1" >> $config_h
cpu-all.h +10 -1
@@ -20,7 +20,7 @@#ifndef CPU_ALL_H #define CPU_ALL_H -#if defined(__arm__) || defined(__sparc__) || defined(__mips__) +#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__)#define WORDS_ALIGNED #endif
@@ -952,6 +952,15 @@ static inline int64_t cpu_get_real_ticks return val; } +#elif defined(__hppa__) + +static inline int64_t cpu_get_real_ticks (void ) +{ +int val; + asmvolatile ("mfctl %%cr16, %0" :"=r" (val)); +return val; +} +#elif defined(__ia64)static inline int64_t cpu_get_real_ticks (void )
cpu-exec.c +29 -0
@@ -657,6 +657,17 @@ int cpu_exec(CPUState *env1)"o0" ,"o1" ,"o2" ,"o3" ,"o4" ,"o5" ,"l0" ,"l1" ,"l2" ,"l3" ,"l4" ,"l5" , "l6", "l7"); +#elif defined(__hppa__) + asmvolatile ("ble 0(%%sr4,%1)\n" +"copy %%r31,%%r18\n" +"copy %%r28,%0\n" + :"=r" (T0 ) + :"r" (gen_func) + :"r1" ,"r2" ,"r3" ,"r4" ,"r5" ,"r6" ,"r7" , +"r8" ,"r9" ,"r10" ,"r11" ,"r12" ,"r13" , +"r18" ,"r19" ,"r20" ,"r21" ,"r22" ,"r23" , +"r24" ,"r25" ,"r26" ,"r27" ,"r28" ,"r29" , +"r30" ,"r31" );#elif defined(__arm__) asmvolatile ("mov pc, %0\n\t" ".global exec_loop\n\t"
@@ -1488,6 +1499,24 @@ int cpu_signal_handler(int host_signum, is_write, &uc->uc_sigmask, puc); } +#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 #error host CPU specific signal handler needed
disas.c +2 -0
@@ -279,6 +279,8 @@ void disas(FILE *out, void *code, unsign print_insn = print_insn_m68k;#elif defined(__s390__) print_insn = print_insn_s390; +#elif defined(__hppa__) + print_insn = print_insn_hppa;#else fprintf (out,"0x%lx: Asm output not supported on this arch\n" , (long ) code);
dis-asm.h +4 -0
@@ -157,6 +157,10 @@ enum bfd_architecture#define bfd_mach_ppc_7400 7400 bfd_arch_rs6000, /* IBM RS/6000 */ bfd_arch_hppa, /* HP PA RISC */ +#define bfd_mach_hppa10 10 +#define bfd_mach_hppa11 11 +#define bfd_mach_hppa20 20 +#define bfd_mach_hppa20w 25 bfd_arch_d10v, /* Mitsubishi D10V */ bfd_arch_z8k, /* Zilog Z8000 */#define bfd_mach_z8001 1
dyngen.c +127 -2
167 lines not on this page · raw message
dyngen-exec.h +7 -0
@@ -124,6 +124,11 @@ extern int printf(const char *, ...);#define AREG1 "r4"#define AREG2 "r5"#define AREG3 "r6" +#elif defined(__hppa__) +#define AREG0 "r17" +#define AREG1 "r14" +#define AREG2 "r15" +#define AREG3 "r16"#elif defined(__mips__)#define AREG0 "fp"#define AREG1 "s0"
@@ -279,6 +284,8 @@ extern int __op_jmp0, __op_jmp1, __op_jm#elif defined(__mips__)#define EXIT_TB () asm volatile ("jr $ra")#define GOTO_LABEL_PARAM (n) asm volatile (".set noat; la $1, " ASM_NAME(__op_gen_label) #n "; jr $1; .set at") +#elif defined(__hppa__) +#define GOTO_LABEL_PARAM (n) asm volatile ("b,n " ASM_NAME(__op_gen_label) #n)#else #error unsupported CPU#endif
hppa.ld +214 -0
214 lines not on this page · raw message
Makefile.target +8 -0
@@ -128,6 +128,11 @@ ifeq ($(ARCH),alpha) CFLAGS+=-msmall-data endif +ifeq ($(ARCH),hppa) +OP_CFLAGS=-O1 -fno-delayed-branch +BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld +endif + ifeq ($(ARCH),ia64) CFLAGS+=-mno-sdata OP_CFLAGS+=-mno-sdata
@@ -267,6 +272,9 @@ endif ifeq ($(findstring sh4, $(TARGET_ARCH) $(ARCH)),sh4) LIBOBJS+=sh4-dis.o endif +ifeq ($(findstring hppa, $(TARGET_BASE_ARCH) $(ARCH)),hppa) +LIBOBJS+=hppa-dis.o +endif ifeq ($(findstring s390, $(TARGET_ARCH) $(ARCH)),s390) LIBOBJS+=s390-dis.o endif
tcg/hppa/tcg-target.c +980 -0
980 lines not on this page · raw message
tcg/hppa/tcg-target.h +204 -0
204 lines not on this page · raw message
tcg/i386/tcg-target.c +2 -1
@@ -47,8 +47,9 @@ const int tcg_target_call_iarg_regs[3] =const int tcg_target_call_oarg_regs[2 ] = {TCG_REG_EAX ,TCG_REG_EDX };static void patch_reloc (uint8_t *code_ptr,int type, -tcg_target_long value) +tcg_target_long value,tcg_target_long addend) { + value += addend;switch (type) {case R_386_32 : *(uint32_t *)code_ptr = value;
tcg/sparc/tcg-target.c +2 -1
@@ -88,8 +88,9 @@ static const int tcg_target_call_oarg_re };static void patch_reloc (uint8_t *code_ptr,int type, -tcg_target_long value) +tcg_target_long value,tcg_target_long addend) { + value += addend;switch (type) {case R_SPARC_32 :if (value != (uint32_t )value)
tcg/tcg.c +23 -7
@@ -53,7 +53,7 @@static void patch_reloc (uint8_t *code_ptr,int type, -tcg_target_long value); +tcg_target_long value,tcg_target_long addend);TCGOpDef tcg_op_defs[] = { #define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size },
@@ -100,7 +100,7 @@ void tcg_out_reloc(TCGContext *s, uint8_/* FIXME: This may break relocations on RISC targets that modify instruction fields in place. The caller may not have written the initial value. */ -patch_reloc (code_ptr, type, l->u.value + addend); +patch_reloc (code_ptr, type, l->u.value, addend); }else {/* add a new relocation entry */ r =tcg_malloc (sizeof (TCGRelocation));
@@ -123,7 +123,7 @@ static void tcg_out_label(TCGContext *s,tcg_abort (); r = l->u.first_reloc;while (r !=NULL ) { -patch_reloc (r->ptr, r->type, value + r->addend); +patch_reloc (r->ptr, r->type, value, r->addend); r = r->next; } l->has_value =1 ;
@@ -1442,7 +1442,7 @@ static int tcg_reg_alloc_call(TCGContextint nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;TCGArg arg, func_arg;TCGTemp *ts; -tcg_target_long stack_offset, call_stack_size; +tcg_target_long stack_offset, call_stack_size, func_addr;int const_func_arg;TCGRegSet allocated_regs;const TCGArgConstraint *arg_ct;
@@ -1464,7 +1464,11 @@ static int tcg_reg_alloc_call(TCGContext call_stack_size = (nb_params - nb_regs) *sizeof (tcg_target_long); call_stack_size = (call_stack_size +TCG_TARGET_STACK_ALIGN -1 ) & ~(TCG_TARGET_STACK_ALIGN -1 ); +#ifdef TCG_TARGET_STACK_GROWSUP +tcg_out_addi (s,TCG_REG_CALL_STACK , call_stack_size); +#else tcg_out_addi (s,TCG_REG_CALL_STACK , -call_stack_size); +#endif stack_offset =0 ;for (i = nb_regs; i < nb_params; i++) {
@@ -1487,7 +1491,11 @@ static int tcg_reg_alloc_call(TCGContext }else {tcg_abort (); } +#ifdef TCG_TARGET_STACK_GROWSUP + stack_offset -=sizeof (tcg_target_long); +#else stack_offset +=sizeof (tcg_target_long); +#endif }/* assign input registers */
@@ -1516,6 +1524,10 @@ static int tcg_reg_alloc_call(TCGContext func_arg = args[nb_oargs + nb_iargs -1 ]; arg_ct = &def->args_ct[0 ]; ts = &s->temps[func_arg]; + func_addr = ts->val; +#ifdef HOST_HPPA + func_addr = (tcg_target_long )__canonicalize_funcptr_for_compare ((void *)func_addr); +#endif const_func_arg =0 ;if (ts->val_type ==TEMP_VAL_MEM ) { reg =tcg_reg_alloc (s, arg_ct->u.regs, allocated_regs);
@@ -1529,12 +1541,12 @@ static int tcg_reg_alloc_call(TCGContext } func_arg = reg; }else if (ts->val_type ==TEMP_VAL_CONST ) { -if (tcg_target_const_match (ts->val, arg_ct)) { +if (tcg_target_const_match (func_addr, arg_ct)) { const_func_arg =1 ; - func_arg = ts->val; + func_arg = func_addr; }else { reg =tcg_reg_alloc (s, arg_ct->u.regs, allocated_regs); -tcg_out_movi (s, ts->type, reg, ts->val); +tcg_out_movi (s, ts->type, reg, func_addr); func_arg = reg; } }else {
@@ -1574,7 +1586,11 @@ static int tcg_reg_alloc_call(TCGContexttcg_out_op (s, opc, &func_arg, &const_func_arg); +#ifdef TCG_TARGET_STACK_GROWSUP +tcg_out_addi (s,TCG_REG_CALL_STACK , -call_stack_size); +#else tcg_out_addi (s,TCG_REG_CALL_STACK , call_stack_size); +#endif /* assign output registers and emit moves if needed */ for (i =0 ; i < nb_oargs; i++) {
tcg/tcg-dyngen.c +50 -0
66 lines not on this page · raw message
tcg/x86_64/tcg-target.c +2 -1
@@ -74,8 +74,9 @@ const int tcg_target_call_oarg_regs[2] = };static void patch_reloc (uint8_t *code_ptr,int type, -tcg_target_long value) +tcg_target_long value,tcg_target_long addend) { + value += addend;switch (type) {case R_X86_64_32 :if (value != (uint32_t )value)