Unit tests for CircleRange

This commit is contained in:
caheckman
2021-08-24 11:50:58 -04:00
parent e83e7004a3
commit b275a02cdf
6 changed files with 844 additions and 19 deletions
@@ -6,7 +6,7 @@ ARCH_TYPE=
ADDITIONAL_FLAGS= ADDITIONAL_FLAGS=
SLEIGHVERSION=sleigh-2.1.0 SLEIGHVERSION=sleigh-2.1.0
EXTENSION_POINT=../../../../../../../ghidra.ext/Ghidra/Features/DecompilerExtensions/src/decompile/cpp EXTENSION_POINT=../../../../../../../ghidra.ext-u/Ghidra/Features/DecompilerExtensions/src/decompile/cpp
GHIDRA_BIN=../../../../../../../ghidra.bin GHIDRA_BIN=../../../../../../../ghidra.bin
OS = $(shell uname -s) OS = $(shell uname -s)
@@ -350,6 +350,13 @@ uintb OpBehaviorInt2Comp::evaluateUnary(int4 sizeout,int4 sizein,uintb in1) cons
return res; return res;
} }
uintb OpBehaviorInt2Comp::recoverInputUnary(int4 sizeout,uintb out,int4 sizein) const
{
uintb res = uintb_negate(out-1,sizein);
return res;
}
uintb OpBehaviorIntNegate::evaluateUnary(int4 sizeout,int4 sizein,uintb in1) const uintb OpBehaviorIntNegate::evaluateUnary(int4 sizeout,int4 sizein,uintb in1) const
{ {
@@ -357,6 +364,13 @@ uintb OpBehaviorIntNegate::evaluateUnary(int4 sizeout,int4 sizein,uintb in1) con
return res; return res;
} }
uintb OpBehaviorIntNegate::recoverInputUnary(int4 sizeout,uintb out,int4 sizein) const
{
uintb res = uintb_negate(out,sizein);
return res;
}
uintb OpBehaviorIntXor::evaluateBinary(int4 sizeout,int4 sizein,uintb in1,uintb in2) const uintb OpBehaviorIntXor::evaluateBinary(int4 sizeout,int4 sizein,uintb in1,uintb in2) const
{ {
@@ -227,6 +227,7 @@ class OpBehaviorInt2Comp : public OpBehavior {
public: public:
OpBehaviorInt2Comp(void): OpBehavior(CPUI_INT_2COMP,true) {} ///< Constructor OpBehaviorInt2Comp(void): OpBehavior(CPUI_INT_2COMP,true) {} ///< Constructor
virtual uintb evaluateUnary(int4 sizeout,int4 sizein,uintb in1) const; virtual uintb evaluateUnary(int4 sizeout,int4 sizein,uintb in1) const;
virtual uintb recoverInputUnary(int4 sizeout,uintb out,int4 sizein) const;
}; };
/// CPUI_INT_NEGATE behavior /// CPUI_INT_NEGATE behavior
@@ -234,6 +235,7 @@ class OpBehaviorIntNegate : public OpBehavior {
public: public:
OpBehaviorIntNegate(void): OpBehavior(CPUI_INT_NEGATE,true) {} ///< Constructor OpBehaviorIntNegate(void): OpBehavior(CPUI_INT_NEGATE,true) {} ///< Constructor
virtual uintb evaluateUnary(int4 sizeout,int4 sizein,uintb in1) const; virtual uintb evaluateUnary(int4 sizeout,int4 sizein,uintb in1) const;
virtual uintb recoverInputUnary(int4 sizeout,uintb out,int4 sizein) const;
}; };
/// CPUI_INT_XOR behavior /// CPUI_INT_XOR behavior
@@ -744,12 +744,18 @@ bool CircleRange::pullBackUnary(OpCode opc,int4 inSize,int4 outSize)
left = (~right + 1 + step) & mask; left = (~right + 1 + step) & mask;
right = val; right = val;
break; break;
case CPUI_INT_NEGATE:
val = (~left + step) & mask;
left = (~right + step) & mask;
right = val;
break;
case CPUI_INT_ZEXT: case CPUI_INT_ZEXT:
{ {
val = calc_mask(inSize); // (smaller) input mask val = calc_mask(inSize); // (smaller) input mask
uintb rem = left % step;
CircleRange zextrange; CircleRange zextrange;
zextrange.left = 0; zextrange.left = rem;
zextrange.right = val + 1; // Biggest possible range of ZEXT zextrange.right = val + 1 + rem; // Biggest possible range of ZEXT
zextrange.mask = mask; zextrange.mask = mask;
zextrange.step = step; // Keep the same stride zextrange.step = step; // Keep the same stride
zextrange.isempty = false; zextrange.isempty = false;
@@ -763,8 +769,10 @@ bool CircleRange::pullBackUnary(OpCode opc,int4 inSize,int4 outSize)
case CPUI_INT_SEXT: case CPUI_INT_SEXT:
{ {
val = calc_mask(inSize); // (smaller) input mask val = calc_mask(inSize); // (smaller) input mask
uintb rem = left & step;
CircleRange sextrange; CircleRange sextrange;
sextrange.left = val ^ (val >> 1); // High order bit for (small) input space sextrange.left = val ^ (val >> 1); // High order bit for (small) input space
sextrange.left += rem;
sextrange.right = sign_extend(sextrange.left, inSize, outSize); sextrange.right = sign_extend(sextrange.left, inSize, outSize);
sextrange.mask = mask; sextrange.mask = mask;
sextrange.step = step; // Keep the same stride sextrange.step = step; // Keep the same stride
@@ -1096,13 +1104,15 @@ bool CircleRange::pushForwardUnary(OpCode opc,const CircleRange &in1,int4 inSize
isempty = false; isempty = false;
step = in1.step; step = in1.step;
mask = calc_mask(outSize); mask = calc_mask(outSize);
left = in1.left; if (in1.left == in1.right) {
right = (in1.right - in1.step) & in1.mask; left = in1.left % step;
if (right < left) { // Extending causes 2 pieces
left = left % step;
right = in1.mask + 1 + left; right = in1.mask + 1 + left;
} }
else { else {
left = in1.left;
right = (in1.right - in1.step) & in1.mask;
if (right < left)
return false; // Extending causes 2 pieces
right += step; // Impossible for it to wrap with bigger mask right += step; // Impossible for it to wrap with bigger mask
} }
break; break;
@@ -1110,16 +1120,19 @@ bool CircleRange::pushForwardUnary(OpCode opc,const CircleRange &in1,int4 inSize
isempty = false; isempty = false;
step = in1.step; step = in1.step;
mask = calc_mask(outSize); mask = calc_mask(outSize);
left = sign_extend(in1.left, inSize, outSize); if (in1.left == in1.right) {
right = sign_extend((in1.right - in1.step)&in1.mask, inSize, outSize); uintb rem = in1.left % step;
if ((intb)right < (intb)left) {
uintb rem = left % step;
right = calc_mask(inSize) >> 1; right = calc_mask(inSize) >> 1;
left = (calc_mask(outSize) ^ right) + rem; left = (calc_mask(outSize) ^ right) + rem;
right = right + 1 + rem; right = right + 1 + rem;
} }
else else {
right += step; left = sign_extend(in1.left, inSize, outSize);
right = sign_extend((in1.right - in1.step)&in1.mask, inSize, outSize);
if ((intb)right < (intb)left)
return false; // Extending causes 2 pieces
right = (right + step) & mask;
}
break; break;
case CPUI_INT_2COMP: case CPUI_INT_2COMP:
isempty = false; isempty = false;
@@ -1133,8 +1146,8 @@ bool CircleRange::pushForwardUnary(OpCode opc,const CircleRange &in1,int4 inSize
isempty = false; isempty = false;
step = in1.step; step = in1.step;
mask = in1.mask; mask = in1.mask;
left = -in1.right & mask; left = (~in1.right + step) & mask;
right = -in1.left & mask; right =(~in1.left + step) & mask;
normalize(); normalize();
break; break;
case CPUI_BOOL_NEGATE: case CPUI_BOOL_NEGATE:
File diff suppressed because it is too large Load Diff
@@ -18,10 +18,10 @@
#include "test.hh" #include "test.hh"
#include <iostream> #include <iostream>
Architecture *glb; static Architecture *glb;
TypeFactory *types; static TypeFactory *types;
CastStrategy *strategy; static CastStrategy *strategy;
Funcdata *dummyFunc; static Funcdata *dummyFunc;
class TypeTestEnvironment { class TypeTestEnvironment {
Architecture *g; Architecture *g;