Last active
February 26, 2017 03:12
-
-
Save keiichiw/d895ee5b10eb2ae1db150856f73cd1b9 to your computer and use it in GitHub Desktop.
ELVMの変換例: EIR, C++Template, C, constexprの比較
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
# 出典: https://github.com/shinh/elvm/blob/master/test/06mem.eir | |
# "MEM" と出力される | |
mov B, 77 | |
store B, 300 | |
load A, 300 | |
load A, 300 | |
putc A | |
mov B, 69 | |
store B, 30 | |
store B, 30 | |
load A, 30 | |
putc A | |
add A, 8 | |
putc A | |
load A, 556 | |
add A, 10 | |
putc A | |
exit |
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
// Template Meta Programming バックエンドの出力 | |
#include <cstdio> | |
#include "cpp_template_lib.hpp" // https://gist.github.com/kw-udon/6248197ec8fdc681b63e4cb8271fac56 | |
typedef enum { a, b, c, d, bp, sp } Reg_Name; | |
template <typename r0, typename m0, typename b0, int pc> | |
struct func_switch_impl { typedef inc_pc<r0, m0, b0> result; }; | |
template <typename r0, typename m0, typename b0> | |
struct func_switch_impl<r0, m0, b0, 0> { | |
typedef jmp_imm<r0, 1> r1; | |
typedef inc_pc<r1, m0, b0> result; | |
}; | |
template <typename r0, typename m0, typename b0> | |
struct func_switch_impl<r0, m0, b0, 1> { | |
typedef mov_imm<r0, b, 77> r1; | |
typedef store_imm<r1, m0, b, 300> m1; | |
typedef load_imm<r1, m1, a, 300> r2; | |
typedef load_imm<r2, m1, a, 300> r3; | |
typedef putc_reg<r3, b0,a> b1; | |
typedef mov_imm<r3, b, 69> r4; | |
typedef store_imm<r4, m1, b, 30> m2; | |
typedef store_imm<r4, m2, b, 30> m3; | |
typedef load_imm<r4, m3, a, 30> r5; | |
typedef putc_reg<r5, b1,a> b2; | |
typedef add_imm<r5, a, 8> r6; | |
typedef putc_reg<r6, b2,a> b3; | |
typedef load_imm<r6, m3, a, 556> r7; | |
typedef add_imm<r7, a, 10> r8; | |
typedef putc_reg<r8, b3,a> b4; | |
typedef exit_inst<r8> r9; | |
typedef inc_pc<r9, m3, b4> result; | |
}; | |
template <typename env, int pc> | |
struct func_switch : func_switch_impl<typename env::regs, typename env::mem, typename env::buf, pc>::result {}; | |
template <typename env, bool, int> | |
struct main_loop { typedef env result; }; | |
template <typename env, int pc> | |
struct main_loop<env, false, pc> { | |
typedef func_switch<env, pc> env2; | |
typedef typename main_loop<env2, env2::regs::exit_flag, env2::regs::pc>::result result; | |
}; | |
struct calc_main { | |
typedef init_memory<MEM_SIZE> mem0; | |
typedef store_value<mem0, 0, 1> mem1; | |
typedef init_regs<0> regs; | |
typedef make_env<regs, mem1, Nil> env; | |
typedef main_loop<env, false, 0>::result result; | |
}; | |
int main() { | |
typedef calc_main::result result; | |
print_buffer<result::buf>::run(); | |
} |
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
// 参考のため、Cバックエンドの出力 | |
#include <stdio.h> | |
#include <stdlib.h> | |
unsigned int a; | |
unsigned int b; | |
unsigned int c; | |
unsigned int d; | |
unsigned int bp; | |
unsigned int sp; | |
unsigned int pc; | |
unsigned int mem[1<<24]; | |
void func0() { | |
while (0 <= pc && pc < 512) { | |
switch (pc) { | |
case -1: /* dummy */ | |
break; | |
case 0: | |
if (1) pc = 1 - 1; | |
break; | |
case 1: | |
b = 77; | |
mem[300] = b; | |
a = mem[300]; | |
a = mem[300]; | |
putchar(a); | |
b = 69; | |
mem[30] = b; | |
mem[30] = b; | |
a = mem[30]; | |
putchar(a); | |
a = (a + 8) & 16777215; | |
putchar(a); | |
a = mem[556]; | |
a = (a + 10) & 16777215; | |
putchar(a); | |
exit(0); | |
} | |
pc++; | |
} | |
} | |
int main() { | |
mem[0] = 1; | |
while (1) { | |
switch (pc / 512 | 0) { | |
case 0: | |
func0(); | |
break; | |
} | |
} | |
return 1; | |
} |
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
// 参考のため、constexprバックエンドの出力 | |
#include <cstdio> | |
#include <utility> | |
const size_t BUF_SIZE = 10000; | |
constexpr char input[] = | |
#include "input.txt" | |
; | |
struct buffer { | |
unsigned int size; | |
unsigned int b[BUF_SIZE]; | |
}; | |
template <size_t... I> | |
constexpr buffer make_buf_impl(unsigned int size, unsigned int* buf, std::index_sequence<I...>) { | |
return buffer{size, {buf[I]...}}; | |
} | |
constexpr buffer make_buf(unsigned int size, unsigned int* buf) { | |
return make_buf_impl(size, buf, std::make_index_sequence<BUF_SIZE>{}); | |
} | |
constexpr buffer constexpr_main() { | |
unsigned int a = 0; | |
unsigned int b = 0; | |
unsigned int c = 0; | |
unsigned int d = 0; | |
unsigned int bp = 0; | |
unsigned int sp = 0; | |
unsigned int pc = 0; | |
unsigned int i_cur = 0; | |
unsigned int o_cur = 0; | |
unsigned int mem[1<<24] = {0}; | |
unsigned int buf[BUF_SIZE] = {0}; | |
mem[0] = 1; | |
while (1) { | |
switch (pc) { | |
case 0: | |
if (1) pc = 1 - 1; | |
break; | |
case 1: | |
b = 77; | |
mem[300] = b; | |
a = mem[300]; | |
a = mem[300]; | |
buf[o_cur++] = a; | |
b = 69; | |
mem[30] = b; | |
mem[30] = b; | |
a = mem[30]; | |
buf[o_cur++] = a; | |
a = (a + 8) & 16777215; | |
buf[o_cur++] = a; | |
a = mem[556]; | |
a = (a + 10) & 16777215; | |
buf[o_cur++] = a; | |
return make_buf(o_cur, buf); | |
} | |
pc++; | |
} | |
return make_buf(o_cur, buf); | |
} | |
int main() { | |
constexpr buffer buf = constexpr_main(); | |
constexpr unsigned int output_size = buf.size; | |
for(int i = 0; i < output_size; ++i) { | |
putchar(buf.b[i]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment