• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env ruby
2
3# Copyright (c) 2021-2022 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$panda_regmap = Regmap.new({
17  arm64: {tr: 28},
18  arm32: {tr: 10},
19  x86_64: {tr: 15}
20})
21
22$arch_regmap = Regmap.new({
23  arm64: {fp: 29, sp: 31, lr: 30},
24  arm32: {fp: 11, sp: 13, lr: 14, pc: 15},
25  x86_64: {fp: 9, sp: 10}
26})
27
28$args_regmap = Regmap.new({
29  arm64: {fp: 29, sp: 31, ret: 0, arg0: 0, arg1: 1, arg2: 2, arg3: 3, arg4: 4, arg5: 5, arg6: 6, arg7: 7},
30  arm32: {fp: 11, sp: 13, ret: 0, arg0: 0, arg1: 1, arg2: 2, arg3: 3},
31  x86_64: {fp: 9, sp: 10, ret: 0, arg0: 7, arg1: 6, arg2: 2, arg3: 1, arg4: 8, arg5: 5}
32})
33
34# Regmap for temp registers
35$temps_regmap = Regmap.new(Options.arch_info.temp_regs.each_with_index.map { |x, i| ["tmp#{i}".to_sym, x] }.to_h,
36                         direct: true)
37
38$callees_regmap = Regmap.new({
39   arm64: (19..28).each_with_index.map { |x, i| ["callee#{i}".to_sym, x] }.to_h,
40   arm32: (4..10).each_with_index.map { |x, i| ["callee#{i}".to_sym, x] }.to_h,
41   x86_64: (11..15).each_with_index.map { |x, i| ["callee#{i}".to_sym, x] }.to_h,
42})
43
44$callers_regmap = Regmap.new({
45  arm64: (0..18).each_with_index.map { |x, i| ["caller#{i}".to_sym, x] }.to_h,
46  arm32: (0..3).each_with_index.map { |x, i| ["caller#{i}".to_sym, x] }.to_h,
47  x86_64: (0..8).each_with_index.map { |x, i| ["caller#{i}".to_sym, x] }.to_h,
48})
49
50# Regmap that contains all defined regmap
51$full_regmap = $panda_regmap + $args_regmap + $arch_regmap + $temps_regmap + $callees_regmap + $callers_regmap
52
53# In default mask we use all registers, except temps and special arch registers(e.g. lr)
54$default_mask = ~RegMask.new($full_regmap, *(Options.arch_info.temp_regs)) - $arch_regmap
55
56# Panda mask is the mask intended to be used with Panda ABI. Currently, we just remove thread reg from the default mask.
57$panda_mask = $default_mask - :tr
58
59# Temporary registers mask
60$temps_mask = RegMask.new($full_regmap, :tmp0, :tmp1, :tmp2)
61
62# Mask of all callers regsiters, except temp registers
63$panda_callers_mask = RegMask.from_regmap($full_regmap, $callers_regmap) - $temps_mask
64
65# Mask of all callees regsiters, except temp registers
66$panda_callees_mask = RegMask.from_regmap($full_regmap, $callees_regmap) - $temps_mask
67
68# Remove even registers from regmask for ARM32, because compiler conservatively uses two physical registers for one
69# virtual register, e.g. for r0 we should also remove r1.
70if Options.arch == :arm32
71  $default_mask = RegMask.from_value($default_mask. regmap, $default_mask.value & 0x55555555)
72  # Some temps may have even values
73  $temps_mask.each { |x| $default_mask[x + 1] = false }
74end
75
76module Constants
77    TLAB_OFFSET = "cross_values::GetManagedThreadTlabOffset(GetArch())"
78    TLAB_CUR_FREE_POSITION_OFFSET = "cross_values::GetTlabCurFreePositionOffset(GetArch())"
79    TLAB_MEMORY_END_ADDR_OFFSET = "cross_values::GetTlabMemoryEndAddrOffset(GetArch())"
80    CREATE_OBJECT_BY_CLASS = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::CREATE_OBJECT_BY_CLASS_SLOW_PATH)"
81    OBJECT_CLASS_OFFSET = "cross_values::GetObjectHeaderClassPointerOffset(GetArch())"
82    WRITE_TLAB_STATS_NO_BRIDGE = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::WRITE_TLAB_STATS_NO_BRIDGE)"
83    WRITE_TLAB_STATS = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::WRITE_TLAB_STATS)"
84    ANNOTATE_SANITIZERS_NO_BRIDGE = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::ANNOTATE_SANITIZERS_NO_BRIDGE)"
85    CREATE_ARRAY_SLOW_PATH = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::CREATE_ARRAY_SLOW_PATH)"
86    GET_CALLEE_METHOD = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::GET_CALLEE_METHOD_DIRECT)"
87    INITIALIZE_CLASS_BY_ID = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::INITIALIZE_CLASS_BY_ID_DIRECT)"
88    RESOLVE_CLASS = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::RESOLVE_CLASS_DIRECT)"
89    GET_VTABLE_INDEX = "cross_values::GetMethodVTableIndexOffset(GetArch())"
90    CLASS_STATE_OFFSET = "cross_values::GetClassStateOffset(GetArch())"
91    ARRAY_LENGTH_OFFSET = "cross_values::GetCoretypesArrayLengthOffset(GetArch())"
92    VREGISTERS_NUM_OFFSET = "cross_values::GetFrameNumVregsOffset(GetArch())"
93    VREGISTERS_OFFSET = "cross_values::GetFrameVregsOffset(GetArch())"
94    VREGISTER_SIZE = "cross_values::GetFrameVregisterSize(GetArch())"
95    VREGISTER_VALUE_OFFSET = "cross_values::GetFrameVregisterValueOffset(GetArch())"
96    GET_ACC_OFFSET = "cross_values::GetFrameAccOffset(GetArch())"
97    GET_ACC_MIRROR_OFFSET = "cross_values::GetFrameAccMirrorOffset(GetArch())"
98    RESOLVE_VIRTUAL_CALL_AOT = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::RESOLVE_VIRTUAL_CALL_AOT)"
99    GET_CLASS_METHODS_OFFSET = "cross_values::GetClassMethodsOffset(GetArch())"
100    FRAME_METHOD_OFFSET = "Frame::GetMethodOffset()"
101    FRAME_INSTRUCTIONS_OFFSET = "Frame::GetInstructionsOffset()"
102    MARK_WORD_OFFSET = "cross_values::GetObjectHeaderMarkWordOffset(GetArch())"
103    INTERNAL_THREAD_ID_OFFSET = "cross_values::GetManagedThreadInternalIdOffset(GetArch())"
104    LOCAL_OBJECTS_LOCKED_ADDR_OFFSET = "cross_values::GetManagedThreadLocalObjectsLockedAddrOffset(GetArch())"
105    LOCKED_OBJECTS_CAPACITY_OFFSET = "cross_values::GetMtManagedThreadLockedObjectCapacityOffset(GetArch())"
106    LOCKED_OBJECTS_SIZE_OFFSET = "cross_values::GetMtManagedThreadLockedObjectSizeOffset(GetArch())"
107    LOCKED_OBJECTS_DATA_OFFSET = "cross_values::GetMtManagedThreadLockedObjectDataOffset(GetArch())"
108    LOCKED_OBJECT_INFO_MONITOR_OFFSET = "cross_values::GetLockedObjectInfoMonitorOffset(GetArch())"
109    LOCKED_OBJECT_INFO_FRAME_OFFSET = "cross_values::GetLockedObjectInfoStackOffset(GetArch())"
110    LOCKED_OBJECT_INFO_SIZE = "cross_values::GetLockedObjectInfoSize(GetArch())"
111    MONITOR_ENTER_SLOW_PATH = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::MONITOR_ENTER_SLOW_PATH)"
112    MONITOR_EXIT_SLOW_PATH = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::MONITOR_EXIT_SLOW_PATH)"
113    CHECK_CAST_SLOW_PATH = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::CHECK_CAST)"
114    MARK_WORD_STATUS_MASK = "static_cast<uint64_t>(MarkWord::STATUS_MASK)"
115    MARK_WORD_LWL_THREAD_ID_OFFSET = "static_cast<uint64_t>(MarkWord::LIGHT_LOCK_THREADID_SHIFT)"
116    MARK_WORD_LWL_THREAD_ID_MASK = "static_cast<uint64_t>(MarkWord::LIGHT_LOCK_THREADID_MASK_IN_PLACE)"
117    MARK_WORD_LWL_COUNTER_INC = "static_cast<uint64_t>(1 << MarkWord::LIGHT_LOCK_LOCK_COUNT_SHIFT)"
118    MARK_WORD_LWL_COUNTER_MASK = "static_cast<uint64_t>(MarkWord::LIGHT_LOCK_LOCK_COUNT_MASK_IN_PLACE)"
119    MARK_WORD_LWL_THREAD_ID_AND_COUNTER_MASK = "static_cast<uint64_t>(MarkWord::LIGHT_LOCK_THREADID_MASK_IN_PLACE | MarkWord::LIGHT_LOCK_LOCK_COUNT_MASK_IN_PLACE)"
120    MARK_WORD_STATUS_MASK_AND_LWL_THREAD_ID_MASK = "static_cast<uint64_t>(MarkWord::STATUS_MASK | MarkWord::LIGHT_LOCK_THREADID_MASK_IN_PLACE)"
121    CLASS_COMPONENT_OFFSET = "cross_values::GetClassComponentTypeOffset(GetArch())"
122    CLASS_TYPE_OFFSET = "cross_values::GetClassTypeOffset(GetArch())"
123    CLASS_ITABLE_ENTRIES_DATA_OFFSET = "CLASS_ITABLE_OFFSET + CLASS_ITABLE_ENTRIES_DATA_OFFSET"
124    CLASS_ITABLE_ENTRIES_SIZE_OFFSET = "CLASS_ITABLE_OFFSET + CLASS_ITABLE_ENTRIES_SIZE_OFFSET"
125    CLASS_ITABLE_ENTRY_SIZE = "cross_values::GetClassItableEntrySize(GetArch())"
126    CLASS_ITABLE_ENTRY_INTERFACE_OFFSET = "cross_values::GetClassItableEntryInterfaceOffset(GetArch())"
127    IS_INSTANCE_BY_BCID = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::IS_INSTANCE_BY_BCID)"
128    CHECK_CAST_BY_BCID = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::CHECK_CAST_BY_BCID)"
129
130    IC_HANDLER_KIND_BIT = "cross_values::GetIcHandlerKindBitStartBit(graph->GetArch())"
131    IC_HANDLER_KIND_MASK = "cross_values::GetIcHandlerKindBitMask(graph->GetArch())"
132    IC_HANDLER_OFFSET_BIT = "cross_values::GetIcHandlerOffsetBitStartBit(graph->GetArch())"
133    IC_HANDLER_OFFSET_MASK = "cross_values::GetIcHandlerOffsetBitMask(graph->GetArch())"
134    IC_HANDLER_INLINE_BIT = "cross_values::GetIcHandlerInlinedPropsBitStartBit(graph->GetArch())"
135    IC_HANDLER_INLINE_MASK = "cross_values::GetIcHandlerInlinedPropsBitMask(graph->GetArch())"
136
137    IC_HANDLER_KIND_FIELD = "cross_values::GetIcHandlerHandlerKindField(graph->GetArch())"
138    DYN_INT_TYPE = "AnyBaseType::UNDEFINED_TYPE"
139    DYN_DOUBLE_TYPE = "AnyBaseType::UNDEFINED_TYPE"
140
141end
142macro(:call_runtime) { |e, *args|
143    entry := LoadI(%tr).Imm(e).ptr
144    CallIndirect(entry, *args)
145}
146
147macro(:call_runtime_save_all) { |e, *args|
148    Intrinsic(:SAVE_REGISTERS_EP).void
149    ret = call_runtime(e, *args)
150    Intrinsic(:RESTORE_REGISTERS_EP).void
151    ret
152}
153