diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/dex/quick/arm/int_arm.cc | 1 | ||||
-rw-r--r-- | compiler/dex/quick/gen_common.cc | 6 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.cc | 4 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 1 | ||||
-rw-r--r-- | compiler/dex/quick/x86/codegen_x86.h | 1 | ||||
-rwxr-xr-x | compiler/dex/quick/x86/int_x86.cc | 20 |
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) { |