Stream SPIR-V instructions directly to a binary

Before this commit sirit generated a stream of tokens that would then be
inserted to the final SPIR-V binary. This design was carried from the
initial design of manually inserting opcodes into the code. Now that
all instructions but labels are inserted when their respective function
is called, the old design can be dropped in favor of generating a valid
stream of SPIR-V opcodes.

The API for variables is broken, but adopting the new one is trivial.
Instead of calling OpVariable and then adding a global or local
variable, OpVariable was removed and global or local variables are
generated when they are called.

Avoiding duplicates is now done with an std::unordered_set instead of
using a linear search jumping through vtables.
This commit is contained in:
ReinUsesLisp
2020-08-01 01:50:01 -03:00
parent c4ea8f4b76
commit 0b9ee36247
31 changed files with 651 additions and 1150 deletions

View File

@@ -1,51 +0,0 @@
/* This file is part of the sirit project.
* Copyright (c) 2019 sirit
* This software may be used and distributed according to the terms of the
* 3-Clause BSD License
*/
#include "stream.h"
namespace Sirit {
Stream::Stream(std::vector<u32>& words_) : words{words_} {}
Stream::~Stream() = default;
void Stream::Write(std::string_view string) {
constexpr std::size_t word_size = 4;
const auto size = string.size();
const auto read = [string, size](std::size_t offset) {
return offset < size ? static_cast<u8>(string[offset]) : u8(0);
};
words.reserve(words.size() + size / word_size + 1);
for (std::size_t i = 0; i < size; i += word_size) {
Write(read(i), read(i + 1), read(i + 2), read(i + 3));
}
if (size % word_size == 0) {
Write(u32(0));
}
}
void Stream::Write(u64 value) {
const u32 dword[] = {static_cast<u32>(value), static_cast<u32>(value >> 32)};
words.insert(std::begin(words), std::cbegin(dword), std::cend(dword));
}
void Stream::Write(u32 value) {
words.push_back(value);
}
void Stream::Write(u16 first, u16 second) {
const u32 word = static_cast<u32>(first) | static_cast<u32>(second) << 16;
Write(word);
}
void Stream::Write(u8 first, u8 second, u8 third, u8 fourth) {
const u32 word = static_cast<u32>(first) | static_cast<u32>(second) << 8 |
static_cast<u32>(third) << 16 | static_cast<u32>(fourth) << 24;
Write(word);
}
} // namespace Sirit