• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)