1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef V8_MACRO_ASSEMBLER_H_
6 #define V8_MACRO_ASSEMBLER_H_
8 #include "src/assembler.h"
11 // Helper types to make boolean flag easier to read at call-site.
18 // Flags used for the AllocateInNewSpace functions.
19 enum AllocationFlags {
21 NO_ALLOCATION_FLAGS = 0,
22 // Return the pointer to the allocated already tagged as a heap object.
24 // The content of the result register already contains the allocation top in
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,
32 // Directly allocate in old space
37 #if V8_TARGET_ARCH_IA32
38 #include "src/ia32/assembler-ia32.h"
39 #include "src/ia32/assembler-ia32-inl.h"
40 #include "src/ia32/macro-assembler-ia32.h"
41 #elif V8_TARGET_ARCH_X64
42 #include "src/x64/assembler-x64.h"
43 #include "src/x64/assembler-x64-inl.h"
44 #include "src/x64/macro-assembler-x64.h"
45 #elif V8_TARGET_ARCH_ARM64
46 #include "src/arm64/assembler-arm64.h"
47 #include "src/arm64/assembler-arm64-inl.h"
48 #include "src/arm64/constants-arm64.h"
49 #include "src/arm64/macro-assembler-arm64.h"
50 #include "src/arm64/macro-assembler-arm64-inl.h"
51 #elif V8_TARGET_ARCH_ARM
52 #include "src/arm/assembler-arm.h"
53 #include "src/arm/assembler-arm-inl.h"
54 #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"
61 #elif V8_TARGET_ARCH_MIPS
62 #include "src/mips/assembler-mips.h"
63 #include "src/mips/assembler-mips-inl.h"
64 #include "src/mips/constants-mips.h"
65 #include "src/mips/macro-assembler-mips.h"
66 #elif V8_TARGET_ARCH_MIPS64
67 #include "src/mips64/assembler-mips64.h"
68 #include "src/mips64/assembler-mips64-inl.h"
69 #include "src/mips64/constants-mips64.h"
70 #include "src/mips64/macro-assembler-mips64.h"
71 #elif V8_TARGET_ARCH_X87
72 #include "src/x87/assembler-x87.h"
73 #include "src/x87/assembler-x87-inl.h"
74 #include "src/x87/macro-assembler-x87.h"
76 #error Unsupported target architecture.
84 explicit FrameScope(MacroAssembler* masm, StackFrame::Type type)
85 : masm_(masm), type_(type), old_has_frame_(masm->has_frame()) {
86 masm->set_has_frame(true);
87 if (type != StackFrame::MANUAL && type_ != StackFrame::NONE) {
88 masm->EnterFrame(type);
93 if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
94 masm_->LeaveFrame(type_);
96 masm_->set_has_frame(old_has_frame_);
99 // Normally we generate the leave-frame code when this object goes
100 // out of scope. Sometimes we may need to generate the code somewhere else
101 // in addition. Calling this will achieve that, but the object stays in
102 // scope, the MacroAssembler is still marked as being in a frame scope, and
103 // the code will be generated again when it goes out of scope.
104 void GenerateLeaveFrame() {
105 DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
106 masm_->LeaveFrame(type_);
110 MacroAssembler* masm_;
111 StackFrame::Type type_;
115 class FrameAndConstantPoolScope {
117 FrameAndConstantPoolScope(MacroAssembler* masm, StackFrame::Type type)
120 old_has_frame_(masm->has_frame()),
121 old_constant_pool_available_(FLAG_enable_embedded_constant_pool &&
122 masm->is_constant_pool_available()) {
123 masm->set_has_frame(true);
124 if (FLAG_enable_embedded_constant_pool) {
125 masm->set_constant_pool_available(true);
127 if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
128 masm->EnterFrame(type, !old_constant_pool_available_);
132 ~FrameAndConstantPoolScope() {
133 masm_->LeaveFrame(type_);
134 masm_->set_has_frame(old_has_frame_);
135 if (FLAG_enable_embedded_constant_pool) {
136 masm_->set_constant_pool_available(old_constant_pool_available_);
140 // Normally we generate the leave-frame code when this object goes
141 // out of scope. Sometimes we may need to generate the code somewhere else
142 // in addition. Calling this will achieve that, but the object stays in
143 // scope, the MacroAssembler is still marked as being in a frame scope, and
144 // the code will be generated again when it goes out of scope.
145 void GenerateLeaveFrame() {
146 DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
147 masm_->LeaveFrame(type_);
151 MacroAssembler* masm_;
152 StackFrame::Type type_;
154 bool old_constant_pool_available_;
156 DISALLOW_IMPLICIT_CONSTRUCTORS(FrameAndConstantPoolScope);
159 // Class for scoping the the unavailability of constant pool access.
160 class ConstantPoolUnavailableScope {
162 explicit ConstantPoolUnavailableScope(MacroAssembler* masm)
164 old_constant_pool_available_(FLAG_enable_embedded_constant_pool &&
165 masm->is_constant_pool_available()) {
166 if (FLAG_enable_embedded_constant_pool) {
167 masm_->set_constant_pool_available(false);
170 ~ConstantPoolUnavailableScope() {
171 if (FLAG_enable_embedded_constant_pool) {
172 masm_->set_constant_pool_available(old_constant_pool_available_);
177 MacroAssembler* masm_;
178 int old_constant_pool_available_;
180 DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolUnavailableScope);
184 class AllowExternalCallThatCantCauseGC: public FrameScope {
186 explicit AllowExternalCallThatCantCauseGC(MacroAssembler* masm)
187 : FrameScope(masm, StackFrame::NONE) { }
191 class NoCurrentFrameScope {
193 explicit NoCurrentFrameScope(MacroAssembler* masm)
194 : masm_(masm), saved_(masm->has_frame()) {
195 masm->set_has_frame(false);
198 ~NoCurrentFrameScope() {
199 masm_->set_has_frame(saved_);
203 MacroAssembler* masm_;
208 // Support for "structured" code comments.
213 Comment(MacroAssembler* masm, const char* msg);
217 MacroAssembler* masm_;
225 Comment(MacroAssembler*, const char*) {}
231 // Wrapper class for passing expected and actual parameter counts as
232 // either registers or immediate values. Used to make sure that the
233 // caller provides exactly the expected number of parameters to the
235 class ParameterCount BASE_EMBEDDED {
237 explicit ParameterCount(Register reg) : reg_(reg), immediate_(0) {}
238 explicit ParameterCount(int imm) : reg_(no_reg), immediate_(imm) {}
240 bool is_reg() const { return !reg_.is(no_reg); }
241 bool is_immediate() const { return !is_reg(); }
243 Register reg() const {
247 int immediate() const {
248 DCHECK(is_immediate());
254 const int immediate_;
256 DISALLOW_IMPLICIT_CONSTRUCTORS(ParameterCount);
260 class AllocationUtils {
262 static ExternalReference GetAllocationTopReference(
263 Isolate* isolate, AllocationFlags flags) {
264 if ((flags & PRETENURE) != 0) {
265 return ExternalReference::old_space_allocation_top_address(isolate);
267 return ExternalReference::new_space_allocation_top_address(isolate);
271 static ExternalReference GetAllocationLimitReference(
272 Isolate* isolate, AllocationFlags flags) {
273 if ((flags & PRETENURE) != 0) {
274 return ExternalReference::old_space_allocation_limit_address(isolate);
276 return ExternalReference::new_space_allocation_limit_address(isolate);
281 } // namespace internal
284 #endif // V8_MACRO_ASSEMBLER_H_