summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/quick/arm/int_arm.cc1
-rw-r--r--compiler/dex/quick/gen_common.cc6
-rw-r--r--compiler/dex/quick/mir_to_lir.cc4
-rw-r--r--compiler/dex/quick/mir_to_lir.h1
-rw-r--r--compiler/dex/quick/x86/codegen_x86.h1
-rwxr-xr-xcompiler/dex/quick/x86/int_x86.cc20
6 files changed, 30 insertions, 3 deletions
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index e38dbf5a8d..4aedbafcfb 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -1162,6 +1162,7 @@ void ArmMir2Lir::GenNegLong(RegLocation rl_dest, RegLocation rl_src) {
// Check for destructive overlap
if (rl_result.reg.GetLowReg() == rl_src.reg.GetHighReg()) {
RegStorage t_reg = AllocTemp();
+ OpRegCopy(t_reg, rl_result.reg.GetLow());
OpRegRegReg(kOpSub, rl_result.reg.GetLow(), z_reg, rl_src.reg.GetLow());
OpRegRegReg(kOpSbc, rl_result.reg.GetHigh(), z_reg, t_reg);
FreeTemp(t_reg);
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index 9be8719b5d..774176ebb1 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -322,6 +322,12 @@ void Mir2Lir::GenIntToLong(RegLocation rl_dest, RegLocation rl_src) {
StoreValueWide(rl_dest, rl_result);
}
+void Mir2Lir::GenLongToInt(RegLocation rl_dest, RegLocation rl_src) {
+ rl_src = UpdateLocWide(rl_src);
+ rl_src = NarrowRegLoc(rl_src);
+ StoreValue(rl_dest, rl_src);
+}
+
void Mir2Lir::GenIntNarrowing(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src) {
rl_src = LoadValue(rl_src, kCoreReg);
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 68856cdce0..320c0f4900 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -933,9 +933,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
break;
case Instruction::LONG_TO_INT:
- rl_src[0] = UpdateLocWide(rl_src[0]);
- rl_src[0] = NarrowRegLoc(rl_src[0]);
- StoreValue(rl_dest, rl_src[0]);
+ GenLongToInt(rl_dest, rl_src[0]);
break;
case Instruction::INT_TO_BYTE:
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 88b260c0eb..5d78a6e25c 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -810,6 +810,7 @@ class Mir2Lir : public Backend {
LIR* taken);
void GenCompareZeroAndBranch(Instruction::Code opcode, RegLocation rl_src, LIR* taken);
virtual void GenIntToLong(RegLocation rl_dest, RegLocation rl_src);
+ virtual void GenLongToInt(RegLocation rl_dest, RegLocation rl_src);
void GenIntNarrowing(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src);
void GenNewArray(uint32_t type_idx, RegLocation rl_dest,
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index 09e1482b4d..9cb0bf53e6 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -90,6 +90,7 @@ class X86Mir2Lir : public Mir2Lir {
OpSize size) OVERRIDE;
LIR* LoadConstantNoClobber(RegStorage r_dest, int value);
LIR* LoadConstantWide(RegStorage r_dest, int64_t value);
+ void GenLongToInt(RegLocation rl_dest, RegLocation rl_src);
LIR* StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src,
OpSize size, VolatileKind is_volatile) OVERRIDE;
LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale,
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index a063ce18c2..80cdc83497 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -3213,6 +3213,26 @@ void X86Mir2Lir::GenIntToLong(RegLocation rl_dest, RegLocation rl_src) {
StoreValueWide(rl_dest, rl_result);
}
+void X86Mir2Lir::GenLongToInt(RegLocation rl_dest, RegLocation rl_src) {
+ rl_src = UpdateLocWide(rl_src);
+ rl_src = NarrowRegLoc(rl_src);
+ StoreValue(rl_dest, rl_src);
+
+ if (cu_->target64) {
+ // if src and dest are in the same phys reg then StoreValue generates
+ // no operation but we need explicit 32-bit mov R, R to clear
+ // the higher 32-bits
+ rl_dest = UpdateLoc(rl_dest);
+ if (rl_src.location == kLocPhysReg && rl_dest.location == kLocPhysReg
+ && IsSameReg(rl_src.reg, rl_dest.reg)) {
+ LIR* copy_lir = OpRegCopyNoInsert(rl_dest.reg, rl_dest.reg);
+ // remove nop flag set by OpRegCopyNoInsert if src == dest
+ copy_lir->flags.is_nop = false;
+ AppendLIR(copy_lir);
+ }
+ }
+}
+
void X86Mir2Lir::GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src1, RegLocation rl_shift) {
if (!cu_->target64) {