mirror of https://github.com/xemu-project/xemu.git
tcg queued patches
-----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJYGMa2AAoJEK0ScMxN0Ceb1XQIAKvJkT7MGO1SnVC6nJfN92TP 7E/h2l1tZ0T4AkBQ1iFe5JpAkYx2rY8jP67EBpyqiSSp3A8mVRpCVgN2uwxoXiLk kkr8t80JIP49pZ+oqbVeXjQN23QpaKP727dYwYxKZhzLxSvtnc34brUvDuBp2bke vm+N7np09g2Gy8DL5tPxs5plgOz2ADgbp7Q4geUHKISJ3XPMt1rbGixupKe/46oF 2T5L0xxTenDZQo8J6FAuZwSnQ07s8QUjWa9VGtdn6CQsiosXuCm5V1UoQl9/ZT6j Of8SnFiVZjkxcjWcFSashtqXTYRck0/g/cSMkYpWruW/cV+EDjiACkVDUfoGi0o= =WF70 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20161101-2' into staging tcg queued patches # gpg: Signature made Tue 01 Nov 2016 16:45:42 GMT # gpg: using RSA key 0xAD1270CC4DD0279B # gpg: Good signature from "Richard Henderson <rth7680@gmail.com>" # gpg: aka "Richard Henderson <rth@redhat.com>" # gpg: aka "Richard Henderson <rth@twiddle.net>" # Primary key fingerprint: 9CB1 8DDA F8E8 49AD 2AFC 16A4 AD12 70CC 4DD0 279B * remotes/rth/tags/pull-tcg-20161101-2: tcg: correct 32-bit tcg_gen_ld8s_i64 sign-extension tcg/tcg.h: Improve documentation of TCGv_i32 etc types MAINTAINERS: Update PPC status and maintainer target-microblaze: Cleanup dec_mul tcg: Add tcg_gen_mulsu2_{i32,i64,tl} log: Add locking to large logging blocks target-openrisc: Do not dump cpu state with -d in_asm target-microblaze: Do not dump cpu state with -d in_asm target-cris: Do not dump cpu state with -d in_asm Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
4eb28abd52
|
@ -1504,8 +1504,8 @@ F: tcg/mips/
|
|||
F: disas/mips.c
|
||||
|
||||
PPC
|
||||
M: Vassili Karpov (malc) <av1474@comtv.ru>
|
||||
S: Maintained
|
||||
M: Richard Henderson <rth@twiddle.net>
|
||||
S: Odd Fixes
|
||||
F: tcg/ppc/
|
||||
F: disas/ppc.c
|
||||
|
||||
|
|
|
@ -150,11 +150,13 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
|
|||
#if defined(DEBUG_DISAS)
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)
|
||||
&& qemu_log_in_addr_range(itb->pc)) {
|
||||
qemu_log_lock();
|
||||
#if defined(TARGET_I386)
|
||||
log_cpu_state(cpu, CPU_DUMP_CCOP);
|
||||
#else
|
||||
log_cpu_state(cpu, 0);
|
||||
#endif
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif /* DEBUG_DISAS */
|
||||
|
||||
|
|
2
exec.c
2
exec.c
|
@ -911,11 +911,13 @@ void cpu_abort(CPUState *cpu, const char *fmt, ...)
|
|||
fprintf(stderr, "\n");
|
||||
cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP);
|
||||
if (qemu_log_separate()) {
|
||||
qemu_log_lock();
|
||||
qemu_log("qemu: fatal: ");
|
||||
qemu_log_vprintf(fmt, ap2);
|
||||
qemu_log("\n");
|
||||
log_cpu_state(cpu, CPU_DUMP_FPU | CPU_DUMP_CCOP);
|
||||
qemu_log_flush();
|
||||
qemu_log_unlock();
|
||||
qemu_log_close();
|
||||
}
|
||||
va_end(ap2);
|
||||
|
|
|
@ -51,6 +51,22 @@ static inline bool qemu_loglevel_mask(int mask)
|
|||
return (qemu_loglevel & mask) != 0;
|
||||
}
|
||||
|
||||
/* Lock output for a series of related logs. Since this is not needed
|
||||
* for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we
|
||||
* assume that qemu_loglevel_mask has already been tested, and that
|
||||
* qemu_loglevel is never set when qemu_logfile is unset.
|
||||
*/
|
||||
|
||||
static inline void qemu_log_lock(void)
|
||||
{
|
||||
qemu_flockfile(qemu_logfile);
|
||||
}
|
||||
|
||||
static inline void qemu_log_unlock(void)
|
||||
{
|
||||
qemu_funlockfile(qemu_logfile);
|
||||
}
|
||||
|
||||
/* Logging functions: */
|
||||
|
||||
/* main logging function
|
||||
|
|
|
@ -87,4 +87,16 @@ void *qemu_alloc_stack(size_t *sz);
|
|||
*/
|
||||
void qemu_free_stack(void *stack, size_t sz);
|
||||
|
||||
/* POSIX and Mingw32 differ in the name of the stdio lock functions. */
|
||||
|
||||
static inline void qemu_flockfile(FILE *f)
|
||||
{
|
||||
flockfile(f);
|
||||
}
|
||||
|
||||
static inline void qemu_funlockfile(FILE *f)
|
||||
{
|
||||
funlockfile(f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -103,6 +103,21 @@ static inline char *realpath(const char *path, char *resolved_path)
|
|||
return resolved_path;
|
||||
}
|
||||
|
||||
/* ??? Mingw appears to export _lock_file and _unlock_file as the functions
|
||||
* with which to lock a stdio handle. But something is wrong in the markup,
|
||||
* either in the header or the library, such that we get undefined references
|
||||
* to "_imp___lock_file" etc when linking. Since we seem to have no other
|
||||
* alternative, and the usage within the logging functions isn't critical,
|
||||
* ignore FILE locking.
|
||||
*/
|
||||
|
||||
static inline void qemu_flockfile(FILE *f)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void qemu_funlockfile(FILE *f)
|
||||
{
|
||||
}
|
||||
|
||||
/* We wrap all the sockets functions so that we can
|
||||
* set errno based on WSAGetLastError()
|
||||
|
|
|
@ -2994,9 +2994,11 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, ctx.pc - pc_start, 1);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -11420,11 +11420,13 @@ done_generating:
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
|
||||
qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("----------------\n");
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, dc->pc - pc_start,
|
||||
4 | (bswap_code(dc->sctlr_b) ? 2 : 0));
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
tb->size = dc->pc - pc_start;
|
||||
|
|
|
@ -11963,11 +11963,13 @@ done_generating:
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
|
||||
qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("----------------\n");
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, dc->pc - pc_start,
|
||||
dc->thumb | (dc->sctlr_b << 1));
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
tb->size = dc->pc - pc_start;
|
||||
|
|
|
@ -3135,29 +3135,6 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
|
|||
|
||||
dc->cpustate_changed = 0;
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
||||
qemu_log(
|
||||
"pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
|
||||
"pid=%x usp=%x\n"
|
||||
"%x.%x.%x.%x\n"
|
||||
"%x.%x.%x.%x\n"
|
||||
"%x.%x.%x.%x\n"
|
||||
"%x.%x.%x.%x\n",
|
||||
dc->pc, dc->ppc,
|
||||
(uint64_t)tb->flags,
|
||||
env->btarget, (unsigned)tb->flags & 7,
|
||||
env->pregs[PR_CCS],
|
||||
env->pregs[PR_PID], env->pregs[PR_USP],
|
||||
env->regs[0], env->regs[1], env->regs[2], env->regs[3],
|
||||
env->regs[4], env->regs[5], env->regs[6], env->regs[7],
|
||||
env->regs[8], env->regs[9],
|
||||
env->regs[10], env->regs[11],
|
||||
env->regs[12], env->regs[13],
|
||||
env->regs[14], env->regs[15]);
|
||||
qemu_log("--------------\n");
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
}
|
||||
|
||||
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
|
||||
num_insns = 0;
|
||||
max_insns = tb->cflags & CF_COUNT_MASK;
|
||||
|
@ -3313,10 +3290,14 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
|
|||
#if !DISAS_CRIS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("--------------\n");
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, dc->pc - pc_start,
|
||||
env->pregs[PR_VR]);
|
||||
qemu_log("\nisize=%d osize=%d\n",
|
||||
dc->pc - pc_start, tcg_op_buf_count());
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -2432,11 +2432,13 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
|
|||
|
||||
if (qemu_loglevel_mask(LOG_UNIMP)) {
|
||||
target_ulong pc = s->pc_start, end = s->pc;
|
||||
qemu_log_lock();
|
||||
qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc);
|
||||
for (; pc < end; ++pc) {
|
||||
qemu_log(" %02x", cpu_ldub_code(env, pc));
|
||||
}
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8470,6 +8472,7 @@ done_generating:
|
|||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
int disas_flags;
|
||||
qemu_log_lock();
|
||||
qemu_log("----------------\n");
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
#ifdef TARGET_X86_64
|
||||
|
@ -8480,6 +8483,7 @@ done_generating:
|
|||
disas_flags = !dc->code32;
|
||||
log_target_disas(cs, pc_start, pc_ptr - pc_start, disas_flags);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1148,10 +1148,12 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("\n");
|
||||
log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
|
||||
qemu_log("\nisize=%d osize=%d\n",
|
||||
dc->pc - pc_start, tcg_op_buf_count());
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -3549,10 +3549,12 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("----------------\n");
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
tb->size = dc->pc - pc_start;
|
||||
|
|
|
@ -581,50 +581,10 @@ static void dec_msr(DisasContext *dc)
|
|||
}
|
||||
}
|
||||
|
||||
/* 64-bit signed mul, lower result in d and upper in d2. */
|
||||
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
|
||||
{
|
||||
TCGv_i64 t0, t1;
|
||||
|
||||
t0 = tcg_temp_new_i64();
|
||||
t1 = tcg_temp_new_i64();
|
||||
|
||||
tcg_gen_ext_i32_i64(t0, a);
|
||||
tcg_gen_ext_i32_i64(t1, b);
|
||||
tcg_gen_mul_i64(t0, t0, t1);
|
||||
|
||||
tcg_gen_extrl_i64_i32(d, t0);
|
||||
tcg_gen_shri_i64(t0, t0, 32);
|
||||
tcg_gen_extrl_i64_i32(d2, t0);
|
||||
|
||||
tcg_temp_free_i64(t0);
|
||||
tcg_temp_free_i64(t1);
|
||||
}
|
||||
|
||||
/* 64-bit unsigned muls, lower result in d and upper in d2. */
|
||||
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
|
||||
{
|
||||
TCGv_i64 t0, t1;
|
||||
|
||||
t0 = tcg_temp_new_i64();
|
||||
t1 = tcg_temp_new_i64();
|
||||
|
||||
tcg_gen_extu_i32_i64(t0, a);
|
||||
tcg_gen_extu_i32_i64(t1, b);
|
||||
tcg_gen_mul_i64(t0, t0, t1);
|
||||
|
||||
tcg_gen_extrl_i64_i32(d, t0);
|
||||
tcg_gen_shri_i64(t0, t0, 32);
|
||||
tcg_gen_extrl_i64_i32(d2, t0);
|
||||
|
||||
tcg_temp_free_i64(t0);
|
||||
tcg_temp_free_i64(t1);
|
||||
}
|
||||
|
||||
/* Multiplier unit. */
|
||||
static void dec_mul(DisasContext *dc)
|
||||
{
|
||||
TCGv d[2];
|
||||
TCGv tmp;
|
||||
unsigned int subcode;
|
||||
|
||||
if ((dc->tb_flags & MSR_EE_FLAG)
|
||||
|
@ -636,13 +596,11 @@ static void dec_mul(DisasContext *dc)
|
|||
}
|
||||
|
||||
subcode = dc->imm & 3;
|
||||
d[0] = tcg_temp_new();
|
||||
d[1] = tcg_temp_new();
|
||||
|
||||
if (dc->type_b) {
|
||||
LOG_DIS("muli r%d r%d %x\n", dc->rd, dc->ra, dc->imm);
|
||||
t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
|
||||
goto done;
|
||||
tcg_gen_mul_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
|
||||
return;
|
||||
}
|
||||
|
||||
/* mulh, mulhsu and mulhu are not available if C_USE_HW_MUL is < 2. */
|
||||
|
@ -651,30 +609,29 @@ static void dec_mul(DisasContext *dc)
|
|||
/* nop??? */
|
||||
}
|
||||
|
||||
tmp = tcg_temp_new();
|
||||
switch (subcode) {
|
||||
case 0:
|
||||
LOG_DIS("mul r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
||||
t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
tcg_gen_mul_tl(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
case 1:
|
||||
LOG_DIS("mulh r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
||||
t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
tcg_gen_muls2_tl(tmp, cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
case 2:
|
||||
LOG_DIS("mulhsu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
||||
t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
tcg_gen_mulsu2_tl(tmp, cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
case 3:
|
||||
LOG_DIS("mulhu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
||||
t_gen_mulu(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
tcg_gen_mulu2_tl(tmp, cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
default:
|
||||
cpu_abort(CPU(dc->cpu), "unknown MUL insn %x\n", subcode);
|
||||
break;
|
||||
}
|
||||
done:
|
||||
tcg_temp_free(d[0]);
|
||||
tcg_temp_free(d[1]);
|
||||
tcg_temp_free(tmp);
|
||||
}
|
||||
|
||||
/* Div unit. */
|
||||
|
@ -1670,13 +1627,6 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
|
|||
cpu_abort(cs, "Microblaze: unaligned PC=%x\n", pc_start);
|
||||
}
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
||||
#if !SIM_COMPAT
|
||||
qemu_log("--------------\n");
|
||||
log_cpu_state(CPU(cpu), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
|
||||
num_insns = 0;
|
||||
max_insns = tb->cflags & CF_COUNT_MASK;
|
||||
|
@ -1820,12 +1770,14 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
|
|||
#if !SIM_COMPAT
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log("\n");
|
||||
qemu_log_lock();
|
||||
qemu_log("--------------\n");
|
||||
#if DISAS_GNU
|
||||
log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
|
||||
#endif
|
||||
qemu_log("\nisize=%d osize=%d\n",
|
||||
dc->pc - pc_start, tcg_op_buf_count());
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -20043,9 +20043,11 @@ done_generating:
|
|||
LOG_DISAS("\n");
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1651,10 +1651,6 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
|
|||
dc->synced_flags = dc->tb_flags = tb->flags;
|
||||
dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
|
||||
dc->singlestep_enabled = cs->singlestep_enabled;
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
||||
qemu_log("-----------------------------------------\n");
|
||||
log_cpu_state(CPU(cpu), 0);
|
||||
}
|
||||
|
||||
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
|
||||
num_insns = 0;
|
||||
|
@ -1754,10 +1750,13 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log("\n");
|
||||
qemu_log_lock();
|
||||
qemu_log("----------------\n");
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
|
||||
qemu_log("\nisize=%d osize=%d\n",
|
||||
dc->pc - pc_start, tcg_op_buf_count());
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -7211,9 +7211,11 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
|
|||
int flags;
|
||||
flags = env->bfd_mach;
|
||||
flags |= ctx.le_mode << 16;
|
||||
qemu_log_lock();
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, ctx.nip - pc_start, flags);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -5432,9 +5432,11 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
|
|||
#if defined(S390X_DEBUG_DISAS)
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, dc.pc - pc_start, 1);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1927,9 +1927,11 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("IN:\n"); /* , lookup_symbol(pc_start)); */
|
||||
log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -5796,10 +5796,12 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("--------------\n");
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, last_pc + 4 - pc_start, 0);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2391,6 +2391,7 @@ void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb)
|
|||
TCGV_UNUSED_I64(dc->zero);
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
}
|
||||
if (!max_insns) {
|
||||
|
@ -2429,7 +2430,10 @@ void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb)
|
|||
tb->size = dc->pc - pc_start;
|
||||
tb->icount = num_insns;
|
||||
|
||||
qemu_log_mask(CPU_LOG_TB_IN_ASM, "\n");
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void restore_state_to_opc(CPUTLGState *env, TranslationBlock *tb,
|
||||
|
|
|
@ -8789,9 +8789,11 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2024,10 +2024,12 @@ done_generating:
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("----------------\n");
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
tb->size = dc->pc - pc_start;
|
||||
|
|
|
@ -3155,10 +3155,12 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(pc_start)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("----------------\n");
|
||||
qemu_log("IN: %s\n", lookup_symbol(pc_start));
|
||||
log_target_disas(cs, pc_start, dc.pc - pc_start, 0);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
tb->size = dc.pc - pc_start;
|
||||
|
|
45
tcg/tcg-op.c
45
tcg/tcg-op.c
|
@ -678,6 +678,33 @@ void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
|
|||
}
|
||||
}
|
||||
|
||||
void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
|
||||
{
|
||||
if (TCG_TARGET_REG_BITS == 32) {
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
TCGv_i32 t2 = tcg_temp_new_i32();
|
||||
tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
|
||||
/* Adjust for negative input for the signed arg1. */
|
||||
tcg_gen_sari_i32(t2, arg1, 31);
|
||||
tcg_gen_and_i32(t2, t2, arg2);
|
||||
tcg_gen_sub_i32(rh, t1, t2);
|
||||
tcg_gen_mov_i32(rl, t0);
|
||||
tcg_temp_free_i32(t0);
|
||||
tcg_temp_free_i32(t1);
|
||||
tcg_temp_free_i32(t2);
|
||||
} else {
|
||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||
TCGv_i64 t1 = tcg_temp_new_i64();
|
||||
tcg_gen_ext_i32_i64(t0, arg1);
|
||||
tcg_gen_extu_i32_i64(t1, arg2);
|
||||
tcg_gen_mul_i64(t0, t0, t1);
|
||||
tcg_gen_extr_i64_i32(rl, rh, t0);
|
||||
tcg_temp_free_i64(t0);
|
||||
tcg_temp_free_i64(t1);
|
||||
}
|
||||
}
|
||||
|
||||
void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
|
||||
{
|
||||
if (TCG_TARGET_HAS_ext8s_i32) {
|
||||
|
@ -790,7 +817,7 @@ void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
|
|||
void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
|
||||
{
|
||||
tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
|
||||
tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), 31);
|
||||
tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
|
||||
}
|
||||
|
||||
void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
|
||||
|
@ -1748,6 +1775,22 @@ void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
|
|||
}
|
||||
}
|
||||
|
||||
void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
|
||||
{
|
||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||
TCGv_i64 t1 = tcg_temp_new_i64();
|
||||
TCGv_i64 t2 = tcg_temp_new_i64();
|
||||
tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
|
||||
/* Adjust for negative input for the signed arg1. */
|
||||
tcg_gen_sari_i64(t2, arg1, 63);
|
||||
tcg_gen_and_i64(t2, t2, arg2);
|
||||
tcg_gen_sub_i64(rh, t1, t2);
|
||||
tcg_gen_mov_i64(rl, t0);
|
||||
tcg_temp_free_i64(t0);
|
||||
tcg_temp_free_i64(t1);
|
||||
tcg_temp_free_i64(t2);
|
||||
}
|
||||
|
||||
/* Size changing operations. */
|
||||
|
||||
void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
|
||||
|
|
|
@ -306,6 +306,7 @@ void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
|
|||
TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh);
|
||||
void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
|
||||
void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
|
||||
void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
|
||||
void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg);
|
||||
void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg);
|
||||
void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg);
|
||||
|
@ -482,6 +483,7 @@ void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
|
|||
TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh);
|
||||
void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
|
||||
void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
|
||||
void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
|
||||
void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg);
|
||||
void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg);
|
||||
void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg);
|
||||
|
@ -956,6 +958,7 @@ void tcg_gen_atomic_xor_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
|
|||
#define tcg_gen_sub2_tl tcg_gen_sub2_i64
|
||||
#define tcg_gen_mulu2_tl tcg_gen_mulu2_i64
|
||||
#define tcg_gen_muls2_tl tcg_gen_muls2_i64
|
||||
#define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i64
|
||||
#define tcg_gen_atomic_cmpxchg_tl tcg_gen_atomic_cmpxchg_i64
|
||||
#define tcg_gen_atomic_xchg_tl tcg_gen_atomic_xchg_i64
|
||||
#define tcg_gen_atomic_fetch_add_tl tcg_gen_atomic_fetch_add_i64
|
||||
|
@ -1043,6 +1046,7 @@ void tcg_gen_atomic_xor_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
|
|||
#define tcg_gen_sub2_tl tcg_gen_sub2_i32
|
||||
#define tcg_gen_mulu2_tl tcg_gen_mulu2_i32
|
||||
#define tcg_gen_muls2_tl tcg_gen_muls2_i32
|
||||
#define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i32
|
||||
#define tcg_gen_atomic_cmpxchg_tl tcg_gen_atomic_cmpxchg_i32
|
||||
#define tcg_gen_atomic_xchg_tl tcg_gen_atomic_xchg_i32
|
||||
#define tcg_gen_atomic_fetch_add_tl tcg_gen_atomic_fetch_add_i32
|
||||
|
|
|
@ -412,10 +412,12 @@ void tcg_prologue_init(TCGContext *s)
|
|||
|
||||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("PROLOGUE: [size=%zu]\n", prologue_size);
|
||||
log_disas(buf0, prologue_size);
|
||||
qemu_log("\n");
|
||||
qemu_log_flush();
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -2542,9 +2544,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
|
||||
&& qemu_log_in_addr_range(tb->pc))) {
|
||||
qemu_log_lock();
|
||||
qemu_log("OP:\n");
|
||||
tcg_dump_ops(s);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2570,9 +2574,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND)
|
||||
&& qemu_log_in_addr_range(tb->pc))) {
|
||||
qemu_log_lock();
|
||||
qemu_log("OP before indirect lowering:\n");
|
||||
tcg_dump_ops(s);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
/* Replace indirect temps with direct temps. */
|
||||
|
@ -2590,9 +2596,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
|
|||
#ifdef DEBUG_DISAS
|
||||
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
|
||||
&& qemu_log_in_addr_range(tb->pc))) {
|
||||
qemu_log_lock();
|
||||
qemu_log("OP after optimization and liveness analysis:\n");
|
||||
tcg_dump_ops(s);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
38
tcg/tcg.h
38
tcg/tcg.h
|
@ -376,14 +376,36 @@ static inline unsigned get_alignment_bits(TCGMemOp memop)
|
|||
|
||||
typedef tcg_target_ulong TCGArg;
|
||||
|
||||
/* Define a type and accessor macros for variables. Using pointer types
|
||||
is nice because it gives some level of type safely. Converting to and
|
||||
from intptr_t rather than int reduces the number of sign-extension
|
||||
instructions that get implied on 64-bit hosts. Users of tcg_gen_* don't
|
||||
need to know about any of this, and should treat TCGv as an opaque type.
|
||||
In addition we do typechecking for different types of variables. TCGv_i32
|
||||
and TCGv_i64 are 32/64-bit variables respectively. TCGv and TCGv_ptr
|
||||
are aliases for target_ulong and host pointer sized values respectively. */
|
||||
/* Define type and accessor macros for TCG variables.
|
||||
|
||||
TCG variables are the inputs and outputs of TCG ops, as described
|
||||
in tcg/README. Target CPU front-end code uses these types to deal
|
||||
with TCG variables as it emits TCG code via the tcg_gen_* functions.
|
||||
They come in several flavours:
|
||||
* TCGv_i32 : 32 bit integer type
|
||||
* TCGv_i64 : 64 bit integer type
|
||||
* TCGv_ptr : a host pointer type
|
||||
* TCGv : an integer type the same size as target_ulong
|
||||
(an alias for either TCGv_i32 or TCGv_i64)
|
||||
The compiler's type checking will complain if you mix them
|
||||
up and pass the wrong sized TCGv to a function.
|
||||
|
||||
Users of tcg_gen_* don't need to know about any of the internal
|
||||
details of these, and should treat them as opaque types.
|
||||
You won't be able to look inside them in a debugger either.
|
||||
|
||||
Internal implementation details follow:
|
||||
|
||||
Note that there is no definition of the structs TCGv_i32_d etc anywhere.
|
||||
This is deliberate, because the values we store in variables of type
|
||||
TCGv_i32 are not really pointers-to-structures. They're just small
|
||||
integers, but keeping them in pointer types like this means that the
|
||||
compiler will complain if you accidentally pass a TCGv_i32 to a
|
||||
function which takes a TCGv_i64, and so on. Only the internals of
|
||||
TCG need to care about the actual contents of the types, and they always
|
||||
box and unbox via the MAKE_TCGV_* and GET_TCGV_* functions.
|
||||
Converting to and from intptr_t rather than int reduces the number
|
||||
of sign-extension instructions that get implied on 64-bit hosts. */
|
||||
|
||||
typedef struct TCGv_i32_d *TCGv_i32;
|
||||
typedef struct TCGv_i64_d *TCGv_i64;
|
||||
|
|
|
@ -1355,10 +1355,12 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
|||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) &&
|
||||
qemu_log_in_addr_range(tb->pc)) {
|
||||
qemu_log_lock();
|
||||
qemu_log("OUT: [size=%d]\n", gen_code_size);
|
||||
log_disas(tb->tc_ptr, gen_code_size);
|
||||
qemu_log("\n");
|
||||
qemu_log_flush();
|
||||
qemu_log_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue