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