diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-07-18 21:12:17 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-07-18 21:12:17 +0000 |
commit | 725cb90bf7e2487fe5aa5621cc10afe6d169e310 (patch) | |
tree | 8d2ffe0b21338890a08f140696e910a1ecb8d960 /target-sparc | |
parent | a3c259974ea93b160112a9c61101e667664443c3 (diff) | |
download | hqemu-725cb90bf7e2487fe5aa5621cc10afe6d169e310.zip hqemu-725cb90bf7e2487fe5aa5621cc10afe6d169e310.tar.gz |
sparc64 fixes (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2062 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc')
-rw-r--r-- | target-sparc/cpu.h | 1 | ||||
-rw-r--r-- | target-sparc/op.c | 24 | ||||
-rw-r--r-- | target-sparc/translate.c | 47 |
3 files changed, 69 insertions, 3 deletions
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index d0bcd40..8cbf0b2 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -210,6 +210,7 @@ typedef struct CPUSPARCState { uint64_t version; uint64_t fprs; uint64_t tick_cmpr, stick_cmpr; + uint64_t gsr; #endif #if !defined(TARGET_SPARC64) && !defined(reg_T2) target_ulong t2; diff --git a/target-sparc/op.c b/target-sparc/op.c index f6d417f..7ea209e 100644 --- a/target-sparc/op.c +++ b/target-sparc/op.c @@ -1514,6 +1514,9 @@ void OPPROTO op_saved(void) env->cansave++; if (env->otherwin == 0) env->canrestore--; + else + env->otherwin--; + FORCE_RET(); } void OPPROTO op_restored(void) @@ -1525,6 +1528,7 @@ void OPPROTO op_restored(void) env->cansave--; else env->otherwin--; + FORCE_RET(); } void OPPROTO op_popc(void) @@ -1571,3 +1575,23 @@ void OPPROTO op_st_asi() helper_st_asi(PARAM1, PARAM2, PARAM3); } +#ifdef TARGET_SPARC64 +void OPPROTO op_alignaddr() +{ + uint64_t tmp; + + tmp = T0 + T1; + env->gsr &= ~7ULL; + env->gsr |= tmp & 7ULL; + T0 = tmp & ~7ULL; +} + +void OPPROTO op_faligndata() +{ + uint64_t tmp; + + tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8); + tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8); + (*((uint64_t *)&DT0)) = tmp; +} +#endif diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 26c8145..4a8ad70 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -364,6 +364,9 @@ GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf); case 0x80: /* Primary address space */ \ gen_op_##width##_raw(); \ break; \ + case 0x82: /* Primary address space, non-faulting load */ \ + gen_op_##width##_raw(); \ + break; \ default: \ break; \ } \ @@ -1151,6 +1154,12 @@ static void disas_sparc_insn(DisasContext * dc) gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs)); gen_movl_T0_reg(rd); break; + case 0x13: /* Graphics Status */ + if (gen_trap_ifnofpu(dc)) + goto jmp_insn; + gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr)); + gen_movl_T0_reg(rd); + break; case 0x17: /* Tick compare */ gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr)); gen_movl_T0_reg(rd); @@ -1166,7 +1175,6 @@ static void disas_sparc_insn(DisasContext * dc) case 0x10: /* Performance Control */ case 0x11: /* Performance Instrumentation Counter */ case 0x12: /* Dispatch Control */ - case 0x13: /* Graphics Status */ case 0x14: /* Softint set, WO */ case 0x15: /* Softint clear, WO */ case 0x16: /* Softint write */ @@ -1870,6 +1878,11 @@ static void disas_sparc_insn(DisasContext * dc) gen_op_sir(); #endif break; + case 0x13: /* Graphics Status */ + if (gen_trap_ifnofpu(dc)) + goto jmp_insn; + gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr)); + break; case 0x17: /* Tick compare */ #if !defined(CONFIG_USER_ONLY) if (!supervisor(dc)) @@ -1895,7 +1908,6 @@ static void disas_sparc_insn(DisasContext * dc) case 0x10: /* Performance Control */ case 0x11: /* Performance Instrumentation Counter */ case 0x12: /* Dispatch Control */ - case 0x13: /* Graphics Status */ case 0x14: /* Softint set */ case 0x15: /* Softint clear */ case 0x16: /* Softint write */ @@ -2077,7 +2089,36 @@ static void disas_sparc_insn(DisasContext * dc) } case 0x36: /* UltraSparc shutdown, VIS */ { - // XXX + int opf = GET_FIELD_SP(insn, 5, 13); + rs1 = GET_FIELD(insn, 13, 17); + rs2 = GET_FIELD(insn, 27, 31); + + switch (opf) { + case 0x018: /* VIS I alignaddr */ + if (gen_trap_ifnofpu(dc)) + goto jmp_insn; + gen_movl_reg_T0(rs1); + gen_movl_reg_T1(rs2); + gen_op_alignaddr(); + gen_movl_T0_reg(rd); + break; + case 0x01a: /* VIS I alignaddrl */ + if (gen_trap_ifnofpu(dc)) + goto jmp_insn; + // XXX + break; + case 0x048: /* VIS I faligndata */ + if (gen_trap_ifnofpu(dc)) + goto jmp_insn; + gen_op_load_fpr_DT0(rs1); + gen_op_load_fpr_DT1(rs2); + gen_op_faligndata(); + gen_op_store_DT0_fpr(rd); + break; + default: + goto illegal_insn; + } + break; } #endif default: |