aboutsummaryrefslogtreecommitdiff
path: root/target-sparc/op.c
diff options
context:
space:
mode:
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2007-09-21 19:10:53 +0000
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2007-09-21 19:10:53 +0000
commit81ad8ba242815e27f990e18778c7cdca2e7e7522 (patch)
tree40a4c750eb33901b9eee8fc53459ae0e88c32a66 /target-sparc/op.c
parent43febf49523552ca678eacc2677d3bac58cda4c0 (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.c144
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) \