extract assembling line
This commit is contained in:
parent
af0214739c
commit
0bdbaa7f1f
1
Makefile
1
Makefile
@ -8,7 +8,6 @@ C_FLAGS = \
|
|||||||
-Wall -Wextra -Wpedantic -Wconversion \
|
-Wall -Wextra -Wpedantic -Wconversion \
|
||||||
-pedantic -pedantic-errors \
|
-pedantic -pedantic-errors \
|
||||||
-Wno-unused-variable \
|
-Wno-unused-variable \
|
||||||
-Wno-unused-parameter \
|
|
||||||
-I. \
|
-I. \
|
||||||
|
|
||||||
L_FLAGS = -pthread
|
L_FLAGS = -pthread
|
||||||
|
308
asm/asm.c
308
asm/asm.c
@ -17,62 +17,26 @@ static inline void set_mov_addr_is_reg(uint32_t* ins);
|
|||||||
static inline void set_mov_is_store(uint32_t* ins);
|
static inline void set_mov_is_store(uint32_t* ins);
|
||||||
static inline uint16_t linety_arithm_ins(LineTy ty);
|
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)
|
||||||
{
|
{
|
||||||
const bool debug = false;
|
|
||||||
|
|
||||||
uint16_t ip = 0;
|
uint16_t ip = 0;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int label;
|
|
||||||
uint16_t ptr;
|
|
||||||
} UnresolvedLabel;
|
|
||||||
typedef struct {
|
|
||||||
int label;
|
|
||||||
uint16_t ip;
|
|
||||||
} ResolvedLabel;
|
|
||||||
|
|
||||||
UnresolvedLabel* unres_labels = malloc(sizeof(UnresolvedLabel) * 64);
|
|
||||||
size_t unres_labels_size = 0;
|
|
||||||
|
|
||||||
ResolvedLabel* res_labels = malloc(sizeof(ResolvedLabel) * 64);
|
|
||||||
size_t res_labels_size = 0;
|
|
||||||
|
|
||||||
#define ADD_LABEL(LABEL) \
|
|
||||||
{ \
|
|
||||||
unres_labels[unres_labels_size++] = (UnresolvedLabel) { LABEL, ip }; \
|
|
||||||
out[ip++] = 0; \
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
printf("assembling...\n");
|
|
||||||
printf("ip op n data...\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < lines_size; ++i) {
|
|
||||||
bool is_label = false;
|
|
||||||
bool is_data = false;
|
|
||||||
|
|
||||||
const Line* line = &lines[i];
|
|
||||||
uint16_t ins_ip = ip;
|
|
||||||
switch (line->ty) {
|
switch (line->ty) {
|
||||||
case LineTy_Label: {
|
case LineTy_Label:
|
||||||
res_labels[res_labels_size++]
|
case LineTy_DataLabel:
|
||||||
= (ResolvedLabel) { line->op1.label, ip * 2 };
|
case LineTy_Jmp_Label:
|
||||||
|
case LineTy_Jnz_Label:
|
||||||
is_label = true;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_DataImm: {
|
case LineTy_DataImm: {
|
||||||
out[ip++] = line->op1.imm;
|
out[ip++] = line->op1.imm;
|
||||||
|
|
||||||
is_data = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LineTy_DataLabel: {
|
|
||||||
ADD_LABEL(line->op1.label);
|
|
||||||
|
|
||||||
is_data = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_Nop: {
|
case LineTy_Nop: {
|
||||||
@ -100,15 +64,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
out[ip++] = op1;
|
out[ip++] = op1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_Jmp_Label: {
|
|
||||||
int op1 = line->op1.label;
|
|
||||||
|
|
||||||
uint32_t ins = Op_Jmp;
|
|
||||||
set_is_imm(&ins);
|
|
||||||
out[ip++] = (uint16_t)ins;
|
|
||||||
ADD_LABEL(op1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LineTy_JmpFar_Reg_Reg: {
|
case LineTy_JmpFar_Reg_Reg: {
|
||||||
uint16_t op1 = line->op1.reg;
|
uint16_t op1 = line->op1.reg;
|
||||||
uint16_t op2 = line->op2.reg;
|
uint16_t op2 = line->op2.reg;
|
||||||
@ -184,18 +139,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
out[ip++] = op2;
|
out[ip++] = op2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_Jnz_Label: {
|
|
||||||
uint16_t op1 = line->op1.reg;
|
|
||||||
int op2 = line->op2.label;
|
|
||||||
|
|
||||||
uint32_t ins = Op_Jnz;
|
|
||||||
set_is_imm(&ins);
|
|
||||||
add_op1_reg(&ins, op1);
|
|
||||||
|
|
||||||
out[ip++] = (uint16_t)ins;
|
|
||||||
ADD_LABEL(op2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LineTy_Cmp_Reg: {
|
case LineTy_Cmp_Reg: {
|
||||||
uint16_t op1 = line->op1.reg;
|
uint16_t op1 = line->op1.reg;
|
||||||
uint16_t op2 = line->op2.reg;
|
uint16_t op2 = line->op2.reg;
|
||||||
@ -219,18 +162,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
out[ip++] = op2;
|
out[ip++] = op2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_Cmp_Label: {
|
|
||||||
uint16_t op1 = line->op1.reg;
|
|
||||||
int op2 = line->op2.label;
|
|
||||||
|
|
||||||
uint32_t ins = Op_Cmp;
|
|
||||||
set_is_imm(&ins);
|
|
||||||
add_op1_reg(&ins, op1);
|
|
||||||
|
|
||||||
out[ip++] = (uint16_t)ins;
|
|
||||||
ADD_LABEL(op2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LineTy_Mov8_Reg_Reg: {
|
case LineTy_Mov8_Reg_Reg: {
|
||||||
uint16_t dst = line->dst.reg;
|
uint16_t dst = line->dst.reg;
|
||||||
uint16_t op2 = line->op2.reg;
|
uint16_t op2 = line->op2.reg;
|
||||||
@ -362,18 +293,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
out[ip++] = op2;
|
out[ip++] = op2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_Mov16_Reg_Label: {
|
|
||||||
uint16_t dst = line->dst.reg;
|
|
||||||
int op2 = line->op2.label;
|
|
||||||
|
|
||||||
uint32_t ins = Op_Mov16;
|
|
||||||
set_is_imm(&ins);
|
|
||||||
ins |= (dst & 0xfu) << 12;
|
|
||||||
|
|
||||||
out[ip++] = (uint16_t)ins;
|
|
||||||
ADD_LABEL(op2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LineTy_Mov16_Reg_MemReg: {
|
case LineTy_Mov16_Reg_MemReg: {
|
||||||
uint16_t dst = line->dst.reg;
|
uint16_t dst = line->dst.reg;
|
||||||
uint16_t op2 = line->op2.reg;
|
uint16_t op2 = line->op2.reg;
|
||||||
@ -401,18 +320,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
out[ip++] = op2;
|
out[ip++] = op2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_Mov16_Reg_MemLabel: {
|
|
||||||
uint16_t dst = line->dst.reg;
|
|
||||||
|
|
||||||
uint32_t ins = Op_Mov16;
|
|
||||||
set_is_imm(&ins);
|
|
||||||
set_mov_is_memory(&ins);
|
|
||||||
add_dst_reg(&ins, dst);
|
|
||||||
|
|
||||||
out[ip++] = (uint16_t)ins;
|
|
||||||
ADD_LABEL(line->op2.label);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LineTy_Mov16_MemReg_Reg: {
|
case LineTy_Mov16_MemReg_Reg: {
|
||||||
uint16_t dst = line->dst.reg;
|
uint16_t dst = line->dst.reg;
|
||||||
uint16_t op2 = line->op2.reg;
|
uint16_t op2 = line->op2.reg;
|
||||||
@ -471,19 +378,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
out[ip++] = op2;
|
out[ip++] = op2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_Mov16_MemLabel_Reg: {
|
|
||||||
int dst = line->dst.label;
|
|
||||||
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;
|
|
||||||
ADD_LABEL(dst);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LineTy_In_Reg: {
|
case LineTy_In_Reg: {
|
||||||
uint16_t dst = line->dst.reg;
|
uint16_t dst = line->dst.reg;
|
||||||
uint16_t op1 = line->op1.reg;
|
uint16_t op1 = line->op1.reg;
|
||||||
@ -526,16 +420,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
out[ip++] = op1;
|
out[ip++] = op1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_Call_Label: {
|
|
||||||
int op1 = line->op1.label;
|
|
||||||
|
|
||||||
uint32_t ins = Op_Call;
|
|
||||||
set_is_imm(&ins);
|
|
||||||
|
|
||||||
out[ip++] = (uint16_t)ins;
|
|
||||||
ADD_LABEL(op1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LineTy_CallFar_Reg_Reg: {
|
case LineTy_CallFar_Reg_Reg: {
|
||||||
uint16_t op1 = line->op1.reg;
|
uint16_t op1 = line->op1.reg;
|
||||||
uint16_t op2 = line->op2.reg;
|
uint16_t op2 = line->op2.reg;
|
||||||
@ -618,16 +502,6 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
out[ip++] = op1;
|
out[ip++] = op1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_Lit_Label: {
|
|
||||||
int op1 = line->op1.label;
|
|
||||||
|
|
||||||
uint32_t ins = Op_Lit;
|
|
||||||
set_is_imm(&ins);
|
|
||||||
|
|
||||||
out[ip++] = (uint16_t)ins;
|
|
||||||
ADD_LABEL(op1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LineTy_Int: {
|
case LineTy_Int: {
|
||||||
uint16_t int_id = line->op1.imm & 0xff;
|
uint16_t int_id = line->op1.imm & 0xff;
|
||||||
|
|
||||||
@ -704,6 +578,164 @@ uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t assemble_lines_with_labels(
|
||||||
|
uint16_t* out, const Line* lines, size_t lines_size)
|
||||||
|
{
|
||||||
|
const bool debug = false;
|
||||||
|
|
||||||
|
uint16_t ip = 0;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int label;
|
||||||
|
uint16_t ptr;
|
||||||
|
} UnresolvedLabel;
|
||||||
|
typedef struct {
|
||||||
|
int label;
|
||||||
|
uint16_t ip;
|
||||||
|
} ResolvedLabel;
|
||||||
|
|
||||||
|
UnresolvedLabel* unres_labels = malloc(sizeof(UnresolvedLabel) * 64);
|
||||||
|
size_t unres_labels_size = 0;
|
||||||
|
|
||||||
|
ResolvedLabel* res_labels = malloc(sizeof(ResolvedLabel) * 64);
|
||||||
|
size_t res_labels_size = 0;
|
||||||
|
|
||||||
|
#define ADD_LABEL(LABEL) \
|
||||||
|
{ \
|
||||||
|
unres_labels[unres_labels_size++] = (UnresolvedLabel) { LABEL, ip }; \
|
||||||
|
out[ip++] = 0; \
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
printf("assembling...\n");
|
||||||
|
printf("ip op n data...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < lines_size; ++i) {
|
||||||
|
bool is_label = false;
|
||||||
|
bool is_data = false;
|
||||||
|
|
||||||
|
const Line* line = &lines[i];
|
||||||
|
uint16_t ins_ip = ip;
|
||||||
|
switch (line->ty) {
|
||||||
|
case LineTy_Label: {
|
||||||
|
res_labels[res_labels_size++]
|
||||||
|
= (ResolvedLabel) { line->op1.label, ip * 2 };
|
||||||
|
|
||||||
|
is_label = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LineTy_DataImm: {
|
||||||
|
ip += assemble_line(&out[ip], line);
|
||||||
|
|
||||||
|
is_data = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LineTy_DataLabel: {
|
||||||
|
ADD_LABEL(line->op1.label);
|
||||||
|
|
||||||
|
is_data = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LineTy_Jmp_Label: {
|
||||||
|
int op1 = line->op1.label;
|
||||||
|
|
||||||
|
uint32_t ins = Op_Jmp;
|
||||||
|
set_is_imm(&ins);
|
||||||
|
out[ip++] = (uint16_t)ins;
|
||||||
|
ADD_LABEL(op1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LineTy_Jnz_Label: {
|
||||||
|
uint16_t op1 = line->op1.reg;
|
||||||
|
int op2 = line->op2.label;
|
||||||
|
|
||||||
|
uint32_t ins = Op_Jnz;
|
||||||
|
set_is_imm(&ins);
|
||||||
|
add_op1_reg(&ins, op1);
|
||||||
|
|
||||||
|
out[ip++] = (uint16_t)ins;
|
||||||
|
ADD_LABEL(op2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LineTy_Cmp_Label: {
|
||||||
|
uint16_t op1 = line->op1.reg;
|
||||||
|
int op2 = line->op2.label;
|
||||||
|
|
||||||
|
uint32_t ins = Op_Cmp;
|
||||||
|
set_is_imm(&ins);
|
||||||
|
add_op1_reg(&ins, op1);
|
||||||
|
|
||||||
|
out[ip++] = (uint16_t)ins;
|
||||||
|
ADD_LABEL(op2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LineTy_Mov16_Reg_Label: {
|
||||||
|
uint16_t dst = line->dst.reg;
|
||||||
|
int op2 = line->op2.label;
|
||||||
|
|
||||||
|
uint32_t ins = Op_Mov16;
|
||||||
|
set_is_imm(&ins);
|
||||||
|
ins |= (dst & 0xfu) << 12;
|
||||||
|
|
||||||
|
out[ip++] = (uint16_t)ins;
|
||||||
|
ADD_LABEL(op2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LineTy_Mov16_Reg_MemLabel: {
|
||||||
|
uint16_t dst = line->dst.reg;
|
||||||
|
|
||||||
|
uint32_t ins = Op_Mov16;
|
||||||
|
set_is_imm(&ins);
|
||||||
|
set_mov_is_memory(&ins);
|
||||||
|
add_dst_reg(&ins, dst);
|
||||||
|
|
||||||
|
out[ip++] = (uint16_t)ins;
|
||||||
|
ADD_LABEL(line->op2.label);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LineTy_Mov16_MemLabel_Reg: {
|
||||||
|
int dst = line->dst.label;
|
||||||
|
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;
|
||||||
|
ADD_LABEL(dst);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LineTy_Call_Label: {
|
||||||
|
int op1 = line->op1.label;
|
||||||
|
|
||||||
|
uint32_t ins = Op_Call;
|
||||||
|
set_is_imm(&ins);
|
||||||
|
|
||||||
|
out[ip++] = (uint16_t)ins;
|
||||||
|
ADD_LABEL(op1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LineTy_Lit_Label: {
|
||||||
|
int op1 = line->op1.label;
|
||||||
|
|
||||||
|
uint32_t ins = Op_Lit;
|
||||||
|
set_is_imm(&ins);
|
||||||
|
|
||||||
|
out[ip++] = (uint16_t)ins;
|
||||||
|
ADD_LABEL(op1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
ip += assemble_line(&out[ip], line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
if (!is_label) {
|
if (!is_label) {
|
||||||
|
@ -114,7 +114,7 @@ typedef struct {
|
|||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
} Line;
|
} Line;
|
||||||
|
|
||||||
uint16_t assemble_to_binary(
|
uint16_t assemble_lines_with_labels(
|
||||||
uint16_t* out, const Line* lines, size_t lines_size);
|
uint16_t* out, const Line* lines, size_t lines_size);
|
||||||
|
|
||||||
Line s_label(int label);
|
Line s_label(int label);
|
||||||
|
@ -105,6 +105,7 @@ Line s_jnz_l(Reg op1_reg, int op2_label)
|
|||||||
{
|
{
|
||||||
return (Line) {
|
return (Line) {
|
||||||
.ty = LineTy_Jnz_Label,
|
.ty = LineTy_Jnz_Label,
|
||||||
|
.op1 = (Ex) { .reg = (uint16_t)op1_reg },
|
||||||
.op2 = (Ex) { .label = op2_label },
|
.op2 = (Ex) { .label = op2_label },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
-pedantic
|
-pedantic
|
||||||
-pedantic-errors
|
-pedantic-errors
|
||||||
-Wno-unused-variable
|
-Wno-unused-variable
|
||||||
-Wno-unused-parameter
|
# -Wno-unused-parameter
|
||||||
# -Wno-unused-function
|
# -Wno-unused-function
|
||||||
-I.
|
-I.
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ void write_program(FILE* fp)
|
|||||||
|
|
||||||
printf("assembling program...\n");
|
printf("assembling program...\n");
|
||||||
uint16_t program_size
|
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("done!\n");
|
||||||
printf("program size = %d\n", program_size);
|
printf("program size = %d\n", program_size);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user