aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-10-02 01:00:59 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commitb124548bcee1ab6d034d4499fe695073566ae37d (patch)
treee4014070ac69a2b821e12cc9264ba54aaa8089f4 /src
parent7eb8642c3ace697b03c4fc6edc90ea0ada715689 (diff)
Add !=,<,<=,>,>=; both signed and not
Diffstat (limited to 'src')
-rw-r--r--src/bytecode/bytecode.c47
-rw-r--r--src/program.c51
-rw-r--r--src/ssa/ssa.c36
-rw-r--r--src/tokenizer.c27
4 files changed, 148 insertions, 13 deletions
diff --git a/src/bytecode/bytecode.c b/src/bytecode/bytecode.c
index b947985..98698bc 100644
--- a/src/bytecode/bytecode.c
+++ b/src/bytecode/bytecode.c
@@ -522,7 +522,12 @@ static void add_instructions(BytecodeCompilerContext *self) {
}
case SSA_EQUALS: {
instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_CMP, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "cmp r%d, r%d, r%d");
+ add_ins5(self, AMAL_OP_EQ, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "eq r%d, r%d, r%d");
+ break;
+ }
+ case SSA_NOT_EQUAL: {
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
+ add_ins5(self, AMAL_OP_NEQ, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "neq r%d, r%d, r%d");
break;
}
case SSA_AND: {
@@ -530,6 +535,46 @@ static void add_instructions(BytecodeCompilerContext *self) {
add_ins5(self, AMAL_OP_BIT_AND, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "and r%d, r%d, r%d");
break;
}
+ case SSA_ILT: {
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
+ add_ins5(self, AMAL_OP_ILT, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "ilt r%d, r%d, r%d");
+ break;
+ }
+ case SSA_ILE: {
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
+ add_ins5(self, AMAL_OP_ILE, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "ile r%d, r%d, r%d");
+ break;
+ }
+ case SSA_IGT: {
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
+ add_ins5(self, AMAL_OP_IGT, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "igt r%d, r%d, r%d");
+ break;
+ }
+ case SSA_IGE: {
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
+ add_ins5(self, AMAL_OP_IGE, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "ige r%d, r%d, r%d");
+ break;
+ }
+ case SSA_LT: {
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
+ add_ins5(self, AMAL_OP_LT, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "lt r%d, r%d, r%d");
+ break;
+ }
+ case SSA_LE: {
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
+ add_ins5(self, AMAL_OP_LE, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "le r%d, r%d, r%d");
+ break;
+ }
+ case SSA_GT: {
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
+ add_ins5(self, AMAL_OP_GT, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "gt r%d, r%d, r%d");
+ break;
+ }
+ case SSA_GE: {
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
+ add_ins5(self, AMAL_OP_GE, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "ge r%d, r%d, r%d");
+ break;
+ }
case SSA_FUNC_START: {
instruction += ssa_extract_data(instruction, &ssa_ins_func_start, sizeof(ssa_ins_func_start));
add_ins6(self, AMAL_OP_FUNC_START, ssa_ins_func_start.flags, ssa_ins_func_start.num_local_vars_regs, "func_start 0x%02x, %u");
diff --git a/src/program.c b/src/program.c
index ac3c923..169d270 100644
--- a/src/program.c
+++ b/src/program.c
@@ -656,13 +656,58 @@ static CHECK_RESULT int amal_program_read_instructions(amal_program *self, amal_
self->read_index += 3;
break;
}
- case AMAL_OP_CMP: {
- return_if_error(amal_exec_cmp(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
+ case AMAL_OP_EQ: {
+ return_if_error(amal_exec_eq(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
+ self->read_index += 3;
+ break;
+ }
+ case AMAL_OP_NEQ: {
+ return_if_error(amal_exec_neq(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
+ self->read_index += 3;
+ break;
+ }
+ case AMAL_OP_ILT: {
+ return_if_error(amal_exec_ilt(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
+ self->read_index += 3;
+ break;
+ }
+ case AMAL_OP_ILE: {
+ return_if_error(amal_exec_ile(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
+ self->read_index += 3;
+ break;
+ }
+ case AMAL_OP_IGT: {
+ return_if_error(amal_exec_igt(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
+ self->read_index += 3;
+ break;
+ }
+ case AMAL_OP_IGE: {
+ return_if_error(amal_exec_ige(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
+ self->read_index += 3;
+ break;
+ }
+ case AMAL_OP_LT: {
+ return_if_error(amal_exec_lt(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
+ self->read_index += 3;
+ break;
+ }
+ case AMAL_OP_LE: {
+ return_if_error(amal_exec_le(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
+ self->read_index += 3;
+ break;
+ }
+ case AMAL_OP_GT: {
+ return_if_error(amal_exec_gt(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
+ self->read_index += 3;
+ break;
+ }
+ case AMAL_OP_GE: {
+ return_if_error(amal_exec_ge(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
self->read_index += 3;
break;
}
case AMAL_OP_BIT_AND: {
- assert(bool_false && "TODO: Implement!");
+ return_if_error(amal_exec_and(executor, self->data.data[self->read_index], self->data.data[self->read_index + 1], self->data.data[self->read_index + 2]));
self->read_index += 3;
break;
}
diff --git a/src/ssa/ssa.c b/src/ssa/ssa.c
index d875ea4..34ecada 100644
--- a/src/ssa/ssa.c
+++ b/src/ssa/ssa.c
@@ -244,15 +244,23 @@ static CHECK_RESULT int ssa_add_ins_form1(Ssa *self, SsaInstruction ins_type, Ss
}
static const char* binop_type_to_string(SsaInstruction binop_type) {
- assert(binop_type >= SSA_ADD && binop_type <= SSA_EQUALS);
+ assert(binop_type >= SSA_ADD && binop_type <= SSA_GE);
switch(binop_type) {
- case SSA_ADD: return "+";
- case SSA_SUB: return "-";
- case SSA_MUL: return "*";
- case SSA_DIV: return "/";
- case SSA_EQUALS: return "==";
- case SSA_AND: return "&&";
- default: return "";
+ case SSA_ADD: return "+";
+ case SSA_SUB: return "-";
+ case SSA_MUL: return "*";
+ case SSA_DIV: return "/";
+ case SSA_EQUALS: return "==";
+ case SSA_AND: return "&&";
+ case SSA_ILT: return "<";
+ case SSA_LT: return "<";
+ case SSA_ILE: return "<=";
+ case SSA_LE: return "<=";
+ case SSA_IGT: return ">";
+ case SSA_GT: return ">";
+ case SSA_IGE: return ">=";
+ case SSA_GE: return ">=";
+ default: return "";
}
}
@@ -287,7 +295,7 @@ static CHECK_RESULT int ssa_ins_assign_reg(Ssa *self, SsaRegister dest, SsaRegis
}
static CHECK_RESULT int ssa_ins_binop(Ssa *self, SsaInstruction binop_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result) {
- assert(binop_type >= SSA_ADD && binop_type <= SSA_AND);
+ assert(binop_type >= SSA_ADD && binop_type <= SSA_GE);
return ssa_add_ins_form2(self, binop_type, lhs, rhs, result);
}
@@ -759,8 +767,18 @@ static SsaInstruction binop_type_to_ssa_type(BinopType binop_type, amal_default_
return 0;
case BINOP_EQUALS:
return SSA_EQUALS;
+ case BINOP_NOT_EQUAL:
+ return SSA_NOT_EQUAL;
case BINOP_AND:
return SSA_AND;
+ case BINOP_LESS:
+ return type->is_signed ? SSA_ILT : SSA_LT;
+ case BINOP_LESS_EQUAL:
+ return type->is_signed ? SSA_ILE : SSA_LE;
+ case BINOP_GREATER:
+ return type->is_signed ? SSA_IGT : SSA_GT;
+ case BINOP_GREATER_EQUAL:
+ return type->is_signed ? SSA_IGE : SSA_GE;
}
return 0;
}
diff --git a/src/tokenizer.c b/src/tokenizer.c
index da6ad53..2c27809 100644
--- a/src/tokenizer.c
+++ b/src/tokenizer.c
@@ -339,6 +339,14 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) {
} else {
*token = TOK_EQUALS;
}
+ } else if(c == '!') {
+ ++self->index;
+ if(self->index < (int)self->code.size && tokenizer_get_char(self) == '=') {
+ ++self->index;
+ SET_BINOP(BINOP_NOT_EQUAL);
+ } else {
+ *token = TOK_NOT;
+ }
} else if(c == '&') {
++self->index;
if(self->index < (int)self->code.size && tokenizer_get_char(self) == '&') {
@@ -347,6 +355,22 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) {
} else {
*token = TOK_AMPERSAND;
}
+ } else if(c == '<') {
+ ++self->index;
+ if(self->index < (int)self->code.size && tokenizer_get_char(self) == '=') {
+ ++self->index;
+ SET_BINOP(BINOP_LESS_EQUAL);
+ } else {
+ SET_BINOP(BINOP_LESS);
+ }
+ } else if(c == '>') {
+ ++self->index;
+ if(self->index < (int)self->code.size && tokenizer_get_char(self) == '=') {
+ ++self->index;
+ SET_BINOP(BINOP_GREATER_EQUAL);
+ } else {
+ SET_BINOP(BINOP_GREATER);
+ }
} else if(c == '(') {
++self->index;
*token = TOK_OPEN_PAREN;
@@ -470,6 +494,9 @@ static BufferView tokenizer_expected_token_as_string(Token token) {
case TOK_EQUALS:
str = "=";
break;
+ case TOK_NOT:
+ str = "!";
+ break;
case TOK_OPEN_PAREN:
str = "(";
break;