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