// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "LLVMRoutineManager.hpp"

#if SWIFTSHADER_LLVM_VERSION < 7

#include "LLVMRoutine.hpp"
#include "llvm/Function.h"
#include "../Common/Memory.hpp"
#include "../Common/Thread.hpp"
#include "../Common/Debug.hpp"

namespace sw
{
	using namespace llvm;

	volatile int LLVMRoutineManager::averageInstructionSize = 4;

	LLVMRoutineManager::LLVMRoutineManager()
	{
		routine = nullptr;
	}

	LLVMRoutineManager::~LLVMRoutineManager()
	{
		delete routine;
	}

	void LLVMRoutineManager::AllocateGOT()
	{
		UNIMPLEMENTED();
	}

	uint8_t *LLVMRoutineManager::allocateStub(const GlobalValue *function, unsigned stubSize, unsigned alignment)
	{
		UNIMPLEMENTED();
		return nullptr;
	}

	uint8_t *LLVMRoutineManager::startFunctionBody(const llvm::Function *function, uintptr_t &actualSize)
	{
		if(actualSize == 0)   // Estimate size
		{
			size_t instructionCount = 0;
			for(llvm::Function::const_iterator basicBlock = function->begin(); basicBlock != function->end(); basicBlock++)
			{
				instructionCount += basicBlock->size();
			}

			actualSize = instructionCount * averageInstructionSize;
		}
		else   // Estimate was too low
		{
			sw::atomicIncrement(&averageInstructionSize);
		}

		// Round up to the next page size
		size_t pageSize = memoryPageSize();
		actualSize = (actualSize + pageSize - 1) & ~(pageSize - 1);

		delete routine;
		routine = new LLVMRoutine(static_cast<int>(actualSize));

		return (uint8_t*)routine->buffer;
	}

	void LLVMRoutineManager::endFunctionBody(const llvm::Function *function, uint8_t *functionStart, uint8_t *functionEnd)
	{
		routine->functionSize = static_cast<int>(static_cast<ptrdiff_t>(functionEnd - functionStart));
	}

	uint8_t *LLVMRoutineManager::startExceptionTable(const llvm::Function* F, uintptr_t &ActualSize)
	{
		UNIMPLEMENTED();
		return nullptr;
	}

	void LLVMRoutineManager::endExceptionTable(const llvm::Function *F, uint8_t *TableStart, uint8_t *TableEnd, uint8_t* FrameRegister)
	{
		UNIMPLEMENTED();
	}

	uint8_t *LLVMRoutineManager::getGOTBase() const
	{
		ASSERT(!HasGOT);
		return nullptr;
	}

	uint8_t *LLVMRoutineManager::allocateSpace(intptr_t Size, unsigned Alignment)
	{
		UNIMPLEMENTED();
		return nullptr;
	}

	uint8_t *LLVMRoutineManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
	{
		UNIMPLEMENTED();
		return nullptr;
	}

	void LLVMRoutineManager::deallocateFunctionBody(void *Body)
	{
		delete routine;
		routine = nullptr;
	}

	void LLVMRoutineManager::deallocateExceptionTable(void *ET)
	{
		if(ET)
		{
			UNIMPLEMENTED();
		}
	}

	void LLVMRoutineManager::setMemoryWritable()
	{
	}

	void LLVMRoutineManager::setMemoryExecutable()
	{
		markExecutable(routine->buffer, routine->bufferSize);
	}

	void LLVMRoutineManager::setPoisonMemory(bool poison)
	{
		UNIMPLEMENTED();
	}

	LLVMRoutine *LLVMRoutineManager::acquireRoutine(void *entry)
	{
		routine->entry = entry;

		LLVMRoutine *result = routine;
		routine = nullptr;

		return result;
	}
}

#endif  // SWIFTSHADER_LLVM_VERSION < 7
