Commit 2cade6a3f60cc203ee2b3fc44d06af3ec048e379
1 parent
a5a52cf2
Support for address masking
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4882 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
58 additions
and
33 deletions
cpu-exec.c
... | ... | @@ -184,8 +184,9 @@ static inline TranslationBlock *tb_find_fast(void) |
184 | 184 | pc = env->regs[15]; |
185 | 185 | #elif defined(TARGET_SPARC) |
186 | 186 | #ifdef TARGET_SPARC64 |
187 | - // Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled | |
188 | - flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2)) | |
187 | + // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled | |
188 | + flags = ((env->pstate & PS_AM) << 2) | |
189 | + | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2)) | |
189 | 190 | | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2); |
190 | 191 | #else |
191 | 192 | // FPU enable . Supervisor | ... | ... |
target-sparc/op_helper.c
... | ... | @@ -32,12 +32,22 @@ do { printf("ASI: " fmt , ##args); } while (0) |
32 | 32 | #define DPRINTF_ASI(fmt, args...) do {} while (0) |
33 | 33 | #endif |
34 | 34 | |
35 | -#ifdef TARGET_ABI32 | |
36 | -#define ABI32_MASK(addr) do { (addr) &= 0xffffffffULL; } while (0) | |
35 | +#ifdef TARGET_SPARC64 | |
36 | +#ifndef TARGET_ABI32 | |
37 | +#define AM_CHECK(env1) ((env1)->pstate & PS_AM) | |
37 | 38 | #else |
38 | -#define ABI32_MASK(addr) do {} while (0) | |
39 | +#define AM_CHECK(env1) (1) | |
40 | +#endif | |
39 | 41 | #endif |
40 | 42 | |
43 | +static inline void address_mask(CPUState *env1, target_ulong *addr) | |
44 | +{ | |
45 | +#ifdef TARGET_SPARC64 | |
46 | + if (AM_CHECK(env1)) | |
47 | + *addr &= 0xffffffffULL; | |
48 | +#endif | |
49 | +} | |
50 | + | |
41 | 51 | void raise_exception(int tt) |
42 | 52 | { |
43 | 53 | env->exception_index = tt; |
... | ... | @@ -1381,7 +1391,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) |
1381 | 1391 | raise_exception(TT_PRIV_ACT); |
1382 | 1392 | |
1383 | 1393 | helper_check_align(addr, size - 1); |
1384 | - ABI32_MASK(addr); | |
1394 | + address_mask(env, &addr); | |
1385 | 1395 | |
1386 | 1396 | switch (asi) { |
1387 | 1397 | case 0x80: // Primary |
... | ... | @@ -1470,7 +1480,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) |
1470 | 1480 | raise_exception(TT_PRIV_ACT); |
1471 | 1481 | |
1472 | 1482 | helper_check_align(addr, size - 1); |
1473 | - ABI32_MASK(addr); | |
1483 | + address_mask(env, &addr); | |
1474 | 1484 | |
1475 | 1485 | /* Convert to little endian */ |
1476 | 1486 | switch (asi) { |
... | ... | @@ -2330,7 +2340,7 @@ void helper_stdf(target_ulong addr, int mem_idx) |
2330 | 2340 | break; |
2331 | 2341 | } |
2332 | 2342 | #else |
2333 | - ABI32_MASK(addr); | |
2343 | + address_mask(env, &addr); | |
2334 | 2344 | stfq_raw(addr, DT0); |
2335 | 2345 | #endif |
2336 | 2346 | } |
... | ... | @@ -2355,7 +2365,7 @@ void helper_lddf(target_ulong addr, int mem_idx) |
2355 | 2365 | break; |
2356 | 2366 | } |
2357 | 2367 | #else |
2358 | - ABI32_MASK(addr); | |
2368 | + address_mask(env, &addr); | |
2359 | 2369 | DT0 = ldfq_raw(addr); |
2360 | 2370 | #endif |
2361 | 2371 | } |
... | ... | @@ -2389,7 +2399,7 @@ void helper_ldqf(target_ulong addr, int mem_idx) |
2389 | 2399 | break; |
2390 | 2400 | } |
2391 | 2401 | #else |
2392 | - ABI32_MASK(addr); | |
2402 | + address_mask(env, &addr); | |
2393 | 2403 | u.ll.upper = ldq_raw(addr); |
2394 | 2404 | u.ll.lower = ldq_raw((addr + 8) & 0xffffffffULL); |
2395 | 2405 | QT0 = u.q; |
... | ... | @@ -2426,7 +2436,7 @@ void helper_stqf(target_ulong addr, int mem_idx) |
2426 | 2436 | } |
2427 | 2437 | #else |
2428 | 2438 | u.q = QT0; |
2429 | - ABI32_MASK(addr); | |
2439 | + address_mask(env, &addr); | |
2430 | 2440 | stq_raw(addr, u.ll.upper); |
2431 | 2441 | stq_raw((addr + 8) & 0xffffffffULL, u.ll.lower); |
2432 | 2442 | #endif | ... | ... |
target-sparc/translate.c
... | ... | @@ -57,6 +57,7 @@ typedef struct DisasContext { |
57 | 57 | int is_br; |
58 | 58 | int mem_idx; |
59 | 59 | int fpu_enabled; |
60 | + int address_mask_32bit; | |
60 | 61 | struct TranslationBlock *tb; |
61 | 62 | uint32_t features; |
62 | 63 | } DisasContext; |
... | ... | @@ -201,12 +202,22 @@ static void gen_op_store_QT0_fpr(unsigned int dst) |
201 | 202 | #endif |
202 | 203 | #endif |
203 | 204 | |
204 | -#ifdef TARGET_ABI32 | |
205 | -#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL); | |
205 | +#ifdef TARGET_SPARC64 | |
206 | +#ifndef TARGET_ABI32 | |
207 | +#define AM_CHECK(dc) ((dc)->address_mask_32bit) | |
206 | 208 | #else |
207 | -#define ABI32_MASK(addr) | |
209 | +#define AM_CHECK(dc) (1) | |
210 | +#endif | |
208 | 211 | #endif |
209 | 212 | |
213 | +static inline void gen_address_mask(DisasContext *dc, TCGv addr) | |
214 | +{ | |
215 | +#ifdef TARGET_SPARC64 | |
216 | + if (AM_CHECK(dc)) | |
217 | + tcg_gen_andi_tl(addr, addr, 0xffffffffULL); | |
218 | +#endif | |
219 | +} | |
220 | + | |
210 | 221 | static inline void gen_movl_reg_TN(int reg, TCGv tn) |
211 | 222 | { |
212 | 223 | if (reg == 0) |
... | ... | @@ -4199,15 +4210,15 @@ static void disas_sparc_insn(DisasContext * dc) |
4199 | 4210 | (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) { |
4200 | 4211 | switch (xop) { |
4201 | 4212 | case 0x0: /* load unsigned word */ |
4202 | - ABI32_MASK(cpu_addr); | |
4213 | + gen_address_mask(dc, cpu_addr); | |
4203 | 4214 | tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx); |
4204 | 4215 | break; |
4205 | 4216 | case 0x1: /* load unsigned byte */ |
4206 | - ABI32_MASK(cpu_addr); | |
4217 | + gen_address_mask(dc, cpu_addr); | |
4207 | 4218 | tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx); |
4208 | 4219 | break; |
4209 | 4220 | case 0x2: /* load unsigned halfword */ |
4210 | - ABI32_MASK(cpu_addr); | |
4221 | + gen_address_mask(dc, cpu_addr); | |
4211 | 4222 | tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx); |
4212 | 4223 | break; |
4213 | 4224 | case 0x3: /* load double word */ |
... | ... | @@ -4221,7 +4232,7 @@ static void disas_sparc_insn(DisasContext * dc) |
4221 | 4232 | tcg_gen_helper_0_2(helper_check_align, cpu_addr, |
4222 | 4233 | r_const); // XXX remove |
4223 | 4234 | tcg_temp_free(r_const); |
4224 | - ABI32_MASK(cpu_addr); | |
4235 | + gen_address_mask(dc, cpu_addr); | |
4225 | 4236 | tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx); |
4226 | 4237 | tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64); |
4227 | 4238 | tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL); |
... | ... | @@ -4232,18 +4243,18 @@ static void disas_sparc_insn(DisasContext * dc) |
4232 | 4243 | } |
4233 | 4244 | break; |
4234 | 4245 | case 0x9: /* load signed byte */ |
4235 | - ABI32_MASK(cpu_addr); | |
4246 | + gen_address_mask(dc, cpu_addr); | |
4236 | 4247 | tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx); |
4237 | 4248 | break; |
4238 | 4249 | case 0xa: /* load signed halfword */ |
4239 | - ABI32_MASK(cpu_addr); | |
4250 | + gen_address_mask(dc, cpu_addr); | |
4240 | 4251 | tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx); |
4241 | 4252 | break; |
4242 | 4253 | case 0xd: /* ldstub -- XXX: should be atomically */ |
4243 | 4254 | { |
4244 | 4255 | TCGv r_const; |
4245 | 4256 | |
4246 | - ABI32_MASK(cpu_addr); | |
4257 | + gen_address_mask(dc, cpu_addr); | |
4247 | 4258 | tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx); |
4248 | 4259 | r_const = tcg_const_tl(0xff); |
4249 | 4260 | tcg_gen_qemu_st8(r_const, cpu_addr, dc->mem_idx); |
... | ... | @@ -4254,7 +4265,7 @@ static void disas_sparc_insn(DisasContext * dc) |
4254 | 4265 | atomically */ |
4255 | 4266 | CHECK_IU_FEATURE(dc, SWAP); |
4256 | 4267 | gen_movl_reg_TN(rd, cpu_val); |
4257 | - ABI32_MASK(cpu_addr); | |
4268 | + gen_address_mask(dc, cpu_addr); | |
4258 | 4269 | tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); |
4259 | 4270 | tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx); |
4260 | 4271 | tcg_gen_extu_i32_tl(cpu_val, cpu_tmp32); |
... | ... | @@ -4356,11 +4367,11 @@ static void disas_sparc_insn(DisasContext * dc) |
4356 | 4367 | #endif |
4357 | 4368 | #ifdef TARGET_SPARC64 |
4358 | 4369 | case 0x08: /* V9 ldsw */ |
4359 | - ABI32_MASK(cpu_addr); | |
4370 | + gen_address_mask(dc, cpu_addr); | |
4360 | 4371 | tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx); |
4361 | 4372 | break; |
4362 | 4373 | case 0x0b: /* V9 ldx */ |
4363 | - ABI32_MASK(cpu_addr); | |
4374 | + gen_address_mask(dc, cpu_addr); | |
4364 | 4375 | tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx); |
4365 | 4376 | break; |
4366 | 4377 | case 0x18: /* V9 ldswa */ |
... | ... | @@ -4402,13 +4413,13 @@ static void disas_sparc_insn(DisasContext * dc) |
4402 | 4413 | save_state(dc, cpu_cond); |
4403 | 4414 | switch (xop) { |
4404 | 4415 | case 0x20: /* load fpreg */ |
4405 | - ABI32_MASK(cpu_addr); | |
4416 | + gen_address_mask(dc, cpu_addr); | |
4406 | 4417 | tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); |
4407 | 4418 | tcg_gen_st_i32(cpu_tmp32, cpu_env, |
4408 | 4419 | offsetof(CPUState, fpr[rd])); |
4409 | 4420 | break; |
4410 | 4421 | case 0x21: /* load fsr */ |
4411 | - ABI32_MASK(cpu_addr); | |
4422 | + gen_address_mask(dc, cpu_addr); | |
4412 | 4423 | tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); |
4413 | 4424 | tcg_gen_st_i32(cpu_tmp32, cpu_env, |
4414 | 4425 | offsetof(CPUState, ft0)); |
... | ... | @@ -4443,15 +4454,15 @@ static void disas_sparc_insn(DisasContext * dc) |
4443 | 4454 | gen_movl_reg_TN(rd, cpu_val); |
4444 | 4455 | switch (xop) { |
4445 | 4456 | case 0x4: /* store word */ |
4446 | - ABI32_MASK(cpu_addr); | |
4457 | + gen_address_mask(dc, cpu_addr); | |
4447 | 4458 | tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx); |
4448 | 4459 | break; |
4449 | 4460 | case 0x5: /* store byte */ |
4450 | - ABI32_MASK(cpu_addr); | |
4461 | + gen_address_mask(dc, cpu_addr); | |
4451 | 4462 | tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx); |
4452 | 4463 | break; |
4453 | 4464 | case 0x6: /* store halfword */ |
4454 | - ABI32_MASK(cpu_addr); | |
4465 | + gen_address_mask(dc, cpu_addr); | |
4455 | 4466 | tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx); |
4456 | 4467 | break; |
4457 | 4468 | case 0x7: /* store double word */ |
... | ... | @@ -4461,7 +4472,7 @@ static void disas_sparc_insn(DisasContext * dc) |
4461 | 4472 | TCGv r_low, r_const; |
4462 | 4473 | |
4463 | 4474 | save_state(dc, cpu_cond); |
4464 | - ABI32_MASK(cpu_addr); | |
4475 | + gen_address_mask(dc, cpu_addr); | |
4465 | 4476 | r_const = tcg_const_i32(7); |
4466 | 4477 | tcg_gen_helper_0_2(helper_check_align, cpu_addr, |
4467 | 4478 | r_const); // XXX remove |
... | ... | @@ -4522,7 +4533,7 @@ static void disas_sparc_insn(DisasContext * dc) |
4522 | 4533 | #endif |
4523 | 4534 | #ifdef TARGET_SPARC64 |
4524 | 4535 | case 0x0e: /* V9 stx */ |
4525 | - ABI32_MASK(cpu_addr); | |
4536 | + gen_address_mask(dc, cpu_addr); | |
4526 | 4537 | tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx); |
4527 | 4538 | break; |
4528 | 4539 | case 0x1e: /* V9 stxa */ |
... | ... | @@ -4539,13 +4550,13 @@ static void disas_sparc_insn(DisasContext * dc) |
4539 | 4550 | save_state(dc, cpu_cond); |
4540 | 4551 | switch (xop) { |
4541 | 4552 | case 0x24: /* store fpreg */ |
4542 | - ABI32_MASK(cpu_addr); | |
4553 | + gen_address_mask(dc, cpu_addr); | |
4543 | 4554 | tcg_gen_ld_i32(cpu_tmp32, cpu_env, |
4544 | 4555 | offsetof(CPUState, fpr[rd])); |
4545 | 4556 | tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); |
4546 | 4557 | break; |
4547 | 4558 | case 0x25: /* stfsr, V9 stxfsr */ |
4548 | - ABI32_MASK(cpu_addr); | |
4559 | + gen_address_mask(dc, cpu_addr); | |
4549 | 4560 | tcg_gen_helper_0_0(helper_stfsr); |
4550 | 4561 | tcg_gen_ld_i32(cpu_tmp32, cpu_env, |
4551 | 4562 | offsetof(CPUState, ft0)); |
... | ... | @@ -4739,6 +4750,9 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, |
4739 | 4750 | #endif |
4740 | 4751 | } else |
4741 | 4752 | dc->fpu_enabled = 0; |
4753 | +#ifdef TARGET_SPARC64 | |
4754 | + dc->address_mask_32bit = env->pstate & PS_AM; | |
4755 | +#endif | |
4742 | 4756 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; |
4743 | 4757 | |
4744 | 4758 | cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL); | ... | ... |