Quick: Handle total high/low register overlap on arm/mips.
OpRegCopyWide() in arm and mips backends didn't handle the
total register overlap when the registers holding the source
and destination pairs are the same but in reverse order.
Bug: 21897012
Change-Id: Ia1f0005cbf5cc1c2d30899575dea21b3efa20ae6
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index 6d30e72..cf01884 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -471,13 +471,18 @@
NewLIR3(kThumb2Fmrrd, r_dest.GetLowReg(), r_dest.GetHighReg(), r_src.GetReg());
} else {
// Handle overlap
- if (r_src.GetHighReg() == r_dest.GetLowReg()) {
- DCHECK_NE(r_src.GetLowReg(), r_dest.GetHighReg());
+ if (r_src.GetHighReg() != r_dest.GetLowReg()) {
+ OpRegCopy(r_dest.GetLow(), r_src.GetLow());
+ OpRegCopy(r_dest.GetHigh(), r_src.GetHigh());
+ } else if (r_src.GetLowReg() != r_dest.GetHighReg()) {
OpRegCopy(r_dest.GetHigh(), r_src.GetHigh());
OpRegCopy(r_dest.GetLow(), r_src.GetLow());
} else {
+ RegStorage r_tmp = AllocTemp();
+ OpRegCopy(r_tmp, r_src.GetHigh());
OpRegCopy(r_dest.GetLow(), r_src.GetLow());
- OpRegCopy(r_dest.GetHigh(), r_src.GetHigh());
+ OpRegCopy(r_dest.GetHigh(), r_tmp);
+ FreeTemp(r_tmp);
}
}
}
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index 9319c64..f5ad7c7 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -258,13 +258,19 @@
}
} else {
// Here if both src and dest are core registers.
- // Handle overlap.
- if (r_src.GetHighReg() == r_dest.GetLowReg()) {
+ // Handle overlap
+ if (r_src.GetHighReg() != r_dest.GetLowReg()) {
+ OpRegCopy(r_dest.GetLow(), r_src.GetLow());
+ OpRegCopy(r_dest.GetHigh(), r_src.GetHigh());
+ } else if (r_src.GetLowReg() != r_dest.GetHighReg()) {
OpRegCopy(r_dest.GetHigh(), r_src.GetHigh());
OpRegCopy(r_dest.GetLow(), r_src.GetLow());
} else {
+ RegStorage r_tmp = AllocTemp();
+ OpRegCopy(r_tmp, r_src.GetHigh());
OpRegCopy(r_dest.GetLow(), r_src.GetLow());
- OpRegCopy(r_dest.GetHigh(), r_src.GetHigh());
+ OpRegCopy(r_dest.GetHigh(), r_tmp);
+ FreeTemp(r_tmp);
}
}
}