Index: qemu/target-sparc/op_helper.c =================================================================== --- qemu.orig/target-sparc/op_helper.c 2007-10-15 16:47:11.000000000 +0000 +++ qemu/target-sparc/op_helper.c 2007-10-15 17:34:28.000000000 +0000 @@ -649,8 +649,6 @@ switch (asi) { case 0x80: // Primary case 0x82: // Primary no-fault - case 0x88: // Primary LE - case 0x8a: // Primary no-fault LE { switch(size) { case 1: @@ -669,6 +667,26 @@ } } break; + case 0x88: // Primary LE + case 0x8a: // Primary no-fault LE + { + switch(size) { + case 1: + ret = ldub_raw(T0); + break; + case 2: + ret = lduwr_raw(T0 & ~1); + break; + case 4: + ret = ldulr_raw(T0 & ~3); + break; + default: + case 8: + ret = ldqr_raw(T0 & ~7); + break; + } + } + break; case 0x81: // Secondary case 0x83: // Secondary no-fault case 0x89: // Secondary LE @@ -679,29 +697,6 @@ break; } - /* Convert from little endian */ - switch (asi) { - case 0x88: // Primary LE - case 0x89: // Secondary LE - case 0x8a: // Primary no-fault LE - case 0x8b: // Secondary no-fault LE - switch(size) { - case 2: - ret = bswap16(ret); - break; - case 4: - ret = bswap32(ret); - break; - case 8: - ret = bswap64(ret); - break; - default: - break; - } - default: - break; - } - /* Convert to signed number */ if (sign) { switch(size) { @@ -726,30 +721,8 @@ if (asi < 0x80) raise_exception(TT_PRIV_ACT); - /* Convert to little endian */ - switch (asi) { - case 0x88: // Primary LE - case 0x89: // Secondary LE - switch(size) { - case 2: - T0 = bswap16(T0); - break; - case 4: - T0 = bswap32(T0); - break; - case 8: - T0 = bswap64(T0); - break; - default: - break; - } - default: - break; - } - switch(asi) { case 0x80: // Primary - case 0x88: // Primary LE { switch(size) { case 1: @@ -768,6 +741,25 @@ } } break; + case 0x88: // Primary LE + { + switch(size) { + case 1: + stb_raw(T0, T1); + break; + case 2: + stwr_raw(T0 & ~1, T1); + break; + case 4: + stlr_raw(T0 & ~3, T1); + break; + case 8: + default: + stqr_raw(T0 & ~7, T1); + break; + } + } + break; case 0x81: // Secondary case 0x89: // Secondary LE // XXX @@ -795,11 +787,8 @@ switch (asi) { case 0x10: // As if user primary - case 0x18: // As if user primary LE case 0x80: // Primary case 0x82: // Primary no-fault - case 0x88: // Primary LE - case 0x8a: // Primary no-fault LE if ((asi & 0x80) && (env->pstate & PS_PRIV)) { if (env->hpstate & HS_PRIV) { switch(size) { @@ -852,10 +841,63 @@ } } break; + case 0x18: // As if user primary LE + case 0x88: // Primary LE + case 0x8a: // Primary no-fault LE + if ((asi & 0x80) && (env->pstate & PS_PRIV)) { + if (env->hpstate & HS_PRIV) { + switch(size) { + case 1: + ret = ldub_hypv(T0); + break; + case 2: + ret = lduwr_hypv(T0 & ~1); + break; + case 4: + ret = ldulr_hypv(T0 & ~3); + break; + default: + case 8: + ret = ldqr_hypv(T0 & ~7); + break; + } + } else { + switch(size) { + case 1: + ret = ldub_kernel(T0); + break; + case 2: + ret = lduwr_kernel(T0 & ~1); + break; + case 4: + ret = ldulr_kernel(T0 & ~3); + break; + default: + case 8: + ret = ldqr_kernel(T0 & ~7); + break; + } + } + } else { + switch(size) { + case 1: + ret = ldub_user(T0); + break; + case 2: + ret = lduwr_user(T0 & ~1); + break; + case 4: + ret = ldulr_user(T0 & ~3); + break; + default: + case 8: + ret = ldqr_user(T0 & ~7); + break; + } + } + break; case 0x14: // Bypass case 0x15: // Bypass, non-cacheable - case 0x1c: // Bypass LE - case 0x1d: // Bypass, non-cacheable LE { switch(size) { case 1: @@ -874,6 +916,26 @@ } break; } + case 0x1c: // Bypass LE + case 0x1d: // Bypass, non-cacheable LE + { + switch(size) { + case 1: + ret = ldub_phys(T0); + break; + case 2: + ret = bswap16(lduw_phys(T0 & ~1)); + break; + case 4: + ret = bswap32(ldul_phys(T0 & ~3)); + break; + default: + case 8: + ret = bswap64(ldq_phys(T0 & ~7)); + break; + } + break; + } case 0x04: // Nucleus case 0x0c: // Nucleus Little Endian (LE) case 0x11: // As if user secondary @@ -957,34 +1019,6 @@ break; } - /* Convert from little endian */ - switch (asi) { - case 0x0c: // Nucleus Little Endian (LE) - case 0x18: // As if user primary LE - case 0x19: // As if user secondary LE - case 0x1c: // Bypass LE - case 0x1d: // Bypass, non-cacheable LE - case 0x88: // Primary LE - case 0x89: // Secondary LE - case 0x8a: // Primary no-fault LE - case 0x8b: // Secondary no-fault LE - switch(size) { - case 2: - ret = bswap16(ret); - break; - case 4: - ret = bswap32(ret); - break; - case 8: - ret = bswap64(ret); - break; - default: - break; - } - default: - break; - } - /* Convert to signed number */ if (sign) { switch(size) { @@ -1010,37 +1044,9 @@ || (asi >= 0x30 && asi < 0x80) && !(env->hpstate & HS_PRIV)) raise_exception(TT_PRIV_ACT); - /* Convert to little endian */ - switch (asi) { - case 0x0c: // Nucleus Little Endian (LE) - case 0x18: // As if user primary LE - case 0x19: // As if user secondary LE - case 0x1c: // Bypass LE - case 0x1d: // Bypass, non-cacheable LE - case 0x88: // Primary LE - case 0x89: // Secondary LE - switch(size) { - case 2: - T0 = bswap16(T0); - break; - case 4: - T0 = bswap32(T0); - break; - case 8: - T0 = bswap64(T0); - break; - default: - break; - } - default: - break; - } - switch(asi) { case 0x10: // As if user primary - case 0x18: // As if user primary LE case 0x80: // Primary - case 0x88: // Primary LE if ((asi & 0x80) && (env->pstate & PS_PRIV)) { if (env->hpstate & HS_PRIV) { switch(size) { @@ -1093,10 +1099,62 @@ } } break; + case 0x18: // As if user primary LE + case 0x88: // Primary LE + if ((asi & 0x80) && (env->pstate & PS_PRIV)) { + if (env->hpstate & HS_PRIV) { + switch(size) { + case 1: + stb_hypv(T0, T1); + break; + case 2: + stwr_hypv(T0 & ~1, T1); + break; + case 4: + stlr_hypv(T0 & ~3, T1); + break; + case 8: + default: + stqr_hypv(T0 & ~7, T1); + break; + } + } else { + switch(size) { + case 1: + stb_kernel(T0, T1); + break; + case 2: + stwr_kernel(T0 & ~1, T1); + break; + case 4: + stlr_kernel(T0 & ~3, T1); + break; + case 8: + default: + stqr_kernel(T0 & ~7, T1); + break; + } + } + } else { + switch(size) { + case 1: + stb_user(T0, T1); + break; + case 2: + stwr_user(T0 & ~1, T1); + break; + case 4: + stlr_user(T0 & ~3, T1); + break; + case 8: + default: + stqr_user(T0 & ~7, T1); + break; + } + } + break; case 0x14: // Bypass case 0x15: // Bypass, non-cacheable - case 0x1c: // Bypass LE - case 0x1d: // Bypass, non-cacheable LE { switch(size) { case 1: @@ -1115,6 +1173,26 @@ } } return; + case 0x1c: // Bypass LE + case 0x1d: // Bypass, non-cacheable LE + { + switch(size) { + case 1: + stb_phys(T0, T1); + break; + case 2: + stw_phys(T0 & ~1, bswap16(T1)); + break; + case 4: + stl_phys(T0 & ~3, bswap32(T1)); + break; + case 8: + default: + stq_phys(T0 & ~7, bswap64(T1)); + break; + } + } + return; case 0x04: // Nucleus case 0x0c: // Nucleus Little Endian (LE) case 0x11: // As if user secondary Index: qemu/target-sparc/op_mem.h =================================================================== --- qemu.orig/target-sparc/op_mem.h 2007-10-15 16:47:11.000000000 +0000 +++ qemu/target-sparc/op_mem.h 2007-10-15 17:00:16.000000000 +0000 @@ -82,16 +82,8 @@ } #ifdef TARGET_SPARC64 -void OPPROTO glue(op_lduw, MEMSUFFIX)(void) -{ - T1 = (uint64_t)(glue(ldul, MEMSUFFIX)(ADDR(T0)) & 0xffffffff); -} - -void OPPROTO glue(op_ldsw, MEMSUFFIX)(void) -{ - T1 = (int64_t)(glue(ldul, MEMSUFFIX)(ADDR(T0)) & 0xffffffff); -} - +SPARC_LD_OP(lduw, ldul); +SPARC_LD_OP(ldsw, ldsl); SPARC_LD_OP(ldx, ldq); SPARC_ST_OP(stx, stq); #endif Index: qemu/cpu-all.h =================================================================== --- qemu.orig/cpu-all.h 2007-10-15 17:10:15.000000000 +0000 +++ qemu/cpu-all.h 2007-10-15 17:27:47.000000000 +0000 @@ -1128,6 +1128,118 @@ #define stfq_le_kernel(p, vt) stfq_kernel(p, vt) #endif +/* native-endian */ +#define ldub_hypv(p) ldub_raw(p) +#define ldsb_hypv(p) ldsb_raw(p) +#define lduw_hypv(p) lduw_raw(p) +#define ldsw_hypv(p) ldsw_raw(p) +#define ldul_hypv(p) ldul_raw(p) +#if (TARGET_LONG_BITS == 64) +#define ldsl_hypv(p) ldsl_raw(p) +#endif +#define ldq_hypv(p) ldq_raw(p) +#define ldfl_hypv(p) ldfl_raw(p) +#define ldfq_hypv(p) ldfq_raw(p) +#define stb_hypv(p, v) stb_raw(p, v) +#define stw_hypv(p, v) stw_raw(p, v) +#define stl_hypv(p, v) stl_raw(p, v) +#define stq_hypv(p, v) stq_raw(p, v) +#define stfl_hypv(p, v) stfl_raw(p, v) +#define stfq_hypv(p, vt) stfq_raw(p, v) +/* reverse-endian */ +#define ldubr_hypv(p) ldub_raw(p) +#define ldsbr_hypv(p) ldsb_raw(p) +#define lduwr_hypv(p) lduwr_raw(p) +#define ldswr_hypv(p) ldswr_raw(p) +#define ldulr_hypv(p) ldulr_raw(p) +#if (TARGET_LONG_BITS == 64) +#define ldslr_hypv(p) ldslr_raw(p) +#endif +#define ldqr_hypv(p) ldqr_raw(p) +#define ldflr_hypv(p) ldflr_raw(p) +#define ldfqr_hypv(p) ldfqr_raw(p) +#define stbr_hypv(p, v) stbr_raw(p, v) +#define stwr_hypv(p, v) stwr_raw(p, v) +#define stlr_hypv(p, v) stlr_raw(p, v) +#define stqr_hypv(p, v) stqr_raw(p, v) +#define stflr_hypv(p, v) stflr_raw(p, v) +#define stfqr_hypv(p, vt) stfqr_raw(p, v) +#if defined(TARGET_WORDS_BIGENDIAN) +/* big-endian */ +#define ldub_be_hypv(p) ldub_hypv(p) +#define ldsb_be_hypv(p) ldsb_hypv(p) +#define lduw_be_hypv(p) lduw_hypv(p) +#define ldsw_be_hypv(p) ldsw_hypv(p) +#define ldul_be_hypv(p) ldul_hypv(p) +#if (TARGET_LONG_BITS == 64) +#define ldsl_be_hypv(p) ldsl_hypv(p) +#endif +#define ldq_be_hypv(p) ldq_hypv(p) +#define ldfl_be_hypv(p) ldfl_hypv(p) +#define ldfq_be_hypv(p) ldfq_hypv(p) +#define stb_be_hypv(p, v) stb_hypv(p, v) +#define stw_be_hypv(p, v) stw_hypv(p, v) +#define stl_be_hypv(p, v) stl_hypv(p, v) +#define stq_be_hypv(p, v) stq_hypv(p, v) +#define stfl_be_hypv(p, v) stfl_hypv(p, v) +#define stfq_be_hypv(p, vt) stfq_hypv(p, vt) +/* little-endian */ +#define ldub_le_hypv(p) ldubr_hypv(p) +#define ldsb_le_hypv(p) ldsbr_hypv(p) +#define lduw_le_hypv(p) lduwr_hypv(p) +#define ldsw_le_hypv(p) ldswr_hypv(p) +#define ldul_le_hypv(p) ldulr_hypv(p) +#if (TARGET_LONG_BITS == 64) +#define ldsl_le_hypv(p) ldslr_hypv(p) +#endif +#define ldq_le_hypv(p) ldqr_hypv(p) +#define ldfl_le_hypv(p) ldflr_hypv(p) +#define ldfq_le_hypv(p) ldfqr_hypv(p) +#define stb_le_hypv(p, v) stbr_hypv(p, v) +#define stw_le_hypv(p, v) stwr_hypv(p, v) +#define stl_le_hypv(p, v) stlr_hypv(p, v) +#define stq_le_hypv(p, v) stqr_hypv(p, v) +#define stfl_le_hypv(p, v) stflr_hypv(p, v) +#define stfq_le_hypv(p, vt) stfqr_hypv(p, vt) +#else +/* big-endian */ +#define ldub_be_hypv(p) ldubr_hypv(p) +#define ldsb_be_hypv(p) ldsbr_hypv(p) +#define lduw_be_hypv(p) lduwr_hypv(p) +#define ldsw_be_hypv(p) ldswr_hypv(p) +#define ldul_be_hypv(p) ldulr_hypv(p) +#if (TARGET_LONG_BITS == 64) +#define ldsl_be_hypv(p) ldslr_hypv(p) +#endif +#define ldq_be_hypv(p) ldqr_hypv(p) +#define ldfl_be_hypv(p) ldflr_hypv(p) +#define ldfq_be_hypv(p) ldfqr_hypv(p) +#define stb_be_hypv(p, v) stbr_hypv(p, v) +#define stw_be_hypv(p, v) stwr_hypv(p, v) +#define stl_be_hypv(p, v) stlr_hypv(p, v) +#define stq_be_hypv(p, v) stqr_hypv(p, v) +#define stfl_be_hypv(p, v) stflr_hypv(p, v) +#define stfq_be_hypv(p, vt) stfqr_hypv(p, vt) +/* little-endian */ +#define ldub_le_hypv(p) ldub_hypv(p) +#define ldsb_le_hypv(p) ldsb_hypv(p) +#define lduw_le_hypv(p) lduw_hypv(p) +#define ldsw_le_hypv(p) ldsw_hypv(p) +#define ldul_le_hypv(p) ldul_hypv(p) +#if (TARGET_LONG_BITS == 64) +#define ldsl_le_hypv(p) ldsl_hypv(p) +#endif +#define ldq_le_hypv(p) ldq_hypv(p) +#define ldfl_le_hypv(p) ldfl_hypv(p) +#define ldfq_le_hypv(p) ldfq_hypv(p) +#define stb_le_hypv(p, v) stb_hypv(p, v) +#define stw_le_hypv(p, v) stw_hypv(p, v) +#define stl_le_hypv(p, v) stl_hypv(p, v) +#define stq_le_hypv(p, v) stq_hypv(p, v) +#define stfl_le_hypv(p, v) stfl_hypv(p, v) +#define stfq_le_hypv(p, vt) stfq_hypv(p, vt) +#endif + #endif /* defined(CONFIG_USER_ONLY) */ /* page related stuff */