sparc64 fixes (Blue Swirl)
[qemu] / target-sparc / op.c
index e466e09..7ea209e 100644 (file)
 #define REG (env->gregs[7])
 #include "op_template.h"
 #define REGNAME i0
-#define REG (env->regwptr[16])
+#define REG (REGWPTR[16])
 #include "op_template.h"
 #define REGNAME i1
-#define REG (env->regwptr[17])
+#define REG (REGWPTR[17])
 #include "op_template.h"
 #define REGNAME i2
-#define REG (env->regwptr[18])
+#define REG (REGWPTR[18])
 #include "op_template.h"
 #define REGNAME i3
-#define REG (env->regwptr[19])
+#define REG (REGWPTR[19])
 #include "op_template.h"
 #define REGNAME i4
-#define REG (env->regwptr[20])
+#define REG (REGWPTR[20])
 #include "op_template.h"
 #define REGNAME i5
-#define REG (env->regwptr[21])
+#define REG (REGWPTR[21])
 #include "op_template.h"
 #define REGNAME i6
-#define REG (env->regwptr[22])
+#define REG (REGWPTR[22])
 #include "op_template.h"
 #define REGNAME i7
-#define REG (env->regwptr[23])
+#define REG (REGWPTR[23])
 #include "op_template.h"
 #define REGNAME l0
-#define REG (env->regwptr[8])
+#define REG (REGWPTR[8])
 #include "op_template.h"
 #define REGNAME l1
-#define REG (env->regwptr[9])
+#define REG (REGWPTR[9])
 #include "op_template.h"
 #define REGNAME l2
-#define REG (env->regwptr[10])
+#define REG (REGWPTR[10])
 #include "op_template.h"
 #define REGNAME l3
-#define REG (env->regwptr[11])
+#define REG (REGWPTR[11])
 #include "op_template.h"
 #define REGNAME l4
-#define REG (env->regwptr[12])
+#define REG (REGWPTR[12])
 #include "op_template.h"
 #define REGNAME l5
-#define REG (env->regwptr[13])
+#define REG (REGWPTR[13])
 #include "op_template.h"
 #define REGNAME l6
-#define REG (env->regwptr[14])
+#define REG (REGWPTR[14])
 #include "op_template.h"
 #define REGNAME l7
-#define REG (env->regwptr[15])
+#define REG (REGWPTR[15])
 #include "op_template.h"
 #define REGNAME o0
-#define REG (env->regwptr[0])
+#define REG (REGWPTR[0])
 #include "op_template.h"
 #define REGNAME o1
-#define REG (env->regwptr[1])
+#define REG (REGWPTR[1])
 #include "op_template.h"
 #define REGNAME o2
-#define REG (env->regwptr[2])
+#define REG (REGWPTR[2])
 #include "op_template.h"
 #define REGNAME o3
-#define REG (env->regwptr[3])
+#define REG (REGWPTR[3])
 #include "op_template.h"
 #define REGNAME o4
-#define REG (env->regwptr[4])
+#define REG (REGWPTR[4])
 #include "op_template.h"
 #define REGNAME o5
-#define REG (env->regwptr[5])
+#define REG (REGWPTR[5])
 #include "op_template.h"
 #define REGNAME o6
-#define REG (env->regwptr[6])
+#define REG (REGWPTR[6])
 #include "op_template.h"
 #define REGNAME o7
-#define REG (env->regwptr[7])
+#define REG (REGWPTR[7])
 #include "op_template.h"
+
+#define REGNAME f0
+#define REG (env->fpr[0])
+#include "fop_template.h"
+#define REGNAME f1
+#define REG (env->fpr[1])
+#include "fop_template.h"
+#define REGNAME f2
+#define REG (env->fpr[2])
+#include "fop_template.h"
+#define REGNAME f3
+#define REG (env->fpr[3])
+#include "fop_template.h"
+#define REGNAME f4
+#define REG (env->fpr[4])
+#include "fop_template.h"
+#define REGNAME f5
+#define REG (env->fpr[5])
+#include "fop_template.h"
+#define REGNAME f6
+#define REG (env->fpr[6])
+#include "fop_template.h"
+#define REGNAME f7
+#define REG (env->fpr[7])
+#include "fop_template.h"
+#define REGNAME f8
+#define REG (env->fpr[8])
+#include "fop_template.h"
+#define REGNAME f9
+#define REG (env->fpr[9])
+#include "fop_template.h"
+#define REGNAME f10
+#define REG (env->fpr[10])
+#include "fop_template.h"
+#define REGNAME f11
+#define REG (env->fpr[11])
+#include "fop_template.h"
+#define REGNAME f12
+#define REG (env->fpr[12])
+#include "fop_template.h"
+#define REGNAME f13
+#define REG (env->fpr[13])
+#include "fop_template.h"
+#define REGNAME f14
+#define REG (env->fpr[14])
+#include "fop_template.h"
+#define REGNAME f15
+#define REG (env->fpr[15])
+#include "fop_template.h"
+#define REGNAME f16
+#define REG (env->fpr[16])
+#include "fop_template.h"
+#define REGNAME f17
+#define REG (env->fpr[17])
+#include "fop_template.h"
+#define REGNAME f18
+#define REG (env->fpr[18])
+#include "fop_template.h"
+#define REGNAME f19
+#define REG (env->fpr[19])
+#include "fop_template.h"
+#define REGNAME f20
+#define REG (env->fpr[20])
+#include "fop_template.h"
+#define REGNAME f21
+#define REG (env->fpr[21])
+#include "fop_template.h"
+#define REGNAME f22
+#define REG (env->fpr[22])
+#include "fop_template.h"
+#define REGNAME f23
+#define REG (env->fpr[23])
+#include "fop_template.h"
+#define REGNAME f24
+#define REG (env->fpr[24])
+#include "fop_template.h"
+#define REGNAME f25
+#define REG (env->fpr[25])
+#include "fop_template.h"
+#define REGNAME f26
+#define REG (env->fpr[26])
+#include "fop_template.h"
+#define REGNAME f27
+#define REG (env->fpr[27])
+#include "fop_template.h"
+#define REGNAME f28
+#define REG (env->fpr[28])
+#include "fop_template.h"
+#define REGNAME f29
+#define REG (env->fpr[29])
+#include "fop_template.h"
+#define REGNAME f30
+#define REG (env->fpr[30])
+#include "fop_template.h"
+#define REGNAME f31
+#define REG (env->fpr[31])
+#include "fop_template.h"
+
+#ifdef TARGET_SPARC64
+#define REGNAME f32
+#define REG (env->fpr[32])
+#include "fop_template.h"
+#define REGNAME f34
+#define REG (env->fpr[34])
+#include "fop_template.h"
+#define REGNAME f36
+#define REG (env->fpr[36])
+#include "fop_template.h"
+#define REGNAME f38
+#define REG (env->fpr[38])
+#include "fop_template.h"
+#define REGNAME f40
+#define REG (env->fpr[40])
+#include "fop_template.h"
+#define REGNAME f42
+#define REG (env->fpr[42])
+#include "fop_template.h"
+#define REGNAME f44
+#define REG (env->fpr[44])
+#include "fop_template.h"
+#define REGNAME f46
+#define REG (env->fpr[46])
+#include "fop_template.h"
+#define REGNAME f48
+#define REG (env->fpr[47])
+#include "fop_template.h"
+#define REGNAME f50
+#define REG (env->fpr[50])
+#include "fop_template.h"
+#define REGNAME f52
+#define REG (env->fpr[52])
+#include "fop_template.h"
+#define REGNAME f54
+#define REG (env->fpr[54])
+#include "fop_template.h"
+#define REGNAME f56
+#define REG (env->fpr[56])
+#include "fop_template.h"
+#define REGNAME f58
+#define REG (env->fpr[58])
+#include "fop_template.h"
+#define REGNAME f60
+#define REG (env->fpr[60])
+#include "fop_template.h"
+#define REGNAME f62
+#define REG (env->fpr[62])
+#include "fop_template.h"
+#endif
+
+#ifdef TARGET_SPARC64
+#ifdef WORDS_BIGENDIAN
+typedef union UREG64 {
+    struct { uint16_t v3, v2, v1, v0; } w;
+    struct { uint32_t v1, v0; } l;
+    uint64_t q;
+} UREG64;
+#else
+typedef union UREG64 {
+    struct { uint16_t v0, v1, v2, v3; } w;
+    struct { uint32_t v0, v1; } l;
+    uint64_t q;
+} UREG64;
+#endif
+
+#define PARAMQ1 \
+({\
+    UREG64 __p;\
+    __p.l.v1 = PARAM1;\
+    __p.l.v0 = PARAM2;\
+    __p.q;\
+}) 
+
+void OPPROTO op_movq_T0_im64(void)
+{
+    T0 = PARAMQ1;
+}
+
+void OPPROTO op_movq_T1_im64(void)
+{
+    T1 = PARAMQ1;
+}
+
+#define XFLAG_SET(x) ((env->xcc&x)?1:0)
+
+#else
 #define EIP (env->pc)
+#endif
 
-#define FLAG_SET(x) (env->psr&x)?1:0
+#define FLAG_SET(x) ((env->psr&x)?1:0)
 
 void OPPROTO op_movl_T0_0(void)
 {
     T0 = 0;
 }
 
-void OPPROTO op_movl_T0_1(void)
-{
-    T0 = 1;
-}
-
 void OPPROTO op_movl_T0_im(void)
 {
-    T0 = PARAM1;
+    T0 = (uint32_t)PARAM1;
 }
 
 void OPPROTO op_movl_T1_im(void)
 {
-    T1 = PARAM1;
+    T1 = (uint32_t)PARAM1;
 }
 
 void OPPROTO op_movl_T2_im(void)
 {
-    T2 = PARAM1;
+    T2 = (uint32_t)PARAM1;
+}
+
+void OPPROTO op_movl_T0_sim(void)
+{
+    T0 = (int32_t)PARAM1;
+}
+
+void OPPROTO op_movl_T1_sim(void)
+{
+    T1 = (int32_t)PARAM1;
+}
+
+void OPPROTO op_movl_T2_sim(void)
+{
+    T2 = (int32_t)PARAM1;
 }
 
-void OPPROTO op_addl_T1_im(void)
+void OPPROTO op_movl_T0_env(void)
 {
-    T1 += PARAM1;
+    T0 = *(uint32_t *)((char *)env + PARAM1);
 }
 
-void OPPROTO op_addl_T1_T2(void)
+void OPPROTO op_movl_env_T0(void)
 {
-    T1 += T2;
+    *(uint32_t *)((char *)env + PARAM1) = T0;
 }
 
-void OPPROTO op_subl_T1_T2(void)
+void OPPROTO op_movtl_T0_env(void)
 {
-    T1 -= T2;
+    T0 = *(target_ulong *)((char *)env + PARAM1);
+}
+
+void OPPROTO op_movtl_env_T0(void)
+{
+    *(target_ulong *)((char *)env + PARAM1) = T0;
 }
 
 void OPPROTO op_add_T1_T0(void)
@@ -168,18 +369,106 @@ void OPPROTO op_add_T1_T0(void)
 
 void OPPROTO op_add_T1_T0_cc(void)
 {
-    unsigned int src1;
+    target_ulong src1;
+
     src1 = T0;
     T0 += T1;
     env->psr = 0;
+#ifdef TARGET_SPARC64
+    if (!(T0 & 0xffffffff))
+       env->psr |= PSR_ZERO;
+    if ((int32_t) T0 < 0)
+       env->psr |= PSR_NEG;
+    if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
+       env->psr |= PSR_CARRY;
+    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
+        ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
+       env->psr |= PSR_OVF;
+
+    env->xcc = 0;
+    if (!T0)
+       env->xcc |= PSR_ZERO;
+    if ((int64_t) T0 < 0)
+       env->xcc |= PSR_NEG;
+    if (T0 < src1)
+       env->xcc |= PSR_CARRY;
+    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
+       env->xcc |= PSR_OVF;
+#else
     if (!T0)
        env->psr |= PSR_ZERO;
-    if ((int) T0 < 0)
+    if ((int32_t) T0 < 0)
        env->psr |= PSR_NEG;
     if (T0 < src1)
        env->psr |= PSR_CARRY;
     if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
        env->psr |= PSR_OVF;
+#endif
+    FORCE_RET();
+}
+
+void OPPROTO op_addx_T1_T0(void)
+{
+    T0 += T1 + FLAG_SET(PSR_CARRY);
+}
+
+void OPPROTO op_addx_T1_T0_cc(void)
+{
+    target_ulong src1;
+    src1 = T0;
+    if (FLAG_SET(PSR_CARRY))
+    {
+      T0 += T1 + 1;
+      env->psr = 0;
+#ifdef TARGET_SPARC64
+      if ((T0 & 0xffffffff) <= (src1 & 0xffffffff))
+        env->psr |= PSR_CARRY;
+      env->xcc = 0;
+      if (T0 <= src1)
+        env->xcc |= PSR_CARRY;
+#else
+      if (T0 <= src1)
+        env->psr |= PSR_CARRY;
+#endif
+    }
+    else
+    {
+      T0 += T1;
+      env->psr = 0;
+#ifdef TARGET_SPARC64
+      if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
+        env->psr |= PSR_CARRY;
+      env->xcc = 0;
+      if (T0 < src1)
+        env->xcc |= PSR_CARRY;
+#else
+      if (T0 < src1)
+        env->psr |= PSR_CARRY;
+#endif
+    }
+#ifdef TARGET_SPARC64
+    if (!(T0 & 0xffffffff))
+       env->psr |= PSR_ZERO;
+    if ((int32_t) T0 < 0)
+       env->psr |= PSR_NEG;
+    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
+        ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
+       env->psr |= PSR_OVF;
+
+    if (!T0)
+       env->xcc |= PSR_ZERO;
+    if ((int64_t) T0 < 0)
+       env->xcc |= PSR_NEG;
+    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
+       env->xcc |= PSR_OVF;
+#else
+    if (!T0)
+       env->psr |= PSR_ZERO;
+    if ((int32_t) T0 < 0)
+       env->psr |= PSR_NEG;
+    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
+       env->psr |= PSR_OVF;
+#endif
     FORCE_RET();
 }
 
@@ -190,19 +479,106 @@ void OPPROTO op_sub_T1_T0(void)
 
 void OPPROTO op_sub_T1_T0_cc(void)
 {
-    unsigned int src1;
+    target_ulong src1;
 
     src1 = T0;
     T0 -= T1;
     env->psr = 0;
+#ifdef TARGET_SPARC64
+    if (!(T0 & 0xffffffff))
+       env->psr |= PSR_ZERO;
+    if ((int32_t) T0 < 0)
+       env->psr |= PSR_NEG;
+    if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
+       env->psr |= PSR_CARRY;
+    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
+        ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
+       env->psr |= PSR_OVF;
+
+    env->xcc = 0;
+    if (!T0)
+       env->xcc |= PSR_ZERO;
+    if ((int64_t) T0 < 0)
+       env->xcc |= PSR_NEG;
+    if (src1 < T1)
+       env->xcc |= PSR_CARRY;
+    if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
+       env->xcc |= PSR_OVF;
+#else
     if (!T0)
        env->psr |= PSR_ZERO;
-    if ((int) T0 < 0)
+    if ((int32_t) T0 < 0)
        env->psr |= PSR_NEG;
     if (src1 < T1)
        env->psr |= PSR_CARRY;
     if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
        env->psr |= PSR_OVF;
+#endif
+    FORCE_RET();
+}
+
+void OPPROTO op_subx_T1_T0(void)
+{
+    T0 -= T1 + FLAG_SET(PSR_CARRY);
+}
+
+void OPPROTO op_subx_T1_T0_cc(void)
+{
+    target_ulong src1;
+    src1 = T0;
+    if (FLAG_SET(PSR_CARRY))
+    {
+      T0 -= T1 + 1;
+      env->psr = 0;
+#ifdef TARGET_SPARC64
+      if ((src1 & 0xffffffff) <= (T1 & 0xffffffff))
+        env->psr |= PSR_CARRY;
+      env->xcc = 0;
+      if (src1 <= T1)
+        env->xcc |= PSR_CARRY;
+#else
+      if (src1 <= T1)
+        env->psr |= PSR_CARRY;
+#endif
+    }
+    else
+    {
+      T0 -= T1;
+      env->psr = 0;
+#ifdef TARGET_SPARC64
+      if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
+        env->psr |= PSR_CARRY;
+      env->xcc = 0;
+      if (src1 < T1)
+        env->xcc |= PSR_CARRY;
+#else
+      if (src1 < T1)
+        env->psr |= PSR_CARRY;
+#endif
+    }
+#ifdef TARGET_SPARC64
+    if (!(T0 & 0xffffffff))
+       env->psr |= PSR_ZERO;
+    if ((int32_t) T0 < 0)
+       env->psr |= PSR_NEG;
+    if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
+        ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
+       env->psr |= PSR_OVF;
+
+    if (!T0)
+       env->xcc |= PSR_ZERO;
+    if ((int64_t) T0 < 0)
+       env->xcc |= PSR_NEG;
+    if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
+       env->xcc |= PSR_OVF;
+#else
+    if (!T0)
+       env->psr |= PSR_ZERO;
+    if ((int32_t) T0 < 0)
+       env->psr |= PSR_NEG;
+    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
+       env->psr |= PSR_OVF;
+#endif
     FORCE_RET();
 }
 
