From ffbd6bb5760d2db4c467529ba68b8c000869aaf9 Mon Sep 17 00:00:00 2001 From: belijzajac Date: Thu, 2 May 2024 22:59:10 +0300 Subject: [PATCH] Comparison machine code for `cmp reg1, reg2` --- src/backend/codegen/CodeGenerator.cpp | 37 ++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/backend/codegen/CodeGenerator.cpp b/src/backend/codegen/CodeGenerator.cpp index 397de28..81c9b29 100644 --- a/src/backend/codegen/CodeGenerator.cpp +++ b/src/backend/codegen/CodeGenerator.cpp @@ -342,13 +342,46 @@ void CodeGenerator::emitCmp(const InstructionPtr &instruction) { const auto &argTwo = instruction->getArg2(); // cmp reg, number - if (argOne->getType() == TType::REGISTER) { + if (argOne->getType() == TType::REGISTER && argTwo->isLiteralIntegerType()) { const auto bytes = MachineCodeTable::getCmpMachineCode(argOne->getValue()); m_textSection.putBytes(bytes); m_textSection.putValue(argTwo->getValue()); return; } + // cmp reg1, reg2 + if (argOne->getType() == TType::REGISTER && argTwo->getType() == TType::REGISTER) { + const auto [dst, src] = assignRegisters(argOne->getValue(), argTwo->getValue()); + assert((src > -1 && dst > -1) && "Failed to look up registers for cmp instruction"); + + // cmp rax ... r15 + // rax ... + // ... ... ... ... + // r15 ... + if (dst < RegisterAllocator::getHalfRegisters() && src < RegisterAllocator::getHalfRegisters()) { + // top left + m_textSection.putBytes(std::byte{0x48}, std::byte{0x39}); + } else if (dst < RegisterAllocator::getHalfRegisters() && src >= RegisterAllocator::getHalfRegisters()) { + // top right + m_textSection.putBytes(std::byte{0x4c}, std::byte{0x39}); + } else if (dst >= RegisterAllocator::getHalfRegisters() && src < RegisterAllocator::getHalfRegisters()) { + // bottom left + m_textSection.putBytes(std::byte{0x49}, std::byte{0x39}); + } else if (dst >= RegisterAllocator::getHalfRegisters() && src >= RegisterAllocator::getHalfRegisters()) { + // bottom right + m_textSection.putBytes(std::byte{0x4d}, std::byte{0x39}); + } else { + assert(0 && "Unknown table entry for cmp instruction"); + } + + const auto result = + 0xc0 + (RegisterAllocator::getHalfRegisters() * (src % RegisterAllocator::getHalfRegisters())) + + (dst % RegisterAllocator::getHalfRegisters()); + assert(result <= 255 && "Result value is out of range"); + m_textSection.putBytes(std::byte(result)); + return; + } + throw CodeGenerationError{"Unknown cmp instruction"}; } @@ -395,8 +428,6 @@ void CodeGenerator::emitJmp(const InstructionPtr &instruction) { const auto &label = instruction->getArg1()->getValue(); const auto offset = m_textSection.size(); m_jumps.emplace_back(Label{label, offset}); - - // Empty displacement m_textSection.putBytes(std::byte{0x00}); }