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:
Richard Henderson 2014-09-19 11:39:20 -07:00
parent 449008f864
commit 951c6300f7
5 changed files with 2322 additions and 2252 deletions

View file

@ -83,7 +83,7 @@ all: $(PROGS) stap
#########################################################
# cpu emulator library
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) += disas/tci.o
obj-y += fpu/softfloat.o

1978
tcg/tcg-op.c Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

137
tcg/tcg.c
View file

@ -870,143 +870,6 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
#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)
{
int i;

View file

@ -706,9 +706,6 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
void tcg_gen_callN(TCGContext *s, void *func,
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,
TCGOpDef *tcg_op_def);