assembler.cc revision dd7624d2b9e599d57762d12031b10b89defc9807
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "assembler.h"
18
19#include <algorithm>
20#include <vector>
21
22#include "arm/assembler_arm.h"
23#include "arm64/assembler_arm64.h"
24#include "mips/assembler_mips.h"
25#include "x86/assembler_x86.h"
26#include "x86_64/assembler_x86_64.h"
27#include "globals.h"
28#include "memory_region.h"
29
30namespace art {
31
32static byte* NewContents(size_t capacity) {
33  return new byte[capacity];
34}
35
36
37AssemblerBuffer::AssemblerBuffer() {
38  static const size_t kInitialBufferCapacity = 4 * KB;
39  contents_ = NewContents(kInitialBufferCapacity);
40  cursor_ = contents_;
41  limit_ = ComputeLimit(contents_, kInitialBufferCapacity);
42  fixup_ = NULL;
43  slow_path_ = NULL;
44#ifndef NDEBUG
45  has_ensured_capacity_ = false;
46  fixups_processed_ = false;
47#endif
48
49  // Verify internal state.
50  CHECK_EQ(Capacity(), kInitialBufferCapacity);
51  CHECK_EQ(Size(), 0U);
52}
53
54
55AssemblerBuffer::~AssemblerBuffer() {
56  delete[] contents_;
57}
58
59
60void AssemblerBuffer::ProcessFixups(const MemoryRegion& region) {
61  AssemblerFixup* fixup = fixup_;
62  while (fixup != NULL) {
63    fixup->Process(region, fixup->position());
64    fixup = fixup->previous();
65  }
66}
67
68
69void AssemblerBuffer::FinalizeInstructions(const MemoryRegion& instructions) {
70  // Copy the instructions from the buffer.
71  MemoryRegion from(reinterpret_cast<void*>(contents()), Size());
72  instructions.CopyFrom(0, from);
73  // Process fixups in the instructions.
74  ProcessFixups(instructions);
75#ifndef NDEBUG
76  fixups_processed_ = true;
77#endif
78}
79
80
81void AssemblerBuffer::ExtendCapacity() {
82  size_t old_size = Size();
83  size_t old_capacity = Capacity();
84  size_t new_capacity = std::min(old_capacity * 2, old_capacity + 1 * MB);
85
86  // Allocate the new data area and copy contents of the old one to it.
87  byte* new_contents = NewContents(new_capacity);
88  memmove(reinterpret_cast<void*>(new_contents),
89          reinterpret_cast<void*>(contents_),
90          old_size);
91
92  // Compute the relocation delta and switch to the new contents area.
93  ptrdiff_t delta = new_contents - contents_;
94  contents_ = new_contents;
95
96  // Update the cursor and recompute the limit.
97  cursor_ += delta;
98  limit_ = ComputeLimit(new_contents, new_capacity);
99
100  // Verify internal state.
101  CHECK_EQ(Capacity(), new_capacity);
102  CHECK_EQ(Size(), old_size);
103}
104
105
106Assembler* Assembler::Create(InstructionSet instruction_set) {
107  switch (instruction_set) {
108    case kArm:
109    case kThumb2:
110      return new arm::ArmAssembler();
111    case kArm64:
112      return new arm64::Arm64Assembler();
113    case kMips:
114      return new mips::MipsAssembler();
115    case kX86:
116      return new x86::X86Assembler();
117    case kX86_64:
118      return new x86_64::X86_64Assembler();
119    default:
120      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
121      return NULL;
122  }
123}
124
125void Assembler::StoreImmediateToThread32(ThreadOffset<4> dest, uint32_t imm,
126                                         ManagedRegister scratch) {
127  UNIMPLEMENTED(FATAL);
128}
129
130void Assembler::StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm,
131                                         ManagedRegister scratch) {
132  UNIMPLEMENTED(FATAL);
133}
134
135void Assembler::StoreStackOffsetToThread32(ThreadOffset<4> thr_offs,
136                                           FrameOffset fr_offs,
137                                           ManagedRegister scratch) {
138  UNIMPLEMENTED(FATAL);
139}
140
141void Assembler::StoreStackOffsetToThread64(ThreadOffset<8> thr_offs,
142                                           FrameOffset fr_offs,
143                                           ManagedRegister scratch) {
144  UNIMPLEMENTED(FATAL);
145}
146
147void Assembler::StoreStackPointerToThread32(ThreadOffset<4> thr_offs) {
148  UNIMPLEMENTED(FATAL);
149}
150
151void Assembler::StoreStackPointerToThread64(ThreadOffset<8> thr_offs) {
152  UNIMPLEMENTED(FATAL);
153}
154
155void Assembler::LoadFromThread32(ManagedRegister dest, ThreadOffset<4> src, size_t size) {
156  UNIMPLEMENTED(FATAL);
157}
158
159void Assembler::LoadFromThread64(ManagedRegister dest, ThreadOffset<8> src, size_t size) {
160  UNIMPLEMENTED(FATAL);
161}
162
163void Assembler::LoadRawPtrFromThread32(ManagedRegister dest, ThreadOffset<4> offs) {
164  UNIMPLEMENTED(FATAL);
165}
166
167void Assembler::LoadRawPtrFromThread64(ManagedRegister dest, ThreadOffset<8> offs) {
168  UNIMPLEMENTED(FATAL);
169}
170
171void Assembler::CopyRawPtrFromThread32(FrameOffset fr_offs, ThreadOffset<4> thr_offs,
172                                       ManagedRegister scratch) {
173  UNIMPLEMENTED(FATAL);
174}
175
176void Assembler::CopyRawPtrFromThread64(FrameOffset fr_offs, ThreadOffset<8> thr_offs,
177                                       ManagedRegister scratch) {
178  UNIMPLEMENTED(FATAL);
179}
180
181void Assembler::CopyRawPtrToThread32(ThreadOffset<4> thr_offs, FrameOffset fr_offs,
182                                     ManagedRegister scratch) {
183  UNIMPLEMENTED(FATAL);
184}
185
186void Assembler::CopyRawPtrToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs,
187                                     ManagedRegister scratch) {
188  UNIMPLEMENTED(FATAL);
189}
190
191void Assembler::CallFromThread32(ThreadOffset<4> offset, ManagedRegister scratch) {
192  UNIMPLEMENTED(FATAL);
193}
194
195void Assembler::CallFromThread64(ThreadOffset<8> offset, ManagedRegister scratch) {
196  UNIMPLEMENTED(FATAL);
197}
198
199}  // namespace art
200