blob: 6338b2c1c10283de471da5fdd20b0ea9a3e88293 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_MACRO_ASSEMBLER_H_
6#define V8_MACRO_ASSEMBLER_H_
7
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/assembler.h"
9
Steve Blocka7e24c12009-10-30 11:49:00 +000010
11// Helper types to make boolean flag easier to read at call-site.
12enum InvokeFlag {
13 CALL_FUNCTION,
14 JUMP_FUNCTION
15};
16
17
Ben Murdochb8a8cc12014-11-26 15:28:44 +000018// Flags used for the AllocateInNewSpace functions.
19enum AllocationFlags {
20 // No special flags.
21 NO_ALLOCATION_FLAGS = 0,
22 // Return the pointer to the allocated already tagged as a heap object.
23 TAG_OBJECT = 1 << 0,
24 // The content of the result register already contains the allocation top in
25 // new space.
26 RESULT_CONTAINS_TOP = 1 << 1,
27 // Specify that the requested size of the space to allocate is specified in
28 // words instead of bytes.
29 SIZE_IN_WORDS = 1 << 2,
30 // Align the allocation to a multiple of kDoubleSize
31 DOUBLE_ALIGNMENT = 1 << 3,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032 // Directly allocate in old space
33 PRETENURE = 1 << 4,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034};
35
36
Steve Blocka7e24c12009-10-30 11:49:00 +000037#if V8_TARGET_ARCH_IA32
Ben Murdochb8a8cc12014-11-26 15:28:44 +000038#include "src/ia32/assembler-ia32.h"
39#include "src/ia32/assembler-ia32-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040#include "src/ia32/macro-assembler-ia32.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000041#elif V8_TARGET_ARCH_X64
Ben Murdochb8a8cc12014-11-26 15:28:44 +000042#include "src/x64/assembler-x64.h"
43#include "src/x64/assembler-x64-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044#include "src/x64/macro-assembler-x64.h"
45#elif V8_TARGET_ARCH_ARM64
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046#include "src/arm64/assembler-arm64.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047#include "src/arm64/assembler-arm64-inl.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000048#include "src/arm64/constants-arm64.h"
49#include "src/arm64/macro-assembler-arm64.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000050#include "src/arm64/macro-assembler-arm64-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000051#elif V8_TARGET_ARCH_ARM
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052#include "src/arm/assembler-arm.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000053#include "src/arm/assembler-arm-inl.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054#include "src/arm/constants-arm.h"
55#include "src/arm/macro-assembler-arm.h"
56#elif V8_TARGET_ARCH_PPC
57#include "src/ppc/assembler-ppc.h"
58#include "src/ppc/assembler-ppc-inl.h"
59#include "src/ppc/constants-ppc.h"
60#include "src/ppc/macro-assembler-ppc.h"
Andrei Popescu31002712010-02-23 13:46:05 +000061#elif V8_TARGET_ARCH_MIPS
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062#include "src/mips/assembler-mips.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063#include "src/mips/assembler-mips-inl.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064#include "src/mips/constants-mips.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065#include "src/mips/macro-assembler-mips.h"
66#elif V8_TARGET_ARCH_MIPS64
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067#include "src/mips64/assembler-mips64.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068#include "src/mips64/assembler-mips64-inl.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000069#include "src/mips64/constants-mips64.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000070#include "src/mips64/macro-assembler-mips64.h"
Ben Murdochda12d292016-06-02 14:46:10 +010071#elif V8_TARGET_ARCH_S390
72#include "src/s390/assembler-s390.h"
73#include "src/s390/assembler-s390-inl.h"
74#include "src/s390/constants-s390.h"
75#include "src/s390/macro-assembler-s390.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076#elif V8_TARGET_ARCH_X87
Ben Murdochb8a8cc12014-11-26 15:28:44 +000077#include "src/x87/assembler-x87.h"
78#include "src/x87/assembler-x87-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079#include "src/x87/macro-assembler-x87.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000080#else
81#error Unsupported target architecture.
82#endif
83
Kristian Monsen80d68ea2010-09-08 11:05:35 +010084namespace v8 {
85namespace internal {
86
Ben Murdoch3ef787d2012-04-12 10:51:47 +010087class FrameScope {
88 public:
89 explicit FrameScope(MacroAssembler* masm, StackFrame::Type type)
90 : masm_(masm), type_(type), old_has_frame_(masm->has_frame()) {
91 masm->set_has_frame(true);
92 if (type != StackFrame::MANUAL && type_ != StackFrame::NONE) {
93 masm->EnterFrame(type);
94 }
95 }
96
97 ~FrameScope() {
98 if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
99 masm_->LeaveFrame(type_);
100 }
101 masm_->set_has_frame(old_has_frame_);
102 }
103
104 // Normally we generate the leave-frame code when this object goes
105 // out of scope. Sometimes we may need to generate the code somewhere else
106 // in addition. Calling this will achieve that, but the object stays in
107 // scope, the MacroAssembler is still marked as being in a frame scope, and
108 // the code will be generated again when it goes out of scope.
109 void GenerateLeaveFrame() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110 DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100111 masm_->LeaveFrame(type_);
112 }
113
114 private:
115 MacroAssembler* masm_;
116 StackFrame::Type type_;
117 bool old_has_frame_;
118};
119
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400120class FrameAndConstantPoolScope {
121 public:
122 FrameAndConstantPoolScope(MacroAssembler* masm, StackFrame::Type type)
123 : masm_(masm),
124 type_(type),
125 old_has_frame_(masm->has_frame()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000126 old_constant_pool_available_(FLAG_enable_embedded_constant_pool &&
127 masm->is_constant_pool_available()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400128 masm->set_has_frame(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000129 if (FLAG_enable_embedded_constant_pool) {
130 masm->set_constant_pool_available(true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400131 }
132 if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
133 masm->EnterFrame(type, !old_constant_pool_available_);
134 }
135 }
136
137 ~FrameAndConstantPoolScope() {
138 masm_->LeaveFrame(type_);
139 masm_->set_has_frame(old_has_frame_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000140 if (FLAG_enable_embedded_constant_pool) {
141 masm_->set_constant_pool_available(old_constant_pool_available_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400142 }
143 }
144
145 // Normally we generate the leave-frame code when this object goes
146 // out of scope. Sometimes we may need to generate the code somewhere else
147 // in addition. Calling this will achieve that, but the object stays in
148 // scope, the MacroAssembler is still marked as being in a frame scope, and
149 // the code will be generated again when it goes out of scope.
150 void GenerateLeaveFrame() {
151 DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
152 masm_->LeaveFrame(type_);
153 }
154
155 private:
156 MacroAssembler* masm_;
157 StackFrame::Type type_;
158 bool old_has_frame_;
159 bool old_constant_pool_available_;
160
161 DISALLOW_IMPLICIT_CONSTRUCTORS(FrameAndConstantPoolScope);
162};
163
164// Class for scoping the the unavailability of constant pool access.
165class ConstantPoolUnavailableScope {
166 public:
167 explicit ConstantPoolUnavailableScope(MacroAssembler* masm)
168 : masm_(masm),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000169 old_constant_pool_available_(FLAG_enable_embedded_constant_pool &&
170 masm->is_constant_pool_available()) {
171 if (FLAG_enable_embedded_constant_pool) {
172 masm_->set_constant_pool_available(false);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400173 }
174 }
175 ~ConstantPoolUnavailableScope() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176 if (FLAG_enable_embedded_constant_pool) {
177 masm_->set_constant_pool_available(old_constant_pool_available_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400178 }
179 }
180
181 private:
182 MacroAssembler* masm_;
183 int old_constant_pool_available_;
184
185 DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolUnavailableScope);
186};
187
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100188
189class AllowExternalCallThatCantCauseGC: public FrameScope {
190 public:
191 explicit AllowExternalCallThatCantCauseGC(MacroAssembler* masm)
192 : FrameScope(masm, StackFrame::NONE) { }
193};
194
195
196class NoCurrentFrameScope {
197 public:
198 explicit NoCurrentFrameScope(MacroAssembler* masm)
199 : masm_(masm), saved_(masm->has_frame()) {
200 masm->set_has_frame(false);
201 }
202
203 ~NoCurrentFrameScope() {
204 masm_->set_has_frame(saved_);
205 }
206
207 private:
208 MacroAssembler* masm_;
209 bool saved_;
210};
211
212
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100213// Support for "structured" code comments.
214#ifdef DEBUG
215
216class Comment {
217 public:
218 Comment(MacroAssembler* masm, const char* msg);
219 ~Comment();
220
221 private:
222 MacroAssembler* masm_;
223 const char* msg_;
224};
225
226#else
227
228class Comment {
229 public:
230 Comment(MacroAssembler*, const char*) {}
231};
232
233#endif // DEBUG
234
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000235
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000236// Wrapper class for passing expected and actual parameter counts as
237// either registers or immediate values. Used to make sure that the
238// caller provides exactly the expected number of parameters to the
239// callee.
240class ParameterCount BASE_EMBEDDED {
241 public:
242 explicit ParameterCount(Register reg) : reg_(reg), immediate_(0) {}
243 explicit ParameterCount(int imm) : reg_(no_reg), immediate_(imm) {}
244
245 bool is_reg() const { return !reg_.is(no_reg); }
246 bool is_immediate() const { return !is_reg(); }
247
248 Register reg() const {
249 DCHECK(is_reg());
250 return reg_;
251 }
252 int immediate() const {
253 DCHECK(is_immediate());
254 return immediate_;
255 }
256
257 private:
258 const Register reg_;
259 const int immediate_;
260
261 DISALLOW_IMPLICIT_CONSTRUCTORS(ParameterCount);
262};
263
264
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000265class AllocationUtils {
266 public:
267 static ExternalReference GetAllocationTopReference(
268 Isolate* isolate, AllocationFlags flags) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000269 if ((flags & PRETENURE) != 0) {
270 return ExternalReference::old_space_allocation_top_address(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000271 }
272 return ExternalReference::new_space_allocation_top_address(isolate);
273 }
274
275
276 static ExternalReference GetAllocationLimitReference(
277 Isolate* isolate, AllocationFlags flags) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000278 if ((flags & PRETENURE) != 0) {
279 return ExternalReference::old_space_allocation_limit_address(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000280 }
281 return ExternalReference::new_space_allocation_limit_address(isolate);
282 }
283};
284
285
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000286} // namespace internal
287} // namespace v8
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100288
Steve Blocka7e24c12009-10-30 11:49:00 +0000289#endif // V8_MACRO_ASSEMBLER_H_