1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "LLVMRoutineManager.hpp" 16 17 #include "LLVMRoutine.hpp" 18 #include "llvm/Function.h" 19 #include "../Common/Memory.hpp" 20 #include "../Common/Thread.hpp" 21 #include "../Common/Debug.hpp" 22 23 namespace sw 24 { 25 using namespace llvm; 26 27 volatile int LLVMRoutineManager::averageInstructionSize = 4; 28 LLVMRoutineManager()29 LLVMRoutineManager::LLVMRoutineManager() 30 { 31 routine = nullptr; 32 } 33 ~LLVMRoutineManager()34 LLVMRoutineManager::~LLVMRoutineManager() 35 { 36 delete routine; 37 } 38 AllocateGOT()39 void LLVMRoutineManager::AllocateGOT() 40 { 41 UNIMPLEMENTED(); 42 } 43 allocateStub(const GlobalValue * function,unsigned stubSize,unsigned alignment)44 uint8_t *LLVMRoutineManager::allocateStub(const GlobalValue *function, unsigned stubSize, unsigned alignment) 45 { 46 UNIMPLEMENTED(); 47 return nullptr; 48 } 49 startFunctionBody(const llvm::Function * function,uintptr_t & actualSize)50 uint8_t *LLVMRoutineManager::startFunctionBody(const llvm::Function *function, uintptr_t &actualSize) 51 { 52 if(actualSize == 0) // Estimate size 53 { 54 size_t instructionCount = 0; 55 for(llvm::Function::const_iterator basicBlock = function->begin(); basicBlock != function->end(); basicBlock++) 56 { 57 instructionCount += basicBlock->size(); 58 } 59 60 actualSize = instructionCount * averageInstructionSize; 61 } 62 else // Estimate was too low 63 { 64 sw::atomicIncrement(&averageInstructionSize); 65 } 66 67 // Round up to the next page size 68 size_t pageSize = memoryPageSize(); 69 actualSize = (actualSize + pageSize - 1) & ~(pageSize - 1); 70 71 delete routine; 72 routine = new LLVMRoutine(static_cast<int>(actualSize)); 73 74 return (uint8_t*)routine->buffer; 75 } 76 endFunctionBody(const llvm::Function * function,uint8_t * functionStart,uint8_t * functionEnd)77 void LLVMRoutineManager::endFunctionBody(const llvm::Function *function, uint8_t *functionStart, uint8_t *functionEnd) 78 { 79 routine->functionSize = static_cast<int>(static_cast<ptrdiff_t>(functionEnd - functionStart)); 80 } 81 startExceptionTable(const llvm::Function * F,uintptr_t & ActualSize)82 uint8_t *LLVMRoutineManager::startExceptionTable(const llvm::Function* F, uintptr_t &ActualSize) 83 { 84 UNIMPLEMENTED(); 85 return nullptr; 86 } 87 endExceptionTable(const llvm::Function * F,uint8_t * TableStart,uint8_t * TableEnd,uint8_t * FrameRegister)88 void LLVMRoutineManager::endExceptionTable(const llvm::Function *F, uint8_t *TableStart, uint8_t *TableEnd, uint8_t* FrameRegister) 89 { 90 UNIMPLEMENTED(); 91 } 92 getGOTBase() const93 uint8_t *LLVMRoutineManager::getGOTBase() const 94 { 95 ASSERT(!HasGOT); 96 return nullptr; 97 } 98 allocateSpace(intptr_t Size,unsigned Alignment)99 uint8_t *LLVMRoutineManager::allocateSpace(intptr_t Size, unsigned Alignment) 100 { 101 UNIMPLEMENTED(); 102 return nullptr; 103 } 104 allocateGlobal(uintptr_t Size,unsigned Alignment)105 uint8_t *LLVMRoutineManager::allocateGlobal(uintptr_t Size, unsigned Alignment) 106 { 107 UNIMPLEMENTED(); 108 return nullptr; 109 } 110 deallocateFunctionBody(void * Body)111 void LLVMRoutineManager::deallocateFunctionBody(void *Body) 112 { 113 delete routine; 114 routine = nullptr; 115 } 116 deallocateExceptionTable(void * ET)117 void LLVMRoutineManager::deallocateExceptionTable(void *ET) 118 { 119 if(ET) 120 { 121 UNIMPLEMENTED(); 122 } 123 } 124 setMemoryWritable()125 void LLVMRoutineManager::setMemoryWritable() 126 { 127 } 128 setMemoryExecutable()129 void LLVMRoutineManager::setMemoryExecutable() 130 { 131 markExecutable(routine->buffer, routine->bufferSize); 132 } 133 setPoisonMemory(bool poison)134 void LLVMRoutineManager::setPoisonMemory(bool poison) 135 { 136 UNIMPLEMENTED(); 137 } 138 acquireRoutine(void * entry)139 LLVMRoutine *LLVMRoutineManager::acquireRoutine(void *entry) 140 { 141 routine->entry = entry; 142 143 LLVMRoutine *result = routine; 144 routine = nullptr; 145 146 return result; 147 } 148 } 149