diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2012-10-06 18:54:46 +0200 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2012-10-06 18:54:46 +0200 |
commit | 046dbab95f33e007428190610d638d2fcaf37fdf (patch) | |
tree | 6110b604ea1eaa50406e5ece905cfa0700110d31 | |
parent | 048d3612a51b3da45081091b734f93428925ebf8 (diff) | |
parent | 1273d9ca09e91bb290d10f704055f6abec363dd6 (diff) |
Merge branch 'target-arm.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm
* 'target-arm.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm:
target-arm: Drop unused DECODE_CPREG_CRN macro
target-arm: use deposit instead of hardcoded version
target-arm: mark a few integer helpers const and pure
target-arm: convert sar, shl and shr helpers to TCG
target-arm: convert add_cc and sub_cc helpers to TCG
target-arm: use globals for CC flags
target-arm: Reinstate display of VFP registers in cpu_dump_state
cpu_dump_state: move DUMP_FPU and DUMP_CCOP flags from x86-only to generic
-rw-r--r-- | cpu-all.h | 3 | ||||
-rw-r--r-- | cpu-exec.c | 2 | ||||
-rw-r--r-- | cpus.c | 6 | ||||
-rw-r--r-- | exec.c | 12 | ||||
-rw-r--r-- | monitor.c | 8 | ||||
-rw-r--r-- | target-arm/cpu.h | 2 | ||||
-rw-r--r-- | target-arm/helper.h | 24 | ||||
-rw-r--r-- | target-arm/op_helper.c | 44 | ||||
-rw-r--r-- | target-arm/translate.c | 302 | ||||
-rw-r--r-- | target-i386/cpu.c | 2 | ||||
-rw-r--r-- | target-i386/cpu.h | 4 | ||||
-rw-r--r-- | target-i386/helper.c | 4 | ||||
-rw-r--r-- | target-i386/seg_helper.c | 4 | ||||
-rw-r--r-- | target-i386/smm_helper.c | 4 |
14 files changed, 183 insertions, 238 deletions
@@ -356,6 +356,9 @@ CPUArchState *cpu_copy(CPUArchState *env); CPUArchState *qemu_get_cpu(int cpu); #define CPU_DUMP_CODE 0x00010000 +#define CPU_DUMP_FPU 0x00020000 /* dump FPU register state, not just integer */ +/* dump info about TCG QEMU's condition code optimization state */ +#define CPU_DUMP_CCOP 0x00040000 void cpu_dump_state(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf, int flags); diff --git a/cpu-exec.c b/cpu-exec.c index 134b3c4fcf..252da86882 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -552,7 +552,7 @@ int cpu_exec(CPUArchState *env) #if defined(TARGET_I386) env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP) | (DF & DF_MASK); - log_cpu_state(env, X86_DUMP_CCOP); + log_cpu_state(env, CPU_DUMP_CCOP); env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); #elif defined(TARGET_M68K) cpu_m68k_flush_flags(env, env->cc_op); @@ -395,11 +395,7 @@ void hw_error(const char *fmt, ...) fprintf(stderr, "\n"); for(env = first_cpu; env != NULL; env = env->next_cpu) { fprintf(stderr, "CPU #%d:\n", env->cpu_index); -#ifdef TARGET_I386 - cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU); -#else - cpu_dump_state(env, stderr, fprintf, 0); -#endif + cpu_dump_state(env, stderr, fprintf, CPU_DUMP_FPU); } va_end(ap); abort(); @@ -1742,20 +1742,12 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...) fprintf(stderr, "qemu: fatal: "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); -#ifdef TARGET_I386 - cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP); -#else - cpu_dump_state(env, stderr, fprintf, 0); -#endif + cpu_dump_state(env, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP); if (qemu_log_enabled()) { qemu_log("qemu: fatal: "); qemu_log_vprintf(fmt, ap2); qemu_log("\n"); -#ifdef TARGET_I386 - log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP); -#else - log_cpu_state(env, 0); -#endif + log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP); qemu_log_flush(); qemu_log_close(); } @@ -898,13 +898,7 @@ static void do_info_registers(Monitor *mon) { CPUArchState *env; env = mon_get_cpu(); -#ifdef TARGET_I386 - cpu_dump_state(env, (FILE *)mon, monitor_fprintf, - X86_DUMP_FPU); -#else - cpu_dump_state(env, (FILE *)mon, monitor_fprintf, - 0); -#endif + cpu_dump_state(env, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU); } static void do_info_jit(Monitor *mon) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 7fac94f817..ff4de10f12 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -423,8 +423,6 @@ void armv7m_nvic_complete_irq(void *opaque, int irq); (((cp) << 16) | ((is64) << 15) | ((crn) << 11) | \ ((crm) << 7) | ((opc1) << 3) | (opc2)) -#define DECODE_CPREG_CRN(enc) (((enc) >> 7) & 0xf) - /* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a * special-behaviour cp reg and bits [15..8] indicate what behaviour * it has. Otherwise it is a simple cp reg, where CONST indicates that diff --git a/target-arm/helper.h b/target-arm/helper.h index afdb2b5b1a..8b9adf1311 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -1,8 +1,8 @@ #include "def-helper.h" -DEF_HELPER_1(clz, i32, i32) -DEF_HELPER_1(sxtb16, i32, i32) -DEF_HELPER_1(uxtb16, i32, i32) +DEF_HELPER_FLAGS_1(clz, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32) +DEF_HELPER_FLAGS_1(sxtb16, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32) +DEF_HELPER_FLAGS_1(uxtb16, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32) DEF_HELPER_3(add_setq, i32, env, i32, i32) DEF_HELPER_3(add_saturate, i32, env, i32, i32) @@ -10,10 +10,10 @@ DEF_HELPER_3(sub_saturate, i32, env, i32, i32) DEF_HELPER_3(add_usaturate, i32, env, i32, i32) DEF_HELPER_3(sub_usaturate, i32, env, i32, i32) DEF_HELPER_2(double_saturate, i32, env, s32) -DEF_HELPER_2(sdiv, s32, s32, s32) -DEF_HELPER_2(udiv, i32, i32, i32) -DEF_HELPER_1(rbit, i32, i32) -DEF_HELPER_1(abs, i32, i32) +DEF_HELPER_FLAGS_2(sdiv, TCG_CALL_CONST | TCG_CALL_PURE, s32, s32, s32) +DEF_HELPER_FLAGS_2(udiv, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32) +DEF_HELPER_FLAGS_1(rbit, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32) +DEF_HELPER_FLAGS_1(abs, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32) #define PAS_OP(pfx) \ DEF_HELPER_3(pfx ## add8, i32, i32, i32, ptr) \ @@ -45,11 +45,12 @@ DEF_HELPER_3(usat, i32, env, i32, i32) DEF_HELPER_3(ssat16, i32, env, i32, i32) DEF_HELPER_3(usat16, i32, env, i32, i32) -DEF_HELPER_2(usad8, i32, i32, i32) +DEF_HELPER_FLAGS_2(usad8, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32) DEF_HELPER_1(logicq_cc, i32, i64) -DEF_HELPER_3(sel_flags, i32, i32, i32, i32) +DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_CONST | TCG_CALL_PURE, + i32, i32, i32, i32) DEF_HELPER_2(exception, void, env, i32) DEF_HELPER_1(wfi, void, env) @@ -142,14 +143,9 @@ DEF_HELPER_2(recpe_u32, i32, i32, env) DEF_HELPER_2(rsqrte_u32, i32, i32, env) DEF_HELPER_5(neon_tbl, i32, env, i32, i32, i32, i32) -DEF_HELPER_3(add_cc, i32, env, i32, i32) DEF_HELPER_3(adc_cc, i32, env, i32, i32) -DEF_HELPER_3(sub_cc, i32, env, i32, i32) DEF_HELPER_3(sbc_cc, i32, env, i32, i32) -DEF_HELPER_3(shl, i32, env, i32, i32) -DEF_HELPER_3(shr, i32, env, i32, i32) -DEF_HELPER_3(sar, i32, env, i32, i32) DEF_HELPER_3(shl_cc, i32, env, i32, i32) DEF_HELPER_3(shr_cc, i32, env, i32, i32) DEF_HELPER_3(sar_cc, i32, env, i32, i32) diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index f13fc3ae57..aef592ab8d 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -323,16 +323,6 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip) The only way to do that in TCG is a conditional branch, which clobbers all our temporaries. For now implement these as helper functions. */ -uint32_t HELPER (add_cc)(CPUARMState *env, uint32_t a, uint32_t b) -{ - uint32_t result; - result = a + b; - env->NF = env->ZF = result; - env->CF = result < a; - env->VF = (a ^ b ^ -1) & (a ^ result); - return result; -} - uint32_t HELPER(adc_cc)(CPUARMState *env, uint32_t a, uint32_t b) { uint32_t result; @@ -348,16 +338,6 @@ uint32_t HELPER(adc_cc)(CPUARMState *env, uint32_t a, uint32_t b) return result; } -uint32_t HELPER(sub_cc)(CPUARMState *env, uint32_t a, uint32_t b) -{ - uint32_t result; - result = a - b; - env->NF = env->ZF = result; - env->CF = a >= b; - env->VF = (a ^ b) & (a ^ result); - return result; -} - uint32_t HELPER(sbc_cc)(CPUARMState *env, uint32_t a, uint32_t b) { uint32_t result; @@ -375,30 +355,6 @@ uint32_t HELPER(sbc_cc)(CPUARMState *env, uint32_t a, uint32_t b) /* Similarly for variable shift instructions. */ -uint32_t HELPER(shl)(CPUARMState *env, uint32_t x, uint32_t i) -{ - int shift = i & 0xff; - if (shift >= 32) - return 0; - return x << shift; -} - -uint32_t HELPER(shr)(CPUARMState *env, uint32_t x, uint32_t i) -{ - int shift = i & 0xff; - if (shift >= 32) - return 0; - return (uint32_t)x >> shift; -} - -uint32_t HELPER(sar)(CPUARMState *env, uint32_t x, uint32_t i) -{ - int shift = i & 0xff; - if (shift >= 32) - shift = 31; - return (int32_t)x >> shift; -} - uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i) { int shift = i & 0xff; diff --git a/target-arm/translate.c b/target-arm/translate.c index 5fded491ec..c6840b7832 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -85,6 +85,7 @@ static TCGv_ptr cpu_env; /* We reuse the same 64-bit temporaries for efficiency. */ static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; static TCGv_i32 cpu_R[16]; +static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF; static TCGv_i32 cpu_exclusive_addr; static TCGv_i32 cpu_exclusive_val; static TCGv_i32 cpu_exclusive_high; @@ -115,6 +116,11 @@ void arm_translate_init(void) offsetof(CPUARMState, regs[i]), regnames[i]); } + cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF"); + cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF"); + cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF"); + cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF"); + cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, exclusive_addr), "exclusive_addr"); cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0, @@ -271,15 +277,6 @@ static void gen_sbfx(TCGv var, int shift, int width) } } -/* Bitfield insertion. Insert val into base. Clobbers base and val. */ -static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask) -{ - tcg_gen_andi_i32(val, val, mask); - tcg_gen_shli_i32(val, val, shift); - tcg_gen_andi_i32(base, base, ~(mask << shift)); - tcg_gen_or_i32(dest, base, val); -} - /* Return (b << 32) + a. Mark inputs as dead */ static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b) { @@ -369,53 +366,100 @@ static void gen_add16(TCGv t0, TCGv t1) tcg_temp_free_i32(t1); } -#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, CF)) - /* Set CF to the top bit of var. */ static void gen_set_CF_bit31(TCGv var) { - TCGv tmp = tcg_temp_new_i32(); - tcg_gen_shri_i32(tmp, var, 31); - gen_set_CF(tmp); - tcg_temp_free_i32(tmp); + tcg_gen_shri_i32(cpu_CF, var, 31); } /* Set N and Z flags from var. */ static inline void gen_logic_CC(TCGv var) { - tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, NF)); - tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, ZF)); + tcg_gen_mov_i32(cpu_NF, var); + tcg_gen_mov_i32(cpu_ZF, var); } /* T0 += T1 + CF. */ static void gen_adc(TCGv t0, TCGv t1) { - TCGv tmp; tcg_gen_add_i32(t0, t0, t1); - tmp = load_cpu_field(CF); - tcg_gen_add_i32(t0, t0, tmp); - tcg_temp_free_i32(tmp); + tcg_gen_add_i32(t0, t0, cpu_CF); } /* dest = T0 + T1 + CF. */ static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1) { - TCGv tmp; tcg_gen_add_i32(dest, t0, t1); - tmp = load_cpu_field(CF); - tcg_gen_add_i32(dest, dest, tmp); - tcg_temp_free_i32(tmp); + tcg_gen_add_i32(dest, dest, cpu_CF); } /* dest = T0 - T1 + CF - 1. */ static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) { - TCGv tmp; tcg_gen_sub_i32(dest, t0, t1); - tmp = load_cpu_field(CF); - tcg_gen_add_i32(dest, dest, tmp); + tcg_gen_add_i32(dest, dest, cpu_CF); tcg_gen_subi_i32(dest, dest, 1); +} + +/* dest = T0 + T1. Compute C, N, V and Z flags */ +static void gen_add_CC(TCGv dest, TCGv t0, TCGv t1) +{ + TCGv tmp; + tcg_gen_add_i32(cpu_NF, t0, t1); + tcg_gen_mov_i32(cpu_ZF, cpu_NF); + tcg_gen_setcond_i32(TCG_COND_LTU, cpu_CF, cpu_NF, t0); + tcg_gen_xor_i32(cpu_VF, cpu_NF, t0); + tmp = tcg_temp_new_i32(); + tcg_gen_xor_i32(tmp, t0, t1); + tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp); tcg_temp_free_i32(tmp); + tcg_gen_mov_i32(dest, cpu_NF); +} + +/* dest = T0 - T1. Compute C, N, V and Z flags */ +static void gen_sub_CC(TCGv dest, TCGv t0, TCGv t1) +{ + TCGv tmp; + tcg_gen_sub_i32(cpu_NF, t0, t1); + tcg_gen_mov_i32(cpu_ZF, cpu_NF); + tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1); + tcg_gen_xor_i32(cpu_VF, cpu_NF, t0); + tmp = tcg_temp_new_i32(); + tcg_gen_xor_i32(tmp, t0, t1); + tcg_gen_and_i32(cpu_VF, cpu_VF, tmp); + tcg_temp_free_i32(tmp); + tcg_gen_mov_i32(dest, cpu_NF); +} + +#define GEN_SHIFT(name) \ +static void gen_##name(TCGv dest, TCGv t0, TCGv t1) \ +{ \ + TCGv tmp1, tmp2, tmp3; \ + tmp1 = tcg_temp_new_i32(); \ + tcg_gen_andi_i32(tmp1, t1, 0xff); \ + tmp2 = tcg_const_i32(0); \ + tmp3 = tcg_const_i32(0x1f); \ + tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \ + tcg_temp_free_i32(tmp3); \ + tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \ + tcg_gen_##name##_i32(dest, tmp2, tmp1); \ + tcg_temp_free_i32(tmp2); \ + tcg_temp_free_i32(tmp1); \ +} +GEN_SHIFT(shl) +GEN_SHIFT(shr) +#undef GEN_SHIFT + +static void gen_sar(TCGv dest, TCGv t0, TCGv t1) +{ + TCGv tmp1, tmp2; + tmp1 = tcg_temp_new_i32(); + tcg_gen_andi_i32(tmp1, t1, 0xff); + tmp2 = tcg_const_i32(0x1f); + tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1); + tcg_temp_free_i32(tmp2); + tcg_gen_sar_i32(dest, t0, tmp1); + tcg_temp_free_i32(tmp1); } /* FIXME: Implement this natively. */ @@ -423,16 +467,14 @@ static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) static void shifter_out_im(TCGv var, int shift) { - TCGv tmp = tcg_temp_new_i32(); if (shift == 0) { - tcg_gen_andi_i32(tmp, var, 1); + tcg_gen_andi_i32(cpu_CF, var, 1); } else { - tcg_gen_shri_i32(tmp, var, shift); - if (shift != 31) - tcg_gen_andi_i32(tmp, tmp, 1); + tcg_gen_shri_i32(cpu_CF, var, shift); + if (shift != 31) { + tcg_gen_andi_i32(cpu_CF, cpu_CF, 1); + } } - gen_set_CF(tmp); - tcg_temp_free_i32(tmp); } /* Shift by immediate. Includes special handling for shift == 0. */ @@ -449,8 +491,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags) case 1: /* LSR */ if (shift == 0) { if (flags) { - tcg_gen_shri_i32(var, var, 31); - gen_set_CF(var); + tcg_gen_shri_i32(cpu_CF, var, 31); } tcg_gen_movi_i32(var, 0); } else { @@ -474,11 +515,11 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags) shifter_out_im(var, shift - 1); tcg_gen_rotri_i32(var, var, shift); break; } else { - TCGv tmp = load_cpu_field(CF); + TCGv tmp = tcg_temp_new_i32(); if (flags) shifter_out_im(var, 0); tcg_gen_shri_i32(var, var, 1); - tcg_gen_shli_i32(tmp, tmp, 31); + tcg_gen_shli_i32(tmp, cpu_CF, 31); tcg_gen_or_i32(var, var, tmp); tcg_temp_free_i32(tmp); } @@ -497,9 +538,15 @@ static inline void gen_arm_shift_reg(TCGv var, int shiftop, } } else { switch (shiftop) { - case 0: gen_helper_shl(var, cpu_env, var, shift); break; - case 1: gen_helper_shr(var, cpu_env, var, shift); break; - case 2: gen_helper_sar(var, cpu_env, var, shift); break; + case 0: + gen_shl(var, var, shift); + break; + case 1: + gen_shr(var, var, shift); + break; + case 2: + gen_sar(var, var, shift); + break; case 3: tcg_gen_andi_i32(shift, shift, 0x1f); tcg_gen_rotr_i32(var, var, shift); break; } @@ -603,99 +650,75 @@ static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b) static void gen_test_cc(int cc, int label) { TCGv tmp; - TCGv tmp2; int inv; switch (cc) { case 0: /* eq: Z */ - tmp = load_cpu_field(ZF); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label); break; case 1: /* ne: !Z */ - tmp = load_cpu_field(ZF); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label); + tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label); break; case 2: /* cs: C */ - tmp = load_cpu_field(CF); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label); + tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label); break; case 3: /* cc: !C */ - tmp = load_cpu_field(CF); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label); break; case 4: /* mi: N */ - tmp = load_cpu_field(NF); - tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); + tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label); break; case 5: /* pl: !N */ - tmp = load_cpu_field(NF); - tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); + tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label); break; case 6: /* vs: V */ - tmp = load_cpu_field(VF); - tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); + tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label); break; case 7: /* vc: !V */ - tmp = load_cpu_field(VF); - tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); + tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label); break; case 8: /* hi: C && !Z */ inv = gen_new_label(); - tmp = load_cpu_field(CF); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv); - tcg_temp_free_i32(tmp); - tmp = load_cpu_field(ZF); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv); + tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label); gen_set_label(inv); break; case 9: /* ls: !C || Z */ - tmp = load_cpu_field(CF); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); - tcg_temp_free_i32(tmp); - tmp = load_cpu_field(ZF); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label); break; case 10: /* ge: N == V -> N ^ V == 0 */ - tmp = load_cpu_field(VF); - tmp2 = load_cpu_field(NF); - tcg_gen_xor_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); + tmp = tcg_temp_new_i32(); + tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); + tcg_temp_free_i32(tmp); break; case 11: /* lt: N != V -> N ^ V != 0 */ - tmp = load_cpu_field(VF); - tmp2 = load_cpu_field(NF); - tcg_gen_xor_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); + tmp = tcg_temp_new_i32(); + tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); + tcg_temp_free_i32(tmp); break; case 12: /* gt: !Z && N == V */ inv = gen_new_label(); - tmp = load_cpu_field(ZF); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv); - tcg_temp_free_i32(tmp); - tmp = load_cpu_field(VF); - tmp2 = load_cpu_field(NF); - tcg_gen_xor_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv); + tmp = tcg_temp_new_i32(); + tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); + tcg_temp_free_i32(tmp); gen_set_label(inv); break; case 13: /* le: Z || N != V */ - tmp = load_cpu_field(ZF); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); - tcg_temp_free_i32(tmp); - tmp = load_cpu_field(VF); - tmp2 = load_cpu_field(NF); - tcg_gen_xor_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label); + tmp = tcg_temp_new_i32(); + tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); + tcg_temp_free_i32(tmp); break; default: fprintf(stderr, "Bad condition code 0x%x\n", cc); abort(); } - tcg_temp_free_i32(tmp); } static const uint8_t table_logic_cc[16] = { @@ -2628,12 +2651,12 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) switch (size) { case 0: tmp2 = neon_load_reg(rn, pass); - gen_bfi(tmp, tmp2, tmp, offset, 0xff); + tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8); tcg_temp_free_i32(tmp2); break; case 1: tmp2 = neon_load_reg(rn, pass); - gen_bfi(tmp, tmp2, tmp, offset, 0xffff); + tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16); tcg_temp_free_i32(tmp2); break; case 2: @@ -3989,7 +4012,8 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn) } if (size != 2) { tmp2 = neon_load_reg(rd, pass); - gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff); + tcg_gen_deposit_i32(tmp, tmp2, tmp, + shift, size ? 16 : 8); tcg_temp_free_i32(tmp2); } neon_store_reg(rd, pass, tmp); @@ -7005,11 +7029,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s) if (IS_USER(s)) { goto illegal_op; } - gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2); + gen_sub_CC(tmp, tmp, tmp2); gen_exception_return(s, tmp); } else { if (set_cc) { - gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2); + gen_sub_CC(tmp, tmp, tmp2); } else { tcg_gen_sub_i32(tmp, tmp, tmp2); } @@ -7018,7 +7042,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s) break; case 0x03: if (set_cc) { - gen_helper_sub_cc(tmp, cpu_env, tmp2, tmp); + gen_sub_CC(tmp, tmp2, tmp); } else { tcg_gen_sub_i32(tmp, tmp2, tmp); } @@ -7026,7 +7050,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s) break; case 0x04: if (set_cc) { - gen_helper_add_cc(tmp, cpu_env, tmp, tmp2); + gen_add_CC(tmp, tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); } @@ -7072,13 +7096,13 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s) break; case 0x0a: if (set_cc) { - gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2); + gen_sub_CC(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp); break; case 0x0b: if (set_cc) { - gen_helper_add_cc(tmp, cpu_env, tmp, tmp2); + gen_add_CC(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp); break; @@ -7593,7 +7617,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s) } if (i != 32) { tmp2 = load_reg(s, rd); - gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1); + tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i); tcg_temp_free_i32(tmp2); } store_reg(s, rd, tmp); @@ -7865,7 +7889,7 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCG break; case 8: /* add */ if (conds) - gen_helper_add_cc(t0, cpu_env, t0, t1); + gen_add_CC(t0, t0, t1); else tcg_gen_add_i32(t0, t0, t1); break; @@ -7883,13 +7907,13 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCG break; case 13: /* sub */ if (conds) - gen_helper_sub_cc(t0, cpu_env, t0, t1); + gen_sub_CC(t0, t0, t1); else tcg_gen_sub_i32(t0, t0, t1); break; case 14: /* rsb */ if (conds) - gen_helper_sub_cc(t0, cpu_env, t1, t0); + gen_sub_CC(t0, t1, t0); else tcg_gen_sub_i32(t0, t1, t0); break; @@ -8704,7 +8728,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw imm = imm + 1 - shift; if (imm != 32) { tmp2 = load_reg(s, rd); - gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1); + tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm); tcg_temp_free_i32(tmp2); } break; @@ -9017,12 +9041,12 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) if (s->condexec_mask) tcg_gen_sub_i32(tmp, tmp, tmp2); else - gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2); + gen_sub_CC(tmp, tmp, tmp2); } else { if (s->condexec_mask) tcg_gen_add_i32(tmp, tmp, tmp2); else - gen_helper_add_cc(tmp, cpu_env, tmp, tmp2); + gen_add_CC(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); @@ -9053,7 +9077,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) tcg_gen_movi_i32(tmp2, insn & 0xff); switch (op) { case 1: /* cmp */ - gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2); + gen_sub_CC(tmp, tmp, tmp2); tcg_temp_free_i32(tmp); tcg_temp_free_i32(tmp2); break; @@ -9061,7 +9085,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) if (s->condexec_mask) tcg_gen_add_i32(tmp, tmp, tmp2); else - gen_helper_add_cc(tmp, cpu_env, tmp, tmp2); + gen_add_CC(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; @@ -9069,7 +9093,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) if (s->condexec_mask) tcg_gen_sub_i32(tmp, tmp, tmp2); else - gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2); + gen_sub_CC(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; @@ -9105,7 +9129,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) case 1: /* cmp */ tmp = load_reg(s, rd); tmp2 = load_reg(s, rm); - gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2); + gen_sub_CC(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp); break; @@ -9166,7 +9190,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) break; case 0x2: /* lsl */ if (s->condexec_mask) { - gen_helper_shl(tmp2, cpu_env, tmp2, tmp); + gen_shl(tmp2, tmp2, tmp); } else { gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp); gen_logic_CC(tmp2); @@ -9174,7 +9198,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) break; case 0x3: /* lsr */ if (s->condexec_mask) { - gen_helper_shr(tmp2, cpu_env, tmp2, tmp); + gen_shr(tmp2, tmp2, tmp); } else { gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp); gen_logic_CC(tmp2); @@ -9182,7 +9206,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) break; case 0x4: /* asr */ if (s->condexec_mask) { - gen_helper_sar(tmp2, cpu_env, tmp2, tmp); + gen_sar(tmp2, tmp2, tmp); } else { gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp); gen_logic_CC(tmp2); @@ -9218,14 +9242,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) if (s->condexec_mask) tcg_gen_neg_i32(tmp, tmp2); else - gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2); + gen_sub_CC(tmp, tmp, tmp2); break; case 0xa: /* cmp */ - gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2); + gen_sub_CC(tmp, tmp, tmp2); rd = 16; break; case 0xb: /* cmn */ - gen_helper_add_cc(tmp, cpu_env, tmp, tmp2); + gen_add_CC(tmp, tmp, tmp2); rd = 16; break; case 0xc: /* orr */ @@ -9970,19 +9994,6 @@ void cpu_dump_state(CPUARMState *env, FILE *f, fprintf_function cpu_fprintf, int flags) { int i; -#if 0 - union { - uint32_t i; - float s; - } s0, s1; - CPU_DoubleU d; - /* ??? This assumes float64 and double have the same layout. - Oh well, it's only debug dumps. */ - union { - float64 f64; - double d; - } d0; -#endif uint32_t psr; for(i=0;i<16;i++) { @@ -10002,20 +10013,23 @@ void cpu_dump_state(CPUARMState *env, FILE *f, fprintf_function cpu_fprintf, psr & CPSR_T ? 'T' : 'A', cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26); -#if 0 - for (i = 0; i < 16; i++) { - d.d = env->vfp.regs[i]; - s0.i = d.l.lower; - s1.i = d.l.upper; - d0.f64 = d.d; - cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n", - i * 2, (int)s0.i, s0.s, - i * 2 + 1, (int)s1.i, s1.s, - i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower, - d0.d); + if (flags & CPU_DUMP_FPU) { + int numvfpregs = 0; + if (arm_feature(env, ARM_FEATURE_VFP)) { + numvfpregs += 16; + } + if (arm_feature(env, ARM_FEATURE_VFP3)) { + numvfpregs += 16; + } + for (i = 0; i < numvfpregs; i++) { + uint64_t v = float64_val(env->vfp.regs[i]); + cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n", + i * 2, (uint32_t)v, + i * 2 + 1, (uint32_t)(v >> 32), + i, v); + } + cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]); } - cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]); -#endif } void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index bb1e44eb01..f3708e63b7 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1759,7 +1759,7 @@ static void x86_cpu_reset(CPUState *s) if (qemu_loglevel_mask(CPU_LOG_RESET)) { qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); - log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP); + log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP); } xcc->parent_reset(s); diff --git a/target-i386/cpu.h b/target-i386/cpu.h index e4a7d5b6e4..871c270116 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -995,10 +995,6 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4); void cpu_smm_update(CPUX86State *env); uint64_t cpu_get_tsc(CPUX86State *env); -/* used to debug */ -#define X86_DUMP_FPU 0x0001 /* dump FPU state too */ -#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */ - #define TARGET_PAGE_BITS 12 #ifdef TARGET_X86_64 diff --git a/target-i386/helper.c b/target-i386/helper.c index c635667d60..2ee7c6d1b1 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -284,7 +284,7 @@ void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf, cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n", env->dr[6], env->dr[7]); } - if (flags & X86_DUMP_CCOP) { + if (flags & CPU_DUMP_CCOP) { if ((unsigned)env->cc_op < CC_OP_NB) snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]); else @@ -303,7 +303,7 @@ void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf, } } cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer); - if (flags & X86_DUMP_FPU) { + if (flags & CPU_DUMP_FPU) { int fptag; fptag = 0; for(i = 0; i < 8; i++) { diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index 5fff8d59c6..ff9337441b 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -31,7 +31,7 @@ #ifdef DEBUG_PCALL # define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__) # define LOG_PCALL_STATE(env) \ - log_cpu_state_mask(CPU_LOG_PCALL, (env), X86_DUMP_CCOP) + log_cpu_state_mask(CPU_LOG_PCALL, (env), CPU_DUMP_CCOP) #else # define LOG_PCALL(...) do { } while (0) # define LOG_PCALL_STATE(env) do { } while (0) @@ -1177,7 +1177,7 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int, qemu_log(" EAX=" TARGET_FMT_lx, EAX); } qemu_log("\n"); - log_cpu_state(env, X86_DUMP_CCOP); + log_cpu_state(env, CPU_DUMP_CCOP); #if 0 { int i; diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c index 8b04eb2e00..eea2fe9782 100644 --- a/target-i386/smm_helper.c +++ b/target-i386/smm_helper.c @@ -47,7 +47,7 @@ void do_smm_enter(CPUX86State *env) int i, offset; qemu_log_mask(CPU_LOG_INT, "SMM: enter\n"); - log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP); + log_cpu_state_mask(CPU_LOG_INT, env, CPU_DUMP_CCOP); env->hflags |= HF_SMM_MASK; cpu_smm_update(env); @@ -295,7 +295,7 @@ void helper_rsm(CPUX86State *env) cpu_smm_update(env); qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n"); - log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP); + log_cpu_state_mask(CPU_LOG_INT, env, CPU_DUMP_CCOP); } #endif /* !CONFIG_USER_ONLY */ |