@@ -236,16 +612,15 @@ void OPPROTO op_xnor_T1_T0(void)
     T0 ^= ~T1;
 }
 
-void OPPROTO op_addx_T1_T0(void)
-{
-    T0 += T1 + ((env->psr & PSR_CARRY) ? 1 : 0);
-}
-
 void OPPROTO op_umul_T1_T0(void)
 {
     uint64_t res;
-    res = (uint64_t) T0 *(uint64_t) T1;
+    res = (uint64_t) T0 * (uint64_t) T1;
+#ifdef TARGET_SPARC64
+    T0 = res;
+#else
     T0 = res & 0xffffffff;
+#endif
     env->y = res >> 32;
 }
 
@@ -253,16 +628,22 @@ void OPPROTO op_smul_T1_T0(void)
 {
     uint64_t res;
     res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
+#ifdef TARGET_SPARC64
+    T0 = res;
+#else
     T0 = res & 0xffffffff;
+#endif
     env->y = res >> 32;
 }
 
 void OPPROTO op_mulscc_T1_T0(void)
 {
-    unsigned int b1, C, V, b2, src1;
-    C = FLAG_SET(PSR_CARRY);
+    unsigned int b1, N, V, b2;
+    target_ulong src1;
+
+    N = FLAG_SET(PSR_NEG);
     V = FLAG_SET(PSR_OVF);
-    b1 = C ^ V;
+    b1 = N ^ V;
     b2 = T0 & 1;
     T0 = (b1 << 31) | (T0 >> 1);
     if (!(env->y & 1))
@@ -273,7 +654,7 @@ void OPPROTO op_mulscc_T1_T0(void)
     env->psr = 0;
     if (!T0)
        env->psr |= PSR_ZERO;
-    if ((int) T0 < 0)
+    if ((int32_t) T0 < 0)
        env->psr |= PSR_NEG;
     if (T0 < src1)
        env->psr |= PSR_CARRY;
@@ -306,11 +687,11 @@ void OPPROTO op_sdiv_T1_T0(void)
     int64_t x0;
     int32_t x1;
 
-    x0 = T0 | ((uint64_t) (env->y) << 32);
+    x0 = T0 | ((int64_t) (env->y) << 32);
     x1 = T1;
     x0 = x0 / x1;
     if ((int32_t) x0 != x0) {
-       T0 = x0 >> 63;
+       T0 = x0 < 0? 0x80000000: 0x7fffffff;
        T1 = 1;
     } else {
        T0 = x0;
@@ -322,41 +703,73 @@ void OPPROTO op_sdiv_T1_T0(void)
 void OPPROTO op_div_cc(void)
 {
     env->psr = 0;
+#ifdef TARGET_SPARC64
     if (!T0)
        env->psr |= PSR_ZERO;
-    if ((int) T0 < 0)
+    if ((int32_t) T0 < 0)
        env->psr |= PSR_NEG;
     if (T1)
        env->psr |= PSR_OVF;
+
+    env->xcc = 0;
+    if (!T0)
+       env->xcc |= PSR_ZERO;
+    if ((int64_t) T0 < 0)
+       env->xcc |= PSR_NEG;
+#else
+    if (!T0)
+       env->psr |= PSR_ZERO;
+    if ((int32_t) T0 < 0)
+       env->psr |= PSR_NEG;
+    if (T1)
+       env->psr |= PSR_OVF;
+#endif
     FORCE_RET();
 }
 
-void OPPROTO op_subx_T1_T0(void)
+#ifdef TARGET_SPARC64
+void OPPROTO op_mulx_T1_T0(void)
 {
-    T0 -= T1 + ((env->psr & PSR_CARRY) ? 1 : 0);
+    T0 *= T1;
+    FORCE_RET();
 }
 
-void OPPROTO op_logic_T0_cc(void)
+void OPPROTO op_udivx_T1_T0(void)
 {
-    env->psr = 0;
-    if (!T0)
-       env->psr |= PSR_ZERO;
-    if ((int) T0 < 0)
-       env->psr |= PSR_NEG;
+    T0 /= T1;
+    FORCE_RET();
+}
+
+void OPPROTO op_sdivx_T1_T0(void)
+{
+    if (T0 == INT64_MIN && T1 == -1)
+       T0 = INT64_MIN;
+    else
+       T0 /= (target_long) T1;
     FORCE_RET();
 }
+#endif
 
-void OPPROTO op_set_flags(void)
+void OPPROTO op_logic_T0_cc(void)
 {
     env->psr = 0;
+#ifdef TARGET_SPARC64
+    if (!(T0 & 0xffffffff))
+       env->psr |= PSR_ZERO;
+    if ((int32_t) T0 < 0)
+       env->psr |= PSR_NEG;
+
+    env->xcc = 0;
+    if (!T0)
+       env->xcc |= PSR_ZERO;
+    if ((int64_t) T0 < 0)
+       env->xcc |= PSR_NEG;
+#else
     if (!T0)
        env->psr |= PSR_ZERO;
-    if ((unsigned int) T0 < (unsigned int) T1)
-       env->psr |= PSR_CARRY;
-    if ((int) T0 < (int) T1)
-       env->psr |= PSR_OVF;
-    if ((int) T0 < 0)
+    if ((int32_t) T0 < 0)
        env->psr |= PSR_NEG;
+#endif
     FORCE_RET();
 }
 
@@ -365,6 +778,27 @@ void OPPROTO op_sll(void)
     T0 <<= T1;
 }
 
+#ifdef TARGET_SPARC64
+void OPPROTO op_srl(void)
+{
+    T0 = (T0 & 0xffffffff) >> T1;
+}
+
+void OPPROTO op_srlx(void)
+{
+    T0 >>= T1;
+}
+
+void OPPROTO op_sra(void)
+{
+    T0 = ((int32_t) (T0 & 0xffffffff)) >> T1;
+}
+
+void OPPROTO op_srax(void)
+{
+    T0 = ((int64_t) T0) >> T1;
+}
+#else
 void OPPROTO op_srl(void)
 {
     T0 >>= T1;
@@ -374,135 +808,193 @@ void OPPROTO op_sra(void)
 {
     T0 = ((int32_t) T0) >> T1;
 }
+#endif
+
+/* Load and store */
+#define MEMSUFFIX _raw
+#include "op_mem.h"
+#if !defined(CONFIG_USER_ONLY)
+#define MEMSUFFIX _user
+#include "op_mem.h"
+
+#define MEMSUFFIX _kernel
+#include "op_mem.h"
+#endif
+
+void OPPROTO op_ldfsr(void)
+{
+    PUT_FSR32(env, *((uint32_t *) &FT0));
+    helper_ldfsr();
+}
+
+void OPPROTO op_stfsr(void)
+{
+    *((uint32_t *) &FT0) = GET_FSR32(env);
+}
 
-void OPPROTO op_st(void)
+#ifndef TARGET_SPARC64
+void OPPROTO op_rdpsr(void)
 {
-    stl((void *) T0, T1);
+    do_rdpsr();
 }
 
-void OPPROTO op_stb(void)
+void OPPROTO op_wrpsr(void)
 {
-    stb((void *) T0, T1);
+    do_wrpsr();
+    FORCE_RET();
 }
 
-void OPPROTO op_sth(void)
+void OPPROTO op_rett(void)
 {
-    stw((void *) T0, T1);
+    helper_rett();
+    FORCE_RET();
 }
 
-void OPPROTO op_std(void)
+/* XXX: use another pointer for %iN registers to avoid slow wrapping
+   handling ? */
+void OPPROTO op_save(void)
 {
-    stl((void *) T0, T1);
-    stl((void *) (T0 + 4), T2);
+    uint32_t cwp;
+    cwp = (env->cwp - 1) & (NWINDOWS - 1); 
+    if (env->wim & (1 << cwp)) {
+        raise_exception(TT_WIN_OVF);
+    }
+    set_cwp(cwp);
+    FORCE_RET();
 }
 
-void OPPROTO op_ld(void)
+void OPPROTO op_restore(void)
 {
-    T1 = ldl((void *) T0);
+    uint32_t cwp;
+    cwp = (env->cwp + 1) & (NWINDOWS - 1); 
+    if (env->wim & (1 << cwp)) {
+        raise_exception(TT_WIN_UNF);
+    }
+    set_cwp(cwp);
+    FORCE_RET();
+}
+#else
+void OPPROTO op_rdccr(void)
+{
+    T0 = GET_CCR(env);
 }
 
-void OPPROTO op_ldub(void)
+void OPPROTO op_wrccr(void)
 {
-    T1 = ldub((void *) T0);
+    PUT_CCR(env, T0);
 }
 
-void OPPROTO op_lduh(void)
+void OPPROTO op_rdtick(void)
 {
-    T1 = lduw((void *) T0);
+    T0 = 0; // XXX read cycle counter and bit 31
 }
 
-void OPPROTO op_ldsb(void)
+void OPPROTO op_wrtick(void)
 {
-    T1 = ldsb((void *) T0);
+    // XXX write cycle counter and bit 31
 }
 
-void OPPROTO op_ldsh(void)
+void OPPROTO op_rdtpc(void)
 {
-    T1 = ldsw((void *) T0);
+    T0 = env->tpc[env->tl];
 }
 
-void OPPROTO op_ldstub(void)
+void OPPROTO op_wrtpc(void)
 {
-    T1 = ldub((void *) T0);
-    stb((void *) T0, 0xff);    /* XXX: Should be Atomically */
+    env->tpc[env->tl] = T0;
 }
 
-void OPPROTO op_swap(void)
+void OPPROTO op_rdtnpc(void)
 {
-    unsigned int tmp = ldl((void *) T0);
-    stl((void *) T0, T1);      /* XXX: Should be Atomically */
-    T1 = tmp;
+    T0 = env->tnpc[env->tl];
 }
 
-void OPPROTO op_ldd(void)
+void OPPROTO op_wrtnpc(void)
 {
-    T1 = ldl((void *) T0);
-    T0 = ldl((void *) (T0 + 4));
+    env->tnpc[env->tl] = T0;
 }
 
-void OPPROTO op_wry(void)
+void OPPROTO op_rdtstate(void)
 {
-    env->y = T0;
+    T0 = env->tstate[env->tl];
 }
 
-void OPPROTO op_rdy(void)
+void OPPROTO op_wrtstate(void)
 {
-    T0 = env->y;
+    env->tstate[env->tl] = T0;
 }
 
-void raise_exception(int tt)
+void OPPROTO op_rdtt(void)
 {
-    env->exception_index = tt;
-    cpu_loop_exit();
-}   
+    T0 = env->tt[env->tl];
+}
+
+void OPPROTO op_wrtt(void)
+{
+    env->tt[env->tl] = T0;
+}
 
-void memcpy32(uint32_t *dst, const uint32_t *src)
+void OPPROTO op_rdpstate(void)
 {
-    dst[0] = src[0];
-    dst[1] = src[1];
-    dst[2] = src[2];
-    dst[3] = src[3];
-    dst[4] = src[4];
-    dst[5] = src[5];
-    dst[6] = src[6];
-    dst[7] = src[7];
+    T0 = env->pstate;
 }
 
-static inline void set_cwp(int new_cwp)
+void OPPROTO op_wrpstate(void)
 {
-    /* put the modified wrap registers at their proper location */
-    if (env->cwp == (NWINDOWS - 1))
-        memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
-    env->cwp = new_cwp;
-    /* put the wrap registers at their temporary location */
-    if (new_cwp == (NWINDOWS - 1))
-        memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
-    env->regwptr = env->regbase + (new_cwp * 16);
+    do_wrpstate();
+}
+
+// CWP handling is reversed in V9, but we still use the V8 register
+// order.
+void OPPROTO op_rdcwp(void)
+{
+    T0 = NWINDOWS - 1 - env->cwp;
+}
+
+void OPPROTO op_wrcwp(void)
+{
+    env->cwp = NWINDOWS - 1 - T0;
 }
 
 /* XXX: use another pointer for %iN registers to avoid slow wrapping
    handling ? */
 void OPPROTO op_save(void)
 {
-    int cwp;
+    uint32_t cwp;
     cwp = (env->cwp - 1) & (NWINDOWS - 1); 
-    if (env->wim & (1 << cwp)) {
-        raise_exception(TT_WIN_OVF);
+    if (env->cansave == 0) {
+        raise_exception(TT_SPILL | (env->otherwin != 0 ? 
+                                   (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
+                                   ((env->wstate & 0x7) << 2)));
+    } else {
+       if (env->cleanwin - env->canrestore == 0) {
+           // XXX Clean windows without trap
+           raise_exception(TT_CLRWIN);
+       } else {
+           env->cansave--;
+           env->canrestore++;
+           set_cwp(cwp);
+       }
     }
-    set_cwp(cwp);
     FORCE_RET();
 }
 
 void OPPROTO op_restore(void)
 {
-    int cwp;
+    uint32_t cwp;
     cwp = (env->cwp + 1) & (NWINDOWS - 1); 
-    if (env->wim & (1 << cwp)) {
-        raise_exception(TT_WIN_UNF);
+    if (env->canrestore == 0) {
+        raise_exception(TT_FILL | (env->otherwin != 0 ? 
+                                  (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
+                                  ((env->wstate & 0x7) << 2)));
+    } else {
+       env->cansave++;
+       env->canrestore--;
+       set_cwp(cwp);
     }
-    set_cwp(cwp);
     FORCE_RET();
 }
+#endif
 
 void OPPROTO op_exception(void)
 {
@@ -525,111 +1017,267 @@ void OPPROTO op_trapcc_T0(void)
     FORCE_RET();
 }
 
+void OPPROTO op_fpexception_im(void)
+{
+    env->exception_index = TT_FP_EXCP;
+    env->fsr &= ~FSR_FTT_MASK;
+    env->fsr |= PARAM1;
+    cpu_loop_exit();
+    FORCE_RET();
+}
+
+void OPPROTO op_debug(void)
+{
+    helper_debug();
+}
+
 void OPPROTO op_exit_tb(void)
 {
     EXIT_TB();
 }
 
+void OPPROTO op_eval_ba(void)
+{
+    T2 = 1;
+}
+
 void OPPROTO op_eval_be(void)
 {
-    T2 = (env->psr & PSR_ZERO);
+    T2 = FLAG_SET(PSR_ZERO);
 }
 
 void OPPROTO op_eval_ble(void)
 {
-    unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
+    target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
     
     T2 = Z | (N ^ V);
 }
 
 void OPPROTO op_eval_bl(void)
 {
-    unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
+    target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
 
     T2 = N ^ V;
 }
 
 void OPPROTO op_eval_bleu(void)
 {
-    unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
+    target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
 
     T2 = C | Z;
 }
 
 void OPPROTO op_eval_bcs(void)
 {
-    T2 = (env->psr & PSR_CARRY);
+    T2 = FLAG_SET(PSR_CARRY);
 }
 
 void OPPROTO op_eval_bvs(void)
 {
-    T2 = (env->psr & PSR_OVF);
+    T2 = FLAG_SET(PSR_OVF);
+}
+
+void OPPROTO op_eval_bn(void)
+{
+    T2 = 0;
 }
 
 void OPPROTO op_eval_bneg(void)
 {
-    T2 = (env->psr & PSR_NEG);
+    T2 = FLAG_SET(PSR_NEG);
 }
 
 void OPPROTO op_eval_bne(void)
 {
-    T2 = !(env->psr & PSR_ZERO);
+    T2 = !FLAG_SET(PSR_ZERO);
 }
 
 void OPPROTO op_eval_bg(void)
 {
-    unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
+    target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
 
     T2 = !(Z | (N ^ V));
 }
 
 void OPPROTO op_eval_bge(void)
 {
-    unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
+    target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
 
     T2 = !(N ^ V);
 }
 
 void OPPROTO op_eval_bgu(void)
 {
-    unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
+    target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
 
     T2 = !(C | Z);
 }
 
 void OPPROTO op_eval_bcc(void)
 {
-    T2 = !(env->psr & PSR_CARRY);
+    T2 = !FLAG_SET(PSR_CARRY);
 }
 
 void OPPROTO op_eval_bpos(void)
 {
-    T2 = !(env->psr & PSR_NEG);
+    T2 = !FLAG_SET(PSR_NEG);
 }
 
 void OPPROTO op_eval_bvc(void)
 {
-    T2 = !(env->psr & PSR_OVF);
+    T2 = !FLAG_SET(PSR_OVF);
 }
 
-void OPPROTO op_movl_T2_0(void)
+#ifdef TARGET_SPARC64
+void OPPROTO op_eval_xbe(void)
 {
-    T2 = 0;
+    T2 = XFLAG_SET(PSR_ZERO);
 }
 
-void OPPROTO op_movl_T2_1(void)
+void OPPROTO op_eval_xble(void)
 {
-    T2 = 1;
+    target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
+    
+    T2 = Z | (N ^ V);
+}
+
+void OPPROTO op_eval_xbl(void)
+{
+    target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
+
+    T2 = N ^ V;
+}
+
+void OPPROTO op_eval_xbleu(void)
+{
+    target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
+
+    T2 = C | Z;
+}
+
+void OPPROTO op_eval_xbcs(void)
+{
+    T2 = XFLAG_SET(PSR_CARRY);
+}
+
+void OPPROTO op_eval_xbvs(void)
+{
+    T2 = XFLAG_SET(PSR_OVF);
 }
 
+void OPPROTO op_eval_xbneg(void)
+{
+    T2 = XFLAG_SET(PSR_NEG);
+}
+
+void OPPROTO op_eval_xbne(void)
+{
+    T2 = !XFLAG_SET(PSR_ZERO);
+}
+
+void OPPROTO op_eval_xbg(void)
+{
+    target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
+
+    T2 = !(Z | (N ^ V));
+}
+
+void OPPROTO op_eval_xbge(void)
+{
+    target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
+
+    T2 = !(N ^ V);
+}
+
+void OPPROTO op_eval_xbgu(void)
+{
+    target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
+
+    T2 = !(C | Z);
+}
+
+void OPPROTO op_eval_xbcc(void)
+{
+    T2 = !XFLAG_SET(PSR_CARRY);
+}
+
+void OPPROTO op_eval_xbpos(void)
+{
+    T2 = !XFLAG_SET(PSR_NEG);
+}
+
+void OPPROTO op_eval_xbvc(void)
+{
+    T2 = !XFLAG_SET(PSR_OVF);
+}
+#endif
+
+#define FCC
+#define FFLAG_SET(x) (env->fsr & x? 1: 0)
+#include "fbranch_template.h"
+
+#ifdef TARGET_SPARC64
+#define FCC _fcc1
+#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
+#include "fbranch_template.h"
+#define FCC _fcc2
+#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
+#include "fbranch_template.h"
+#define FCC _fcc3
+#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
+#include "fbranch_template.h"
+#endif
+
+#ifdef TARGET_SPARC64
+void OPPROTO op_eval_brz(void)
+{
+    T2 = (T0 == 0);
+}
+
+void OPPROTO op_eval_brnz(void)
+{
+    T2 = (T0 != 0);
+}
+
+void OPPROTO op_eval_brlz(void)
+{
+    T2 = ((int64_t)T0 < 0);
+}
+
+void OPPROTO op_eval_brlez(void)
+{
+    T2 = ((int64_t)T0 <= 0);
+}
+
+void OPPROTO op_eval_brgz(void)
+{
+    T2 = ((int64_t)T0 > 0);
+}
+
+void OPPROTO op_eval_brgez(void)
+{
+    T2 = ((int64_t)T0 >= 0);
+}
+
+void OPPROTO op_jmp_im64(void)
+{
+    env->pc = PARAMQ1;
+}
+
+void OPPROTO op_movq_npc_im64(void)
+{
+    env->npc = PARAMQ1;
+}
+#endif
+
 void OPPROTO op_jmp_im(void)
 {
-    env->pc = PARAM1;
+    env->pc = (uint32_t)PARAM1;
 }
 
 void OPPROTO op_movl_npc_im(void)
 {
-    env->npc = PARAM1;
+    env->npc = (uint32_t)PARAM1;
 }
 
 void OPPROTO op_movl_npc_T0(void)
@@ -637,30 +1285,313 @@ void OPPROTO op_movl_npc_T0(void)
     env->npc = T0;
 }
 
+void OPPROTO op_mov_pc_npc(void)
+{
+    env->pc = env->npc;
+}
+
 void OPPROTO op_next_insn(void)
 {
     env->pc = env->npc;
     env->npc = env->npc + 4;
 }
 
-void OPPROTO op_generic_branch(void)
+void OPPROTO op_goto_tb0(void)
 {
-    if (T2) {
-       env->npc = PARAM1;
-    } else {
-       env->npc = PARAM2;
-    }
+    GOTO_TB(op_goto_tb0, PARAM1, 0);
+}
+
+void OPPROTO op_goto_tb1(void)
+{
+    GOTO_TB(op_goto_tb1, PARAM1, 1);
+}
+
+void OPPROTO op_jmp_label(void)
+{
+    GOTO_LABEL_PARAM(1);
+}
+
+void OPPROTO op_jnz_T2_label(void)
+{
+    if (T2)
+        GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
 
-void OPPROTO op_generic_branch_a(void)
+void OPPROTO op_jz_T2_label(void)
 {
-    if (T2) {
-       env->pc = PARAM2;
-       env->npc = PARAM1;
-    } else {
-       env->pc = PARAM2 + 4;
-       env->npc = PARAM2 + 8;
+    if (!T2)
+        GOTO_LABEL_PARAM(1);
+    FORCE_RET();
+}
+
+void OPPROTO op_flush_T0(void)
+{
+    helper_flush(T0);
+}
+
+#define F_OP(name, p) void OPPROTO op_f##name##p(void)
+
+#define F_BINOP(name)                                           \
+    F_OP(name, s)                                               \
+    {                                                           \
+        FT0 = float32_ ## name (FT0, FT1, &env->fp_status);     \
+    }                                                           \
+    F_OP(name, d)                                               \
+    {                                                           \
+        DT0 = float64_ ## name (DT0, DT1, &env->fp_status);     \
     }
+
+F_BINOP(add);
+F_BINOP(sub);
+F_BINOP(mul);
+F_BINOP(div);
+#undef F_BINOP
+
+void OPPROTO op_fsmuld(void)
+{
+    DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status),
+                      float32_to_float64(FT1, &env->fp_status),
+                      &env->fp_status);
+}
+
+#define F_HELPER(name)    \
+    F_OP(name, s)         \
+    {                     \
+        do_f##name##s();  \
+    }                     \
+    F_OP(name, d)         \
+    {                     \
+        do_f##name##d();  \
+    }
+
+F_HELPER(sqrt);
+
+F_OP(neg, s)
+{
+    FT0 = float32_chs(FT1);
+}
+
+F_OP(abs, s)
+{
+    do_fabss();
+}
+
+F_HELPER(cmp);
+
+#ifdef TARGET_SPARC64
+F_OP(neg, d)
+{
+    DT0 = float64_chs(DT1);
+}
+
+F_OP(abs, d)
+{
+    do_fabsd();
+}
+
+void OPPROTO op_fcmps_fcc1(void)
+{
+    do_fcmps_fcc1();
+}
+
+void OPPROTO op_fcmpd_fcc1(void)
+{
+    do_fcmpd_fcc1();
+}
+
+void OPPROTO op_fcmps_fcc2(void)
+{
+    do_fcmps_fcc2();
+}
+
+void OPPROTO op_fcmpd_fcc2(void)
+{
+    do_fcmpd_fcc2();
+}
+
+void OPPROTO op_fcmps_fcc3(void)
+{
+    do_fcmps_fcc3();
+}
+
+void OPPROTO op_fcmpd_fcc3(void)
+{
+    do_fcmpd_fcc3();
+}
+#endif
+
+/* Integer to float conversion.  */
+#ifdef USE_INT_TO_FLOAT_HELPERS
+F_HELPER(ito);
+#else
+F_OP(ito, s)
+{
+    FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
+}
+
+F_OP(ito, d)
+{
+    DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
+}
+
+#ifdef TARGET_SPARC64
+F_OP(xto, s)
+{
+    FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
+}
+
+F_OP(xto, d)
+{
+    DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
+}
+#endif
+#endif
+#undef F_HELPER
+
+/* floating point conversion */
+void OPPROTO op_fdtos(void)
+{
+    FT0 = float64_to_float32(DT1, &env->fp_status);
+}
+
+void OPPROTO op_fstod(void)
+{
+    DT0 = float32_to_float64(FT1, &env->fp_status);
+}
+
+/* Float to integer conversion.  */
+void OPPROTO op_fstoi(void)
+{
+    *((int32_t *)&FT0) = float32_to_int32(FT1, &env->fp_status);
+}
+
+void OPPROTO op_fdtoi(void)
+{
+    *((int32_t *)&FT0) = float64_to_int32(DT1, &env->fp_status);
+}
+
+#ifdef TARGET_SPARC64
+void OPPROTO op_fstox(void)
+{
+    *((int64_t *)&DT0) = float32_to_int64(FT1, &env->fp_status);
+}
+
+void OPPROTO op_fdtox(void)
+{
+    *((int64_t *)&DT0) = float64_to_int64(DT1, &env->fp_status);
+}
+
+void OPPROTO op_fmovs_cc(void)
+{
+    if (T2)
+       FT0 = FT1;
+}
+
+void OPPROTO op_fmovd_cc(void)
+{
+    if (T2)
+       DT0 = DT1;
+}
+
+void OPPROTO op_mov_cc(void)
+{
+    if (T2)
+       T0 = T1;
+}
+
+void OPPROTO op_flushw(void)
+{
+    if (env->cansave != NWINDOWS - 2) {
+        raise_exception(TT_SPILL | (env->otherwin != 0 ? 
+                                   (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
+                                   ((env->wstate & 0x7) << 2)));
+    }
+}
+
+void OPPROTO op_saved(void)
+{
+    env->cansave++;
+    if (env->otherwin == 0)
+       env->canrestore--;
+    else
+       env->otherwin--;
     FORCE_RET();
 }
+
+void OPPROTO op_restored(void)
+{
+    env->canrestore++;
+    if (env->cleanwin < NWINDOWS - 1)
+       env->cleanwin++;
+    if (env->otherwin == 0)
+       env->cansave--;
+    else
+       env->otherwin--;
+    FORCE_RET();
+}
+
+void OPPROTO op_popc(void)
+{
+    do_popc();
+}
+
+void OPPROTO op_done(void)
+{
+    do_done();
+}
+
+void OPPROTO op_retry(void)
+{
+    do_retry();
+}
+
+void OPPROTO op_sir(void)
+{
+    // XXX
+
+}
+
+void OPPROTO op_ld_asi_reg()
+{
+    T0 += PARAM1;
+    helper_ld_asi(env->asi, PARAM2, PARAM3);
+}
+
+void OPPROTO op_st_asi_reg()
+{
+    T0 += PARAM1;
+    helper_st_asi(env->asi, PARAM2, PARAM3);
+}
+#endif
+
+void OPPROTO op_ld_asi()
+{
+    helper_ld_asi(PARAM1, PARAM2, PARAM3);
+}
+
+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