GP-4300 Full extended division in optimized division rules

This commit is contained in:
caheckman 2024-03-27 22:55:19 +00:00
parent c63be6d2c3
commit 4bbbba3e5a
17 changed files with 821 additions and 228 deletions

View file

@ -780,37 +780,55 @@ void Varnode::printRawHeritage(ostream &s,int4 depth) const
s << endl;
}
/// If \b this is a constant, or is extended (INT_ZEXT,INT_SEXT) from a constant,
/// the \e value of the constant is passed back and a non-negative integer is returned, either:
/// - 0 for a normal constant Varnode
/// - 1 for a zero extension (INT_ZEXT) of a normal constant
/// - 2 for a sign extension (INT_SEXT) of a normal constant
/// \param val is a reference to the constant value that is passed back
/// \return the extension code (or -1 if \b this cannot be interpreted as a constant)
int4 Varnode::isConstantExtended(uintb &val) const
/// If \b this is a constant, or is extended (INT_ZEXT,INT_SEXT,PIECE) from a constant,
/// the \e value of the constant (currently up to 128 bits) is passed back and \b true is returned.
/// \param val will hold the 128-bit constant value
/// \return \b true if a constant was recovered
bool Varnode::isConstantExtended(uint8 *val) const
{
if (isConstant()) {
val = getOffset();
return 0;
val[0] = getOffset();
val[1] = 0;
return true;
}
if (!isWritten()) return -1;
if (!isWritten() || size <= 8) return false;
if (size > 16) return false; // Currently only up to 128-bit values
OpCode opc = def->code();
if (opc == CPUI_INT_ZEXT) {
Varnode *vn0 = def->getIn(0);
if (vn0->isConstant()) {
val = vn0->getOffset();
return 1;
val[0] = vn0->getOffset();
val[1] = 0;
return true;
}
}
else if (opc == CPUI_INT_SEXT) {
Varnode *vn0 = def->getIn(0);
if (vn0->isConstant()) {
val = vn0->getOffset();
return 2;
val[0] = vn0->getOffset();
if (vn0->getSize() < 8)
val[0] = sign_extend(val[0], vn0->getSize(), size);
val[1] = (signbit_negative(val[0], 8)) ? 0xffffffffffffffffL : 0;
return true;
}
}
return -1;
else if (opc == CPUI_PIECE) {
Varnode *vnlo = def->getIn(1);
if (vnlo->isConstant()) {
val[0] = vnlo->getOffset();
Varnode *vnhi = def->getIn(0);
if (vnhi->isConstant()) {
val[1] = vnhi->getOffset();
if (vnlo->getSize() == 8)
return true;
val[0] |= val[1] << 8*vnlo->getSize();
val[1] >>= 8*(8-vnlo->getSize());
return true;
}
}
}
return false;
}
/// Make an initial determination of the Datatype of this Varnode. If a Datatype is already