|
|
- #include "molasses/parser_primitives.h"
- #include "molasses/generator_primitives.h"
-
- namespace molasses {
- parser_context register_integers(parser_context ctx)
- requires (architecture == architecture_t::x86_64_linux) {
- 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)
- requires (architecture == architecture_t::x86_64_linux) {
- 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",
- " imull %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 %eax, %rax\n",
- " pushq %rax\n"
- })
- )
- );
-
- ctx.operations.emplace_back(
- std::make_shared<molasses::primitive_operation>(
- std::string{"drop_i64"},
- std::vector<std::string>({"i64"}),
- std::vector<std::string>({}),
- std::vector<std::string>({
- " popq %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> generate_call(const std::string& target)
- requires (architecture == architecture_t::x86_64_linux) {
- return {
- " call "+target+"\n",
- };
- }
-
- std::vector<std::string> generate_push_int32(int32_t target)
- requires (architecture == architecture_t::x86_64_linux) {
- return {
- " pushq $" +std::to_string(target)+ "\n"
- };
- }
-
- std::vector<std::string> generate_label(const std::string& target)
- requires (architecture == architecture_t::x86_64_linux) {
- return {
- target+":\n"
- };
- }
-
- std::vector<std::string> generate_return()
- requires (architecture == architecture_t::x86_64_linux) {
- return {
- " // Return to caller\n",
- " addq $-8, %r10\n",
- " pushq (%r10)\n",
- " retq\n"
- };
- }
-
- std::vector<std::string> generate_enter()
- requires (architecture == architecture_t::x86_64_linux) {
- return {
- " // Prepare the function stack\n",
- " popq (%r10)\n"
- " addq $8, %r10\n",
- };
- }
-
- std::vector<std::string> initialize_stack()
- requires (architecture == architecture_t::x86_64_linux) {
- std::vector<std::string> operations = {
- "code:\n",
- " .skip 1000000\n",
- ".text\n",
- " .globl _start\n",
- "initialize_callstack:\n",
- " movq $9, %rax\n",
- " movq $0, %rdi\n",
- " movq $8192, %rsi\n",
- " movq $3, %rdx\n",
- " movq $34, %r10\n",
- " movq $-1, %r8\n",
- " movq $0, %r9\n",
- " syscall\n",
- " movq %rax, %r10\n",
- " retq\n",
- "_start:\n",
- " call initialize_callstack\n"
- };
-
- for(const auto& op : generate_call("main")) {
- operations.push_back(op);
- }
-
- for(const auto& op : std::vector<std::string>{
- " movq $0, %rdi\n",
- " movq $60, %rax\n",
- " syscall\n"
- }
- ) {
- operations.push_back(op);
- }
- return operations;
- }
- }
|