• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env ruby
2
3# Copyright (c) 2021-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$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
60if Options.arch == :arm64
61  $temps_mask = RegMask.new($full_regmap, :tmp0, :tmp1)
62else
63  $temps_mask = RegMask.new($full_regmap, :tmp0, :tmp1, :tmp2)
64end
65# Mask of all callers regsiters, except temp registers
66$panda_callers_mask = RegMask.from_regmap($full_regmap, $callers_regmap) - $temps_mask
67
68# Mask of all callees regsiters, except temp registers
69$panda_callees_mask = RegMask.from_regmap($full_regmap, $callees_regmap) - $temps_mask
70
71# Remove even registers from regmask for ARM32, because compiler conservatively uses two physical registers for one
72# virtual register, e.g. for r0 we should also remove r1.
73if Options.arch == :arm32
74  $default_mask = RegMask.from_value($default_mask. regmap, $default_mask.value & 0x55555555)
75  # Some temps may have even values
76  $temps_mask.each { |x| $default_mask[x + 1] = false }
77end
78
79module Constants
80    TLAB_OFFSET = "cross_values::GetManagedThreadTlabOffset(GetArch())"
81    TLAB_CUR_FREE_POSITION_OFFSET = "cross_values::GetTlabCurFreePositionOffset(GetArch())"
82    TLAB_MEMORY_END_ADDR_OFFSET = "cross_values::GetTlabMemoryEndAddrOffset(GetArch())"
83    OBJECT_CLASS_OFFSET = "cross_values::GetObjectHeaderClassPointerOffset(GetArch())"
84    WRITE_TLAB_STATS_NO_BRIDGE = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::WRITE_TLAB_STATS_NO_BRIDGE)"
85    ANNOTATE_SANITIZERS_NO_BRIDGE = "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::ANNOTATE_SANITIZERS_NO_BRIDGE)"
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    ARRAY_DATA_OFFSET = "cross_values::GetCoretypesArrayDataOffset(GetArch())"
93    ARRAY_CLASS_SIZE = "sizeof(coretypes::Array)"
94    ARRAY_CLASS_SIZE_WITH_ALIGNMENT = "sizeof(coretypes::Array) + TLAB_ALIGNMENT - 1"
95    VREGISTERS_NUM_OFFSET = "cross_values::GetFrameNumVregsOffset(GetArch())"
96    VREGISTERS_OFFSET = "cross_values::GetFrameVregsOffset(GetArch())"
97    VREGISTER_SIZE = "cross_values::GetFrameVregisterSize(GetArch())"
98    FRAME_SIZE = "cross_values::GetFrameSize(GetArch())"
99    DEFAULT_FRAME_ALIGNMENT_IN_BYTES = "GetAlignmentInBytes(DEFAULT_FRAME_ALIGNMENT)"
100    VREGISTER_VALUE_OFFSET = "cross_values::GetFrameVregisterValueOffset(GetArch())"
101    OBJECT_TAG = "cross_values::GetFrameVregisterObjectTag(GetArch())"
102    PRIMITIVE_TAG = "cross_values::GetFrameVregisterPrimitiveTag(GetArch())"
103    GET_ACC_OFFSET = "cross_values::GetFrameAccOffset(GetArch())"
104    GET_ACC_MIRROR_OFFSET = "cross_values::GetFrameAccMirrorOffset(GetArch())"
105    GET_HOTNESS_COUNTER_OFFSET = "cross_values::GetMethodHotnessCounterOffset(GetArch())"
106    GET_FRAME_KIND_OFFSET = "cross_values::GetManagedThreadFrameKindOffset(GetArch())"
107    GET_CLASS_METHODS_OFFSET = "cross_values::GetClassMethodsOffset(GetArch())"
108    METHOD_NUM_ARGS_OFFSET = "cross_values::GetMethodNumArgsOffset(GetArch())"
109    METHOD_CLASS_OFFSET = "cross_values::GetMethodClassOffset(GetArch())"
110    METHOD_PANDA_FILE_OFFSET = "cross_values::GetMethodPandaFileOffset(GetArch())"
111    METHOD_CODE_ID_OFFSET = "cross_values::GetMethodCodeIdOffset(GetArch())"
112    METHOD_NATIVE_POINTER_OFFSET = "cross_values::GetMethodNativePointerOffset(GetArch())"
113    METHOD_COMPILED_ENTRY_POINT_OFFSET = "cross_values::GetMethodCompiledEntryPointOffset(GetArch())"
114    FRAME_NUM_VREGS_OFFSET = "cross_values::GetFrameNumVregsOffset(GetArch())"
115    FRAME_NUM_ACTUAL_ARGS_OFFSET = "cross_values::GetFrameNumActualArgsOffset(GetArch())"
116    FRAME_METHOD_OFFSET = "cross_values::GetFrameMethodOffset(GetArch())"
117    FRAME_PREV_FRAME_OFFSET = "cross_values::GetFramePrevFrameOffset(GetArch())"
118    FRAME_BYTECODE_OFFSET = "cross_values::GetFrameBytecodeOffset(GetArch())"
119    FRAME_FLAGS_OFFSET = "cross_values::GetFrameFlagsOffset(GetArch())"
120    FRAME_NEXT_INSTRUCTION_OFFSET = "cross_values::GetFrameNextInstructionOffset(GetArch())"
121    FRAME_INSTRUCTIONS_OFFSET = "cross_values::GetFrameInstructionsOffset(GetArch())"
122    FRAME_EXT_OFFSET = "cross_values::GetFrameExtOffset(GetArch())"
123    FIELD_ACCESS_FLAGS_OFFSET = "cross_values::GetFieldAccessFlagsOffset(GetArch())"
124    FIELD_OFFSET_OFFSET = "cross_values::GetFieldOffsetOffset(GetArch())"
125    FIELD_CLASS_OFFSET = "cross_values::GetFieldClassOffset(GetArch())"
126    THREAD_STACK_FRAME_ALLOCATOR_OFFSET = "cross_values::GetManagedThreadStackFrameAllocatorOffset(GetArch())"
127    THREAD_FRAME_OFFSET = "cross_values::GetManagedThreadFrameOffset(GetArch())"
128    THREAD_EXCEPTION_OFFSET = "cross_values::GetManagedThreadExceptionOffset(GetArch())"
129    THREAD_INTERPRETER_CACHE_OFFSET = "cross_values::GetManagedThreadInterpreterCacheOffset(GetArch())"
130    THREAD_FLAG_OFFSET = "cross_values::GetManagedThreadFlagOffset(GetArch())"
131    THREAD_VM_OFFSET = "cross_values::GetThreadVmOffset(GetArch())"
132    MARK_WORD_OFFSET = "cross_values::GetObjectHeaderMarkWordOffset(GetArch())"
133    BASE_CLASS_MANAGED_OBJECT_OFFSET = "cross_values::GetBaseClassManagedObjectOffset(GetArch())"
134    BASE_CLASS_FLAGS_OFFSET = "cross_values::GetBaseClassFlagsOffset(graph->GetArch())"
135    INTERNAL_THREAD_ID_OFFSET = "cross_values::GetManagedThreadInternalIdOffset(GetArch())"
136    LOCAL_OBJECTS_LOCKED_ADDR_OFFSET = "cross_values::GetManagedThreadLocalObjectsLockedAddrOffset(GetArch())"
137    LOCKED_OBJECTS_CAPACITY_OFFSET = "cross_values::GetMtManagedThreadLockedObjectCapacityOffset(GetArch())"
138    LOCKED_OBJECTS_SIZE_OFFSET = "cross_values::GetMtManagedThreadLockedObjectSizeOffset(GetArch())"
139    LOCKED_OBJECTS_DATA_OFFSET = "cross_values::GetMtManagedThreadLockedObjectDataOffset(GetArch())"
140    LOCKED_OBJECT_INFO_MONITOR_OFFSET = "cross_values::GetLockedObjectInfoMonitorOffset(GetArch())"
141    LOCKED_OBJECT_INFO_FRAME_OFFSET = "cross_values::GetLockedObjectInfoStackOffset(GetArch())"
142    LOCKED_OBJECT_INFO_SIZE = "cross_values::GetLockedObjectInfoSize(GetArch())"
143    MARK_WORD_STATUS_MASK = "static_cast<uint64_t>(MarkWord::STATUS_MASK)"
144    MARK_WORD_LWL_THREAD_ID_OFFSET = "static_cast<uint64_t>(MarkWord::LIGHT_LOCK_THREADID_SHIFT)"
145    MARK_WORD_LWL_THREAD_ID_MASK = "static_cast<uint64_t>(MarkWord::LIGHT_LOCK_THREADID_MASK_IN_PLACE)"
146    MARK_WORD_LWL_COUNTER_INC = "static_cast<uint64_t>(1 << MarkWord::LIGHT_LOCK_LOCK_COUNT_SHIFT)"
147    MARK_WORD_LWL_COUNTER_MASK = "static_cast<uint64_t>(MarkWord::LIGHT_LOCK_LOCK_COUNT_MASK_IN_PLACE)"
148    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)"
149    MARK_WORD_STATUS_MASK_AND_LWL_THREAD_ID_MASK = "static_cast<uint64_t>(MarkWord::STATUS_MASK | MarkWord::LIGHT_LOCK_THREADID_MASK_IN_PLACE)"
150    CLASS_COMPONENT_OFFSET = "cross_values::GetClassComponentTypeOffset(GetArch())"
151    CLASS_TYPE_OFFSET = "cross_values::GetClassTypeOffset(GetArch())"
152    CLASS_ITABLE_ENTRIES_DATA_OFFSET = "CLASS_ITABLE_OFFSET + CLASS_ITABLE_ENTRIES_DATA_OFFSET"
153    CLASS_ITABLE_ENTRIES_SIZE_OFFSET = "CLASS_ITABLE_OFFSET + CLASS_ITABLE_ENTRIES_SIZE_OFFSET"
154    CLASS_ITABLE_ENTRY_SIZE = "cross_values::GetClassItableEntrySize(GetArch())"
155    CLASS_ITABLE_ENTRY_INTERFACE_OFFSET = "cross_values::GetClassItableEntryInterfaceOffset(GetArch())"
156    METHOD_ACCESS_FLAGS_OFFSET = "cross_values::GetMethodAccessFlagsOffset(GetArch())"
157
158    IC_HANDLER_KIND_BIT = "cross_values::GetIcHandlerKindBitStartBit(graph->GetArch())"
159    IC_HANDLER_KIND_MASK = "cross_values::GetIcHandlerKindBitMask(graph->GetArch())"
160    IC_HANDLER_OFFSET_BIT = "cross_values::GetIcHandlerOffsetBitStartBit(graph->GetArch())"
161    IC_HANDLER_OFFSET_MASK = "cross_values::GetIcHandlerOffsetBitMask(graph->GetArch())"
162    IC_HANDLER_INLINE_BIT = "cross_values::GetIcHandlerInlinedPropsBitStartBit(graph->GetArch())"
163    IC_HANDLER_INLINE_MASK = "cross_values::GetIcHandlerInlinedPropsBitMask(graph->GetArch())"
164    IC_HANDLER_KIND_FIELD = "cross_values::GetIcHandlerHandlerKindField(graph->GetArch())"
165
166    REFERENCE_TYPE_SHIFT = "compiler::DataType::ShiftByType(compiler::DataType::REFERENCE, GetArch())"
167    REFERENCE_TYPE_SIZE = "1 << compiler::DataType::ShiftByType(compiler::DataType::REFERENCE, GetArch())"
168    REFERENCE_PAIR_ALIGNMENT_MASK = "(2 << compiler::DataType::ShiftByType(compiler::DataType::REFERENCE, GetArch())) - 1"
169
170    DYN_UNDEFINED = "AnyBaseType::UNDEFINED_TYPE"
171    TLS_CARD_TABLE_MIN_ADDR_OFFSET = "cross_values::GetManagedThreadCardTableMinAddrOffset(GetArch())"
172    TLS_CARD_TABLE_ADDR_OFFSET = "cross_values::GetManagedThreadCardTableAddrOffset(GetArch())"
173
174    REF_UINT = "DataType::GetIntTypeForReference(GetGraph()->GetArch())"
175
176    REGION_SIZE_BIT = "ark::helpers::math::GetIntLog2(mem::ObjectAllocatorG1<>::GetRegionSize())"
177    MANAGED_THREAD_G1_POST_BARRIER_BUFFER_OFFSET = "cross_values::GetManagedThreadG1PostBarrierBufferOffset(GetArch())"
178    G1_LOCK_BUFFER_DATA_OFFSET = "cross_values::GetG1LockBufferDataOffset(GetArch())"
179    G1_LOCK_BUFFER_TAIL_OFFSET = "cross_values::GetG1LockBufferTailOffset(GetArch())"
180    G1_LOCK_BUFFER_HEAD_OFFSET = "cross_values::GetG1LockBufferHeadOffset(GetArch())"
181    G1_LOCK_BUFFER_SIZE_MASK = "mem::GCG1BarrierSet::G1PostBarrierRingBufferType::RING_BUFFER_SIZE_MASK"
182    CARD_TABLE_CARD_BITS = "mem::CardTable::GetCardBits()"
183    CARD_VALUE_OFFSET = "cross_values::GetCardValueOffset(GetArch())"
184    CARD_CLEAR_VALUE = "mem::CardTable::Card::GetClearValue()"
185    CARD_MARKED_VALUE = "mem::CardTable::Card::GetMarkedValue()"
186    CARD_YOUNG_VALUE = "mem::CardTable::Card::GetYoungValue()"
187    CARD_DIRTY_VALUE = "mem::CardTable::GetCardDirtyValue()"
188    CARD_STATUS_MASK = "mem::CardTable::Card::GetStatusMask()"
189    CARD_HOT_FLAG = "mem::CardTable::Card::GetHotFlag()"
190    CARD_ALIGNMENT_MASK = "cross_values::GetCardAlignmentMask(GetArch())"
191    POINTER_LOG_SIZE = "cross_values::GetPointerLogSize(GetArch())"
192
193    COMPILER_REFERENCE = "compiler::DataType::REFERENCE"
194    COMPILER_BOOL = "compiler::DataType::BOOL"
195    COMPILER_UINT8 = "compiler::DataType::UINT8"
196    COMPILER_UINT16 = "compiler::DataType::UINT16"
197    COMPILER_UINT32 = "compiler::DataType::UINT32"
198    COMPILER_UINT64 = "compiler::DataType::UINT64"
199    COMPILER_INT32 = "compiler::DataType::INT32"
200    COMPILER_PTR = "compiler::DataType::POINTER"
201
202    STRING_CLASS_SIZE = "sizeof(coretypes::String)"
203    STRING_CLASS_SIZE_WITH_ALIGNMENT = "sizeof(coretypes::String) + TLAB_ALIGNMENT - 1"
204    STRING_MUTF8_1B_MAX = "0x7f"
205    STRING_MUTF8_1B_MIN = "0x01"
206    STRING_LENGTH_OFFSET = "ark::coretypes::STRING_LENGTH_OFFSET"
207    STRING_HASHCODE_OFFSET = "ark::coretypes::STRING_HASHCODE_OFFSET"
208    STRING_DATA_OFFSET = "ark::coretypes::STRING_DATA_OFFSET"
209    ALIGNMENT_MASK = "~(TLAB_ALIGNMENT - 1)"
210
211    # shift one bit less to keep ACC_INTRINSIC bit
212    INTRINSIC_MASK_SHIFT = "INTRINSIC_SHIFT - VERIFICATION_STATUS_WIDTH - 1"
213    VERIFIED_OK = "static_cast<uint64_t>(Method::VerificationStage::VERIFIED_OK)"
214  end
215
216macro(:call_runtime) { |e, *args|
217    entry := LoadI(%tr).Imm(e).ptr
218    CallIndirect(entry, *args)
219}
220
221macro(:call_runtime_save_all) { |e, *args|
222    Intrinsic(:SAVE_REGISTERS_EP).void
223    ret = call_runtime(e, *args)
224    Intrinsic(:RESTORE_REGISTERS_EP).void
225    ret
226}
227
228macro(:i32tou32) do |arg|
229  Cast(arg).SrcType("DataType::INT32").u32
230end
231
232macro(:u32toi32) do |arg|
233  Cast(arg).SrcType("DataType::UINT32").i32
234end
235
236macro(:i32tof64) do |arg|
237  Cast(arg).SrcType("DataType::INT32").f64
238end
239
240macro(:u32tof64) do |arg|
241  Cast(arg).SrcType("DataType::UINT32").f64
242end
243
244macro(:f64tou32) do |arg|
245  Cast(arg).SrcType("DataType::FLOAT64").u32
246end
247
248macro(:f64toi64) do |arg|
249  Cast(arg).SrcType("DataType::FLOAT64").i64
250end
251
252macro(:u64tou32) do |arg|
253  Cast(arg).SrcType("DataType::UINT64").u32
254end
255
256macro(:i32toanychecked) do |arg|
257  If(arg, 0).LT.b {
258    cast_res0 := f64toany(i32tof64(arg))
259  } Else {
260    cast_res1 := i32toany(arg)
261  }
262  Phi(cast_res0, cast_res1).any
263end
264
265macro(:anytoi32) do |arg|
266  CastAnyTypeValue(arg).AnyType("AnyBaseType::ECMASCRIPT_INT_TYPE").i32
267end
268
269macro(:anytof64) do |arg|
270  CastAnyTypeValue(arg).AnyType("AnyBaseType::ECMASCRIPT_DOUBLE_TYPE").f64
271end
272
273macro(:anytou32) do |arg|
274  i32tou32(CastAnyTypeValue(arg).AnyType("AnyBaseType::ECMASCRIPT_INT_TYPE").i32)
275end
276
277macro(:anytoheapobj) do |arg|
278  CastAnyTypeValue(arg)
279    .AnyType("AnyBaseType::ECMASCRIPT_HEAP_OBJECT_TYPE")
280    .SetFlag("ark::compiler::inst_flags::Flags::NO_CSE")
281    .SetFlag("ark::compiler::inst_flags::Flags::NO_HOIST")
282    .ref
283end
284
285macro(:heapobjtoany) do |arg|
286  CastValueToAnyType(arg).AnyType("AnyBaseType::ECMASCRIPT_HEAP_OBJECT_TYPE").any
287end
288
289['8', '16'].each do |from|
290  ['u32', 'u64'].each do |to|
291    macro(:"u#{from}to#{to}") do |arg|
292      Cast(arg).SrcType("DataType::UINT#{from}").send(:"#{to}")
293    end
294  end
295end
296
297['8', '16'].each do |from|
298  macro(:"i#{from}toi32") do |arg|
299    Cast(arg).SrcType("DataType::INT#{from}").i32
300  end
301end
302
303[['u32', 'UINT32'], ['i32', 'INT32']].each do |from, from_type|
304  ['b', 'i8', 'u8', 'i16', 'u16', 'i64', 'u64'].each do |to|
305    macro(:"#{from}to#{to}") do |arg|
306      Cast(arg).SrcType("DataType::#{from_type}").send(:"#{to}")
307    end
308  end
309end
310
311macro(:load_class) do |obj|
312  if defines.ARK_HYBRID && defines.PANDA_TARGET_64
313    klass_with_flags = LoadI(obj).Imm(Constants::OBJECT_CLASS_OFFSET).u64
314    # Mask for class pointer
315    Bitcast(And(klass_with_flags, 0x0000ffffffffffff).u64).ref
316  else
317    LoadI(obj).Imm(Constants::OBJECT_CLASS_OFFSET).ref
318  end
319end
320
321macro(:store_class) do |obj, klass|
322  if defines.ARK_HYBRID && defines.PANDA_TARGET_64
323    StoreI(obj, OrI(Bitcast(klass).u64).Imm("0x1000000000000000UL").u64).Imm(Constants::OBJECT_CLASS_OFFSET).u64
324  else
325    StoreI(obj, klass).Imm(Constants::OBJECT_CLASS_OFFSET).ref
326  end
327end
328
329macro(:get_class) do |arg|
330  Intrinsic(:DYN_OBJECT_GET_CLASS, arg).ref
331end
332
333macro(:get_bits) do |data, offset, mask|
334  AndI(ShrI(data).Imm(offset).i32).Imm(mask).i32
335end
336
337macro(:set_bits) do |data, offset, mask, bits|
338  Or(data, ShlI(AndI(bits).Imm(mask).i32).Imm(offset).i32).i32
339end
340
341macro(:nullptr) do
342  src_type = Options.arch_64_bits? ? 'DataType::INT64' : 'DataType::INT32'
343  Bitcast(0).SrcType(src_type).ptr
344end
345
346macro(:get_entrypoint_offset) do |entrypoint_id|
347  "cross_values::GetManagedThreadEntrypointOffset(GetArch(), EntrypointId::#{entrypoint_id})"
348end
349