Commit c2bc0e388016a8a2a47c35334f1c11c85901bedc
1 parent
48318011
Remove someexplicit alignment checks (initial patch by Fabrice Bellard)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4431 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
112 additions
and
98 deletions
target-sparc/op_helper.c
| @@ -33,6 +33,12 @@ do { printf("ASI: " fmt , ##args); } while (0) | @@ -33,6 +33,12 @@ do { printf("ASI: " fmt , ##args); } while (0) | ||
| 33 | #define DPRINTF_ASI(fmt, args...) do {} while (0) | 33 | #define DPRINTF_ASI(fmt, args...) do {} while (0) |
| 34 | #endif | 34 | #endif |
| 35 | 35 | ||
| 36 | +#ifdef TARGET_ABI32 | ||
| 37 | +#define ABI32_MASK(addr) do { (addr) &= 0xffffffffULL; } while (0) | ||
| 38 | +#else | ||
| 39 | +#define ABI32_MASK(addr) do {} while (0) | ||
| 40 | +#endif | ||
| 41 | + | ||
| 36 | void raise_exception(int tt) | 42 | void raise_exception(int tt) |
| 37 | { | 43 | { |
| 38 | env->exception_index = tt; | 44 | env->exception_index = tt; |
| @@ -55,8 +61,13 @@ void helper_trapcc(target_ulong nb_trap, target_ulong do_trap) | @@ -55,8 +61,13 @@ void helper_trapcc(target_ulong nb_trap, target_ulong do_trap) | ||
| 55 | 61 | ||
| 56 | void helper_check_align(target_ulong addr, uint32_t align) | 62 | void helper_check_align(target_ulong addr, uint32_t align) |
| 57 | { | 63 | { |
| 58 | - if (addr & align) | 64 | + if (addr & align) { |
| 65 | +#ifdef DEBUG_UNALIGNED | ||
| 66 | + printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx | ||
| 67 | + "\n", addr, env->pc); | ||
| 68 | +#endif | ||
| 59 | raise_exception(TT_UNALIGNED); | 69 | raise_exception(TT_UNALIGNED); |
| 70 | + } | ||
| 60 | } | 71 | } |
| 61 | 72 | ||
| 62 | #define F_HELPER(name, p) void helper_f##name##p(void) | 73 | #define F_HELPER(name, p) void helper_f##name##p(void) |
| @@ -832,6 +843,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | @@ -832,6 +843,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | ||
| 832 | uint32_t last_addr = addr; | 843 | uint32_t last_addr = addr; |
| 833 | #endif | 844 | #endif |
| 834 | 845 | ||
| 846 | + helper_check_align(addr, size - 1); | ||
| 835 | switch (asi) { | 847 | switch (asi) { |
| 836 | case 2: /* SuperSparc MXCC registers */ | 848 | case 2: /* SuperSparc MXCC registers */ |
| 837 | switch (addr) { | 849 | switch (addr) { |
| @@ -1030,6 +1042,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | @@ -1030,6 +1042,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | ||
| 1030 | 1042 | ||
| 1031 | void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size) | 1043 | void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size) |
| 1032 | { | 1044 | { |
| 1045 | + helper_check_align(addr, size - 1); | ||
| 1033 | switch(asi) { | 1046 | switch(asi) { |
| 1034 | case 2: /* SuperSparc MXCC registers */ | 1047 | case 2: /* SuperSparc MXCC registers */ |
| 1035 | switch (addr) { | 1048 | switch (addr) { |
| @@ -1335,6 +1348,9 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | @@ -1335,6 +1348,9 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | ||
| 1335 | if (asi < 0x80) | 1348 | if (asi < 0x80) |
| 1336 | raise_exception(TT_PRIV_ACT); | 1349 | raise_exception(TT_PRIV_ACT); |
| 1337 | 1350 | ||
| 1351 | + helper_check_align(addr, size - 1); | ||
| 1352 | + ABI32_MASK(addr); | ||
| 1353 | + | ||
| 1338 | switch (asi) { | 1354 | switch (asi) { |
| 1339 | case 0x80: // Primary | 1355 | case 0x80: // Primary |
| 1340 | case 0x82: // Primary no-fault | 1356 | case 0x82: // Primary no-fault |
| @@ -1421,6 +1437,9 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) | @@ -1421,6 +1437,9 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) | ||
| 1421 | if (asi < 0x80) | 1437 | if (asi < 0x80) |
| 1422 | raise_exception(TT_PRIV_ACT); | 1438 | raise_exception(TT_PRIV_ACT); |
| 1423 | 1439 | ||
| 1440 | + helper_check_align(addr, size - 1); | ||
| 1441 | + ABI32_MASK(addr); | ||
| 1442 | + | ||
| 1424 | /* Convert to little endian */ | 1443 | /* Convert to little endian */ |
| 1425 | switch (asi) { | 1444 | switch (asi) { |
| 1426 | case 0x88: // Primary LE | 1445 | case 0x88: // Primary LE |
| @@ -1491,6 +1510,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | @@ -1491,6 +1510,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) | ||
| 1491 | || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) | 1510 | || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) |
| 1492 | raise_exception(TT_PRIV_ACT); | 1511 | raise_exception(TT_PRIV_ACT); |
| 1493 | 1512 | ||
| 1513 | + helper_check_align(addr, size - 1); | ||
| 1494 | switch (asi) { | 1514 | switch (asi) { |
| 1495 | case 0x10: // As if user primary | 1515 | case 0x10: // As if user primary |
| 1496 | case 0x18: // As if user primary LE | 1516 | case 0x18: // As if user primary LE |
| @@ -1714,6 +1734,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) | @@ -1714,6 +1734,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) | ||
| 1714 | || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) | 1734 | || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) |
| 1715 | raise_exception(TT_PRIV_ACT); | 1735 | raise_exception(TT_PRIV_ACT); |
| 1716 | 1736 | ||
| 1737 | + helper_check_align(addr, size - 1); | ||
| 1717 | /* Convert to little endian */ | 1738 | /* Convert to little endian */ |
| 1718 | switch (asi) { | 1739 | switch (asi) { |
| 1719 | case 0x0c: // Nucleus Little Endian (LE) | 1740 | case 0x0c: // Nucleus Little Endian (LE) |
| @@ -2009,6 +2030,7 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) | @@ -2009,6 +2030,7 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) | ||
| 2009 | unsigned int i; | 2030 | unsigned int i; |
| 2010 | target_ulong val; | 2031 | target_ulong val; |
| 2011 | 2032 | ||
| 2033 | + helper_check_align(addr, 3); | ||
| 2012 | switch (asi) { | 2034 | switch (asi) { |
| 2013 | case 0xf0: // Block load primary | 2035 | case 0xf0: // Block load primary |
| 2014 | case 0xf1: // Block load secondary | 2036 | case 0xf1: // Block load secondary |
| @@ -2018,10 +2040,7 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) | @@ -2018,10 +2040,7 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) | ||
| 2018 | raise_exception(TT_ILL_INSN); | 2040 | raise_exception(TT_ILL_INSN); |
| 2019 | return; | 2041 | return; |
| 2020 | } | 2042 | } |
| 2021 | - if (addr & 0x3f) { | ||
| 2022 | - raise_exception(TT_UNALIGNED); | ||
| 2023 | - return; | ||
| 2024 | - } | 2043 | + helper_check_align(addr, 0x3f); |
| 2025 | for (i = 0; i < 16; i++) { | 2044 | for (i = 0; i < 16; i++) { |
| 2026 | *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x8f, 4, 0); | 2045 | *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x8f, 4, 0); |
| 2027 | addr += 4; | 2046 | addr += 4; |
| @@ -2052,6 +2071,7 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd) | @@ -2052,6 +2071,7 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd) | ||
| 2052 | unsigned int i; | 2071 | unsigned int i; |
| 2053 | target_ulong val = 0; | 2072 | target_ulong val = 0; |
| 2054 | 2073 | ||
| 2074 | + helper_check_align(addr, 3); | ||
| 2055 | switch (asi) { | 2075 | switch (asi) { |
| 2056 | case 0xf0: // Block store primary | 2076 | case 0xf0: // Block store primary |
| 2057 | case 0xf1: // Block store secondary | 2077 | case 0xf1: // Block store secondary |
| @@ -2061,10 +2081,7 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd) | @@ -2061,10 +2081,7 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd) | ||
| 2061 | raise_exception(TT_ILL_INSN); | 2081 | raise_exception(TT_ILL_INSN); |
| 2062 | return; | 2082 | return; |
| 2063 | } | 2083 | } |
| 2064 | - if (addr & 0x3f) { | ||
| 2065 | - raise_exception(TT_UNALIGNED); | ||
| 2066 | - return; | ||
| 2067 | - } | 2084 | + helper_check_align(addr, 0x3f); |
| 2068 | for (i = 0; i < 16; i++) { | 2085 | for (i = 0; i < 16; i++) { |
| 2069 | val = *(uint32_t *)&env->fpr[rd++]; | 2086 | val = *(uint32_t *)&env->fpr[rd++]; |
| 2070 | helper_st_asi(addr, val, asi & 0x8f, 4); | 2087 | helper_st_asi(addr, val, asi & 0x8f, 4); |
| @@ -2183,55 +2200,53 @@ uint64_t helper_pack64(target_ulong high, target_ulong low) | @@ -2183,55 +2200,53 @@ uint64_t helper_pack64(target_ulong high, target_ulong low) | ||
| 2183 | return ((uint64_t)high << 32) | (uint64_t)(low & 0xffffffff); | 2200 | return ((uint64_t)high << 32) | (uint64_t)(low & 0xffffffff); |
| 2184 | } | 2201 | } |
| 2185 | 2202 | ||
| 2186 | -#ifdef TARGET_ABI32 | ||
| 2187 | -#define ADDR(x) ((x) & 0xffffffff) | ||
| 2188 | -#else | ||
| 2189 | -#define ADDR(x) (x) | ||
| 2190 | -#endif | ||
| 2191 | - | ||
| 2192 | void helper_stdf(target_ulong addr, int mem_idx) | 2203 | void helper_stdf(target_ulong addr, int mem_idx) |
| 2193 | { | 2204 | { |
| 2205 | + helper_check_align(addr, 7); | ||
| 2194 | #if !defined(CONFIG_USER_ONLY) | 2206 | #if !defined(CONFIG_USER_ONLY) |
| 2195 | switch (mem_idx) { | 2207 | switch (mem_idx) { |
| 2196 | case 0: | 2208 | case 0: |
| 2197 | - stfq_user(ADDR(addr), DT0); | 2209 | + stfq_user(addr, DT0); |
| 2198 | break; | 2210 | break; |
| 2199 | case 1: | 2211 | case 1: |
| 2200 | - stfq_kernel(ADDR(addr), DT0); | 2212 | + stfq_kernel(addr, DT0); |
| 2201 | break; | 2213 | break; |
| 2202 | #ifdef TARGET_SPARC64 | 2214 | #ifdef TARGET_SPARC64 |
| 2203 | case 2: | 2215 | case 2: |
| 2204 | - stfq_hypv(ADDR(addr), DT0); | 2216 | + stfq_hypv(addr, DT0); |
| 2205 | break; | 2217 | break; |
| 2206 | #endif | 2218 | #endif |
| 2207 | default: | 2219 | default: |
| 2208 | break; | 2220 | break; |
| 2209 | } | 2221 | } |
| 2210 | #else | 2222 | #else |
| 2211 | - stfq_raw(ADDR(addr), DT0); | 2223 | + ABI32_MASK(addr); |
| 2224 | + stfq_raw(addr, DT0); | ||
| 2212 | #endif | 2225 | #endif |
| 2213 | } | 2226 | } |
| 2214 | 2227 | ||
| 2215 | void helper_lddf(target_ulong addr, int mem_idx) | 2228 | void helper_lddf(target_ulong addr, int mem_idx) |
| 2216 | { | 2229 | { |
| 2230 | + helper_check_align(addr, 7); | ||
| 2217 | #if !defined(CONFIG_USER_ONLY) | 2231 | #if !defined(CONFIG_USER_ONLY) |
| 2218 | switch (mem_idx) { | 2232 | switch (mem_idx) { |
| 2219 | case 0: | 2233 | case 0: |
| 2220 | - DT0 = ldfq_user(ADDR(addr)); | 2234 | + DT0 = ldfq_user(addr); |
| 2221 | break; | 2235 | break; |
| 2222 | case 1: | 2236 | case 1: |
| 2223 | - DT0 = ldfq_kernel(ADDR(addr)); | 2237 | + DT0 = ldfq_kernel(addr); |
| 2224 | break; | 2238 | break; |
| 2225 | #ifdef TARGET_SPARC64 | 2239 | #ifdef TARGET_SPARC64 |
| 2226 | case 2: | 2240 | case 2: |
| 2227 | - DT0 = ldfq_hypv(ADDR(addr)); | 2241 | + DT0 = ldfq_hypv(addr); |
| 2228 | break; | 2242 | break; |
| 2229 | #endif | 2243 | #endif |
| 2230 | default: | 2244 | default: |
| 2231 | break; | 2245 | break; |
| 2232 | } | 2246 | } |
| 2233 | #else | 2247 | #else |
| 2234 | - DT0 = ldfq_raw(ADDR(addr)); | 2248 | + ABI32_MASK(addr); |
| 2249 | + DT0 = ldfq_raw(addr); | ||
| 2235 | #endif | 2250 | #endif |
| 2236 | } | 2251 | } |
| 2237 | 2252 | ||
| @@ -2240,22 +2255,23 @@ void helper_ldqf(target_ulong addr, int mem_idx) | @@ -2240,22 +2255,23 @@ void helper_ldqf(target_ulong addr, int mem_idx) | ||
| 2240 | // XXX add 128 bit load | 2255 | // XXX add 128 bit load |
| 2241 | CPU_QuadU u; | 2256 | CPU_QuadU u; |
| 2242 | 2257 | ||
| 2258 | + helper_check_align(addr, 7); | ||
| 2243 | #if !defined(CONFIG_USER_ONLY) | 2259 | #if !defined(CONFIG_USER_ONLY) |
| 2244 | switch (mem_idx) { | 2260 | switch (mem_idx) { |
| 2245 | case 0: | 2261 | case 0: |
| 2246 | - u.ll.upper = ldq_user(ADDR(addr)); | ||
| 2247 | - u.ll.lower = ldq_user(ADDR(addr + 8)); | 2262 | + u.ll.upper = ldq_user(addr); |
| 2263 | + u.ll.lower = ldq_user(addr + 8); | ||
| 2248 | QT0 = u.q; | 2264 | QT0 = u.q; |
| 2249 | break; | 2265 | break; |
| 2250 | case 1: | 2266 | case 1: |
| 2251 | - u.ll.upper = ldq_kernel(ADDR(addr)); | ||
| 2252 | - u.ll.lower = ldq_kernel(ADDR(addr + 8)); | 2267 | + u.ll.upper = ldq_kernel(addr); |
| 2268 | + u.ll.lower = ldq_kernel(addr + 8); | ||
| 2253 | QT0 = u.q; | 2269 | QT0 = u.q; |
| 2254 | break; | 2270 | break; |
| 2255 | #ifdef TARGET_SPARC64 | 2271 | #ifdef TARGET_SPARC64 |
| 2256 | case 2: | 2272 | case 2: |
| 2257 | - u.ll.upper = ldq_hypv(ADDR(addr)); | ||
| 2258 | - u.ll.lower = ldq_hypv(ADDR(addr + 8)); | 2273 | + u.ll.upper = ldq_hypv(addr); |
| 2274 | + u.ll.lower = ldq_hypv(addr + 8); | ||
| 2259 | QT0 = u.q; | 2275 | QT0 = u.q; |
| 2260 | break; | 2276 | break; |
| 2261 | #endif | 2277 | #endif |
| @@ -2263,8 +2279,9 @@ void helper_ldqf(target_ulong addr, int mem_idx) | @@ -2263,8 +2279,9 @@ void helper_ldqf(target_ulong addr, int mem_idx) | ||
| 2263 | break; | 2279 | break; |
| 2264 | } | 2280 | } |
| 2265 | #else | 2281 | #else |
| 2266 | - u.ll.upper = ldq_raw(ADDR(addr)); | ||
| 2267 | - u.ll.lower = ldq_raw(ADDR(addr + 8)); | 2282 | + ABI32_MASK(addr); |
| 2283 | + u.ll.upper = ldq_raw(addr); | ||
| 2284 | + u.ll.lower = ldq_raw((addr + 8) & 0xffffffffULL); | ||
| 2268 | QT0 = u.q; | 2285 | QT0 = u.q; |
| 2269 | #endif | 2286 | #endif |
| 2270 | } | 2287 | } |
| @@ -2274,23 +2291,24 @@ void helper_stqf(target_ulong addr, int mem_idx) | @@ -2274,23 +2291,24 @@ void helper_stqf(target_ulong addr, int mem_idx) | ||
| 2274 | // XXX add 128 bit store | 2291 | // XXX add 128 bit store |
| 2275 | CPU_QuadU u; | 2292 | CPU_QuadU u; |
| 2276 | 2293 | ||
| 2294 | + helper_check_align(addr, 7); | ||
| 2277 | #if !defined(CONFIG_USER_ONLY) | 2295 | #if !defined(CONFIG_USER_ONLY) |
| 2278 | switch (mem_idx) { | 2296 | switch (mem_idx) { |
| 2279 | case 0: | 2297 | case 0: |
| 2280 | u.q = QT0; | 2298 | u.q = QT0; |
| 2281 | - stq_user(ADDR(addr), u.ll.upper); | ||
| 2282 | - stq_user(ADDR(addr + 8), u.ll.lower); | 2299 | + stq_user(addr, u.ll.upper); |
| 2300 | + stq_user(addr + 8, u.ll.lower); | ||
| 2283 | break; | 2301 | break; |
| 2284 | case 1: | 2302 | case 1: |
| 2285 | u.q = QT0; | 2303 | u.q = QT0; |
| 2286 | - stq_kernel(ADDR(addr), u.ll.upper); | ||
| 2287 | - stq_kernel(ADDR(addr + 8), u.ll.lower); | 2304 | + stq_kernel(addr, u.ll.upper); |
| 2305 | + stq_kernel(addr + 8, u.ll.lower); | ||
| 2288 | break; | 2306 | break; |
| 2289 | #ifdef TARGET_SPARC64 | 2307 | #ifdef TARGET_SPARC64 |
| 2290 | case 2: | 2308 | case 2: |
| 2291 | u.q = QT0; | 2309 | u.q = QT0; |
| 2292 | - stq_hypv(ADDR(addr), u.ll.upper); | ||
| 2293 | - stq_hypv(ADDR(addr + 8), u.ll.lower); | 2310 | + stq_hypv(addr, u.ll.upper); |
| 2311 | + stq_hypv(addr + 8, u.ll.lower); | ||
| 2294 | break; | 2312 | break; |
| 2295 | #endif | 2313 | #endif |
| 2296 | default: | 2314 | default: |
| @@ -2298,13 +2316,12 @@ void helper_stqf(target_ulong addr, int mem_idx) | @@ -2298,13 +2316,12 @@ void helper_stqf(target_ulong addr, int mem_idx) | ||
| 2298 | } | 2316 | } |
| 2299 | #else | 2317 | #else |
| 2300 | u.q = QT0; | 2318 | u.q = QT0; |
| 2301 | - stq_raw(ADDR(addr), u.ll.upper); | ||
| 2302 | - stq_raw(ADDR(addr + 8), u.ll.lower); | 2319 | + ABI32_MASK(addr); |
| 2320 | + stq_raw(addr, u.ll.upper); | ||
| 2321 | + stq_raw((addr + 8) & 0xffffffffULL, u.ll.lower); | ||
| 2303 | #endif | 2322 | #endif |
| 2304 | } | 2323 | } |
| 2305 | 2324 | ||
| 2306 | -#undef ADDR | ||
| 2307 | - | ||
| 2308 | void helper_ldfsr(void) | 2325 | void helper_ldfsr(void) |
| 2309 | { | 2326 | { |
| 2310 | int rnd_mode; | 2327 | int rnd_mode; |
| @@ -2833,12 +2850,32 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user, | @@ -2833,12 +2850,32 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user, | ||
| 2833 | #define SHIFT 3 | 2850 | #define SHIFT 3 |
| 2834 | #include "softmmu_template.h" | 2851 | #include "softmmu_template.h" |
| 2835 | 2852 | ||
| 2853 | +/* XXX: make it generic ? */ | ||
| 2854 | +static void cpu_restore_state2(void *retaddr) | ||
| 2855 | +{ | ||
| 2856 | + TranslationBlock *tb; | ||
| 2857 | + unsigned long pc; | ||
| 2858 | + | ||
| 2859 | + if (retaddr) { | ||
| 2860 | + /* now we have a real cpu fault */ | ||
| 2861 | + pc = (unsigned long)retaddr; | ||
| 2862 | + tb = tb_find_pc(pc); | ||
| 2863 | + if (tb) { | ||
| 2864 | + /* the PC is inside the translated code. It means that we have | ||
| 2865 | + a virtual CPU fault */ | ||
| 2866 | + cpu_restore_state(tb, env, pc, (void *)(long)env->cond); | ||
| 2867 | + } | ||
| 2868 | + } | ||
| 2869 | +} | ||
| 2870 | + | ||
| 2836 | static void do_unaligned_access(target_ulong addr, int is_write, int is_user, | 2871 | static void do_unaligned_access(target_ulong addr, int is_write, int is_user, |
| 2837 | void *retaddr) | 2872 | void *retaddr) |
| 2838 | { | 2873 | { |
| 2839 | #ifdef DEBUG_UNALIGNED | 2874 | #ifdef DEBUG_UNALIGNED |
| 2840 | - printf("Unaligned access to 0x%x from 0x%x\n", addr, env->pc); | 2875 | + printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx |
| 2876 | + "\n", addr, env->pc); | ||
| 2841 | #endif | 2877 | #endif |
| 2878 | + cpu_restore_state2(retaddr); | ||
| 2842 | raise_exception(TT_UNALIGNED); | 2879 | raise_exception(TT_UNALIGNED); |
| 2843 | } | 2880 | } |
| 2844 | 2881 | ||
| @@ -2848,9 +2885,7 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user, | @@ -2848,9 +2885,7 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user, | ||
| 2848 | /* XXX: fix it to restore all registers */ | 2885 | /* XXX: fix it to restore all registers */ |
| 2849 | void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) | 2886 | void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) |
| 2850 | { | 2887 | { |
| 2851 | - TranslationBlock *tb; | ||
| 2852 | int ret; | 2888 | int ret; |
| 2853 | - unsigned long pc; | ||
| 2854 | CPUState *saved_env; | 2889 | CPUState *saved_env; |
| 2855 | 2890 | ||
| 2856 | /* XXX: hack to restore env in all cases, even if not called from | 2891 | /* XXX: hack to restore env in all cases, even if not called from |
| @@ -2860,16 +2895,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) | @@ -2860,16 +2895,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) | ||
| 2860 | 2895 | ||
| 2861 | ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); | 2896 | ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); |
| 2862 | if (ret) { | 2897 | if (ret) { |
| 2863 | - if (retaddr) { | ||
| 2864 | - /* now we have a real cpu fault */ | ||
| 2865 | - pc = (unsigned long)retaddr; | ||
| 2866 | - tb = tb_find_pc(pc); | ||
| 2867 | - if (tb) { | ||
| 2868 | - /* the PC is inside the translated code. It means that we have | ||
| 2869 | - a virtual CPU fault */ | ||
| 2870 | - cpu_restore_state(tb, env, pc, (void *)env->cond); | ||
| 2871 | - } | ||
| 2872 | - } | 2898 | + cpu_restore_state2(retaddr); |
| 2873 | cpu_loop_exit(); | 2899 | cpu_loop_exit(); |
| 2874 | } | 2900 | } |
| 2875 | env = saved_env; | 2901 | env = saved_env; |
target-sparc/translate.c
| @@ -3945,7 +3945,6 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -3945,7 +3945,6 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 3945 | { | 3945 | { |
| 3946 | unsigned int xop = GET_FIELD(insn, 7, 12); | 3946 | unsigned int xop = GET_FIELD(insn, 7, 12); |
| 3947 | 3947 | ||
| 3948 | - save_state(dc, cpu_cond); | ||
| 3949 | cpu_src1 = get_src1(insn, cpu_src1); | 3948 | cpu_src1 = get_src1(insn, cpu_src1); |
| 3950 | if (xop == 0x3c || xop == 0x3e) | 3949 | if (xop == 0x3c || xop == 0x3e) |
| 3951 | { | 3950 | { |
| @@ -3968,7 +3967,6 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -3968,7 +3967,6 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 3968 | (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) { | 3967 | (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) { |
| 3969 | switch (xop) { | 3968 | switch (xop) { |
| 3970 | case 0x0: /* load unsigned word */ | 3969 | case 0x0: /* load unsigned word */ |
| 3971 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | ||
| 3972 | ABI32_MASK(cpu_addr); | 3970 | ABI32_MASK(cpu_addr); |
| 3973 | tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx); | 3971 | tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx); |
| 3974 | break; | 3972 | break; |
| @@ -3977,7 +3975,6 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -3977,7 +3975,6 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 3977 | tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx); | 3975 | tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx); |
| 3978 | break; | 3976 | break; |
| 3979 | case 0x2: /* load unsigned halfword */ | 3977 | case 0x2: /* load unsigned halfword */ |
| 3980 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1)); | ||
| 3981 | ABI32_MASK(cpu_addr); | 3978 | ABI32_MASK(cpu_addr); |
| 3982 | tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx); | 3979 | tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx); |
| 3983 | break; | 3980 | break; |
| @@ -3985,7 +3982,9 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -3985,7 +3982,9 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 3985 | if (rd & 1) | 3982 | if (rd & 1) |
| 3986 | goto illegal_insn; | 3983 | goto illegal_insn; |
| 3987 | else { | 3984 | else { |
| 3988 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); | 3985 | + save_state(dc, cpu_cond); |
| 3986 | + tcg_gen_helper_0_2(helper_check_align, cpu_addr, | ||
| 3987 | + tcg_const_i32(7)); // XXX remove | ||
| 3989 | ABI32_MASK(cpu_addr); | 3988 | ABI32_MASK(cpu_addr); |
| 3990 | tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx); | 3989 | tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx); |
| 3991 | tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64); | 3990 | tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64); |
| @@ -4001,7 +4000,6 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4001,7 +4000,6 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4001 | tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx); | 4000 | tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx); |
| 4002 | break; | 4001 | break; |
| 4003 | case 0xa: /* load signed halfword */ | 4002 | case 0xa: /* load signed halfword */ |
| 4004 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1)); | ||
| 4005 | ABI32_MASK(cpu_addr); | 4003 | ABI32_MASK(cpu_addr); |
| 4006 | tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx); | 4004 | tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx); |
| 4007 | break; | 4005 | break; |
| @@ -4012,7 +4010,6 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4012,7 +4010,6 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4012 | break; | 4010 | break; |
| 4013 | case 0x0f: /* swap register with memory. Also atomically */ | 4011 | case 0x0f: /* swap register with memory. Also atomically */ |
| 4014 | CHECK_IU_FEATURE(dc, SWAP); | 4012 | CHECK_IU_FEATURE(dc, SWAP); |
| 4015 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | ||
| 4016 | gen_movl_reg_TN(rd, cpu_val); | 4013 | gen_movl_reg_TN(rd, cpu_val); |
| 4017 | ABI32_MASK(cpu_addr); | 4014 | ABI32_MASK(cpu_addr); |
| 4018 | tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); | 4015 | tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); |
| @@ -4027,7 +4024,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4027,7 +4024,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4027 | if (!supervisor(dc)) | 4024 | if (!supervisor(dc)) |
| 4028 | goto priv_insn; | 4025 | goto priv_insn; |
| 4029 | #endif | 4026 | #endif |
| 4030 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | 4027 | + save_state(dc, cpu_cond); |
| 4031 | gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0); | 4028 | gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0); |
| 4032 | break; | 4029 | break; |
| 4033 | case 0x11: /* load unsigned byte alternate */ | 4030 | case 0x11: /* load unsigned byte alternate */ |
| @@ -4037,6 +4034,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4037,6 +4034,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4037 | if (!supervisor(dc)) | 4034 | if (!supervisor(dc)) |
| 4038 | goto priv_insn; | 4035 | goto priv_insn; |
| 4039 | #endif | 4036 | #endif |
| 4037 | + save_state(dc, cpu_cond); | ||
| 4040 | gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0); | 4038 | gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0); |
| 4041 | break; | 4039 | break; |
| 4042 | case 0x12: /* load unsigned halfword alternate */ | 4040 | case 0x12: /* load unsigned halfword alternate */ |
| @@ -4046,7 +4044,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4046,7 +4044,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4046 | if (!supervisor(dc)) | 4044 | if (!supervisor(dc)) |
| 4047 | goto priv_insn; | 4045 | goto priv_insn; |
| 4048 | #endif | 4046 | #endif |
| 4049 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1)); | 4047 | + save_state(dc, cpu_cond); |
| 4050 | gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0); | 4048 | gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0); |
| 4051 | break; | 4049 | break; |
| 4052 | case 0x13: /* load double word alternate */ | 4050 | case 0x13: /* load double word alternate */ |
| @@ -4058,7 +4056,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4058,7 +4056,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4058 | #endif | 4056 | #endif |
| 4059 | if (rd & 1) | 4057 | if (rd & 1) |
| 4060 | goto illegal_insn; | 4058 | goto illegal_insn; |
| 4061 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); | 4059 | + save_state(dc, cpu_cond); |
| 4062 | gen_ldda_asi(cpu_tmp0, cpu_val, cpu_addr, insn); | 4060 | gen_ldda_asi(cpu_tmp0, cpu_val, cpu_addr, insn); |
| 4063 | gen_movl_TN_reg(rd + 1, cpu_tmp0); | 4061 | gen_movl_TN_reg(rd + 1, cpu_tmp0); |
| 4064 | break; | 4062 | break; |
| @@ -4069,6 +4067,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4069,6 +4067,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4069 | if (!supervisor(dc)) | 4067 | if (!supervisor(dc)) |
| 4070 | goto priv_insn; | 4068 | goto priv_insn; |
| 4071 | #endif | 4069 | #endif |
| 4070 | + save_state(dc, cpu_cond); | ||
| 4072 | gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1); | 4071 | gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1); |
| 4073 | break; | 4072 | break; |
| 4074 | case 0x1a: /* load signed halfword alternate */ | 4073 | case 0x1a: /* load signed halfword alternate */ |
| @@ -4078,7 +4077,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4078,7 +4077,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4078 | if (!supervisor(dc)) | 4077 | if (!supervisor(dc)) |
| 4079 | goto priv_insn; | 4078 | goto priv_insn; |
| 4080 | #endif | 4079 | #endif |
| 4081 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1)); | 4080 | + save_state(dc, cpu_cond); |
| 4082 | gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1); | 4081 | gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1); |
| 4083 | break; | 4082 | break; |
| 4084 | case 0x1d: /* ldstuba -- XXX: should be atomically */ | 4083 | case 0x1d: /* ldstuba -- XXX: should be atomically */ |
| @@ -4088,6 +4087,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4088,6 +4087,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4088 | if (!supervisor(dc)) | 4087 | if (!supervisor(dc)) |
| 4089 | goto priv_insn; | 4088 | goto priv_insn; |
| 4090 | #endif | 4089 | #endif |
| 4090 | + save_state(dc, cpu_cond); | ||
| 4091 | gen_ldstub_asi(cpu_val, cpu_addr, insn); | 4091 | gen_ldstub_asi(cpu_val, cpu_addr, insn); |
| 4092 | break; | 4092 | break; |
| 4093 | case 0x1f: /* swap reg with alt. memory. Also atomically */ | 4093 | case 0x1f: /* swap reg with alt. memory. Also atomically */ |
| @@ -4098,7 +4098,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4098,7 +4098,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4098 | if (!supervisor(dc)) | 4098 | if (!supervisor(dc)) |
| 4099 | goto priv_insn; | 4099 | goto priv_insn; |
| 4100 | #endif | 4100 | #endif |
| 4101 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | 4101 | + save_state(dc, cpu_cond); |
| 4102 | gen_movl_reg_TN(rd, cpu_val); | 4102 | gen_movl_reg_TN(rd, cpu_val); |
| 4103 | gen_swap_asi(cpu_val, cpu_addr, insn); | 4103 | gen_swap_asi(cpu_val, cpu_addr, insn); |
| 4104 | break; | 4104 | break; |
| @@ -4112,38 +4112,36 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4112,38 +4112,36 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4112 | #endif | 4112 | #endif |
| 4113 | #ifdef TARGET_SPARC64 | 4113 | #ifdef TARGET_SPARC64 |
| 4114 | case 0x08: /* V9 ldsw */ | 4114 | case 0x08: /* V9 ldsw */ |
| 4115 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | ||
| 4116 | ABI32_MASK(cpu_addr); | 4115 | ABI32_MASK(cpu_addr); |
| 4117 | tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx); | 4116 | tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx); |
| 4118 | break; | 4117 | break; |
| 4119 | case 0x0b: /* V9 ldx */ | 4118 | case 0x0b: /* V9 ldx */ |
| 4120 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); | ||
| 4121 | ABI32_MASK(cpu_addr); | 4119 | ABI32_MASK(cpu_addr); |
| 4122 | tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx); | 4120 | tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx); |
| 4123 | break; | 4121 | break; |
| 4124 | case 0x18: /* V9 ldswa */ | 4122 | case 0x18: /* V9 ldswa */ |
| 4125 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | 4123 | + save_state(dc, cpu_cond); |
| 4126 | gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1); | 4124 | gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1); |
| 4127 | break; | 4125 | break; |
| 4128 | case 0x1b: /* V9 ldxa */ | 4126 | case 0x1b: /* V9 ldxa */ |
| 4129 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); | 4127 | + save_state(dc, cpu_cond); |
| 4130 | gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0); | 4128 | gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0); |
| 4131 | break; | 4129 | break; |
| 4132 | case 0x2d: /* V9 prefetch, no effect */ | 4130 | case 0x2d: /* V9 prefetch, no effect */ |
| 4133 | goto skip_move; | 4131 | goto skip_move; |
| 4134 | case 0x30: /* V9 ldfa */ | 4132 | case 0x30: /* V9 ldfa */ |
| 4135 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | 4133 | + save_state(dc, cpu_cond); |
| 4136 | gen_ldf_asi(cpu_addr, insn, 4, rd); | 4134 | gen_ldf_asi(cpu_addr, insn, 4, rd); |
| 4137 | goto skip_move; | 4135 | goto skip_move; |
| 4138 | case 0x33: /* V9 lddfa */ | 4136 | case 0x33: /* V9 lddfa */ |
| 4139 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | 4137 | + save_state(dc, cpu_cond); |
| 4140 | gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd)); | 4138 | gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd)); |
| 4141 | goto skip_move; | 4139 | goto skip_move; |
| 4142 | case 0x3d: /* V9 prefetcha, no effect */ | 4140 | case 0x3d: /* V9 prefetcha, no effect */ |
| 4143 | goto skip_move; | 4141 | goto skip_move; |
| 4144 | case 0x32: /* V9 ldqfa */ | 4142 | case 0x32: /* V9 ldqfa */ |
| 4145 | CHECK_FPU_FEATURE(dc, FLOAT128); | 4143 | CHECK_FPU_FEATURE(dc, FLOAT128); |
| 4146 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | 4144 | + save_state(dc, cpu_cond); |
| 4147 | gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd)); | 4145 | gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd)); |
| 4148 | goto skip_move; | 4146 | goto skip_move; |
| 4149 | #endif | 4147 | #endif |
| @@ -4157,15 +4155,16 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4157,15 +4155,16 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4157 | } else if (xop >= 0x20 && xop < 0x24) { | 4155 | } else if (xop >= 0x20 && xop < 0x24) { |
| 4158 | if (gen_trap_ifnofpu(dc, cpu_cond)) | 4156 | if (gen_trap_ifnofpu(dc, cpu_cond)) |
| 4159 | goto jmp_insn; | 4157 | goto jmp_insn; |
| 4158 | + save_state(dc, cpu_cond); | ||
| 4160 | switch (xop) { | 4159 | switch (xop) { |
| 4161 | case 0x20: /* load fpreg */ | 4160 | case 0x20: /* load fpreg */ |
| 4162 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | 4161 | + ABI32_MASK(cpu_addr); |
| 4163 | tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); | 4162 | tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); |
| 4164 | tcg_gen_st_i32(cpu_tmp32, cpu_env, | 4163 | tcg_gen_st_i32(cpu_tmp32, cpu_env, |
| 4165 | offsetof(CPUState, fpr[rd])); | 4164 | offsetof(CPUState, fpr[rd])); |
| 4166 | break; | 4165 | break; |
| 4167 | case 0x21: /* load fsr */ | 4166 | case 0x21: /* load fsr */ |
| 4168 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | 4167 | + ABI32_MASK(cpu_addr); |
| 4169 | tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); | 4168 | tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); |
| 4170 | tcg_gen_st_i32(cpu_tmp32, cpu_env, | 4169 | tcg_gen_st_i32(cpu_tmp32, cpu_env, |
| 4171 | offsetof(CPUState, ft0)); | 4170 | offsetof(CPUState, ft0)); |
| @@ -4173,14 +4172,10 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4173,14 +4172,10 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4173 | break; | 4172 | break; |
| 4174 | case 0x22: /* load quad fpreg */ | 4173 | case 0x22: /* load quad fpreg */ |
| 4175 | CHECK_FPU_FEATURE(dc, FLOAT128); | 4174 | CHECK_FPU_FEATURE(dc, FLOAT128); |
| 4176 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, | ||
| 4177 | - tcg_const_i32(7)); | ||
| 4178 | tcg_gen_helper_0_2(helper_ldqf, cpu_addr, dc->mem_idx); | 4175 | tcg_gen_helper_0_2(helper_ldqf, cpu_addr, dc->mem_idx); |
| 4179 | gen_op_store_QT0_fpr(QFPREG(rd)); | 4176 | gen_op_store_QT0_fpr(QFPREG(rd)); |
| 4180 | break; | 4177 | break; |
| 4181 | case 0x23: /* load double fpreg */ | 4178 | case 0x23: /* load double fpreg */ |
| 4182 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, | ||
| 4183 | - tcg_const_i32(7)); | ||
| 4184 | tcg_gen_helper_0_2(helper_lddf, cpu_addr, | 4179 | tcg_gen_helper_0_2(helper_lddf, cpu_addr, |
| 4185 | tcg_const_i32(dc->mem_idx)); | 4180 | tcg_const_i32(dc->mem_idx)); |
| 4186 | gen_op_store_DT0_fpr(DFPREG(rd)); | 4181 | gen_op_store_DT0_fpr(DFPREG(rd)); |
| @@ -4193,7 +4188,6 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4193,7 +4188,6 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4193 | gen_movl_reg_TN(rd, cpu_val); | 4188 | gen_movl_reg_TN(rd, cpu_val); |
| 4194 | switch (xop) { | 4189 | switch (xop) { |
| 4195 | case 0x4: /* store word */ | 4190 | case 0x4: /* store word */ |
| 4196 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | ||
| 4197 | ABI32_MASK(cpu_addr); | 4191 | ABI32_MASK(cpu_addr); |
| 4198 | tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx); | 4192 | tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx); |
| 4199 | break; | 4193 | break; |
| @@ -4202,7 +4196,6 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4202,7 +4196,6 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4202 | tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx); | 4196 | tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx); |
| 4203 | break; | 4197 | break; |
| 4204 | case 0x6: /* store halfword */ | 4198 | case 0x6: /* store halfword */ |
| 4205 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1)); | ||
| 4206 | ABI32_MASK(cpu_addr); | 4199 | ABI32_MASK(cpu_addr); |
| 4207 | tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx); | 4200 | tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx); |
| 4208 | break; | 4201 | break; |
| @@ -4212,7 +4205,10 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4212,7 +4205,10 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4212 | else { | 4205 | else { |
| 4213 | TCGv r_low; | 4206 | TCGv r_low; |
| 4214 | 4207 | ||
| 4215 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); | 4208 | + save_state(dc, cpu_cond); |
| 4209 | + ABI32_MASK(cpu_addr); | ||
| 4210 | + tcg_gen_helper_0_2(helper_check_align, cpu_addr, | ||
| 4211 | + tcg_const_i32(7)); // XXX remove | ||
| 4216 | r_low = tcg_temp_new(TCG_TYPE_I32); | 4212 | r_low = tcg_temp_new(TCG_TYPE_I32); |
| 4217 | gen_movl_reg_TN(rd + 1, r_low); | 4213 | gen_movl_reg_TN(rd + 1, r_low); |
| 4218 | tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_val, | 4214 | tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_val, |
| @@ -4228,7 +4224,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4228,7 +4224,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4228 | if (!supervisor(dc)) | 4224 | if (!supervisor(dc)) |
| 4229 | goto priv_insn; | 4225 | goto priv_insn; |
| 4230 | #endif | 4226 | #endif |
| 4231 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | 4227 | + save_state(dc, cpu_cond); |
| 4232 | gen_st_asi(cpu_val, cpu_addr, insn, 4); | 4228 | gen_st_asi(cpu_val, cpu_addr, insn, 4); |
| 4233 | break; | 4229 | break; |
| 4234 | case 0x15: /* store byte alternate */ | 4230 | case 0x15: /* store byte alternate */ |
| @@ -4238,6 +4234,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4238,6 +4234,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4238 | if (!supervisor(dc)) | 4234 | if (!supervisor(dc)) |
| 4239 | goto priv_insn; | 4235 | goto priv_insn; |
| 4240 | #endif | 4236 | #endif |
| 4237 | + save_state(dc, cpu_cond); | ||
| 4241 | gen_st_asi(cpu_val, cpu_addr, insn, 1); | 4238 | gen_st_asi(cpu_val, cpu_addr, insn, 1); |
| 4242 | break; | 4239 | break; |
| 4243 | case 0x16: /* store halfword alternate */ | 4240 | case 0x16: /* store halfword alternate */ |
| @@ -4247,7 +4244,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4247,7 +4244,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4247 | if (!supervisor(dc)) | 4244 | if (!supervisor(dc)) |
| 4248 | goto priv_insn; | 4245 | goto priv_insn; |
| 4249 | #endif | 4246 | #endif |
| 4250 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1)); | 4247 | + save_state(dc, cpu_cond); |
| 4251 | gen_st_asi(cpu_val, cpu_addr, insn, 2); | 4248 | gen_st_asi(cpu_val, cpu_addr, insn, 2); |
| 4252 | break; | 4249 | break; |
| 4253 | case 0x17: /* store double word alternate */ | 4250 | case 0x17: /* store double word alternate */ |
| @@ -4260,19 +4257,18 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4260,19 +4257,18 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4260 | if (rd & 1) | 4257 | if (rd & 1) |
| 4261 | goto illegal_insn; | 4258 | goto illegal_insn; |
| 4262 | else { | 4259 | else { |
| 4263 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); | 4260 | + save_state(dc, cpu_cond); |
| 4264 | gen_stda_asi(cpu_val, cpu_addr, insn, rd); | 4261 | gen_stda_asi(cpu_val, cpu_addr, insn, rd); |
| 4265 | } | 4262 | } |
| 4266 | break; | 4263 | break; |
| 4267 | #endif | 4264 | #endif |
| 4268 | #ifdef TARGET_SPARC64 | 4265 | #ifdef TARGET_SPARC64 |
| 4269 | case 0x0e: /* V9 stx */ | 4266 | case 0x0e: /* V9 stx */ |
| 4270 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); | ||
| 4271 | ABI32_MASK(cpu_addr); | 4267 | ABI32_MASK(cpu_addr); |
| 4272 | tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx); | 4268 | tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx); |
| 4273 | break; | 4269 | break; |
| 4274 | case 0x1e: /* V9 stxa */ | 4270 | case 0x1e: /* V9 stxa */ |
| 4275 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); | 4271 | + save_state(dc, cpu_cond); |
| 4276 | gen_st_asi(cpu_val, cpu_addr, insn, 8); | 4272 | gen_st_asi(cpu_val, cpu_addr, insn, 8); |
| 4277 | break; | 4273 | break; |
| 4278 | #endif | 4274 | #endif |
| @@ -4282,17 +4278,16 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4282,17 +4278,16 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4282 | } else if (xop > 0x23 && xop < 0x28) { | 4278 | } else if (xop > 0x23 && xop < 0x28) { |
| 4283 | if (gen_trap_ifnofpu(dc, cpu_cond)) | 4279 | if (gen_trap_ifnofpu(dc, cpu_cond)) |
| 4284 | goto jmp_insn; | 4280 | goto jmp_insn; |
| 4281 | + save_state(dc, cpu_cond); | ||
| 4285 | switch (xop) { | 4282 | switch (xop) { |
| 4286 | case 0x24: /* store fpreg */ | 4283 | case 0x24: /* store fpreg */ |
| 4287 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | 4284 | + ABI32_MASK(cpu_addr); |
| 4288 | tcg_gen_ld_i32(cpu_tmp32, cpu_env, | 4285 | tcg_gen_ld_i32(cpu_tmp32, cpu_env, |
| 4289 | offsetof(CPUState, fpr[rd])); | 4286 | offsetof(CPUState, fpr[rd])); |
| 4290 | tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); | 4287 | tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); |
| 4291 | break; | 4288 | break; |
| 4292 | case 0x25: /* stfsr, V9 stxfsr */ | 4289 | case 0x25: /* stfsr, V9 stxfsr */ |
| 4293 | -#ifdef CONFIG_USER_ONLY | ||
| 4294 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | ||
| 4295 | -#endif | 4290 | + ABI32_MASK(cpu_addr); |
| 4296 | tcg_gen_helper_0_0(helper_stfsr); | 4291 | tcg_gen_helper_0_0(helper_stfsr); |
| 4297 | tcg_gen_ld_i32(cpu_tmp32, cpu_env, | 4292 | tcg_gen_ld_i32(cpu_tmp32, cpu_env, |
| 4298 | offsetof(CPUState, ft0)); | 4293 | offsetof(CPUState, ft0)); |
| @@ -4302,8 +4297,6 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4302,8 +4297,6 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4302 | #ifdef TARGET_SPARC64 | 4297 | #ifdef TARGET_SPARC64 |
| 4303 | /* V9 stqf, store quad fpreg */ | 4298 | /* V9 stqf, store quad fpreg */ |
| 4304 | CHECK_FPU_FEATURE(dc, FLOAT128); | 4299 | CHECK_FPU_FEATURE(dc, FLOAT128); |
| 4305 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, | ||
| 4306 | - tcg_const_i32(7)); | ||
| 4307 | gen_op_load_fpr_QT0(QFPREG(rd)); | 4300 | gen_op_load_fpr_QT0(QFPREG(rd)); |
| 4308 | tcg_gen_helper_0_2(helper_stqf, cpu_addr, dc->mem_idx); | 4301 | tcg_gen_helper_0_2(helper_stqf, cpu_addr, dc->mem_idx); |
| 4309 | break; | 4302 | break; |
| @@ -4320,8 +4313,6 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4320,8 +4313,6 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4320 | #endif | 4313 | #endif |
| 4321 | #endif | 4314 | #endif |
| 4322 | case 0x27: /* store double fpreg */ | 4315 | case 0x27: /* store double fpreg */ |
| 4323 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, | ||
| 4324 | - tcg_const_i32(7)); | ||
| 4325 | gen_op_load_fpr_DT0(DFPREG(rd)); | 4316 | gen_op_load_fpr_DT0(DFPREG(rd)); |
| 4326 | tcg_gen_helper_0_2(helper_stdf, cpu_addr, | 4317 | tcg_gen_helper_0_2(helper_stdf, cpu_addr, |
| 4327 | tcg_const_i32(dc->mem_idx)); | 4318 | tcg_const_i32(dc->mem_idx)); |
| @@ -4330,10 +4321,10 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4330,10 +4321,10 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4330 | goto illegal_insn; | 4321 | goto illegal_insn; |
| 4331 | } | 4322 | } |
| 4332 | } else if (xop > 0x33 && xop < 0x3f) { | 4323 | } else if (xop > 0x33 && xop < 0x3f) { |
| 4324 | + save_state(dc, cpu_cond); | ||
| 4333 | switch (xop) { | 4325 | switch (xop) { |
| 4334 | #ifdef TARGET_SPARC64 | 4326 | #ifdef TARGET_SPARC64 |
| 4335 | case 0x34: /* V9 stfa */ | 4327 | case 0x34: /* V9 stfa */ |
| 4336 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | ||
| 4337 | gen_op_load_fpr_FT0(rd); | 4328 | gen_op_load_fpr_FT0(rd); |
| 4338 | gen_stf_asi(cpu_addr, insn, 4, rd); | 4329 | gen_stf_asi(cpu_addr, insn, 4, rd); |
| 4339 | break; | 4330 | break; |
| @@ -4345,17 +4336,14 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4345,17 +4336,14 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4345 | gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd)); | 4336 | gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd)); |
| 4346 | break; | 4337 | break; |
| 4347 | case 0x37: /* V9 stdfa */ | 4338 | case 0x37: /* V9 stdfa */ |
| 4348 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | ||
| 4349 | gen_op_load_fpr_DT0(DFPREG(rd)); | 4339 | gen_op_load_fpr_DT0(DFPREG(rd)); |
| 4350 | gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd)); | 4340 | gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd)); |
| 4351 | break; | 4341 | break; |
| 4352 | case 0x3c: /* V9 casa */ | 4342 | case 0x3c: /* V9 casa */ |
| 4353 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); | ||
| 4354 | gen_cas_asi(cpu_val, cpu_addr, cpu_val, insn, rd); | 4343 | gen_cas_asi(cpu_val, cpu_addr, cpu_val, insn, rd); |
| 4355 | gen_movl_TN_reg(rd, cpu_val); | 4344 | gen_movl_TN_reg(rd, cpu_val); |
| 4356 | break; | 4345 | break; |
| 4357 | case 0x3e: /* V9 casxa */ | 4346 | case 0x3e: /* V9 casxa */ |
| 4358 | - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); | ||
| 4359 | gen_casx_asi(cpu_val, cpu_addr, cpu_val, insn, rd); | 4347 | gen_casx_asi(cpu_val, cpu_addr, cpu_val, insn, rd); |
| 4360 | gen_movl_TN_reg(rd, cpu_val); | 4348 | gen_movl_TN_reg(rd, cpu_val); |
| 4361 | break; | 4349 | break; |