OLD | NEW |
1 //===- subzero/src/assembler.cpp - Assembler base class -------------------===// | 1 //===- subzero/src/assembler.cpp - Assembler base class -------------------===// |
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 // This file implements the Assembler class. | 17 // This file implements the Assembler class. |
18 // | 18 // |
19 //===----------------------------------------------------------------------===// | 19 //===----------------------------------------------------------------------===// |
20 | 20 |
21 #include "assembler.h" | 21 #include "assembler.h" |
22 #include "IceGlobalContext.h" | 22 #include "IceGlobalContext.h" |
23 #include "IceMemoryRegion.h" | |
24 #include "IceOperand.h" | 23 #include "IceOperand.h" |
25 | 24 |
26 namespace Ice { | 25 namespace Ice { |
27 | 26 |
28 static uintptr_t NewContents(Assembler &assembler, intptr_t capacity) { | 27 static uintptr_t NewContents(Assembler &assembler, intptr_t capacity) { |
29 uintptr_t result = assembler.AllocateBytes(capacity); | 28 uintptr_t result = assembler.AllocateBytes(capacity); |
30 return result; | 29 return result; |
31 } | 30 } |
32 | 31 |
33 #ifndef NDEBUG | 32 #ifndef NDEBUG |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 fixups_processed_ = false; | 68 fixups_processed_ = false; |
70 #endif // !NDEBUG | 69 #endif // !NDEBUG |
71 | 70 |
72 // Verify internal state. | 71 // Verify internal state. |
73 assert(Capacity() == kInitialBufferCapacity); | 72 assert(Capacity() == kInitialBufferCapacity); |
74 assert(Size() == 0); | 73 assert(Size() == 0); |
75 } | 74 } |
76 | 75 |
77 AssemblerBuffer::~AssemblerBuffer() {} | 76 AssemblerBuffer::~AssemblerBuffer() {} |
78 | 77 |
79 void AssemblerBuffer::ProcessFixups(const MemoryRegion ®ion) { | |
80 for (SizeT I = 0; I < fixups_.size(); ++I) { | |
81 AssemblerFixup *fixup = fixups_[I]; | |
82 fixup->Process(region, fixup->position()); | |
83 } | |
84 } | |
85 | |
86 void AssemblerBuffer::FinalizeInstructions(const MemoryRegion &instructions) { | |
87 // Copy the instructions from the buffer. | |
88 MemoryRegion from(reinterpret_cast<void *>(contents()), Size()); | |
89 instructions.CopyFrom(0, from); | |
90 | |
91 // Process fixups in the instructions. | |
92 ProcessFixups(instructions); | |
93 #ifndef NDEBUG | |
94 fixups_processed_ = true; | |
95 #endif // !NDEBUG | |
96 } | |
97 | |
98 void AssemblerBuffer::ExtendCapacity() { | 78 void AssemblerBuffer::ExtendCapacity() { |
99 intptr_t old_size = Size(); | 79 intptr_t old_size = Size(); |
100 intptr_t old_capacity = Capacity(); | 80 intptr_t old_capacity = Capacity(); |
101 const intptr_t OneMB = 1 << 20; | 81 const intptr_t OneMB = 1 << 20; |
102 intptr_t new_capacity = std::min(old_capacity * 2, old_capacity + OneMB); | 82 intptr_t new_capacity = std::min(old_capacity * 2, old_capacity + OneMB); |
103 if (new_capacity < old_capacity) { | 83 if (new_capacity < old_capacity) { |
104 // FATAL | 84 // FATAL |
105 llvm_unreachable("Unexpected overflow in AssemblerBuffer::ExtendCapacity"); | 85 llvm_unreachable("Unexpected overflow in AssemblerBuffer::ExtendCapacity"); |
106 } | 86 } |
107 | 87 |
108 // Allocate the new data area and copy contents of the old one to it. | 88 // Allocate the new data area and copy contents of the old one to it. |
109 uintptr_t new_contents = NewContents(assembler_, new_capacity); | 89 uintptr_t new_contents = NewContents(assembler_, new_capacity); |
110 memmove(reinterpret_cast<void *>(new_contents), | 90 memmove(reinterpret_cast<void *>(new_contents), |
111 reinterpret_cast<void *>(contents_), old_size); | 91 reinterpret_cast<void *>(contents_), old_size); |
112 | 92 |
113 // Compute the relocation delta and switch to the new contents area. | 93 // Compute the relocation delta and switch to the new contents area. |
114 intptr_t delta = new_contents - contents_; | 94 intptr_t delta = new_contents - contents_; |
115 contents_ = new_contents; | 95 contents_ = new_contents; |
116 | 96 |
117 // Update the cursor and recompute the limit. | 97 // Update the cursor and recompute the limit. |
118 cursor_ += delta; | 98 cursor_ += delta; |
119 limit_ = ComputeLimit(new_contents, new_capacity); | 99 limit_ = ComputeLimit(new_contents, new_capacity); |
120 | 100 |
121 // Verify internal state. | 101 // Verify internal state. |
122 assert(Capacity() == new_capacity); | 102 assert(Capacity() == new_capacity); |
123 assert(Size() == old_size); | 103 assert(Size() == old_size); |
124 } | 104 } |
125 | 105 |
| 106 llvm::StringRef Assembler::getBufferView() const { |
| 107 return llvm::StringRef(reinterpret_cast<const char *>(buffer_.contents()), |
| 108 buffer_.Size()); |
| 109 } |
| 110 |
126 void Assembler::emitIASBytes(GlobalContext *Ctx) const { | 111 void Assembler::emitIASBytes(GlobalContext *Ctx) const { |
127 Ostream &Str = Ctx->getStrEmit(); | 112 Ostream &Str = Ctx->getStrEmit(); |
128 intptr_t EndPosition = buffer_.Size(); | 113 intptr_t EndPosition = buffer_.Size(); |
129 intptr_t CurPosition = 0; | 114 intptr_t CurPosition = 0; |
130 const intptr_t FixupSize = 4; | 115 const intptr_t FixupSize = 4; |
131 for (AssemblerBuffer::FixupList::const_iterator | 116 for (AssemblerBuffer::FixupList::const_iterator |
132 FixupI = buffer_.fixups_begin(), | 117 FixupI = buffer_.fixups_begin(), |
133 FixupE = buffer_.fixups_end(); FixupI != FixupE; ++FixupI) { | 118 FixupE = buffer_.fixups_end(); FixupI != FixupE; ++FixupI) { |
134 AssemblerFixup *NextFixup = *FixupI; | 119 AssemblerFixup *NextFixup = *FixupI; |
135 intptr_t NextFixupLoc = NextFixup->position(); | 120 intptr_t NextFixupLoc = NextFixup->position(); |
(...skipping 20 matching lines...) Expand all Loading... |
156 } | 141 } |
157 // Handle any bytes that are not prefixed by a fixup. | 142 // Handle any bytes that are not prefixed by a fixup. |
158 for (intptr_t i = CurPosition; i < EndPosition; ++i) { | 143 for (intptr_t i = CurPosition; i < EndPosition; ++i) { |
159 Str << "\t.byte 0x"; | 144 Str << "\t.byte 0x"; |
160 Str.write_hex(buffer_.Load<uint8_t>(i)); | 145 Str.write_hex(buffer_.Load<uint8_t>(i)); |
161 Str << "\n"; | 146 Str << "\n"; |
162 } | 147 } |
163 } | 148 } |
164 | 149 |
165 } // end of namespace Ice | 150 } // end of namespace Ice |
OLD | NEW |