|
|
@ -3,19 +3,178 @@ |
|
|
|
#include <iostream>
|
|
|
|
#include "molasses/parser_primitives.h"
|
|
|
|
|
|
|
|
enum class architecture_t { |
|
|
|
x86_64 |
|
|
|
}; |
|
|
|
|
|
|
|
constexpr architecture_t architecture = architecture_t::x86_64; |
|
|
|
|
|
|
|
namespace molasses { |
|
|
|
parser_context register_integers(parser_context ctx) { |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("i8",1)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("i16",2)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("i32",4)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("i64",8)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("u8",1)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("u16",2)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("u32",4)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("u64",8)); |
|
|
|
|
|
|
|
return ctx; |
|
|
|
} |
|
|
|
parser_context register_integers(parser_context ctx) { |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("i8",1)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("i16",2)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("i32",4)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("i64",8)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("u8",1)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("u16",2)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("u32",4)); |
|
|
|
ctx.types.push_back(std::make_shared<primitive_type>("u64",8)); |
|
|
|
|
|
|
|
return ctx; |
|
|
|
} |
|
|
|
|
|
|
|
parser_context register_i32_operations(parser_context ctx) { |
|
|
|
ctx.operations.emplace_back( |
|
|
|
std::make_shared<molasses::primitive_operation>( |
|
|
|
std::string{"+"}, |
|
|
|
std::vector<std::string>({"i32", "i32"}), |
|
|
|
std::vector<std::string>({"i32"}), |
|
|
|
std::vector<std::string>({ |
|
|
|
" popq %rax\n", |
|
|
|
" popq %rbx\n", |
|
|
|
" addl %ebx, %eax\n", |
|
|
|
" andl $0xFFFFFFFF, %eax\n", |
|
|
|
" pushq %rax\n" |
|
|
|
}) |
|
|
|
) |
|
|
|
); |
|
|
|
ctx.operations.emplace_back( |
|
|
|
std::make_shared<molasses::primitive_operation>( |
|
|
|
std::string{"*"}, |
|
|
|
std::vector<std::string>({"i32", "i32"}), |
|
|
|
std::vector<std::string>({"i32"}), |
|
|
|
std::vector<std::string>({ |
|
|
|
" popq %rax\n", |
|
|
|
" popq %rbx\n", |
|
|
|
" multl %ebx, %eax\n", |
|
|
|
" andl $0xFFFFFFFF, %eax\n", |
|
|
|
" pushq %rax\n" |
|
|
|
}) |
|
|
|
) |
|
|
|
); |
|
|
|
ctx.operations.emplace_back( |
|
|
|
std::make_shared<molasses::primitive_operation>( |
|
|
|
std::string{"-"}, |
|
|
|
std::vector<std::string>({"i32", "i32"}), |
|
|
|
std::vector<std::string>({"i32"}), |
|
|
|
std::vector<std::string>({ |
|
|
|
" popq %rax\n", |
|
|
|
" popq %rbx\n", |
|
|
|
" subl %ebx, %eax\n", |
|
|
|
" andl $0xFFFFFFFF, %eax\n", |
|
|
|
" pushq %rax\n" |
|
|
|
}) |
|
|
|
) |
|
|
|
); |
|
|
|
ctx.operations.emplace_back( |
|
|
|
std::make_shared<molasses::primitive_operation>( |
|
|
|
std::string{"i32-to-i64"}, |
|
|
|
std::vector<std::string>({"i32"}), |
|
|
|
std::vector<std::string>({"i64"}), |
|
|
|
std::vector<std::string>({ |
|
|
|
" popq %rax\n", |
|
|
|
" movslq %rax\n", |
|
|
|
" pushq %rax\n" |
|
|
|
}) |
|
|
|
) |
|
|
|
); |
|
|
|
|
|
|
|
ctx.operations.emplace_back( |
|
|
|
std::make_shared<molasses::primitive_operation>( |
|
|
|
std::string{"syscall1"}, |
|
|
|
std::vector<std::string>({"i64", "i64"}), |
|
|
|
std::vector<std::string>({"i64"}), |
|
|
|
std::vector<std::string>({ |
|
|
|
" popq %rax\n", |
|
|
|
" popq %rdi\n", |
|
|
|
" syscall\n", |
|
|
|
" pushq %rax\n" |
|
|
|
}) |
|
|
|
) |
|
|
|
); |
|
|
|
ctx.operations.emplace_back( |
|
|
|
std::make_shared<molasses::primitive_operation>( |
|
|
|
std::string{"syscall2"}, |
|
|
|
std::vector<std::string>({"i64", "i64", "i64"}), |
|
|
|
std::vector<std::string>({"i64"}), |
|
|
|
std::vector<std::string>({ |
|
|
|
" popq %rax\n", |
|
|
|
" popq %rdi\n", |
|
|
|
" popq %rsi\n", |
|
|
|
" syscall\n", |
|
|
|
" pushq %rax\n" |
|
|
|
}) |
|
|
|
) |
|
|
|
); |
|
|
|
ctx.operations.emplace_back( |
|
|
|
std::make_shared<molasses::primitive_operation>( |
|
|
|
std::string{"syscall3"}, |
|
|
|
std::vector<std::string>({"i64", "i64", "i64", "i64"}), |
|
|
|
std::vector<std::string>({"i64"}), |
|
|
|
std::vector<std::string>({ |
|
|
|
" popq %rax\n", |
|
|
|
" popq %rdi\n", |
|
|
|
" popq %rsi\n", |
|
|
|
" popq %rdx\n", |
|
|
|
" syscall\n", |
|
|
|
" pushq %rax\n" |
|
|
|
}) |
|
|
|
) |
|
|
|
); |
|
|
|
ctx.operations.emplace_back( |
|
|
|
std::make_shared<molasses::primitive_operation>( |
|
|
|
std::string{"syscall4"}, |
|
|
|
std::vector<std::string>({"i64", "i64", "i64", "i64", "i64"}), |
|
|
|
std::vector<std::string>({"i64"}), |
|
|
|
std::vector<std::string>({ |
|
|
|
" popq %rax\n", |
|
|
|
" popq %rdi\n", |
|
|
|
" popq %rsi\n", |
|
|
|
" popq %rdx\n", |
|
|
|
" popq %r10\n", |
|
|
|
" syscall\n", |
|
|
|
" pushq %rax\n" |
|
|
|
}) |
|
|
|
) |
|
|
|
); |
|
|
|
ctx.operations.emplace_back( |
|
|
|
std::make_shared<molasses::primitive_operation>( |
|
|
|
std::string{"syscall5"}, |
|
|
|
std::vector<std::string>({"i64", "i64", "i64", "i64", "i64", "i64"}), |
|
|
|
std::vector<std::string>({"i64"}), |
|
|
|
std::vector<std::string>({ |
|
|
|
" popq %rax\n", |
|
|
|
" popq %rdi\n", |
|
|
|
" popq %rsi\n", |
|
|
|
" popq %rdx\n", |
|
|
|
" popq %r10\n", |
|
|
|
" popq %r8\n", |
|
|
|
" syscall\n", |
|
|
|
" pushq %rax\n" |
|
|
|
}) |
|
|
|
) |
|
|
|
); |
|
|
|
ctx.operations.emplace_back( |
|
|
|
std::make_shared<molasses::primitive_operation>( |
|
|
|
std::string{"syscall6"}, |
|
|
|
std::vector<std::string>({"i64", "i64", "i64", "i64", "i64", "i64", "i64"}), |
|
|
|
std::vector<std::string>({"i64"}), |
|
|
|
std::vector<std::string>({ |
|
|
|
" popq %rax\n", |
|
|
|
" popq %rdi\n", |
|
|
|
" popq %rsi\n", |
|
|
|
" popq %rdx\n", |
|
|
|
" popq %r10\n", |
|
|
|
" popq %r8\n", |
|
|
|
" popq %r9\n", |
|
|
|
" syscall\n", |
|
|
|
" pushq %rax\n" |
|
|
|
}) |
|
|
|
) |
|
|
|
); |
|
|
|
|
|
|
|
return ctx; |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<std::string> operator>>(std::vector<std::string> current_stack, const operation& next_op) { |
|
|
|
{ |
|
|
@ -90,7 +249,8 @@ namespace molasses { |
|
|
|
return type_stack == execution_output; |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<std::string> initialize_stack() { |
|
|
|
std::vector<std::string> initialize_stack() |
|
|
|
requires (architecture == architecture_t::x86_64) { |
|
|
|
return { |
|
|
|
".bss\n",// TODO: make threadlocal
|
|
|
|
"stack_instruction:\n", |
|
|
@ -215,7 +375,8 @@ namespace molasses { |
|
|
|
return ctx; |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<std::string> generate_call(std::string target) { |
|
|
|
std::vector<std::string> generate_call(std::string target) |
|
|
|
requires (architecture == architecture_t::x86_64) { |
|
|
|
static uint64_t label_count= 0; |
|
|
|
return { |
|
|
|
" movq return_label_n"+std::to_string(label_count)+", (stack_instruction)\n", |
|
|
@ -225,13 +386,14 @@ namespace molasses { |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<std::string> generate_push_int32(int32_t target) { |
|
|
|
std::vector<std::string> generate_push_int32(int32_t target) k">requires (architecture == architecture_t::x86_64) { |
|
|
|
return { |
|
|
|
" pushq $" +std::to_string(target)+ "\n" |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<std::string> procedure_operation::generate(const parser_context& ctx, const lexed_output& lexer_data) const { |
|
|
|
std::vector<std::string> procedure_operation::generate(const parser_context& ctx, const lexed_output& lexer_data) const |
|
|
|
requires (architecture == architecture_t::x86_64) { |
|
|
|
std::vector<std::string> ops; |
|
|
|
ops.emplace_back(name()+":\n"); |
|
|
|
|
|
|
|