From 0bdbaa7f1fb731fcb3a48473d07e9cbc4c0f59c0 Mon Sep 17 00:00:00 2001 From: sfja Date: Tue, 1 Apr 2025 17:15:37 +0200 Subject: [PATCH] extract assembling line --- Makefile | 1 - asm/asm.c | 1106 +++++++++++++++++++++++---------------------- asm/asm.h | 2 +- asm/ctors.c | 1 + compile_flags.txt | 2 +- kern/main.c | 2 +- vm/vm.c | 1 + 7 files changed, 574 insertions(+), 541 deletions(-) diff --git a/Makefile b/Makefile index 77a68ad..28102ac 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,6 @@ C_FLAGS = \ -Wall -Wextra -Wpedantic -Wconversion \ -pedantic -pedantic-errors \ -Wno-unused-variable \ - -Wno-unused-parameter \ -I. \ L_FLAGS = -pthread diff --git a/asm/asm.c b/asm/asm.c index c12cf6b..a8dba25 100644 --- a/asm/asm.c +++ b/asm/asm.c @@ -17,7 +17,572 @@ static inline void set_mov_addr_is_reg(uint32_t* ins); static inline void set_mov_is_store(uint32_t* ins); static inline uint16_t linety_arithm_ins(LineTy ty); -uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) +uint16_t assemble_line(uint16_t* out, const Line* line) +{ + uint16_t ip = 0; + + switch (line->ty) { + case LineTy_Label: + case LineTy_DataLabel: + case LineTy_Jmp_Label: + case LineTy_Jnz_Label: + case LineTy_Cmp_Label: + case LineTy_Mov16_Reg_Label: + case LineTy_Mov16_Reg_MemLabel: + case LineTy_Mov16_MemLabel_Reg: + case LineTy_Call_Label: + case LineTy_Lit_Label: { + fprintf(stderr, "error: labels not supported %d\n", line->ty); + break; + } + case LineTy_DataImm: { + out[ip++] = line->op1.imm; + break; + } + case LineTy_Nop: { + out[ip++] = Op_Nop; + break; + } + case LineTy_Hlt: { + out[ip++] = Op_Hlt; + break; + } + case LineTy_Jmp_Reg: { + uint16_t op1 = line->op1.reg; + + uint32_t ins = Op_Jmp; + add_op1_reg(&ins, op1); + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_Jmp_Imm: { + uint16_t op1 = line->op1.imm; + + uint32_t ins = Op_Jmp; + set_is_imm(&ins); + out[ip++] = (uint16_t)ins; + out[ip++] = op1; + break; + } + case LineTy_JmpFar_Reg_Reg: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Jmp; + ins |= 1 << 7; + add_op1_reg(&ins, op1); + add_op2_reg(&ins, op2); + + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_JmpFar_Reg_Imm: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Jmp; + ins |= 1 << 7; + ins |= 1 << 8; + add_op1_reg(&ins, op1); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; + } + case LineTy_JmpFar_Imm_Reg: { + uint16_t op1 = line->op1.imm; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Jmp; + ins |= 1 << 7; + set_is_imm(&ins); + add_op2_reg(&ins, op2); + + out[ip++] = (uint16_t)ins; + out[ip++] = op1; + break; + } + case LineTy_JmpFar_Imm_Imm: { + uint16_t op1 = line->op1.imm; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Jmp; + ins |= 1 << 7; + ins |= 1 << 8; + set_is_imm(&ins); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + out[ip++] = op1; + break; + } + case LineTy_Jnz_Reg: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Jnz; + add_op1_reg(&ins, op1); + add_op2_reg(&ins, op2); + + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_Jnz_Imm: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Jnz; + set_is_imm(&ins); + add_op1_reg(&ins, op1); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; + } + case LineTy_Cmp_Reg: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Cmp; + add_op1_reg(&ins, op1); + add_op2_reg(&ins, op2); + + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_Cmp_Imm: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Cmp; + set_is_imm(&ins); + add_op1_reg(&ins, op1); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; + } + case LineTy_Mov8_Reg_Reg: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Mov8; + ins |= (op2 & 0xfu) << 7; + ins |= (dst & 0xfu) << 12; + + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_Mov8_Reg_Imm: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Mov8; + set_is_imm(&ins); + ins |= (dst & 0xfu) << 12; + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; + } + case LineTy_Mov8_Reg_MemReg: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Mov8; + add_op2_reg(&ins, op2); + set_mov_is_memory(&ins); + set_mov_addr_is_reg(&ins); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + out[ip++] = line->offset; + break; + } + case LineTy_Mov8_Reg_MemImm: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Mov8; + set_is_imm(&ins); + set_mov_is_memory(&ins); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; + } + case LineTy_Mov8_MemReg_Reg: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Mov8; + add_op2_reg(&ins, op2); + set_mov_is_memory(&ins); + set_mov_addr_is_reg(&ins); + set_mov_is_store(&ins); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + out[ip++] = line->offset; + break; + } + case LineTy_Mov8_MemReg_Imm: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Mov8; + set_is_imm(&ins); + set_mov_is_memory(&ins); + set_mov_addr_is_reg(&ins); + set_mov_is_store(&ins); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + out[ip++] = line->offset; + out[ip++] = op2; + break; + } + case LineTy_Mov8_MemImm_Reg: { + uint16_t dst = line->dst.imm; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Mov8; + add_op2_reg(&ins, op2); + set_mov_is_memory(&ins); + set_mov_is_store(&ins); + + out[ip++] = (uint16_t)ins; + out[ip++] = dst; + break; + } + case LineTy_Mov8_MemImm_Imm: { + uint16_t dst = line->dst.imm; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Mov8; + set_is_imm(&ins); + set_mov_is_memory(&ins); + set_mov_is_store(&ins); + + out[ip++] = (uint16_t)ins; + out[ip++] = dst; + out[ip++] = op2; + break; + } + case LineTy_Mov16_Reg_Reg: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Mov16; + ins |= (op2 & 0xfu) << 7; + ins |= (dst & 0xfu) << 12; + + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_Mov16_Reg_Imm: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Mov16; + set_is_imm(&ins); + ins |= (dst & 0xfu) << 12; + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; + } + case LineTy_Mov16_Reg_MemReg: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Mov16; + add_op2_reg(&ins, op2); + set_mov_is_memory(&ins); + set_mov_addr_is_reg(&ins); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + out[ip++] = line->offset; + break; + } + case LineTy_Mov16_Reg_MemImm: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Mov16; + set_is_imm(&ins); + set_mov_is_memory(&ins); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; + } + case LineTy_Mov16_MemReg_Reg: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Mov16; + add_op2_reg(&ins, op2); + set_mov_is_memory(&ins); + set_mov_addr_is_reg(&ins); + set_mov_is_store(&ins); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + out[ip++] = line->offset; + break; + } + case LineTy_Mov16_MemReg_Imm: { + uint16_t dst = line->dst.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Mov16; + set_is_imm(&ins); + set_mov_is_memory(&ins); + set_mov_addr_is_reg(&ins); + set_mov_is_store(&ins); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + out[ip++] = line->offset; + out[ip++] = op2; + break; + } + case LineTy_Mov16_MemImm_Reg: { + uint16_t dst = line->dst.imm; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Mov16; + add_op2_reg(&ins, op2); + set_mov_is_memory(&ins); + set_mov_is_store(&ins); + + out[ip++] = (uint16_t)ins; + out[ip++] = dst; + break; + } + case LineTy_Mov16_MemImm_Imm: { + uint16_t dst = line->dst.imm; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Mov16; + set_is_imm(&ins); + set_mov_is_memory(&ins); + set_mov_is_store(&ins); + + out[ip++] = (uint16_t)ins; + out[ip++] = dst; + out[ip++] = op2; + break; + } + case LineTy_In_Reg: { + uint16_t dst = line->dst.reg; + uint16_t op1 = line->op1.reg; + + uint32_t ins = Op_In; + add_op1_reg(&ins, op1); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_In_Imm: { + uint16_t dst = line->dst.reg; + uint16_t op1 = line->op1.imm; + + uint32_t ins = Op_In; + set_is_imm(&ins); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + out[ip++] = op1; + break; + } + case LineTy_Call_Reg: { + uint16_t op1 = line->op1.reg; + + uint32_t ins = Op_Call; + add_op1_reg(&ins, op1); + + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_Call_Imm: { + uint16_t op1 = line->op1.imm; + + uint32_t ins = Op_Call; + set_is_imm(&ins); + + out[ip++] = (uint16_t)ins; + out[ip++] = op1; + break; + } + case LineTy_CallFar_Reg_Reg: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Jmp; + ins |= 1 << 13; + add_op1_reg(&ins, op1); + ins |= (op2 << 7) & 0x7; + + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_CallFar_Reg_Imm: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Jmp; + ins |= 1 << 13; + ins |= 1 << 14; + add_op1_reg(&ins, op1); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; + } + case LineTy_CallFar_Imm_Reg: { + uint16_t op1 = line->op1.imm; + uint16_t op2 = line->op2.reg; + + uint32_t ins = Op_Jmp; + ins |= 1 << 13; + set_is_imm(&ins); + ins |= (op2 << 7) & 0x7; + + out[ip++] = (uint16_t)ins; + out[ip++] = op1; + break; + } + case LineTy_CallFar_Imm_Imm: { + uint16_t op1 = line->op1.imm; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Jmp; + ins |= 1 << 13; + ins |= 1 << 14; + set_is_imm(&ins); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + out[ip++] = op1; + break; + } + case LineTy_Ret: { + uint32_t ins = Op_Ret; + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_RetFar: { + uint32_t ins = Op_Ret; + ins |= 1 << 6; + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_Lit_Reg: { + uint16_t op1 = line->op1.reg; + + uint32_t ins = Op_Lit; + add_op1_reg(&ins, op1); + + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_Lit_Imm: { + uint16_t op1 = line->op1.imm; + + uint32_t ins = Op_Lit; + set_is_imm(&ins); + + out[ip++] = (uint16_t)ins; + out[ip++] = op1; + break; + } + case LineTy_Int: { + uint16_t int_id = line->op1.imm & 0xff; + + uint32_t ins = Op_Int; + ins |= (uint16_t)(int_id << 8); + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_IRet: { + uint32_t ins = Op_Ret; + ins |= 1 << 6; + out[ip++] = (uint16_t)ins; + break; + } + case LineTy_Or_Imm: + case LineTy_Xor_Imm: + case LineTy_And_Imm: + case LineTy_Shl_Imm: + case LineTy_RShl_Imm: + case LineTy_Shr_Imm: + case LineTy_RShr_Imm: + case LineTy_Add_Imm: + case LineTy_Sub_Imm: + case LineTy_RSub_Imm: + case LineTy_Mul_Imm: + case LineTy_IMul_Imm: + case LineTy_Div_Imm: + case LineTy_IDiv_Imm: + case LineTy_RDiv_Imm: + case LineTy_RIDiv_Imm: + case LineTy_Mod_Imm: + case LineTy_RMod_Imm: { + uint16_t dst = line->dst.reg; + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = linety_arithm_ins(line->ty); + set_is_imm(&ins); + add_op1_reg(&ins, op1); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; + } + case LineTy_Or_Reg: + case LineTy_Xor_Reg: + case LineTy_And_Reg: + case LineTy_Shl_Reg: + case LineTy_RShl_Reg: + case LineTy_Shr_Reg: + case LineTy_RShr_Reg: + case LineTy_Add_Reg: + case LineTy_Sub_Reg: + case LineTy_RSub_Reg: + case LineTy_Mul_Reg: + case LineTy_IMul_Reg: + case LineTy_Div_Reg: + case LineTy_IDiv_Reg: + case LineTy_RDiv_Reg: + case LineTy_RIDiv_Reg: + case LineTy_Mod_Reg: + case LineTy_RMod_Reg: { + uint16_t dst = line->dst.reg; + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.reg; + + uint32_t ins = linety_arithm_ins(line->ty); + add_op2_reg(&ins, op2); + add_op1_reg(&ins, op1); + add_dst_reg(&ins, dst); + + out[ip++] = (uint16_t)ins; + break; + } + } + return ip; +} + +uint16_t assemble_lines_with_labels( + uint16_t* out, const Line* lines, size_t lines_size) { const bool debug = false; @@ -64,7 +629,7 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) break; } case LineTy_DataImm: { - out[ip++] = line->op1.imm; + ip += assemble_line(&out[ip], line); is_data = true; break; @@ -75,31 +640,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) is_data = true; break; } - case LineTy_Nop: { - out[ip++] = Op_Nop; - break; - } - case LineTy_Hlt: { - out[ip++] = Op_Hlt; - break; - } - case LineTy_Jmp_Reg: { - uint16_t op1 = line->op1.reg; - - uint32_t ins = Op_Jmp; - add_op1_reg(&ins, op1); - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_Jmp_Imm: { - uint16_t op1 = line->op1.imm; - - uint32_t ins = Op_Jmp; - set_is_imm(&ins); - out[ip++] = (uint16_t)ins; - out[ip++] = op1; - break; - } case LineTy_Jmp_Label: { int op1 = line->op1.label; @@ -109,81 +649,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) ADD_LABEL(op1); break; } - case LineTy_JmpFar_Reg_Reg: { - uint16_t op1 = line->op1.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Jmp; - ins |= 1 << 7; - add_op1_reg(&ins, op1); - add_op2_reg(&ins, op2); - - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_JmpFar_Reg_Imm: { - uint16_t op1 = line->op1.reg; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Jmp; - ins |= 1 << 7; - ins |= 1 << 8; - add_op1_reg(&ins, op1); - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - break; - } - case LineTy_JmpFar_Imm_Reg: { - uint16_t op1 = line->op1.imm; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Jmp; - ins |= 1 << 7; - set_is_imm(&ins); - add_op2_reg(&ins, op2); - - out[ip++] = (uint16_t)ins; - out[ip++] = op1; - break; - } - case LineTy_JmpFar_Imm_Imm: { - uint16_t op1 = line->op1.imm; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Jmp; - ins |= 1 << 7; - ins |= 1 << 8; - set_is_imm(&ins); - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - out[ip++] = op1; - break; - } - case LineTy_Jnz_Reg: { - uint16_t op1 = line->op1.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Jnz; - add_op1_reg(&ins, op1); - add_op2_reg(&ins, op2); - - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_Jnz_Imm: { - uint16_t op1 = line->op1.reg; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Jnz; - set_is_imm(&ins); - add_op1_reg(&ins, op1); - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - break; - } case LineTy_Jnz_Label: { uint16_t op1 = line->op1.reg; int op2 = line->op2.label; @@ -196,29 +661,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) ADD_LABEL(op2); break; } - case LineTy_Cmp_Reg: { - uint16_t op1 = line->op1.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Cmp; - add_op1_reg(&ins, op1); - add_op2_reg(&ins, op2); - - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_Cmp_Imm: { - uint16_t op1 = line->op1.reg; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Cmp; - set_is_imm(&ins); - add_op1_reg(&ins, op1); - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - break; - } case LineTy_Cmp_Label: { uint16_t op1 = line->op1.reg; int op2 = line->op2.label; @@ -231,137 +673,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) ADD_LABEL(op2); break; } - case LineTy_Mov8_Reg_Reg: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Mov8; - ins |= (op2 & 0xfu) << 7; - ins |= (dst & 0xfu) << 12; - - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_Mov8_Reg_Imm: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Mov8; - set_is_imm(&ins); - ins |= (dst & 0xfu) << 12; - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - break; - } - case LineTy_Mov8_Reg_MemReg: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Mov8; - add_op2_reg(&ins, op2); - set_mov_is_memory(&ins); - set_mov_addr_is_reg(&ins); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - out[ip++] = line->offset; - break; - } - case LineTy_Mov8_Reg_MemImm: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Mov8; - set_is_imm(&ins); - set_mov_is_memory(&ins); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - break; - } - case LineTy_Mov8_MemReg_Reg: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Mov8; - add_op2_reg(&ins, op2); - set_mov_is_memory(&ins); - set_mov_addr_is_reg(&ins); - set_mov_is_store(&ins); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - out[ip++] = line->offset; - break; - } - case LineTy_Mov8_MemReg_Imm: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Mov8; - set_is_imm(&ins); - set_mov_is_memory(&ins); - set_mov_addr_is_reg(&ins); - set_mov_is_store(&ins); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - out[ip++] = line->offset; - out[ip++] = op2; - break; - } - case LineTy_Mov8_MemImm_Reg: { - uint16_t dst = line->dst.imm; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Mov8; - add_op2_reg(&ins, op2); - set_mov_is_memory(&ins); - set_mov_is_store(&ins); - - out[ip++] = (uint16_t)ins; - out[ip++] = dst; - break; - } - case LineTy_Mov8_MemImm_Imm: { - uint16_t dst = line->dst.imm; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Mov8; - set_is_imm(&ins); - set_mov_is_memory(&ins); - set_mov_is_store(&ins); - - out[ip++] = (uint16_t)ins; - out[ip++] = dst; - out[ip++] = op2; - break; - } - case LineTy_Mov16_Reg_Reg: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Mov16; - ins |= (op2 & 0xfu) << 7; - ins |= (dst & 0xfu) << 12; - - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_Mov16_Reg_Imm: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Mov16; - set_is_imm(&ins); - ins |= (dst & 0xfu) << 12; - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - break; - } case LineTy_Mov16_Reg_Label: { uint16_t dst = line->dst.reg; int op2 = line->op2.label; @@ -374,33 +685,7 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) ADD_LABEL(op2); break; } - case LineTy_Mov16_Reg_MemReg: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.reg; - uint32_t ins = Op_Mov16; - add_op2_reg(&ins, op2); - set_mov_is_memory(&ins); - set_mov_addr_is_reg(&ins); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - out[ip++] = line->offset; - break; - } - case LineTy_Mov16_Reg_MemImm: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Mov16; - set_is_imm(&ins); - set_mov_is_memory(&ins); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - break; - } case LineTy_Mov16_Reg_MemLabel: { uint16_t dst = line->dst.reg; @@ -413,64 +698,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) ADD_LABEL(line->op2.label); break; } - case LineTy_Mov16_MemReg_Reg: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Mov16; - add_op2_reg(&ins, op2); - set_mov_is_memory(&ins); - set_mov_addr_is_reg(&ins); - set_mov_is_store(&ins); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - out[ip++] = line->offset; - break; - } - case LineTy_Mov16_MemReg_Imm: { - uint16_t dst = line->dst.reg; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Mov16; - set_is_imm(&ins); - set_mov_is_memory(&ins); - set_mov_addr_is_reg(&ins); - set_mov_is_store(&ins); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - out[ip++] = line->offset; - out[ip++] = op2; - break; - } - case LineTy_Mov16_MemImm_Reg: { - uint16_t dst = line->dst.imm; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Mov16; - add_op2_reg(&ins, op2); - set_mov_is_memory(&ins); - set_mov_is_store(&ins); - - out[ip++] = (uint16_t)ins; - out[ip++] = dst; - break; - } - case LineTy_Mov16_MemImm_Imm: { - uint16_t dst = line->dst.imm; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Mov16; - set_is_imm(&ins); - set_mov_is_memory(&ins); - set_mov_is_store(&ins); - - out[ip++] = (uint16_t)ins; - out[ip++] = dst; - out[ip++] = op2; - break; - } case LineTy_Mov16_MemLabel_Reg: { int dst = line->dst.label; uint16_t op2 = line->op2.reg; @@ -484,48 +711,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) ADD_LABEL(dst); break; } - case LineTy_In_Reg: { - uint16_t dst = line->dst.reg; - uint16_t op1 = line->op1.reg; - - uint32_t ins = Op_In; - add_op1_reg(&ins, op1); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_In_Imm: { - uint16_t dst = line->dst.reg; - uint16_t op1 = line->op1.imm; - - uint32_t ins = Op_In; - set_is_imm(&ins); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - out[ip++] = op1; - break; - } - case LineTy_Call_Reg: { - uint16_t op1 = line->op1.reg; - - uint32_t ins = Op_Call; - add_op1_reg(&ins, op1); - - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_Call_Imm: { - uint16_t op1 = line->op1.imm; - - uint32_t ins = Op_Call; - set_is_imm(&ins); - - out[ip++] = (uint16_t)ins; - out[ip++] = op1; - break; - } case LineTy_Call_Label: { int op1 = line->op1.label; @@ -536,88 +721,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) ADD_LABEL(op1); break; } - case LineTy_CallFar_Reg_Reg: { - uint16_t op1 = line->op1.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Jmp; - ins |= 1 << 13; - add_op1_reg(&ins, op1); - ins |= (op2 << 7) & 0x7; - - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_CallFar_Reg_Imm: { - uint16_t op1 = line->op1.reg; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Jmp; - ins |= 1 << 13; - ins |= 1 << 14; - add_op1_reg(&ins, op1); - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - break; - } - case LineTy_CallFar_Imm_Reg: { - uint16_t op1 = line->op1.imm; - uint16_t op2 = line->op2.reg; - - uint32_t ins = Op_Jmp; - ins |= 1 << 13; - set_is_imm(&ins); - ins |= (op2 << 7) & 0x7; - - out[ip++] = (uint16_t)ins; - out[ip++] = op1; - break; - } - case LineTy_CallFar_Imm_Imm: { - uint16_t op1 = line->op1.imm; - uint16_t op2 = line->op2.imm; - - uint32_t ins = Op_Jmp; - ins |= 1 << 13; - ins |= 1 << 14; - set_is_imm(&ins); - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - out[ip++] = op1; - break; - } - case LineTy_Ret: { - uint32_t ins = Op_Ret; - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_RetFar: { - uint32_t ins = Op_Ret; - ins |= 1 << 6; - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_Lit_Reg: { - uint16_t op1 = line->op1.reg; - - uint32_t ins = Op_Lit; - add_op1_reg(&ins, op1); - - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_Lit_Imm: { - uint16_t op1 = line->op1.imm; - - uint32_t ins = Op_Lit; - set_is_imm(&ins); - - out[ip++] = (uint16_t)ins; - out[ip++] = op1; - break; - } case LineTy_Lit_Label: { int op1 = line->op1.label; @@ -628,79 +731,8 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) ADD_LABEL(op1); break; } - case LineTy_Int: { - uint16_t int_id = line->op1.imm & 0xff; - - uint32_t ins = Op_Int; - ins |= (uint16_t)(int_id << 8); - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_IRet: { - uint32_t ins = Op_Ret; - ins |= 1 << 6; - out[ip++] = (uint16_t)ins; - break; - } - case LineTy_Or_Imm: - case LineTy_Xor_Imm: - case LineTy_And_Imm: - case LineTy_Shl_Imm: - case LineTy_RShl_Imm: - case LineTy_Shr_Imm: - case LineTy_RShr_Imm: - case LineTy_Add_Imm: - case LineTy_Sub_Imm: - case LineTy_RSub_Imm: - case LineTy_Mul_Imm: - case LineTy_IMul_Imm: - case LineTy_Div_Imm: - case LineTy_IDiv_Imm: - case LineTy_RDiv_Imm: - case LineTy_RIDiv_Imm: - case LineTy_Mod_Imm: - case LineTy_RMod_Imm: { - uint16_t dst = line->dst.reg; - uint16_t op1 = line->op1.reg; - uint16_t op2 = line->op2.imm; - - uint32_t ins = linety_arithm_ins(line->ty); - set_is_imm(&ins); - add_op1_reg(&ins, op1); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; - out[ip++] = op2; - break; - } - case LineTy_Or_Reg: - case LineTy_Xor_Reg: - case LineTy_And_Reg: - case LineTy_Shl_Reg: - case LineTy_RShl_Reg: - case LineTy_Shr_Reg: - case LineTy_RShr_Reg: - case LineTy_Add_Reg: - case LineTy_Sub_Reg: - case LineTy_RSub_Reg: - case LineTy_Mul_Reg: - case LineTy_IMul_Reg: - case LineTy_Div_Reg: - case LineTy_IDiv_Reg: - case LineTy_RDiv_Reg: - case LineTy_RIDiv_Reg: - case LineTy_Mod_Reg: - case LineTy_RMod_Reg: { - uint16_t dst = line->dst.reg; - uint16_t op1 = line->op1.reg; - uint16_t op2 = line->op2.reg; - - uint32_t ins = linety_arithm_ins(line->ty); - add_op2_reg(&ins, op2); - add_op1_reg(&ins, op1); - add_dst_reg(&ins, dst); - - out[ip++] = (uint16_t)ins; + default: { + ip += assemble_line(&out[ip], line); break; } } diff --git a/asm/asm.h b/asm/asm.h index b3990ea..5b516b2 100644 --- a/asm/asm.h +++ b/asm/asm.h @@ -114,7 +114,7 @@ typedef struct { uint16_t offset; } Line; -uint16_t assemble_to_binary( +uint16_t assemble_lines_with_labels( uint16_t* out, const Line* lines, size_t lines_size); Line s_label(int label); diff --git a/asm/ctors.c b/asm/ctors.c index 6d88504..399888e 100644 --- a/asm/ctors.c +++ b/asm/ctors.c @@ -105,6 +105,7 @@ Line s_jnz_l(Reg op1_reg, int op2_label) { return (Line) { .ty = LineTy_Jnz_Label, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, .op2 = (Ex) { .label = op2_label }, }; } diff --git a/compile_flags.txt b/compile_flags.txt index ea92534..e7d8f39 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -7,7 +7,7 @@ -pedantic -pedantic-errors -Wno-unused-variable --Wno-unused-parameter +# -Wno-unused-parameter # -Wno-unused-function -I. diff --git a/kern/main.c b/kern/main.c index e0eb8bc..ece9893 100644 --- a/kern/main.c +++ b/kern/main.c @@ -203,7 +203,7 @@ void write_program(FILE* fp) printf("assembling program...\n"); uint16_t program_size - = assemble_to_binary(program, program_asm, program_asm_size); + = assemble_lines_with_labels(program, program_asm, program_asm_size); printf("done!\n"); printf("program size = %d\n", program_size); diff --git a/vm/vm.c b/vm/vm.c index 7812399..aca8c0c 100644 --- a/vm/vm.c +++ b/vm/vm.c @@ -1,5 +1,6 @@ #include "vm.h" #include "common/arch.h" +#include "common/op_str.h" #include #include #include