mirror of https://github.com/xemu-project/xemu.git
tcg: Move some opcode generation functions out of line
Some of these functions are really quite large. We have a number of things that ought to be circularly dependent, but we duplicated code to break that chain for the inlines. This saved 25% of the code size of one of the translators I examined. Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
449008f864
commit
951c6300f7
|
@ -83,7 +83,7 @@ all: $(PROGS) stap
|
||||||
#########################################################
|
#########################################################
|
||||||
# cpu emulator library
|
# cpu emulator library
|
||||||
obj-y = exec.o translate-all.o cpu-exec.o
|
obj-y = exec.o translate-all.o cpu-exec.o
|
||||||
obj-y += tcg/tcg.o tcg/optimize.o
|
obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
|
||||||
obj-$(CONFIG_TCG_INTERPRETER) += tci.o
|
obj-$(CONFIG_TCG_INTERPRETER) += tci.o
|
||||||
obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
|
obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
|
||||||
obj-y += fpu/softfloat.o
|
obj-y += fpu/softfloat.o
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
2454
tcg/tcg-op.h
2454
tcg/tcg-op.h
File diff suppressed because it is too large
Load Diff
137
tcg/tcg.c
137
tcg/tcg.c
|
@ -870,143 +870,6 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
|
||||||
#endif /* TCG_TARGET_EXTEND_ARGS */
|
#endif /* TCG_TARGET_EXTEND_ARGS */
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TCG_TARGET_REG_BITS == 32
|
|
||||||
void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
|
|
||||||
int c, int right, int arith)
|
|
||||||
{
|
|
||||||
if (c == 0) {
|
|
||||||
tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
|
|
||||||
tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
|
|
||||||
} else if (c >= 32) {
|
|
||||||
c -= 32;
|
|
||||||
if (right) {
|
|
||||||
if (arith) {
|
|
||||||
tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
|
|
||||||
tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
|
|
||||||
} else {
|
|
||||||
tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
|
|
||||||
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
|
|
||||||
tcg_gen_movi_i32(TCGV_LOW(ret), 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TCGv_i32 t0, t1;
|
|
||||||
|
|
||||||
t0 = tcg_temp_new_i32();
|
|
||||||
t1 = tcg_temp_new_i32();
|
|
||||||
if (right) {
|
|
||||||
tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
|
|
||||||
if (arith)
|
|
||||||
tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
|
|
||||||
else
|
|
||||||
tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
|
|
||||||
tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
|
|
||||||
tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
|
|
||||||
tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
|
|
||||||
} else {
|
|
||||||
tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
|
|
||||||
/* Note: ret can be the same as arg1, so we use t1 */
|
|
||||||
tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
|
|
||||||
tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
|
|
||||||
tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
|
|
||||||
tcg_gen_mov_i32(TCGV_LOW(ret), t1);
|
|
||||||
}
|
|
||||||
tcg_temp_free_i32(t0);
|
|
||||||
tcg_temp_free_i32(t1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st)
|
|
||||||
{
|
|
||||||
switch (op & MO_SIZE) {
|
|
||||||
case MO_8:
|
|
||||||
op &= ~MO_BSWAP;
|
|
||||||
break;
|
|
||||||
case MO_16:
|
|
||||||
break;
|
|
||||||
case MO_32:
|
|
||||||
if (!is64) {
|
|
||||||
op &= ~MO_SIGN;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MO_64:
|
|
||||||
if (!is64) {
|
|
||||||
tcg_abort();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (st) {
|
|
||||||
op &= ~MO_SIGN;
|
|
||||||
}
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
|
|
||||||
{
|
|
||||||
memop = tcg_canonicalize_memop(memop, 0, 0);
|
|
||||||
|
|
||||||
*tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i32;
|
|
||||||
tcg_add_param_i32(val);
|
|
||||||
tcg_add_param_tl(addr);
|
|
||||||
*tcg_ctx.gen_opparam_ptr++ = memop;
|
|
||||||
*tcg_ctx.gen_opparam_ptr++ = idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
|
|
||||||
{
|
|
||||||
memop = tcg_canonicalize_memop(memop, 0, 1);
|
|
||||||
|
|
||||||
*tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i32;
|
|
||||||
tcg_add_param_i32(val);
|
|
||||||
tcg_add_param_tl(addr);
|
|
||||||
*tcg_ctx.gen_opparam_ptr++ = memop;
|
|
||||||
*tcg_ctx.gen_opparam_ptr++ = idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
|
|
||||||
{
|
|
||||||
memop = tcg_canonicalize_memop(memop, 1, 0);
|
|
||||||
|
|
||||||
#if TCG_TARGET_REG_BITS == 32
|
|
||||||
if ((memop & MO_SIZE) < MO_64) {
|
|
||||||
tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop);
|
|
||||||
if (memop & MO_SIGN) {
|
|
||||||
tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31);
|
|
||||||
} else {
|
|
||||||
tcg_gen_movi_i32(TCGV_HIGH(val), 0);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i64;
|
|
||||||
tcg_add_param_i64(val);
|
|
||||||
tcg_add_param_tl(addr);
|
|
||||||
*tcg_ctx.gen_opparam_ptr++ = memop;
|
|
||||||
*tcg_ctx.gen_opparam_ptr++ = idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
|
|
||||||
{
|
|
||||||
memop = tcg_canonicalize_memop(memop, 1, 1);
|
|
||||||
|
|
||||||
#if TCG_TARGET_REG_BITS == 32
|
|
||||||
if ((memop & MO_SIZE) < MO_64) {
|
|
||||||
tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i64;
|
|
||||||
tcg_add_param_i64(val);
|
|
||||||
tcg_add_param_tl(addr);
|
|
||||||
*tcg_ctx.gen_opparam_ptr++ = memop;
|
|
||||||
*tcg_ctx.gen_opparam_ptr++ = idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tcg_reg_alloc_start(TCGContext *s)
|
static void tcg_reg_alloc_start(TCGContext *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -706,9 +706,6 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
|
||||||
void tcg_gen_callN(TCGContext *s, void *func,
|
void tcg_gen_callN(TCGContext *s, void *func,
|
||||||
TCGArg ret, int nargs, TCGArg *args);
|
TCGArg ret, int nargs, TCGArg *args);
|
||||||
|
|
||||||
void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
|
|
||||||
int c, int right, int arith);
|
|
||||||
|
|
||||||
TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args,
|
TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args,
|
||||||
TCGOpDef *tcg_op_def);
|
TCGOpDef *tcg_op_def);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue