all arithm ops

This commit is contained in:
sfja 2025-03-31 21:30:21 +02:00
parent feb6e29903
commit 356719720e
2 changed files with 439 additions and 38 deletions

424
asm/asm.c
View File

@ -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);

View File

@ -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)