From 356719720e8669231d9bf82f7491456bc3073e1a Mon Sep 17 00:00:00 2001 From: sfja Date: Mon, 31 Mar 2025 21:30:21 +0200 Subject: [PATCH] all arithm ops --- asm/asm.c | 424 +++++++++++++++++++++++++++++++++++++++++++++++++----- asm/asm.h | 53 +++++++ 2 files changed, 439 insertions(+), 38 deletions(-) diff --git a/asm/asm.c b/asm/asm.c index d19c45b..91371ba 100644 --- a/asm/asm.c +++ b/asm/asm.c @@ -192,42 +192,330 @@ Line s_iret(void) { return (Line) { .ty = LineTy_IRet }; } - -#define DEFINE_BINARY_I(FN, LINETY) \ - Line s_##FN##_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) \ - { \ - return (Line) { \ - .ty = LineTy_##LINETY##_Imm, \ - .dst = (Ex) { .reg = (uint16_t)dst_reg }, \ - .op1 = (Ex) { .reg = (uint16_t)op1_reg }, \ - .op2 = (Ex) { .imm = op2_imm }, \ - }; \ - } - -DEFINE_BINARY_I(or, Or) -DEFINE_BINARY_I(xor, Xor) -DEFINE_BINARY_I(and, And) -DEFINE_BINARY_I(add, Add) -DEFINE_BINARY_I(sub, Sub) -DEFINE_BINARY_I(mul, Mul) - -#define DEFINE_BINARY_R(FN, LINETY) \ - Line s_##FN##_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) \ - { \ - return (Line) { \ - .ty = LineTy_##LINETY##_Reg, \ - .dst = (Ex) { .reg = (uint16_t)dst_reg }, \ - .op1 = (Ex) { .reg = (uint16_t)op1_reg }, \ - .op2 = (Ex) { .reg = (uint16_t)op2_reg }, \ - }; \ - } - -DEFINE_BINARY_R(or, Or) -DEFINE_BINARY_R(xor, Xor) -DEFINE_BINARY_R(and, And) -DEFINE_BINARY_R(add, Add) -DEFINE_BINARY_R(sub, Sub) -DEFINE_BINARY_R(mul, Mul) +Line s_or_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_Or_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_xor_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_Xor_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_and_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_And_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_shl_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_Shl_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_rshl_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_RShl_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_shr_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_Shr_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_rshr_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_RShr_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_add_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_Add_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_sub_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_Sub_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_rsub_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_RSub_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_mul_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_Mul_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_imul_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_IMul_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_div_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_Div_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_idiv_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_IDiv_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_rdiv_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_RDiv_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_ridiv_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_RIDiv_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_mod_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_Mod_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_rmod_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_RMod_Imm, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_or_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_Or_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_xor_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_Xor_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_and_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_And_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_shl_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_Shl_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_rshl_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_RShl_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_shr_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_Shr_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_rshr_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_RShr_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_add_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_Add_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_sub_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_Sub_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_rsub_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_RSub_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_mul_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_Mul_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_imul_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_IMul_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_div_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_Div_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_idiv_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_IDiv_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_rdiv_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_RDiv_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_ridiv_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_RIDiv_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_mod_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_Mod_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_rmod_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_RMod_Reg, + .dst = (Ex) { .reg = (uint16_t)dst_reg }, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} static inline void add_dst_reg(uint32_t* ins, uint16_t reg); static inline void add_op1_reg(uint32_t* ins, uint16_t reg); @@ -543,9 +831,21 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) 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_Mul_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; @@ -562,9 +862,21 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) 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_Mul_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; @@ -680,15 +992,51 @@ static inline uint16_t linety_arithm_ins(LineTy ty) case LineTy_And_Imm: case LineTy_And_Reg: return Op_And; + case LineTy_Shl_Imm: + case LineTy_Shl_Reg: + return Op_Shl; + case LineTy_RShl_Imm: + case LineTy_RShl_Reg: + return Op_RShl; + case LineTy_Shr_Imm: + case LineTy_Shr_Reg: + return Op_Shr; + case LineTy_RShr_Imm: + case LineTy_RShr_Reg: + return Op_RShr; case LineTy_Add_Imm: case LineTy_Add_Reg: return Op_Add; case LineTy_Sub_Imm: case LineTy_Sub_Reg: return Op_Sub; + case LineTy_RSub_Imm: + case LineTy_RSub_Reg: + return Op_RSub; case LineTy_Mul_Imm: case LineTy_Mul_Reg: return Op_Mul; + case LineTy_IMul_Imm: + case LineTy_IMul_Reg: + return Op_IMul; + case LineTy_Div_Imm: + case LineTy_Div_Reg: + return Op_Div; + case LineTy_IDiv_Imm: + case LineTy_IDiv_Reg: + return Op_IDiv; + case LineTy_RDiv_Imm: + case LineTy_RDiv_Reg: + return Op_RDiv; + case LineTy_RIDiv_Imm: + case LineTy_RIDiv_Reg: + return Op_RIDiv; + case LineTy_Mod_Imm: + case LineTy_Mod_Reg: + return Op_Mod; + case LineTy_RMod_Imm: + case LineTy_RMod_Reg: + return Op_RMod; default: fprintf(stderr, "error: line type '%d' not handled\n", ty); exit(1); diff --git a/asm/asm.h b/asm/asm.h index 64a999f..dddfc89 100644 --- a/asm/asm.h +++ b/asm/asm.h @@ -31,18 +31,45 @@ typedef enum { LineTy_Lit_Label, LineTy_Int, LineTy_IRet, + LineTy_Or_Imm, LineTy_Xor_Imm, LineTy_And_Imm, + LineTy_Shl_Imm, + LineTy_RShl_Imm, + LineTy_Shr_Imm, + LineTy_RShr_Imm, LineTy_Add_Imm, LineTy_Sub_Imm, + LineTy_RSub_Imm, LineTy_Mul_Imm, + LineTy_IMul_Imm, + LineTy_Div_Imm, + LineTy_IDiv_Imm, + LineTy_RDiv_Imm, + LineTy_RIDiv_Imm, + LineTy_Mod_Imm, + LineTy_RMod_Imm, + LineTy_Or_Reg, LineTy_Xor_Reg, LineTy_And_Reg, + LineTy_Shl_Reg, + LineTy_RShl_Reg, + LineTy_Shr_Reg, + LineTy_RShr_Reg, LineTy_Add_Reg, LineTy_Sub_Reg, + LineTy_RSub_Reg, LineTy_Mul_Reg, + LineTy_IMul_Reg, + LineTy_Div_Reg, + LineTy_IDiv_Reg, + LineTy_RDiv_Reg, + LineTy_RIDiv_Reg, + LineTy_Mod_Reg, + LineTy_RMod_Reg, + } LineTy; typedef struct { @@ -89,18 +116,44 @@ Line s_lit_i(uint16_t op1_imm); Line s_lit_l(int op1_label); Line s_int(uint8_t int_id); Line s_iret(void); + Line s_or_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); Line s_xor_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); Line s_and_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_shl_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_rshl_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_shr_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_rshr_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); Line s_add_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); Line s_sub_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_rsub_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); Line s_mul_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_imul_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_div_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_idiv_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_rdiv_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_ridiv_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_mod_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); +Line s_rmod_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm); + Line s_or_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); Line s_xor_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); Line s_and_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_shl_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_rshl_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_shr_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_rshr_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); Line s_add_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); Line s_sub_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_rsub_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); Line s_mul_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_imul_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_div_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_idiv_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_rdiv_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_ridiv_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_mod_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); +Line s_rmod_r(Reg dst_reg, Reg op1_reg, Reg op2_reg); #define s_push_r(REG) s_add_i(Rsp, Rsp, 2), s_mov16_mr_r(Rsp, 0, REG)