interpreter_intrinsics.cc revision 78f1bdc6bbf0ac07a333ada2396987e8391eee49
178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee/*
278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * Copyright (C) 2017 The Android Open Source Project
378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee *
478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * Licensed under the Apache License, Version 2.0 (the "License");
578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * you may not use this file except in compliance with the License.
678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * You may obtain a copy of the License at
778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee *
878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee *      http://www.apache.org/licenses/LICENSE-2.0
978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee *
1078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * Unless required by applicable law or agreed to in writing, software
1178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * distributed under the License is distributed on an "AS IS" BASIS,
1278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * See the License for the specific language governing permissions and
1478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee * limitations under the License.
1578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee */
1678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
1778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee#include "interpreter/interpreter_common.h"
1878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee#include "interpreter/interpreter_intrinsics.h"
1978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
2078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeenamespace art {
2178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeenamespace interpreter {
2278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
2378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee#define BINARY_SIMPLE_INTRINSIC(name, op, get, set, offset)  \
2478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeestatic ALWAYS_INLINE bool name(ShadowFrame* shadow_frame,    \
2578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                               const Instruction* inst,      \
2678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                               uint16_t inst_data,           \
2778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                               JValue* result_register)      \
2878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {                  \
2978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  uint32_t arg[Instruction::kMaxVarArgRegs] = {};            \
3078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  inst->GetVarArgs(arg, inst_data);                          \
3178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  result_register->set(op(shadow_frame->get(arg[0]), shadow_frame->get(arg[offset]))); \
3278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  return true;                                               \
3378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee}
3478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
3578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee#define UNARY_SIMPLE_INTRINSIC(name, op, get, set)           \
3678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeestatic ALWAYS_INLINE bool name(ShadowFrame* shadow_frame,    \
3778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                               const Instruction* inst,      \
3878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                               uint16_t inst_data,           \
3978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                               JValue* result_register)      \
4078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {                  \
4178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  uint32_t arg[Instruction::kMaxVarArgRegs] = {};            \
4278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  inst->GetVarArgs(arg, inst_data);                          \
4378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  result_register->set(op(shadow_frame->get(arg[0])));       \
4478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  return true;                                               \
4578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee}
4678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
4778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.min(II)I
4878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeBINARY_SIMPLE_INTRINSIC(MterpMathMinIntInt, std::min, GetVReg, SetI, 1);
4978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.min(JJ)J
5078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeBINARY_SIMPLE_INTRINSIC(MterpMathMinLongLong, std::min, GetVRegLong, SetJ, 2);
5178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.max(II)I
5278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeBINARY_SIMPLE_INTRINSIC(MterpMathMaxIntInt, std::max, GetVReg, SetI, 1);
5378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.max(JJ)J
5478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeBINARY_SIMPLE_INTRINSIC(MterpMathMaxLongLong, std::max, GetVRegLong, SetJ, 2);
5578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.abs(I)I
5678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathAbsInt, std::abs, GetVReg, SetI);
5778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.abs(J)J
5878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathAbsLong, std::abs, GetVRegLong, SetJ);
5978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.abs(F)F
6078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathAbsFloat, 0x7fffffff&, GetVReg, SetI);
6178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.abs(D)D
6278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathAbsDouble, INT64_C(0x7fffffffffffffff)&, GetVRegLong, SetJ);
6378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.sqrt(D)D
6478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathSqrt, std::sqrt, GetVRegDouble, SetD);
6578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.ceil(D)D
6678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathCeil, std::ceil, GetVRegDouble, SetD);
6778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.floor(D)D
6878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathFloor, std::floor, GetVRegDouble, SetD);
6978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.sin(D)D
7078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathSin, std::sin, GetVRegDouble, SetD);
7178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.cos(D)D
7278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathCos, std::cos, GetVRegDouble, SetD);
7378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.tan(D)D
7478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathTan, std::tan, GetVRegDouble, SetD);
7578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.asin(D)D
7678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathAsin, std::asin, GetVRegDouble, SetD);
7778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.acos(D)D
7878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathAcos, std::acos, GetVRegDouble, SetD);
7978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee// java.lang.Math.atan(D)D
8078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeeUNARY_SIMPLE_INTRINSIC(MterpMathAtan, std::atan, GetVRegDouble, SetD);
8178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
8278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee#define INTRINSIC_CASE(name)                                           \
8378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    case Intrinsics::k##name:                                          \
8478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee      res = Mterp##name(shadow_frame, inst, inst_data, result_register); \
8578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee      break;
8678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
8778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbeebool MterpHandleIntrinsic(ShadowFrame* shadow_frame,
8878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                          ArtMethod* const called_method,
8978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                          const Instruction* inst,
9078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                          uint16_t inst_data,
9178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee                          JValue* result_register)
9278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    REQUIRES_SHARED(Locks::mutator_lock_) {
9378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  Intrinsics intrinsic = static_cast<Intrinsics>(called_method->GetIntrinsic());
9478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  bool res = false;  // Assume failure
9578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  switch (intrinsic) {
9678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathMinIntInt)
9778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathMinLongLong)
9878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathMaxIntInt)
9978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathMaxLongLong)
10078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathAbsInt)
10178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathAbsLong)
10278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathAbsFloat)
10378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathAbsDouble)
10478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathSqrt)
10578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathCeil)
10678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathFloor)
10778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathSin)
10878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathCos)
10978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathTan)
11078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathAsin)
11178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathAcos)
11278f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    INTRINSIC_CASE(MathAtan)
11378f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee    default:
11478f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee      res = false;  // Punt
11578f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee      break;
11678f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  }
11778f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee  return res;
11878f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee}
11978f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee
12078f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee}  // namespace interpreter
12178f1bdc6bbf0ac07a333ada2396987e8391eee49buzbee}  // namespace art
122