fxos: improve analysis of move-register when value is known
This commit is contained in:
parent
eacdf9da99
commit
9b817fe808
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
11
lib/lang.cpp
11
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<CpuRegisterName>(name);
|
||||
return r;
|
||||
}
|
||||
|
||||
//---
|
||||
// Instruction operands
|
||||
//---
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue