mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Create and use LZCOUNT Pcode op
This commit is contained in:
parent
865cd22cab
commit
14880b53c4
47 changed files with 288 additions and 247 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue