1#!/usr/bin/env ruby 2 3# Copyright (c) 2023-2024 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 lowercase_suffix = el_size.to_s + "b" 50 #$regmask = Options.arch_64_bits? ? $temps_mask + :arg0 + :arg1 + :arg2 + :arg3 + :arg4 : $panda_mask 51 $regmask = $panda_mask 52 function("ArrayCopyTo#{suffix}".to_sym, 53 params: {src_obj: 'ref', dst_obj: 'ref', dst_start: 'u32', src_start: 'u32', src_end: 'u32'}, 54 regmap: $full_regmap, 55 regalloc_set: $regmask, 56 mode: [:FastPath]) { 57 58 # Arm32 is not supported 59 if Options.arch == :arm32 60 Intrinsic(:UNREACHABLE).void.Terminator 61 next 62 end 63 64 65if defines.PANDA_WITH_ETS 66 do_checks_ets 67 68 len := Sub(src_end, src_start).u32; 69 el_log_size = Math.log2(el_size).to_i 70 do_array_copy(el_size, el_log_size, src_obj, dst_obj, src_start, dst_start, len) 71 72 Goto(:End) 73 74Label(:FallToIntrinsic) 75 # call Intrinsic 76 ep_offset = get_entrypoint_offset("ARRAY_COPY_TO#{suffix}_SLOW_PATH") 77 Intrinsic(:SLOW_PATH_ENTRY, src_obj, dst_obj, dst_start, src_start, src_end).AddImm(ep_offset).MethodAsImm("ArrayCopyTo#{lowercase_suffix}OddSavedBridge").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 91def GenerateArrayCopyToUnchecked(el_size) 92 suffix = el_size.to_s + "Byte" 93 #$regmask = Options.arch_64_bits? ? $temps_mask + :arg0 + :arg1 + :arg2 + :arg3 + :arg4 : $panda_mask 94 $regmask = $panda_mask 95 function("ArrayCopyToUnchecked#{suffix}".to_sym, 96 params: {src_obj: 'ref', dst_obj: 'ref', dst_start: 'u32', src_start: 'u32', src_end: 'u32'}, 97 regmap: $full_regmap, 98 regalloc_set: $regmask, 99 mode: [:FastPath]) { 100 101 # Arm32 is not supported 102 if Options.arch == :arm32 103 Intrinsic(:UNREACHABLE).void.Terminator 104 next 105 end 106 107 len := Sub(src_end, src_start).u32; 108 el_log_size = Math.log2(el_size).to_i 109 do_array_copy(el_size, el_log_size, src_obj, dst_obj, src_start, dst_start, len) 110 ReturnVoid().void 111} 112end 113 114GenerateArrayCopyToUnchecked(el_size = 1) 115GenerateArrayCopyToUnchecked(el_size = 2) 116GenerateArrayCopyToUnchecked(el_size = 4) 117GenerateArrayCopyToUnchecked(el_size = 8)