|
|
@ -24,9 +24,9 @@ void instruction_pushglobal::print(int indent, std::ostream& to) const { |
|
|
|
} |
|
|
|
|
|
|
|
void instruction_pushglobal::gen_llvm(llvm_context& ctx, Function* f) const { |
|
|
|
auto& global_f = ctx.custom_functions.at("f_" + name); |
|
|
|
auto arity = ctx.create_i32(global_f->arity); |
|
|
|
ctx.create_push(f, ctx.create_global(f, global_f->function, arity)); |
|
|
|
auto& global_f = ctx.get_custom_function(name); |
|
|
|
auto arity = ctx.create_i32(global_f.arity); |
|
|
|
ctx.create_push(f, ctx.create_global(f, global_f.function, arity)); |
|
|
|
} |
|
|
|
|
|
|
|
void instruction_push::print(int indent, std::ostream& to) const { |
|
|
@ -101,17 +101,17 @@ void instruction_jump::print(int indent, std::ostream& to) const { |
|
|
|
void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const { |
|
|
|
auto top_node = ctx.create_peek(f, ctx.create_size(0)); |
|
|
|
auto tag = ctx.unwrap_data_tag(top_node); |
|
|
|
auto safety_block = BasicBlock::Create(ctx.ctx, "safety", f); |
|
|
|
auto switch_op = ctx.builder.CreateSwitch(tag, safety_block, tag_mappings.size()); |
|
|
|
auto safety_block = ctx.create_basic_block("safety", f); |
|
|
|
auto switch_op = ctx.get_builder().CreateSwitch(tag, safety_block, tag_mappings.size()); |
|
|
|
std::vector<BasicBlock*> blocks; |
|
|
|
|
|
|
|
for(auto& branch : branches) { |
|
|
|
auto branch_block = BasicBlock::Create(ctx.ctx, "branch", f); |
|
|
|
ctx.builder.SetInsertPoint(branch_block); |
|
|
|
auto branch_block = ctx.create_basic_block("branch", f); |
|
|
|
ctx.get_builder().SetInsertPoint(branch_block); |
|
|
|
for(auto& instruction : branch) { |
|
|
|
instruction->gen_llvm(ctx, f); |
|
|
|
} |
|
|
|
ctx.builder.CreateBr(safety_block); |
|
|
|
ctx.get_builder().CreateBr(safety_block); |
|
|
|
blocks.push_back(branch_block); |
|
|
|
} |
|
|
|
|
|
|
@ -119,7 +119,7 @@ void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const { |
|
|
|
switch_op->addCase(ctx.create_i8(mapping.first), blocks[mapping.second]); |
|
|
|
} |
|
|
|
|
|
|
|
ctx.builder.SetInsertPoint(safety_block); |
|
|
|
ctx.get_builder().SetInsertPoint(safety_block); |
|
|
|
} |
|
|
|
|
|
|
|
void instruction_if::print(int indent, std::ostream& to) const { |
|
|
@ -140,25 +140,25 @@ void instruction_if::gen_llvm(llvm_context& ctx, llvm::Function* f) const { |
|
|
|
auto top_node = ctx.create_peek(f, ctx.create_size(0)); |
|
|
|
auto num = ctx.unwrap_num(top_node); |
|
|
|
|
|
|
|
auto nonzero_block = BasicBlock::Create(ctx.ctx, "nonzero", f); |
|
|
|
auto zero_block = BasicBlock::Create(ctx.ctx, "zero", f); |
|
|
|
auto resume_block = BasicBlock::Create(ctx.ctx, "resume", f); |
|
|
|
auto switch_op = ctx.builder.CreateSwitch(num, nonzero_block, 2); |
|
|
|
auto nonzero_block = ctx.create_basic_block("nonzero", f); |
|
|
|
auto zero_block = ctx.create_basic_block("zero", f); |
|
|
|
auto resume_block = ctx.create_basic_block("resume", f); |
|
|
|
auto switch_op = ctx.get_builder().CreateSwitch(num, nonzero_block, 2); |
|
|
|
|
|
|
|
switch_op->addCase(ctx.create_i32(0), zero_block); |
|
|
|
ctx.builder.SetInsertPoint(nonzero_block); |
|
|
|
ctx.get_builder().SetInsertPoint(nonzero_block); |
|
|
|
for(auto& instruction : on_true) { |
|
|
|
instruction->gen_llvm(ctx, f); |
|
|
|
} |
|
|
|
ctx.builder.CreateBr(resume_block); |
|
|
|
ctx.get_builder().CreateBr(resume_block); |
|
|
|
|
|
|
|
ctx.builder.SetInsertPoint(zero_block); |
|
|
|
ctx.get_builder().SetInsertPoint(zero_block); |
|
|
|
for(auto& instruction : on_false) { |
|
|
|
instruction->gen_llvm(ctx, f); |
|
|
|
} |
|
|
|
ctx.builder.CreateBr(resume_block); |
|
|
|
ctx.get_builder().CreateBr(resume_block); |
|
|
|
|
|
|
|
ctx.builder.SetInsertPoint(resume_block); |
|
|
|
ctx.get_builder().SetInsertPoint(resume_block); |
|
|
|
} |
|
|
|
|
|
|
|
void instruction_slide::print(int indent, std::ostream& to) const { |
|
|
@ -180,13 +180,13 @@ void instruction_binop::gen_llvm(llvm_context& ctx, Function* f) const { |
|
|
|
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; |
|
|
|
case MODULO: result = ctx.builder.CreateSRem(left_int, right_int); break; |
|
|
|
case EQUALS: result = ctx.builder.CreateICmpEQ(left_int, right_int); break; |
|
|
|
case LESS_EQUALS: result = ctx.builder.CreateICmpSLE(left_int, right_int); break; |
|
|
|
case PLUS: result = ctx.get_builder().CreateAdd(left_int, right_int); break; |
|
|
|
case MINUS: result = ctx.get_builder().CreateSub(left_int, right_int); break; |
|
|
|
case TIMES: result = ctx.get_builder().CreateMul(left_int, right_int); break; |
|
|
|
case DIVIDE: result = ctx.get_builder().CreateSDiv(left_int, right_int); break; |
|
|
|
case MODULO: result = ctx.get_builder().CreateSRem(left_int, right_int); break; |
|
|
|
case EQUALS: result = ctx.get_builder().CreateICmpEQ(left_int, right_int); break; |
|
|
|
case LESS_EQUALS: result = ctx.get_builder().CreateICmpSLE(left_int, right_int); break; |
|
|
|
} |
|
|
|
ctx.create_push(f, ctx.create_num(f, result)); |
|
|
|
} |
|
|
|