blob: 13b52e5dc552cd12e78e2092ded37b80b16c7102 [file] [log] [blame]
Artem Serov12e097c2016-08-08 15:13:26 +01001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
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
17#ifndef ART_COMPILER_UTILS_ARM_JNI_MACRO_ASSEMBLER_ARM_VIXL_H_
18#define ART_COMPILER_UTILS_ARM_JNI_MACRO_ASSEMBLER_ARM_VIXL_H_
19
20#include "base/arena_containers.h"
21#include "base/logging.h"
22#include "constants_arm.h"
23#include "offsets.h"
24#include "utils/arm/assembler_arm_shared.h"
25#include "utils/arm/assembler_arm_vixl.h"
26#include "utils/arm/managed_register_arm.h"
27#include "utils/assembler.h"
28#include "utils/jni_macro_assembler.h"
29
30namespace art {
31namespace arm {
32
33class ArmVIXLJNIMacroAssembler FINAL
34 : public JNIMacroAssemblerFwd<ArmVIXLAssembler, PointerSize::k32> {
35 private:
36 class ArmException;
37 public:
38 explicit ArmVIXLJNIMacroAssembler(ArenaAllocator* arena)
39 : JNIMacroAssemblerFwd(arena),
40 exception_blocks_(arena->Adapter(kArenaAllocAssembler)) {}
41
42 virtual ~ArmVIXLJNIMacroAssembler() {}
43 void FinalizeCode() OVERRIDE;
44
45 //
46 // Overridden common assembler high-level functionality
47 //
48
49 // Emit code that will create an activation on the stack.
50 void BuildFrame(size_t frame_size,
51 ManagedRegister method_reg,
52 ArrayRef<const ManagedRegister> callee_save_regs,
53 const ManagedRegisterEntrySpills& entry_spills) OVERRIDE;
54
55 // Emit code that will remove an activation from the stack.
56 void RemoveFrame(size_t frame_size,
Roland Levillain0d127e12017-07-05 17:01:11 +010057 ArrayRef<const ManagedRegister> callee_save_regs,
58 bool may_suspend) OVERRIDE;
Artem Serov12e097c2016-08-08 15:13:26 +010059
60 void IncreaseFrameSize(size_t adjust) OVERRIDE;
61 void DecreaseFrameSize(size_t adjust) OVERRIDE;
62
63 // Store routines.
64 void Store(FrameOffset offs, ManagedRegister src, size_t size) OVERRIDE;
65 void StoreRef(FrameOffset dest, ManagedRegister src) OVERRIDE;
66 void StoreRawPtr(FrameOffset dest, ManagedRegister src) OVERRIDE;
67
68 void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister scratch) OVERRIDE;
69
70 void StoreStackOffsetToThread(ThreadOffset32 thr_offs,
71 FrameOffset fr_offs,
72 ManagedRegister scratch) OVERRIDE;
73
74 void StoreStackPointerToThread(ThreadOffset32 thr_offs) OVERRIDE;
75
76 void StoreSpanning(FrameOffset dest,
77 ManagedRegister src,
78 FrameOffset in_off,
79 ManagedRegister scratch) OVERRIDE;
80
81 // Load routines.
82 void Load(ManagedRegister dest, FrameOffset src, size_t size) OVERRIDE;
83
84 void LoadFromThread(ManagedRegister dest,
85 ThreadOffset32 src,
86 size_t size) OVERRIDE;
87
88 void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE;
89
90 void LoadRef(ManagedRegister dest,
91 ManagedRegister base,
92 MemberOffset offs,
93 bool unpoison_reference) OVERRIDE;
94
95 void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs) OVERRIDE;
96
97 void LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset32 offs) OVERRIDE;
98
99 // Copying routines.
100 void Move(ManagedRegister dest, ManagedRegister src, size_t size) OVERRIDE;
101
102 void CopyRawPtrFromThread(FrameOffset fr_offs,
103 ThreadOffset32 thr_offs,
104 ManagedRegister scratch) OVERRIDE;
105
106 void CopyRawPtrToThread(ThreadOffset32 thr_offs,
107 FrameOffset fr_offs,
108 ManagedRegister scratch) OVERRIDE;
109
110 void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister scratch) OVERRIDE;
111
112 void Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch, size_t size) OVERRIDE;
113
114 void Copy(FrameOffset dest,
115 ManagedRegister src_base,
116 Offset src_offset,
117 ManagedRegister scratch,
118 size_t size) OVERRIDE;
119
120 void Copy(ManagedRegister dest_base,
121 Offset dest_offset,
122 FrameOffset src,
123 ManagedRegister scratch,
124 size_t size) OVERRIDE;
125
126 void Copy(FrameOffset dest,
127 FrameOffset src_base,
128 Offset src_offset,
129 ManagedRegister scratch,
130 size_t size) OVERRIDE;
131
132 void Copy(ManagedRegister dest,
133 Offset dest_offset,
134 ManagedRegister src,
135 Offset src_offset,
136 ManagedRegister scratch,
137 size_t size) OVERRIDE;
138
139 void Copy(FrameOffset dest,
140 Offset dest_offset,
141 FrameOffset src,
142 Offset src_offset,
143 ManagedRegister scratch,
144 size_t size) OVERRIDE;
145
146 // Sign extension.
147 void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE;
148
149 // Zero extension.
150 void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE;
151
152 // Exploit fast access in managed code to Thread::Current().
153 void GetCurrentThread(ManagedRegister mtr) OVERRIDE;
154 void GetCurrentThread(FrameOffset dest_offset,
155 ManagedRegister scratch) OVERRIDE;
156
157 // Set up out_reg to hold a Object** into the handle scope, or to be null if the
158 // value is null and null_allowed. in_reg holds a possibly stale reference
159 // that can be used to avoid loading the handle scope entry to see if the value is
160 // null.
161 void CreateHandleScopeEntry(ManagedRegister out_reg,
162 FrameOffset handlescope_offset,
163 ManagedRegister in_reg,
164 bool null_allowed) OVERRIDE;
165
166 // Set up out_off to hold a Object** into the handle scope, or to be null if the
167 // value is null and null_allowed.
168 void CreateHandleScopeEntry(FrameOffset out_off,
169 FrameOffset handlescope_offset,
170 ManagedRegister scratch,
171 bool null_allowed) OVERRIDE;
172
173 // src holds a handle scope entry (Object**) load this into dst.
174 void LoadReferenceFromHandleScope(ManagedRegister dst,
175 ManagedRegister src) OVERRIDE;
176
177 // Heap::VerifyObject on src. In some cases (such as a reference to this) we
178 // know that src may not be null.
179 void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE;
180 void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE;
181
182 // Call to address held at [base+offset].
183 void Call(ManagedRegister base, Offset offset, ManagedRegister scratch) OVERRIDE;
184 void Call(FrameOffset base, Offset offset, ManagedRegister scratch) OVERRIDE;
185 void CallFromThread(ThreadOffset32 offset, ManagedRegister scratch) OVERRIDE;
186
187 // Generate code to check if Thread::Current()->exception_ is non-null
188 // and branch to a ExceptionSlowPath if it is.
189 void ExceptionPoll(ManagedRegister scratch, size_t stack_adjust);
190
Igor Murashkinae7ff922016-10-06 14:59:19 -0700191 // Create a new label that can be used with Jump/Bind calls.
192 std::unique_ptr<JNIMacroLabel> CreateLabel() OVERRIDE;
193 // Emit an unconditional jump to the label.
194 void Jump(JNIMacroLabel* label) OVERRIDE;
195 // Emit a conditional jump to the label by applying a unary condition test to the register.
196 void Jump(JNIMacroLabel* label, JNIMacroUnaryCondition cond, ManagedRegister test) OVERRIDE;
197 // Code at this offset will serve as the target for the Jump call.
198 void Bind(JNIMacroLabel* label) OVERRIDE;
199
Artem Serov12e097c2016-08-08 15:13:26 +0100200 void MemoryBarrier(ManagedRegister scratch) OVERRIDE;
201
202 void EmitExceptionPoll(ArmVIXLJNIMacroAssembler::ArmException *exception);
203 void Load(ArmManagedRegister dest, vixl32::Register base, int32_t offset, size_t size);
204
205 private:
206 class ArmException {
207 private:
208 ArmException(ArmManagedRegister scratch, size_t stack_adjust)
209 : scratch_(scratch), stack_adjust_(stack_adjust) {}
210
211 vixl32::Label* Entry() { return &exception_entry_; }
212
213 // Register used for passing Thread::Current()->exception_ .
214 const ArmManagedRegister scratch_;
215
216 // Stack adjust for ExceptionPool.
217 const size_t stack_adjust_;
218
219 vixl32::Label exception_entry_;
220
221 friend class ArmVIXLJNIMacroAssembler;
222 DISALLOW_COPY_AND_ASSIGN(ArmException);
223 };
224
225 // List of exception blocks to generate at the end of the code cache.
226 ArenaVector<std::unique_ptr<ArmVIXLJNIMacroAssembler::ArmException>> exception_blocks_;
227 // Used for testing.
Vladimir Marko0e851e22016-08-25 18:17:56 +0100228 friend class ArmVIXLAssemblerTest_VixlLoadFromOffset_Test;
229 friend class ArmVIXLAssemblerTest_VixlStoreToOffset_Test;
Artem Serov12e097c2016-08-08 15:13:26 +0100230};
231
Igor Murashkinae7ff922016-10-06 14:59:19 -0700232class ArmVIXLJNIMacroLabel FINAL
233 : public JNIMacroLabelCommon<ArmVIXLJNIMacroLabel,
234 vixl32::Label,
235 kArm> {
236 public:
237 vixl32::Label* AsArm() {
238 return AsPlatformLabel();
239 }
240};
241
Artem Serov12e097c2016-08-08 15:13:26 +0100242} // namespace arm
243} // namespace art
244
245#endif // ART_COMPILER_UTILS_ARM_JNI_MACRO_ASSEMBLER_ARM_VIXL_H_