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
|
||||
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
1978
tcg/tcg-op.c
Normal file
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 */
|
||||
}
|
||||
|
||||
#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;
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user