From b124548bcee1ab6d034d4499fe695073566ae37d Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 2 Oct 2019 01:00:59 +0200 Subject: Add !=,<,<=,>,>=; both signed and not --- src/bytecode/bytecode.c | 47 ++++++++++++++++++++++++++++++++++++++++++++- src/program.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++--- src/ssa/ssa.c | 36 +++++++++++++++++++++++++--------- src/tokenizer.c | 27 ++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 13 deletions(-) (limited to 'src') 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; -- cgit v1.2.3