summaryrefslogtreecommitdiff
path: root/compiler/optimizing/intrinsics.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/intrinsics.cc')
-rw-r--r--compiler/optimizing/intrinsics.cc43
1 files changed, 36 insertions, 7 deletions
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc
index 8ef13e125e..3db9816173 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -31,7 +31,7 @@ static inline InvokeType GetIntrinsicInvokeType(Intrinsics i) {
switch (i) {
case Intrinsics::kNone:
return kInterface; // Non-sensical for intrinsic.
-#define OPTIMIZING_INTRINSICS(Name, IsStatic) \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment) \
case Intrinsics::k ## Name: \
return IsStatic;
#include "intrinsics_list.h"
@@ -42,7 +42,21 @@ INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
return kInterface;
}
-
+// Function that returns whether an intrinsic needs an environment or not.
+static inline IntrinsicNeedsEnvironment IntrinsicNeedsEnvironment(Intrinsics i) {
+ switch (i) {
+ case Intrinsics::kNone:
+ return kNeedsEnvironment; // Non-sensical for intrinsic.
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment) \
+ case Intrinsics::k ## Name: \
+ return NeedsEnvironment;
+#include "intrinsics_list.h"
+INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+#undef INTRINSICS_LIST
+#undef OPTIMIZING_INTRINSICS
+ }
+ return kNeedsEnvironment;
+}
static Primitive::Type GetType(uint64_t data, bool is_op_size) {
if (is_op_size) {
@@ -70,7 +84,10 @@ static Primitive::Type GetType(uint64_t data, bool is_op_size) {
}
}
-static Intrinsics GetIntrinsic(InlineMethod method) {
+static Intrinsics GetIntrinsic(InlineMethod method, InstructionSet instruction_set) {
+ if (instruction_set == kMips || instruction_set == kMips64) {
+ return Intrinsics::kNone;
+ }
switch (method.opcode) {
// Floating-point conversions.
case kIntrinsicDoubleCvt:
@@ -103,6 +120,16 @@ static Intrinsics GetIntrinsic(InlineMethod method) {
LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
UNREACHABLE();
}
+ case kIntrinsicNumberOfLeadingZeros:
+ switch (GetType(method.d.data, true)) {
+ case Primitive::kPrimInt:
+ return Intrinsics::kIntegerNumberOfLeadingZeros;
+ case Primitive::kPrimLong:
+ return Intrinsics::kLongNumberOfLeadingZeros;
+ default:
+ LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
+ UNREACHABLE();
+ }
// Abs.
case kIntrinsicAbsDouble:
@@ -187,6 +214,8 @@ static Intrinsics GetIntrinsic(InlineMethod method) {
return Intrinsics::kStringCharAt;
case kIntrinsicCompareTo:
return Intrinsics::kStringCompareTo;
+ case kIntrinsicEquals:
+ return Intrinsics::kStringEquals;
case kIntrinsicGetCharsNoCheck:
return Intrinsics::kStringGetCharsNoCheck;
case kIntrinsicIsEmptyOrLength:
@@ -339,7 +368,7 @@ void IntrinsicsRecognizer::Run() {
driver_->GetMethodInlinerMap()->GetMethodInliner(&invoke->GetDexFile());
DCHECK(inliner != nullptr);
if (inliner->IsIntrinsic(invoke->GetDexMethodIndex(), &method)) {
- Intrinsics intrinsic = GetIntrinsic(method);
+ Intrinsics intrinsic = GetIntrinsic(method, graph_->GetInstructionSet());
if (intrinsic != Intrinsics::kNone) {
if (!CheckInvokeType(intrinsic, invoke)) {
@@ -347,7 +376,7 @@ void IntrinsicsRecognizer::Run() {
<< intrinsic << " for "
<< PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile());
} else {
- invoke->SetIntrinsic(intrinsic);
+ invoke->SetIntrinsic(intrinsic, IntrinsicNeedsEnvironment(intrinsic));
}
}
}
@@ -359,9 +388,9 @@ void IntrinsicsRecognizer::Run() {
std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic) {
switch (intrinsic) {
case Intrinsics::kNone:
- os << "No intrinsic.";
+ os << "None";
break;
-#define OPTIMIZING_INTRINSICS(Name, IsStatic) \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment) \
case Intrinsics::k ## Name: \
os << # Name; \
break;