Create and use LZCOUNT Pcode op

This commit is contained in:
Pokechu22 2022-07-11 12:40:19 -07:00
parent 865cd22cab
commit 14880b53c4
47 changed files with 288 additions and 247 deletions

View file

@ -3617,6 +3617,7 @@ void ActionDeadCode::propagateConsumed(vector<Varnode *> &worklist)
pushConsumed(b,op->getIn(2), worklist);
break;
case CPUI_POPCOUNT:
case CPUI_LZCOUNT:
a = 16 * op->getIn(0)->getSize() - 1; // Mask for possible bits that could be set
a &= outc; // Of the bits that could be set, which are consumed
b = (a == 0) ? 0 : ~((uintb)0); // if any consumed, treat all input bits as consumed

View file

@ -55,7 +55,8 @@ const uint4 DynamicHash::transtable[] = {
0, // CAST is skipped
CPUI_INT_ADD, CPUI_INT_ADD, // PTRADD and PTRSUB hash same as INT_ADD
CPUI_SEGMENTOP, CPUI_CPOOLREF, CPUI_NEW, CPUI_INSERT, CPUI_EXTRACT, CPUI_POPCOUNT
CPUI_SEGMENTOP, CPUI_CPOOLREF, CPUI_NEW, CPUI_INSERT, CPUI_EXTRACT,
CPUI_POPCOUNT, CPUI_LZCOUNT
};

View file

@ -645,6 +645,10 @@ uintb PcodeOp::getNZMaskLocal(bool cliploop) const
resmask = coveringmask((uintb)sz1);
resmask &= fullmask;
break;
case CPUI_LZCOUNT:
resmask = coveringmask(getIn(0)->getSize() * 8);
resmask &= fullmask;
break;
case CPUI_SUBPIECE:
resmask = getIn(0)->getNZMask();
sz1 = (int4)getIn(1)->getOffset();

View file

@ -102,6 +102,7 @@ void OpBehavior::registerInstructions(vector<OpBehavior *> &inst,const Translate
inst[CPUI_INSERT] = new OpBehavior(CPUI_INSERT,false);
inst[CPUI_EXTRACT] = new OpBehavior(CPUI_EXTRACT,false);
inst[CPUI_POPCOUNT] = new OpBehaviorPopcount();
inst[CPUI_LZCOUNT] = new OpBehaviorLzcount();
}
/// \param sizeout is the size of the output in bytes
@ -757,3 +758,8 @@ uintb OpBehaviorPopcount::evaluateUnary(int4 sizeout,int4 sizein,uintb in1) cons
return (uintb)popcount(in1);
}
uintb OpBehaviorLzcount::evaluateUnary(int4 sizeout,int4 sizein,uintb in1) const
{
return (uintb)(count_leading_zeros(in1) - 8*(sizeof(uintb) - sizein));
}

View file

@ -511,4 +511,11 @@ public:
virtual uintb evaluateUnary(int4 sizeout,int4 sizein,uintb in1) const;
};
/// CPUI_LZCOUNT behavior
class OpBehaviorLzcount : public OpBehavior {
public:
OpBehaviorLzcount(void) : OpBehavior(CPUI_LZCOUNT,true) {} ///< Constructor
virtual uintb evaluateUnary(int4 sizeout,int4 sizein,uintb in1) const;
};
#endif

View file

@ -42,14 +42,14 @@ static const char *opcode_name[] = {
"TRUNC", "CEIL", "FLOOR", "ROUND",
"BUILD", "DELAY_SLOT", "PIECE", "SUBPIECE", "CAST",
"LABEL", "CROSSBUILD", "SEGMENTOP", "CPOOLREF", "NEW",
"INSERT", "EXTRACT", "POPCOUNT"
"INSERT", "EXTRACT", "POPCOUNT", "LZCOUNT"
};
static const int4 opcode_indices[] = {
0, 39, 37, 40, 38, 4, 6, 60, 7, 8, 9, 64, 5, 57, 1, 68, 66,
0, 39, 37, 40, 38, 4, 6, 60, 7, 8, 9, 64, 5, 57, 1, 68, 66,
61, 71, 55, 52, 47, 48, 41, 43, 44, 49, 46, 51, 42, 53, 50, 58, 70,
54, 24, 19, 27, 21, 33, 11, 29, 15, 16, 32, 25, 12, 28, 35, 30,
23, 22, 34, 18, 13, 14, 36, 31, 20, 26, 17, 65, 2, 69, 62, 72, 10, 59,
23, 22, 34, 18, 13, 14, 36, 31, 20, 26, 17, 65, 2, 73, 69, 62, 72, 10, 59,
67, 3, 63, 56, 45
};

View file

@ -123,8 +123,9 @@ enum OpCode {
CPUI_INSERT = 70, ///< Insert a bit-range
CPUI_EXTRACT = 71, ///< Extract a bit-range
CPUI_POPCOUNT = 72, ///< Count the 1-bits
CPUI_LZCOUNT = 73, ///< Count the leading 0-bits
CPUI_MAX = 73 ///< Value indicating the end of the op-code values
CPUI_MAX = 74 ///< Value indicating the end of the op-code values
};
extern const char *get_opname(OpCode opc); ///< Convert an OpCode to the name as a string

View file

