diff --git a/asm/asm.c b/asm/asm.c index 9368905..4f4cfc1 100644 --- a/asm/asm.c +++ b/asm/asm.c @@ -1,4 +1,5 @@ #include "asm.h" +#include "common/arch.h" #include "common/op_str.h" #include #include @@ -107,6 +108,58 @@ 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; diff --git a/asm/asm.h b/asm/asm.h index fef500e..b00f642 100644 --- a/asm/asm.h +++ b/asm/asm.h @@ -13,6 +13,10 @@ typedef enum { LineTy_Jmp_Reg, LineTy_Jmp_Imm, LineTy_Jmp_Label, + LineTy_JmpFar_Reg_Reg, + LineTy_JmpFar_Reg_Imm, + LineTy_JmpFar_Imm_Reg, + LineTy_JmpFar_Imm_Imm, LineTy_Jnz_Reg, LineTy_Jnz_Imm, LineTy_Jnz_Label, @@ -116,6 +120,10 @@ Line s_hlt(void); Line s_jmp_r(Reg op1_reg); Line s_jmp_i(uint16_t op1_imm); Line s_jmp_l(int op1_label); +Line s_jmpf_r_r(Reg op1_reg, Reg op2_reg); +Line s_jmpf_r_i(Reg op1_reg, uint16_t op2_imm); +Line s_jmpf_i_r(uint16_t op1_imm, Reg op2_reg); +Line s_jmpf_i_i(uint16_t op1_imm, uint16_t op2_imm); Line s_jnz_r(Reg op1_reg, Reg op2_reg); Line s_jnz_i(Reg op1_reg, uint16_t op2_imm); Line s_jnz_l(Reg op1_reg, int op2_label); diff --git a/asm/ctors.c b/asm/ctors.c index 69c0b87..939ad1e 100644 --- a/asm/ctors.c +++ b/asm/ctors.c @@ -53,10 +53,43 @@ Line s_jmp_l(int op1_label) .op1 = (Ex) { .label = op1_label }, }; } +Line s_jmpf_r_r(Reg op1_reg, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_JmpFar_Reg_Reg, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_jmpf_r_i(Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_JmpFar_Reg_Imm, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} +Line s_jmpf_i_r(uint16_t op1_imm, Reg op2_reg) +{ + return (Line) { + .ty = LineTy_JmpFar_Imm_Reg, + .op1 = (Ex) { .imm = op1_imm }, + .op2 = (Ex) { .reg = (uint16_t)op2_reg }, + }; +} +Line s_jmpf_i_i(uint16_t op1_imm, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_JmpFar_Imm_Imm, + .op1 = (Ex) { .imm = op1_imm }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} Line s_jnz_r(Reg op1_reg, Reg op2_reg) { return (Line) { .ty = LineTy_Jnz_Reg, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, .op2 = (Ex) { .reg = (uint16_t)op2_reg }, }; } @@ -64,6 +97,7 @@ Line s_jnz_i(Reg op1_reg, uint16_t op2_imm) { return (Line) { .ty = LineTy_Jnz_Imm, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, .op2 = (Ex) { .imm = op2_imm }, }; }