1// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/globals.h"
6#if defined(TARGET_ARCH_ARM)
7
8#include "vm/runtime_entry.h"
9
10#include "vm/simulator.h"
11#include "vm/stub_code.h"
12
13#if !defined(DART_PRECOMPILED_RUNTIME)
14#include "vm/compiler/assembler/assembler.h"
15#endif // !defined(DART_PRECOMPILED_RUNTIME)
16
17namespace dart {
18
19#define __ assembler->
20
21uword RuntimeEntry::GetEntryPoint() const {
22 // Compute the effective address. When running under the simulator,
23 // this is a redirection address that forces the simulator to call
24 // into the runtime system.
25 uword entry = reinterpret_cast<uword>(function());
26#if defined(USING_SIMULATOR)
27 // Redirection to leaf runtime calls supports a maximum of 4 arguments passed
28 // in registers (maximum 2 double arguments for leaf float runtime calls).
29 ASSERT(argument_count() >= 0);
30 ASSERT(!is_leaf() || (!is_float() && (argument_count() <= 4)) ||
31 (argument_count() <= 2));
32 Simulator::CallKind call_kind =
33 is_leaf() ? (is_float() ? Simulator::kLeafFloatRuntimeCall
34 : Simulator::kLeafRuntimeCall)
35 : Simulator::kRuntimeCall;
36 entry =
37 Simulator::RedirectExternalReference(entry, call_kind, argument_count());
38#endif
39 return entry;
40}
41
42#if !defined(DART_PRECOMPILED_RUNTIME)
43// Generate code to call into the stub which will call the runtime
44// function. Input for the stub is as follows:
45// SP : points to the arguments and return value array.
46// R9 : address of the runtime function to call.
47// R4 : number of arguments to the call.
48void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry,
49 compiler::Assembler* assembler,
50 intptr_t argument_count) {
51 if (runtime_entry->is_leaf()) {
52 ASSERT(argument_count == runtime_entry->argument_count());
53 __ LoadFromOffset(
54 kWord, TMP, THR,
55 compiler::target::Thread::OffsetFromThread(runtime_entry));
56 __ str(TMP,
57 compiler::Address(THR, compiler::target::Thread::vm_tag_offset()));
58 __ blx(TMP);
59 __ LoadImmediate(TMP, VMTag::kDartCompiledTagId);
60 __ str(TMP,
61 compiler::Address(THR, compiler::target::Thread::vm_tag_offset()));
62 ASSERT((kAbiPreservedCpuRegs & (1 << THR)) != 0);
63 ASSERT((kAbiPreservedCpuRegs & (1 << PP)) != 0);
64 } else {
65 // Argument count is not checked here, but in the runtime entry for a more
66 // informative error message.
67 __ LoadFromOffset(
68 kWord, R9, THR,
69 compiler::target::Thread::OffsetFromThread(runtime_entry));
70 __ LoadImmediate(R4, argument_count);
71 __ BranchLinkToRuntime();
72 }
73}
74#endif // !defined(DART_PRECOMPILED_RUNTIME)
75
76} // namespace dart
77
78#endif // defined TARGET_ARCH_ARM
79