Commit 2cade6a3f60cc203ee2b3fc44d06af3ec048e379

Authored by blueswir1
1 parent a5a52cf2

Support for address masking

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4882 c046a42c-6fe2-441c-8c8c-71466251a162
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(&quot;ASI: &quot; 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);
... ...