diff options
Diffstat (limited to 'include/bytecode')
-rw-r--r-- | include/bytecode/bytecode.h | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/include/bytecode/bytecode.h b/include/bytecode/bytecode.h index b571383..32488cc 100644 --- a/include/bytecode/bytecode.h +++ b/include/bytecode/bytecode.h @@ -12,41 +12,45 @@ Variable length opcodes. Sizes range from 1 to 4 bytes. # Instruction formats Instructions can be in 6 different formats: - 1. 1 byte: Opcode - 2. 2 bytes: Opcode + register - 3. 3 bytes: Opcode + register + register + 1. 1 byte: Opcode(u8) + 2. 2 bytes: Opcode(u8) + register(u8) + 3. 3 bytes: Opcode(u8) + register(u8) + register(u8) 4. 3 bytes:\ - 4.1 Opcode + intermediate\ - 4.2 Opcode + data\ - 4.3 Opcode + index\ - 4.4 Opcode + offset - 5. 4 bytes: Opcode + register + register + register + 4.1 Opcode(u8) + intermediate(u16)\ + 4.2 Opcode(u8) + data(u16)\ + 4.3 Opcode(u8) + offset(i16)\ + 4.4 Opcode(u8) + num_reg(u16)\ + 4.5 Opcode(u8) + register(u8) + num_args(u8) + 5. 4 bytes: Opcode(u8) + register(u8) + register(u8) + register(u8) 6. 4 bytes:\ - 6.1 Opcode + register + offset\ - 6.2 Opcode + register + intermediate\ - 6.3 Opcode + register + data + 6.1 Opcode(u8) + register(u8) + offset(i16)\ + 6.2 Opcode(u8) + register(u8) + intermediate(u16)\ + 6.3 Opcode(u8) + register(u8) + data(u16) + 7. 4 bytes: Opcode(u8) + index(u16) + num_args(u8) */ typedef enum { - AMAL_OP_NOP, /* No operation. This can be used for patching */ + AMAL_OP_NOP, /* No operation (do nothing). This can be used for patching code */ AMAL_OP_SETZ, /* setz reg - Set register value to 0 */ - AMAL_OP_MOV, /* mov dst, src - move src register to dst register */ - AMAL_OP_MOVI, /* movi dst, src - move src intermediate to dst register */ - AMAL_OP_MOVD, /* movd dst, src - move src data to dst register */ - AMAL_OP_ADD, /* add dst, reg1, reg2 */ - AMAL_OP_SUB, /* sub dst, reg1, reg2 */ - AMAL_OP_MUL, /* mul dst, reg1, reg2 */ - AMAL_OP_DIV, /* div dst, reg1, reg2 */ + AMAL_OP_MOV, /* mov dst, src - Move src register to dst register */ + AMAL_OP_MOVI, /* movi dst, src - Move src intermediate to dst register */ + AMAL_OP_MOVD, /* movd dst, src - Move src data to dst register */ + AMAL_OP_ADD, /* add dst, reg1, reg2 - Add reg1 and reg2 and put the result in dst */ + AMAL_OP_SUB, /* sub dst, reg1, reg2 - Substract reg2 from reg1 and put the result in dst */ + AMAL_OP_IMUL, /* imul dst, reg1, reg2 - Signed multiplication */ + AMAL_OP_MUL, /* mul dst, reg1, reg2 - Unsigned multiplication */ + AMAL_OP_IDIV, /* idiv dst, reg1, reg2 - Signed division */ + AMAL_OP_DIV, /* div dst, reg1, reg2 - Unsigned division */ AMAL_OP_PUSH, /* push reg - Push register onto stack */ AMAL_OP_PUSHI, /* pushi int - Push intermediate onto stack */ AMAL_OP_PUSHD, /* pushd data - Push data onto stack */ - AMAL_OP_CALL, /* call fi - Call a function using function index (fi). fi is u16 */ - AMAL_OP_CALLR, /* callr reg - Call a function using a register. Used for function pointers */ + AMAL_OP_CALL, /* call fi, num_args - Call a function using function index (fi) and num_args arguments. fi is u16 and num_args is u8 */ + AMAL_OP_CALLR, /* callr reg, num_args - Call a function using a register. Used for function pointers. num_args is u8 */ AMAL_OP_CMP, /* cmp dst, reg1, reg2 - Set dst to 1 if reg1 equals reg2, otherwise set it to 0 */ - AMAL_OP_JZ, /* jz reg, offset - jump to offset if reg is zero. offset is i16 */ - AMAL_OP_JMP, /* jmp offset - unconditional jump to offset. offset is i16 */ - AMAL_OP_RET, /* ret */ - AMAL_OP_FUNC_START, /* func_start */ - AMAL_OP_FUNC_END /* func_end */ + AMAL_OP_JZ, /* jz reg, offset - Jump to offset if reg is zero. offset is i16 */ + AMAL_OP_JMP, /* jmp offset - Unconditional jump to offset. offset is i16 */ + AMAL_OP_RET, /* ret - Return from the function */ + AMAL_OP_FUNC_START, /* func_start num_reg - Start of a function which has num_reg registers allocated. num_reg is a u16 */ + AMAL_OP_FUNC_END /* func_end - End of a function. Implementation should do a ret here */ } AmalOpcode; typedef u8 AmalOpcodeType; @@ -61,7 +65,7 @@ typedef struct { Parser *parser; /* borrowed */ } BytecodeCompilerContext; -CHECK_RESULT int bytecode_init(Bytecode *self, ScopedAllocator *allocator); +CHECK_RESULT int bytecode_init(Bytecode *self, ArenaAllocator *allocator); /* longjump to self->env on failure */ void generate_bytecode_from_ssa(BytecodeCompilerContext *self); |