translate.c (e8325dc02d059685331d8607d5e620328bac594e) | translate.c (0faef01b3989bb1fb6e0ed73ffa909e77b79f780) |
---|---|
1/* 2 SPARC translation 3 4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at> 5 Copyright (C) 2003-2005 Fabrice Bellard 6 7 This library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Lesser General Public --- 24 unchanged lines hidden (view full) --- 33#include "asi.h" 34 35#define HELPER_H "helper.h" 36#include "exec/helper-info.c.inc" 37#undef HELPER_H 38 39#ifdef TARGET_SPARC64 40# define gen_helper_rdpsr(D, E) qemu_build_not_reached() | 1/* 2 SPARC translation 3 4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at> 5 Copyright (C) 2003-2005 Fabrice Bellard 6 7 This library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Lesser General Public --- 24 unchanged lines hidden (view full) --- 33#include "asi.h" 34 35#define HELPER_H "helper.h" 36#include "exec/helper-info.c.inc" 37#undef HELPER_H 38 39#ifdef TARGET_SPARC64 40# define gen_helper_rdpsr(D, E) qemu_build_not_reached() |
41# define gen_helper_power_down(E) qemu_build_not_reached() |
|
41#else | 42#else |
43# define gen_helper_clear_softint(E, S) qemu_build_not_reached() |
|
42# define gen_helper_flushw(E) qemu_build_not_reached() 43# define gen_helper_rdccr(D, E) qemu_build_not_reached() 44# define gen_helper_rdcwp(D, E) qemu_build_not_reached() | 44# define gen_helper_flushw(E) qemu_build_not_reached() 45# define gen_helper_rdccr(D, E) qemu_build_not_reached() 46# define gen_helper_rdcwp(D, E) qemu_build_not_reached() |
47# define gen_helper_set_softint(E, S) qemu_build_not_reached() |
|
45# define gen_helper_tick_get_count(D, E, T, C) qemu_build_not_reached() | 48# define gen_helper_tick_get_count(D, E, T, C) qemu_build_not_reached() |
49# define gen_helper_wrccr(E, S) qemu_build_not_reached() 50# define gen_helper_write_softint(E, S) qemu_build_not_reached() |
|
46# define MAXTL_MASK 0 47#endif 48 49/* Dynamic PC, must exit to main loop. */ 50#define DYNAMIC_PC 1 51/* Dynamic PC, one of two values according to jump_pc[T2]. */ 52#define JUMP_PC 2 53/* Dynamic PC, may lookup next TB. */ --- 2807 unchanged lines hidden (view full) --- 2861#define TRANS(NAME, AVAIL, FUNC, ...) \ 2862 static bool trans_##NAME(DisasContext *dc, arg_##NAME *a) \ 2863 { return avail_##AVAIL(dc) && FUNC(dc, __VA_ARGS__); } 2864 2865#define avail_ALL(C) true 2866#ifdef TARGET_SPARC64 2867# define avail_32(C) false 2868# define avail_ASR17(C) false | 51# define MAXTL_MASK 0 52#endif 53 54/* Dynamic PC, must exit to main loop. */ 55#define DYNAMIC_PC 1 56/* Dynamic PC, one of two values according to jump_pc[T2]. */ 57#define JUMP_PC 2 58/* Dynamic PC, may lookup next TB. */ --- 2807 unchanged lines hidden (view full) --- 2866#define TRANS(NAME, AVAIL, FUNC, ...) \ 2867 static bool trans_##NAME(DisasContext *dc, arg_##NAME *a) \ 2868 { return avail_##AVAIL(dc) && FUNC(dc, __VA_ARGS__); } 2869 2870#define avail_ALL(C) true 2871#ifdef TARGET_SPARC64 2872# define avail_32(C) false 2873# define avail_ASR17(C) false |
2874# define avail_POWERDOWN(C) false |
|
2869# define avail_64(C) true 2870# define avail_GL(C) ((C)->def->features & CPU_FEATURE_GL) 2871# define avail_HYPV(C) ((C)->def->features & CPU_FEATURE_HYPV) 2872#else 2873# define avail_32(C) true 2874# define avail_ASR17(C) ((C)->def->features & CPU_FEATURE_ASR17) | 2875# define avail_64(C) true 2876# define avail_GL(C) ((C)->def->features & CPU_FEATURE_GL) 2877# define avail_HYPV(C) ((C)->def->features & CPU_FEATURE_HYPV) 2878#else 2879# define avail_32(C) true 2880# define avail_ASR17(C) ((C)->def->features & CPU_FEATURE_ASR17) |
2881# define avail_POWERDOWN(C) ((C)->def->features & CPU_FEATURE_POWERDOWN) |
|
2875# define avail_64(C) false 2876# define avail_GL(C) false 2877# define avail_HYPV(C) false 2878#endif 2879 2880/* Default case for non jump instructions. */ 2881static bool advance_pc(DisasContext *dc) 2882{ --- 189 unchanged lines hidden (view full) --- 3072{ 3073 /* Special-case %g0 because that's the canonical nop. */ 3074 if (a->rd) { 3075 gen_store_gpr(dc, a->rd, tcg_constant_tl((uint32_t)a->i << 10)); 3076 } 3077 return advance_pc(dc); 3078} 3079 | 2882# define avail_64(C) false 2883# define avail_GL(C) false 2884# define avail_HYPV(C) false 2885#endif 2886 2887/* Default case for non jump instructions. */ 2888static bool advance_pc(DisasContext *dc) 2889{ --- 189 unchanged lines hidden (view full) --- 3079{ 3080 /* Special-case %g0 because that's the canonical nop. */ 3081 if (a->rd) { 3082 gen_store_gpr(dc, a->rd, tcg_constant_tl((uint32_t)a->i << 10)); 3083 } 3084 return advance_pc(dc); 3085} 3086 |
3087/* 3088 * Major Opcode 10 -- integer, floating-point, vis, and system insns. 3089 */ 3090 |
|
3080static bool do_tcc(DisasContext *dc, int cond, int cc, 3081 int rs1, bool imm, int rs2_or_imm) 3082{ 3083 int mask = ((dc->def->features & CPU_FEATURE_HYPV) && supervisor(dc) 3084 ? UA2005_HTRAP_MASK : V8_TRAP_MASK); 3085 DisasCompare cmp; 3086 TCGLabel *lab; 3087 TCGv_i32 trap; --- 480 unchanged lines hidden (view full) --- 3568{ 3569 if (avail_64(dc)) { 3570 gen_helper_flushw(tcg_env); 3571 return advance_pc(dc); 3572 } 3573 return false; 3574} 3575 | 3091static bool do_tcc(DisasContext *dc, int cond, int cc, 3092 int rs1, bool imm, int rs2_or_imm) 3093{ 3094 int mask = ((dc->def->features & CPU_FEATURE_HYPV) && supervisor(dc) 3095 ? UA2005_HTRAP_MASK : V8_TRAP_MASK); 3096 DisasCompare cmp; 3097 TCGLabel *lab; 3098 TCGv_i32 trap; --- 480 unchanged lines hidden (view full) --- 3579{ 3580 if (avail_64(dc)) { 3581 gen_helper_flushw(tcg_env); 3582 return advance_pc(dc); 3583 } 3584 return false; 3585} 3586 |
3587static bool do_wr_special(DisasContext *dc, arg_r_r_ri *a, bool priv, 3588 void (*func)(DisasContext *, TCGv)) 3589{ 3590 TCGv src; 3591 3592 /* For simplicity, we under-decoded the rs2 form. */ 3593 if (!a->imm && (a->rs2_or_imm & ~0x1f)) { 3594 return false; 3595 } 3596 if (!priv) { 3597 return raise_priv(dc); 3598 } 3599 3600 if (a->rs1 == 0 && (a->imm || a->rs2_or_imm == 0)) { 3601 src = tcg_constant_tl(a->rs2_or_imm); 3602 } else { 3603 TCGv src1 = gen_load_gpr(dc, a->rs1); 3604 if (a->rs2_or_imm == 0) { 3605 src = src1; 3606 } else { 3607 src = tcg_temp_new(); 3608 if (a->imm) { 3609 tcg_gen_xori_tl(src, src1, a->rs2_or_imm); 3610 } else { 3611 tcg_gen_xor_tl(src, src1, gen_load_gpr(dc, a->rs2_or_imm)); 3612 } 3613 } 3614 } 3615 func(dc, src); 3616 return advance_pc(dc); 3617} 3618 3619static void do_wry(DisasContext *dc, TCGv src) 3620{ 3621 tcg_gen_ext32u_tl(cpu_y, src); 3622} 3623 3624TRANS(WRY, ALL, do_wr_special, a, true, do_wry) 3625 3626static void do_wrccr(DisasContext *dc, TCGv src) 3627{ 3628 gen_helper_wrccr(tcg_env, src); 3629} 3630 3631TRANS(WRCCR, 64, do_wr_special, a, true, do_wrccr) 3632 3633static void do_wrasi(DisasContext *dc, TCGv src) 3634{ 3635 TCGv tmp = tcg_temp_new(); 3636 3637 tcg_gen_ext8u_tl(tmp, src); 3638 tcg_gen_st32_tl(tmp, tcg_env, env64_field_offsetof(asi)); 3639 /* End TB to notice changed ASI. */ 3640 dc->base.is_jmp = DISAS_EXIT; 3641} 3642 3643TRANS(WRASI, 64, do_wr_special, a, true, do_wrasi) 3644 3645static void do_wrfprs(DisasContext *dc, TCGv src) 3646{ 3647#ifdef TARGET_SPARC64 3648 tcg_gen_trunc_tl_i32(cpu_fprs, src); 3649 dc->fprs_dirty = 0; 3650 dc->base.is_jmp = DISAS_EXIT; 3651#else 3652 qemu_build_not_reached(); 3653#endif 3654} 3655 3656TRANS(WRFPRS, 64, do_wr_special, a, true, do_wrfprs) 3657 3658static void do_wrgsr(DisasContext *dc, TCGv src) 3659{ 3660 gen_trap_ifnofpu(dc); 3661 tcg_gen_mov_tl(cpu_gsr, src); 3662} 3663 3664TRANS(WRGSR, 64, do_wr_special, a, true, do_wrgsr) 3665 3666static void do_wrsoftint_set(DisasContext *dc, TCGv src) 3667{ 3668 gen_helper_set_softint(tcg_env, src); 3669} 3670 3671TRANS(WRSOFTINT_SET, 64, do_wr_special, a, supervisor(dc), do_wrsoftint_set) 3672 3673static void do_wrsoftint_clr(DisasContext *dc, TCGv src) 3674{ 3675 gen_helper_clear_softint(tcg_env, src); 3676} 3677 3678TRANS(WRSOFTINT_CLR, 64, do_wr_special, a, supervisor(dc), do_wrsoftint_clr) 3679 3680static void do_wrsoftint(DisasContext *dc, TCGv src) 3681{ 3682 gen_helper_write_softint(tcg_env, src); 3683} 3684 3685TRANS(WRSOFTINT, 64, do_wr_special, a, supervisor(dc), do_wrsoftint) 3686 3687static void do_wrtick_cmpr(DisasContext *dc, TCGv src) 3688{ 3689#ifdef TARGET_SPARC64 3690 TCGv_ptr r_tickptr = tcg_temp_new_ptr(); 3691 3692 tcg_gen_mov_tl(cpu_tick_cmpr, src); 3693 tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, tick)); 3694 translator_io_start(&dc->base); 3695 gen_helper_tick_set_limit(r_tickptr, cpu_tick_cmpr); 3696 /* End TB to handle timer interrupt */ 3697 dc->base.is_jmp = DISAS_EXIT; 3698#else 3699 qemu_build_not_reached(); 3700#endif 3701} 3702 3703TRANS(WRTICK_CMPR, 64, do_wr_special, a, supervisor(dc), do_wrtick_cmpr) 3704 3705static void do_wrstick(DisasContext *dc, TCGv src) 3706{ 3707#ifdef TARGET_SPARC64 3708 TCGv_ptr r_tickptr = tcg_temp_new_ptr(); 3709 3710 tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, stick)); 3711 translator_io_start(&dc->base); 3712 gen_helper_tick_set_count(r_tickptr, src); 3713 /* End TB to handle timer interrupt */ 3714 dc->base.is_jmp = DISAS_EXIT; 3715#else 3716 qemu_build_not_reached(); 3717#endif 3718} 3719 3720TRANS(WRSTICK, 64, do_wr_special, a, supervisor(dc), do_wrstick) 3721 3722static void do_wrstick_cmpr(DisasContext *dc, TCGv src) 3723{ 3724#ifdef TARGET_SPARC64 3725 TCGv_ptr r_tickptr = tcg_temp_new_ptr(); 3726 3727 tcg_gen_mov_tl(cpu_stick_cmpr, src); 3728 tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, stick)); 3729 translator_io_start(&dc->base); 3730 gen_helper_tick_set_limit(r_tickptr, cpu_stick_cmpr); 3731 /* End TB to handle timer interrupt */ 3732 dc->base.is_jmp = DISAS_EXIT; 3733#else 3734 qemu_build_not_reached(); 3735#endif 3736} 3737 3738TRANS(WRSTICK_CMPR, 64, do_wr_special, a, supervisor(dc), do_wrstick_cmpr) 3739 3740static void do_wrpowerdown(DisasContext *dc, TCGv src) 3741{ 3742 save_state(dc); 3743 gen_helper_power_down(tcg_env); 3744} 3745 3746TRANS(WRPOWERDOWN, POWERDOWN, do_wr_special, a, supervisor(dc), do_wrpowerdown) 3747 3748static bool trans_NOP_v7(DisasContext *dc, arg_NOP_v7 *a) 3749{ 3750 /* 3751 * TODO: Need a feature bit for sparcv8. 3752 * In the meantime, treat all 32-bit cpus like sparcv7. 3753 */ 3754 if (avail_32(dc)) { 3755 return advance_pc(dc); 3756 } 3757 return false; 3758} 3759 |
|
3576#define CHECK_IU_FEATURE(dc, FEATURE) \ 3577 if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \ 3578 goto illegal_insn; 3579#define CHECK_FPU_FEATURE(dc, FEATURE) \ 3580 if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \ 3581 goto nfpu_insn; 3582 3583/* before an instruction, dc->pc must be static */ --- 644 unchanged lines hidden (view full) --- 4228 cpu_tmp0 = tcg_temp_new(); 4229 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f); 4230 tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0); 4231 } 4232 gen_store_gpr(dc, rd, cpu_dst); 4233 break; 4234#endif 4235 case 0x30: | 3760#define CHECK_IU_FEATURE(dc, FEATURE) \ 3761 if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \ 3762 goto illegal_insn; 3763#define CHECK_FPU_FEATURE(dc, FEATURE) \ 3764 if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \ 3765 goto nfpu_insn; 3766 3767/* before an instruction, dc->pc must be static */ --- 644 unchanged lines hidden (view full) --- 4412 cpu_tmp0 = tcg_temp_new(); 4413 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f); 4414 tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0); 4415 } 4416 gen_store_gpr(dc, rd, cpu_dst); 4417 break; 4418#endif 4419 case 0x30: |
4236 { 4237 cpu_tmp0 = tcg_temp_new(); 4238 switch(rd) { 4239 case 0: /* wry */ 4240 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); 4241 tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff); 4242 break; 4243#ifndef TARGET_SPARC64 4244 case 0x01 ... 0x0f: /* undefined in the 4245 SPARCv8 manual, nop 4246 on the microSPARC 4247 II */ 4248 case 0x10 ... 0x1f: /* implementation-dependent 4249 in the SPARCv8 4250 manual, nop on the 4251 microSPARC II */ 4252 if ((rd == 0x13) && (dc->def->features & 4253 CPU_FEATURE_POWERDOWN)) { 4254 /* LEON3 power-down */ 4255 save_state(dc); 4256 gen_helper_power_down(tcg_env); 4257 } 4258 break; 4259#else 4260 case 0x2: /* V9 wrccr */ 4261 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); 4262 gen_helper_wrccr(tcg_env, cpu_tmp0); 4263 tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS); 4264 dc->cc_op = CC_OP_FLAGS; 4265 break; 4266 case 0x3: /* V9 wrasi */ 4267 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); 4268 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xff); 4269 tcg_gen_st32_tl(cpu_tmp0, tcg_env, 4270 offsetof(CPUSPARCState, asi)); 4271 /* 4272 * End TB to notice changed ASI. 4273 * TODO: Could notice src1 = %g0 and IS_IMM, 4274 * update DisasContext and not exit the TB. 4275 */ 4276 save_state(dc); 4277 gen_op_next_insn(); 4278 tcg_gen_lookup_and_goto_ptr(); 4279 dc->base.is_jmp = DISAS_NORETURN; 4280 break; 4281 case 0x6: /* V9 wrfprs */ 4282 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); 4283 tcg_gen_trunc_tl_i32(cpu_fprs, cpu_tmp0); 4284 dc->fprs_dirty = 0; 4285 save_state(dc); 4286 gen_op_next_insn(); 4287 tcg_gen_exit_tb(NULL, 0); 4288 dc->base.is_jmp = DISAS_NORETURN; 4289 break; 4290 case 0xf: /* V9 sir, nop if user */ | 4420 goto illegal_insn; /* WRASR in decodetree */ |
4291#if !defined(CONFIG_USER_ONLY) | 4421#if !defined(CONFIG_USER_ONLY) |
4292 if (supervisor(dc)) { 4293 ; // XXX 4294 } 4295#endif 4296 break; 4297 case 0x13: /* Graphics Status */ 4298 if (gen_trap_ifnofpu(dc)) { 4299 goto jmp_insn; 4300 } 4301 tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2); 4302 break; 4303 case 0x14: /* Softint set */ 4304 if (!supervisor(dc)) 4305 goto illegal_insn; 4306 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); 4307 gen_helper_set_softint(tcg_env, cpu_tmp0); 4308 break; 4309 case 0x15: /* Softint clear */ 4310 if (!supervisor(dc)) 4311 goto illegal_insn; 4312 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); 4313 gen_helper_clear_softint(tcg_env, cpu_tmp0); 4314 break; 4315 case 0x16: /* Softint write */ 4316 if (!supervisor(dc)) 4317 goto illegal_insn; 4318 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); 4319 gen_helper_write_softint(tcg_env, cpu_tmp0); 4320 break; 4321 case 0x17: /* Tick compare */ 4322#if !defined(CONFIG_USER_ONLY) 4323 if (!supervisor(dc)) 4324 goto illegal_insn; 4325#endif 4326 { 4327 TCGv_ptr r_tickptr; 4328 4329 tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1, 4330 cpu_src2); 4331 r_tickptr = tcg_temp_new_ptr(); 4332 tcg_gen_ld_ptr(r_tickptr, tcg_env, 4333 offsetof(CPUSPARCState, tick)); 4334 translator_io_start(&dc->base); 4335 gen_helper_tick_set_limit(r_tickptr, 4336 cpu_tick_cmpr); 4337 /* End TB to handle timer interrupt */ 4338 dc->base.is_jmp = DISAS_EXIT; 4339 } 4340 break; 4341 case 0x18: /* System tick */ 4342#if !defined(CONFIG_USER_ONLY) 4343 if (!supervisor(dc)) 4344 goto illegal_insn; 4345#endif 4346 { 4347 TCGv_ptr r_tickptr; 4348 4349 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, 4350 cpu_src2); 4351 r_tickptr = tcg_temp_new_ptr(); 4352 tcg_gen_ld_ptr(r_tickptr, tcg_env, 4353 offsetof(CPUSPARCState, stick)); 4354 translator_io_start(&dc->base); 4355 gen_helper_tick_set_count(r_tickptr, 4356 cpu_tmp0); 4357 /* End TB to handle timer interrupt */ 4358 dc->base.is_jmp = DISAS_EXIT; 4359 } 4360 break; 4361 case 0x19: /* System tick compare */ 4362#if !defined(CONFIG_USER_ONLY) 4363 if (!supervisor(dc)) 4364 goto illegal_insn; 4365#endif 4366 { 4367 TCGv_ptr r_tickptr; 4368 4369 tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1, 4370 cpu_src2); 4371 r_tickptr = tcg_temp_new_ptr(); 4372 tcg_gen_ld_ptr(r_tickptr, tcg_env, 4373 offsetof(CPUSPARCState, stick)); 4374 translator_io_start(&dc->base); 4375 gen_helper_tick_set_limit(r_tickptr, 4376 cpu_stick_cmpr); 4377 /* End TB to handle timer interrupt */ 4378 dc->base.is_jmp = DISAS_EXIT; 4379 } 4380 break; 4381 4382 case 0x10: /* Performance Control */ 4383 case 0x11: /* Performance Instrumentation 4384 Counter */ 4385 case 0x12: /* Dispatch Control */ 4386#endif 4387 default: 4388 goto illegal_insn; 4389 } 4390 } 4391 break; 4392#if !defined(CONFIG_USER_ONLY) | |
4393 case 0x31: /* wrpsr, V9 saved, restored */ 4394 { 4395 if (!supervisor(dc)) 4396 goto priv_insn; 4397#ifdef TARGET_SPARC64 4398 switch (rd) { 4399 case 0: 4400 gen_helper_saved(tcg_env); --- 1558 unchanged lines hidden --- | 4422 case 0x31: /* wrpsr, V9 saved, restored */ 4423 { 4424 if (!supervisor(dc)) 4425 goto priv_insn; 4426#ifdef TARGET_SPARC64 4427 switch (rd) { 4428 case 0: 4429 gen_helper_saved(tcg_env); --- 1558 unchanged lines hidden --- |