bool GenInlinedRound(CallInfo* info, bool is_double) OVERRIDE;
bool GenInlinedPeek(CallInfo* info, OpSize size) OVERRIDE;
bool GenInlinedPoke(CallInfo* info, OpSize size) OVERRIDE;
+ bool GenInlinedAbsInt(CallInfo* info) OVERRIDE;
bool GenInlinedAbsLong(CallInfo* info) OVERRIDE;
bool GenInlinedArrayCopyCharArray(CallInfo* info) OVERRIDE;
void GenIntToLong(RegLocation rl_dest, RegLocation rl_src) OVERRIDE;
if (reg_class == kFPReg) {
NewLIR2(kA64Fabs2ff, rl_result.reg.GetReg(), rl_src.reg.GetReg());
} else {
- NewLIR4(kA64Ubfm4rrdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), 0, 30);
+ // Clear the sign bit in an integer register.
+ OpRegRegImm(kOpAnd, rl_result.reg, rl_src.reg, 0x7fffffff);
}
StoreValue(rl_dest, rl_result);
return true;
if (reg_class == kFPReg) {
NewLIR2(FWIDE(kA64Fabs2ff), rl_result.reg.GetReg(), rl_src.reg.GetReg());
} else {
- NewLIR4(WIDE(kA64Ubfm4rrdd), rl_result.reg.GetReg(), rl_src.reg.GetReg(), 0, 62);
+ // Clear the sign bit in an integer register.
+ OpRegRegImm64(kOpAnd, rl_result.reg, rl_src.reg, 0x7fffffffffffffff);
}
StoreValueWide(rl_dest, rl_result);
return true;
return rl_result;
}
+bool Arm64Mir2Lir::GenInlinedAbsInt(CallInfo* info) {
+ RegLocation rl_src = info->args[0];
+ rl_src = LoadValue(rl_src, kCoreReg);
+ RegLocation rl_dest = InlineTarget(info);
+ RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
+
+ // Compare the source value with zero. Write the negated value to the result if
+ // negative, otherwise write the original value.
+ OpRegImm(kOpCmp, rl_src.reg, 0);
+ NewLIR4(kA64Csneg4rrrc, rl_result.reg.GetReg(), rl_src.reg.GetReg(), rl_src.reg.GetReg(),
+ kArmCondPl);
+ StoreValue(rl_dest, rl_result);
+ return true;
+}
+
bool Arm64Mir2Lir::GenInlinedAbsLong(CallInfo* info) {
RegLocation rl_src = info->args[0];
rl_src = LoadValueWide(rl_src, kCoreReg);
RegLocation rl_dest = InlineTargetWide(info);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- RegStorage sign_reg = AllocTempWide();
- // abs(x) = y<=x>>63, (x+y)^y.
- OpRegRegImm(kOpAsr, sign_reg, rl_src.reg, 63);
- OpRegRegReg(kOpAdd, rl_result.reg, rl_src.reg, sign_reg);
- OpRegReg(kOpXor, rl_result.reg, sign_reg);
+
+ // Compare the source value with zero. Write the negated value to the result if
+ // negative, otherwise write the original value.
+ OpRegImm(kOpCmp, rl_src.reg, 0);
+ NewLIR4(WIDE(kA64Csneg4rrrc), rl_result.reg.GetReg(), rl_src.reg.GetReg(),
+ rl_src.reg.GetReg(), kArmCondPl);
StoreValueWide(rl_dest, rl_result);
return true;
}
bool GenInlinedStringIsEmptyOrLength(CallInfo* info, bool is_empty);
virtual bool GenInlinedReverseBits(CallInfo* info, OpSize size);
bool GenInlinedReverseBytes(CallInfo* info, OpSize size);
- bool GenInlinedAbsInt(CallInfo* info);
+ virtual bool GenInlinedAbsInt(CallInfo* info);
virtual bool GenInlinedAbsLong(CallInfo* info);
virtual bool GenInlinedAbsFloat(CallInfo* info) = 0;
virtual bool GenInlinedAbsDouble(CallInfo* info) = 0;