Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/assembler.h

Issue 574133002: Add initial integrated assembler w/ some Xmm ops. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: remove duplicate pxor, and use enum Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceUtils.h ('k') | src/assembler.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, 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 // Modified by the Subzero authors.
6 //
7 //===- subzero/src/assembler.h - Integrated assembler -----------*- C++ -*-===//
8 //
9 // The Subzero Code Generator
10 //
11 // This file is distributed under the University of Illinois Open Source
12 // License. See LICENSE.TXT for details.
13 //
14 //===----------------------------------------------------------------------===//
15 //
16 // This file declares the Assembler base class. Instructions are assembled
17 // by architecture-specific assemblers that derive from this base class.
18 // This base class manages buffers and fixups for emitting code, etc.
19 //
20 //===----------------------------------------------------------------------===//
21
22 #ifndef SUBZERO_SRC_ASSEMBLER_H
23 #define SUBZERO_SRC_ASSEMBLER_H
24
25 #include "IceDefs.h"
26
27 #include "IceFixups.h"
28 #include "llvm/Support/Allocator.h"
29
30 namespace Ice {
31
32 // Forward declarations.
33 class Assembler;
34 class AssemblerFixup;
35 class AssemblerBuffer;
36 class ConstantRelocatable;
37 class MemoryRegion;
38
39 // Assembler fixups are positions in generated code that hold relocation
40 // information that needs to be processed before finalizing the code
41 // into executable memory.
42 class AssemblerFixup {
43 public:
44 virtual void Process(const MemoryRegion &region, intptr_t position) = 0;
45
46 // It would be ideal if the destructor method could be made private,
47 // but the g++ compiler complains when this is subclassed.
48 virtual ~AssemblerFixup() { llvm_unreachable("~AssemblerFixup used"); }
49
50 intptr_t position() const { return position_; }
51
52 FixupKind kind() const { return kind_; }
53
54 const ConstantRelocatable *value() const { return value_; }
55
56 protected:
57 AssemblerFixup(FixupKind Kind, const ConstantRelocatable *Value)
58 : position_(0), kind_(Kind), value_(Value) {}
59
60 private:
61 intptr_t position_;
62 FixupKind kind_;
63 const ConstantRelocatable *value_;
64
65 void set_position(intptr_t position) { position_ = position; }
66
67 AssemblerFixup(const AssemblerFixup &) LLVM_DELETED_FUNCTION;
68 AssemblerFixup &operator=(const AssemblerFixup &) LLVM_DELETED_FUNCTION;
69 friend class AssemblerBuffer;
70 };
71
72 // Assembler buffers are used to emit binary code. They grow on demand.
73 class AssemblerBuffer {
74 public:
75 AssemblerBuffer(Assembler &);
76 ~AssemblerBuffer();
77
78 // Basic support for emitting, loading, and storing.
79 template <typename T> void Emit(T value) {
80 assert(HasEnsuredCapacity());
81 *reinterpret_cast<T *>(cursor_) = value;
82 cursor_ += sizeof(T);
83 }
84
85 template <typename T> T Load(intptr_t position) const {
86 assert(position >= 0 &&
87 position <= (Size() - static_cast<intptr_t>(sizeof(T))));
88 return *reinterpret_cast<T *>(contents_ + position);
89 }
90
91 template <typename T> void Store(intptr_t position, T value) {
92 assert(position >= 0 &&
93 position <= (Size() - static_cast<intptr_t>(sizeof(T))));
94 *reinterpret_cast<T *>(contents_ + position) = value;
95 }
96
97 // Emit a fixup at the current location.
98 void EmitFixup(AssemblerFixup *fixup) {
99 fixup->set_position(Size());
100 fixups_.push_back(fixup);
101 }
102
103 // Get the size of the emitted code.
104 intptr_t Size() const { return cursor_ - contents_; }
105 uintptr_t contents() const { return contents_; }
106
107 // Copy the assembled instructions into the specified memory block
108 // and apply all fixups.
109 // TODO(jvoung): This will be different. We'll be writing the text
110 // and reloc section to a file?
111 void FinalizeInstructions(const MemoryRegion &region);
112
113 // To emit an instruction to the assembler buffer, the EnsureCapacity helper
114 // must be used to guarantee that the underlying data area is big enough to
115 // hold the emitted instruction. Usage:
116 //
117 // AssemblerBuffer buffer;
118 // AssemblerBuffer::EnsureCapacity ensured(&buffer);
119 // ... emit bytes for single instruction ...
120
121 #if defined(DEBUG)
122 class EnsureCapacity {
123 public:
124 explicit EnsureCapacity(AssemblerBuffer *buffer);
125 ~EnsureCapacity();
126
127 private:
128 AssemblerBuffer *buffer_;
129 intptr_t gap_;
130
131 intptr_t ComputeGap() { return buffer_->Capacity() - buffer_->Size(); }
132 };
133
134 bool has_ensured_capacity_;
135 bool HasEnsuredCapacity() const { return has_ensured_capacity_; }
136 #else
137 class EnsureCapacity {
138 public:
139 explicit EnsureCapacity(AssemblerBuffer *buffer) {
140 if (buffer->cursor() >= buffer->limit())
141 buffer->ExtendCapacity();
142 }
143 };
144
145 // When building the C++ tests, assertion code is enabled. To allow
146 // asserting that the user of the assembler buffer has ensured the
147 // capacity needed for emitting, we add a dummy method in non-debug mode.
148 bool HasEnsuredCapacity() const { return true; }
149 #endif
150
151 // Returns the position in the instruction stream.
152 intptr_t GetPosition() const { return cursor_ - contents_; }
153
154 // For bringup only.
155 AssemblerFixup *GetLatestFixup() const;
156
157 private:
158 // The limit is set to kMinimumGap bytes before the end of the data area.
159 // This leaves enough space for the longest possible instruction and allows
160 // for a single, fast space check per instruction.
161 static const intptr_t kMinimumGap = 32;
162
163 uintptr_t contents_;
164 uintptr_t cursor_;
165 uintptr_t limit_;
166 Assembler &assembler_;
167 std::vector<AssemblerFixup *> fixups_;
168 #if defined(DEBUG)
169 bool fixups_processed_;
170 #endif
171
172 uintptr_t cursor() const { return cursor_; }
173 uintptr_t limit() const { return limit_; }
174 intptr_t Capacity() const {
175 assert(limit_ >= contents_);
176 return (limit_ - contents_) + kMinimumGap;
177 }
178
179 // Process the fixup chain.
180 void ProcessFixups(const MemoryRegion &region);
181
182 // Compute the limit based on the data area and the capacity. See
183 // description of kMinimumGap for the reasoning behind the value.
184 static uintptr_t ComputeLimit(uintptr_t data, intptr_t capacity) {
185 return data + capacity - kMinimumGap;
186 }
187
188 void ExtendCapacity();
189
190 friend class AssemblerFixup;
191 };
192
193 class Assembler {
194 public:
195 Assembler() {}
196 ~Assembler() {}
197
198 // Allocate a chunk of bytes using the per-Assembler allocator.
199 uintptr_t AllocateBytes(size_t bytes) {
200 // For now, alignment is not related to NaCl bundle alignment, since
201 // the buffer's GetPosition is relative to the base. So NaCl bundle
202 // alignment checks can be relative to that base. Later, the buffer
203 // will be copied out to a ".text" section (or an in memory-buffer
204 // that can be mprotect'ed with executable permission), and that
205 // second buffer should be aligned for NaCl.
206 const size_t Alignment = 16;
207 return reinterpret_cast<uintptr_t>(Allocator.Allocate(bytes, Alignment));
208 }
209
210 // Allocate data of type T using the per-Assembler allocator.
211 template <typename T> T *Allocate() { return Allocator.Allocate<T>(); }
212
213 private:
214 llvm::BumpPtrAllocator Allocator;
215
216 Assembler(const Assembler &) LLVM_DELETED_FUNCTION;
217 Assembler &operator=(const Assembler &) LLVM_DELETED_FUNCTION;
218 };
219
220 } // end of namespace Ice
221
222 #endif // SUBZERO_SRC_ASSEMBLER_H_
OLDNEW
« no previous file with comments | « src/IceUtils.h ('k') | src/assembler.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698