mirror of https://gitee.com/openkylin/qemu.git
target-mips: add gen_base_offset_addr
This is a common pattern in existing code. We'll also use it to implement the mips16 SAVE/RESTORE instructions. Signed-off-by: Nathan Froyd <froydnj@codesourcery.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
7dca4ad050
commit
662d748516
|
@ -981,6 +981,19 @@ OP_ST_ATOMIC(scd,st64,ld64,0x7);
|
||||||
#endif
|
#endif
|
||||||
#undef OP_ST_ATOMIC
|
#undef OP_ST_ATOMIC
|
||||||
|
|
||||||
|
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
|
||||||
|
int base, int16_t offset)
|
||||||
|
{
|
||||||
|
if (base == 0) {
|
||||||
|
tcg_gen_movi_tl(addr, offset);
|
||||||
|
} else if (offset == 0) {
|
||||||
|
gen_load_gpr(addr, base);
|
||||||
|
} else {
|
||||||
|
tcg_gen_movi_tl(addr, offset);
|
||||||
|
gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Load and store */
|
/* Load and store */
|
||||||
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
|
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
|
||||||
int base, int16_t offset)
|
int base, int16_t offset)
|
||||||
|
@ -989,14 +1002,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
|
||||||
TCGv t0 = tcg_temp_new();
|
TCGv t0 = tcg_temp_new();
|
||||||
TCGv t1 = tcg_temp_new();
|
TCGv t1 = tcg_temp_new();
|
||||||
|
|
||||||
if (base == 0) {
|
gen_base_offset_addr(ctx, t0, base, offset);
|
||||||
tcg_gen_movi_tl(t0, offset);
|
|
||||||
} else if (offset == 0) {
|
|
||||||
gen_load_gpr(t0, base);
|
|
||||||
} else {
|
|
||||||
tcg_gen_movi_tl(t0, offset);
|
|
||||||
gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
|
|
||||||
}
|
|
||||||
/* Don't do NOP if destination is zero: we must perform the actual
|
/* Don't do NOP if destination is zero: we must perform the actual
|
||||||
memory access. */
|
memory access. */
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
|
@ -1147,14 +1153,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
|
||||||
|
|
||||||
t0 = tcg_temp_local_new();
|
t0 = tcg_temp_local_new();
|
||||||
|
|
||||||
if (base == 0) {
|
gen_base_offset_addr(ctx, t0, base, offset);
|
||||||
tcg_gen_movi_tl(t0, offset);
|
|
||||||
} else if (offset == 0) {
|
|
||||||
gen_load_gpr(t0, base);
|
|
||||||
} else {
|
|
||||||
tcg_gen_movi_tl(t0, offset);
|
|
||||||
gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
|
|
||||||
}
|
|
||||||
/* Don't do NOP if destination is zero: we must perform the actual
|
/* Don't do NOP if destination is zero: we must perform the actual
|
||||||
memory access. */
|
memory access. */
|
||||||
|
|
||||||
|
@ -1186,14 +1185,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
|
||||||
const char *opn = "flt_ldst";
|
const char *opn = "flt_ldst";
|
||||||
TCGv t0 = tcg_temp_new();
|
TCGv t0 = tcg_temp_new();
|
||||||
|
|
||||||
if (base == 0) {
|
gen_base_offset_addr(ctx, t0, base, offset);
|
||||||
tcg_gen_movi_tl(t0, offset);
|
|
||||||
} else if (offset == 0) {
|
|
||||||
gen_load_gpr(t0, base);
|
|
||||||
} else {
|
|
||||||
tcg_gen_movi_tl(t0, offset);
|
|
||||||
gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
|
|
||||||
}
|
|
||||||
/* Don't do NOP if destination is zero: we must perform the actual
|
/* Don't do NOP if destination is zero: we must perform the actual
|
||||||
memory access. */
|
memory access. */
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
|
|
Loading…
Reference in New Issue