// Copyright 2020 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 "LLVMAsm.hpp"

#ifdef ENABLE_RR_EMIT_ASM_FILE

#	include "Debug.hpp"
#	include "llvm/IR/LegacyPassManager.h"
#	include "llvm/Support/FileSystem.h"
#	include <fstream>
#	include <iomanip>
#	include <regex>
#	include <sstream>

namespace rr {
namespace AsmFile {

std::string generateFilename(std::string routineName)
{
	// Names from gtests sometimes have invalid file name characters
	std::replace(routineName.begin(), routineName.end(), '/', '_');

	static size_t counter = 0;
	std::stringstream f;
	f << "reactor_jit_llvm_" << std::setfill('0') << std::setw(4) << counter++ << "_" << routineName << ".asm";
	return f.str();
}

bool emitAsmFile(const std::string &filename, llvm::orc::JITTargetMachineBuilder builder, llvm::Module &module)
{
	auto targetMachine = builder.createTargetMachine();
	if(!targetMachine)
		return false;

	auto fileType = llvm::CGFT_AssemblyFile;
	std::error_code EC;
	llvm::raw_fd_ostream dest(filename, EC, llvm::sys::fs::OF_None);
	ASSERT(!EC);
	llvm::legacy::PassManager pm;
	auto &options = targetMachine.get()->Options.MCOptions;
	options.ShowMCEncoding = true;
	options.AsmVerbose = true;
	targetMachine.get()->addPassesToEmitFile(pm, dest, nullptr, fileType);
	pm.run(module);
	return true;
}

void fixupAsmFile(const std::string &filename, std::vector<const void *> addresses)
{
	// Read input asm file into memory so we can overwrite it. This also allows us to merge multiline
	// comments into a single line for easier parsing below.
	std::vector<std::string> lines;
	{
		std::ifstream fin(filename);
		std::string line;
		while(std::getline(fin, line))
		{
			auto firstChar = [&] {
				auto index = line.find_first_not_of(" \t");
				if(index == std::string::npos)
					return '\n';
				return line[index];
			};

			if(!lines.empty() && firstChar() == '#')
			{
				lines.back() += line;
			}
			else
			{
				lines.push_back(line);
			}
		}
	}

	std::ofstream fout(filename);

	// Output function table
	fout << "\nFunction Addresses:\n";
	for(size_t i = 0; i < addresses.size(); i++)
	{
		fout << "f" << i << ": " << addresses[i] << "\n";
	}
	fout << "\n";

	size_t functionIndex = ~0;
	size_t instructionAddress = 0;

	for(auto &line : lines)
	{
		size_t pos{};

		if(line.find("# -- Begin function") != std::string::npos)
		{
			++functionIndex;

			if(functionIndex < addresses.size())
			{
				instructionAddress = (size_t)addresses[functionIndex];
			}
			else
			{
				// For coroutines, more functions are compiled than the top-level three.
				// For now, just output 0-based instructions.
				instructionAddress = 0;
			}
		}

		// Handle alignment directives by aligning the instruction address. When lowered, these actually
		// map to a nops to pad to the next aligned address.
		pos = line.find(".p2align");
		if(pos != std::string::npos)
		{
			// This assumes GNU asm format (https://sourceware.org/binutils/docs/as/P2align.html#P2align)
			static std::regex reAlign(R"(.*\.p2align.*([0-9]+).*)");
			std::smatch matches;
			auto found = std::regex_search(line, matches, reAlign);
			ASSERT(found);
			auto alignPow2 = std::stoi(matches[1]);
			auto align = 1 << alignPow2;
			instructionAddress = (instructionAddress + align - 1) & ~(align - 1);
		}

		// Detect instruction lines and prepend the location (address)
		pos = line.find("encoding: [");
		if(pos != std::string::npos)
		{
			// Determine offset of next instruction (size of this instruction in bytes)
			// e.g. # encoding: [0x48,0x89,0x4c,0x24,0x40]
			// Count number of commas in the array + 1
			auto endPos = line.find("]", pos);
			auto instructionSize = 1 + std::count_if(line.begin() + pos, line.begin() + endPos, [](char c) { return c == ','; });

			// Prepend current location to instruction line
			std::stringstream location;
			location << "[0x" << std::uppercase << std::hex << instructionAddress << "] ";
			line = location.str() + line;

			instructionAddress += instructionSize;
		}

		fout << line + "\n";
	}
}

}  // namespace AsmFile
}  // namespace rr

#endif  // ENABLE_RR_EMIT_ASM_FILE
