Created
July 28, 2024 01:09
-
-
Save randombit/a337d5d0e04afb563c9a65147458d21c to your computer and use it in GitHub Desktop.
Compile time generation of asm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Demo of constexpr asm (gcc 15) | |
#include <stdlib.h> | |
#include <array> | |
#include <string> | |
#include <algorithm> | |
consteval std::string body_i(std::string_view x, size_t i) { | |
std::string out; | |
for(char c : x) { | |
if(c == '#') { | |
if(i < 10) { | |
out.push_back(c: '0' + i % 10); | |
} else { | |
out.push_back(c: '0' + i / 10); | |
out.push_back(c: '0' + i % 10); | |
} | |
} else { | |
out.push_back(c); | |
} | |
} | |
return out; | |
} | |
template<size_t N> | |
consteval auto wordn_add3() { | |
static_assert(N < 100); | |
auto gen_asm = []() { | |
size_t n = N; | |
std::string s = ""; | |
const std::string hdr = "\trorq %[carry]\n\t"; | |
const std::string tail = "sbbq %[carry],%[carry]\n\tnegq %[carry]\n\t"; | |
const std::string body = R"( | |
movq 8*#(%[x]), %[carry] | |
adcq 8*#(%[y]), %[carry] | |
movq %[carry], 8*#(%[z]) | |
)"; | |
s += hdr; | |
for(size_t i = 0; i != N; ++i) { | |
s += body_i(x: body, i); | |
} | |
s += tail; | |
return s; | |
}; | |
constexpr size_t C = gen_asm().size(); | |
std::string s = gen_asm(); | |
std::array<char, C> r = {}; | |
s.copy(s: r.begin(), n: s.size()); | |
return r; | |
} | |
template<size_t N1, size_t N2> | |
consteval auto concat(std::array<char, N1> x, | |
std::array<char, N2> y) { | |
std::array<char, N1 + N2> xy; | |
for(size_t i = 0; i != N1; ++i) { | |
xy[i] = x[i]; | |
} | |
for(size_t i = 0; i != N2; ++i) { | |
xy[N1 + i] = y[i]; | |
} | |
return xy; | |
} | |
onsteval size_t str_length(std::string_view sv) { | |
return sv.size(); | |
} | |
template <size_t N> | |
class StringLiteral { | |
public: | |
constexpr StringLiteral(const char (&str)[N]) { std::copy_n(str, N, value); } | |
static constexpr size_t len = N; | |
char value[N]; | |
}; | |
template<StringLiteral S> | |
consteval auto literal() { | |
constexpr size_t N = S.len; | |
std::array<char, N> r = {}; | |
//std::copy_n(r.data(), S.value, N); | |
std::copy_n(S.value, N, r.data()); | |
return r; | |
} | |
int main() { | |
auto x: std::array<char, C> = wordn_add3<32>(); | |
for(auto c: char: x) { | |
printf(format: "%c", c); | |
} | |
printf(format: "\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment