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
											
										
									
								
							
							
								
								
									
										2468
									
								
								tcg/tcg-op.h
								
								
								
								
							
							
						
						
									
										2468
									
								
								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