diff options
author | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-09-21 19:10:53 +0000 |
---|---|---|
committer | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-09-21 19:10:53 +0000 |
commit | 81ad8ba242815e27f990e18778c7cdca2e7e7522 (patch) | |
tree | 40a4c750eb33901b9eee8fc53459ae0e88c32a66 /target-sparc/op.c | |
parent | 43febf49523552ca678eacc2677d3bac58cda4c0 (diff) |
Rework ASI instructions (Aurelien Jarno)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3205 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc/op.c')
-rw-r--r-- | target-sparc/op.c | 144 |
1 files changed, 142 insertions, 2 deletions
diff --git a/target-sparc/op.c b/target-sparc/op.c index f2168af9ab..bb084ee0db 100644 --- a/target-sparc/op.c +++ b/target-sparc/op.c @@ -1862,10 +1862,126 @@ void OPPROTO op_ld_asi_reg() void OPPROTO op_st_asi_reg() { T0 += PARAM1; - helper_st_asi(env->asi, PARAM2, PARAM3); + helper_st_asi(env->asi, PARAM2); +} + +void OPPROTO op_ldstub_asi_reg() /* XXX: should be atomically */ +{ + target_ulong tmp; + + T0 += PARAM1; + helper_ld_asi(env->asi, 1, 0); + tmp = T1; + T1 = 0xff; + helper_st_asi(env->asi, 1); + T1 = tmp; +} + +void OPPROTO op_swap_asi_reg() /* XXX: should be atomically */ +{ + target_ulong tmp1, tmp2; + + T0 += PARAM1; + tmp1 = T1; + helper_ld_asi(env->asi, 4, 0); + tmp2 = T1; + T1 = tmp1; + helper_st_asi(env->asi, 4); + T1 = tmp2; +} + +void OPPROTO op_ldda_asi() +{ + helper_ld_asi(PARAM1, 8, 0); + T0 = T1 & 0xffffffffUL; + T1 >>= 32; +} + +void OPPROTO op_ldda_asi_reg() +{ + T0 += PARAM1; + helper_ld_asi(env->asi, 8, 0); + T0 = T1 & 0xffffffffUL; + T1 >>= 32; +} + +void OPPROTO op_stda_asi() +{ + T1 <<= 32; + T1 += T2 & 0xffffffffUL; + helper_st_asi(PARAM1, 8); +} + +void OPPROTO op_stda_asi_reg() +{ + T0 += PARAM1; + T1 <<= 32; + T1 += T2 & 0xffffffffUL; + helper_st_asi(env->asi, 8); +} + +void OPPROTO op_cas_asi() /* XXX: should be atomically */ +{ + target_ulong tmp; + + tmp = T1 & 0xffffffffUL; + helper_ld_asi(PARAM1, 4, 0); + if (tmp == T1) { + tmp = T1; + T1 = T2 & 0xffffffffUL; + helper_st_asi(PARAM1, 4); + T1 = tmp; + } + T1 &= 0xffffffffUL; +} + +void OPPROTO op_cas_asi_reg() /* XXX: should be atomically */ +{ + target_ulong tmp; + + T0 += PARAM1; + tmp = T1 & 0xffffffffUL; + helper_ld_asi(env->asi, 4, 0); + if (tmp == T1) { + tmp = T1; + T1 = T2 & 0xffffffffUL; + helper_st_asi(env->asi, 4); + T1 = tmp; + } + T1 &= 0xffffffffUL; +} + +void OPPROTO op_casx_asi() /* XXX: should be atomically */ +{ + target_ulong tmp; + + tmp = T1; + helper_ld_asi(PARAM1, 8, 0); + if (tmp == T1) { + tmp = T1; + T1 = T2; + helper_st_asi(PARAM1, 8); + T1 = tmp; + } +} + +void OPPROTO op_casx_asi_reg() /* XXX: should be atomically */ +{ + target_ulong tmp; + + T0 += PARAM1; + tmp = T1; + helper_ld_asi(env->asi, 8, 0); + if (tmp == T1) { + tmp = T1; + T1 = T2; + helper_st_asi(env->asi, 8); + T1 = tmp; + } } #endif +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) void OPPROTO op_ld_asi() { helper_ld_asi(PARAM1, PARAM2, PARAM3); @@ -1873,9 +1989,33 @@ void OPPROTO op_ld_asi() void OPPROTO op_st_asi() { - helper_st_asi(PARAM1, PARAM2, PARAM3); + helper_st_asi(PARAM1, PARAM2); } +void OPPROTO op_ldstub_asi() /* XXX: should be atomically */ +{ + target_ulong tmp; + + helper_ld_asi(PARAM1, 1, 0); + tmp = T1; + T1 = 0xff; + helper_st_asi(PARAM1, 1); + T1 = tmp; +} + +void OPPROTO op_swap_asi() /* XXX: should be atomically */ +{ + target_ulong tmp1, tmp2; + + tmp1 = T1; + helper_ld_asi(PARAM1, 4, 0); + tmp2 = T1; + T1 = tmp1; + helper_st_asi(PARAM1, 4); + T1 = tmp2; +} +#endif + #ifdef TARGET_SPARC64 // This function uses non-native bit order #define GET_FIELD(X, FROM, TO) \ |