| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| // Class for intrinsifying functions. |
| #define SHOULD_NOT_INCLUDE_RUNTIME |
| |
| #include "vm/compiler/asm_intrinsifier.h" |
| |
| namespace dart { |
| namespace compiler { |
| |
| void AsmIntrinsifier::String_identityHash(Assembler* assembler, |
| Label* normal_ir_body) { |
| String_getHashCode(assembler, normal_ir_body); |
| } |
| |
| void AsmIntrinsifier::RegExp_ExecuteMatch(Assembler* assembler, |
| Label* normal_ir_body) { |
| AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(assembler, normal_ir_body, |
| /*sticky=*/false); |
| } |
| |
| void AsmIntrinsifier::RegExp_ExecuteMatchSticky(Assembler* assembler, |
| Label* normal_ir_body) { |
| AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(assembler, normal_ir_body, |
| /*sticky=*/true); |
| } |
| |
| #define __ assembler-> |
| |
| // TODO(srdjan): Add combinations (one-byte/two-byte/external strings). |
| void AsmIntrinsifier::StringEquality(Assembler* assembler, |
| Register obj1, |
| Register obj2, |
| Register temp1, |
| Register temp2, |
| Register result, |
| Label* normal_ir_body, |
| intptr_t string_cid) { |
| Label is_true, is_false, loop; |
| |
| __ CompareRegisters(obj1, obj2); |
| __ BranchIf(EQUAL, &is_true, AssemblerBase::kNearJump); |
| __ BranchIfSmi(obj2, &is_false, AssemblerBase::kNearJump); |
| __ CompareClassId(obj2, string_cid, temp1); |
| __ BranchIf(NOT_EQUAL, normal_ir_body, AssemblerBase::kNearJump); |
| |
| __ LoadFieldFromOffset(temp1, obj1, target::String::length_offset()); |
| __ CompareWithMemoryValue( |
| temp1, FieldAddress(obj2, target::String::length_offset())); |
| __ BranchIf(NOT_EQUAL, &is_false, AssemblerBase::kNearJump); |
| |
| // Ensure temp1 has length in bytes |
| if (string_cid == kOneByteStringCid) { |
| __ ArithmeticShiftRightImmediate(temp1, 1); |
| } |
| // Rounding up to word boundary |
| __ AddImmediate(temp1, target::kWordSize - 1); |
| __ ArithmeticShiftRightImmediate(temp1, target::kWordSizeLog2); |
| __ CompareWords(obj1, obj2, |
| target::String::length_offset() + target::kWordSize, temp1, |
| temp2, &is_true); |
| |
| __ Bind(&is_false); |
| __ LoadObject(result, CastHandle<Object>(FalseObject())); |
| __ Ret(); |
| |
| __ Bind(&is_true); |
| __ LoadObject(result, CastHandle<Object>(TrueObject())); |
| __ Ret(); |
| |
| __ Bind(normal_ir_body); |
| } |
| |
| } // namespace compiler |
| } // namespace dart |