From 9b817fe8085a59747af0d27bdeae2bfc2768c66b Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Tue, 26 Dec 2023 16:07:36 +0100 Subject: [PATCH] fxos: improve analysis of move-register when value is known --- include/fxos/analysis.h | 5 +---- include/fxos/lang.h | 6 ++++-- lib/analysis.cpp | 25 +++++++++++++++++++------ lib/lang.cpp | 11 ++++++++++- lib/view/assembly.cpp | 7 ++++--- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/include/fxos/analysis.h b/include/fxos/analysis.h index 7cb978c..911a589 100644 --- a/include/fxos/analysis.h +++ b/include/fxos/analysis.h @@ -30,10 +30,7 @@ struct ProgramState setBottom(); } - RelConst getRegister(int n) const - { - return ((unsigned)n >= 16) ? RelConstDomain().bottom() : m_regs[n]; - } + RelConst getRegister(CpuRegister reg) const; // TODO: More value in program state diff --git a/include/fxos/lang.h b/include/fxos/lang.h index 37f0f3f..664477d 100644 --- a/include/fxos/lang.h +++ b/include/fxos/lang.h @@ -89,7 +89,9 @@ public: } /* Get the register number for r0 ... r15, -1 for other registers. */ - int getR() const; + int getRn() const; + /* Make an r0 ... r15 register name from its number. */ + static CpuRegister makeRn(int n); private: CpuRegisterName m_name; @@ -160,7 +162,7 @@ struct AsmOperand std::string str() const; /* Is this operand a register? */ - bool isReg() const + bool isRegister() const { return m_kind == Reg; } diff --git a/lib/analysis.cpp b/lib/analysis.cpp index 11b4366..4df7b9f 100644 --- a/lib/analysis.cpp +++ b/lib/analysis.cpp @@ -12,6 +12,14 @@ namespace FxOS { +RelConst ProgramState::getRegister(CpuRegister reg) const +{ + int n = reg.getRn(); + if(n >= 0) + return m_regs[n]; + return RelConstDomain().top(); +} + void ProgramState::setFunctionInit() { // TODO: Analysis: Set symbolic parameters at function entry @@ -45,8 +53,9 @@ void ProgramState::applyDiff(ProgramStateDiff const &diff) case ProgramStateDiff::BaseType::RegisterUpdate: { CpuRegister reg = diff.registerName(); - if(reg.getR() >= 0) - m_regs[reg.getR()] = diff.registerValue(); + int n = reg.getRn(); + if(n >= 0) + m_regs[n] = diff.registerValue(); break; } } @@ -69,7 +78,7 @@ void ProgramState::joinWith(ProgramState const &other) RelConstDomain RCD; for(int i = 0; i < 16; i++) { - m_regs[i] = RCD.join(m_regs[i], other.getRegister(i)); + m_regs[i] = RCD.join(m_regs[i], other.m_regs[i]); } } @@ -78,7 +87,7 @@ bool ProgramState::le(ProgramState const &other) const RelConstDomain RCD; for(int i = 0; i < 16; i++) { - if(!RCD.le(m_regs[i], other.getRegister(i))) + if(!RCD.le(m_regs[i], other.m_regs[i])) return false; } return true; @@ -202,12 +211,16 @@ static ProgramStateDiff interpretInstruction( AsmOperand src = asmins.operand(0); AsmOperand dst = asmins.operand(1); - if(!dst.isReg()) + if(!dst.isRegister()) diff.setNoOp(); else if(src.isConstant()) { RelConst c = RCD.constant(computeConstantOperand(ins, src)); diff.setRegisterUpdate(dst.base(), c); } + else if(src.isRegister()) { + RelConst v = PS.getRegister(src.base()); + diff.setRegisterUpdate(dst.base(), v); + } else diff.setRegisterTouched(dst.base()); break; @@ -231,7 +244,7 @@ static ProgramStateDiff interpretInstruction( case AsmInstruction::SH_shll16: case AsmInstruction::SH_shlr16: { AsmOperand op = asmins.operand(0); - assert(op.isReg()); + assert(op.isRegister()); diff.setRegisterTouched(op.base()); break; } diff --git a/lib/lang.cpp b/lib/lang.cpp index e2385fc..3e36282 100644 --- a/lib/lang.cpp +++ b/lib/lang.cpp @@ -53,7 +53,7 @@ std::string CpuRegister::str() const noexcept return regnames[i]; } -int CpuRegister::getR() const +int CpuRegister::getRn() const { if(m_name >= R0 && m_name <= R7) return m_name - R0; @@ -63,6 +63,15 @@ int CpuRegister::getR() const return -1; } +CpuRegister CpuRegister::makeRn(int n) +{ + assert(n >= 0 && n < 16 && "makeRn: invalid number"); + CpuRegister r; + int name = (n >= 8) ? (R8 + (n - 8)) : (R0 + n); + r.m_name = static_cast(name); + return r; +} + //--- // Instruction operands //--- diff --git a/lib/view/assembly.cpp b/lib/view/assembly.cpp index a58a240..2fbefb5 100644 --- a/lib/view/assembly.cpp +++ b/lib/view/assembly.cpp @@ -246,7 +246,8 @@ static void viewProgramState(ProgramState const &PS, std::string lineStart) RelConstDomain RCD; std::cout << "\e[36m"; viewStrings(std::views::iota(0, 16) | std::views::transform([&](int i) { - return fmt::format("r{}:{}", i, PS.getRegister(i).str(false)); + auto ri = CpuRegister::makeRn(i); + return fmt::format("r{}:{}", i, PS.getRegister(ri).str(false)); }), opts); std::cout << "\e[0m"; @@ -306,8 +307,8 @@ void viewAssemblyInstruction( case AsmInstruction::SH_jmp: case AsmInstruction::SH_jsr: if(PS) { - int n = ins.opcode().operand(0).base().getR(); - RelConst target = PS->getRegister(n); + CpuRegister targetReg = ins.opcode().operand(0).base(); + RelConst target = PS->getRegister(targetReg); comments.emplace_back( target.str(false), fmt::fg(fmt::terminal_color::yellow)); }