2019-11-02 16:38:11 -07:00
|
|
|
#include "instruction.hpp"
|
2019-11-05 00:42:33 -08:00
|
|
|
#include "llvm_context.hpp"
|
|
|
|
#include <llvm/IR/Function.h>
|
|
|
|
|
|
|
|
using namespace llvm;
|
2019-11-02 16:38:11 -07:00
|
|
|
|
|
|
|
static void print_indent(int n, std::ostream& to) {
|
|
|
|
while(n--) to << " ";
|
|
|
|
}
|
|
|
|
|
|
|
|
void instruction_pushint::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "PushInt(" << value << ")" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_pushint::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
ctx.create_push(f, ctx.create_num(ctx.create_i32(value)));
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_pushglobal::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "PushGlobal(" << name << ")" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_pushglobal::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_push::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "Push(" << offset << ")" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_push::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
ctx.create_push(f, ctx.create_peek(f, ctx.create_size(offset)));
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_mkapp::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "MkApp()" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_mkapp::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
auto left = ctx.create_pop(f);
|
|
|
|
auto right = ctx.create_pop(f);
|
|
|
|
ctx.create_push(f, ctx.create_app(left, right));
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_update::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "Update(" << offset << ")" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_update::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
ctx.create_update(f, ctx.create_size(offset));
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_pack::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "Pack(" << tag << ", " << size << ")" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_pack::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
ctx.create_pack(f, ctx.create_size(size), ctx.create_i8(tag));
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_split::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "Split()" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_split::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
ctx.create_split(f, ctx.create_size(size));
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_jump::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "Jump(" << std::endl;
|
|
|
|
for(auto& instruction_set : branches) {
|
|
|
|
for(auto& instruction : instruction_set) {
|
|
|
|
instruction->print(indent + 2, to);
|
|
|
|
}
|
|
|
|
to << std::endl;
|
|
|
|
}
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << ")" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_slide::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "Slide(" << offset << ")" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_slide::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
ctx.create_slide(f, ctx.create_size(offset));
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_binop::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "BinOp(" << op_action(op) << ")" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_binop::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
auto left_int = ctx.unwrap_num(ctx.create_pop(f));
|
|
|
|
auto right_int = ctx.unwrap_num(ctx.create_pop(f));
|
|
|
|
llvm::Value* result;
|
|
|
|
switch(op) {
|
|
|
|
case PLUS: result = ctx.builder.CreateAdd(left_int, right_int); break;
|
|
|
|
case MINUS: result = ctx.builder.CreateSub(left_int, right_int); break;
|
|
|
|
case TIMES: result = ctx.builder.CreateMul(left_int, right_int); break;
|
|
|
|
case DIVIDE: result = ctx.builder.CreateSDiv(left_int, right_int); break;
|
|
|
|
}
|
|
|
|
ctx.create_push(f, ctx.create_num(result));
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_eval::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "Eval()" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_eval::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
ctx.create_push(f, ctx.create_eval(ctx.create_pop(f)));
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_alloc::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "Alloc(" << amount << ")" << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void instruction_alloc::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
ctx.create_alloc(f, ctx.create_size(amount));
|
|
|
|
}
|
|
|
|
|
2019-11-02 16:38:11 -07:00
|
|
|
void instruction_unwind::print(int indent, std::ostream& to) const {
|
|
|
|
print_indent(indent, to);
|
|
|
|
to << "Unwind()" << std::endl;
|
|
|
|
}
|
2019-11-05 00:42:33 -08:00
|
|
|
|
|
|
|
void instruction_unwind::gen_llvm(llvm_context& ctx, Function* f) const {
|
|
|
|
// Nothing
|
|
|
|
}
|