Index: runtime/vm/assembler_arm.cc |
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc |
index 1fe7e91c178d8ba8c1663522b685033dba36c548..6ca3f40fa3193fcad392b1de61aacf08977d57d2 100644 |
--- a/runtime/vm/assembler_arm.cc |
+++ b/runtime/vm/assembler_arm.cc |
@@ -1934,6 +1934,47 @@ void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) { |
} |
+void Assembler::ComputeRange(Register result, |
+ Register value, |
+ Register scratch, |
+ Label* not_mint) { |
+ const Register hi = TMP; |
+ const Register lo = scratch; |
+ |
+ Label done; |
+ mov(result, Operand(value, LSR, kBitsPerWord - 1)); |
+ tst(value, Operand(kSmiTagMask)); |
+ b(&done, EQ); |
+ CompareClassId(value, kMintCid, result); |
+ b(not_mint, NE); |
+ ldr(hi, FieldAddress(value, Mint::value_offset() + kWordSize)); |
+ ldr(lo, FieldAddress(value, Mint::value_offset())); |
+ rsb(result, hi, Operand(ICData::kInt32RangeBit)); |
+ cmp(hi, Operand(lo, ASR, kBitsPerWord - 1)); |
+ b(&done, EQ); |
+ LoadImmediate(result, ICData::kUint32RangeBit); // Uint32 |
+ tst(hi, Operand(hi)); |
+ LoadImmediate(result, ICData::kInt64RangeBit, NE); // Int64 |
+ Bind(&done); |
+} |
+ |
+ |
+void Assembler::UpdateRangeFeedback(Register value, |
+ intptr_t index, |
+ Register ic_data, |
+ Register scratch1, |
+ Register scratch2, |
+ Label* miss) { |
+ ASSERT(ICData::IsValidRangeFeedbackIndex(index)); |
+ ComputeRange(scratch1, value, scratch2, miss); |
+ ldr(scratch2, FieldAddress(ic_data, ICData::range_feedback_offset())); |
+ orr(scratch2, |
+ scratch2, |
+ Operand(scratch1, LSL, ICData::kBitsPerRangeFeedback * index)); |
+ str(scratch2, FieldAddress(ic_data, ICData::range_feedback_offset())); |
+} |
+ |
+ |
static bool CanEncodeBranchOffset(int32_t offset) { |
ASSERT(Utils::IsAligned(offset, 4)); |
return Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset); |