sirit/src/sirit.cpp

155 lines
3.9 KiB
C++
Raw Normal View History

2018-08-23 08:59:57 +01:00
/* This file is part of the sirit project.
* Copyright (c) 2018 ReinUsesLisp
* This software may be used and distributed according to the terms of the GNU
* General Public License version 2 or any later version.
*/
2018-08-26 00:16:37 +01:00
#include <algorithm>
#include <cassert>
#include "sirit/sirit.h"
#include "common_types.h"
2018-08-26 00:34:06 +01:00
#include "op.h"
2018-08-26 00:16:37 +01:00
#include "stream.h"
namespace Sirit {
template<typename T>
2018-08-26 00:34:06 +01:00
static void WriteEnum(Stream& stream, spv::Op opcode, T value) {
Op op{opcode};
op.Add(static_cast<u32>(value));
op.Write(stream);
2018-08-26 00:16:37 +01:00
}
Module::Module() {}
Module::~Module() = default;
std::vector<u8> Module::Assembly() const {
std::vector<u8> bytes;
Stream stream{bytes};
stream.Write(spv::MagicNumber);
stream.Write(spv::Version);
stream.Write(GeneratorMagicNumber);
stream.Write(bound);
stream.Write(static_cast<u32>(0));
for (auto capability : capabilities) {
WriteEnum(stream, spv::Op::OpCapability, capability);
}
// TODO write extensions
// TODO write ext inst imports
2018-08-26 00:34:06 +01:00
Op memory_model_ref{spv::Op::OpMemoryModel};
2018-08-26 00:16:37 +01:00
memory_model_ref.Add(static_cast<u32>(addressing_model));
memory_model_ref.Add(static_cast<u32>(memory_model));
memory_model_ref.Write(stream);
for (const auto& entry_point : entry_points) {
entry_point->Write(stream);
}
// TODO write execution mode
// TODO write debug symbols
// TODO write annotations
for (const auto& decl : declarations) {
decl->Write(stream);
}
for (const auto& line : code) {
line->Write(stream);
}
return bytes;
}
void Module::Optimize(int level) {
}
void Module::AddCapability(spv::Capability capability) {
capabilities.insert(capability);
}
void Module::SetMemoryModel(spv::AddressingModel addressing_model, spv::MemoryModel memory_model) {
this->addressing_model = addressing_model;
this->memory_model = memory_model;
}
2018-08-26 00:34:06 +01:00
void Module::AddEntryPoint(spv::ExecutionModel execution_model, const Op* entry_point,
const std::string& name, const std::vector<const Op*>& interfaces) {
Op* op{new Op(spv::Op::OpEntryPoint)};
2018-08-26 00:16:37 +01:00
op->Add(static_cast<u32>(execution_model));
op->Add(entry_point);
op->Add(name);
op->Add(interfaces);
2018-08-26 00:34:06 +01:00
entry_points.push_back(std::unique_ptr<Op>(op));
2018-08-26 00:16:37 +01:00
}
2018-08-26 00:34:06 +01:00
const Op* Module::TypeVoid() {
return AddDeclaration(new Op(spv::Op::OpTypeVoid, bound));
2018-08-26 00:16:37 +01:00
}
2018-08-26 00:34:06 +01:00
const Op* Module::TypeFunction(const Op* return_type, const std::vector<const Op*>& arguments) {
Op* type_func{new Op(spv::Op::OpTypeFunction, bound)};
2018-08-26 00:16:37 +01:00
type_func->Add(return_type);
2018-08-26 00:34:06 +01:00
for (const Op* arg : arguments) {
2018-08-26 00:16:37 +01:00
type_func->Add(arg);
}
return AddDeclaration(type_func);
}
2018-08-26 00:34:06 +01:00
const Op* Module::Emit(const Op* op) {
assert(op);
code.push_back(op);
return op;
2018-08-26 00:16:37 +01:00
}
2018-08-26 00:34:06 +01:00
const Op* Module::Function(const Op* result_type, spv::FunctionControlMask function_control,
const Op* function_type) {
Op* op{new Op{spv::Op::OpFunction, bound++, result_type}};
2018-08-26 00:16:37 +01:00
op->Add(static_cast<u32>(function_control));
op->Add(function_type);
return AddCode(op);
}
2018-08-26 00:34:06 +01:00
const Op* Module::Label() {
2018-08-26 00:16:37 +01:00
return AddCode(spv::Op::OpLabel, bound++);
}
2018-08-26 00:34:06 +01:00
const Op* Module::Return() {
2018-08-26 00:16:37 +01:00
return AddCode(spv::Op::OpReturn);
}
2018-08-26 00:34:06 +01:00
const Op* Module::FunctionEnd() {
2018-08-26 00:16:37 +01:00
return AddCode(spv::Op::OpFunctionEnd);
}
2018-08-26 00:34:06 +01:00
const Op* Module::AddCode(Op* op) {
code_store.push_back(std::unique_ptr<Op>(op));
return op;
2018-08-26 00:16:37 +01:00
}
2018-08-26 00:34:06 +01:00
const Op* Module::AddCode(spv::Op opcode, u32 id) {
return AddCode(new Op{opcode, id});
2018-08-26 00:16:37 +01:00
}
2018-08-26 00:34:06 +01:00
const Op* Module::AddDeclaration(Op* op) {
2018-08-26 00:16:37 +01:00
const auto& found{std::find_if(declarations.begin(), declarations.end(), [=](const auto& other) {
2018-08-26 00:34:06 +01:00
return *other == *op;
2018-08-26 00:16:37 +01:00
})};
if (found != declarations.end()) {
2018-08-26 00:34:06 +01:00
delete op;
2018-08-26 00:16:37 +01:00
return found->get();
} else {
2018-08-26 00:34:06 +01:00
declarations.push_back(std::unique_ptr<Op>(op));
2018-08-26 00:16:37 +01:00
bound++;
2018-08-26 00:34:06 +01:00
return op;
2018-08-26 00:16:37 +01:00
}
}
} // namespace Sirit