summaryrefslogtreecommitdiff
path: root/compiler/optimizing/intrinsics_x86.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/intrinsics_x86.cc')
-rw-r--r--compiler/optimizing/intrinsics_x86.cc111
1 files changed, 73 insertions, 38 deletions
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index 75ec85985a..8baa2a24e4 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -87,7 +87,8 @@ class ReadBarrierSystemArrayCopySlowPathX86 : public SlowPathCode {
<< "Unexpected instruction in read barrier arraycopy slow path: "
<< instruction_->DebugName();
DCHECK(instruction_->GetLocations()->Intrinsified());
- DCHECK_EQ(instruction_->AsInvoke()->GetIntrinsic(), Intrinsics::kSystemArrayCopy);
+ // TODO: Remove "OrNull".
+ DCHECK_EQ(instruction_->AsInvokeOrNull()->GetIntrinsic(), Intrinsics::kSystemArrayCopy);
int32_t element_size = DataType::Size(DataType::Type::kReference);
uint32_t offset = mirror::Array::DataOffset(element_size).Uint32Value();
@@ -119,7 +120,8 @@ class ReadBarrierSystemArrayCopySlowPathX86 : public SlowPathCode {
__ Bind(&loop);
// value = src_array[i + src_pos]
if (src_pos.IsConstant()) {
- int32_t constant = src_pos.GetConstant()->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t constant = src_pos.GetConstant()->AsIntConstantOrNull()->GetValue();
int32_t adjusted_offset = offset + constant * element_size;
__ movl(temp2, Address(src, temp1, ScaleFactor::TIMES_4, adjusted_offset));
} else {
@@ -142,7 +144,8 @@ class ReadBarrierSystemArrayCopySlowPathX86 : public SlowPathCode {
__ MaybePoisonHeapReference(temp2);
// dest_array[i + dest_pos] = value
if (dest_pos.IsConstant()) {
- int32_t constant = dest_pos.GetConstant()->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t constant = dest_pos.GetConstant()->AsIntConstantOrNull()->GetValue();
int32_t adjusted_offset = offset + constant * element_size;
__ movl(Address(dest, temp1, ScaleFactor::TIMES_4, adjusted_offset), temp2);
} else {
@@ -393,7 +396,8 @@ void IntrinsicLocationsBuilderX86::VisitMathRoundFloat(HInvoke* invoke) {
return;
}
- HInvokeStaticOrDirect* static_or_direct = invoke->AsInvokeStaticOrDirect();
+ // TODO: Remove "OrNull".
+ HInvokeStaticOrDirect* static_or_direct = invoke->AsInvokeStaticOrDirectOrNull();
DCHECK(static_or_direct != nullptr);
LocationSummary* locations =
new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
@@ -429,8 +433,9 @@ void IntrinsicCodeGeneratorX86::VisitMathRoundFloat(HInvoke* invoke) {
__ subss(t2, t1);
if (locations->GetInputCount() == 2 && locations->InAt(1).IsValid()) {
// Direct constant area available.
+ // TODO: Remove "OrNull".
HX86ComputeBaseMethodAddress* method_address =
- invoke->InputAt(1)->AsX86ComputeBaseMethodAddress();
+ invoke->InputAt(1)->AsX86ComputeBaseMethodAddressOrNull();
Register constant_area = locations->InAt(1).AsRegister<Register>();
__ comiss(t2, codegen_->LiteralInt32Address(bit_cast<int32_t, float>(0.5f),
method_address,
@@ -523,7 +528,8 @@ static void GenLowestOneBit(X86Assembler* assembler,
if (invoke->InputAt(0)->IsConstant()) {
// Evaluate this at compile time.
- int64_t value = Int64FromConstant(invoke->InputAt(0)->AsConstant());
+ // TODO: Remove "OrNull".
+ int64_t value = Int64FromConstant(invoke->InputAt(0)->AsConstantOrNull());
if (value == 0) {
if (is_long) {
__ xorl(out_loc.AsRegisterPairLow<Register>(), out_loc.AsRegisterPairLow<Register>());
@@ -774,9 +780,9 @@ void IntrinsicCodeGeneratorX86::VisitMathNextAfter(HInvoke* invoke) {
static void CreateSystemArrayCopyLocations(HInvoke* invoke) {
// We need at least two of the positions or length to be an integer constant,
// or else we won't have enough free registers.
- HIntConstant* src_pos = invoke->InputAt(1)->AsIntConstant();
- HIntConstant* dest_pos = invoke->InputAt(3)->AsIntConstant();
- HIntConstant* length = invoke->InputAt(4)->AsIntConstant();
+ HIntConstant* src_pos = invoke->InputAt(1)->AsIntConstantOrNull();
+ HIntConstant* dest_pos = invoke->InputAt(3)->AsIntConstantOrNull();
+ HIntConstant* length = invoke->InputAt(4)->AsIntConstantOrNull();
int num_constants =
((src_pos != nullptr) ? 1 : 0)
@@ -833,13 +839,15 @@ static void CheckPosition(X86Assembler* assembler,
const uint32_t length_offset = mirror::Array::LengthOffset().Uint32Value();
if (pos.IsConstant()) {
- int32_t pos_const = pos.GetConstant()->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t pos_const = pos.GetConstant()->AsIntConstantOrNull()->GetValue();
if (pos_const == 0) {
if (!length_is_input_length) {
// Check that length(input) >= length.
if (length.IsConstant()) {
__ cmpl(Address(input, length_offset),
- Immediate(length.GetConstant()->AsIntConstant()->GetValue()));
+ // TODO: Remove "OrNull".
+ Immediate(length.GetConstant()->AsIntConstantOrNull()->GetValue()));
} else {
__ cmpl(Address(input, length_offset), length.AsRegister<Register>());
}
@@ -853,7 +861,8 @@ static void CheckPosition(X86Assembler* assembler,
// Check that (length(input) - pos) >= length.
if (length.IsConstant()) {
- __ cmpl(temp, Immediate(length.GetConstant()->AsIntConstant()->GetValue()));
+ // TODO: Remove "OrNull".
+ __ cmpl(temp, Immediate(length.GetConstant()->AsIntConstantOrNull()->GetValue()));
} else {
__ cmpl(temp, length.AsRegister<Register>());
}
@@ -878,7 +887,8 @@ static void CheckPosition(X86Assembler* assembler,
__ movl(temp, Address(input, length_offset));
__ subl(temp, pos_reg);
if (length.IsConstant()) {
- __ cmpl(temp, Immediate(length.GetConstant()->AsIntConstant()->GetValue()));
+ // TODO: Remove "OrNull".
+ __ cmpl(temp, Immediate(length.GetConstant()->AsIntConstantOrNull()->GetValue()));
} else {
__ cmpl(temp, length.AsRegister<Register>());
}
@@ -929,7 +939,8 @@ static void SystemArrayCopyPrimitive(HInvoke* invoke,
// We need the count in ECX.
if (length.IsConstant()) {
- __ movl(count, Immediate(length.GetConstant()->AsIntConstant()->GetValue()));
+ // TODO: Remove "OrNull".
+ __ movl(count, Immediate(length.GetConstant()->AsIntConstantOrNull()->GetValue()));
} else {
__ movl(count, length.AsRegister<Register>());
}
@@ -947,13 +958,15 @@ static void SystemArrayCopyPrimitive(HInvoke* invoke,
const uint32_t data_offset = mirror::Array::DataOffset(data_size).Uint32Value();
if (src_pos.IsConstant()) {
- int32_t src_pos_const = src_pos.GetConstant()->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t src_pos_const = src_pos.GetConstant()->AsIntConstantOrNull()->GetValue();
__ leal(src_base, Address(src, data_size * src_pos_const + data_offset));
} else {
__ leal(src_base, Address(src, src_pos.AsRegister<Register>(), scale_factor, data_offset));
}
if (dest_pos.IsConstant()) {
- int32_t dest_pos_const = dest_pos.GetConstant()->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t dest_pos_const = dest_pos.GetConstant()->AsIntConstantOrNull()->GetValue();
__ leal(dest_base, Address(dest, data_size * dest_pos_const + data_offset));
} else {
__ leal(dest_base, Address(dest, dest_pos.AsRegister<Register>(), scale_factor, data_offset));
@@ -1204,7 +1217,8 @@ static void GenerateStringIndexOf(HInvoke* invoke,
SlowPathCode* slow_path = nullptr;
HInstruction* code_point = invoke->InputAt(1);
if (code_point->IsIntConstant()) {
- if (static_cast<uint32_t>(code_point->AsIntConstant()->GetValue()) >
+ // TODO: Remove "OrNull".
+ if (static_cast<uint32_t>(code_point->AsIntConstantOrNull()->GetValue()) >
std::numeric_limits<uint16_t>::max()) {
// Always needs the slow-path. We could directly dispatch to it, but this case should be
// rare, so for simplicity just put the full slow-path down and branch unconditionally.
@@ -1444,8 +1458,9 @@ void IntrinsicCodeGeneratorX86::VisitStringGetCharsNoCheck(HInvoke* invoke) {
// public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin);
Register obj = locations->InAt(0).AsRegister<Register>();
Location srcBegin = locations->InAt(1);
+ // TODO: Remove "OrNull".
int srcBegin_value =
- srcBegin.IsConstant() ? srcBegin.GetConstant()->AsIntConstant()->GetValue() : 0;
+ srcBegin.IsConstant() ? srcBegin.GetConstant()->AsIntConstantOrNull()->GetValue() : 0;
Register srcEnd = locations->InAt(2).AsRegister<Register>();
Register dst = locations->InAt(3).AsRegister<Register>();
Register dstBegin = locations->InAt(4).AsRegister<Register>();
@@ -1598,7 +1613,8 @@ static void GenPoke(LocationSummary* locations, DataType::Type size, X86Assemble
case DataType::Type::kInt8:
if (value_loc.IsConstant()) {
__ movb(Address(address, 0),
- Immediate(value_loc.GetConstant()->AsIntConstant()->GetValue()));
+ // TODO: Remove "OrNull".
+ Immediate(value_loc.GetConstant()->AsIntConstantOrNull()->GetValue()));
} else {
__ movb(Address(address, 0), value_loc.AsRegister<ByteRegister>());
}
@@ -1606,7 +1622,8 @@ static void GenPoke(LocationSummary* locations, DataType::Type size, X86Assemble
case DataType::Type::kInt16:
if (value_loc.IsConstant()) {
__ movw(Address(address, 0),
- Immediate(value_loc.GetConstant()->AsIntConstant()->GetValue()));
+ // TODO: Remove "OrNull".
+ Immediate(value_loc.GetConstant()->AsIntConstantOrNull()->GetValue()));
} else {
__ movw(Address(address, 0), value_loc.AsRegister<Register>());
}
@@ -1614,14 +1631,16 @@ static void GenPoke(LocationSummary* locations, DataType::Type size, X86Assemble
case DataType::Type::kInt32:
if (value_loc.IsConstant()) {
__ movl(Address(address, 0),
- Immediate(value_loc.GetConstant()->AsIntConstant()->GetValue()));
+ // TODO: Remove "OrNull".
+ Immediate(value_loc.GetConstant()->AsIntConstantOrNull()->GetValue()));
} else {
__ movl(Address(address, 0), value_loc.AsRegister<Register>());
}
break;
case DataType::Type::kInt64:
if (value_loc.IsConstant()) {
- int64_t value = value_loc.GetConstant()->AsLongConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int64_t value = value_loc.GetConstant()->AsLongConstantOrNull()->GetValue();
__ movl(Address(address, 0), Immediate(Low32Bits(value)));
__ movl(Address(address, 4), Immediate(High32Bits(value)));
} else {
@@ -2551,7 +2570,8 @@ static void GenBitCount(X86Assembler* assembler,
if (invoke->InputAt(0)->IsConstant()) {
// Evaluate this at compile time.
- int64_t value = Int64FromConstant(invoke->InputAt(0)->AsConstant());
+ // TODO: Remove "OrNull".
+ int64_t value = Int64FromConstant(invoke->InputAt(0)->AsConstantOrNull());
int32_t result = is_long
? POPCOUNT(static_cast<uint64_t>(value))
: POPCOUNT(static_cast<uint32_t>(value));
@@ -2618,7 +2638,8 @@ static void GenLeadingZeros(X86Assembler* assembler,
if (invoke->InputAt(0)->IsConstant()) {
// Evaluate this at compile time.
- int64_t value = Int64FromConstant(invoke->InputAt(0)->AsConstant());
+ // TODO: Remove "OrNull".
+ int64_t value = Int64FromConstant(invoke->InputAt(0)->AsConstantOrNull());
if (value == 0) {
value = is_long ? 64 : 32;
} else {
@@ -2722,7 +2743,8 @@ static void GenTrailingZeros(X86Assembler* assembler,
if (invoke->InputAt(0)->IsConstant()) {
// Evaluate this at compile time.
- int64_t value = Int64FromConstant(invoke->InputAt(0)->AsConstant());
+ // TODO: Remove "OrNull".
+ int64_t value = Int64FromConstant(invoke->InputAt(0)->AsConstantOrNull());
if (value == 0) {
value = is_long ? 64 : 32;
} else {
@@ -2812,7 +2834,8 @@ static void GenSystemArrayCopyBaseAddress(X86Assembler* assembler,
const uint32_t data_offset = mirror::Array::DataOffset(element_size).Uint32Value();
if (pos.IsConstant()) {
- int32_t constant = pos.GetConstant()->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t constant = pos.GetConstant()->AsIntConstantOrNull()->GetValue();
__ leal(base, Address(array, element_size * constant + data_offset));
} else {
__ leal(base, Address(array, pos.AsRegister<Register>(), scale_factor, data_offset));
@@ -2833,7 +2856,8 @@ static void GenSystemArrayCopyEndAddress(X86Assembler* assembler,
const ScaleFactor scale_factor = static_cast<ScaleFactor>(DataType::SizeShift(type));
if (copy_length.IsConstant()) {
- int32_t constant = copy_length.GetConstant()->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t constant = copy_length.GetConstant()->AsIntConstantOrNull()->GetValue();
__ leal(end, Address(base, element_size * constant));
} else {
__ leal(end, Address(base, copy_length.AsRegister<Register>(), scale_factor, 0));
@@ -2907,9 +2931,11 @@ void IntrinsicCodeGeneratorX86::VisitSystemArrayCopy(HInvoke* invoke) {
// If source and destination are the same, we go to slow path if we need to do
// forward copying.
if (src_pos.IsConstant()) {
- int32_t src_pos_constant = src_pos.GetConstant()->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t src_pos_constant = src_pos.GetConstant()->AsIntConstantOrNull()->GetValue();
if (dest_pos.IsConstant()) {
- int32_t dest_pos_constant = dest_pos.GetConstant()->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t dest_pos_constant = dest_pos.GetConstant()->AsIntConstantOrNull()->GetValue();
if (optimizations.GetDestinationIsSource()) {
// Checked when building locations.
DCHECK_GE(src_pos_constant, dest_pos_constant);
@@ -2931,7 +2957,8 @@ void IntrinsicCodeGeneratorX86::VisitSystemArrayCopy(HInvoke* invoke) {
__ j(kNotEqual, &conditions_on_positions_validated);
}
if (dest_pos.IsConstant()) {
- int32_t dest_pos_constant = dest_pos.GetConstant()->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t dest_pos_constant = dest_pos.GetConstant()->AsIntConstantOrNull()->GetValue();
__ cmpl(src_pos.AsRegister<Register>(), Immediate(dest_pos_constant));
__ j(kLess, intrinsic_slow_path->GetEntryLabel());
} else {
@@ -3267,7 +3294,8 @@ void IntrinsicCodeGeneratorX86::VisitSystemArrayCopy(HInvoke* invoke) {
static void RequestBaseMethodAddressInRegister(HInvoke* invoke) {
LocationSummary* locations = invoke->GetLocations();
if (locations != nullptr) {
- HInvokeStaticOrDirect* invoke_static_or_direct = invoke->AsInvokeStaticOrDirect();
+ // TODO: Remove "OrNull".
+ HInvokeStaticOrDirect* invoke_static_or_direct = invoke->AsInvokeStaticOrDirectOrNull();
// Note: The base method address is not present yet when this is called from the
// PCRelativeHandlerVisitor via IsCallFreeIntrinsic() to determine whether to insert it.
if (invoke_static_or_direct->HasSpecialInput()) {
@@ -3300,17 +3328,20 @@ void IntrinsicCodeGeneratorX86::VisitIntegerValueOf(HInvoke* invoke) {
Register out = locations->Out().AsRegister<Register>();
auto allocate_instance = [&]() {
DCHECK_EQ(out, InvokeRuntimeCallingConvention().GetRegisterAt(0));
- codegen_->LoadIntrinsicDeclaringClass(out, invoke->AsInvokeStaticOrDirect());
+ // TODO: Remove "OrNull".
+ codegen_->LoadIntrinsicDeclaringClass(out, invoke->AsInvokeStaticOrDirectOrNull());
codegen_->InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc());
CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
};
if (invoke->InputAt(0)->IsConstant()) {
- int32_t value = invoke->InputAt(0)->AsIntConstant()->GetValue();
+ // TODO: Remove "OrNull".
+ int32_t value = invoke->InputAt(0)->AsIntConstantOrNull()->GetValue();
if (static_cast<uint32_t>(value - info.low) < info.length) {
// Just embed the j.l.Integer in the code.
DCHECK_NE(info.value_boot_image_reference, IntegerValueOfInfo::kInvalidReference);
codegen_->LoadBootImageAddress(
- out, info.value_boot_image_reference, invoke->AsInvokeStaticOrDirect());
+ // TODO: Remove "OrNull".
+ out, info.value_boot_image_reference, invoke->AsInvokeStaticOrDirectOrNull());
} else {
DCHECK(locations->CanCall());
// Allocate and initialize a new j.l.Integer.
@@ -3333,9 +3364,11 @@ void IntrinsicCodeGeneratorX86::VisitIntegerValueOf(HInvoke* invoke) {
"Check heap reference size.");
if (codegen_->GetCompilerOptions().IsBootImage()) {
DCHECK_EQ(invoke->InputCount(), invoke->GetNumberOfArguments() + 1u);
- size_t method_address_index = invoke->AsInvokeStaticOrDirect()->GetSpecialInputIndex();
+ // TODO: Remove "OrNull".
+ size_t method_address_index = invoke->AsInvokeStaticOrDirectOrNull()->GetSpecialInputIndex();
+ // TODO: Remove "OrNull".
HX86ComputeBaseMethodAddress* method_address =
- invoke->InputAt(method_address_index)->AsX86ComputeBaseMethodAddress();
+ invoke->InputAt(method_address_index)->AsX86ComputeBaseMethodAddressOrNull();
DCHECK(method_address != nullptr);
Register method_address_reg =
invoke->GetLocations()->InAt(method_address_index).AsRegister<Register>();
@@ -3347,8 +3380,9 @@ void IntrinsicCodeGeneratorX86::VisitIntegerValueOf(HInvoke* invoke) {
// adjust the offset accordingly.
uint32_t mid_array_boot_image_offset =
info.array_data_boot_image_reference - info.low * kElementSize;
+ // TODO: Remove "OrNull".
codegen_->LoadBootImageAddress(
- out, mid_array_boot_image_offset, invoke->AsInvokeStaticOrDirect());
+ out, mid_array_boot_image_offset, invoke->AsInvokeStaticOrDirectOrNull());
DCHECK_NE(out, in);
__ movl(out, Address(out, in, TIMES_4, 0));
}
@@ -3387,7 +3421,8 @@ void IntrinsicCodeGeneratorX86::VisitReferenceGetReferent(HInvoke* invoke) {
// Load the java.lang.ref.Reference class, use the output register as a temporary.
codegen_->LoadIntrinsicDeclaringClass(out.AsRegister<Register>(),
- invoke->AsInvokeStaticOrDirect());
+ // TODO: Remove "OrNull".
+ invoke->AsInvokeStaticOrDirectOrNull());
// Check static fields java.lang.ref.Reference.{disableIntrinsic,slowPathEnabled} together.
MemberOffset disable_intrinsic_offset = IntrinsicVisitor::GetReferenceDisableIntrinsicOffset();