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

Unified 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, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceUtils.h ('k') | src/assembler.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/assembler.h
diff --git a/src/assembler.h b/src/assembler.h
new file mode 100644
index 0000000000000000000000000000000000000000..92cc98d1f9c5ba9b4bc0d81a7f5918f56b8b694b
--- /dev/null
+++ b/src/assembler.h
@@ -0,0 +1,222 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Modified by the Subzero authors.
+//
+//===- subzero/src/assembler.h - Integrated assembler -----------*- C++ -*-===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Assembler base class. Instructions are assembled
+// by architecture-specific assemblers that derive from this base class.
+// This base class manages buffers and fixups for emitting code, etc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ASSEMBLER_H
+#define SUBZERO_SRC_ASSEMBLER_H
+
+#include "IceDefs.h"
+
+#include "IceFixups.h"
+#include "llvm/Support/Allocator.h"
+
+namespace Ice {
+
+// Forward declarations.
+class Assembler;
+class AssemblerFixup;
+class AssemblerBuffer;
+class ConstantRelocatable;
+class MemoryRegion;
+
+// Assembler fixups are positions in generated code that hold relocation
+// information that needs to be processed before finalizing the code
+// into executable memory.
+class AssemblerFixup {
+public:
+ virtual void Process(const MemoryRegion &region, intptr_t position) = 0;
+
+ // It would be ideal if the destructor method could be made private,
+ // but the g++ compiler complains when this is subclassed.
+ virtual ~AssemblerFixup() { llvm_unreachable("~AssemblerFixup used"); }
+
+ intptr_t position() const { return position_; }
+
+ FixupKind kind() const { return kind_; }
+
+ const ConstantRelocatable *value() const { return value_; }
+
+protected:
+ AssemblerFixup(FixupKind Kind, const ConstantRelocatable *Value)
+ : position_(0), kind_(Kind), value_(Value) {}
+
+private:
+ intptr_t position_;
+ FixupKind kind_;
+ const ConstantRelocatable *value_;
+
+ void set_position(intptr_t position) { position_ = position; }
+
+ AssemblerFixup(const AssemblerFixup &) LLVM_DELETED_FUNCTION;
+ AssemblerFixup &operator=(const AssemblerFixup &) LLVM_DELETED_FUNCTION;
+ friend class AssemblerBuffer;
+};
+
+// Assembler buffers are used to emit binary code. They grow on demand.
+class AssemblerBuffer {
+public:
+ AssemblerBuffer(Assembler &);
+ ~AssemblerBuffer();
+
+ // Basic support for emitting, loading, and storing.
+ template <typename T> void Emit(T value) {
+ assert(HasEnsuredCapacity());
+ *reinterpret_cast<T *>(cursor_) = value;
+ cursor_ += sizeof(T);
+ }
+
+ template <typename T> T Load(intptr_t position) const {
+ assert(position >= 0 &&
+ position <= (Size() - static_cast<intptr_t>(sizeof(T))));
+ return *reinterpret_cast<T *>(contents_ + position);
+ }
+
+ template <typename T> void Store(intptr_t position, T value) {
+ assert(position >= 0 &&
+ position <= (Size() - static_cast<intptr_t>(sizeof(T))));
+ *reinterpret_cast<T *>(contents_ + position) = value;
+ }
+
+ // Emit a fixup at the current location.
+ void EmitFixup(AssemblerFixup *fixup) {
+ fixup->set_position(Size());
+ fixups_.push_back(fixup);
+ }
+
+ // Get the size of the emitted code.
+ intptr_t Size() const { return cursor_ - contents_; }
+ uintptr_t contents() const { return contents_; }
+
+ // Copy the assembled instructions into the specified memory block
+ // and apply all fixups.
+ // TODO(jvoung): This will be different. We'll be writing the text
+ // and reloc section to a file?
+ void FinalizeInstructions(const MemoryRegion &region);
+
+// To emit an instruction to the assembler buffer, the EnsureCapacity helper
+// must be used to guarantee that the underlying data area is big enough to
+// hold the emitted instruction. Usage:
+//
+// AssemblerBuffer buffer;
+// AssemblerBuffer::EnsureCapacity ensured(&buffer);
+// ... emit bytes for single instruction ...
+
+#if defined(DEBUG)
+ class EnsureCapacity {
+ public:
+ explicit EnsureCapacity(AssemblerBuffer *buffer);
+ ~EnsureCapacity();
+
+ private:
+ AssemblerBuffer *buffer_;
+ intptr_t gap_;
+
+ intptr_t ComputeGap() { return buffer_->Capacity() - buffer_->Size(); }
+ };
+
+ bool has_ensured_capacity_;
+ bool HasEnsuredCapacity() const { return has_ensured_capacity_; }
+#else
+ class EnsureCapacity {
+ public:
+ explicit EnsureCapacity(AssemblerBuffer *buffer) {
+ if (buffer->cursor() >= buffer->limit())
+ buffer->ExtendCapacity();
+ }
+ };
+
+ // When building the C++ tests, assertion code is enabled. To allow
+ // asserting that the user of the assembler buffer has ensured the
+ // capacity needed for emitting, we add a dummy method in non-debug mode.
+ bool HasEnsuredCapacity() const { return true; }
+#endif
+
+ // Returns the position in the instruction stream.
+ intptr_t GetPosition() const { return cursor_ - contents_; }
+
+ // For bringup only.
+ AssemblerFixup *GetLatestFixup() const;
+
+private:
+ // The limit is set to kMinimumGap bytes before the end of the data area.
+ // This leaves enough space for the longest possible instruction and allows
+ // for a single, fast space check per instruction.
+ static const intptr_t kMinimumGap = 32;
+
+ uintptr_t contents_;
+ uintptr_t cursor_;
+ uintptr_t limit_;
+ Assembler &assembler_;
+ std::vector<AssemblerFixup *> fixups_;
+#if defined(DEBUG)
+ bool fixups_processed_;
+#endif
+
+ uintptr_t cursor() const { return cursor_; }
+ uintptr_t limit() const { return limit_; }
+ intptr_t Capacity() const {
+ assert(limit_ >= contents_);
+ return (limit_ - contents_) + kMinimumGap;
+ }
+
+ // Process the fixup chain.
+ void ProcessFixups(const MemoryRegion &region);
+
+ // Compute the limit based on the data area and the capacity. See
+ // description of kMinimumGap for the reasoning behind the value.
+ static uintptr_t ComputeLimit(uintptr_t data, intptr_t capacity) {
+ return data + capacity - kMinimumGap;
+ }
+
+ void ExtendCapacity();
+
+ friend class AssemblerFixup;
+};
+
+class Assembler {
+public:
+ Assembler() {}
+ ~Assembler() {}
+
+ // Allocate a chunk of bytes using the per-Assembler allocator.
+ uintptr_t AllocateBytes(size_t bytes) {
+ // For now, alignment is not related to NaCl bundle alignment, since
+ // the buffer's GetPosition is relative to the base. So NaCl bundle
+ // alignment checks can be relative to that base. Later, the buffer
+ // will be copied out to a ".text" section (or an in memory-buffer
+ // that can be mprotect'ed with executable permission), and that
+ // second buffer should be aligned for NaCl.
+ const size_t Alignment = 16;
+ return reinterpret_cast<uintptr_t>(Allocator.Allocate(bytes, Alignment));
+ }
+
+ // Allocate data of type T using the per-Assembler allocator.
+ template <typename T> T *Allocate() { return Allocator.Allocate<T>(); }
+
+private:
+ llvm::BumpPtrAllocator Allocator;
+
+ Assembler(const Assembler &) LLVM_DELETED_FUNCTION;
+ Assembler &operator=(const Assembler &) LLVM_DELETED_FUNCTION;
+};
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ASSEMBLER_H_
« 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