Merge remote-tracking branch

'origin/GP-3155_caheckman_PR-2810_Pokechu22_countleadingzeros'
(Closes #2810)
This commit is contained in:
Ryan Kurtz 2023-03-24 14:27:51 -04:00
commit 9cf60faef0
94 changed files with 3604 additions and 3451 deletions

View File

@ -64,8 +64,8 @@ task generateParsers {
*/
task yaccDecompiler {
Task t1 = createBisonTask("xml", "decompile", false, true);
Task t2 = createBisonTask("grammar", "decompile", false, true);
Task t1 = createBisonTask("xml", "decompile", false);
Task t2 = createBisonTask("grammar", "decompile", false);
if (t1 != null) {
dependsOn t1, t2
@ -79,9 +79,9 @@ task yaccDecompiler {
*/
task yaccSleigh {
Task t1 = createBisonTask("slghparse", "sleigh", true, false); // also produces slghparse.hh header file
Task t2 = createBisonTask("pcodeparse", "sleigh", false, true);
Task t3 = createBisonTask("xml", "sleigh", false, true);
Task t1 = createBisonTask("slghparse", "sleigh", true); // also produces slghparse.hh header file
Task t2 = createBisonTask("pcodeparse", "sleigh", false);
Task t3 = createBisonTask("xml", "sleigh", false);
if (t1 != null) {
dependsOn t1,t2,t3
@ -110,6 +110,8 @@ def installPoint = "$rootDir/GhidraDocs/languages/html"
def installHelpPoint = "../help/help"
def defaultStylePoint = "$rootDir/Ghidra/Framework/Help/src/main/resources/help/shared/DefaultStyle.css"
task buildDecompilerHelpHtml(type: Exec) {
workingDir 'src/main/doc'
@ -134,7 +136,7 @@ task buildDecompilerHelpHtml(type: Exec) {
xsltproc --output $buildDir/decomp_noscaling.xml --stringparam profile.condition "noscaling" commonprofile.xsl decompileplugin.xml 2>&1
xsltproc --stringparam base.dir ${installHelpPoint}/topics/DecompilePlugin/ --stringparam root.filename Decompiler decompileplugin_html.xsl $buildDir/decomp_noscaling.xml 2>&1
rm ${installHelpPoint}/topics/DecompilePlugin/Decompiler.html
sed -i -e '/Frontpage.css/ { p; s/Frontpage.css/languages.css/; }' ${installHelpPoint}/topics/DecompilePlugin/*.html 2>&1
sed -i -e '/DefaultStyle.css/ { p; sQhref=".*"Qhref="../../shared/languages.css"Q; }' ${installHelpPoint}/topics/DecompilePlugin/*.html 2>&1
echo '** Done. **'
"""
@ -174,6 +176,9 @@ task buildDecompilerHelpPdf(type: Exec) {
workingDir 'src/main/doc'
outputs.dir "$workingDir/$buildDir/pdf"
outputs.file "$workingDir/$buildDir/pdf/decompileplugin.pdf"
// 'which' returns the number of failed arguments
// Using 'which' first will allow the entire command to fail if the required
// executables are not installed.
@ -186,19 +191,25 @@ task buildDecompilerHelpPdf(type: Exec) {
echo '** Checking if required executables are installed. **'
which fop 2>&1
which xsltproc 2>&1
rm -f $buildDir/decompileplugin.fo $buildDir/decompileplugin.pdf $buildDir/decompileplugin_withscaling.xml 2>&1
rm -rf $buildDir/images 2>&1
mkdir -p $buildDir/images 2>&1
cp $installHelpPoint/topics/DecompilePlugin/images/*.png $buildDir/images 2>&1
cp $installHelpPoint/topics/DecompilePlugin/images/*.gif $buildDir/images 2>&1
cp $installHelpPoint/shared/*.png $buildDir/images 2>&1
mkdir -p $buildDir/pdf/images 2>&1
cp $installHelpPoint/topics/DecompilePlugin/images/*.png $buildDir/pdf/images 2>&1
cp ../resources/images/decompileFunction.gif $buildDir/pdf/images 2>&1
cp ../../../../../Framework/Help/src/main/resources/help/shared/warning.png $buildDir/pdf/images 2>&1
cp ../../../../../Framework/Help/src/main/resources/help/shared/tip.png $buildDir/pdf/images 2>&1
cp ../../../../../Framework/Help/src/main/resources/help/shared/note.png $buildDir/pdf/images 2>&1
cp ../../../../../Features/Base/src/main/resources/images/camera-photo.png $buildDir/pdf/images 2>&1
cp ../../../../../Framework/Gui/src/main/resources/images/openFolder.png $buildDir/pdf/images 2>&1
cp ../../../../../Framework/Gui/src/main/resources/images/reload3.png $buildDir/pdf/images 2>&1
cp ../../../../../Framework/Gui/src/main/resources/images/page_white_copy.png $buildDir/pdf/images 2>&1
cp ../../../../../Framework/Docking/src/main/resources/images/document-properties.png $buildDir/pdf/images 2>&1
cp ../../../../../Framework/Project/src/main/resources/images/page_edit.png $buildDir/pdf/images 2>&1
echo '** Building decompileplugin.fo **'
xsltproc --output $buildDir/decompileplugin_withscaling.xml --stringparam profile.condition "withscaling" commonprofile.xsl decompileplugin.xml 2>&1
xsltproc --output $buildDir/decompileplugin.fo decompileplugin_pdf.xsl $buildDir/decompileplugin_withscaling.xml 2>&1
xsltproc --output $buildDir/pdf/decompileplugin_withscaling.xml --stringparam profile.condition "withscaling" commonprofile.xsl decompileplugin.xml 2>&1
xsltproc --output $buildDir/pdf/decompileplugin.fo decompileplugin_pdf.xsl $buildDir/pdf/decompileplugin_withscaling.xml 2>&1
echo '** Building decompileplugin.pdf **'
fop $buildDir/decompileplugin.fo $buildDir/decompileplugin.pdf 2>&1
fop $buildDir/pdf/decompileplugin.fo $buildDir/pdf/decompileplugin.pdf 2>&1
echo '** Done. **'
"""
@ -323,12 +334,11 @@ task buildDecompilerDocumentationHtml(type: Exec) {
echo -e '** Building index.html **'
xsltproc --output $buildDir/index.html main_html.xsl main.xml 2>&1
sed -i -e '/Frontpage.css/ { p; s/Frontpage.css/languages.css/; }' $buildDir/index.html
sed -i -e '/DefaultStyle.css/ { p; sQhref=".*"Qhref="../../shared/languages.css"Q; }' $buildDir/index.html
echo '** Building html/sleigh.html **'
xsltproc --stringparam base.dir $buildDir/html/ --stringparam root.filename sleigh sleigh_html.xsl sleigh.xml 2>&1
sed -i -e '/Frontpage.css/ { p; s/Frontpage.css/languages.css/; }' $buildDir/html/sleigh*.html
cp $installPoint/Frontpage.css $buildDir/html 2>&1
cp $defaultStylePoint $buildDir/html 2>&1
cp $installPoint/languages.css $buildDir/html
cp $installPoint/Diagram1.png $buildDir/html
cp $installPoint/Diagram2.png $buildDir/html
@ -336,11 +346,9 @@ task buildDecompilerDocumentationHtml(type: Exec) {
echo '** Building html/pcoderef.html **'
xsltproc --stringparam base.dir $buildDir/html/ --stringparam root.filename pcoderef pcoderef_html.xsl pcoderef.xml 2>&1
sed -i -e '/Frontpage.css/ { p; s/Frontpage.css/languages.css/; }' $buildDir/html/pcoderef.html
sed -i -e '/Frontpage.css/ { p; s/Frontpage.css/languages.css/; }' $buildDir/html/pcodedescription.html
sed -i -e '/Frontpage.css/ { p; s/Frontpage.css/languages.css/; }' $buildDir/html/pseudo-ops.html
sed -i -e '/Frontpage.css/ { p; s/Frontpage.css/languages.css/; }' $buildDir/html/reference.html
cp $installPoint/Frontpage.css $buildDir/html
sed -i -e '/DefaultStyle.css/ { p; sQhref=".*"Qhref="languages.css"Q; }' $buildDir/html/*.html
cp $defaultStylePoint $buildDir/html
cp $installPoint/languages.css $buildDir/html
echo '** Installing html documentation. **'
@ -402,40 +410,25 @@ boolean isUpToDate(File srcFile, File resultFile) {
/**
* Create a bison task to compile a yacc file (*.y) for the sleigh/decompiler
*/
Task createBisonTask(String filename, String binaryName, boolean generateHeader, boolean qualifyVariables) {
Task createBisonTask(String filename, String binaryName, boolean generateHeader) {
def outputCppDir = "${cppSourceDir}"
def outputHeadersDir = "${cppSourceDir}"
def yaccFile = "${cppSourceDir}/${filename}.y"
def ccFile = "${outputCppDir}/${filename}.cc"
def headerFile = "${outputCppDir}/${filename}.hh"
def yaccFile = "${filename}.y"
def ccFile = "${filename}.cc"
def headerFile = "${filename}.hh"
return task("bison_${binaryName}_$filename", type: Exec) {
inputs.file "${yaccFile}"
outputs.file "${ccFile}"
inputs.file "${cppSourceDir}/${yaccFile}"
outputs.file "${cppSourceDir}/${ccFile}"
if (generateHeader) {
outputs.file "${headerFile}"
}
// doFirst {
// file(outputCppDir).mkdirs()
// file(outputHeadersDir)mkdirs()
// }
workingDir "${cppSourceDir}"
executable 'bison' // use bison program to process yacc files
// specify the bison's output file
args "-o", "${ccFile}"
// most of the yacc files should be compiled with a variable qualifyer to avoid dupes.
// Unfortunately there is one (slghparse) that can't use a qualifyer because it
// declares a variable used by other files.
if (qualifyVariables) {
args "-p", filename
}
// specify the bison's output file and that no #line directives should be generated
args "-l", "-o", "${ccFile}"
// tell bison where to put the hh file.
if (generateHeader) {
@ -452,25 +445,20 @@ Task createBisonTask(String filename, String binaryName, boolean generateHeader,
*/
Task createLexTask(String filename, String binaryName) {
def outputCppDir = "${cppSourceDir}"
def lexFile = "${cppSourceDir}/${filename}.l"
def ccFile = "${outputCppDir}/${filename}.cc"
def lexFile = "${filename}.l"
def ccFile = "${filename}.cc"
return task("lex_${binaryName}_$filename", type: Exec) {
// set up inputs and outputs so that gradle knows when this needs to be rebuilt
inputs.file "${lexFile}"
outputs.files "${ccFile}"
inputs.file "${cppSourceDir}/${lexFile}"
outputs.files "${cppSourceDir}/${ccFile}"
// doFirst {
// file(outputCppDir).mkdirs();
// }
workingDir "${cppSourceDir}"
executable 'flex' // the program to execute
// tell flex where to put the output
args "-o", "${ccFile}"
// tell flex where to put the output and not to generate #line directives
args "-L", "-o", "${ccFile}"
// tell flex the input file
args "${lexFile}"

View File

@ -31,6 +31,7 @@ src/decompile/datatests/impliedfield.xml||GHIDRA||||END|
src/decompile/datatests/indproto.xml||GHIDRA||||END|
src/decompile/datatests/injectoverride.xml||GHIDRA||||END|
src/decompile/datatests/loopcomment.xml||GHIDRA||||END|
src/decompile/datatests/lzcount.xml||GHIDRA||||END|
src/decompile/datatests/mixfloatint.xml||GHIDRA||||END|
src/decompile/datatests/modulo.xml||GHIDRA||||END|
src/decompile/datatests/modulo2.xml||GHIDRA||||END|

View File

@ -231,15 +231,15 @@ sla_opt/%.o: %.cc
$(CXX) $(ARCH_TYPE) -c $(OPT_CXXFLAGS) $(ADDITIONAL_FLAGS) $(SLEIGH_OPT) $< -o $@
grammar.cc: grammar.y
$(YACC) -p cparse -o $@ $<
$(YACC) -l -o $@ $<
xml.cc: xml.y
$(YACC) -p xml -o $@ $<
$(YACC) -l -o $@ $<
pcodeparse.cc: pcodeparse.y
$(YACC) -p pcode -o $@ $<
$(YACC) -l -o $@ $<
slghparse.cc: slghparse.y
$(YACC) -d -o $@ $<
$(YACC) -l -d -o $@ $<
slghscan.cc: slghscan.l
$(LEX) -o$@ $<
$(LEX) -L -o$@ $<
ruleparse.cc: ruleparse.y
$(YACC) -p ruleparse -d -o $@ $<

View File

@ -3619,6 +3619,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
@ -5390,6 +5391,7 @@ void ActionDatabase::universalAction(Architecture *conf)
actprop->addRule( new RulePopcountBoolXor("analysis") );
actprop->addRule( new RuleOrMultiBool("analysis") );
actprop->addRule( new RuleXorSwap("analysis") );
actprop->addRule( new RuleLzcountShiftBool("analysis") );
actprop->addRule( new RuleSubvarAnd("subvar") );
actprop->addRule( new RuleSubvarSubpiece("subvar") );
actprop->addRule( new RuleSplitFlow("subvar") );

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

@ -73,7 +73,8 @@
/* Pull parsers. */
#define YYPULL 1
/* Substitute the type names. */
#define YYSTYPE GRAMMARSTYPE
/* Substitute the variable and function names. */
#define yyparse grammarparse
#define yylex grammarlex
@ -85,16 +86,15 @@
#define yychar grammarchar
/* Copy the first part of user declarations. */
#line 16 "src/decompile/cpp/grammar.y" /* yacc.c:339 */
#include "grammar.hh"
extern int yylex(void);
extern int yyerror(const char *str);
extern int grammarlex(void);
extern int grammarerror(const char *str);
static CParse *parse;
extern int yydebug;
#line 83 "src/decompile/cpp/grammar.cc" /* yacc.c:339 */
# ifndef YY_NULLPTR
# if defined __cplusplus && 201103L <= __cplusplus
@ -114,17 +114,25 @@ extern int yydebug;
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#ifndef GRAMMARDEBUG
# if defined YYDEBUG
#if YYDEBUG
# define GRAMMARDEBUG 1
# else
# define GRAMMARDEBUG 0
# endif
# else /* ! defined YYDEBUG */
# define GRAMMARDEBUG 0
# endif /* ! defined YYDEBUG */
#endif /* ! defined GRAMMARDEBUG */
#if GRAMMARDEBUG
extern int grammardebug;
#endif
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
#ifndef GRAMMARTOKENTYPE
# define GRAMMARTOKENTYPE
enum grammartokentype
{
DOTDOTDOT = 258,
BADTOKEN = 259,
@ -143,11 +151,11 @@ extern int grammardebug;
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
#if ! defined GRAMMARSTYPE && ! defined GRAMMARSTYPE_IS_DECLARED
union YYSTYPE
union GRAMMARSTYPE
{
#line 25 "src/decompile/cpp/grammar.y" /* yacc.c:355 */
uint4 flags;
TypeDeclarator *dec;
@ -160,16 +168,16 @@ union YYSTYPE
string *str;
uintb *i;
#line 149 "src/decompile/cpp/grammar.cc" /* yacc.c:355 */
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
typedef union GRAMMARSTYPE GRAMMARSTYPE;
# define GRAMMARSTYPE_IS_TRIVIAL 1
# define GRAMMARSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE grammarlval;
extern GRAMMARSTYPE grammarlval;
int grammarparse (void);
@ -177,7 +185,7 @@ int grammarparse (void);
/* Copy the second part of user declarations. */
#line 166 "src/decompile/cpp/grammar.cc" /* yacc.c:358 */
#ifdef short
# undef short
@ -358,7 +366,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
#if (! defined yyoverflow \
&& (! defined __cplusplus \
|| (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
|| (defined GRAMMARSTYPE_IS_TRIVIAL && GRAMMARSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
@ -472,7 +480,7 @@ static const yytype_uint8 yytranslate[] =
15
};
#if YYDEBUG
#if GRAMMARDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
@ -487,7 +495,7 @@ static const yytype_uint8 yyrline[] =
};
#endif
#if YYDEBUG || YYERROR_VERBOSE || 0
#if GRAMMARDEBUG || YYERROR_VERBOSE || 0
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
@ -706,7 +714,7 @@ while (0)
/* Enable debugging if requested. */
#if YYDEBUG
#if GRAMMARDEBUG
# ifndef YYFPRINTF
# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
@ -827,12 +835,12 @@ do { \
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
int yydebug;
#else /* !YYDEBUG */
#else /* !GRAMMARDEBUG */
# define YYDPRINTF(Args)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */
#endif /* !GRAMMARDEBUG */
/* YYINITDEPTH -- initial size of the parser's stacks. */
@ -1343,427 +1351,427 @@ yyreduce:
switch (yyn)
{
case 2:
#line 60 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ parse->setResultDeclarations((yyvsp[0].declist)); }
#line 1334 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 3:
#line 61 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ vector<TypeDeclarator *> *res = parse->newVecDeclarator(); res->push_back((yyvsp[0].dec)); parse->setResultDeclarations(res); }
#line 1340 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 4:
#line 65 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = parse->mergeSpecDecVec((yyvsp[-1].spec)); }
#line 1346 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 5:
#line 66 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = parse->mergeSpecDecVec((yyvsp[-2].spec),(yyvsp[-1].declist)); }
#line 1352 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 6:
#line 70 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->newSpecifier(); parse->addSpecifier((yyval.spec),(yyvsp[0].str)); }
#line 1358 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 7:
#line 71 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->newSpecifier(); parse->addTypeSpecifier((yyval.spec),(yyvsp[0].type)); }
#line 1364 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 8:
#line 72 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->newSpecifier(); parse->addSpecifier((yyval.spec),(yyvsp[0].str)); }
#line 1370 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 9:
#line 73 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->newSpecifier(); parse->addFuncSpecifier((yyval.spec),(yyvsp[0].str)); }
#line 1376 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 10:
#line 74 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->addSpecifier((yyvsp[0].spec),(yyvsp[-1].str)); }
#line 1382 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 11:
#line 75 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->addTypeSpecifier((yyvsp[0].spec),(yyvsp[-1].type)); }
#line 1388 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 12:
#line 76 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->addSpecifier((yyvsp[0].spec),(yyvsp[-1].str)); }
#line 1394 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 13:
#line 77 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->addFuncSpecifier((yyvsp[0].spec),(yyvsp[-1].str)); }
#line 1400 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 14:
#line 81 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = parse->newVecDeclarator(); (yyval.declist)->push_back((yyvsp[0].dec)); }
#line 1406 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 15:
#line 82 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = (yyvsp[-2].declist); (yyval.declist)->push_back((yyvsp[0].dec)); }
#line 1412 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 16:
#line 86 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = (yyvsp[0].dec); }
#line 1418 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 17:
#line 91 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = (yyvsp[0].type); }
#line 1424 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 18:
#line 92 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = (yyvsp[0].type); }
#line 1430 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 19:
#line 93 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = (yyvsp[0].type); }
#line 1436 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 20:
#line 97 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->newStruct("",(yyvsp[-1].declist)); }
#line 1442 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 21:
#line 98 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->newStruct(*(yyvsp[-3].str),(yyvsp[-1].declist)); }
#line 1448 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 22:
#line 99 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->oldStruct(*(yyvsp[0].str)); }
#line 1454 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 23:
#line 100 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->newUnion("",(yyvsp[-1].declist)); }
#line 1460 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 24:
#line 101 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->newUnion(*(yyvsp[-3].str),(yyvsp[-1].declist)); }
#line 1466 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 25:
#line 102 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->oldUnion(*(yyvsp[0].str)); }
#line 1472 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 26:
#line 106 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = (yyvsp[0].declist); }
#line 1478 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 27:
#line 107 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = (yyvsp[-1].declist); (yyval.declist)->insert((yyval.declist)->end(),(yyvsp[0].declist)->begin(),(yyvsp[0].declist)->end()); }
#line 1484 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 28:
#line 111 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = parse->mergeSpecDecVec((yyvsp[-2].spec),(yyvsp[-1].declist)); }
#line 1490 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 29:
#line 115 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->newSpecifier(); parse->addTypeSpecifier((yyval.spec),(yyvsp[0].type)); }
#line 1496 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 30:
#line 116 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->addTypeSpecifier((yyvsp[0].spec),(yyvsp[-1].type)); }
#line 1502 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 31:
#line 117 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->newSpecifier(); parse->addSpecifier((yyval.spec),(yyvsp[0].str)); }
#line 1508 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 32:
#line 118 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.spec) = parse->addSpecifier((yyvsp[0].spec),(yyvsp[-1].str)); }
#line 1514 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 33:
#line 122 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = parse->newVecDeclarator(); (yyval.declist)->push_back((yyvsp[0].dec)); }
#line 1520 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 34:
#line 123 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = (yyvsp[-2].declist); (yyval.declist)->push_back((yyvsp[0].dec)); }
#line 1526 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 35:
#line 127 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = (yyvsp[0].dec); }
#line 1532 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 36:
#line 132 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->newEnum(*(yyvsp[-3].str),(yyvsp[-1].vecenum)); }
#line 1538 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 37:
#line 133 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->newEnum("",(yyvsp[-1].vecenum)); }
#line 1544 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 38:
#line 134 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->newEnum(*(yyvsp[-4].str),(yyvsp[-2].vecenum)); }
#line 1550 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 39:
#line 135 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->newEnum("",(yyvsp[-2].vecenum)); }
#line 1556 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 40:
#line 136 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.type) = parse->oldEnum(*(yyvsp[0].str)); }
#line 1562 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 41:
#line 140 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.vecenum) = parse->newVecEnumerator(); (yyval.vecenum)->push_back((yyvsp[0].enumer)); }
#line 1568 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 42:
#line 141 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.vecenum) = (yyvsp[-2].vecenum); (yyval.vecenum)->push_back((yyvsp[0].enumer)); }
#line 1574 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 43:
#line 145 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.enumer) = parse->newEnumerator(*(yyvsp[0].str)); }
#line 1580 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 44:
#line 146 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.enumer) = parse->newEnumerator(*(yyvsp[-2].str),*(yyvsp[0].i)); }
#line 1586 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 45:
#line 150 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = (yyvsp[0].dec); }
#line 1592 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 46:
#line 151 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->mergePointer((yyvsp[-1].ptrspec),(yyvsp[0].dec)); }
#line 1598 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 47:
#line 155 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->newDeclarator((yyvsp[0].str)); }
#line 1604 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 48:
#line 156 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = (yyvsp[-1].dec); }
#line 1610 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 49:
#line 157 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->newArray((yyvsp[-4].dec),(yyvsp[-2].flags),(yyvsp[-1].i)); }
#line 1616 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 50:
#line 158 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->newArray((yyvsp[-3].dec),0,(yyvsp[-1].i)); }
#line 1622 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 51:
#line 160 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->newFunc((yyvsp[-3].dec),(yyvsp[-1].declist)); }
#line 1628 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 52:
#line 165 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.ptrspec) = parse->newPointer(); (yyval.ptrspec)->push_back(0); }
#line 1634 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 53:
#line 166 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.ptrspec) = parse->newPointer(); (yyval.ptrspec)->push_back((yyvsp[0].flags)); }
#line 1640 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 54:
#line 167 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.ptrspec) = (yyvsp[0].ptrspec); (yyval.ptrspec)->push_back(0); }
#line 1646 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 55:
#line 168 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.ptrspec) = (yyvsp[0].ptrspec); (yyval.ptrspec)->push_back((yyvsp[-1].flags)); }
#line 1652 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 56:
#line 172 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.flags) = parse->convertFlag((yyvsp[0].str)); }
#line 1658 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 57:
#line 173 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.flags) = (yyvsp[-1].flags); (yyval.flags) |= parse->convertFlag((yyvsp[0].str)); }
#line 1664 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 58:
#line 177 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = (yyvsp[0].declist); }
#line 1670 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 59:
#line 178 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = (yyvsp[-2].declist); (yyval.declist)->push_back((TypeDeclarator *)0); }
#line 1676 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 60:
#line 182 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = parse->newVecDeclarator(); (yyval.declist)->push_back((yyvsp[0].dec)); }
#line 1682 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 61:
#line 183 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.declist) = (yyvsp[-2].declist); (yyval.declist)->push_back((yyvsp[0].dec)); }
#line 1688 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 62:
#line 187 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->mergeSpecDec((yyvsp[-1].spec),(yyvsp[0].dec)); }
#line 1694 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 63:
#line 188 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->mergeSpecDec((yyvsp[0].spec)); }
#line 1700 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 64:
#line 189 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->mergeSpecDec((yyvsp[-1].spec),(yyvsp[0].dec)); }
#line 1706 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 65:
#line 193 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->newDeclarator(); parse->mergePointer((yyvsp[0].ptrspec),(yyval.dec)); }
#line 1712 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 66:
#line 194 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = (yyvsp[0].dec); }
#line 1718 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 67:
#line 195 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->mergePointer((yyvsp[-1].ptrspec),(yyvsp[0].dec)); }
#line 1724 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 68:
#line 199 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = (yyvsp[-1].dec); }
#line 1730 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 69:
#line 201 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->newArray((yyvsp[-3].dec),0,(yyvsp[-1].i)); }
#line 1736 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 70:
#line 203 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.dec) = parse->newFunc((yyvsp[-3].dec),(yyvsp[-1].declist)); }
#line 1742 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
case 71:
#line 207 "src/decompile/cpp/grammar.y" /* yacc.c:1646 */
{ (yyval.i) = (yyvsp[0].i); }
#line 1748 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
break;
#line 1752 "src/decompile/cpp/grammar.cc" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@ -1991,7 +1999,7 @@ yyreturn:
#endif
return yyresult;
}
#line 210 "src/decompile/cpp/grammar.y" /* yacc.c:1906 */
void GrammarToken::set(uint4 tp)
@ -3114,13 +3122,13 @@ bool CParse::parseStream(istream &s,uint4 doctype)
return runParse(doctype);
}
int yylex(void)
int grammarlex(void)
{
return parse->lex();
}
int yyerror(const char *str)
int grammarerror(const char *str)
{
return 0;

View File

@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
%define api.prefix {grammar}
%{
#include "grammar.hh"
extern int yylex(void);
extern int yyerror(const char *str);
extern int grammarlex(void);
extern int grammarerror(const char *str);
static CParse *parse;
extern int yydebug;
%}
%union {
@ -1329,13 +1329,13 @@ bool CParse::parseStream(istream &s,uint4 doctype)
return runParse(doctype);
}
int yylex(void)
int grammarlex(void)
{
return parse->lex();
}
int yyerror(const char *str)
int grammarerror(const char *str)
{
return 0;

View File

@ -644,6 +644,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

File diff suppressed because it is too large Load Diff

View File

@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
%define api.prefix {pcode}
%{
#include "pcodeparse.hh"
//#define YYERROR_VERBOSE
extern int yylex(void);
extern int pcodelex(void);
static PcodeSnippet *pcode;
extern int yydebug;
extern int yyerror(const char *str );
extern int pcodeerror(const char *str );
%}
%union {
@ -800,11 +800,11 @@ void PcodeSnippet::addOperand(const string &name,int4 index)
addSymbol(sym);
}
int yylex(void) {
int pcodelex(void) {
return pcode->lex();
}
int yyerror(const char *s)
int pcodeerror(const char *s)
{
pcode->reportError((const Location *)0,s);

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

@ -10163,3 +10163,65 @@ int4 RuleXorSwap::applyOp(PcodeOp *op,Funcdata &data)
}
return 0;
}
/// \class RuleLzcountShiftBool
/// \brief Simplify equality checks that use lzcount: `lzcount(X) >> c => X == 0` if X is 2^c bits wide
///
/// Some compilers check if a value is equal to zero by checking the most
/// significant bit in lzcount; for instance on a 32-bit system,
/// the result of lzcount on zero would have the 5th bit set.
/// - `lzcount(a ^ 3) >> 5 => a ^ 3 == 0 => a == 3` (by RuleXorCollapse)
/// - `lzcount(a - 3) >> 5 => a - 3 == 0 => a == 3` (by RuleEqual2Zero)
void RuleLzcountShiftBool::getOpList(vector<uint4> &oplist) const
{
oplist.push_back(CPUI_LZCOUNT);
}
int4 RuleLzcountShiftBool::applyOp(PcodeOp *op,Funcdata &data)
{
Varnode *outVn = op->getOut();
list<PcodeOp *>::const_iterator iter, iter2;
uintb max_return = 8 * op->getIn(0)->getSize();
if (popcount(max_return) != 1) {
// This rule only makes sense with sizes that are powers of 2; if the maximum value
// returned by lzcount was, say, 24, then both 16 >> 4 and 24 >> 4
// are 1, and thus the check does not make sense. (Such processors couldn't
// use lzcount for checking equality in any case.)
return 0;
}
for(iter=outVn->beginDescend();iter!=outVn->endDescend();++iter) {
PcodeOp *baseOp = *iter;
if (baseOp->code() != CPUI_INT_RIGHT && baseOp->code() != CPUI_INT_SRIGHT) continue;
Varnode *vn1 = baseOp->getIn(1);
if (!vn1->isConstant()) continue;
uintb shift = vn1->getOffset();
if ((max_return >> shift) == 1) {
// Becomes a comparison with zero
PcodeOp* newOp = data.newOp(2, baseOp->getAddr());
data.opSetOpcode(newOp, CPUI_INT_EQUAL);
Varnode* b = data.newConstant(op->getIn(0)->getSize(), 0);
data.opSetInput(newOp, op->getIn(0), 0);
data.opSetInput(newOp, b, 1);
// CPUI_INT_EQUAL must produce a 1-byte boolean result
Varnode* eqResVn = data.newUniqueOut(1, newOp);
data.opInsertBefore(newOp, baseOp);
// Because the old output had size op->getIn(0)->getSize(),
// we have to guarantee that a Varnode of this size gets outputted
// to the descending PcodeOps. This is handled here with CPUI_INT_ZEXT.
data.opRemoveInput(baseOp, 1);
if (baseOp->getOut()->getSize() == 1)
data.opSetOpcode(baseOp, CPUI_COPY);
else
data.opSetOpcode(baseOp, CPUI_INT_ZEXT);
data.opSetInput(baseOp, eqResVn, 0);
return 1;
}
}
return 0;
}

View File

@ -1595,4 +1595,14 @@ public:
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
};
class RuleLzcountShiftBool : public Rule {
public:
RuleLzcountShiftBool(const string &g) : Rule( g, 0, "lzcountshiftbool") {} ///< Constructor
virtual Rule *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Rule *)0;
return new RuleLzcountShiftBool(getGroup());
}
virtual void getOpList(vector<uint4> &oplist) const;
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
};
#endif

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;
}

File diff suppressed because it is too large Load Diff

View File

@ -107,71 +107,72 @@ extern int yydebug;
OP_CPOOLREF = 302,
OP_NEW = 303,
OP_POPCOUNT = 304,
BADINTEGER = 305,
GOTO_KEY = 306,
CALL_KEY = 307,
RETURN_KEY = 308,
IF_KEY = 309,
DEFINE_KEY = 310,
ATTACH_KEY = 311,
MACRO_KEY = 312,
SPACE_KEY = 313,
TYPE_KEY = 314,
RAM_KEY = 315,
DEFAULT_KEY = 316,
REGISTER_KEY = 317,
ENDIAN_KEY = 318,
WITH_KEY = 319,
ALIGN_KEY = 320,
OP_UNIMPL = 321,
TOKEN_KEY = 322,
SIGNED_KEY = 323,
NOFLOW_KEY = 324,
HEX_KEY = 325,
DEC_KEY = 326,
BIG_KEY = 327,
LITTLE_KEY = 328,
SIZE_KEY = 329,
WORDSIZE_KEY = 330,
OFFSET_KEY = 331,
NAMES_KEY = 332,
VALUES_KEY = 333,
VARIABLES_KEY = 334,
PCODEOP_KEY = 335,
IS_KEY = 336,
LOCAL_KEY = 337,
DELAYSLOT_KEY = 338,
CROSSBUILD_KEY = 339,
EXPORT_KEY = 340,
BUILD_KEY = 341,
CONTEXT_KEY = 342,
ELLIPSIS_KEY = 343,
GLOBALSET_KEY = 344,
BITRANGE_KEY = 345,
CHAR = 346,
INTEGER = 347,
INTB = 348,
STRING = 349,
SYMBOLSTRING = 350,
SPACESYM = 351,
SECTIONSYM = 352,
TOKENSYM = 353,
USEROPSYM = 354,
VALUESYM = 355,
VALUEMAPSYM = 356,
CONTEXTSYM = 357,
NAMESYM = 358,
VARSYM = 359,
BITSYM = 360,
SPECSYM = 361,
VARLISTSYM = 362,
OPERANDSYM = 363,
STARTSYM = 364,
ENDSYM = 365,
NEXT2SYM = 366,
MACROSYM = 367,
LABELSYM = 368,
SUBTABLESYM = 369
OP_LZCOUNT = 305,
BADINTEGER = 306,
GOTO_KEY = 307,
CALL_KEY = 308,
RETURN_KEY = 309,
IF_KEY = 310,
DEFINE_KEY = 311,
ATTACH_KEY = 312,
MACRO_KEY = 313,
SPACE_KEY = 314,
TYPE_KEY = 315,
RAM_KEY = 316,
DEFAULT_KEY = 317,
REGISTER_KEY = 318,
ENDIAN_KEY = 319,
WITH_KEY = 320,
ALIGN_KEY = 321,
OP_UNIMPL = 322,
TOKEN_KEY = 323,
SIGNED_KEY = 324,
NOFLOW_KEY = 325,
HEX_KEY = 326,
DEC_KEY = 327,
BIG_KEY = 328,
LITTLE_KEY = 329,
SIZE_KEY = 330,
WORDSIZE_KEY = 331,
OFFSET_KEY = 332,
NAMES_KEY = 333,
VALUES_KEY = 334,
VARIABLES_KEY = 335,
PCODEOP_KEY = 336,
IS_KEY = 337,
LOCAL_KEY = 338,
DELAYSLOT_KEY = 339,
CROSSBUILD_KEY = 340,
EXPORT_KEY = 341,
BUILD_KEY = 342,
CONTEXT_KEY = 343,
ELLIPSIS_KEY = 344,
GLOBALSET_KEY = 345,
BITRANGE_KEY = 346,
CHAR = 347,
INTEGER = 348,
INTB = 349,
STRING = 350,
SYMBOLSTRING = 351,
SPACESYM = 352,
SECTIONSYM = 353,
TOKENSYM = 354,
USEROPSYM = 355,
VALUESYM = 356,
VALUEMAPSYM = 357,
CONTEXTSYM = 358,
NAMESYM = 359,
VARSYM = 360,
BITSYM = 361,
SPECSYM = 362,
VARLISTSYM = 363,
OPERANDSYM = 364,
STARTSYM = 365,
ENDSYM = 366,
NEXT2SYM = 367,
MACROSYM = 368,
LABELSYM = 369,
SUBTABLESYM = 370
};
#endif
@ -180,7 +181,7 @@ extern int yydebug;
union YYSTYPE
{
#line 29 "slghparse.y" /* yacc.c:1909 */
char ch;
uintb *i;
@ -225,7 +226,7 @@ union YYSTYPE
FamilySymbol *famsym;
SpecificSymbol *specsym;
#line 214 "slghparse.hh" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;

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; }

File diff suppressed because it is too large Load Diff

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

View File

@ -476,6 +476,7 @@ void ScoreUnionFields::scoreTrialDown(const Trial &trial,bool lastLevel)
case CPUI_INT_AND:
case CPUI_INT_OR:
case CPUI_POPCOUNT:
case CPUI_LZCOUNT:
if (meta == TYPE_ARRAY || meta == TYPE_STRUCT || meta == TYPE_UNION || meta == TYPE_CODE || meta == TYPE_FLOAT)
score = -5;
else if (meta == TYPE_PTR || meta == TYPE_BOOL)
@ -717,6 +718,7 @@ void ScoreUnionFields::scoreTrialUp(const Trial &trial,bool lastLevel)
case CPUI_INT_AND:
case CPUI_INT_OR:
case CPUI_POPCOUNT:
case CPUI_LZCOUNT:
if (meta == TYPE_ARRAY || meta == TYPE_STRUCT || meta == TYPE_UNION || meta == TYPE_CODE || meta == TYPE_FLOAT)
score = -5;
else if (meta == TYPE_PTR || meta == TYPE_BOOL)

View File

@ -73,7 +73,8 @@
/* Pull parsers. */
#define YYPULL 1
/* Substitute the type names. */
#define YYSTYPE XMLSTYPE
/* Substitute the variable and function names. */
#define yyparse xmlparse
#define yylex xmllex
@ -85,7 +86,7 @@
#define yychar xmlchar
/* Copy the first part of user declarations. */
#line 16 "src/decompile/cpp/xml.y" /* yacc.c:339 */
#include "xml.hh"
// CharData mode look for '<' '&' or "]]>"
@ -179,16 +180,15 @@ struct NameValue {
string *value; ///< The value
};
extern int yylex(void); ///< Interface to the scanner
extern int yyerror(const char *str); ///< Interface for registering an error in parsing
extern int xmllex(void); ///< Interface to the scanner
extern int xmlerror(const char *str); ///< Interface for registering an error in parsing
extern void print_content(const string &str); ///< Send character data to the ContentHandler
extern int4 convertEntityRef(const string &ref); ///< Convert an XML entity to its equivalent character
extern int4 convertCharRef(const string &ref); ///< Convert an XML character reference to its equivalent character
static XmlScan *global_scan; ///< Global reference to the scanner
static ContentHandler *handler; ///< Global reference to the content handler
extern int yydebug; ///< Debug mode
#line 177 "src/decompile/cpp/xml.cc" /* yacc.c:339 */
# ifndef YY_NULLPTR
# if defined __cplusplus && 201103L <= __cplusplus
@ -208,17 +208,25 @@ extern int yydebug; ///< Debug mode
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#ifndef XMLDEBUG
# if defined YYDEBUG
#if YYDEBUG
# define XMLDEBUG 1
# else
# define XMLDEBUG 0
# endif
# else /* ! defined YYDEBUG */
# define XMLDEBUG 0
# endif /* ! defined YYDEBUG */
#endif /* ! defined XMLDEBUG */
#if XMLDEBUG
extern int xmldebug;
#endif
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
#ifndef XMLTOKENTYPE
# define XMLTOKENTYPE
enum xmltokentype
{
CHARDATA = 258,
CDATA = 259,
@ -233,27 +241,27 @@ extern int xmldebug;
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
#if ! defined XMLSTYPE && ! defined XMLSTYPE_IS_DECLARED
union YYSTYPE
union XMLSTYPE
{
#line 119 "src/decompile/cpp/xml.y" /* yacc.c:355 */
int4 i;
string *str;
Attributes *attr;
NameValue *pair;
#line 233 "src/decompile/cpp/xml.cc" /* yacc.c:355 */
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
typedef union XMLSTYPE XMLSTYPE;
# define XMLSTYPE_IS_TRIVIAL 1
# define XMLSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE xmllval;
extern XMLSTYPE xmllval;
int xmlparse (void);
@ -261,7 +269,7 @@ int xmlparse (void);
/* Copy the second part of user declarations. */
#line 250 "src/decompile/cpp/xml.cc" /* yacc.c:358 */
#ifdef short
# undef short
@ -442,7 +450,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
#if (! defined yyoverflow \
&& (! defined __cplusplus \
|| (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
|| (defined XMLSTYPE_IS_TRIVIAL && XMLSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
@ -555,7 +563,7 @@ static const yytype_uint8 yytranslate[] =
5, 6, 7, 8, 9, 10, 11
};
#if YYDEBUG
#if XMLDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
@ -570,7 +578,7 @@ static const yytype_uint8 yyrline[] =
};
#endif
#if YYDEBUG || YYERROR_VERBOSE || 0
#if XMLDEBUG || YYERROR_VERBOSE || 0
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
@ -815,7 +823,7 @@ while (0)
/* Enable debugging if requested. */
#if YYDEBUG
#if XMLDEBUG
# ifndef YYFPRINTF
# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
@ -936,12 +944,12 @@ do { \
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
int yydebug;
#else /* !YYDEBUG */
#else /* !XMLDEBUG */
# define YYDPRINTF(Args)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */
#endif /* !XMLDEBUG */
/* YYINITDEPTH -- initial size of the parser's stacks. */
@ -1452,259 +1460,259 @@ yyreduce:
switch (yyn)
{
case 10:
#line 144 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = new string; global_scan->setmode(XmlScan::AttValueSingleMode); }
#line 1443 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 11:
#line 145 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-1].str); *(yyval.str) += *(yyvsp[0].str); delete (yyvsp[0].str); global_scan->setmode(XmlScan::AttValueSingleMode); }
#line 1449 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 12:
#line 146 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-1].str); *(yyval.str) += (yyvsp[0].i); global_scan->setmode(XmlScan::AttValueSingleMode); }
#line 1455 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 13:
#line 147 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = new string; global_scan->setmode(XmlScan::AttValueDoubleMode); }
#line 1461 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 14:
#line 148 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-1].str); *(yyval.str) += *(yyvsp[0].str); delete (yyvsp[0].str); global_scan->setmode(XmlScan::AttValueDoubleMode); }
#line 1467 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 15:
#line 149 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-1].str); *(yyval.str) += (yyvsp[0].i); global_scan->setmode(XmlScan::AttValueDoubleMode); }
#line 1473 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 16:
#line 150 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-1].str); }
#line 1479 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 17:
#line 151 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-1].str); }
#line 1485 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 18:
#line 152 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ global_scan->setmode(XmlScan::NameMode); delete (yyvsp[0].str); }
#line 1491 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 19:
#line 153 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ global_scan->setmode(XmlScan::CommentMode); delete (yyvsp[-3].str); }
#line 1497 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 20:
#line 154 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ delete (yyvsp[-3].str); }
#line 1503 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 21:
#line 155 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ delete (yyvsp[-1].str); yyerror("Processing instructions are not supported"); YYERROR; }
#line 1509 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 22:
#line 156 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-1].str); }
#line 1515 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 23:
#line 157 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ global_scan->setmode(XmlScan::CDataMode); delete (yyvsp[-8].str); }
#line 1521 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 32:
#line 168 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ delete (yyvsp[-8].str); yyerror("DTD's not supported"); YYERROR; }
#line 1527 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 39:
#line 176 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ handler->setVersion(*(yyvsp[0].str)); delete (yyvsp[0].str); }
#line 1533 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 40:
#line 177 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ handler->setEncoding(*(yyvsp[0].str)); delete (yyvsp[0].str); }
#line 1539 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 46:
#line 184 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ handler->endElement((yyvsp[0].attr)->getelemURI(),(yyvsp[0].attr)->getelemName(),(yyvsp[0].attr)->getelemName()); delete (yyvsp[0].attr); }
#line 1545 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 47:
#line 185 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ handler->endElement((yyvsp[-2].attr)->getelemURI(),(yyvsp[-2].attr)->getelemName(),(yyvsp[-2].attr)->getelemName()); delete (yyvsp[-2].attr); delete (yyvsp[0].str); }
#line 1551 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 48:
#line 187 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ handler->startElement((yyvsp[-1].attr)->getelemURI(),(yyvsp[-1].attr)->getelemName(),(yyvsp[-1].attr)->getelemName(),*(yyvsp[-1].attr)); (yyval.attr) = (yyvsp[-1].attr); }
#line 1557 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 49:
#line 188 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ handler->startElement((yyvsp[-2].attr)->getelemURI(),(yyvsp[-2].attr)->getelemName(),(yyvsp[-2].attr)->getelemName(),*(yyvsp[-2].attr)); (yyval.attr) = (yyvsp[-2].attr); }
#line 1563 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 50:
#line 189 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ handler->startElement((yyvsp[-2].attr)->getelemURI(),(yyvsp[-2].attr)->getelemName(),(yyvsp[-2].attr)->getelemName(),*(yyvsp[-2].attr)); (yyval.attr) = (yyvsp[-2].attr); }
#line 1569 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 51:
#line 190 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ handler->startElement((yyvsp[-3].attr)->getelemURI(),(yyvsp[-3].attr)->getelemName(),(yyvsp[-3].attr)->getelemName(),*(yyvsp[-3].attr)); (yyval.attr) = (yyvsp[-3].attr); }
#line 1575 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 52:
#line 192 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.attr) = new Attributes((yyvsp[0].str)); global_scan->setmode(XmlScan::SNameMode); }
#line 1581 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 53:
#line 193 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.attr) = (yyvsp[-1].attr); (yyval.attr)->add_attribute( (yyvsp[0].pair)->name, (yyvsp[0].pair)->value); delete (yyvsp[0].pair); global_scan->setmode(XmlScan::SNameMode); }
#line 1587 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 54:
#line 194 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.pair) = new NameValue; (yyval.pair)->name = (yyvsp[-2].str); (yyval.pair)->value = (yyvsp[0].str); }
#line 1593 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 55:
#line 195 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ global_scan->setmode(XmlScan::NameMode); delete (yyvsp[-1].str); }
#line 1599 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 56:
#line 196 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-1].str); }
#line 1605 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 57:
#line 197 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-2].str); }
#line 1611 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 58:
#line 199 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ global_scan->setmode(XmlScan::CharDataMode); }
#line 1617 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 59:
#line 200 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ print_content( *(yyvsp[0].str) ); delete (yyvsp[0].str); global_scan->setmode(XmlScan::CharDataMode); }
#line 1623 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 60:
#line 201 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ global_scan->setmode(XmlScan::CharDataMode); }
#line 1629 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 61:
#line 202 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ string *tmp=new string(); *tmp += (yyvsp[0].i); print_content(*tmp); delete tmp; global_scan->setmode(XmlScan::CharDataMode); }
#line 1635 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 62:
#line 203 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ print_content( *(yyvsp[0].str) ); delete (yyvsp[0].str); global_scan->setmode(XmlScan::CharDataMode); }
#line 1641 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 63:
#line 204 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ global_scan->setmode(XmlScan::CharDataMode); }
#line 1647 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 64:
#line 205 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ global_scan->setmode(XmlScan::CharDataMode); }
#line 1653 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 65:
#line 207 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.i) = convertEntityRef(*(yyvsp[0].str)); delete (yyvsp[0].str); }
#line 1659 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 66:
#line 208 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.i) = convertCharRef(*(yyvsp[0].str)); delete (yyvsp[0].str); }
#line 1665 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 67:
#line 210 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ global_scan->setmode(XmlScan::NameMode); }
#line 1671 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 68:
#line 211 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ global_scan->setmode(XmlScan::CharRefMode); }
#line 1677 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 69:
#line 212 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-1].str); }
#line 1683 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
case 70:
#line 213 "src/decompile/cpp/xml.y" /* yacc.c:1646 */
{ (yyval.str) = (yyvsp[-1].str); }
#line 1689 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
break;
#line 1693 "src/decompile/cpp/xml.cc" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@ -1932,7 +1940,7 @@ yyreturn:
#endif
return yyresult;
}
#line 214 "src/decompile/cpp/xml.y" /* yacc.c:1906 */
XmlScan::XmlScan(istream &t) : s(t)
@ -2217,7 +2225,7 @@ int4 convertCharRef(const string &ref)
return val;
}
int yylex(void)
int xmllex(void)
{
int res = global_scan->nexttoken();
@ -2226,7 +2234,7 @@ int yylex(void)
return res;
}
int yyerror(const char *str)
int xmlerror(const char *str)
{
handler->setError(str);

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
%define api.prefix {xml}
%{
#include "xml.hh"
// CharData mode look for '<' '&' or "]]>"
@ -106,14 +107,13 @@ struct NameValue {
string *value; ///< The value
};
extern int yylex(void); ///< Interface to the scanner
extern int yyerror(const char *str); ///< Interface for registering an error in parsing
extern int xmllex(void); ///< Interface to the scanner
extern int xmlerror(const char *str); ///< Interface for registering an error in parsing
extern void print_content(const string &str); ///< Send character data to the ContentHandler
extern int4 convertEntityRef(const string &ref); ///< Convert an XML entity to its equivalent character
extern int4 convertCharRef(const string &ref); ///< Convert an XML character reference to its equivalent character
static XmlScan *global_scan; ///< Global reference to the scanner
static ContentHandler *handler; ///< Global reference to the content handler
extern int yydebug; ///< Debug mode
%}
%union {
@ -495,7 +495,7 @@ int4 convertCharRef(const string &ref)
return val;
}
int yylex(void)
int xmllex(void)
{
int res = global_scan->nexttoken();
@ -504,7 +504,7 @@ int yylex(void)
return res;
}
int yyerror(const char *str)
int xmlerror(const char *str)
{
handler->setError(str);

View File

@ -0,0 +1,17 @@
<decompilertest>
<!-- Example of a "Count Leading Zeros" instruction (cntlzw) being used as a zero test -->
<binaryimage arch="PowerPC:BE:32:default:default">
<bytechunk space="ram" offset="0x10020" readonly="true">
686300037c6300345463d97e4e800020
</bytechunk>
<symbol space="ram" offset="0x10020" name="cntlzwtest"/>
</binaryimage>
<script>
<com>lo fu cntlzwtest</com>
<com>decompile</com>
<com>print C</com>
<com>quit</com>
</script>
<stringmatch name = "Leading zeros count #1" min="1" max="1">return param_1 == 3;</stringmatch>
<stringmatch name = "Leading zeros count #2" min="0" max="0">lzcount</stringmatch>
</decompilertest>

View File

@ -25,7 +25,7 @@
<xsl:param name="use.id.as.filename" select="1"/> <!-- Split up into files based on id attribute -->
<xsl:param name="html.stylesheet" select="'Frontpage.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="html.stylesheet" select="'DefaultStyle.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="chunker.output.indent" select="'yes'"/> <!-- Do proper indenting of html -->

View File

@ -40,11 +40,15 @@
</xsl:element>
</xsl:template>
<xsl:template name="body.attributes">
<!-- Remove all BODY attributes so that CSS stylesheet can provide everything -->
</xsl:template>
<xsl:param name="suppress.navigation" select="1"/> <!-- Turn off header/footer navigation links -->
<xsl:param name="use.id.as.filename" select="1"/> <!-- Split up into files based on id attribute -->
<xsl:param name="html.stylesheet" select="'../../shared/Frontpage.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="html.stylesheet" select="'help/shared/DefaultStyle.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="chunk.section.depth" select="0"/>
@ -54,5 +58,5 @@
<xsl:param name="admon.textlabel" select="0"/> <!-- Don't display title for important/note tags -->
<xsl:param name="admon.graphics.path" select="'../../shared/'"/>
<xsl:param name="admon.graphics.path" select="'help/shared/'"/>
</xsl:stylesheet>

View File

@ -35,6 +35,6 @@
<xsl:param name="admon.textlabel" select="0"/> <!-- Don't display title for important/note tags -->
<xsl:param name="admon.graphics.path" select="'../../../build/images'"/>
<xsl:param name="admon.graphics.path" select="'../../../build/pdf/images/'"/>
</xsl:stylesheet>

View File

@ -23,7 +23,7 @@
set toc,title
</xsl:param>
<xsl:param name="html.stylesheet" select="'html/Frontpage.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="html.stylesheet" select="'html/DefaultStyle.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:output method="html"
encoding="UTF8"

View File

@ -2,7 +2,7 @@
<article id="pcoderef_title">
<info>
<title>P-Code Reference Manual</title>
<releaseinfo>Last updated September 5, 2019</releaseinfo>
<releaseinfo>Last updated March 2, 2023</releaseinfo>
</info>
<table xml:id="mytoc.htmltable" width="90%" frame='none'>
<col width="25%"/>
@ -22,7 +22,7 @@
<td><link linkend="cpui_int_sub">INT_SUB</link></td>
<td><link linkend="cpui_float_equal">FLOAT_EQUAL</link></td>
</tr>
<tr>P
<tr>
<td></td>
<td><link linkend="cpui_store">STORE</link></td>
<td><link linkend="cpui_int_carry">INT_CARRY</link></td>
@ -90,52 +90,58 @@
</tr>
<tr>
<td></td>
<td><link linkend="cpui_int_equal">INT_EQUAL</link></td>
<td><link linkend="cpui_lzcount">LZCOUNT</link></td>
<td><link linkend="cpui_int_mult">INT_MULT</link></td>
<td><link linkend="cpui_float_floor">FLOAT_FLOOR</link></td>
</tr>
<tr>
<td></td>
<td><link linkend="cpui_int_notequal">INT_NOTEQUAL</link></td>
<td><link linkend="cpui_int_equal">INT_EQUAL</link></td>
<td><link linkend="cpui_int_div">INT_DIV</link></td>
<td><link linkend="cpui_float_round">FLOAT_ROUND</link></td>
</tr>
<tr>
<td></td>
<td><link linkend="cpui_int_less">INT_LESS</link></td>
<td><link linkend="cpui_int_notequal">INT_NOTEQUAL</link></td>
<td><link linkend="cpui_int_rem">INT_REM</link></td>
<td><link linkend="cpui_float_nan">FLOAT_NAN</link></td>
</tr>
<tr>
<td></td>
<td><link linkend="cpui_int_sless">INT_SLESS</link></td>
<td><link linkend="cpui_int_less">INT_LESS</link></td>
<td><link linkend="cpui_int_sdiv">INT_SDIV</link></td>
<td><link linkend="cpui_int2float">INT2FLOAT</link></td>
</tr>
<tr>
<td></td>
<td><link linkend="cpui_int_lessequal">INT_LESSEQUAL</link></td>
<td><link linkend="cpui_int_sless">INT_SLESS</link></td>
<td><link linkend="cpui_int_srem">INT_SREM</link></td>
<td><link linkend="cpui_float2float">FLOAT2FLOAT</link></td>
</tr>
<tr>
<td></td>
<td><link linkend="cpui_int_slessequal">INT_SLESSEQUAL</link></td>
<td><link linkend="cpui_int_lessequal">INT_LESSEQUAL</link></td>
<td><link linkend="cpui_bool_negate">BOOL_NEGATE</link></td>
<td><link linkend="cpui_trunc">TRUNC</link></td>
</tr>
<tr>
<td></td>
<td><link linkend="cpui_int_zext">INT_ZEXT</link></td>
<td><link linkend="cpui_int_slessequal">INT_SLESSEQUAL</link></td>
<td><link linkend="cpui_bool_xor">BOOL_XOR</link></td>
<td><link linkend="cpui_cpoolref">CPOOLREF</link></td>
</tr>
<tr>
<td></td>
<td><link linkend="cpui_int_sext">INT_SEXT</link></td>
<td><link linkend="cpui_int_zext">INT_ZEXT</link></td>
<td><link linkend="cpui_bool_and">BOOL_AND</link></td>
<td><link linkend="cpui_new">NEW</link></td>
</tr>
<tr>
<td></td>
<td><link linkend="cpui_int_sext">INT_SEXT</link></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<sect1 id="index">
@ -977,6 +983,50 @@ count is zero extended into the output varnode.
</para>
</sect2>
<sect2 id="cpui_lzcount"><title>LZCOUNT</title>
<informalexample>
<table xml:id="lzcount.htmltable" frame="above" width="80%" rules="groups">
<col width="23%"/>
<col width="15%"/>
<col width="61%"/>
<thead>
<tr>
<td align="center" colspan="2"><emphasis role="bold">Parameters</emphasis></td>
<td><emphasis role="bold">Description</emphasis></td>
</tr>
</thead>
<tbody>
<tr>
<td align='right'>input0</td>
<td/>
<td>Input varnode to count.</td>
</tr>
<tr>
<td align='right'>output</td>
<td/>
<td>Resulting integer varnode containing count.</td>
</tr>
</tbody>
<tfoot>
<tr>
<td align="center" colspan="2"><emphasis role="bold">Semantic statement</emphasis></td>
<td/>
</tr>
<tr>
<td/>
<td colspan="2"><code>output = lzcount(input0);</code></td>
</tr>
</tfoot>
</table>
</informalexample>
<para>
This operator counts the number of zeros starting at the most significant bit.
For instance, for a 4-byte varnode, a value of 0 returns 32, a value of 1
returns 31, and the value 2<superscript>31</superscript> returns 0.
The resulting count is zero extended into the output varnode.
</para>
</sect2>
<sect2 id="cpui_int_equal"><title>INT_EQUAL</title>
<informalexample>
<table xml:id="intequal.htmltable" frame="above" width="80%" rules="groups">
@ -4058,6 +4108,11 @@ to SLEIGH <emphasis role="bold">bitrange</emphasis> syntax such as output = inpu
<td><code>popcount(v0)</code></td>
<td>Count 1 bits in v0.</td>
</tr>
<tr>
<td>LZCOUNT</td>
<td><code>lzcount(v0)</code></td>
<td>Counts the number of leading zero bits in v0.</td>
</tr>
<tr>
<td>INT_EQUAL</td>
<td><code>v0 == v1</code></td>

View File

@ -8,7 +8,7 @@
<xsl:param name="use.id.as.filename" select="1"/> <!-- Split up into files based on id attribute -->
<xsl:param name="html.stylesheet" select="'Frontpage.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="html.stylesheet" select="'DefaultStyle.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="chunker.output.indent" select="'yes'"/> <!-- Do proper indenting of html -->

View File

@ -4,7 +4,7 @@
<title>SLEIGH</title>
<subtitle>A Language for Rapid Processor Specification</subtitle>
<pubdate>Originally published December 16, 2005</pubdate>
<releaseinfo>Last updated August 24, 2022</releaseinfo>
<releaseinfo>Last updated March 2, 2023</releaseinfo>
</info>
<simplesect id="sleigh_history">
<info>
@ -279,7 +279,8 @@ general purpose processor instruction sets. They break up into groups.
</tr>
<tr>
<td>Logical</td>
<td><code>INT_NEGATE, INT_XOR, INT_AND, INT_OR, INT_LEFT, INT_RIGHT, INT_SRIGHT, POPCOUNT</code></td>
<td><code>INT_NEGATE, INT_XOR, INT_AND, INT_OR, INT_LEFT, INT_RIGHT, INT_SRIGHT,
POPCOUNT, LZCOUNT</code></td>
</tr>
<tr>
<td>Integer Comparison</td>
@ -3856,6 +3857,12 @@ to lowest.
<td>Count the number of 1 bits in v0.
</td>
</tr>
<tr>
<td><code>LZCOUNT</code></td>
<td><code>lzcount(v0)</code></td>
<td>Count the number of leading 0 bits in v0.
</td>
</tr>
<tr>
<td><code>(simulated)</code></td>
<td><code>v0[6,1]</code></td>

View File

@ -8,7 +8,7 @@
<xsl:param name="use.id.as.filename" select="1"/> <!-- Split up into files based on id attribute -->
<xsl:param name="html.stylesheet" select="'Frontpage.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="html.stylesheet" select="'DefaultStyle.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="chunker.output.indent" select="'yes'"/> <!-- Do proper indenting of html -->

View File

@ -3,14 +3,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Program Annotations Affecting the Decompiler</title>
<link rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="help/shared/languages.css">
<link rel="stylesheet" type="text/css" href="../../shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="Decompiler.html" title="Decompiler">
<link rel="up" href="Decompiler.html" title="Decompiler">
<link rel="prev" href="DecompilerConcepts.html" title="Decompiler Concepts">
<link rel="next" href="DecompilerOptions.html" title="Decompiler Options">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter">
<body><div class="chapter">
<div class="titlepage"><div><div><h1 class="title">
<a name="DecompilerAnnotations"></a>Program Annotations Affecting the Decompiler</h1></div></div></div>

View File

@ -3,14 +3,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Decompiler Concepts</title>
<link rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="help/shared/languages.css">
<link rel="stylesheet" type="text/css" href="../../shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="Decompiler.html" title="Decompiler">
<link rel="up" href="Decompiler.html" title="Decompiler">
<link rel="prev" href="DecompilerIntro.html" title="Decompiler">
<link rel="next" href="DecompilerAnnotations.html" title="Program Annotations Affecting the Decompiler">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter">
<body><div class="chapter">
<div class="titlepage"><div><div><h1 class="title">
<a name="DecompilerConcepts"></a>Decompiler Concepts</h1></div></div></div>
@ -182,7 +182,7 @@
</p>
<div class="informalexample">
<div class="table">
<a name="ops.htmltable"></a><p class="title"><b>Table<EFBFBD>.<2E>P-code Operations</b></p>
<a name="ops.htmltable"></a><p class="title"><b>Table . P-code Operations</b></p>
<div class="table-contents"><table width="90%" frame="box" rules="all" id="ops.htmltable">
<col width="40%">

View File

@ -3,14 +3,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Decompiler</title>
<link rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="help/shared/languages.css">
<link rel="stylesheet" type="text/css" href="../../shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="Decompiler.html" title="Decompiler">
<link rel="up" href="Decompiler.html" title="Decompiler">
<link rel="prev" href="Decompiler.html" title="Decompiler">
<link rel="next" href="DecompilerConcepts.html" title="Decompiler Concepts">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter">
<body><div class="chapter">
<div class="titlepage"><div><div><h1 class="title">
<a name="DecompilerIntro"></a>Decompiler</h1></div></div></div>
@ -64,7 +64,7 @@
<li class="listitem" style="list-style-type: disc">
Press the <span class="guiicon">
<span class="inlinemediaobject"><img src="images/decompileFunction.gif" width="16" height="16"></span>
</span><EFBFBD>icon
</span> icon
in the tool bar, <span class="emphasis"><em>or</em></span>
</li>
<li class="listitem" style="list-style-type: disc">

View File

@ -3,14 +3,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Decompiler Options</title>
<link rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="help/shared/languages.css">
<link rel="stylesheet" type="text/css" href="../../shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="Decompiler.html" title="Decompiler">
<link rel="up" href="Decompiler.html" title="Decompiler">
<link rel="prev" href="DecompilerAnnotations.html" title="Program Annotations Affecting the Decompiler">
<link rel="next" href="DecompilerWindow.html" title="Decompiler Window">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter">
<body><div class="chapter">
<div class="titlepage"><div><div><h1 class="title">
<a name="DecompilerOptions"></a>Decompiler Options</h1></div></div></div>
@ -40,12 +40,12 @@
<li class="listitem" style="list-style-type: none">
&#8195;<span class="guiicon">
<span class="inlinemediaobject"><img src="images/document-properties.png" width="16" height="16"></span>
</span><EFBFBD><span class="emphasis"><em>Analysis</em></span> - lists <a class="xref" href="DecompilerOptions.html#AnalysisOptions" title="Analysis Options">Analysis Options</a> that affect the Decompiler's transformation process.
</span> <span class="emphasis"><em>Analysis</em></span> - lists <a class="xref" href="DecompilerOptions.html#AnalysisOptions" title="Analysis Options">Analysis Options</a> that affect the Decompiler's transformation process.
</li>
<li class="listitem" style="list-style-type: none">
&#8195;<span class="guiicon">
<span class="inlinemediaobject"><img src="images/document-properties.png" width="16" height="16"></span>
</span><EFBFBD><span class="emphasis"><em>Display</em></span> - lists <a class="xref" href="DecompilerOptions.html#DisplayOptions" title="Display Options">Display Options</a> that affect the final presentation of Decompiler output.
</span> <span class="emphasis"><em>Display</em></span> - lists <a class="xref" href="DecompilerOptions.html#DisplayOptions" title="Display Options">Display Options</a> that affect the final presentation of Decompiler output.
</li>
</ul></div>
</div>

View File

@ -3,13 +3,13 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Decompiler Window</title>
<link rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="help/shared/languages.css">
<link rel="stylesheet" type="text/css" href="../../shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="Decompiler.html" title="Decompiler">
<link rel="up" href="Decompiler.html" title="Decompiler">
<link rel="prev" href="DecompilerOptions.html" title="Decompiler Options">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter">
<body><div class="chapter">
<div class="titlepage"><div><div><h1 class="title">
<a name="DecompilerWindow"></a>Decompiler Window</h1></div></div></div>
@ -18,7 +18,7 @@
function in the Code Browser, then select the
<span class="guiicon">
<span class="inlinemediaobject"><img src="images/decompileFunction.gif" width="16" height="16"></span>
</span><EFBFBD>icon from the tool bar, or the
</span> icon from the tool bar, or the
<span class="bold"><strong>Decompile</strong></span> option from the
<span class="bold"><strong>Window</strong></span> menu in the tool.
</p>
@ -91,7 +91,7 @@
Initially pressing
<span class="guiicon">
<span class="inlinemediaobject"><img src="images/decompileFunction.gif" width="16" height="16"></span>
</span><EFBFBD>or selecting
</span> or selecting
<span class="bold"><strong>Decompile</strong></span> from the <span class="bold"><strong>Window</strong></span> menu in the tool
brings up the <span class="emphasis"><em>main</em></span> window. The main window always displays the function
at the <span class="emphasis"><em>current address</em></span> within the Code Browser and follows as the user navigates
@ -153,7 +153,7 @@
Pressing the
<span class="guiicon">
<span class="inlinemediaobject"><img src="images/camera-photo.png" width="16" height="16"></span>
</span><EFBFBD>icon
</span> icon
in any Decompiler window's toolbar causes a <span class="emphasis"><em>Snapshot</em></span> window
to be created, which shows decompilation of the same function.
Unlike the <span class="emphasis"><em>main</em></span> window however, the <span class="emphasis"><em>Snapshot</em></span> window
@ -240,7 +240,7 @@
<p>
<span class="guiicon">
<span class="inlinemediaobject"><img src="images/page_edit.png" width="16" height="16"></span>
</span><EFBFBD>- button
</span> - button
</p>
<p>
Exports the decompiled result of the current function to a file. A file chooser
@ -265,7 +265,7 @@
<p>
<span class="guiicon">
<span class="inlinemediaobject"><img src="images/camera-photo.png" width="16" height="16"></span>
</span><EFBFBD>- button
</span> - button
</p>
<p>
Creates a new <span class="emphasis"><em>Snapshot</em></span> window. The <span class="emphasis"><em>Snapshot</em></span> window
@ -282,7 +282,7 @@
<p>
<span class="guiicon">
<span class="inlinemediaobject"><img src="images/reload3.png" width="16" height="16"></span>
</span><EFBFBD>- button
</span> - button
</p>
<p>
Triggers a re-decompilation of the current function displayed in the window.
@ -310,7 +310,7 @@
<p>
<span class="guiicon">
<span class="inlinemediaobject"><img src="images/page_white_copy.png" width="16" height="16"></span>
</span><EFBFBD>- button
</span> - button
</p>
<p>
Copies the currently selected text in the Decompiler window to the clipboard.

View File

@ -62,7 +62,7 @@ task unpackFidDatabases {
// Relative to the 'workingDir' Exec task property.
def installPoint = "../help/help"
task buildFidDocumentationPdf(type: Exec) {
task buildFidHelpPdf(type: Exec) {
workingDir 'src/main/doc'
@ -91,7 +91,7 @@ task buildFidDocumentationPdf(type: Exec) {
cp $installPoint/topics/FunctionID/images/*.png $buildDir/images
echo '** Building FunctionID.fo **'
xsltproc --output $buildDir/fid_withscaling.xml --stringparam profile.condition "withscaling" /usr/share/sgml/docbook/xsl-stylesheets/profiling/profile.xsl fid.xml 2>&1
xsltproc --output $buildDir/fid_withscaling.xml --stringparam profile.condition "withscaling" commonprofile.xsl fid.xml 2>&1
xsltproc --output $buildDir/FunctionID.fo fid_pdf.xsl $buildDir/fid_withscaling.xml 2>&1
echo '** Building FunctionID.pdf **'
@ -137,10 +137,12 @@ task buildFidDocumentationPdf(type: Exec) {
* A build (ex: 'gradle buildLocal') will place the html files in the distribution.
* There is an associated, auto-generated clean task.
**/
task buildFidDocumentationHtml(type: Exec) {
task buildFidHelpHtml(type: Exec) {
workingDir 'src/main/doc'
def buildDir = "../../../build/html"
// 'which' returns the number of failed arguments
// Using the 'which' command first will allow the task to fail if the required
// executables are not installed.
@ -158,9 +160,10 @@ task buildFidDocumentationHtml(type: Exec) {
rm -f $installPoint/topics/FunctionID/*.html
echo '** Building html files **'
xsltproc --output $buildDir/fid_noscaling.xml --stringparam profile.condition "noscaling" /usr/share/sgml/docbook/xsl-stylesheets/profiling/profile.xsl fid.xml 2>&1
xsltproc --output $buildDir/fid_noscaling.xml --stringparam profile.condition "noscaling" commonprofile.xsl fid.xml 2>&1
xsltproc --stringparam base.dir ${installPoint}/topics/FunctionID/ fid_html.xsl $buildDir/fid_noscaling.xml 2>&1
sed -i -e '/Frontpage.css/ { p; s/Frontpage.css/languages.css/; }' ${installPoint}/topics/FunctionID/*.html
rm ${installPoint}/topics/FunctionID/index.html
sed -i -e '/DefaultStyle.css/ { p; sQhref=".*"Qhref="../../shared/languages.css"Q; }' ${installPoint}/topics/FunctionID/*.html
echo '** Done. **'
"""

View File

@ -4,6 +4,7 @@ Module.manifest||GHIDRA||||END|
data/building_fid.txt||GHIDRA||||END|
data/common_symbols_win32.txt||GHIDRA|||Symbols used to generate fiddb files distributed with Ghidra|END|
data/common_symbols_win64.txt||GHIDRA|||Symbols used to generate fiddb files distributed with Ghidra|END|
src/main/doc/commonprofile.xsl||GHIDRA||||END|
src/main/doc/fid.xml||GHIDRA||||END|
src/main/doc/fid_common.xsl||GHIDRA||||END|
src/main/doc/fid_html.xsl||GHIDRA||||END|

View File

@ -0,0 +1,6 @@
<?xml version='1.0'?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/profiling/profile.xsl"/>
</xsl:stylesheet>

View File

@ -41,7 +41,7 @@ from Microsoft Visual Studio for the x86 processor. These have been broken apart
separate Function ID databases, based on 32-bit or 64-code and the version of Visual Studio.
Within each database, there are a two library variants -- one for debug versions and one for production.
</para>
<sect2>
<sect2 id="hashing">
<title>Hashing</title>
<para>
Function ID works by calculating a cumulative hash over all the machine <emphasis>instructions</emphasis>
@ -82,7 +82,7 @@ is robust against changes due to linking; the <emphasis role="bold">specific has
helps distinguish between closely related variants of a function.
</para>
</sect2>
<sect2>
<sect2 id="parentchild">
<title>Parents and Children</title>
<para>
When Function ID examines a function, its parent and child functions are also considered
@ -92,7 +92,7 @@ the full hashes of the functions will be identical, but the system will try to m
the two subfunctions, allowing it to distinguish between the two.
</para>
</sect2>
<sect2>
<sect2 id="libraries">
<title>Libraries</title>
<para>
Within a Function ID database, functions are grouped into <emphasis>libraries</emphasis>,
@ -144,7 +144,7 @@ the analyzer will still report a single match but will leave off the fields it
couldn't distinguish.
</para>
</sect2>
<sect2>
<sect2 id="singlematches">
<title>Single Matches</title>
<para>
A <emphasis role="bold">Single Match</emphasis> for a function occurs under the following conditions:
@ -283,7 +283,7 @@ increasing its overall score.
If there are still more than one potential match, the highest assigned score is
used to filter out matches with lower scores.
</para>
<sect2>
<sect2 id="matchingfunction">
<title>Matching Function Names</title>
<para>
If there are still multiple potential matches once thresholds have been applied to the
@ -416,7 +416,7 @@ to populate the database.
<imagedata condition="withscaling" fileref="images/PopulateFidDbFromPrograms1.png" width="100%" contentwidth="4in" contentdepth="3.033175in" align="center"/>
</imageobject>
</mediaobject>
<sect3>
<sect3 id="dialogfields">
<title>Dialog Fields</title>
<para>
<informalexample>
@ -519,7 +519,7 @@ most commonly called within the library. This list can be used to create a
</section>
<section id="preparelibraries">
<title>Preparing Libraries for a Function ID Database</title>
<sect2>
<sect2 id="programlocation">
<title>Location of Programs</title>
<para>
All functions going into a single Function ID <emphasis>Library</emphasis> must already be imported and analyzed
@ -530,7 +530,7 @@ the root for the library. The process acts recursively, so there can be addition
but all programs to be included in the library must be under the one root.
</para>
</sect2>
<sect2>
<sect2 id="analysis">
<title>Analysis</title>
<para>
All programs must be analyzed enough to have recovered the bodies of all the functions that are to be included
@ -572,7 +572,7 @@ function that is declared as a match by the analyzer but has the incorrect symbo
As with any classification algorithm, it is generally not possible to eliminate this kind
of error completely, but with Function ID there are some mitigation strategies.
</para>
<sect2>
<sect2 id="causes">
<title>Causes</title>
<para>
False positives for the most part only happen with small functions.
@ -611,7 +611,7 @@ There are two related causes with Function ID:
In either case, Function ID can apply a symbol that is misleading for the analyst.
</para>
</sect2>
<sect2>
<sect2 id="mitigation">
<title>Mitigation via Threshold</title>
<para>
All mitigation strategies, to some extent, trade-off false positives for
@ -758,7 +758,7 @@ section and check the box next to "FidDebugPlugin".
The Function ID Debug Plug-in introduces the following actions to the
<emphasis role="bold">Tools -> Function ID</emphasis> menu.
</para>
<sect2>
<sect2 id="readonly">
<title>Create Read-only Database</title>
<para>
Users can convert the read/write (.fidb) database into the a read-only (.fidbf) form. This is
@ -787,7 +787,7 @@ the <command>RETURN</command> key, with the cursor and focus still in the desire
<imagedata condition="withscaling" fileref="images/FIDSearch.png" width="100%" contentwidth="4in" contentdepth="3.3397in" align="center"/>
</imageobject>
</mediaobject>
<sect3>
<sect3 id="searchfields">
<title>Search Fields</title>
<para>
<informalexample>
@ -845,7 +845,7 @@ the <command>RETURN</command> key, with the cursor and focus still in the desire
</informalexample>
</para>
</sect3>
<sect3>
<sect3 id="resultwindow">
<title>Result Window</title>
<para>
Invoking a search will bring up the <emphasis>Result Window</emphasis>, presenting a row for
@ -901,7 +901,7 @@ other columns:
</variablelist>
</informalexample>
</para>
<sect4>
<sect4 id="editmenu">
<title>Edit Menu</title>
<para>
The <emphasis>Result Window</emphasis> supports a small number of actions under the
@ -962,7 +962,7 @@ strategy.
</sect4>
</sect3>
</sect2>
<sect2>
<sect2 id="tableviewer">
<title>Table Viewer</title>
<para>
This invokes an extremely low-level view into the underlying tables that back a

View File

@ -2,7 +2,7 @@
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="/usr/share/sgml/docbook/xsl-stylesheets/html/chunk.xsl"/>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>
<xsl:include href="fid_common.xsl" />
@ -40,9 +40,15 @@
</xsl:element>
</xsl:template>
<xsl:template name="body.attributes">
<!-- Remove all BODY attributes so that CSS stylesheet can provide everything -->
</xsl:template>
<xsl:param name="suppress.navigation" select="1"/> <!-- Turn off header/footer navigation links -->
<xsl:param name="use.id.as.filename" select="1"/> <!-- Split up into files based on id attribute -->
<xsl:param name="html.stylesheet" select="'../../shared/Frontpage.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="html.stylesheet" select="'help/shared/DefaultStyle.css'"/> <!-- Use our custom cascading style sheet -->
<xsl:param name="chunk.section.depth" select="0"/>

View File

@ -2,7 +2,7 @@
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="/usr/share/sgml/docbook/xsl-stylesheets/fo/docbook.xsl"/>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
<xsl:template match="table" mode="label.markup"/>

View File

@ -3,24 +3,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Function ID</title>
<link rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="help/shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="stylesheet" type="text/css" href="../../shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="index.html" title="Function ID">
<link rel="up" href="index.html" title="Function ID">
<link rel="prev" href="index.html" title="Function ID">
<link rel="next" href="FunctionIDPlugin.html" title="Function ID Plug-in">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">Function ID</th></tr>
<tr>
<td width="20%" align="left"></td>
<th width="60%" align="center"><EFBFBD></th>
<td width="20%" align="right"><EFBFBD><a accesskey="n" href="FunctionIDPlugin.html">Next</a>
</td>
</tr>
</table>
<hr>
</div>
<div class="chapter">
<body><div class="chapter">
<div class="titlepage"><div><div><h1 class="title">
<a name="FunctionID"></a>Function ID</h1></div></div></div>
<div class="mediaobject" align="center"><table border="0" summary="manufactured viewport for HTML img" style="cellpadding: 0; cellspacing: 0;" width="100%"><tr><td align="center"><img src="images/FIDmatch.png" align="middle" width="723" height="267"></td></tr></table></div>
@ -57,7 +47,7 @@ Within each database, there are a two library variants -- one for debug versions
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472630336"></a>Hashing</h3></div></div></div>
<a name="hashing"></a>Hashing</h3></div></div></div>
<p>
Function ID works by calculating a cumulative hash over all the machine <span class="emphasis"><em>instructions</em></span>
that make up the body of a function. For each function, two different 64-bit hashes are computed: a
@ -90,7 +80,7 @@ helps distinguish between closely related variants of a function.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472620992"></a>Parents and Children</h3></div></div></div>
<a name="parentchild"></a>Parents and Children</h3></div></div></div>
<p>
When Function ID examines a function, its parent and child functions are also considered
as a way of disambiguating multiple matches. For example, suppose two functions have identical
@ -101,7 +91,7 @@ the two subfunctions, allowing it to distinguish between the two.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472619376"></a>Libraries</h3></div></div></div>
<a name="libraries"></a>Libraries</h3></div></div></div>
<p>
Within a Function ID database, functions are grouped into <span class="emphasis"><em>libraries</em></span>,
which are intended to be recognizable named software components
@ -141,7 +131,7 @@ couldn't distinguish.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472607824"></a>Single Matches</h3></div></div></div>
<a name="singlematches"></a>Single Matches</h3></div></div></div>
<p>
A <span class="bold"><strong>Single Match</strong></span> for a function occurs under the following conditions:
</p>
@ -268,7 +258,7 @@ used to filter out matches with lower scores.
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472572880"></a>Matching Function Names</h3></div></div></div>
<a name="matchingfunction"></a>Matching Function Names</h3></div></div></div>
<p>
If there are still multiple potential matches once thresholds have been applied to the
match scores, the remaining matches will be grouped based on function names. If
@ -284,22 +274,5 @@ parameter information is stripped.
</p>
</div>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"></td>
<td width="20%" align="center"><EFBFBD></td>
<td width="40%" align="right"><EFBFBD><a accesskey="n" href="FunctionIDPlugin.html">Next</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Function ID<49></td>
<td width="20%" align="center"></td>
<td width="40%" align="right" valign="top"><EFBFBD>Function ID Plug-in</td>
</tr>
</table>
</div>
</body>
</div></body>
</html>

View File

@ -3,24 +3,13 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Function ID Debug Plug-in</title>
<link rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="help/shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="stylesheet" type="text/css" href="../../shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="index.html" title="Function ID">
<link rel="up" href="index.html" title="Function ID">
<link rel="prev" href="FunctionIDPlugin.html" title="Function ID Plug-in">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">Function ID Debug Plug-in</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="FunctionIDPlugin.html">Prev</a><EFBFBD></td>
<th width="60%" align="center"><EFBFBD></th>
<td width="20%" align="right"><EFBFBD></td>
</tr>
</table>
<hr>
</div>
<div class="chapter">
<body><div class="chapter">
<div class="titlepage"><div><div><h1 class="title">
<a name="FunctionIDDebug"></a>Function ID Debug Plug-in</h1></div></div></div>
<p>
@ -54,7 +43,7 @@ The Function ID Debug Plug-in introduces the following actions to the
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472459600"></a>Create Read-only Database</h3></div></div></div>
<a name="readonly"></a>Create Read-only Database</h3></div></div></div>
<p>
Users can convert the read/write (.fidb) database into the a read-only (.fidbf) form. This is
the more efficient final form used directly by the Function ID analyzer. The .fidbf form is
@ -80,7 +69,7 @@ the <span class="command"><strong>RETURN</strong></span> key, with the cursor an
<div class="mediaobject" align="center"><table border="0" summary="manufactured viewport for HTML img" style="cellpadding: 0; cellspacing: 0;" width="100%"><tr><td align="center"><img src="images/FIDSearch.png" align="middle" width="315" height="263"></td></tr></table></div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140323472451184"></a>Search Fields</h4></div></div></div>
<a name="searchfields"></a>Search Fields</h4></div></div></div>
<p>
</p>
<div class="informalexample"><div class="variablelist"><dl class="variablelist">
@ -118,7 +107,7 @@ the <span class="command"><strong>RETURN</strong></span> key, with the cursor an
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140323472437088"></a>Result Window</h4></div></div></div>
<a name="resultwindow"></a>Result Window</h4></div></div></div>
<p>
Invoking a search will bring up the <span class="emphasis"><em>Result Window</em></span>, presenting a row for
each matching function record. Columns list properties of the function and correspond
@ -162,7 +151,7 @@ other columns:
</p>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140323472422400"></a>Edit Menu</h5></div></div></div>
<a name="editmenu"></a>Edit Menu</h5></div></div></div>
<p>
The <span class="emphasis"><em>Result Window</em></span> supports a small number of actions under the
<span class="bold"><strong>Edit</strong></span> menu that allow the user to change the
@ -203,7 +192,7 @@ strategy.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472406032"></a>Table Viewer</h3></div></div></div>
<a name="tableviewer"></a>Table Viewer</h3></div></div></div>
<p>
This invokes an extremely low-level view into the underlying tables that back a
Function ID database. It can be invoked on any attached database. A window is brought up
@ -214,22 +203,5 @@ present readable values. The only meaningful table is likely to be the
</p>
</div>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="FunctionIDPlugin.html">Prev</a><EFBFBD></td>
<td width="20%" align="center"><EFBFBD></td>
<td width="40%" align="right"><EFBFBD></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Function ID Plug-in<69></td>
<td width="20%" align="center"></td>
<td width="40%" align="right" valign="top"><EFBFBD></td>
</tr>
</table>
</div>
</body>
</div></body>
</html>

View File

@ -3,26 +3,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Function ID Plug-in</title>
<link rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="help/shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="stylesheet" type="text/css" href="../../shared/languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="index.html" title="Function ID">
<link rel="up" href="index.html" title="Function ID">
<link rel="prev" href="FunctionID.html" title="Function ID">
<link rel="next" href="FunctionIDDebug.html" title="Function ID Debug Plug-in">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">Function ID Plug-in</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="FunctionID.html">Prev</a><EFBFBD></td>
<th width="60%" align="center"><EFBFBD></th>
<td width="20%" align="right"><EFBFBD><a accesskey="n" href="FunctionIDDebug.html">Next</a>
</td>
</tr>
</table>
<hr>
</div>
<div class="chapter">
<body><div class="chapter">
<div class="titlepage"><div><div><h1 class="title">
<a name="FunctionIDPlugin"></a>Function ID Plug-in</h1></div></div></div>
<p>
@ -132,7 +120,7 @@ to populate the database.
<div class="mediaobject" align="center"><table border="0" summary="manufactured viewport for HTML img" style="cellpadding: 0; cellspacing: 0;" width="100%"><tr><td align="center"><img src="images/PopulateFidDbFromPrograms1.png" align="middle" width="422" height="320"></td></tr></table></div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140323472541088"></a>Dialog Fields</h4></div></div></div>
<a name="dialogfields"></a>Dialog Fields</h4></div></div></div>
<p>
</p>
<div class="informalexample"><div class="variablelist"><dl class="variablelist">
@ -204,7 +192,7 @@ most commonly called within the library. This list can be used to create a
<a name="preparelibraries"></a>Preparing Libraries for a Function ID Database</h2></div></div></div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472516592"></a>Location of Programs</h3></div></div></div>
<a name="programlocation"></a>Location of Programs</h3></div></div></div>
<p>
All functions going into a single Function ID <span class="emphasis"><em>Library</em></span> must already be imported and analyzed
somewhere within a single Ghidra repository (shared or non-shared). Multiple libraries contained within
@ -216,7 +204,7 @@ but all programs to be included in the library must be under the one root.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472513952"></a>Analysis</h3></div></div></div>
<a name="analysis"></a>Analysis</h3></div></div></div>
<p>
All programs must be analyzed enough to have recovered the bodies of all the functions that are to be included
in the library. Generally, the easiest way to accomplish this is to run Ghidra's default auto-analysis.
@ -260,7 +248,7 @@ of error completely, but with Function ID there are some mitigation strategies.
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472502064"></a>Causes</h3></div></div></div>
<a name="causes"></a>Causes</h3></div></div></div>
<p>
False positives for the most part only happen with small functions.
There are two related causes with Function ID:
@ -291,7 +279,7 @@ In either case, Function ID can apply a symbol that is misleading for the analys
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140323472493552"></a>Mitigation via Threshold</h3></div></div></div>
<a name="mitigation"></a>Mitigation via Threshold</h3></div></div></div>
<p>
All mitigation strategies, to some extent, trade-off false positives for
<span class="bold"><strong>false negatives</strong></span>, which are functions that should have
@ -391,23 +379,5 @@ script.
</p>
</div>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="FunctionID.html">Prev</a><EFBFBD></td>
<td width="20%" align="center"><EFBFBD></td>
<td width="40%" align="right"><EFBFBD><a accesskey="n" href="FunctionIDDebug.html">Next</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Function ID<49></td>
<td width="20%" align="center"></td>
<td width="40%" align="right" valign="top"><EFBFBD>Function ID Debug Plug-in</td>
</tr>
</table>
</div>
</body>
</div></body>
</html>

View File

@ -1,57 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.pcode.emulate.callother;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.memstate.MemoryState;
import ghidra.pcodeCPort.error.LowlevelError;
import ghidra.program.model.pcode.Varnode;
public class CountLeadingOnesOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate emu, Varnode out, Varnode[] inputs) {
if (out == null) {
throw new LowlevelError("CALLOTHER: Count Leading Ones op missing required output");
}
if (inputs.length != 2 || inputs[1].getSize() == 0 || inputs[1].isConstant()) {
throw new LowlevelError(
"CALLOTHER: Count Leading Ones op requires one non-constant varnode input");
}
// TODO: add support for larger varnode sizes
Varnode in = inputs[1];
if (in.getSize() > 8 || out.getSize() > 8) {
throw new LowlevelError(
"CALLOTHER: Count Leading Ones op only supports varnodes of size 8-bytes or less");
}
MemoryState memoryState = emu.getMemoryState();
long value = memoryState.getValue(in);
long mask = 1L << ((in.getSize() * 8) - 1);
long count = 0;
while ( (mask & value) != 0 ) {
++count;
value = value << 1;
}
memoryState.setValue(out, count);
}
}

View File

@ -1,60 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.pcode.emulate.callother;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.memstate.MemoryState;
import ghidra.pcodeCPort.error.LowlevelError;
import ghidra.program.model.pcode.Varnode;
public class CountLeadingZerosOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate emu, Varnode out, Varnode[] inputs) {
if (out == null) {
throw new LowlevelError("CALLOTHER: Count Leading Zeros op missing required output");
}
if (inputs.length != 2 || inputs[1].getSize() == 0 || inputs[1].isConstant()) {
throw new LowlevelError(
"CALLOTHER: Count Leading Zeros op requires one non-constant varnode input");
}
// TODO: add support for larger varnode sizes
Varnode in = inputs[1];
if (in.getSize() > 8 || out.getSize() > 8) {
throw new LowlevelError(
"CALLOTHER: Count Leading Zeros op only supports varnodes of size 8-bytes or less");
}
MemoryState memoryState = emu.getMemoryState();
long value = memoryState.getValue(in);
long mask = 1L << ((in.getSize() * 8) - 1);
long count = 0;
while (mask != 0) {
if ((mask & value) != 0) {
break;
}
++count;
mask >>>= 1;
}
memoryState.setValue(out, count);
}
}

View File

@ -104,6 +104,7 @@ public class OpBehaviorFactory {
opBehaviorMap.put(PcodeOp.INSERT, new SpecialOpBehavior(PcodeOp.INSERT));
opBehaviorMap.put(PcodeOp.EXTRACT, new SpecialOpBehavior(PcodeOp.EXTRACT));
opBehaviorMap.put(PcodeOp.POPCOUNT, new OpBehaviorPopcount());
opBehaviorMap.put(PcodeOp.LZCOUNT, new OpBehaviorLzcount());
}
private OpBehaviorFactory() {

View File

@ -0,0 +1,62 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.pcode.opbehavior;
import java.math.BigInteger;
import ghidra.program.model.pcode.PcodeOp;
public class OpBehaviorLzcount extends UnaryOpBehavior {
public OpBehaviorLzcount() {
super(PcodeOp.LZCOUNT);
}
@Override
public long evaluateUnary(int sizeout, int sizein, long val) {
long mask = 1L << ((sizein * 8) - 1);
long count = 0;
while (mask != 0) {
if ((mask & val) != 0) {
break;
}
++count;
mask >>>= 1;
}
return count;
}
@Override
public BigInteger evaluateUnary(int sizeout, int sizein, BigInteger unsignedIn1) {
int bitcount = 0;
sizein = sizein * 8 - 1;
while (sizein >= 0) {
if (unsignedIn1.testBit(sizein)) {
break;
}
bitcount += 1;
sizein -= 1;
}
if (sizeout == 1) {
bitcount &= 0xff;
}
else if (sizeout == 2) {
bitcount &= 0xffff;
}
return BigInteger.valueOf(bitcount);
}
}

View File

@ -39,8 +39,26 @@ public class OpBehaviorPopcount extends UnaryOpBehavior {
@Override
public BigInteger evaluateUnary(int sizeout, int sizein, BigInteger unsignedIn1) {
// TODO Auto-generated method stub
return null;
int bitcount = 0;
while (sizein >= 8) {
bitcount += evaluateUnary(1, 8, unsignedIn1.longValue());
sizein -= 8;
if (sizein == 0) {
break;
}
unsignedIn1 = unsignedIn1.shiftRight(64);
}
if (sizein > 0) {
long mask = sizein * 8 - 1;
bitcount += evaluateUnary(1, 8, unsignedIn1.longValue() & mask);
}
if (sizeout == 1) {
bitcount &= 0xff;
}
else if (sizeout == 2) {
bitcount &= 0xffff;
}
return BigInteger.valueOf(bitcount);
}
}

View File

@ -113,6 +113,7 @@ public enum OpCode {
CPUI_INSERT,
CPUI_EXTRACT,
CPUI_POPCOUNT,
CPUI_LZCOUNT,
CPUI_MAX;
@ -203,7 +204,8 @@ public enum OpCode {
"UNUSED1", "FLOAT_NAN", "FLOAT_ADD", "FLOAT_DIV", "FLOAT_MULT", "FLOAT_SUB",
"FLOAT_NEG", "FLOAT_ABS", "FLOAT_SQRT", "INT2FLOAT", "FLOAT2FLOAT", "TRUNC", "CEIL",
"FLOOR", "ROUND", "BUILD", "DELAY_SLOT", "PIECE", "SUBPIECE", "CAST", "LABEL",
"CROSSBUILD", "SEGMENTOP", "CPOOLREF", "NEW", "INSERT", "EXTRACT", "POPCOUNT" };
"CROSSBUILD", "SEGMENTOP", "CPOOLREF", "NEW", "INSERT", "EXTRACT", "POPCOUNT",
"LZCOUNT" };
public static String get_opname(OpCode op) {
return opcode_name[op.ordinal()];
@ -212,7 +214,7 @@ public enum OpCode {
static final int opcode_indices[] = { 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, 67, 3, 63, 56, 45 };
65, 2, 73, 69, 62, 72, 10, 59, 67, 3, 63, 56, 45 };
public static OpCode get_opcode(String nm) { // Use binary search to find name
int min = 1; // Don't include BLANK

View File

@ -996,6 +996,9 @@ public abstract class PcodeCompile {
if ("popcount".equals(name) && hasOperands(1, operands, location, name)) {
return createOp(location, OpCode.CPUI_POPCOUNT, r);
}
if ("lzcount".equals(name) && hasOperands(1, operands, location, name)) {
return createOp(location, OpCode.CPUI_LZCOUNT, r);
}
return null;
}
@ -1073,6 +1076,9 @@ public abstract class PcodeCompile {
if ("popcount".equals(name)) {
return true;
}
if ("lzcount".equals(name)) {
return true;
}
return false;
}

View File

@ -75,7 +75,7 @@ public class DynamicHash {
0, // CAST is skipped
PcodeOp.INT_ADD, PcodeOp.INT_ADD, // PTRADD and PTRSUB hash same as INT_ADD
PcodeOp.SEGMENTOP, PcodeOp.CPOOLREF, PcodeOp.NEW, PcodeOp.INSERT, PcodeOp.EXTRACT,
PcodeOp.POPCOUNT };
PcodeOp.POPCOUNT, PcodeOp.LZCOUNT };
/**
* An edge between a Varnode and a PcodeOp

View File

@ -132,8 +132,9 @@ public class PcodeOp {
public static final int INSERT = 70;
public static final int EXTRACT = 71;
public static final int POPCOUNT = 72;
public static final int LZCOUNT = 73;
public static final int PCODE_MAX = 73;
public static final int PCODE_MAX = 74;
private static Hashtable<String, Integer> opcodeTable;
@ -689,6 +690,8 @@ public class PcodeOp {
return "EXTRACT";
case POPCOUNT:
return "POPCOUNT";
case LZCOUNT:
return "LZCOUNT";
default:
return "INVALID_OP";

View File

@ -0,0 +1,91 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.pcode.opbehavior;
import java.math.BigInteger;
import org.junit.Assert;
import org.junit.Test;
import ghidra.pcode.utils.Utils;
public class OpBehaviorLzcountTest extends AbstractOpBehaviorTest {
@Test
public void testEvaluateUnaryLong() {
OpBehaviorLzcount op = new OpBehaviorLzcount();
Assert.assertEquals(8, op.evaluateUnary(1, 1, 0L));
Assert.assertEquals(16, op.evaluateUnary(1, 2, 0L));
Assert.assertEquals(32, op.evaluateUnary(1, 4, 0L));
Assert.assertEquals(64, op.evaluateUnary(1, 8, 0L));
Assert.assertEquals(0, op.evaluateUnary(1, 1, 0xffL));
Assert.assertEquals(0, op.evaluateUnary(1, 2, 0xffffL));
Assert.assertEquals(0, op.evaluateUnary(1, 4, 0xffffffffL));
Assert.assertEquals(0, op.evaluateUnary(1, 8, 0xffffffffffffffffL));
Assert.assertEquals(0, op.evaluateUnary(1, 1, 0x96L));
Assert.assertEquals(0, op.evaluateUnary(1, 2, 0xdbf4L));
Assert.assertEquals(1, op.evaluateUnary(1, 4, 0x460f457bL));
Assert.assertEquals(3, op.evaluateUnary(1, 8, 0x1fae97efca7d5759L));
Assert.assertEquals(4, op.evaluateUnary(1, 1, 0xaL));
Assert.assertEquals(6, op.evaluateUnary(1, 2, 0x2a5L));
Assert.assertEquals(9, op.evaluateUnary(1, 4, 0x60dfffL));
Assert.assertEquals(13, op.evaluateUnary(1, 8, 0x635017adefe4eL));
Assert.assertEquals(3, op.evaluateUnary(1, 1, 0x17L));
Assert.assertEquals(8, op.evaluateUnary(1, 2, 0xd1L));
Assert.assertEquals(22, op.evaluateUnary(1, 4, 0x39eL));
Assert.assertEquals(27, op.evaluateUnary(1, 8, 0x189c178d6aL));
Assert.assertEquals(4, op.evaluateUnary(1, 1, 0xfL));
Assert.assertEquals(4, op.evaluateUnary(1, 2, 0xff0L));
Assert.assertEquals(0, op.evaluateUnary(1, 4, 0xffff0000L));
Assert.assertEquals(24, op.evaluateUnary(1, 8, 0xff00ff00ffL));
}
@Test
public void testEvaluateUnaryBigInteger() {
OpBehaviorLzcount op = new OpBehaviorLzcount();
BigInteger NEGATIVE_ONE = Utils.convertToUnsignedValue(BigInteger.valueOf(-1), 16);
BigInteger BIG_POSITIVE = new BigInteger("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16);
BigInteger BIG_NEGATIVE = Utils
.convertToUnsignedValue(new BigInteger("80000000000000000000000000000000", 16), 16);
assertEquals(BigInteger.valueOf(128), op.evaluateUnary(1, 16, BigInteger.ZERO), 16);
assertEquals(BigInteger.ZERO, op.evaluateUnary(1, 16, NEGATIVE_ONE), 16);
assertEquals(BigInteger.ONE, op.evaluateUnary(1, 16, BIG_POSITIVE), 16);
assertEquals(BigInteger.ZERO, op.evaluateUnary(1, 16, BIG_NEGATIVE), 16);
BigInteger val = BigInteger.valueOf(0x35017adefe4eL);
val = val.shiftLeft(64);
val = val.or(Utils.convertToUnsignedValue(BigInteger.valueOf(0xd46223189c178d6aL), 8));
assertEquals(BigInteger.valueOf(18), op.evaluateUnary(1, 16, val), 16);
BigInteger FF = BigInteger.valueOf(0xff);
val = BigInteger.ZERO;
for (int i = 0; i < 20; ++i) {
val = val.shiftLeft(16);
val = val.add(FF);
}
assertEquals(BigInteger.valueOf(8), op.evaluateUnary(1, 40, val), 40);
}
}

View File

@ -0,0 +1,90 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.pcode.opbehavior;
import java.math.BigInteger;
import org.junit.Assert;
import org.junit.Test;
import ghidra.pcode.utils.Utils;
public class OpBehaviorPopcountTest extends AbstractOpBehaviorTest {
@Test
public void testEvaluateUnaryLong() {
OpBehaviorPopcount op = new OpBehaviorPopcount();
Assert.assertEquals(0, op.evaluateUnary(1, 1, 0L));
Assert.assertEquals(0, op.evaluateUnary(1, 2, 0L));
Assert.assertEquals(0, op.evaluateUnary(1, 4, 0L));
Assert.assertEquals(0, op.evaluateUnary(1, 8, 0L));
Assert.assertEquals(8, op.evaluateUnary(1, 1, 0xffL));
Assert.assertEquals(16, op.evaluateUnary(1, 2, 0xffffL));
Assert.assertEquals(32, op.evaluateUnary(1, 4, 0xffffffffL));
Assert.assertEquals(64, op.evaluateUnary(1, 8, 0xffffffffffffffffL));
Assert.assertEquals(4, op.evaluateUnary(1, 1, 0x96L));
Assert.assertEquals(11, op.evaluateUnary(1, 2, 0xdbf4L));
Assert.assertEquals(16, op.evaluateUnary(1, 4, 0x460f457bL));
Assert.assertEquals(41, op.evaluateUnary(1, 8, 0x1fae97efca7d5759L));
Assert.assertEquals(5, op.evaluateUnary(1, 1, 0x7aL));
Assert.assertEquals(10, op.evaluateUnary(1, 2, 0xfca5L));
Assert.assertEquals(20, op.evaluateUnary(1, 4, 0x2660dfffL));
Assert.assertEquals(38, op.evaluateUnary(1, 8, 0x79f635017adefe4eL));
Assert.assertEquals(4, op.evaluateUnary(1, 1, 0x17L));
Assert.assertEquals(10, op.evaluateUnary(1, 2, 0x77d1L));
Assert.assertEquals(15, op.evaluateUnary(1, 4, 0x5758039eL));
Assert.assertEquals(28, op.evaluateUnary(1, 8, 0xd46223189c178d6aL));
Assert.assertEquals(7, op.evaluateUnary(1, 1, 0xbfL));
Assert.assertEquals(12, op.evaluateUnary(1, 2, 0xe3efL));
Assert.assertEquals(17, op.evaluateUnary(1, 4, 0xb2d7e134L));
Assert.assertEquals(34, op.evaluateUnary(1, 8, 0x69f7a0fa6eeda6L));
}
@Test
public void testEvaluateUnaryBigInteger() {
OpBehaviorPopcount op = new OpBehaviorPopcount();
BigInteger NEGATIVE_ONE = Utils.convertToUnsignedValue(BigInteger.valueOf(-1), 16);
BigInteger BIG_POSITIVE = new BigInteger("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16);
BigInteger BIG_NEGATIVE = Utils
.convertToUnsignedValue(new BigInteger("80000000000000000000000000000000", 16), 16);
assertEquals(BigInteger.ZERO, op.evaluateUnary(1, 16, BigInteger.ZERO), 16);
assertEquals(BigInteger.valueOf(128), op.evaluateUnary(1, 16, NEGATIVE_ONE), 16);
assertEquals(BigInteger.valueOf(127), op.evaluateUnary(1, 16, BIG_POSITIVE), 16);
assertEquals(BigInteger.ONE, op.evaluateUnary(1, 16, BIG_NEGATIVE), 16);
BigInteger val = BigInteger.valueOf(0x79f635017adefe4eL);
val = val.shiftLeft(64);
val = val.or(Utils.convertToUnsignedValue(BigInteger.valueOf(0xd46223189c178d6aL), 8));
assertEquals(BigInteger.valueOf(66), op.evaluateUnary(1, 16, val), 16);
BigInteger FF = BigInteger.valueOf(0xff);
val = BigInteger.ZERO;
for (int i = 0; i < 20; ++i) {
val = val.shiftLeft(16);
val = val.add(FF);
}
assertEquals(BigInteger.valueOf(160), op.evaluateUnary(1, 40, val), 40);
}
}

View File

@ -931,8 +931,6 @@ with : extGUARD=1 {
logflags(); tmp:4 = e2l; getbitfield(tmp, f_off, f_wd); f_reg = tmp; resbitflags(f_reg, f_wd-1);
}
define pcodeop countLeadingZeros;
:bfffo e2l{f_off:f_wd},f_reg is opbig=0xed & op67=3 & $(DAT_DIR_CTL_ADDR_MODES); f_off & f_wd & f_reg & flddo=0 & fldoffdat=0 & flddw=0 & fldwddat=0; e2l
[ savmod2=savmod1; regtsan=regtfan; ] {
# "Find First One in Bit Field" pronounced "boo-foe"
@ -945,7 +943,7 @@ define pcodeop countLeadingZeros;
ZF = (tmp == 0);
VF = 0;
CF = 0;
tmp2:4 = countLeadingZeros(tmp);
tmp2:4 = lzcount(tmp);
# NB- it seems the MSB left most bit is really at offset 0,
# and the right LSB is at offset 31
tmp3:4 = tmp2 % 32:4; # need mod for when there are all zeros, when tmp2 would = 32

View File

@ -17,7 +17,6 @@ package ghidra.program.emulation;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.CountLeadingZerosOpBehavior;
import ghidra.pcode.emulate.callother.OpBehaviorOther;
import ghidra.pcode.memstate.MemoryState;
import ghidra.pcodeCPort.error.LowlevelError;
@ -45,10 +44,6 @@ public class m68kEmulateInstructionStateModifier extends EmulateInstructionState
ISA_MODE0 = new RegisterValue(isaModeReg, BigInteger.ZERO);
*/
// These classes are defined here:
// ghidra/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/emulate/callother
registerPcodeOpBehavior("countLeadingZeros", new CountLeadingZerosOpBehavior());
registerPcodeOpBehavior("findFirstOne", new FindFirstOneOpBehavior());
}

View File

@ -117,7 +117,6 @@ define context contextreg
ARMcondCk = (35,35) # Finished ARM condition check phase
;
define pcodeop count_leading_zeroes;
define pcodeop coprocessor_function;
define pcodeop coprocessor_function2;
define pcodeop coprocessor_load;

View File

@ -1627,7 +1627,7 @@ define pcodeop IndexCheck;
:clz^ItCond Rd0811,Rm0003 is TMode=1 & ItCond & op4=0xfab & Rm0003; op12=15 & Rd0811
{
build ItCond;
Rd0811 = count_leading_zeroes(Rm0003);
Rd0811 = lzcount(Rm0003);
}
:cmn^ItCond Rn0003,ThumbExpandImm12 is TMode=1 & ItCond & (op11=0x1e & thc0909=0 & sop0508=8 & thc0404=1 & Rn0003; thc1515=0 & thc0811=15) & ThumbExpandImm12

View File

@ -2484,7 +2484,7 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
{
build COND;
build rm;
Rd = count_leading_zeroes(rm);
Rd = lzcount(rm);
}
@endif # VERSION_5

View File

@ -19,7 +19,6 @@ import java.math.BigInteger;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.CountLeadingZerosOpBehavior;
import ghidra.pcode.error.LowlevelError;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.Register;
@ -46,8 +45,6 @@ public class ARMEmulateInstructionStateModifier extends EmulateInstructionStateM
aMode = new RegisterValue(TModeReg, BigInteger.ZERO);
}
registerPcodeOpBehavior("count_leading_zeroes", new CountLeadingZerosOpBehavior());
/**
* We could registerPcodeOpBehavior for one or more of the following pcodeop's:
*
@ -85,7 +82,6 @@ public class ARMEmulateInstructionStateModifier extends EmulateInstructionStateM
coprocessor_store2
coprocessor_storelong
coprocessor_storelong2
count_leading_zeroes
disableDataAbortInterrupts
disableFIQinterrupts
disableIRQinterrupts

View File

@ -1001,12 +1001,6 @@ define pcodeop getCopRegH;
define pcodeop setCopReg;
define pcodeop setCopRegH;
# countLeadingOnes(val)
define pcodeop countLeadingOnes;
# countLeadingZeros(val)
define pcodeop countLeadingZeros;
# extractField(value, msbd, lsb)
define pcodeop extractField;

View File

@ -980,13 +980,13 @@ define pcodeop SYNC;
# 0111 00ss ssst tttt dddd d000 0010 0001
:clo RD, RSsrc is $(AMODE) & REL6=0 & prime=0x1C & sa=0x0 & fct=0x21 & RD & RSsrc {
# Count leading ones in a word
RD = countLeadingOnes( RSsrc );
RD = lzcount( ~RSsrc );
}
# 0111 00ss ssst tttt dddd d000 0010 0000
:clz RD, RSsrc is $(AMODE) & REL6=0 & prime=0x1C & sa=0x0 & fct=0x20 & RD & RSsrc {
# Count leading zeros in a word
RD = countLeadingZeros( RSsrc );
RD = lzcount( RSsrc );
}
# 0000 00ss ssst tttt 0000 0000 0001 1010
@ -1573,11 +1573,11 @@ define pcodeop SYNC;
}
:clo RD, RSsrc is $(AMODE) & REL6=1 & prime=0x00 & op=0 & sa=0x1 & fct=0x11 & RD & RSsrc {
RD = countLeadingOnes( RSsrc );
RD = lzcount( ~RSsrc );
}
:clz RD, RSsrc is $(AMODE) & REL6=1 & prime=0x00 & op=0 & sa=0x1 & fct=0x10 & RD & RSsrc {
RD = countLeadingZeros( RSsrc );
RD = lzcount( RSsrc );
}
:div RD, RS32src, RT32src is $(AMODE) & REL6=1 & prime=0x00 & fct=0x1A & fct2=0x02 & RD & RS32src & RT32src {

View File

@ -7,11 +7,11 @@
# 0111 00ss ssst tttt dddd d000 0010 0101
:dclo RD, RSsrc is $(AMODE) & ((REL6=0 & prime=0x1C & sa=0x0 & fct=0x25) | (REL6=1 & prime=0x00 & sa=0x1 & fct=0x13 & op=0)) & RD & RSsrc {
RD = countLeadingOnes( RSsrc );
RD = lzcount( ~RSsrc );
}
# 0111 00ss ssst tttt dddd d000 0010 0100
:dclz RD, RSsrc is $(AMODE) & ((REL6=0 & prime=0x1C & sa=0x0 & fct=0x24) | (REL6=1 & prime=0x00 & sa=0x1 & fct=0x12 & op=0)) & RD & RSsrc {
RD = countLeadingZeros( RSsrc );
RD = lzcount( RSsrc );
}
# 0111 11ss ssst tttt mmmm mLLL LL00 0011

View File

@ -697,11 +697,11 @@ STORE_TOP16: STORE_SREG^ra,EXT_CODE4E(sp) is mic_listr6 & REL6=1 & STORE_SREG &
}
:clo mic_rt32_5, RS0L is ISA_MODE=1 & RELP=0 & mic_op=0b000000 & mic_rt32_5 & RS0L ; micb_poolax=0b111100 & micb_axf=0b0100101100 {
mic_rt32_5 = countLeadingOnes( RS0L );
mic_rt32_5 = lzcount( ~RS0L );
}
:clz mic_rt32_5, RS0L is ISA_MODE=1 & RELP=0 & mic_op=0b000000 & mic_rt32_5 & RS0L ; micb_poolax=0b111100 & micb_axf=0b0101101100 {
mic_rt32_5 = countLeadingZeros( RS0L );
mic_rt32_5 = lzcount( RS0L );
}
:cop2 EXT_MU23 is ISA_MODE=1 & RELP=0 & mic_op=0b000000 & mic_code ; micb_cop=0b010 & EXT_MU23 [ ext_32_code=mic_code; ] {
@ -1676,11 +1676,11 @@ STORE_TOP16: STORE_SREG^ra,EXT_CODE4E(sp) is mic_listr6 & REL6=1 & STORE_SREG &
}
:dclo mic_rt32_5, mic_rs32_0 is ISA_MODE=1 & RELP=0 & mic_op=0b010110 & mic_rt32_5 & mic_rs32_0 ; micb_poolax=0b111100 & micb_axf=0b0100101100 {
mic_rt32_5 = countLeadingOnes( mic_rs32_0 );
mic_rt32_5 = lzcount( ~mic_rs32_0 );
}
:dclz mic_rt32_5, mic_rs32_0 is ISA_MODE=1 & RELP=0 & mic_op=0b010110 & mic_rt32_5 & mic_rs32_0 ; micb_poolax=0b111100 & micb_axf=0b0101101100 {
mic_rt32_5 = countLeadingZeros( mic_rs32_0 );
mic_rt32_5 = lzcount( mic_rs32_0 );
}
:dext mic_rt32_5, mic_rs32_0, micb_pos, SIZEP is ISA_MODE=1 & RELP=0 & mic_op=0b010110 & REL6=1 & mic_rt32_5 & mic_rs32_0 ; micb_poolax=0b101100 & micb_pos & SIZEP {

View File

@ -19,8 +19,6 @@ import java.math.BigInteger;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.CountLeadingOnesOpBehavior;
import ghidra.pcode.emulate.callother.CountLeadingZerosOpBehavior;
import ghidra.pcode.error.LowlevelError;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.Register;
@ -49,13 +47,6 @@ public class MIPSEmulateInstructionStateModifier extends EmulateInstructionState
ISA_MODE0 = new RegisterValue(isaModeReg, BigInteger.ZERO);
}
// These classes are defined here:
// ghidra/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/emulate/callother
registerPcodeOpBehavior("countLeadingZeros", new CountLeadingZerosOpBehavior());
registerPcodeOpBehavior("countLeadingOnes", new CountLeadingOnesOpBehavior());
/**
* We could registerPcodeOpBehavior for one or more of the following
* pcodeop's:

View File

@ -1415,7 +1415,6 @@ attach variables vrC_8_15 [vr0_8_15 vr1_8_15 vr2_8_15 vr3_8_15 vr4_8_15 vr5_8_15
################################################################
define pcodeop clearHistory;
define pcodeop countLeadingZeros;
define pcodeop countTrailingZeros;
define pcodeop dataCacheBlockAllocate;
define pcodeop dataCacheBlockFlush;

View File

@ -814,13 +814,13 @@
#cntlzd r0,r0 0x7c 00 00 74
:cntlzd A,S is OP=31 & S & A & BITS_11_15=0 & XOP_1_10=58 & Rc=0
{
A = countLeadingZeros(S);
A = lzcount(S);
}
#cntlzd. r0,r0 0x7c 00 00 75
:cntlzd. A,S is OP=31 & S & A & BITS_11_15=0 & XOP_1_10=58 & Rc=1
{
A = countLeadingZeros(S);
A = lzcount(S);
cr0flags(A);
}
@endif
@ -828,13 +828,13 @@
#cntlzw r0,r0 0x7c 00 00 34
:cntlzw A,S is OP=31 & S & A & BITS_11_15=0 & XOP_1_10=26 & Rc=0
{
A = countLeadingZeros(S:4);
A = lzcount(S:4);
}
#cntlzw. r0,r0 0x7c 00 00 35
:cntlzw. A,S is OP=31 & S & A & BITS_11_15=0 & XOP_1_10=26 & Rc=1
{
A = countLeadingZeros(S:4);
A = lzcount(S:4);
cr0flags(A);
}
#===========================================================

View File

@ -19,7 +19,6 @@ import java.math.BigInteger;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.CountLeadingZerosOpBehavior;
import ghidra.pcode.emulate.callother.OpBehaviorOther;
import ghidra.pcode.memstate.MemoryState;
import ghidra.pcodeCPort.error.LowlevelError;
@ -30,7 +29,6 @@ public class PPCEmulateInstructionStateModifier extends EmulateInstructionStateM
public PPCEmulateInstructionStateModifier(Emulate emu) {
super(emu);
registerPcodeOpBehavior("countLeadingZeros", new CountLeadingZerosOpBehavior());
registerPcodeOpBehavior("vectorPermute", new vectorPermuteOpBehavior());
}

View File

@ -490,8 +490,6 @@ define pcodeop cache_index_ivld;
define pcodeop cache_index_wb;
define pcodeop cache_index_wi;
define pcodeop round16;
define pcodeop leading_ones;
define pcodeop leading_zeros;
define pcodeop leading_signs;
define pcodeop crc32;
@ -1840,7 +1838,7 @@ SC: [a10]const0815Z10zz is PCPMode=0 & a10 & const0815Z10zz & op0003=8 & op0404=
# CLO D[c], D[a] (RR)
:clo Rd2831,Rd0811 is PCPMode=0 & Rd0811 & op0007=0xf & op1215=0x0 ; Rd2831 & op1627=0x1c0
{
Rd2831 = leading_ones(Rd0811);
Rd2831 = lzcount(~Rd0811);
}
# CLO.H D[c], D[a] (RR)
@ -1848,8 +1846,8 @@ SC: [a10]const0815Z10zz is PCPMode=0 & a10 & const0815Z10zz & op0003=8 & op0404=
{
local tmp1:4 = zext(Rd0811[16,16]);
local tmp0:4 = zext(Rd0811[0,16]);
Rd2831[16,16] = leading_ones(tmp1);
Rd2831[0,16] = leading_ones(tmp0);
Rd2831[16,16] = lzcount(~tmp1);
Rd2831[0,16] = lzcount(~tmp0);
}
# CLS D[c], D[a] (RR)
@ -1870,13 +1868,13 @@ SC: [a10]const0815Z10zz is PCPMode=0 & a10 & const0815Z10zz & op0003=8 & op0404=
# CLZ D[c], D[a] (RR)
:clz Rd2831,Rd0811 is PCPMode=0 & Rd0811 & op0007=0xf & op1215=0x0 ; Rd2831 & op1627=0x1b0
{
Rd2831 = leading_zeros(Rd0811);
Rd2831 = lzcount(Rd0811);
}
# CLZ.H D[c], D[a] (RR)
:clz.h Rd2831,Rd0811 is PCPMode=0 & Rd0811 & op0007=0xf & op1215=0x0 ; Rd2831 & op1627=0x7c0
{
local result:4 = (leading_zeros(Rd0811[16,16]) << 16) | leading_zeros(Rd0811[0,16]);
local result:4 = (lzcount(Rd0811[16,16]) << 16) | lzcount(Rd0811[0,16]);
Rd2831 = result;
}

View File

@ -11,57 +11,22 @@ macro lzcntflags(input, output) {
:LZCNT Reg16, rm16 is vexMode=0 & opsize=0 & $(PRE_66) & $(PRE_F3) & byte=0x0F; byte=0xBD; Reg16 ... & rm16 {
countTmp:2 = 0;
inputTmp:2 = rm16;
<loopbegin>
if ((inputTmp & 0x8000) != 0) goto <loopend>;
countTmp = countTmp + 1;
inputTmp = (inputTmp << 1) | 1;
goto <loopbegin>;
<loopend>
lzcntflags(rm16, countTmp);
Reg16 = countTmp;
Reg16 = lzcount(rm16);
lzcntflags(rm16, Reg16);
}
:LZCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xBD; Reg32 ... & check_Reg32_dest ... & rm32 {
countTmp:4 = 0;
inputTmp:4 = rm32;
<loopbegin>
if ((inputTmp & 0x80000000) != 0) goto <loopend>;
countTmp = countTmp + 1;
inputTmp = (inputTmp << 1) | 1;
goto <loopbegin>;
<loopend>
lzcntflags(rm32, countTmp);
Reg32 = countTmp;
Reg32 = lzcount(rm32);
lzcntflags(rm32, Reg32);
build check_Reg32_dest;
}
@ifdef IA64
:LZCNT Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xBD; Reg64 ... & rm64 {
countTmp:8 = 0;
inputTmp:8 = rm64;
<loopbegin>
if ((inputTmp & 0x8000000000000000) != 0) goto <loopend>;
countTmp = countTmp + 1;
inputTmp = (inputTmp << 1) | 1;
goto <loopbegin>;
<loopend>
lzcntflags(rm64, countTmp);
Reg64 = countTmp;
Reg64 = lzcount(rm64);
lzcntflags(rm64, Reg64);
}
@endif

View File

@ -661,6 +661,7 @@ exprSingle returns Expression:
| pcodeop='floor' '(' op1=expr ')'
| pcodeop='round' '(' op1=expr ')'
| pcodeop='popcount' '(' op1=expr ')'
| pcodeop='lzcount' '(' op1=expr ')'
| pcodeop='cpool' '(' op1=expr ',' op2=expr ',' op3=expr ')'
| pcodeop='newobject' '(' op1=newObjParams ')'
| op=[macroOrPcode] op1=paramlist
@ -1142,4 +1143,4 @@ terminal WS : (' '|'\t'|'\r'|'\n')+;
//
//terminal DEFINENAME: 'synthetic:DEFINENAME';
//terminal BEGINDEFINE: 'synthetic:BEGINDEFINE';
//terminal ENDDEFINE: 'synthetic:ENDDEFINE';
//terminal ENDDEFINE: 'synthetic:ENDDEFINE';

View File

@ -2,7 +2,8 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Additional P-CODE Operations</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="pcoderef.html" title="P-Code Reference Manual">
<link rel="up" href="pcoderef.html" title="P-Code Reference Manual">

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>P-Code Operation Reference</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="pcoderef.html" title="P-Code Reference Manual">
@ -676,6 +676,49 @@ count is zero extended into the output varnode.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="cpui_lzcount"></a>LZCOUNT</h3></div></div></div>
<div class="informalexample"><div class="table">
<a name="lzcount.htmltable"></a><table xml:id="lzcount.htmltable" frame="above" width="80%" rules="groups">
<col width="23%">
<col width="15%">
<col width="61%">
<thead><tr>
<td align="center" colspan="2"><span class="bold"><strong>Parameters</strong></span></td>
<td><span class="bold"><strong>Description</strong></span></td>
</tr></thead>
<tbody>
<tr>
<td align="right">input0</td>
<td></td>
<td>Input varnode to count.</td>
</tr>
<tr>
<td align="right">output</td>
<td></td>
<td>Resulting integer varnode containing count.</td>
</tr>
</tbody>
<tfoot>
<tr>
<td align="center" colspan="2"><span class="bold"><strong>Semantic statement</strong></span></td>
<td></td>
</tr>
<tr>
<td></td>
<td colspan="2"><code class="code">output = lzcount(input0);</code></td>
</tr>
</tfoot>
</table>
</div></div>
<p>
This operator counts the number of zeros starting at the most significant bit.
For instance, for a 4-byte varnode, a value of 0 returns 32, a value of 1
returns 31, and the value 2<sup>31</sup> returns 0.
The resulting count is zero extended into the output varnode.
</p>
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="cpui_int_equal"></a>INT_EQUAL</h3></div></div></div>
<div class="informalexample"><div class="table">
<a name="intequal.htmltable"></a><table xml:id="intequal.htmltable" frame="above" width="80%" rules="groups">

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>P-Code Reference Manual</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="pcoderef.html" title="P-Code Reference Manual">
@ -26,7 +26,7 @@
<div>
<div><h1 class="title">
<a name="pcoderef_title"></a>P-Code Reference Manual</h1></div>
<div><p class="releaseinfo">Last updated September 5, 2019</p></div>
<div><p class="releaseinfo">Last updated March 2, 2023</p></div>
</div>
<hr>
</div>
@ -117,52 +117,58 @@
</tr>
<tr>
<td></td>
<td><a class="link" href="pcodedescription.html#cpui_int_equal" title="INT_EQUAL">INT_EQUAL</a></td>
<td><a class="link" href="pcodedescription.html#cpui_lzcount" title="LZCOUNT">LZCOUNT</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_mult" title="INT_MULT">INT_MULT</a></td>
<td><a class="link" href="pcodedescription.html#cpui_float_floor" title="FLOAT_FLOOR">FLOAT_FLOOR</a></td>
</tr>
<tr>
<td></td>
<td><a class="link" href="pcodedescription.html#cpui_int_notequal" title="INT_NOTEQUAL">INT_NOTEQUAL</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_equal" title="INT_EQUAL">INT_EQUAL</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_div" title="INT_DIV">INT_DIV</a></td>
<td><a class="link" href="pcodedescription.html#cpui_float_round" title="FLOAT_ROUND">FLOAT_ROUND</a></td>
</tr>
<tr>
<td></td>
<td><a class="link" href="pcodedescription.html#cpui_int_less" title="INT_LESS">INT_LESS</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_notequal" title="INT_NOTEQUAL">INT_NOTEQUAL</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_rem" title="INT_REM">INT_REM</a></td>
<td><a class="link" href="pcodedescription.html#cpui_float_nan" title="FLOAT_NAN">FLOAT_NAN</a></td>
</tr>
<tr>
<td></td>
<td><a class="link" href="pcodedescription.html#cpui_int_sless" title="INT_SLESS">INT_SLESS</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_less" title="INT_LESS">INT_LESS</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_sdiv" title="INT_SDIV">INT_SDIV</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int2float" title="INT2FLOAT">INT2FLOAT</a></td>
</tr>
<tr>
<td></td>
<td><a class="link" href="pcodedescription.html#cpui_int_lessequal" title="INT_LESSEQUAL">INT_LESSEQUAL</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_sless" title="INT_SLESS">INT_SLESS</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_srem" title="INT_SREM">INT_SREM</a></td>
<td><a class="link" href="pcodedescription.html#cpui_float2float" title="FLOAT2FLOAT">FLOAT2FLOAT</a></td>
</tr>
<tr>
<td></td>
<td><a class="link" href="pcodedescription.html#cpui_int_slessequal" title="INT_SLESSEQUAL">INT_SLESSEQUAL</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_lessequal" title="INT_LESSEQUAL">INT_LESSEQUAL</a></td>
<td><a class="link" href="pcodedescription.html#cpui_bool_negate" title="BOOL_NEGATE">BOOL_NEGATE</a></td>
<td><a class="link" href="pcodedescription.html#cpui_trunc" title="TRUNC">TRUNC</a></td>
</tr>
<tr>
<td></td>
<td><a class="link" href="pcodedescription.html#cpui_int_zext" title="INT_ZEXT">INT_ZEXT</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_slessequal" title="INT_SLESSEQUAL">INT_SLESSEQUAL</a></td>
<td><a class="link" href="pcodedescription.html#cpui_bool_xor" title="BOOL_XOR">BOOL_XOR</a></td>
<td><a class="link" href="pseudo-ops.html#cpui_cpoolref" title="CPOOLREF">CPOOLREF</a></td>
</tr>
<tr>
<td></td>
<td><a class="link" href="pcodedescription.html#cpui_int_sext" title="INT_SEXT">INT_SEXT</a></td>
<td><a class="link" href="pcodedescription.html#cpui_int_zext" title="INT_ZEXT">INT_ZEXT</a></td>
<td><a class="link" href="pcodedescription.html#cpui_bool_and" title="BOOL_AND">BOOL_AND</a></td>
<td><a class="link" href="pseudo-ops.html#cpui_new" title="NEW">NEW</a></td>
</tr>
<tr>
<td></td>
<td><a class="link" href="pcodedescription.html#cpui_int_sext" title="INT_SEXT">INT_SEXT</a></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Pseudo P-CODE Operations</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="pcoderef.html" title="P-Code Reference Manual">

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Syntax Reference</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="pcoderef.html" title="P-Code Reference Manual">
@ -139,6 +139,11 @@
<td><code class="code">popcount(v0)</code></td>
<td>Count 1 bits in v0.</td>
</tr>
<tr>
<td>LZCOUNT</td>
<td><code class="code">lzcount(v0)</code></td>
<td>Counts the number of leading zero bits in v0.</td>
</tr>
<tr>
<td>INT_EQUAL</td>
<td><code class="code">v0 == v1</code></td>

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>SLEIGH</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="sleigh.html" title="SLEIGH">
@ -27,7 +27,7 @@
<div><h1 class="title">
<a name="sleigh_title"></a>SLEIGH</h1></div>
<div><h3 class="subtitle"><i>A Language for Rapid Processor Specification</i></h3></div>
<div><p class="releaseinfo">Last updated August 24, 2022</p></div>
<div><p class="releaseinfo">Last updated March 2, 2023</p></div>
<div><p class="pubdate">Originally published December 16, 2005</p></div>
</div>
<hr>
@ -372,7 +372,8 @@ general purpose processor instruction sets. They break up into groups.
</tr>
<tr>
<td>Logical</td>
<td><code class="code">INT_NEGATE, INT_XOR, INT_AND, INT_OR, INT_LEFT, INT_RIGHT, INT_SRIGHT, POPCOUNT</code></td>
<td><code class="code">INT_NEGATE, INT_XOR, INT_AND, INT_OR, INT_LEFT, INT_RIGHT, INT_SRIGHT,
POPCOUNT, LZCOUNT</code></td>
</tr>
<tr>
<td>Integer Comparison</td>

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>7. Constructors</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="sleigh.html" title="SLEIGH">

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>8. Using Context</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="sleigh.html" title="SLEIGH">

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>4. Basic Definitions</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="sleigh.html" title="SLEIGH">

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>2. Basic Specification Layout</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="sleigh.html" title="SLEIGH">

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>3. Preprocessing</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="sleigh.html" title="SLEIGH">

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>9. P-code Tables</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="sleigh.html" title="SLEIGH">
@ -83,6 +83,12 @@ to lowest.
<td>Count the number of 1 bits in v0.
</td>
</tr>
<tr>
<td><code class="code">LZCOUNT</code></td>
<td><code class="code">lzcount(v0)</code></td>
<td>Count the number of leading 0 bits in v0.
</td>
</tr>
<tr>
<td><code class="code">(simulated)</code></td>
<td><code class="code">v0[6,1]</code></td>

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>5. Introduction to Symbols</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="sleigh.html" title="SLEIGH">

View File

@ -2,7 +2,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>6. Tokens and Fields</title>
<link rel="stylesheet" type="text/css" href="Frontpage.css">
<link rel="stylesheet" type="text/css" href="DefaultStyle.css">
<link rel="stylesheet" type="text/css" href="languages.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="sleigh.html" title="SLEIGH">