mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Determine lane size from PIECE as well as SUBPIECE
This commit is contained in:
parent
c267e85e1e
commit
e7c75b663d
2 changed files with 29 additions and 12 deletions
|
@ -830,8 +830,8 @@ void Architecture::parseLaneSizes(const Element *el)
|
||||||
lanerecords.sort();
|
lanerecords.sort();
|
||||||
|
|
||||||
// Dedup records that are contained by (the following) records
|
// Dedup records that are contained by (the following) records
|
||||||
list<LanedRegister>::const_iterator viter = lanerecords.begin();
|
list<LanedRegister>::iterator viter = lanerecords.begin();
|
||||||
list<LanedRegister>::const_iterator nextiter = viter;
|
list<LanedRegister>::iterator nextiter = viter;
|
||||||
++nextiter;
|
++nextiter;
|
||||||
while(nextiter != lanerecords.end()) {
|
while(nextiter != lanerecords.end()) {
|
||||||
if ((*viter).contains(*nextiter)) {
|
if ((*viter).contains(*nextiter)) {
|
||||||
|
|
|
@ -497,10 +497,11 @@ int4 ActionStackPtrFlow::apply(Funcdata &data)
|
||||||
|
|
||||||
/// \brief Try to divide a single Varnode into lanes
|
/// \brief Try to divide a single Varnode into lanes
|
||||||
///
|
///
|
||||||
/// Look for a CPUI_SUBPIECE op that takes the given Varnode as the input. If
|
/// Look for a CPUI_SUBPIECE op that takes the given Varnode as the input or a
|
||||||
/// the output size is an acceptable lane size, try to split data-flow through
|
/// CPUI_PIECE op that defines it. The smallest piece involved in this op is considered the
|
||||||
/// this Varnode using this lane scheme. Try a split for every output size of such a
|
/// putative lane size. If this lane size is acceptable, try to split data-flow through
|
||||||
/// SUBPIECE op until one succeeds.
|
/// this Varnode using this lane scheme. Try a split for every CPUI_SUBPIECE/CPUI_PIECE the
|
||||||
|
/// given Varnode is involved in until one succeeds.
|
||||||
/// \param data is the function being transformed
|
/// \param data is the function being transformed
|
||||||
/// \param vn is the given single Varnode
|
/// \param vn is the given single Varnode
|
||||||
/// \param lanedRegister is acceptable set of lane sizes for the Varnode
|
/// \param lanedRegister is acceptable set of lane sizes for the Varnode
|
||||||
|
@ -510,11 +511,27 @@ bool ActionLaneDivide::processVarnode(Funcdata &data,Varnode *vn,const LanedRegi
|
||||||
{
|
{
|
||||||
list<PcodeOp *>::const_iterator iter = vn->beginDescend();
|
list<PcodeOp *>::const_iterator iter = vn->beginDescend();
|
||||||
LanedRegister checkedLanes;
|
LanedRegister checkedLanes;
|
||||||
while(iter != vn->endDescend()) {
|
int4 step = 0; // 0 = descendants, 1 = def, 2 = done
|
||||||
|
while(step < 2) {
|
||||||
|
int4 curSize; // Putative lane size
|
||||||
|
if (step == 0) {
|
||||||
PcodeOp *op = *iter;
|
PcodeOp *op = *iter;
|
||||||
++iter;
|
++iter;
|
||||||
if (op->code() != CPUI_SUBPIECE) continue;
|
if (iter == vn->endDescend())
|
||||||
int4 curSize = op->getOut()->getSize();
|
step = 1;
|
||||||
|
if (op->code() != CPUI_SUBPIECE) continue; // Is the big register split into pieces
|
||||||
|
curSize = op->getOut()->getSize();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
step = 2;
|
||||||
|
if (!vn->isWritten()) continue;
|
||||||
|
PcodeOp *op = vn->getDef();
|
||||||
|
if (op->code() != CPUI_PIECE) continue; // Is the big register formed from smaller pieces
|
||||||
|
curSize = op->getIn(0)->getSize();
|
||||||
|
int4 tmpSize = op->getIn(1)->getSize();
|
||||||
|
if (tmpSize < curSize)
|
||||||
|
curSize = tmpSize;
|
||||||
|
}
|
||||||
if (lanedRegister.allowedLane(curSize)) {
|
if (lanedRegister.allowedLane(curSize)) {
|
||||||
if (checkedLanes.allowedLane(curSize)) continue;
|
if (checkedLanes.allowedLane(curSize)) continue;
|
||||||
checkedLanes.addSize(curSize); // Only check this scheme once
|
checkedLanes.addSize(curSize); // Only check this scheme once
|
||||||
|
@ -525,7 +542,7 @@ bool ActionLaneDivide::processVarnode(Funcdata &data,Varnode *vn,const LanedRegi
|
||||||
}
|
}
|
||||||
if (!description.subset(bytePos,vn->getSize())) // Try to restrict lane scheme to actual Varnode
|
if (!description.subset(bytePos,vn->getSize())) // Try to restrict lane scheme to actual Varnode
|
||||||
continue;
|
continue;
|
||||||
LaneDivide laneDivide(&data,op->getIn(0),description,allowDowncast);
|
LaneDivide laneDivide(&data,vn,description,allowDowncast);
|
||||||
if (laneDivide.doTrace()) {
|
if (laneDivide.doTrace()) {
|
||||||
laneDivide.apply();
|
laneDivide.apply();
|
||||||
count += 1; // Indicate a change was made
|
count += 1; // Indicate a change was made
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue