Revision 2cade6a3 target-sparc/translate.c
b/target-sparc/translate.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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); |
Also available in: Unified diff