Implement comparison operators
This commit is contained in:
@ -235,11 +235,13 @@ namespace elna::riscv
|
||||
void visitor::visit(source::call_statement *statement)
|
||||
{
|
||||
std::size_t argument_offset{ 0 };
|
||||
|
||||
for (auto& argument : statement->arguments())
|
||||
{
|
||||
argument->accept(this);
|
||||
const auto free_register = this->register_in_use ? x_register::a0 : x_register::t0;
|
||||
this->instructions.push_back(instruction(base_opcode::store)
|
||||
.s(argument_offset, funct3_t::sw, x_register::sp, x_register::a0));
|
||||
.s(argument_offset, funct3_t::sw, x_register::sp, free_register));
|
||||
argument_offset += 4;
|
||||
}
|
||||
relocate(statement->name(), address_t::text);
|
||||
@ -321,19 +323,21 @@ namespace elna::riscv
|
||||
|
||||
this->register_in_use = true;
|
||||
expression->lhs().accept(this);
|
||||
auto lhs_stack_position = this->variable_counter * 4;
|
||||
++this->variable_counter;
|
||||
|
||||
this->instructions.push_back( // movl %eax, -x(%rbp); where x is a number.
|
||||
this->instructions.push_back(
|
||||
instruction(base_opcode::store)
|
||||
.s(static_cast<std::uint32_t>(this->variable_counter * 4), funct3_t::sw, x_register::sp, x_register::a0)
|
||||
.s(static_cast<std::uint32_t>(lhs_stack_position), funct3_t::sw, x_register::sp, x_register::a0)
|
||||
);
|
||||
auto lhs_stack_position = ++this->variable_counter;
|
||||
|
||||
this->register_in_use = false;
|
||||
expression->rhs().accept(this);
|
||||
this->register_in_use = lhs_register == x_register::a0; // Restore.
|
||||
|
||||
this->instructions.push_back(instruction(base_opcode::load)
|
||||
.i(x_register::a0, funct3_t::lw, x_register::sp,
|
||||
static_cast<std::int8_t>((lhs_stack_position - 1) * 4))
|
||||
static_cast<std::int8_t>(lhs_stack_position))
|
||||
);
|
||||
|
||||
// Calculate the result and assign it to a variable on the stack.
|
||||
@ -355,6 +359,38 @@ namespace elna::riscv
|
||||
this->instructions.push_back(instruction(base_opcode::op)
|
||||
.r(lhs_register, funct3_t::div, x_register::a0, x_register::t0, funct7_t::muldiv));
|
||||
break;
|
||||
case source::binary_operator::equals:
|
||||
this->instructions.push_back(instruction(base_opcode::op)
|
||||
.r(lhs_register, funct3_t::sub, x_register::a0, x_register::t0, funct7_t::sub));
|
||||
this->instructions.push_back(instruction(base_opcode::opImm)
|
||||
.i(lhs_register, funct3_t::sltiu, lhs_register, 1));
|
||||
break;
|
||||
case source::binary_operator::not_equals:
|
||||
this->instructions.push_back(instruction(base_opcode::op)
|
||||
.r(lhs_register, funct3_t::sub, x_register::a0, x_register::t0, funct7_t::sub));
|
||||
this->instructions.push_back(instruction(base_opcode::op)
|
||||
.r(lhs_register, funct3_t::sltu, x_register::zero, lhs_register));
|
||||
break;
|
||||
case source::binary_operator::less:
|
||||
this->instructions.push_back(instruction(base_opcode::op)
|
||||
.r(lhs_register, funct3_t::sltu, x_register::a0, x_register::t0));
|
||||
break;
|
||||
case source::binary_operator::greater_equal:
|
||||
this->instructions.push_back(instruction(base_opcode::op)
|
||||
.r(lhs_register, funct3_t::sltu, x_register::t0, x_register::a0));
|
||||
break;
|
||||
case source::binary_operator::greater:
|
||||
this->instructions.push_back(instruction(base_opcode::op)
|
||||
.r(lhs_register, funct3_t::slt, x_register::a0, x_register::t0));
|
||||
this->instructions.push_back(instruction(base_opcode::opImm)
|
||||
.i(lhs_register, funct3_t::xori, lhs_register, 1));
|
||||
break;
|
||||
case source::binary_operator::less_equal:
|
||||
this->instructions.push_back(instruction(base_opcode::op)
|
||||
.r(lhs_register, funct3_t::slt, x_register::t0, x_register::a0));
|
||||
this->instructions.push_back(instruction(base_opcode::opImm)
|
||||
.i(lhs_register, funct3_t::xori, lhs_register, 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user