1#!/usr/bin/env ruby 2 3# Copyright (c) 2023 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16# NB: put the functions generation to the ETS plugin 17 18include_relative 'array_helpers.irt' 19 20macro(:do_checks_ets) do 21 src_size := LoadI(src_obj).Imm(Constants::ARRAY_LENGTH_OFFSET).u32 22 dst_size := LoadI(dst_obj).Imm(Constants::ARRAY_LENGTH_OFFSET).u32 23 24 If(src_start, src_end).GT.Unlikely.b { 25 Goto(:FallToIntrinsic) 26 } 27 28 If(src_end, src_size).GT.Unlikely.b { 29 Goto(:FallToIntrinsic) 30 } 31 32 IfImm(Compare(src_start, 0).LT.b).Imm(0).NE.Unlikely.b { 33 Goto(:FallToIntrinsic) 34 } 35 36 IfImm(Compare(dst_start, 0).LT.b).Imm(0).NE.Unlikely.b { 37 Goto(:FallToIntrinsic) 38 } 39 40 data_length := Sub(src_end, src_start).u32 41 available_space := Sub(dst_size, dst_start).u32 42 IfImm(Compare(data_length, available_space).GT.b).Imm(0).NE.Unlikely.b { 43 Goto(:FallToIntrinsic) 44 } 45end 46 47def GenerateArrayCopyTo(el_size) 48 suffix = el_size.to_s + "B" 49 #$regmask = Options.arch_64_bits? ? $temps_mask + :arg0 + :arg1 + :arg2 + :arg3 + :arg4 : $panda_mask 50 $regmask = $panda_mask 51 function("ArrayCopyTo#{suffix}".to_sym, 52 params: {src_obj: 'ref', dst_obj: 'ref', dst_start: 'u32', src_start: 'u32', src_end: 'u32'}, 53 regmap: $full_regmap, 54 regalloc_set: $regmask, 55 mode: [:FastPath]) { 56 57 # Arm32 is not supported 58 if Options.arch == :arm32 59 Intrinsic(:UNREACHABLE).void.Terminator 60 next 61 end 62 63 64if defines.PANDA_WITH_ETS 65 do_checks_ets 66 67 len := Sub(src_end, src_start).u32; 68 el_log_size = Math.log2(el_size).to_i 69 do_array_copy(el_size, el_log_size, src_obj, dst_obj, src_start, dst_start, len) 70 71 Goto(:End) 72 73Label(:FallToIntrinsic) 74 # call Intrinsic 75 id1 = get_entrypoint_offset("ARRAY_COPY_TO#{suffix}_SLOW_PATH") 76 id2 = get_entrypoint_offset("ARRAY_COPY_TO#{suffix}_ODD_SAVED") 77 Intrinsic(:SLOW_PATH_ENTRY, src_obj, dst_obj, dst_start, src_start, src_end).AddImm(id1).AddImm(id2).Terminator.void 78 Intrinsic(:UNREACHABLE).Terminator.void if defines.DEBUG 79end 80 81Label(:End) 82 ReturnVoid().void 83} 84end 85 86GenerateArrayCopyTo(el_size = 1) 87GenerateArrayCopyTo(el_size = 2) 88GenerateArrayCopyTo(el_size = 4) 89GenerateArrayCopyTo(el_size = 8) 90 91