Commit 0c9c3a9e3a5efd1871241e2cf1e2195b4243f92c

Authored by balrog
1 parent 63d41246

arm: Don't potentially overwrite input registers in add2, sub2.

According to malc TCG will often genereate an add2/sub2/mul2 with low
half of the output in the same register as high half of one of the
inputs, so account for that.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5847 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 13 additions and 4 deletions
tcg/arm/tcg-target.c
@@ -295,10 +295,19 @@ static inline void tcg_out_dat_reg2(TCGContext *s, @@ -295,10 +295,19 @@ static inline void tcg_out_dat_reg2(TCGContext *s,
295 int cond, int opc0, int opc1, int rd0, int rd1, 295 int cond, int opc0, int opc1, int rd0, int rd1,
296 int rn0, int rn1, int rm0, int rm1, int shift) 296 int rn0, int rn1, int rm0, int rm1, int shift)
297 { 297 {
298 - tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) |  
299 - (rn0 << 16) | (rd0 << 12) | shift | rm0);  
300 - tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) |  
301 - (rn1 << 16) | (rd1 << 12) | shift | rm1); 298 + if (rd0 == rn1 || rd0 == rm1) {
  299 + tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) |
  300 + (rn0 << 16) | (8 << 12) | shift | rm0);
  301 + tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) |
  302 + (rn1 << 16) | (rd1 << 12) | shift | rm1);
  303 + tcg_out_dat_reg(s, cond, ARITH_MOV,
  304 + rd0, 0, TCG_REG_R8, SHIFT_IMM_LSL(0));
  305 + } else {
  306 + tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) |
  307 + (rn0 << 16) | (rd0 << 12) | shift | rm0);
  308 + tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) |
  309 + (rn1 << 16) | (rd1 << 12) | shift | rm1);
  310 + }
302 } 311 }
303 312
304 static inline void tcg_out_dat_imm(TCGContext *s, 313 static inline void tcg_out_dat_imm(TCGContext *s,