Merge remote-tracking branch 'origin/patch'

This commit is contained in:
Ryan Kurtz
2025-12-10 12:33:30 -05:00
3 changed files with 45 additions and 22 deletions

View File

@@ -157,12 +157,15 @@ void Funcdata::pushMultiequals(BlockBasic *bb)
list<PcodeOp *>::iterator titer = origvn->descend.begin();
while(titer != origvn->descend.end()) {
PcodeOp *op = *titer++;
i = op->getSlot(origvn);
// Do not replace MULTIEQUAL references in the same block
// as replaceop. These are patched by block_remove
if ((op->code()==CPUI_MULTIEQUAL)&&(op->getParent()==outblock)&&(i==outblock_ind))
continue;
opSetInput(op,replacevn,i);
for(i=0;i<op->numInput();++i) {
if (op->getIn(i) != origvn)
continue;
if (i == outblock_ind && op->getParent() == outblock && op->code() == CPUI_MULTIEQUAL) {
continue;
}
opSetInput(op,replacevn,i);
break;
}
}
}
}

View File

@@ -6691,17 +6691,39 @@ int4 RuleStructOffset0::applyOp(PcodeOp *op,Funcdata &data)
Datatype *ct = ptrVn->getTypeReadFacing(op);
if (ct->getMetatype() != TYPE_PTR) return 0;
Datatype *baseType = ((TypePointer *)ct)->getPtrTo();
int8 offset = 0;
int8 offset;
if (ct->isFormalPointerRel() && ((TypePointerRel *)ct)->evaluateThruParent(0)) {
TypePointerRel *ptRel = (TypePointerRel *)ct;
baseType = ptRel->getParent();
if (baseType->getMetatype() != TYPE_STRUCT)
return 0;
int8 iOff = ptRel->getByteOffset();
if (iOff >= baseType->getSize())
offset = ptRel->getByteOffset();
if (offset >= baseType->getSize())
return 0;
offset = iOff;
if (baseType->getSize() < movesize)
return 0; // Moving something bigger than entire structure
int8 newoff;
Datatype *subType = baseType->getSubType(offset,&newoff); // Get field at pointer's offset
if (subType==(Datatype *)0) return 0;
if (subType->getSize() < movesize) return 0; // Subtype is too small to handle LOAD/STORE
newoff = AddrSpace::byteToAddress(newoff, ptRel->getWordSize());
offset = -newoff & calc_mask(ptrVn->getSize());
// Create pointer up to parent
PcodeOp *newop = data.newOpBefore(op,CPUI_PTRSUB,ptrVn,data.newConstant(ptrVn->getSize(),offset));
if (ptrVn->getType()->needsResolution())
data.inheritResolution(ptrVn->getType(),newop, 0, op, 1);
newop->setStopTypePropagation();
if (newoff != 0) {
// Add newoff in to get back to zero total offset
PcodeOp *addop = data.newOpBefore(op,CPUI_INT_ADD,newop->getOut(),data.newConstant(ptrVn->getSize(),newoff));
data.opSetInput(op,addop->getOut(),1);
}
else {
data.opSetInput(op,newop->getOut(),1);
}
return 1;
}
offset = 0;
if (baseType->getMetatype() == TYPE_STRUCT) {
if (baseType->getSize() < movesize)
return 0; // Moving something bigger than entire structure

View File

@@ -3715,13 +3715,11 @@ bool LaneDivide::buildStore(PcodeOp *op,int4 numLanes,int4 skipLanes)
}
TransformVar *basePtr = getPreexistingVarnode(origPtr);
int4 ptrSize = origPtr->getSize();
Varnode *valueVn = op->getIn(2);
for(int4 i=0;i<numLanes;++i) {
// Order lanes by pointer offset. Least significant to most for little endian, or most significant to least for big endian.
int8 bytePos = 0; // Smallest pointer offset
for(int4 count=0;count<numLanes;++count) {
int4 i = spc->isBigEndian() ? numLanes -1 - count: count; // little = least to most, big = most to least
TransformOp *ropStore = newOpReplace(3, CPUI_STORE, op);
int4 bytePos = description.getPosition(skipLanes + i);
int4 sz = description.getSize(skipLanes + i);
if (spc->isBigEndian())
bytePos = valueVn->getSize() - (bytePos + sz); // Convert position to address order
// Construct the pointer
TransformVar *ptrVn;
@@ -3738,6 +3736,7 @@ bool LaneDivide::buildStore(PcodeOp *op,int4 numLanes,int4 skipLanes)
opSetInput(ropStore,newConstant(spaceConstSize,0,spaceConst),0);
opSetInput(ropStore,ptrVn,1);
opSetInput(ropStore,inVars+i,2);
bytePos += description.getSize(skipLanes + i);
}
return true;
}
@@ -3763,13 +3762,11 @@ bool LaneDivide::buildLoad(PcodeOp *op,TransformVar *outVars,int4 numLanes,int4
}
TransformVar *basePtr = getPreexistingVarnode(origPtr);
int4 ptrSize = origPtr->getSize();
int4 outSize = op->getOut()->getSize();
for(int4 i=0;i<numLanes;++i) {
// Order lanes by pointer offset. Least significant to most for little endian, or most significant to least for big endian.
int8 bytePos = 0; // Smallest pointer offset
for(int4 count=0;count<numLanes;++count) {
TransformOp *ropLoad = newOpReplace(2, CPUI_LOAD, op);
int4 bytePos = description.getPosition(skipLanes + i);
int4 sz = description.getSize(skipLanes + i);
if (spc->isBigEndian())
bytePos = outSize - (bytePos + sz); // Convert position to address order
int4 i = spc->isBigEndian() ? numLanes - 1 - count : count; // little = least to most, big = most to least
// Construct the pointer
TransformVar *ptrVn;
@@ -3786,6 +3783,7 @@ bool LaneDivide::buildLoad(PcodeOp *op,TransformVar *outVars,int4 numLanes,int4
opSetInput(ropLoad,newConstant(spaceConstSize,0,spaceConst),0);
opSetInput(ropLoad,ptrVn,1);
opSetOutput(ropLoad,outVars+i);
bytePos += description.getSize(skipLanes + i);
}
return true;
}