2011-9-17 17:22:00
/* Release a temporary variable. */
static void dead_tmp(TCGv tmp)
{
int i;
num_temps--;
i = num_temps;
if (TCGV_EQUAL(temps[i], tmp))
return;
/* Shuffle this temp to the last slot. */
while (!TCGV_EQUAL(temps[i], tmp))
i--;
while (i < num_temps) {
temps[i] = temps[i + 1];
i++;
}
temps[i] = tmp;
}
从本地cache中移除
static inline void tcg_gen_ld_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
{
tcg_gen_ldst_op_i32(INDEX_op_ld_i32, ret, arg2, offset);
}
就一个load指令
static inline TCGv load_cpu_offset(int offset)
{
TCGv tmp = new_tmp();
tcg_gen_ld_i32(tmp, cpu_env, offset);
return tmp;
}
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
static inline void store_cpu_offset(TCGv var, int offset)
{
tcg_gen_st_i32(var, cpu_env, offset);
dead_tmp(var);
}
#define store_cpu_field(var, name) \
store_cpu_offset(var, offsetof(CPUState, name))
/* Set a variable to the value of a CPU register. */
static void load_reg_var(DisasContext *s, TCGv var, int reg)
{
if (reg == 15) {
uint32_t addr;
/* normaly, since we updated PC, we need only to add one insn */
if (s->thumb)
addr = (long)s->pc + 2;
else
addr = (long)s->pc + 4;
tcg_gen_movi_i32(var, addr);
} else {
tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
}
}
/* Create a new temporary and set it to the value of a CPU register. */
static inline TCGv load_reg(DisasContext *s, int reg)
{
TCGv tmp = new_tmp();
load_reg_var(s, tmp, reg);
return tmp;
}
/* Set a CPU register. The source must be a temporary and will be
marked as dead. */
static void store_reg(DisasContext *s, int reg, TCGv var)
{
if (reg == 15) {
tcg_gen_andi_i32(var, var, ~1);
s->is_jmp = DISAS_JUMP;
}
tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
dead_tmp(var);
}
load 和store Reg