@ -329,6 +329,7 @@ public:
virtual void opInsertOp(const PcodeOp *op);
virtual void opExtractOp(const PcodeOp *op);
virtual void opPopcountOp(const PcodeOp *op) { opFunc(op); }
virtual void opLzcountOp(const PcodeOp *op) { opFunc(op); }
};
/// \brief Set of print commands for displaying an open brace '{' and setting a new indent level

View file

@ -554,6 +554,7 @@ public:
virtual void opInsertOp(const PcodeOp *op)=0; ///< Emit an INSERT operator
virtual void opExtractOp(const PcodeOp *op)=0; ///< Emit an EXTRACT operator
virtual void opPopcountOp(const PcodeOp *op)=0; ///< Emit a POPCOUNT operator
virtual void opLzcountOp(const PcodeOp *op)=0; ///< Emit a LZCOUNT operator
virtual string unnamedField(int4 off,int4 size); ///< Generate an artificial field name
static int4 mostNaturalBase(uintb val); ///< Determine the most natural base for an integer

View file

@ -785,6 +785,9 @@ void ConsistencyChecker::printOpName(ostream &s,OpTpl *op)
case CPUI_POPCOUNT:
s << "Count bits(popcount)";
break;
case CPUI_LZCOUNT:
s << "Count leading zero bits(lzcount)";
break;
default:
break;
}

View file

@ -94,7 +94,7 @@
%right '!' '~'
%token OP_ZEXT OP_CARRY OP_BORROW OP_SEXT OP_SCARRY OP_SBORROW OP_NAN OP_ABS
%token OP_SQRT OP_CEIL OP_FLOOR OP_ROUND OP_INT2FLOAT OP_FLOAT2FLOAT
%token OP_TRUNC OP_CPOOLREF OP_NEW OP_POPCOUNT
%token OP_TRUNC OP_CPOOLREF OP_NEW OP_POPCOUNT OP_LZCOUNT
%token BADINTEGER GOTO_KEY CALL_KEY RETURN_KEY IF_KEY
%token DEFINE_KEY ATTACH_KEY MACRO_KEY SPACE_KEY TYPE_KEY RAM_KEY DEFAULT_KEY
@ -444,6 +444,7 @@ expr: varnode { $$ = new ExprTree($1); }
| OP_NEW '(' expr ')' { $$ = slgh->pcode.createOp(CPUI_NEW,$3); }
| OP_NEW '(' expr ',' expr ')' { $$ = slgh->pcode.createOp(CPUI_NEW,$3,$5); }
| OP_POPCOUNT '(' expr ')' { $$ = slgh->pcode.createOp(CPUI_POPCOUNT,$3); }
| OP_LZCOUNT '(' expr ')' { $$ = slgh->pcode.createOp(CPUI_LZCOUNT,$3); }
| specificsymbol '(' integervarnode ')' { $$ = slgh->pcode.createOp(CPUI_SUBPIECE,new ExprTree($1->getVarnode()),new ExprTree($3)); }
| specificsymbol ':' INTEGER { $$ = slgh->pcode.createBitRange($1,0,(uint4)(*$3 * 8)); delete $3; }
| specificsymbol '[' INTEGER ',' INTEGER ']' { $$ = slgh->pcode.createBitRange($1,(uint4)*$3,(uint4)*$5); delete $3, delete $5; }

View file

@ -641,6 +641,7 @@ with { BEGIN(pattern); withsection = 1; slgh->calcContextLayout(); return WITH
<sem>cpool { return OP_CPOOLREF; }
<sem>newobject { return OP_NEW; }
<sem>popcount { return OP_POPCOUNT; }
<sem>lzcount { return OP_LZCOUNT; }
<sem>if { return IF_KEY; }
<sem>goto { return GOTO_KEY; }
<sem>call { return CALL_KEY; }

View file

@ -102,6 +102,7 @@ void TypeOp::registerInstructions(vector<TypeOp *> &inst,TypeFactory *tlst,
inst[CPUI_INSERT] = new TypeOpInsert(tlst);
inst[CPUI_EXTRACT] = new TypeOpExtract(tlst);
inst[CPUI_POPCOUNT] = new TypeOpPopcount(tlst);
inst[CPUI_LZCOUNT] = new TypeOpLzcount(tlst);
}
/// Change basic data-type info (signed vs unsigned) and operator names ( '>>' vs '>>>' )
@ -2323,3 +2324,10 @@ TypeOpPopcount::TypeOpPopcount(TypeFactory *t)
opflags = PcodeOp::unary;
behave = new OpBehaviorPopcount();
}
TypeOpLzcount::TypeOpLzcount(TypeFactory *t)
: TypeOpFunc(t,CPUI_LZCOUNT,"LZCOUNT",TYPE_INT,TYPE_UNKNOWN)
{
opflags = PcodeOp::unary;
behave = new OpBehaviorLzcount();
}

View file

@ -857,4 +857,11 @@ public:
virtual void push(PrintLanguage *lng,const PcodeOp *op,const PcodeOp *readOp) const { lng->opPopcountOp(op); }
};
/// \brief Information about the LZCOUNT op-code
class TypeOpLzcount : public TypeOpFunc {
public:
TypeOpLzcount(TypeFactory *t); ///< Constructor
virtual void push(PrintLanguage *lng,const PcodeOp *op,const PcodeOp *readOp) const { lng->opLzcountOp(op); }
};
#endif