summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/intrinsics_arm64.cc17
-rw-r--r--compiler/optimizing/intrinsics_arm_vixl.cc1
-rw-r--r--compiler/optimizing/intrinsics_x86.cc1
-rw-r--r--compiler/optimizing/intrinsics_x86_64.cc21
4 files changed, 40 insertions, 0 deletions
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index d58d8f4b0a..d0c64c2230 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -3856,6 +3856,23 @@ void IntrinsicCodeGeneratorARM64::VisitLongDivideUnsigned(HInvoke* invoke) {
GenerateDivideUnsigned(invoke, codegen_);
}
+void IntrinsicLocationsBuilderARM64::VisitMathMultiplyHigh(HInvoke* invoke) {
+ CreateIntIntToIntLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorARM64::VisitMathMultiplyHigh(HInvoke* invoke) {
+ LocationSummary* locations = invoke->GetLocations();
+ MacroAssembler* masm = codegen_->GetVIXLAssembler();
+ DataType::Type type = invoke->GetType();
+ DCHECK(type == DataType::Type::kInt64);
+
+ Register x = RegisterFrom(locations->InAt(0), type);
+ Register y = RegisterFrom(locations->InAt(1), type);
+ Register out = RegisterFrom(locations->Out(), type);
+
+ __ Smulh(out, x, y);
+}
+
class VarHandleSlowPathARM64 : public IntrinsicSlowPathARM64 {
public:
VarHandleSlowPathARM64(HInvoke* invoke, std::memory_order order)
diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc
index 42156d43c5..2a2f245025 100644
--- a/compiler/optimizing/intrinsics_arm_vixl.cc
+++ b/compiler/optimizing/intrinsics_arm_vixl.cc
@@ -5371,6 +5371,7 @@ UNIMPLEMENTED_INTRINSIC(ARMVIXL, FP16Greater)
UNIMPLEMENTED_INTRINSIC(ARMVIXL, FP16GreaterEquals)
UNIMPLEMENTED_INTRINSIC(ARMVIXL, FP16Less)
UNIMPLEMENTED_INTRINSIC(ARMVIXL, FP16LessEquals)
+UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathMultiplyHigh)
UNIMPLEMENTED_INTRINSIC(ARMVIXL, StringStringIndexOf);
UNIMPLEMENTED_INTRINSIC(ARMVIXL, StringStringIndexOfAfter);
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index a4f1bd1df2..b0c4b5736f 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -4613,6 +4613,7 @@ UNIMPLEMENTED_INTRINSIC(X86, FP16Greater)
UNIMPLEMENTED_INTRINSIC(X86, FP16GreaterEquals)
UNIMPLEMENTED_INTRINSIC(X86, FP16Less)
UNIMPLEMENTED_INTRINSIC(X86, FP16LessEquals)
+UNIMPLEMENTED_INTRINSIC(X86, MathMultiplyHigh)
UNIMPLEMENTED_INTRINSIC(X86, StringStringIndexOf);
UNIMPLEMENTED_INTRINSIC(X86, StringStringIndexOfAfter);
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc
index 7d056f9c59..63511817c0 100644
--- a/compiler/optimizing/intrinsics_x86_64.cc
+++ b/compiler/optimizing/intrinsics_x86_64.cc
@@ -2830,6 +2830,27 @@ void IntrinsicCodeGeneratorX86_64::VisitIntegerDivideUnsigned(HInvoke* invoke) {
__ Bind(slow_path->GetExitLabel());
}
+void IntrinsicLocationsBuilderX86_64::VisitMathMultiplyHigh(HInvoke* invoke) {
+ LocationSummary* locations =
+ new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
+ locations->SetInAt(0, Location::RegisterLocation(RAX));
+ locations->SetInAt(1, Location::RequiresRegister());
+ locations->SetOut(Location::RegisterLocation(RDX));
+ locations->AddTemp(Location::RegisterLocation(RAX));
+}
+
+void IntrinsicCodeGeneratorX86_64::VisitMathMultiplyHigh(HInvoke* invoke) {
+ X86_64Assembler* assembler = GetAssembler();
+ LocationSummary* locations = invoke->GetLocations();
+
+ CpuRegister y = locations->InAt(1).AsRegister<CpuRegister>();
+
+ DCHECK_EQ(locations->InAt(0).AsRegister<Register>(), RAX);
+ DCHECK_EQ(locations->Out().AsRegister<Register>(), RDX);
+
+ __ imulq(y);
+}
+
UNIMPLEMENTED_INTRINSIC(X86_64, FloatIsInfinite)
UNIMPLEMENTED_INTRINSIC(X86_64, DoubleIsInfinite)