Aarch64: fix references handling in Load*Indexed.
Fix the way we handle references in Load/StoreBaseIndexed and friends.
We assume references are 64-bit RegStorage entities, with the
difference that they are load as 32-bit values.
Change-Id: I7fe987ef9e97e9a5042b85378b33d1e85710d8b5
diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h
index 294b9ea..7d75da9 100644
--- a/compiler/dex/quick/arm64/codegen_arm64.h
+++ b/compiler/dex/quick/arm64/codegen_arm64.h
@@ -78,7 +78,8 @@
OVERRIDE;
LIR* LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale,
OpSize size) OVERRIDE;
- LIR* LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest) OVERRIDE;
+ LIR* LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale)
+ OVERRIDE;
LIR* LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
RegStorage r_dest, OpSize size) OVERRIDE;
LIR* LoadConstantNoClobber(RegStorage r_dest, int value);
@@ -89,7 +90,8 @@
VolatileKind is_volatile) OVERRIDE;
LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale,
OpSize size) OVERRIDE;
- LIR* StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src) OVERRIDE;
+ LIR* StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale)
+ OVERRIDE;
LIR* StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
RegStorage r_src, OpSize size) OVERRIDE;
void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) OVERRIDE;
diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc
index 86dddae..e8f5cb9 100644
--- a/compiler/dex/quick/arm64/int_arm64.cc
+++ b/compiler/dex/quick/arm64/int_arm64.cc
@@ -823,7 +823,7 @@
FreeTemp(reg_len);
}
if (rl_result.ref) {
- LoadRefIndexed(reg_ptr, As64BitReg(rl_index.reg), rl_result.reg);
+ LoadRefIndexed(reg_ptr, As64BitReg(rl_index.reg), rl_result.reg, scale);
} else {
LoadBaseIndexed(reg_ptr, As64BitReg(rl_index.reg), rl_result.reg, scale, size);
}
@@ -920,7 +920,7 @@
FreeTemp(reg_len);
}
if (rl_src.ref) {
- StoreRefIndexed(reg_ptr, As64BitReg(rl_index.reg), rl_src.reg);
+ StoreRefIndexed(reg_ptr, As64BitReg(rl_index.reg), rl_src.reg, scale);
} else {
StoreBaseIndexed(reg_ptr, As64BitReg(rl_index.reg), rl_src.reg, scale, size);
}
diff --git a/compiler/dex/quick/arm64/utility_arm64.cc b/compiler/dex/quick/arm64/utility_arm64.cc
index eb08404..22a4ec4 100644
--- a/compiler/dex/quick/arm64/utility_arm64.cc
+++ b/compiler/dex/quick/arm64/utility_arm64.cc
@@ -927,11 +927,9 @@
opcode = WIDE(kA64Ldr4rXxG);
expected_scale = 3;
break;
+ case kSingle: // Intentional fall-through.
+ case k32: // Intentional fall-through.
case kReference:
- // TODO(Arm64): r_dest must be 64-bit below. Remove the hack below.
- r_dest = (r_dest.Is64Bit()) ? As32BitReg(r_dest) : r_dest;
- case kSingle:
- case k32:
r_dest = Check32BitReg(r_dest);
opcode = kA64Ldr4rXxG;
expected_scale = 2;
@@ -972,8 +970,9 @@
return load;
}
-LIR* Arm64Mir2Lir::LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest) {
- return LoadBaseIndexed(r_base, r_index, As32BitReg(r_dest), 2, kReference);
+LIR* Arm64Mir2Lir::LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest,
+ int scale) {
+ return LoadBaseIndexed(r_base, r_index, As32BitReg(r_dest), scale, kReference);
}
LIR* Arm64Mir2Lir::StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src,
@@ -1016,11 +1015,9 @@
opcode = WIDE(kA64Str4rXxG);
expected_scale = 3;
break;
- case kReference:
- // TODO(Arm64): r_src must be 64-bit below. Remove the hack below.
- r_src = (r_src.Is64Bit()) ? As32BitReg(r_src) : r_src;
case kSingle: // Intentional fall-trough.
case k32: // Intentional fall-trough.
+ case kReference:
r_src = Check32BitReg(r_src);
opcode = kA64Str4rXxG;
expected_scale = 2;
@@ -1053,8 +1050,9 @@
return store;
}
-LIR* Arm64Mir2Lir::StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src) {
- return StoreBaseIndexed(r_base, r_index, As32BitReg(r_src), 2, kReference);
+LIR* Arm64Mir2Lir::StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src,
+ int scale) {
+ return StoreBaseIndexed(r_base, r_index, As32BitReg(r_src), scale, kReference);
}
/*
@@ -1084,11 +1082,9 @@
alt_opcode = WIDE(kA64Ldur3rXd);
}
break;
- case kReference:
- // TODO(Arm64): r_dest must be 64-bit below. Remove the hack below.
- r_dest = (r_dest.Is64Bit()) ? As32BitReg(r_dest) : r_dest;
case kSingle: // Intentional fall-through.
case k32: // Intentional fall-trough.
+ case kReference:
r_dest = Check32BitReg(r_dest);
scale = 2;
if (r_dest.IsFloat()) {
@@ -1185,11 +1181,9 @@
alt_opcode = FWIDE(kA64Stur3rXd);
}
break;
- case kReference:
- // TODO(Arm64): r_src must be 64-bit below. Remove the hack below.
- r_src = (r_src.Is64Bit()) ? As32BitReg(r_src) : r_src;
case kSingle: // Intentional fall-through.
case k32: // Intentional fall-trough.
+ case kReference:
r_src = Check32BitReg(r_src);
scale = 2;
if (r_src.IsFloat()) {
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index e262703..4cc1375 100755
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -1692,8 +1692,11 @@
FreeTemp(rl_temp_offset);
}
} else {
- LoadBaseIndexed(rl_object.reg, rl_offset.reg, rl_result.reg, 0,
- (rl_result.ref) ? kReference : k32);
+ if (rl_result.ref) {
+ LoadRefIndexed(rl_object.reg, rl_offset.reg, rl_result.reg, 0);
+ } else {
+ LoadBaseIndexed(rl_object.reg, rl_offset.reg, rl_result.reg, 0, k32);
+ }
}
if (is_volatile) {
@@ -1742,8 +1745,11 @@
}
} else {
rl_value = LoadValue(rl_src_value);
- StoreBaseIndexed(rl_object.reg, rl_offset.reg, rl_value.reg, 0,
- (rl_value.ref) ? kReference : k32);
+ if (rl_value.ref) {
+ StoreRefIndexed(rl_object.reg, rl_offset.reg, rl_value.reg, 0);
+ } else {
+ StoreBaseIndexed(rl_object.reg, rl_offset.reg, rl_value.reg, 0, k32);
+ }
}
// Free up the temp early, to ensure x86 doesn't run out of temporaries in MarkGCCard.
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 6768790..cfcc5c8 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -1023,8 +1023,9 @@
return LoadBaseDisp(r_base, displacement, r_dest, kReference, is_volatile);
}
// Load a reference at base + index and decompress into register.
- virtual LIR* LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest) {
- return LoadBaseIndexed(r_base, r_index, r_dest, 2, kReference);
+ virtual LIR* LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest,
+ int scale) {
+ return LoadBaseIndexed(r_base, r_index, r_dest, scale, kReference);
}
// Load Dalvik value with 32-bit memory storage. If compressed object reference, decompress.
virtual RegLocation LoadValue(RegLocation rl_src, RegisterClass op_kind);
@@ -1050,8 +1051,9 @@
return StoreBaseDisp(r_base, displacement, r_src, kReference, is_volatile);
}
// Store an uncompressed reference into a compressed 32-bit container by index.
- virtual LIR* StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src) {
- return StoreBaseIndexed(r_base, r_index, r_src, 2, kReference);
+ virtual LIR* StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src,
+ int scale) {
+ return StoreBaseIndexed(r_base, r_index, r_src, scale, kReference);
}
// Store 32 bits, regardless of target.
virtual LIR* Store32Disp(RegStorage r_base, int displacement, RegStorage r_src) {