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