diff options
author | 2021-01-20 21:52:54 +0000 | |
---|---|---|
committer | 2021-02-10 12:33:48 +0000 | |
commit | 745da80dbf169d83e2acb847b0c9c07985d51bdf (patch) | |
tree | a01990e419ee49fe255a6df108027a89b568975a | |
parent | 16f7f8e384f0ae13c53525ff12affbc00605b0ec (diff) |
Add Math.multiplyHigh intrinsic
Test: ./art/test/testrunner/testrunner.py --target --optimizing --64 -t 082-inline-execute
Test: ./art/test/testrunner/testrunner.py --host --optimizing --64 -t 082-inline-execute
Change-Id: I4b6cafa8b9e513eca7c5c139440024d87a7ef758
-rw-r--r-- | compiler/optimizing/intrinsics_arm64.cc | 17 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_arm_vixl.cc | 1 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_x86.cc | 1 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_x86_64.cc | 21 | ||||
-rw-r--r-- | runtime/image.cc | 4 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_intrinsics.cc | 1 | ||||
-rw-r--r-- | runtime/intrinsics_list.h | 1 | ||||
-rw-r--r-- | test/082-inline-execute/src/Main.java | 7 |
8 files changed, 51 insertions, 2 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) diff --git a/runtime/image.cc b/runtime/image.cc index 6c7be3c24d..60870773a0 100644 --- a/runtime/image.cc +++ b/runtime/image.cc @@ -29,8 +29,8 @@ namespace art { const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' }; -// Last change: Reference.refersTo() intrinsic. -const uint8_t ImageHeader::kImageVersion[] = { '0', '9', '4', '\0' }; +// Last change: Math.multiplyHigh intrinsic. +const uint8_t ImageHeader::kImageVersion[] = { '0', '9', '5', '\0' }; ImageHeader::ImageHeader(uint32_t image_reservation_size, uint32_t component_count, diff --git a/runtime/interpreter/interpreter_intrinsics.cc b/runtime/interpreter/interpreter_intrinsics.cc index 369615c9ee..7236bad5de 100644 --- a/runtime/interpreter/interpreter_intrinsics.cc +++ b/runtime/interpreter/interpreter_intrinsics.cc @@ -500,6 +500,7 @@ bool MterpHandleIntrinsic(ShadowFrame* shadow_frame, UNIMPLEMENTED_CASE(MathRint /* (D)D */) UNIMPLEMENTED_CASE(MathRoundDouble /* (D)J */) UNIMPLEMENTED_CASE(MathRoundFloat /* (F)I */) + UNIMPLEMENTED_CASE(MathMultiplyHigh /* (JJ)J */) UNIMPLEMENTED_CASE(SystemArrayCopyChar /* ([CI[CII)V */) UNIMPLEMENTED_CASE(SystemArrayCopy /* (Ljava/lang/Object;ILjava/lang/Object;II)V */) UNIMPLEMENTED_CASE(ThreadCurrentThread /* ()Ljava/lang/Thread; */) diff --git a/runtime/intrinsics_list.h b/runtime/intrinsics_list.h index 86d35cbc0a..c0ef1c9a68 100644 --- a/runtime/intrinsics_list.h +++ b/runtime/intrinsics_list.h @@ -156,6 +156,7 @@ V(MathRint, kStatic, kNeedsEnvironment, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "rint", "(D)D") \ V(MathRoundDouble, kStatic, kNeedsEnvironment, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "round", "(D)J") \ V(MathRoundFloat, kStatic, kNeedsEnvironment, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "round", "(F)I") \ + V(MathMultiplyHigh, kStatic, kNeedsEnvironment, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "multiplyHigh", "(JJ)J") \ V(SystemArrayCopyChar, kStatic, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljava/lang/System;", "arraycopy", "([CI[CII)V") \ V(SystemArrayCopy, kStatic, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljava/lang/System;", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V") \ V(ThreadCurrentThread, kStatic, kNeedsEnvironment, kNoSideEffects, kNoThrow, "Ljava/lang/Thread;", "currentThread", "()Ljava/lang/Thread;") \ diff --git a/test/082-inline-execute/src/Main.java b/test/082-inline-execute/src/Main.java index 5597947cfc..f4a234b437 100644 --- a/test/082-inline-execute/src/Main.java +++ b/test/082-inline-execute/src/Main.java @@ -44,6 +44,7 @@ public class Main { test_Math_isNaN_F(); test_Math_isInfinite_D(); test_Math_isInfinite_F(); + test_Math_multiplyHigh(); test_Short_reverseBytes(); test_Integer_reverseBytes(); test_Long_reverseBytes(); @@ -978,6 +979,12 @@ public class Main { Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x80000001))); } + public static void test_Math_multiplyHigh() { + Math.multiplyHigh(2L, 3L); + Assert.assertEquals(Math.multiplyHigh(2L, 3L), 0L); + Assert.assertEquals(Math.multiplyHigh(Long.MAX_VALUE, Long.MAX_VALUE), 4611686018427387903L); + } + public static void test_StrictMath_abs_I() { StrictMath.abs(-1); Assert.assertEquals(StrictMath.abs(0), 0); |