logoalt Hacker News

simpleuilast Wednesday at 10:07 AM1 replyview on HN

Very interesting, care to share the source?


Replies

shaknalast Wednesday at 10:24 AM

Oh, it's still a while off that. I do plan to make it public at some point, but when I'm actually happy the code isn't completely vomit.

But for a simple taste, the push to stack function currently looks like this. (All the emit stuff just writes bytes into a mmap that gets executed later.)

    void compile_push_literal(Value val) {
    #if ARCH_X86_64
        emit_bytes((uint8_t[]){X86_MOV_RDI_IMM64_0, X86_MOV_RDI_IMM64_1}, 2); emit_uint64_le(val);
        emit_bytes((uint8_t[]){X86_MOV_RAX_IMM64_0, X86_MOV_RAX_IMM64_1}, 2); emit_uint64_le((uint64_t)push);
        emit_bytes((uint8_t[]){X86_CALL_RAX_0, X86_CALL_RAX_1}, 2);
    #elif ARCH_ARM64
        uint64_t imm = val;
        emit_uint32_le(ARM64_MOVZ_OP | (ARM64_REG_X0 << 0) | ((imm & 0xFFFF) << 5));
        emit_uint32_le(ARM64_MOVK_OP_LSL16 | (ARM64_REG_X0 << 0) | (((imm >> 16) & 0xFFFF) << 5));
        emit_uint32_le(ARM64_MOVK_OP_LSL32 | (ARM64_REG_X0 << 0) | (((imm >> 32) & 0xFFFF) << 5));
        emit_uint32_le(ARM64_MOVK_OP_LSL48 | (ARM64_REG_X0 << 0) | (((imm >> 48) & 0xFFFF) << 5));
        uint64_t func_addr = (uint64_t)push;
        emit_uint32_le(ARM64_MOVZ_OP | (ARM64_REG_X1 << 0) | ((func_addr & 0xFFFF) << 5));
        emit_uint32_le(ARM64_MOVK_OP_LSL16 | (ARM64_REG_X1 << 0) | (((func_addr >> 16) & 0xFFFF) << 5));
        emit_uint32_le(ARM64_MOVK_OP_LSL32 | (ARM64_REG_X1 << 0) | (((func_addr >> 32) & 0xFFFF) << 5));
        emit_uint32_le(ARM64_MOVK_OP_LSL48 | (ARM64_REG_X1 << 0) | (((func_addr >> 48) & 0xFFFF) << 5));
        emit_uint32_le(ARM64_BLR_OP | (ARM64_REG_X1 << 5));
    #elif ARCH_RISCV64
        emit_load_imm_riscv(val, RISCV_REG_A0, RISCV_REG_T1);
        emit_load_imm_riscv((uint64_t)push, RISCV_REG_T0, RISCV_REG_T1);
        emit_uint32_le((0 << 20) | (RISCV_REG_T0 << 15) | (RISCV_F3_JALR << 12) | (RISCV_REG_RA << 7) | RISCV_OP_JALR);
    #endif
    }
show 3 replies