summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/compiler_enums.h1
-rw-r--r--compiler/dex/mir_graph.h1
-rw-r--r--compiler/dex/quick/arm/codegen_arm.h10
-rw-r--r--compiler/dex/quick/arm/int_arm.cc18
-rw-r--r--compiler/dex/quick/arm64/codegen_arm64.h12
-rw-r--r--compiler/dex/quick/arm64/int_arm64.cc21
-rw-r--r--compiler/dex/quick/gen_common.cc14
-rw-r--r--compiler/dex/quick/mips/codegen_mips.h10
-rw-r--r--compiler/dex/quick/mips/int_mips.cc13
-rw-r--r--compiler/dex/quick/mir_to_lir.cc14
-rw-r--r--compiler/dex/quick/mir_to_lir.h13
-rw-r--r--compiler/dex/quick/x86/codegen_x86.h23
-rwxr-xr-xcompiler/dex/quick/x86/int_x86.cc49
-rwxr-xr-xcompiler/dex/quick/x86/target_x86.cc2
14 files changed, 109 insertions, 92 deletions
diff --git a/compiler/dex/compiler_enums.h b/compiler/dex/compiler_enums.h
index 78da420339..c6c5ca7d4f 100644
--- a/compiler/dex/compiler_enums.h
+++ b/compiler/dex/compiler_enums.h
@@ -306,6 +306,7 @@ enum MIROptimizationFlagPositions {
kMIRIgnoreRangeCheck,
kMIRRangeCheckOnly,
kMIRIgnoreClInitCheck,
+ kMirIgnoreDivZeroCheck,
kMIRInlined, // Invoke is inlined (ie dead).
kMIRInlinedPred, // Invoke is inlined via prediction.
kMIRCallee, // Instruction is inlined from callee.
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index a405af16a3..5c74e9e6bf 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -147,6 +147,7 @@ enum OatMethodAttributes {
#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
#define MIR_IGNORE_CLINIT_CHECK (1 << kMIRIgnoreClInitCheck)
+#define MIR_IGNORE_DIV_ZERO_CHECK (1 << kMirIgnoreDivZeroCheck)
#define MIR_INLINED (1 << kMIRInlined)
#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
#define MIR_CALLEE (1 << kMIRCallee)
diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h
index 1c87a0386c..6fd29f25dc 100644
--- a/compiler/dex/quick/arm/codegen_arm.h
+++ b/compiler/dex/quick/arm/codegen_arm.h
@@ -87,15 +87,15 @@ class ArmMir2Lir FINAL : public Mir2Lir {
// Required for target - Dalvik-level generators.
void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2) OVERRIDE;
+ RegLocation rl_src2, int flags) OVERRIDE;
void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2);
+ RegLocation rl_src1, RegLocation rl_src2, int flags);
void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_dest, int scale);
void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index,
RegLocation rl_src, int scale, bool card_mark);
void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_shift);
+ RegLocation rl_src1, RegLocation rl_shift, int flags);
void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
RegLocation rl_src2);
void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
@@ -224,8 +224,8 @@ class ArmMir2Lir FINAL : public Mir2Lir {
void InsertFixupBefore(LIR* prev_lir, LIR* orig_lir, LIR* new_lir);
void AssignDataOffsets();
RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2,
- bool is_div, bool check_zero);
- RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div);
+ bool is_div, int flags) OVERRIDE;
+ RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div) OVERRIDE;
typedef struct {
OpKind op;
uint32_t shift;
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index 018dc1c0c6..9742243632 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -678,7 +678,7 @@ bool ArmMir2Lir::EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit)
}
RegLocation ArmMir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2, bool is_div, bool check_zero) {
+ RegLocation rl_src2, bool is_div, int flags) {
LOG(FATAL) << "Unexpected use of GenDivRem for Arm";
return rl_dest;
}
@@ -1264,7 +1264,7 @@ void ArmMir2Lir::GenMulLong(Instruction::Code opcode, RegLocation rl_dest,
}
void ArmMir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2) {
+ RegLocation rl_src2, int flags) {
switch (opcode) {
case Instruction::MUL_LONG:
case Instruction::MUL_LONG_2ADDR:
@@ -1279,7 +1279,7 @@ void ArmMir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, R
}
// Fallback for all other ops.
- Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
+ Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags);
}
/*
@@ -1464,7 +1464,8 @@ void ArmMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
void ArmMir2Lir::GenShiftImmOpLong(Instruction::Code opcode,
- RegLocation rl_dest, RegLocation rl_src, RegLocation rl_shift) {
+ RegLocation rl_dest, RegLocation rl_src, RegLocation rl_shift,
+ int flags) {
rl_src = LoadValueWide(rl_src, kCoreReg);
// Per spec, we only care about low 6 bits of shift amount.
int shift_amount = mir_graph_->ConstantValue(rl_shift) & 0x3f;
@@ -1537,11 +1538,12 @@ void ArmMir2Lir::GenShiftImmOpLong(Instruction::Code opcode,
}
void ArmMir2Lir::GenArithImmOpLong(Instruction::Code opcode,
- RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) {
+ RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2,
+ int flags) {
if ((opcode == Instruction::SUB_LONG_2ADDR) || (opcode == Instruction::SUB_LONG)) {
if (!rl_src2.is_const) {
// Don't bother with special handling for subtract from immediate.
- GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
+ GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags);
return;
}
} else {
@@ -1552,7 +1554,7 @@ void ArmMir2Lir::GenArithImmOpLong(Instruction::Code opcode,
}
}
if (PartiallyIntersects(rl_src1, rl_dest)) {
- GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
+ GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags);
return;
}
DCHECK(rl_src2.is_const);
@@ -1569,7 +1571,7 @@ void ArmMir2Lir::GenArithImmOpLong(Instruction::Code opcode,
case Instruction::SUB_LONG:
case Instruction::SUB_LONG_2ADDR:
if ((mod_imm_lo < 0) || (mod_imm_hi < 0)) {
- GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
+ GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags);
return;
}
break;
diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h
index 510bd4c5de..9f0260635d 100644
--- a/compiler/dex/quick/arm64/codegen_arm64.h
+++ b/compiler/dex/quick/arm64/codegen_arm64.h
@@ -141,13 +141,13 @@ class Arm64Mir2Lir FINAL : public Mir2Lir {
void GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
RegLocation lr_shift) OVERRIDE;
void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2) OVERRIDE;
+ RegLocation rl_src2, int flags) OVERRIDE;
void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index,
RegLocation rl_dest, int scale) OVERRIDE;
void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index,
RegLocation rl_src, int scale, bool card_mark) OVERRIDE;
void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_shift) OVERRIDE;
+ RegLocation rl_shift, int flags) OVERRIDE;
void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
RegLocation rl_src2) OVERRIDE;
void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
@@ -173,7 +173,7 @@ class Arm64Mir2Lir FINAL : public Mir2Lir {
bool GenInlinedArrayCopyCharArray(CallInfo* info) OVERRIDE;
void GenIntToLong(RegLocation rl_dest, RegLocation rl_src) OVERRIDE;
void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2) OVERRIDE;
+ RegLocation rl_src2, int flags) OVERRIDE;
RegLocation GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegStorage reg_hi, bool is_div)
OVERRIDE;
RegLocation GenDivRemLit(RegLocation rl_dest, RegStorage reg_lo, int lit, bool is_div)
@@ -363,8 +363,8 @@ class Arm64Mir2Lir FINAL : public Mir2Lir {
void InsertFixupBefore(LIR* prev_lir, LIR* orig_lir, LIR* new_lir);
void AssignDataOffsets();
RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2,
- bool is_div, bool check_zero);
- RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div);
+ bool is_div, int flags) OVERRIDE;
+ RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div) OVERRIDE;
size_t GetLoadStoreSize(LIR* lir);
bool SmallLiteralDivRem64(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src,
@@ -413,7 +413,7 @@ class Arm64Mir2Lir FINAL : public Mir2Lir {
void GenNotLong(RegLocation rl_dest, RegLocation rl_src);
void GenNegLong(RegLocation rl_dest, RegLocation rl_src);
void GenDivRemLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2, bool is_div);
+ RegLocation rl_src2, bool is_div, int flags);
InToRegStorageMapping in_to_reg_storage_mapping_;
static const A64EncodingMap EncodingMap[kA64Last];
diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc
index abcb30f49a..6e7241dcd6 100644
--- a/compiler/dex/quick/arm64/int_arm64.cc
+++ b/compiler/dex/quick/arm64/int_arm64.cc
@@ -614,7 +614,7 @@ RegLocation Arm64Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegStorage reg1, int
}
RegLocation Arm64Mir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2, bool is_div, bool check_zero) {
+ RegLocation rl_src2, bool is_div, int flags) {
LOG(FATAL) << "Unexpected use of GenDivRem for Arm64";
return rl_dest;
}
@@ -1020,7 +1020,7 @@ void Arm64Mir2Lir::GenIntToLong(RegLocation rl_dest, RegLocation rl_src) {
}
void Arm64Mir2Lir::GenDivRemLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2, bool is_div) {
+ RegLocation rl_src1, RegLocation rl_src2, bool is_div, int flags) {
if (rl_src2.is_const) {
DCHECK(rl_src2.wide);
int64_t lit = mir_graph_->ConstantValueWide(rl_src2);
@@ -1032,7 +1032,9 @@ void Arm64Mir2Lir::GenDivRemLong(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_result;
rl_src1 = LoadValueWide(rl_src1, kCoreReg);
rl_src2 = LoadValueWide(rl_src2, kCoreReg);
- GenDivZeroCheck(rl_src2.reg);
+ if ((flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) {
+ GenDivZeroCheck(rl_src2.reg);
+ }
rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, is_div);
StoreValueWide(rl_dest, rl_result);
}
@@ -1067,7 +1069,7 @@ void Arm64Mir2Lir::GenNotLong(RegLocation rl_dest, RegLocation rl_src) {
}
void Arm64Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2) {
+ RegLocation rl_src1, RegLocation rl_src2, int flags) {
switch (opcode) {
case Instruction::NOT_LONG:
GenNotLong(rl_dest, rl_src2);
@@ -1086,11 +1088,11 @@ void Arm64Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
return;
case Instruction::DIV_LONG:
case Instruction::DIV_LONG_2ADDR:
- GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ true);
+ GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ true, flags);
return;
case Instruction::REM_LONG:
case Instruction::REM_LONG_2ADDR:
- GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ false);
+ GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ false, flags);
return;
case Instruction::AND_LONG_2ADDR:
case Instruction::AND_LONG:
@@ -1312,7 +1314,8 @@ void Arm64Mir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
}
void Arm64Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode,
- RegLocation rl_dest, RegLocation rl_src, RegLocation rl_shift) {
+ RegLocation rl_dest, RegLocation rl_src, RegLocation rl_shift,
+ int flags) {
OpKind op = kOpBkpt;
// Per spec, we only care about low 6 bits of shift amount.
int shift_amount = mir_graph_->ConstantValue(rl_shift) & 0x3f;
@@ -1344,7 +1347,7 @@ void Arm64Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode,
}
void Arm64Mir2Lir::GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2) {
+ RegLocation rl_src1, RegLocation rl_src2, int flags) {
OpKind op = kOpBkpt;
switch (opcode) {
case Instruction::ADD_LONG:
@@ -1373,7 +1376,7 @@ void Arm64Mir2Lir::GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_de
if (op == kOpSub) {
if (!rl_src2.is_const) {
- return GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
+ return GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags);
}
} else {
// Associativity.
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index a33d15fb32..2abfcc3639 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -1501,7 +1501,7 @@ void Mir2Lir::GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest,
void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2) {
+ RegLocation rl_src1, RegLocation rl_src2, int flags) {
DCHECK(cu_->instruction_set != kX86 && cu_->instruction_set != kX86_64);
OpKind op = kOpBkpt;
bool is_div_rem = false;
@@ -1600,7 +1600,7 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
if (cu_->instruction_set == kMips || cu_->instruction_set == kArm64) {
rl_src1 = LoadValue(rl_src1, kCoreReg);
rl_src2 = LoadValue(rl_src2, kCoreReg);
- if (check_zero) {
+ if (check_zero && (flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) {
GenDivZeroCheck(rl_src2.reg);
}
rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv);
@@ -1612,7 +1612,7 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
// calculate using a MUL and subtract.
rl_src1 = LoadValue(rl_src1, kCoreReg);
rl_src2 = LoadValue(rl_src2, kCoreReg);
- if (check_zero) {
+ if (check_zero && (flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) {
GenDivZeroCheck(rl_src2.reg);
}
rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv);
@@ -1626,7 +1626,7 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
LoadValueDirectFixed(rl_src2, TargetReg(kArg1, kNotWide));
RegStorage r_tgt = CallHelperSetup(kQuickIdivmod);
LoadValueDirectFixed(rl_src1, TargetReg(kArg0, kNotWide));
- if (check_zero) {
+ if (check_zero && (flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) {
GenDivZeroCheck(TargetReg(kArg1, kNotWide));
}
// NOTE: callout here is not a safepoint.
@@ -1914,7 +1914,7 @@ void Mir2Lir::GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, Re
}
void Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2) {
+ RegLocation rl_src1, RegLocation rl_src2, int flags) {
RegLocation rl_result;
OpKind first_op = kOpBkpt;
OpKind second_op = kOpBkpt;
@@ -1999,7 +1999,9 @@ void Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
RegStorage r_tmp2 = TargetReg(kArg2, kWide);
LoadValueDirectWideFixed(rl_src2, r_tmp2);
RegStorage r_tgt = CallHelperSetup(target);
- GenDivZeroCheckWide(r_tmp2);
+ if ((flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) {
+ GenDivZeroCheckWide(r_tmp2);
+ }
LoadValueDirectWideFixed(rl_src1, r_tmp1);
// NOTE: callout here is not a safepoint
CallHelper(r_tgt, target, false /* not safepoint */);
diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h
index bd709f38ae..508d474404 100644
--- a/compiler/dex/quick/mips/codegen_mips.h
+++ b/compiler/dex/quick/mips/codegen_mips.h
@@ -86,13 +86,13 @@ class MipsMir2Lir FINAL : public Mir2Lir {
// Required for target - Dalvik-level generators.
void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2);
+ RegLocation rl_src1, RegLocation rl_src2, int flags);
void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_dest, int scale);
void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_src, int scale, bool card_mark);
void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_shift);
+ RegLocation rl_shift, int flags);
void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
RegLocation rl_src2);
void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
@@ -108,7 +108,7 @@ class MipsMir2Lir FINAL : public Mir2Lir {
bool GenInlinedPeek(CallInfo* info, OpSize size);
bool GenInlinedPoke(CallInfo* info, OpSize size);
void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2) OVERRIDE;
+ RegLocation rl_src2, int flags) OVERRIDE;
RegLocation GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegStorage reg_hi, bool is_div);
RegLocation GenDivRemLit(RegLocation rl_dest, RegStorage reg_lo, int lit, bool is_div);
void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
@@ -190,8 +190,8 @@ class MipsMir2Lir FINAL : public Mir2Lir {
void ConvertShortToLongBranch(LIR* lir);
RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2, bool is_div, bool check_zero);
- RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div);
+ RegLocation rl_src2, bool is_div, int flags) OVERRIDE;
+ RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div) OVERRIDE;
};
} // namespace art
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index 30aa611f9f..baf7311398 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -263,7 +263,7 @@ RegLocation MipsMir2Lir::GenDivRemLit(RegLocation rl_dest, RegStorage reg1, int
}
RegLocation MipsMir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2, bool is_div, bool check_zero) {
+ RegLocation rl_src2, bool is_div, int flags) {
LOG(FATAL) << "Unexpected use of GenDivRem for Mips";
return rl_dest;
}
@@ -437,7 +437,7 @@ void MipsMir2Lir::GenSubLong(Instruction::Code opcode, RegLocation rl_dest,
}
void MipsMir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2) {
+ RegLocation rl_src2, int flags) {
switch (opcode) {
case Instruction::ADD_LONG:
case Instruction::ADD_LONG_2ADDR:
@@ -456,7 +456,7 @@ void MipsMir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
}
// Fallback for all other ops.
- Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
+ Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags);
}
void MipsMir2Lir::GenNegLong(RegLocation rl_dest, RegLocation rl_src) {
@@ -628,15 +628,16 @@ void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
}
void MipsMir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_shift) {
+ RegLocation rl_src1, RegLocation rl_shift, int flags) {
// Default implementation is just to ignore the constant case.
GenShiftOpLong(opcode, rl_dest, rl_src1, rl_shift);
}
void MipsMir2Lir::GenArithImmOpLong(Instruction::Code opcode,
- RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) {
+ RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2,
+ int flags) {
// Default - bail to non-const handler.
- GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
+ GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags);
}
} // namespace art
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 4399981272..408606d366 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -928,12 +928,12 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
case Instruction::NEG_INT:
case Instruction::NOT_INT:
- GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[0]);
+ GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[0], opt_flags);
break;
case Instruction::NEG_LONG:
case Instruction::NOT_LONG:
- GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[0]);
+ GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[0], opt_flags);
break;
case Instruction::NEG_FLOAT:
@@ -993,7 +993,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
GenArithOpIntLit(opcode, rl_dest, rl_src[0],
mir_graph_->ConstantValue(rl_src[1].orig_sreg));
} else {
- GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1]);
+ GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1], opt_flags);
}
break;
@@ -1013,7 +1013,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[1]), opcode)) {
GenArithOpIntLit(opcode, rl_dest, rl_src[0], mir_graph_->ConstantValue(rl_src[1]));
} else {
- GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1]);
+ GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1], opt_flags);
}
break;
@@ -1028,7 +1028,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
case Instruction::OR_LONG_2ADDR:
case Instruction::XOR_LONG_2ADDR:
if (rl_src[0].is_const || rl_src[1].is_const) {
- GenArithImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
+ GenArithImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1], opt_flags);
break;
}
FALLTHROUGH_INTENDED;
@@ -1038,7 +1038,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
case Instruction::MUL_LONG_2ADDR:
case Instruction::DIV_LONG_2ADDR:
case Instruction::REM_LONG_2ADDR:
- GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
+ GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[1], opt_flags);
break;
case Instruction::SHL_LONG:
@@ -1048,7 +1048,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
case Instruction::SHR_LONG_2ADDR:
case Instruction::USHR_LONG_2ADDR:
if (rl_src[1].is_const) {
- GenShiftImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
+ GenShiftImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1], opt_flags);
} else {
GenShiftOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
}
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index ea93bbe7f2..3e0844bec1 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -857,7 +857,7 @@ class Mir2Lir : public Backend {
void GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src, int lit);
virtual void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2);
+ RegLocation rl_src1, RegLocation rl_src2, int flags);
void GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_dest, RegLocation rl_src);
virtual void GenSuspendTest(int opt_flags);
virtual void GenSuspendTestAndBranch(int opt_flags, LIR* target);
@@ -865,7 +865,7 @@ class Mir2Lir : public Backend {
// This will be overridden by x86 implementation.
virtual void GenConstWide(RegLocation rl_dest, int64_t value);
virtual void GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2);
+ RegLocation rl_src1, RegLocation rl_src2, int flags);
// Shared by all targets - implemented in gen_invoke.cc.
LIR* CallHelper(RegStorage r_tgt, QuickEntrypointEnum trampoline, bool safepoint_pc,
@@ -1259,7 +1259,7 @@ class Mir2Lir : public Backend {
// Required for target - Dalvik-level generators.
virtual void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2) = 0;
+ RegLocation rl_src1, RegLocation rl_src2, int flags) = 0;
virtual void GenArithOpDouble(Instruction::Code opcode,
RegLocation rl_dest, RegLocation rl_src1,
RegLocation rl_src2) = 0;
@@ -1297,10 +1297,11 @@ class Mir2Lir : public Backend {
* @param rl_src1 Numerator Location.
* @param rl_src2 Divisor Location.
* @param is_div 'true' if this is a division, 'false' for a remainder.
- * @param check_zero 'true' if an exception should be generated if the divisor is 0.
+ * @param flags The instruction optimization flags. It can include information
+ * if exception check can be elided.
*/
virtual RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2, bool is_div, bool check_zero) = 0;
+ RegLocation rl_src2, bool is_div, int flags) = 0;
/*
* @brief Generate an integer div or rem operation by a literal.
* @param rl_dest Destination Location.
@@ -1382,7 +1383,7 @@ class Mir2Lir : public Backend {
RegLocation rl_index, RegLocation rl_src, int scale,
bool card_mark) = 0;
virtual void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_shift) = 0;
+ RegLocation rl_src1, RegLocation rl_shift, int flags) = 0;
// Required for target - single operation generators.
virtual LIR* OpUnconditionalBranch(LIR* target) = 0;
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index b3544dafba..7b5b831e38 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -180,11 +180,11 @@ class X86Mir2Lir : public Mir2Lir {
// Long instructions.
void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2) OVERRIDE;
+ RegLocation rl_src2, int flags) OVERRIDE;
void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2) OVERRIDE;
+ RegLocation rl_src2, int flags) OVERRIDE;
void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_shift) OVERRIDE;
+ RegLocation rl_src1, RegLocation rl_shift, int flags) OVERRIDE;
void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) OVERRIDE;
void GenIntToLong(RegLocation rl_dest, RegLocation rl_src) OVERRIDE;
void GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest,
@@ -314,9 +314,10 @@ class X86Mir2Lir : public Mir2Lir {
* @param rl_dest Destination for the result.
* @param rl_lhs Left hand operand.
* @param rl_rhs Right hand operand.
+ * @param flags The instruction optimization flags.
*/
void GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_lhs,
- RegLocation rl_rhs) OVERRIDE;
+ RegLocation rl_rhs, int flags) OVERRIDE;
/*
* @brief Load the Method* of a dex method into the register.
@@ -768,10 +769,11 @@ class X86Mir2Lir : public Mir2Lir {
* @param rl_src1 Numerator Location.
* @param rl_src2 Divisor Location.
* @param is_div 'true' if this is a division, 'false' for a remainder.
- * @param check_zero 'true' if an exception should be generated if the divisor is 0.
+ * @param flags The instruction optimization flags. It can include information
+ * if exception check can be elided.
*/
RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2,
- bool is_div, bool check_zero);
+ bool is_div, int flags);
/*
* @brief Generate an integer div or rem operation by a literal.
@@ -788,10 +790,11 @@ class X86Mir2Lir : public Mir2Lir {
* @param rl_dest The destination.
* @param rl_src The value to be shifted.
* @param shift_amount How much to shift.
+ * @param flags The instruction optimization flags.
* @returns the RegLocation of the result.
*/
RegLocation GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src, int shift_amount);
+ RegLocation rl_src, int shift_amount, int flags);
/*
* Generate an imul of a register by a constant or a better sequence.
* @param dest Destination Register.
@@ -858,13 +861,13 @@ class X86Mir2Lir : public Mir2Lir {
// Try to do a long multiplication where rl_src2 is a constant. This simplified setup might fail,
// in which case false will be returned.
- bool GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64_t val);
+ bool GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64_t val, int flags);
void GenMulLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2);
+ RegLocation rl_src2, int flags);
void GenNotLong(RegLocation rl_dest, RegLocation rl_src);
void GenNegLong(RegLocation rl_dest, RegLocation rl_src);
void GenDivRemLong(Instruction::Code, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2, bool is_div);
+ RegLocation rl_src2, bool is_div, int flags);
void SpillCoreRegs();
void UnSpillCoreRegs();
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index acf5599d5f..aa1bf7fe6d 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -768,7 +768,7 @@ RegLocation X86Mir2Lir::GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegSto
}
RegLocation X86Mir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2, bool is_div, bool check_zero) {
+ RegLocation rl_src2, bool is_div, int flags) {
// We have to use fixed registers, so flush all the temps.
// Prepare for explicit register usage.
@@ -783,7 +783,7 @@ RegLocation X86Mir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1,
// Copy LHS sign bit into EDX.
NewLIR0(kx86Cdq32Da);
- if (check_zero) {
+ if ((flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) {
// Handle division by zero case.
GenDivZeroCheck(rs_r1);
}
@@ -1506,7 +1506,7 @@ void X86Mir2Lir::GenImulMemImm(RegStorage dest, int sreg, int displacement, int
}
void X86Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2) {
+ RegLocation rl_src2, int flags) {
if (!cu_->target64) {
// Some x86 32b ops are fallback.
switch (opcode) {
@@ -1515,7 +1515,7 @@ void X86Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, R
case Instruction::DIV_LONG_2ADDR:
case Instruction::REM_LONG:
case Instruction::REM_LONG_2ADDR:
- Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
+ Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags);
return;
default:
@@ -1541,17 +1541,17 @@ void X86Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, R
case Instruction::MUL_LONG:
case Instruction::MUL_LONG_2ADDR:
- GenMulLong(opcode, rl_dest, rl_src1, rl_src2);
+ GenMulLong(opcode, rl_dest, rl_src1, rl_src2, flags);
return;
case Instruction::DIV_LONG:
case Instruction::DIV_LONG_2ADDR:
- GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ true);
+ GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ true, flags);
return;
case Instruction::REM_LONG:
case Instruction::REM_LONG_2ADDR:
- GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ false);
+ GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ false, flags);
return;
case Instruction::AND_LONG_2ADDR:
@@ -1579,7 +1579,7 @@ void X86Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, R
}
}
-bool X86Mir2Lir::GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64_t val) {
+bool X86Mir2Lir::GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64_t val, int flags) {
// All memory accesses below reference dalvik regs.
ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
@@ -1597,14 +1597,14 @@ bool X86Mir2Lir::GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64
StoreValueWide(rl_dest, rl_src1);
return true;
} else if (val == 2) {
- GenArithOpLong(Instruction::ADD_LONG, rl_dest, rl_src1, rl_src1);
+ GenArithOpLong(Instruction::ADD_LONG, rl_dest, rl_src1, rl_src1, flags);
return true;
} else if (IsPowerOfTwo(val)) {
int shift_amount = LowestSetBit(val);
if (!PartiallyIntersects(rl_src1, rl_dest)) {
rl_src1 = LoadValueWide(rl_src1, kCoreReg);
RegLocation rl_result = GenShiftImmOpLong(Instruction::SHL_LONG, rl_dest, rl_src1,
- shift_amount);
+ shift_amount, flags);
StoreValueWide(rl_dest, rl_result);
return true;
}
@@ -1658,13 +1658,13 @@ bool X86Mir2Lir::GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64
}
void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2) {
+ RegLocation rl_src2, int flags) {
if (rl_src1.is_const) {
std::swap(rl_src1, rl_src2);
}
if (rl_src2.is_const) {
- if (GenMulLongConst(rl_dest, rl_src1, mir_graph_->ConstantValueWide(rl_src2))) {
+ if (GenMulLongConst(rl_dest, rl_src1, mir_graph_->ConstantValueWide(rl_src2), flags)) {
return;
}
}
@@ -2164,7 +2164,7 @@ void X86Mir2Lir::GenDivRemLongLit(RegLocation rl_dest, RegLocation rl_src,
}
void X86Mir2Lir::GenDivRemLong(Instruction::Code, RegLocation rl_dest, RegLocation rl_src1,
- RegLocation rl_src2, bool is_div) {
+ RegLocation rl_src2, bool is_div, int flags) {
if (!cu_->target64) {
LOG(FATAL) << "Unexpected use GenDivRemLong()";
return;
@@ -2191,7 +2191,9 @@ void X86Mir2Lir::GenDivRemLong(Instruction::Code, RegLocation rl_dest, RegLocati
NewLIR0(kx86Cqo64Da);
// Handle division by zero case.
- GenDivZeroCheckWide(rs_r1q);
+ if ((flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) {
+ GenDivZeroCheckWide(rs_r1q);
+ }
// Have to catch 0x8000000000000000/-1 case, or we will get an exception!
NewLIR2(kX86Cmp64RI8, rs_r1q.GetReg(), -1);
@@ -2392,7 +2394,7 @@ void X86Mir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
}
RegLocation X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src, int shift_amount) {
+ RegLocation rl_src, int shift_amount, int flags) {
RegLocation rl_result = EvalLocWide(rl_dest, kCoreReg, true);
if (cu_->target64) {
OpKind op = static_cast<OpKind>(0); /* Make gcc happy */
@@ -2477,7 +2479,7 @@ RegLocation X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation
}
void X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src, RegLocation rl_shift) {
+ RegLocation rl_src, RegLocation rl_shift, int flags) {
// Per spec, we only care about low 6 bits of shift amount.
int shift_amount = mir_graph_->ConstantValue(rl_shift) & 0x3f;
if (shift_amount == 0) {
@@ -2487,7 +2489,7 @@ void X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest
} else if (shift_amount == 1 &&
(opcode == Instruction::SHL_LONG || opcode == Instruction::SHL_LONG_2ADDR)) {
// Need to handle this here to avoid calling StoreValueWide twice.
- GenArithOpLong(Instruction::ADD_LONG, rl_dest, rl_src, rl_src);
+ GenArithOpLong(Instruction::ADD_LONG, rl_dest, rl_src, rl_src, flags);
return;
}
if (PartiallyIntersects(rl_src, rl_dest)) {
@@ -2495,12 +2497,13 @@ void X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest
return;
}
rl_src = LoadValueWide(rl_src, kCoreReg);
- RegLocation rl_result = GenShiftImmOpLong(opcode, rl_dest, rl_src, shift_amount);
+ RegLocation rl_result = GenShiftImmOpLong(opcode, rl_dest, rl_src, shift_amount, flags);
StoreValueWide(rl_dest, rl_result);
}
void X86Mir2Lir::GenArithImmOpLong(Instruction::Code opcode,
- RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) {
+ RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2,
+ int flags) {
bool isConstSuccess = false;
switch (opcode) {
case Instruction::ADD_LONG:
@@ -2519,7 +2522,7 @@ void X86Mir2Lir::GenArithImmOpLong(Instruction::Code opcode,
if (rl_src2.is_const) {
isConstSuccess = GenLongLongImm(rl_dest, rl_src1, rl_src2, opcode);
} else {
- GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
+ GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags);
isConstSuccess = true;
}
break;
@@ -2545,7 +2548,7 @@ void X86Mir2Lir::GenArithImmOpLong(Instruction::Code opcode,
if (!isConstSuccess) {
// Default - bail to non-const handler.
- GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
+ GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags);
}
}
@@ -2917,7 +2920,7 @@ void X86Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx,
}
void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_lhs, RegLocation rl_rhs) {
+ RegLocation rl_lhs, RegLocation rl_rhs, int flags) {
OpKind op = kOpBkpt;
bool is_div_rem = false;
bool unary = false;
@@ -3022,7 +3025,7 @@ void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
// Get the div/rem stuff out of the way.
if (is_div_rem) {
- rl_result = GenDivRem(rl_dest, rl_lhs, rl_rhs, op == kOpDiv, true);
+ rl_result = GenDivRem(rl_dest, rl_lhs, rl_rhs, op == kOpDiv, flags);
StoreValue(rl_dest, rl_result);
return;
}
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 2ef4c218c3..79d5eebe17 100755
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -2166,7 +2166,7 @@ void X86Mir2Lir::GenAddReduceVector(BasicBlock *bb, MIR *mir) {
NewLIR2(kX86MovdrxRR, temp_loc.reg.GetHighReg(), vector_src.GetReg());
}
- GenArithOpLong(Instruction::ADD_LONG_2ADDR, rl_dest, temp_loc, temp_loc);
+ GenArithOpLong(Instruction::ADD_LONG_2ADDR, rl_dest, temp_loc, temp_loc, mir->optimization_flags);
} else if (opsize == kSignedByte || opsize == kUnsignedByte) {
RegStorage rs_tmp = Get128BitRegister(AllocTempDouble());
NewLIR2(kX86PxorRR, rs_tmp.GetReg(), rs_tmp.GetReg());