Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceAssembler.h - Integrated assembler --------*- C++ -*-===// | 1 //===- subzero/src/IceAssembler.h - Integrated assembler --------*- C++ -*-===// |
| 2 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
| 4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
| 5 // | 5 // |
| 6 // Modified by the Subzero authors. | 6 // Modified by the Subzero authors. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // The Subzero Code Generator | 10 // The Subzero Code Generator |
| 11 // | 11 // |
| 12 // This file is distributed under the University of Illinois Open Source | 12 // This file is distributed under the University of Illinois Open Source |
| 13 // License. See LICENSE.TXT for details. | 13 // License. See LICENSE.TXT for details. |
| 14 // | 14 // |
| 15 //===----------------------------------------------------------------------===// | 15 //===----------------------------------------------------------------------===// |
| 16 /// | 16 /// |
| 17 /// \file | 17 /// \file |
| 18 /// This file declares the Assembler base class. Instructions are assembled | 18 /// This file declares the Assembler base class. Instructions are assembled |
| 19 /// by architecture-specific assemblers that derive from this base class. | 19 /// by architecture-specific assemblers that derive from this base class. |
| 20 /// This base class manages buffers and fixups for emitting code, etc. | 20 /// This base class manages buffers and fixups for emitting code, etc. |
| 21 /// | 21 /// |
| 22 //===----------------------------------------------------------------------===// | 22 //===----------------------------------------------------------------------===// |
| 23 | 23 |
| 24 #ifndef SUBZERO_SRC_ICEASSEMBLER_H | 24 #ifndef SUBZERO_SRC_ICEASSEMBLER_H |
| 25 #define SUBZERO_SRC_ICEASSEMBLER_H | 25 #define SUBZERO_SRC_ICEASSEMBLER_H |
| 26 | 26 |
| 27 #include "IceDefs.h" | 27 #include "IceDefs.h" |
| 28 #include "IceFixups.h" | 28 #include "IceFixups.h" |
| 29 #include "IceUtils.h" | |
| 29 | 30 |
| 30 namespace Ice { | 31 namespace Ice { |
| 31 | 32 |
| 33 /// A Label can be in one of three states: | |
| 34 /// - Unused. | |
| 35 /// - Linked, unplaced and tracking the position of branches to the label. | |
| 36 /// - Bound, placed and tracking its position. | |
| 37 class Label { | |
| 38 Label(const Label &) = delete; | |
| 39 Label &operator=(const Label &) = delete; | |
| 40 | |
| 41 public: | |
| 42 Label() = default; | |
| 43 ~Label() = default; | |
| 44 | |
| 45 virtual void finalCheck() const { | |
| 46 // Assert if label is being destroyed with unresolved branches pending. | |
| 47 assert(!isLinked()); | |
| 48 } | |
| 49 | |
| 50 // TODO(jvoung): why are labels offset by this? | |
| 51 static const uint32_t kWordSize = sizeof(uint32_t); | |
|
Jim Stichnoth
2015/07/30 15:20:23
Make this private or protected? constexpr?
ascull
2015/07/30 17:29:59
Done.
| |
| 52 | |
| 53 /// Returns the position for bound labels (branches that come after this are | |
| 54 /// considered backward branches). Cannot be used for unused or linked labels. | |
| 55 intptr_t getPosition() const { | |
| 56 assert(isBound()); | |
| 57 return -Position - kWordSize; | |
| 58 } | |
| 59 | |
| 60 /// Returns the position of an earlier branch instruction that was linked to | |
| 61 /// this label (branches that use this are considered forward branches). The | |
| 62 /// linked instructions form a linked list, of sorts, using the instruction's | |
| 63 /// displacement field for the location of the next instruction that is also | |
| 64 /// linked to this label. | |
| 65 intptr_t getLinkPosition() const { | |
| 66 assert(isLinked()); | |
| 67 return Position - kWordSize; | |
| 68 } | |
| 69 | |
| 70 bool isBound() const { return Position < 0; } | |
| 71 bool isLinked() const { return Position > 0; } | |
| 72 virtual bool isUnused() const { return Position == 0; } | |
| 73 | |
| 74 protected: | |
| 75 void bindTo(intptr_t position) { | |
| 76 assert(!isBound()); | |
| 77 Position = -position - kWordSize; | |
| 78 assert(isBound()); | |
| 79 } | |
| 80 | |
| 81 void linkTo(intptr_t position) { | |
| 82 assert(!isBound()); | |
| 83 Position = position + kWordSize; | |
| 84 assert(isLinked()); | |
| 85 } | |
| 86 | |
| 87 intptr_t Position = 0; | |
| 88 }; | |
| 89 | |
| 32 /// Assembler buffers are used to emit binary code. They grow on demand. | 90 /// Assembler buffers are used to emit binary code. They grow on demand. |
| 33 class AssemblerBuffer { | 91 class AssemblerBuffer { |
| 34 AssemblerBuffer(const AssemblerBuffer &) = delete; | 92 AssemblerBuffer(const AssemblerBuffer &) = delete; |
| 35 AssemblerBuffer &operator=(const AssemblerBuffer &) = delete; | 93 AssemblerBuffer &operator=(const AssemblerBuffer &) = delete; |
| 36 | 94 |
| 37 public: | 95 public: |
| 38 AssemblerBuffer(Assembler &); | 96 AssemblerBuffer(Assembler &); |
| 39 ~AssemblerBuffer(); | 97 ~AssemblerBuffer(); |
| 40 | 98 |
| 41 /// Basic support for emitting, loading, and storing. | 99 /// Basic support for emitting, loading, and storing. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 // second buffer should be aligned for NaCl. | 226 // second buffer should be aligned for NaCl. |
| 169 const size_t Alignment = 16; | 227 const size_t Alignment = 16; |
| 170 return reinterpret_cast<uintptr_t>(Allocator.Allocate(bytes, Alignment)); | 228 return reinterpret_cast<uintptr_t>(Allocator.Allocate(bytes, Alignment)); |
| 171 } | 229 } |
| 172 | 230 |
| 173 /// Allocate data of type T using the per-Assembler allocator. | 231 /// Allocate data of type T using the per-Assembler allocator. |
| 174 template <typename T> T *allocate() { return Allocator.Allocate<T>(); } | 232 template <typename T> T *allocate() { return Allocator.Allocate<T>(); } |
| 175 | 233 |
| 176 /// Align the tail end of the function to the required target alignment. | 234 /// Align the tail end of the function to the required target alignment. |
| 177 virtual void alignFunction() = 0; | 235 virtual void alignFunction() = 0; |
| 236 /// Align the tail end of the basic block to the required target alignment. | |
| 237 void alignCfgNode() { | |
| 238 const SizeT Align = 1 << getBundleAlignLog2Bytes(); | |
| 239 padWithNop(Utils::OffsetToAlignment(Buffer.getPosition(), Align)); | |
| 240 } | |
| 178 | 241 |
| 179 /// Add nop padding of a particular width to the current bundle. | 242 /// Add nop padding of a particular width to the current bundle. |
| 180 virtual void padWithNop(intptr_t Padding) = 0; | 243 virtual void padWithNop(intptr_t Padding) = 0; |
| 181 | 244 |
| 182 virtual SizeT getBundleAlignLog2Bytes() const = 0; | 245 virtual SizeT getBundleAlignLog2Bytes() const = 0; |
| 183 | 246 |
| 184 virtual const char *getNonExecPadDirective() const = 0; | 247 virtual const char *getAlignDirective() const = 0; |
| 185 virtual llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const = 0; | 248 virtual llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const = 0; |
| 186 | 249 |
| 250 /// Get the label for a CfgNode. | |
| 251 virtual Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) = 0; | |
| 187 /// Mark the current text location as the start of a CFG node | 252 /// Mark the current text location as the start of a CFG node |
| 188 /// (represented by NodeNumber). | 253 /// (represented by NodeNumber). |
| 189 virtual void bindCfgNodeLabel(SizeT NodeNumber) = 0; | 254 virtual void bindCfgNodeLabel(SizeT NodeNumber) = 0; |
| 190 | 255 |
| 191 virtual bool fixupIsPCRel(FixupKind Kind) const = 0; | 256 virtual bool fixupIsPCRel(FixupKind Kind) const = 0; |
| 192 | 257 |
| 193 // Return a view of all the bytes of code for the current function. | 258 // Return a view of all the bytes of code for the current function. |
| 194 llvm::StringRef getBufferView() const; | 259 llvm::StringRef getBufferView() const; |
| 195 | 260 |
| 196 const FixupRefList &fixups() const { return Buffer.fixups(); } | 261 const FixupRefList &fixups() const { return Buffer.fixups(); } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 protected: | 299 protected: |
| 235 // Buffer's constructor uses the Allocator, so it needs to appear after it. | 300 // Buffer's constructor uses the Allocator, so it needs to appear after it. |
| 236 // TODO(jpp): dependencies on construction order are a nice way of shooting | 301 // TODO(jpp): dependencies on construction order are a nice way of shooting |
| 237 // yourself in the foot. Fix this. | 302 // yourself in the foot. Fix this. |
| 238 AssemblerBuffer Buffer; | 303 AssemblerBuffer Buffer; |
| 239 }; | 304 }; |
| 240 | 305 |
| 241 } // end of namespace Ice | 306 } // end of namespace Ice |
| 242 | 307 |
| 243 #endif // SUBZERO_SRC_ICEASSEMBLER_H_ | 308 #endif // SUBZERO_SRC_ICEASSEMBLER_H_ |
| OLD | NEW |