Fix X86Mir2Lir::LoadBaseIndexedDisp causing SEGV
If you are loading an 'array' long/double value, the generated code
could cause a SEGV, because the destination for the first load is the
same as the index register. The case for the base register being the
same as the destination was handled, but not the index register.
With this change, Calculator properly runs on the emulator.
Change-Id: Ib7e652938cdc9e127fb80ee2f541a4225a5e9ab7
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
diff --git a/compiler/dex/quick/x86/utility_x86.cc b/compiler/dex/quick/x86/utility_x86.cc
index 91c39fa..a2c215c 100644
--- a/compiler/dex/quick/x86/utility_x86.cc
+++ b/compiler/dex/quick/x86/utility_x86.cc
@@ -435,15 +435,37 @@
displacement + LOWORD_OFFSET);
} else {
if (rBase == r_dest) {
- load2 = NewLIR5(opcode, r_dest_hi, rBase, r_index, scale,
- displacement + HIWORD_OFFSET);
- load = NewLIR5(opcode, r_dest, rBase, r_index, scale,
- displacement + LOWORD_OFFSET);
+ if (r_dest_hi == r_index) {
+ // We can't use either register for the first load.
+ int temp = AllocTemp();
+ load2 = NewLIR5(opcode, temp, rBase, r_index, scale,
+ displacement + HIWORD_OFFSET);
+ load = NewLIR5(opcode, r_dest, rBase, r_index, scale,
+ displacement + LOWORD_OFFSET);
+ OpRegCopy(r_dest_hi, temp);
+ FreeTemp(temp);
+ } else {
+ load2 = NewLIR5(opcode, r_dest_hi, rBase, r_index, scale,
+ displacement + HIWORD_OFFSET);
+ load = NewLIR5(opcode, r_dest, rBase, r_index, scale,
+ displacement + LOWORD_OFFSET);
+ }
} else {
- load = NewLIR5(opcode, r_dest, rBase, r_index, scale,
- displacement + LOWORD_OFFSET);
- load2 = NewLIR5(opcode, r_dest_hi, rBase, r_index, scale,
- displacement + HIWORD_OFFSET);
+ if (r_dest == r_index) {
+ // We can't use either register for the first load.
+ int temp = AllocTemp();
+ load = NewLIR5(opcode, temp, rBase, r_index, scale,
+ displacement + LOWORD_OFFSET);
+ load2 = NewLIR5(opcode, r_dest_hi, rBase, r_index, scale,
+ displacement + HIWORD_OFFSET);
+ OpRegCopy(r_dest, temp);
+ FreeTemp(temp);
+ } else {
+ load = NewLIR5(opcode, r_dest, rBase, r_index, scale,
+ displacement + LOWORD_OFFSET);
+ load2 = NewLIR5(opcode, r_dest_hi, rBase, r_index, scale,
+ displacement + HIWORD_OFFSET);
+ }
}
}
}