summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/dex/quick/mir_to_lir.cc32
-rwxr-xr-xcompiler/dex/quick/x86/int_x86.cc4
-rwxr-xr-xcompiler/dex/quick/x86/target_x86.cc6
3 files changed, 28 insertions, 14 deletions
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 524ee21e63..1ff64c9ee7 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -603,13 +603,13 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
}
case Instruction::AGET_WIDE:
- GenArrayGet(opt_flags, k64, rl_src[0], rl_src[1], rl_dest, 3);
+ GenArrayGet(opt_flags, rl_dest.fp ? kDouble : k64, rl_src[0], rl_src[1], rl_dest, 3);
break;
case Instruction::AGET_OBJECT:
GenArrayGet(opt_flags, kReference, rl_src[0], rl_src[1], rl_dest, 2);
break;
case Instruction::AGET:
- GenArrayGet(opt_flags, k32, rl_src[0], rl_src[1], rl_dest, 2);
+ GenArrayGet(opt_flags, rl_dest.fp ? kSingle : k32, rl_src[0], rl_src[1], rl_dest, 2);
break;
case Instruction::AGET_BOOLEAN:
GenArrayGet(opt_flags, kUnsignedByte, rl_src[0], rl_src[1], rl_dest, 0);
@@ -624,10 +624,10 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
GenArrayGet(opt_flags, kSignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
break;
case Instruction::APUT_WIDE:
- GenArrayPut(opt_flags, k64, rl_src[1], rl_src[2], rl_src[0], 3, false);
+ GenArrayPut(opt_flags, rl_src[0].fp ? kDouble : k64, rl_src[1], rl_src[2], rl_src[0], 3, false);
break;
case Instruction::APUT:
- GenArrayPut(opt_flags, k32, rl_src[1], rl_src[2], rl_src[0], 2, false);
+ GenArrayPut(opt_flags, rl_src[0].fp ? kSingle : k32, rl_src[1], rl_src[2], rl_src[0], 2, false);
break;
case Instruction::APUT_OBJECT: {
bool is_null = mir_graph_->IsConstantNullRef(rl_src[0]);
@@ -661,11 +661,19 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
case Instruction::IGET_WIDE:
// kPrimLong and kPrimDouble share the same entrypoints.
- GenIGet(mir, opt_flags, k64, Primitive::kPrimLong, rl_dest, rl_src[0]);
+ if (rl_dest.fp) {
+ GenIGet(mir, opt_flags, kDouble, Primitive::kPrimDouble, rl_dest, rl_src[0]);
+ } else {
+ GenIGet(mir, opt_flags, k64, Primitive::kPrimLong, rl_dest, rl_src[0]);
+ }
break;
case Instruction::IGET:
- GenIGet(mir, opt_flags, k32, Primitive::kPrimInt, rl_dest, rl_src[0]);
+ if (rl_dest.fp) {
+ GenIGet(mir, opt_flags, kSingle, Primitive::kPrimFloat, rl_dest, rl_src[0]);
+ } else {
+ GenIGet(mir, opt_flags, k32, Primitive::kPrimInt, rl_dest, rl_src[0]);
+ }
break;
case Instruction::IGET_CHAR:
@@ -685,7 +693,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
break;
case Instruction::IPUT_WIDE:
- GenIPut(mir, opt_flags, k64, rl_src[0], rl_src[1]);
+ GenIPut(mir, opt_flags, rl_src[0].fp ? kDouble : k64, rl_src[0], rl_src[1]);
break;
case Instruction::IPUT_OBJECT:
@@ -693,7 +701,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
break;
case Instruction::IPUT:
- GenIPut(mir, opt_flags, k32, rl_src[0], rl_src[1]);
+ GenIPut(mir, opt_flags, rl_src[0].fp ? kSingle : k32, rl_src[0], rl_src[1]);
break;
case Instruction::IPUT_BYTE:
@@ -714,7 +722,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
break;
case Instruction::SGET:
- GenSget(mir, rl_dest, k32, Primitive::kPrimInt);
+ GenSget(mir, rl_dest, rl_dest.fp ? kSingle : k32, Primitive::kPrimInt);
break;
case Instruction::SGET_CHAR:
@@ -735,7 +743,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
case Instruction::SGET_WIDE:
// kPrimLong and kPrimDouble share the same entrypoints.
- GenSget(mir, rl_dest, k64, Primitive::kPrimLong);
+ GenSget(mir, rl_dest, rl_dest.fp ? kDouble : k64, Primitive::kPrimDouble);
break;
case Instruction::SPUT_OBJECT:
@@ -743,7 +751,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
break;
case Instruction::SPUT:
- GenSput(mir, rl_src[0], k32);
+ GenSput(mir, rl_src[0], rl_src[0].fp ? kSingle : k32);
break;
case Instruction::SPUT_BYTE:
@@ -761,7 +769,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
case Instruction::SPUT_WIDE:
- GenSput(mir, rl_src[0], k64);
+ GenSput(mir, rl_src[0], rl_src[0].fp ? kDouble : k64);
break;
case Instruction::INVOKE_STATIC_RANGE:
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 85ab92bc08..a79f2993ee 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -2319,7 +2319,7 @@ void X86Mir2Lir::OpRegThreadMem(OpKind op, RegStorage r_dest, ThreadOffset<8> th
*/
void X86Mir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_dest, int scale) {
- RegisterClass reg_class = RegClassBySize(size);
+ RegisterClass reg_class = RegClassForFieldLoadStore(size, false);
int len_offset = mirror::Array::LengthOffset().Int32Value();
RegLocation rl_result;
rl_array = LoadValue(rl_array, kRefReg);
@@ -2368,7 +2368,7 @@ void X86Mir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
*/
void X86Mir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_src, int scale, bool card_mark) {
- RegisterClass reg_class = RegClassBySize(size);
+ RegisterClass reg_class = RegClassForFieldLoadStore(size, false);
int len_offset = mirror::Array::LengthOffset().Int32Value();
int data_offset;
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 97732e2c12..142acbc8a4 100755
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -798,6 +798,12 @@ bool X86Mir2Lir::IsUnconditionalBranch(LIR* lir) {
}
RegisterClass X86Mir2Lir::RegClassForFieldLoadStore(OpSize size, bool is_volatile) {
+ // Prefer XMM registers. Fixes a problem with iget/iput to a FP when cached temporary
+ // with same VR is a Core register.
+ if (size == kSingle || size == kDouble) {
+ return kFPReg;
+ }
+
// X86_64 can handle any size.
if (cu_->target64) {
return RegClassBySize(size);