For upstream

-----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEErET+3BT38evtv0FRKcWWeA9ryoMFAl3K0rcACgkQKcWWeA9r
 yoNMeQf9GzzIwWO+JAxbKUEc5Bs8Kgq2wOOTnzQvzHobDFtEzlET6TE6zP6gJG9i
 /QGY5H+mo7KueORwOWAgUjIIGMpZrinsvppOM/xtfDerdUYXoyHXej8Q5dEFZGRn
 R4jFEUs6d0OBHCRV/tLzpoQA0Yw3Jd67hlDRjwEPMTUTqQWWw/pFoYnNbTGwBoim
 ySDTBwzM1+EQv7bJU9hZKGjKc47e5zwU5FpmLmmlqF9FDNSR2I+0nGpvo0yzwJIf
 k5a/m2JL74UQzLvDMKv8Bnop2iRKrRrwFP5Y1UEOA2wmABaJTfftGCf1nczfUZVZ
 8oacwBghuISsQxWUZzu8AJMHs8/3rg==
 =fzCL
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/edgar/tags/edgar/xilinx-next-2019-11-12.for-upstream' into staging

For upstream

# gpg: Signature made Tue 12 Nov 2019 15:41:43 GMT
# gpg:                using RSA key AC44FEDC14F7F1EBEDBF415129C596780F6BCA83
# gpg: Good signature from "Edgar E. Iglesias (Xilinx key) <edgar.iglesias@xilinx.com>" [unknown]
# gpg:                 aka "Edgar E. Iglesias <edgar.iglesias@gmail.com>" [full]
# Primary key fingerprint: AC44 FEDC 14F7 F1EB EDBF  4151 29C5 9678 0F6B CA83

* remotes/edgar/tags/edgar/xilinx-next-2019-11-12.for-upstream:
  target/microblaze: Plug temp leak around eval_cond_jmp()
  target/microblaze: Plug temp leaks with delay slot setup
  target/microblaze: Plug temp leaks for loads/stores

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-11-12 16:10:43 +00:00
commit 04d57cfa7e

View File

@ -962,17 +962,7 @@ static void dec_load(DisasContext *dc)
switch (size) {
case 1:
{
/* 00 -> 11
01 -> 10
10 -> 10
11 -> 00 */
TCGv low = tcg_temp_new();
tcg_gen_andi_tl(low, addr, 3);
tcg_gen_sub_tl(low, tcg_const_tl(3), low);
tcg_gen_andi_tl(addr, addr, ~3);
tcg_gen_or_tl(addr, addr, low);
tcg_temp_free(low);
tcg_gen_xori_tl(addr, addr, 3);
break;
}
@ -1006,9 +996,16 @@ static void dec_load(DisasContext *dc)
tcg_gen_qemu_ld_i32(v, addr, mem_index, mop);
if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
TCGv_i32 t0 = tcg_const_i32(0);
TCGv_i32 treg = tcg_const_i32(dc->rd);
TCGv_i32 tsize = tcg_const_i32(size - 1);
tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
gen_helper_memalign(cpu_env, addr, tcg_const_i32(dc->rd),
tcg_const_i32(0), tcg_const_i32(size - 1));
gen_helper_memalign(cpu_env, addr, treg, t0, tsize);
tcg_temp_free_i32(t0);
tcg_temp_free_i32(treg);
tcg_temp_free_i32(tsize);
}
if (ex) {
@ -1095,17 +1092,7 @@ static void dec_store(DisasContext *dc)
switch (size) {
case 1:
{
/* 00 -> 11
01 -> 10
10 -> 10
11 -> 00 */
TCGv low = tcg_temp_new();
tcg_gen_andi_tl(low, addr, 3);
tcg_gen_sub_tl(low, tcg_const_tl(3), low);
tcg_gen_andi_tl(addr, addr, ~3);
tcg_gen_or_tl(addr, addr, low);
tcg_temp_free(low);
tcg_gen_xori_tl(addr, addr, 3);
break;
}
@ -1124,6 +1111,10 @@ static void dec_store(DisasContext *dc)
/* Verify alignment if needed. */
if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
TCGv_i32 t1 = tcg_const_i32(1);
TCGv_i32 treg = tcg_const_i32(dc->rd);
TCGv_i32 tsize = tcg_const_i32(size - 1);
tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
/* FIXME: if the alignment is wrong, we should restore the value
* in memory. One possible way to achieve this is to probe
@ -1131,8 +1122,11 @@ static void dec_store(DisasContext *dc)
* the alignment checks in between the probe and the mem
* access.
*/
gen_helper_memalign(cpu_env, addr, tcg_const_i32(dc->rd),
tcg_const_i32(1), tcg_const_i32(size - 1));
gen_helper_memalign(cpu_env, addr, treg, t1, tsize);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(treg);
tcg_temp_free_i32(tsize);
}
if (ex) {
@ -1183,6 +1177,17 @@ static void eval_cond_jmp(DisasContext *dc, TCGv_i64 pc_true, TCGv_i64 pc_false)
tcg_temp_free_i64(tmp_zero);
}
static void dec_setup_dslot(DisasContext *dc)
{
TCGv_i32 tmp = tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG));
dc->delayed_branch = 2;
dc->tb_flags |= D_FLAG;
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUMBState, bimm));
tcg_temp_free_i32(tmp);
}
static void dec_bcc(DisasContext *dc)
{
unsigned int cc;
@ -1194,10 +1199,7 @@ static void dec_bcc(DisasContext *dc)
dc->delayed_branch = 1;
if (dslot) {
dc->delayed_branch = 2;
dc->tb_flags |= D_FLAG;
tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
cpu_env, offsetof(CPUMBState, bimm));
dec_setup_dslot(dc);
}
if (dec_alu_op_b_is_small_imm(dc)) {
@ -1256,10 +1258,7 @@ static void dec_br(DisasContext *dc)
dc->delayed_branch = 1;
if (dslot) {
dc->delayed_branch = 2;
dc->tb_flags |= D_FLAG;
tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
cpu_env, offsetof(CPUMBState, bimm));
dec_setup_dslot(dc);
}
if (link && dc->rd)
tcg_gen_movi_i32(cpu_R[dc->rd], dc->pc);
@ -1361,10 +1360,7 @@ static void dec_rts(DisasContext *dc)
return;
}
dc->delayed_branch = 2;
dc->tb_flags |= D_FLAG;
tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
cpu_env, offsetof(CPUMBState, bimm));
dec_setup_dslot(dc);
if (i_bit) {
LOG_DIS("rtid ir=%x\n", dc->ir);
@ -1685,7 +1681,10 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
dc->tb_flags &= ~D_FLAG;
/* If it is a direct jump, try direct chaining. */
if (dc->jmp == JMP_INDIRECT) {
eval_cond_jmp(dc, env_btarget, tcg_const_i64(dc->pc));
TCGv_i64 tmp_pc = tcg_const_i64(dc->pc);
eval_cond_jmp(dc, env_btarget, tmp_pc);
tcg_temp_free_i64(tmp_pc);
dc->is_jmp = DISAS_JUMP;
} else if (dc->jmp == JMP_DIRECT) {
t_sync_flags(dc);