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