Compare commits

...

11 Commits

Author SHA1 Message Date
Godzil
b58f315c98 cleanup things, stop trying with CS 2018-09-19 17:59:25 +01:00
Godzil
7687c2b7d2 Trying to make parser to correctly handle CS 2018-09-18 18:50:13 +01:00
Artur K
0abbce6f4e
Merge pull request #32 from nemerle/add-license-1
Create LICENSE
2018-03-23 19:59:48 +01:00
Artur K
8ffdf657ec
Create LICENSE
Original code was using GPL.
2018-03-23 19:59:34 +01:00
nemerle
2232a76033 Disregard signed/unsigned difference in AstIdent::idID 2017-02-13 16:14:38 +01:00
nemerle
d6af9c1555 Add iInvalid enum value for invalid instructions
Various cleanups.
2017-02-13 13:24:54 +01:00
nemerle
d7acc8cd4d rename otherLongRegi to getPairedRegisterAt, make it a method of
LOCAL_ID struct.
2017-02-13 12:31:30 +01:00
nemerle
a5f1d17e83 Various code cleanups. 2017-02-13 12:11:29 +01:00
nemerle
29efcd5be1 Remove references to malloc.h closes #28 2017-02-07 12:09:58 +01:00
Artur K
4656db9484 Merge pull request #25 from gitter-badger/gitter-badge
Add a Gitter chat badge to Readme.md
2016-05-23 13:30:14 +02:00
The Gitter Badger
b33d7239e5 Add Gitter badge 2016-05-23 11:28:47 +00:00
34 changed files with 1479 additions and 1059 deletions

339
LICENSE Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -6,6 +6,8 @@ To reflect those fixes, I've edited the original readme a bit.
dcc Distribution dcc Distribution
================ ================
[![Join the chat at https://gitter.im/nemerle/dcc](https://badges.gitter.im/nemerle/dcc.svg)](https://gitter.im/nemerle/dcc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
The code provided in this distribution is (C) by their authors: The code provided in this distribution is (C) by their authors:
- Cristina Cifuentes (most of dcc code) - Cristina Cifuentes (most of dcc code)
- Mike van Emmerik (signatures and prototype code) - Mike van Emmerik (signatures and prototype code)

View File

@ -3,9 +3,9 @@
#include <vector> #include <vector>
struct PROG /* Loaded program image parameters */ struct PROG /* Loaded program image parameters */
{ {
int16_t initCS=0; uint16_t initCS=0;
int16_t initIP=0; /* These are initial load values */ uint16_t initIP=0; /* These are initial load values */
int16_t initSS=0; /* Probably not of great interest */ uint16_t initSS=0; /* Probably not of great interest */
uint16_t initSP=0; uint16_t initSP=0;
bool fCOM=false; /* Flag set if COM program (else EXE)*/ bool fCOM=false; /* Flag set if COM program (else EXE)*/
int cReloc=0; /* No. of relocation table entries */ int cReloc=0; /* No. of relocation table entries */

View File

@ -1,16 +1,13 @@
#pragma once #pragma once
#include "ast.h" #include "ast.h"
#ifdef PASCAL
#undef PASCAL
#endif
class QTextStream; class QTextStream;
struct CConv { struct CConv {
enum Type { enum Type {
UNKNOWN=0, eUnknown=0,
C, eCdecl,
PASCAL ePascal
}; };
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0; virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
virtual void writeComments(QTextStream &)=0; virtual void writeComments(QTextStream &)=0;

View File

@ -99,7 +99,7 @@ enum icodeType
/* LOW_LEVEL icode opcodes */ /* LOW_LEVEL icode opcodes */
enum llIcode enum llIcode
{ {
//iINVALID, iINVALID=-1,
iCBW, /* 0 */ iCBW, /* 0 */
iAAA, iAAA,
iAAD, iAAD,

View File

@ -100,7 +100,7 @@ protected:
hasCase(false),liveAnal(0) hasCase(false),liveAnal(0)
{ {
type = new FunctionType; type = new FunctionType;
callingConv(CConv::UNKNOWN); callingConv(CConv::eUnknown);
} }
public: public:

View File

@ -221,9 +221,6 @@ struct AstIdent : public UnaryOperator
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym); virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx); virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId); virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
protected:
eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl);
}; };
struct GlobalVariable : public AstIdent struct GlobalVariable : public AstIdent
{ {
@ -272,7 +269,7 @@ struct Constant : public AstIdent
} }
QString walkCondExpr(Function *pProc, int *numLoc) const; QString walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *pproc) const; int hlTypeSize(Function *pproc) const;
hlType expType(Function *pproc) const; hlType expType(Function *pproc) const { return TYPE_CONST; }
}; };
struct FuncNode : public AstIdent struct FuncNode : public AstIdent
{ {

View File

@ -28,25 +28,25 @@ extern bundle cCode; /* Output C procedure's declaration and code */
extern QString asm1_name, asm2_name; /* Assembler output filenames */ extern QString asm1_name, asm2_name; /* Assembler output filenames */
typedef struct { /* Command line option flags */ /** Command line option flags */
unsigned verbose : 1; struct OPTION
unsigned VeryVerbose : 1; {
unsigned asm1 : 1; /* Early disassembly listing */ bool verbose;
unsigned asm2 : 1; /* Disassembly listing after restruct */ bool VeryVerbose;
unsigned Map : 1; bool asm1; /* Early disassembly listing */
unsigned Stats : 1; bool asm2; /* Disassembly listing after restruct */
unsigned Interact : 1; /* Interactive mode */ bool Map;
unsigned Calls : 1; /* Follow register indirect calls */ bool Stats;
bool Interact; /* Interactive mode */
bool Calls; /* Follow register indirect calls */
QString filename; /* The input filename */ QString filename; /* The input filename */
uint32_t CustomEntryPoint; uint32_t CustomEntryPoint;
} OPTION; };
extern OPTION option; /* Command line options */ extern OPTION option; /* Command line options */
#include "BinaryImage.h" #include "BinaryImage.h"
/* Memory map states */ /* Memory map states */
enum eAreaType enum eAreaType
{ {
@ -100,7 +100,5 @@ QString writeJcondInv(HLTYPE, Function *, int *);
/* Exported funcions from locident.c */ /* Exported funcions from locident.c */
bool checkLongEq(LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset); bool checkLongEq(LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
bool checkLongRegEq(LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &); bool checkLongRegEq(LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
eReg otherLongRegi(eReg, int, LOCAL_ID *);
extern const char *indentStr(int level); extern const char *indentStr(int level);

View File

@ -165,8 +165,8 @@ struct AssignType : public HlTypeSupport
/* for HLI_ASSIGN */ /* for HLI_ASSIGN */
protected: protected:
public: public:
Expr *m_lhs; Expr * m_lhs;
Expr *rhs; Expr * m_rhs;
AssignType() {} AssignType() {}
Expr *lhs() const {return m_lhs;} Expr *lhs() const {return m_lhs;}
void lhs(Expr *l); void lhs(Expr *l);
@ -176,8 +176,8 @@ public:
struct ExpType : public HlTypeSupport struct ExpType : public HlTypeSupport
{ {
/* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/ /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
Expr *v; Expr * v;
ExpType() : v(0) {} ExpType() : v(nullptr) {}
bool removeRegFromLong(eReg regi, LOCAL_ID *locId) bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
{ {
v=performLongRemoval(regi,locId,v); v=performLongRemoval(regi,locId,v);
@ -313,7 +313,7 @@ struct LLOperand
struct LLInst struct LLInst
{ {
protected: protected:
uint32_t m_opcode; // Low level opcode identifier llIcode m_opcode; // Low level opcode identifier
uint32_t flg; /* icode flags */ uint32_t flg; /* icode flags */
LLOperand m_src; /* source operand */ LLOperand m_src; /* source operand */
public: public:
@ -326,8 +326,8 @@ public:
std::vector<uint32_t> caseTbl2; std::vector<uint32_t> caseTbl2;
int hllLabNum; /* label # for hll codegen */ int hllLabNum; /* label # for hll codegen */
uint32_t getOpcode() const { return m_opcode;} llIcode getOpcode() const { return m_opcode;}
void setOpcode(uint32_t op) { m_opcode=op; } void setOpcode(uint32_t op) { m_opcode=(llIcode)op; }
bool conditionalJump() bool conditionalJump()
{ {
return (getOpcode() >= iJB) and (getOpcode() < iJCXZ); return (getOpcode() >= iJB) and (getOpcode() < iJCXZ);

View File

@ -28,7 +28,7 @@ struct LLInst;
typedef std::list<ICODE>::iterator iICODE; typedef std::list<ICODE>::iterator iICODE;
struct IDX_ARRAY : public std::vector<iICODE> struct IDX_ARRAY : public std::vector<iICODE>
{ {
bool inList(iICODE idx) bool inList(iICODE idx) const
{ {
return std::find(begin(),end(),idx)!=end(); return std::find(begin(),end(),idx)!=end();
} }
@ -96,10 +96,9 @@ protected:
LONGID_TYPE m_longId; /* For TYPE_LONG_(UN)SIGN registers */ LONGID_TYPE m_longId; /* For TYPE_LONG_(UN)SIGN registers */
public: public:
hlType type; /* Probable type */ hlType type; /* Probable type */
bool illegal; /* Boolean: not a valid field any more */
//std::vector<iICODE> idx;
IDX_ARRAY idx; /* Index into icode array (REG_FRAME only) */ IDX_ARRAY idx; /* Index into icode array (REG_FRAME only) */
frameType loc; /* Frame location */ frameType loc; /* Frame location */
bool illegal; /* Boolean: not a valid field any more */
bool hasMacro; /* Identifier requires a macro */ bool hasMacro; /* Identifier requires a macro */
char macro[10]; /* Macro for this identifier */ char macro[10]; /* Macro for this identifier */
QString name; /* Identifier's name */ QString name; /* Identifier's name */
@ -143,6 +142,8 @@ public:
sprintf (buf, "loc%d", i); sprintf (buf, "loc%d", i);
name=buf; name=buf;
} }
bool isLongRegisterPair() const { return (loc == REG_FRAME) and isLong();}
eReg getPairedRegister(eReg first) const;
}; };
struct LOCAL_ID struct LOCAL_ID
@ -170,10 +171,11 @@ public:
void flagByteWordId(int off); void flagByteWordId(int off);
void propLongId(uint8_t regL, uint8_t regH, const QString & name); void propLongId(uint8_t regL, uint8_t regH, const QString & name);
size_t csym() const {return id_arr.size();} size_t csym() const {return id_arr.size();}
void newRegArg(iICODE picode, iICODE ticode) const; void newRegArg(ICODE & picode, ICODE & ticode) const;
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const; void processTargetIcode(ICODE & picode, int &numHlIcodes, ICODE & ticode, bool isLong) const;
void forwardSubs(Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const; void forwardSubs(Expr *lhs, Expr *rhs, ICODE & picode, ICODE & ticode, int &numHlIcodes) const;
AstIdent *createId(const ID *retVal, iICODE ix_); AstIdent *createId(const ID *retVal, iICODE ix_);
eReg getPairedRegisterAt(int idx,eReg first) const;
}; };

View File

@ -54,7 +54,7 @@ public:
ilFunction createFunction(FunctionType *f, const QString & name); ilFunction createFunction(FunctionType *f, const QString & name);
bool valid(ilFunction iter); bool valid(ilFunction iter);
int getSymIdxByAdd(uint32_t adr); int getSymIdxByAddr(uint32_t adr);
bool validSymIdx(size_t idx); bool validSymIdx(size_t idx);
size_t symbolSize(size_t idx); size_t symbolSize(size_t idx);
hlType symbolType(size_t idx); hlType symbolType(size_t idx);

View File

@ -11,7 +11,7 @@
struct STATE struct STATE
{ {
uint32_t IP; /* Offset into Image */ uint32_t IP; /* Offset into Image */
int16_t r[INDEX_BX_SI]; /* Value of segs and AX */ uint16_t r[INDEX_BX_SI]; /* Value of segs and AX */
bool f[INDEX_BX_SI]; /* True if r[.] has a value */ bool f[INDEX_BX_SI]; /* True if r[.] has a value */
struct struct
{ /* For case stmt indexed reg */ { /* For case stmt indexed reg */

View File

@ -15,9 +15,9 @@ CConv *CConv::create(Type v)
if(nullptr==u_call) if(nullptr==u_call)
u_call = new Unknown_CallingConvention; u_call = new Unknown_CallingConvention;
switch(v) { switch(v) {
case UNKNOWN: return u_call; case eUnknown: return u_call;
case C: return c_call; case eCdecl: return c_call;
case PASCAL: return p_call; case ePascal: return p_call;
} }
assert(false); assert(false);
return nullptr; return nullptr;

View File

@ -228,8 +228,7 @@ struct ComLoader : public DosLoader {
prog.initSP = 0xFFFE; prog.initSP = 0xFFFE;
prog.cReloc = 0; prog.cReloc = 0;
prepareImage(prog,cb,fp); prepareImage(prog, cb, fp);
/* Set up memory map */ /* Set up memory map */
cb = (prog.cbImage + 3) / 4; cb = (prog.cbImage + 3) / 4;
@ -238,6 +237,120 @@ struct ComLoader : public DosLoader {
return true; return true;
} }
}; };
#if 0
struct RomLoader {
bool canLoad(QFile &fp) {
fp.seek(0xFFF0);
uint8_t sig[1];
if(fp.read((char *)sig,1) == 1)
{
return (sig[0] == 0xEA);
}
return false;
}
bool load(PROG &prog,QFile &fp) {
printf("Loading ROM...\n");
fp.seek(0);
/* ROM file
* In this case the load module size is just the file length
*/
auto cb = fp.size();
fp.seek(cb - 0x10);
uint8_t buf[5];
printf("Going to get CS/IP...\n");
if(fp.read((char *)buf, 5) != 5)
{
return false;
}
fp.seek(0);
/* ROM File, Hard to say where it is suppose to start, so try to trust the
*/
prog.initIP = (buf[2] << 8) | buf[1];
//prog.initCS = 0;
prog.initCS = (buf[4] << 8) | buf[3];
prog.initSS = 0;
prog.initSP = 0xFFFE;
prog.cReloc = 0;
prepareImage(prog, cb, fp);
/* Set up memory map */
cb = (prog.cbImage + 3) / 4;
prog.map = (uint8_t *)malloc(cb);
memset(prog.map, BM_UNKNOWN, (size_t)cb);
return true;
}
protected:
void prepareImage(PROG &prog, size_t sz, QFile &fp)
{
int32_t start = 0x100000 - sz;
/* Allocate a block of memory for the program. */
prog.cbImage = 1 * 1024 * 1024; /* Allocate the whole 1MB memory */
//prog.cbImage = 64 * 1024; /* Allocate the whole 1MB memory */
prog.Imagez = new uint8_t [prog.cbImage];
if (fp.read((char *)prog.Imagez + start, sz) != sz)
//if (fp.read((char *)prog.Imagez, sz) != sz)
{
fatalError(CANNOT_READ, fp.fileName().toLocal8Bit().data());
}
}
};
#else
struct RomLoader {
bool canLoad(QFile &fp) {
fp.seek(0xFFF0);
uint8_t sig[1];
if(fp.read((char *)sig,1) == 1)
{
return (sig[0] == 0xEA);
}
return false;
}
bool load(PROG &prog,QFile &fp) {
fp.seek(0);
/* COM file
* In this case the load module size is just the file length
*/
auto cb = fp.size();
/* COM programs start off with an ORG 100H (to leave room for a PSP)
* This is also the implied start address so if we load the image
* at offset 100H addresses should all line up properly again.
*/
prog.initCS = 0;
prog.initIP = 0x000;
prog.initSS = 0;
prog.initSP = 0xFFFE;
prog.cReloc = 0;
prepareImage(prog, cb, fp);
/* Set up memory map */
cb = (prog.cbImage + 3) / 4;
prog.map = (uint8_t *)malloc(cb);
memset(prog.map, BM_UNKNOWN, (size_t)cb);
return true;
}
protected:
void prepareImage(PROG &prog, size_t sz, QFile &fp)
{
/* Allocate a block of memory for the program. */
prog.cbImage = sz;
prog.Imagez = new uint8_t[prog.cbImage];
if (sz != fp.read((char *)prog.Imagez, sz))
fatalError(CANNOT_READ, fp.fileName().toLocal8Bit().data());
}
};
#endif
struct ExeLoader : public DosLoader { struct ExeLoader : public DosLoader {
bool canLoad(QFile &fp) { bool canLoad(QFile &fp) {
if(fp.size()<sizeof(header)) if(fp.size()<sizeof(header))
@ -340,8 +453,16 @@ bool Project::load()
{ {
fatalError(CANNOT_READ, fname); fatalError(CANNOT_READ, fname);
} }
RomLoader rom_loader;
ComLoader com_loader; ComLoader com_loader;
ExeLoader exe_loader; ExeLoader exe_loader;
if(rom_loader.canLoad(finfo)) {
/* We have no relacation and code should be on 64K only,
* So let's consider it as a COM file
*/
prog.fCOM = true;
return rom_loader.load(prog,finfo);
}
if(exe_loader.canLoad(finfo)) { if(exe_loader.canLoad(finfo)) {
prog.fCOM = false; prog.fCOM = false;
return exe_loader.load(prog,finfo); return exe_loader.load(prog,finfo);

View File

@ -13,6 +13,7 @@
#include "project.h" #include "project.h"
#include <QtCore/QTextStream> #include <QtCore/QTextStream>
#include <QtCore/QDebug>
#include <boost/range.hpp> #include <boost/range.hpp>
#include <boost/range/adaptor/filtered.hpp> #include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm.hpp> #include <boost/range/algorithm.hpp>
@ -29,12 +30,15 @@ using namespace boost::adaptors;
extern int strSize (const uint8_t *, char); extern int strSize (const uint8_t *, char);
extern char *cChar(uint8_t c); extern char *cChar(uint8_t c);
namespace
{
// Conditional operator symbols in C. Index by condOp enumeration type // Conditional operator symbols in C. Index by condOp enumeration type
static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ", constexpr const char * condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
" & ", " | ", " ^ ", " ~ ", " & ", " | ", " ^ ", " ~ ",
" + ", " - ", " * ", " / ", " + ", " - ", " * ", " / ",
" >> ", " << ", " % ", " && ", " || " }; " >> ", " << ", " % ", " && ", " || " };
/* Size of hl types */
constexpr const int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4};
/* Local expression stack */ /* Local expression stack */
//typedef struct _EXP_STK { //typedef struct _EXP_STK {
@ -43,13 +47,13 @@ static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ",
//} EXP_STK; - for local expression stack //} EXP_STK; - for local expression stack
/* Returns the integer i in C hexadecimal format */ /* Returns the integer i in C hexadecimal format */
static const char *hexStr (uint16_t i) const char *hexStr (uint16_t i)
{ {
static char buf[10]; static char buf[10];
sprintf (buf, "%s%x", (i > 9) ? "0x" : "", i); sprintf (buf, "%s%x", (i > 9) ? "0x" : "", i);
return (buf); return buf;
}
} }
/* Sets the du record for registers according to the du flag */ /* Sets the du record for registers according to the du flag */
void ICODE::setRegDU (eReg regi, operDu du_in) void ICODE::setRegDU (eReg regi, operDu du_in)
@ -62,19 +66,19 @@ void ICODE::setRegDU (eReg regi, operDu du_in)
} }
switch (du_in) switch (du_in)
{ {
case eDEF: case eDEF:
du.def.addReg(regi); du.def.addReg(regi);
du1.addDef(regi); du1.addDef(regi);
break; break;
case eUSE: case eUSE:
du.use.addReg(regi); du.use.addReg(regi);
break; break;
case USE_DEF: case USE_DEF:
du.addDefinedAndUsed(regi); du.addDefinedAndUsed(regi);
du1.addDef(regi); du1.addDef(regi);
break; break;
case NONE: /* do nothing */ case NONE: /* do nothing */
break; break;
} }
} }
@ -84,24 +88,24 @@ void ICODE::copyDU(const ICODE &duIcode, operDu _du, operDu duDu)
{ {
switch (_du) switch (_du)
{ {
case eDEF: case eDEF:
if (duDu == eDEF) if (duDu == eDEF)
du.def=duIcode.du.def; du.def=duIcode.du.def;
else else
du.def=duIcode.du.use; du.def=duIcode.du.use;
break; break;
case eUSE: case eUSE:
if (duDu == eDEF) if (duDu == eDEF)
du.use = duIcode.du.def; du.use = duIcode.du.def;
else else
du.use = duIcode.du.use; du.use = duIcode.du.use;
break; break;
case USE_DEF: case USE_DEF:
du = duIcode.du; du = duIcode.du;
break; break;
case NONE: case NONE:
assert(false); assert(false);
break; break;
} }
} }
@ -124,7 +128,7 @@ GlobalVariable::GlobalVariable(int16_t segValue, int16_t off)
valid = true; valid = true;
ident.idType = GLOB_VAR; ident.idType = GLOB_VAR;
adr = opAdr(segValue, off); adr = opAdr(segValue, off);
auto i=Project::get()->getSymIdxByAdd(adr); auto i=Project::get()->getSymIdxByAddr(adr);
if ( not Project::get()->validSymIdx(i) ) if ( not Project::get()->validSymIdx(i) )
{ {
printf ("Error, glob var not found in symtab\n"); printf ("Error, glob var not found in symtab\n");
@ -136,7 +140,7 @@ GlobalVariable::GlobalVariable(int16_t segValue, int16_t off)
QString GlobalVariable::walkCondExpr(Function *, int *) const QString GlobalVariable::walkCondExpr(Function *, int *) const
{ {
if(valid) if(valid)
return Project::get()->symtab[globIdx].name; return Project::get()->symbolName(globIdx);
return "INVALID GlobalVariable"; return "INVALID GlobalVariable";
} }
@ -259,26 +263,26 @@ AstIdent *AstIdent::Other(eReg seg, eReg regi, int16_t off)
* TYPE_WORD_SIGN */ * TYPE_WORD_SIGN */
AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_) AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
{ {
int idx;
AstIdent *newExp=nullptr; AstIdent *newExp=nullptr;
switch(retVal->type) switch(retVal->type)
{ {
case TYPE_LONG_SIGN: case TYPE_LONG_SIGN:
{ {
newExp = new AstIdent(); newExp = new AstIdent();
idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_); int idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
newExp->ident.idType = LONG_VAR; newExp->ident.idType = LONG_VAR;
newExp->ident.idNode.longIdx = idx; newExp->ident.idNode.longIdx = idx;
break; break;
} }
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG,locsym); case TYPE_WORD_SIGN:
break; newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG,locsym);
case TYPE_BYTE_SIGN: break;
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),BYTE_REG,locsym); case TYPE_BYTE_SIGN:
break; newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),BYTE_REG,locsym);
default: break;
fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type); default:
fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type);
} }
return (newExp); return (newExp);
} }
@ -345,20 +349,19 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
newExp = AstIdent::Other (pm.seg, pm.regi, pm.off); newExp = AstIdent::Other (pm.seg, pm.regi, pm.off);
/**** check long ops, indexed global var *****/ /**** check long ops, indexed global var *****/
} }
else /* (pm->regi >= INDEXBASE and pm->off = 0) => indexed and no off */ else /* (pm->regi >= INDEXBASE and pm->off = 0) => indexed and no off */
{ {
if ((pm.seg == rDS) and (pm.regi > INDEX_BP_DI)) /* dereference */ if ((pm.seg == rDS) and (pm.regi > INDEX_BP_DI)) /* dereference */
{ {
eReg selected; eReg selected;
switch (pm.regi) { switch (pm.regi) {
case INDEX_SI: selected = rSI; break; case INDEX_SI: selected = rSI; break;
case INDEX_DI: selected = rDI; break; case INDEX_DI: selected = rDI; break;
case INDEX_BP: selected = rBP; break; case INDEX_BP: selected = rBP; break;
case INDEX_BX: selected = rBX; break; case INDEX_BX: selected = rBX; break;
default: default:
newExp = nullptr; newExp = nullptr;
assert(false); assert(false);
} }
//NOTICE: was selected, 0 //NOTICE: was selected, 0
newExp = new RegisterNode(LLOperand(selected, 0), &pProc->localId); newExp = new RegisterNode(LLOperand(selected, 0), &pProc->localId);
@ -368,7 +371,7 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
else else
newExp = AstIdent::Other (pm.seg, pm.regi, 0); newExp = AstIdent::Other (pm.seg, pm.regi, 0);
} }
return (newExp); return newExp;
} }
@ -378,31 +381,28 @@ condId LLInst::idType(opLoc sd) const
const LLOperand &pm((sd == SRC) ? src() : m_dst); const LLOperand &pm((sd == SRC) ? src() : m_dst);
if ((sd == SRC) and testFlags(I)) if ((sd == SRC) and testFlags(I))
return (CONSTANT); return CONSTANT;
else if (pm.regi == 0) else if (pm.regi == 0)
return (GLOB_VAR); return GLOB_VAR;
else if ( pm.isReg() ) else if ( pm.isReg() )
return (REGISTER); return REGISTER;
else if ((pm.seg == rSS) and (pm.regi == INDEX_BP)) else if ((pm.seg == rSS) and (pm.regi == INDEX_BP)) // TODO: this assumes BP-based function frames !
{ {
//TODO: which pm.seg/pm.regi pairs should produce PARAM/LOCAL_VAR ? //TODO: which pm.seg/pm.regi pairs should produce PARAM/LOCAL_VAR ?
if (pm.off >= 0) if (pm.off >= 0)
return (PARAM); return PARAM;
else return LOCAL_VAR;
return (LOCAL_VAR);
} }
else else
return (OTHER); return OTHER;
} }
/* Size of hl types */
int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4};
int Expr::hlTypeSize(Function * pproc) const int Expr::hlTypeSize(Function * pproc) const
{ {
if (this == nullptr) if (this == nullptr)
return (2); /* for TYPE_UNKNOWN */ return 2; /* for TYPE_UNKNOWN */
fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type); fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type);
return 2; // CC: is this correct? return 2; // CC: is this correct?
} }
@ -429,22 +429,22 @@ int AstIdent::hlTypeSize(Function *pproc) const
{ {
switch (ident.idType) switch (ident.idType)
{ {
case GLOB_VAR: case GLOB_VAR:
assert(false); assert(false);
return 1; return 1;
case LOCAL_VAR: case LOCAL_VAR:
return (hlSize[pproc->localId.id_arr[ident.idNode.localIdx].type]); return (hlSize[pproc->localId.id_arr[ident.idNode.localIdx].type]);
case PARAM: case PARAM:
return (hlSize[pproc->args[ident.idNode.paramIdx].type]); return (hlSize[pproc->args[ident.idNode.paramIdx].type]);
case STRING: case STRING:
return (2); return 2;
case LONG_VAR: case LONG_VAR:
return (4); return 4;
case OTHER: case OTHER:
return (2); return 2;
default: default:
assert(false); assert(false);
return -1; return -1;
} /* eos */ } /* eos */
} }
hlType BinaryOperator::expType(Function *pproc) const hlType BinaryOperator::expType(Function *pproc) const
@ -478,24 +478,24 @@ hlType AstIdent::expType(Function *pproc) const
{ {
switch (ident.idType) switch (ident.idType)
{ {
case UNDEF: case UNDEF:
case CONSTANT: case CONSTANT:
case FUNCTION: case FUNCTION:
case REGISTER: case REGISTER:
case GLOB_VAR: case GLOB_VAR:
case GLOB_VAR_IDX: case GLOB_VAR_IDX:
assert(false); assert(false);
return TYPE_UNKNOWN; return TYPE_UNKNOWN;
case LOCAL_VAR: case LOCAL_VAR:
return (pproc->localId.id_arr[ident.idNode.localIdx].type); return (pproc->localId.id_arr[ident.idNode.localIdx].type);
case PARAM: case PARAM:
return (pproc->args[ident.idNode.paramIdx].type); return (pproc->args[ident.idNode.paramIdx].type);
case STRING: case STRING:
return (TYPE_STR); return (TYPE_STR);
case LONG_VAR: case LONG_VAR:
return (pproc->localId.id_arr[ident.idNode.longIdx].type); return (pproc->localId.id_arr[ident.idNode.longIdx].type);
default: default:
return (TYPE_UNKNOWN); return (TYPE_UNKNOWN);
} /* eos */ } /* eos */
return (TYPE_UNKNOWN); return (TYPE_UNKNOWN);
} }
@ -508,17 +508,17 @@ hlType AstIdent::expType(Function *pproc) const
Expr * HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree) Expr * HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree)
{ {
switch (tree->m_type) { switch (tree->m_type) {
case BOOLEAN_OP: case BOOLEAN_OP:
case POST_INC: case POST_DEC: case POST_INC: case POST_DEC:
case PRE_INC: case PRE_DEC: case PRE_INC: case PRE_DEC:
case NEGATION: case ADDRESSOF: case NEGATION: case ADDRESSOF:
case DEREFERENCE: case DEREFERENCE:
case IDENTIFIER: case IDENTIFIER:
return tree->performLongRemoval(regi,locId); return tree->performLongRemoval(regi,locId);
break; break;
default: default:
fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type); fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type);
break; break;
} }
return tree; return tree;
} }
@ -560,55 +560,59 @@ QString AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
switch (ident.idType) switch (ident.idType)
{ {
case LOCAL_VAR: case LOCAL_VAR:
o << pProc->localId.id_arr[ident.idNode.localIdx].name; o << pProc->localId.id_arr[ident.idNode.localIdx].name;
break; break;
case PARAM: case PARAM:
psym = &pProc->args[ident.idNode.paramIdx]; psym = &pProc->args[ident.idNode.paramIdx];
if (psym->hasMacro) if (psym->hasMacro)
o << psym->macro<<"("<<psym->name<< ")"; o << psym->macro<<"("<<psym->name<< ")";
else else
o << psym->name; o << psym->name;
break; break;
case STRING: case STRING:
o << getString (ident.idNode.strIdx); o << getString (ident.idNode.strIdx);
break; break;
case LONG_VAR: case LONG_VAR:
id = &pProc->localId.id_arr[ident.idNode.longIdx]; id = &pProc->localId.id_arr[ident.idNode.longIdx];
if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/ if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/
o << id->name; o << id->name;
else if (id->loc == REG_FRAME) else if (id->loc == REG_FRAME)
{ {
id->setLocalName(++(*numLoc)); id->setLocalName(++(*numLoc));
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; "; codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" << codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
Machine_X86::regName(id->longId().l()) << " */\n"; Machine_X86::regName(id->longId().l()) << " */\n";
o << id->name; o << id->name;
pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name); pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name);
} }
else /* GLB_FRAME */ else /* GLB_FRAME */
{ {
if (id->id.longGlb.regi == 0) /* not indexed */ if (id->id.longGlb.regi == 0) /* not indexed */
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]"; o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]";
else if (id->id.longGlb.regi == rBX) else if (id->id.longGlb.regi == rBX)
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]"; o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]";
} else {
break; qCritical() << "AstIdent::walkCondExpr unhandled LONG_VAR in GLB_FRAME";
case OTHER: assert(false);
off = ident.idNode.other.off; }
o << Machine_X86::regName(ident.idNode.other.seg)<< "["; }
o << Machine_X86::regName(ident.idNode.other.regi); break;
if (off < 0) case OTHER:
o << "-"<< hexStr (-off); off = ident.idNode.other.off;
else if (off>0) o << Machine_X86::regName(ident.idNode.other.seg)<< "[";
o << "+"<< hexStr (off); o << Machine_X86::regName(ident.idNode.other.regi);
o << "]"; if (off < 0)
break; o << "-"<< hexStr (-off);
default: else if (off>0)
assert(false); o << "+"<< hexStr (off);
return ""; o << "]";
break;
default:
assert(false);
return "";
} /* eos */ } /* eos */
@ -632,33 +636,33 @@ QString UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const
QString outStr; QString outStr;
switch(m_type) switch(m_type)
{ {
case NEGATION: case NEGATION:
outStr+=wrapUnary(pProc,numLoc,'!'); outStr+=wrapUnary(pProc,numLoc,'!');
break; break;
case ADDRESSOF: case ADDRESSOF:
outStr+=wrapUnary(pProc,numLoc,'&'); outStr+=wrapUnary(pProc,numLoc,'&');
break; break;
case DEREFERENCE: case DEREFERENCE:
outStr+=wrapUnary(pProc,numLoc,'*'); outStr+=wrapUnary(pProc,numLoc,'*');
break; break;
case POST_INC: case POST_INC:
outStr += unaryExp->walkCondExpr (pProc, numLoc) + "++"; outStr += unaryExp->walkCondExpr (pProc, numLoc) + "++";
break; break;
case POST_DEC: case POST_DEC:
outStr += unaryExp->walkCondExpr (pProc, numLoc) + "--"; outStr += unaryExp->walkCondExpr (pProc, numLoc) + "--";
break; break;
case PRE_INC: case PRE_INC:
outStr += "++" + unaryExp->walkCondExpr (pProc, numLoc); outStr += "++" + unaryExp->walkCondExpr (pProc, numLoc);
break; break;
case PRE_DEC: case PRE_DEC:
outStr += "--" + unaryExp->walkCondExpr (pProc, numLoc); outStr += "--" + unaryExp->walkCondExpr (pProc, numLoc);
break; break;
} }
return outStr; return outStr;
} }
@ -666,9 +670,6 @@ QString UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const
/* Walks the conditional expression tree and returns the result on a string */ /* Walks the conditional expression tree and returns the result on a string */
/* Changes the boolean conditional operator at the root of this expression */ /* Changes the boolean conditional operator at the root of this expression */
void BinaryOperator::changeBoolOp (condOp newOp) void BinaryOperator::changeBoolOp (condOp newOp)
{ {
@ -707,18 +708,18 @@ Expr *UnaryOperator::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *lo
Expr *temp; Expr *temp;
switch (m_type) { switch (m_type) {
case NEGATION: case NEGATION:
case ADDRESSOF: case ADDRESSOF:
case DEREFERENCE: case DEREFERENCE:
temp = unaryExp->insertSubTreeReg( _expr, regi, locsym); temp = unaryExp->insertSubTreeReg( _expr, regi, locsym);
if (nullptr!=temp) if (nullptr!=temp)
{ {
unaryExp = temp; unaryExp = temp;
return this; return this;
} }
return nullptr; return nullptr;
default: default:
fprintf(stderr,"insertSubTreeReg attempt on unhandled type %d\n",m_type); fprintf(stderr,"insertSubTreeReg attempt on unhandled type %d\n",m_type);
} }
return nullptr; return nullptr;
} }
@ -799,9 +800,8 @@ Expr *BinaryOperator::insertSubTreeLongReg(Expr *_expr, int longIdx)
Expr *AstIdent::insertSubTreeLongReg(Expr *_expr, int longIdx) Expr *AstIdent::insertSubTreeLongReg(Expr *_expr, int longIdx)
{ {
if (ident.idNode.longIdx == longIdx) if (ident.idNode.longIdx == longIdx)
{
return _expr; return _expr;
}
return nullptr; return nullptr;
} }
@ -817,29 +817,29 @@ Expr *BinaryOperator::clone() const
Expr *BinaryOperator::inverse() const Expr *BinaryOperator::inverse() const
{ {
static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL, constexpr static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY, LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY,
DUMMY, DBL_OR, DBL_AND}; DUMMY, DBL_OR, DBL_AND};
BinaryOperator *res=reinterpret_cast<BinaryOperator *>(this->clone()); BinaryOperator *res=reinterpret_cast<BinaryOperator *>(this->clone());
switch (m_op) switch (m_op)
{ {
case LESS_EQUAL: case LESS: case EQUAL: case LESS_EQUAL: case LESS: case EQUAL:
case NOT_EQUAL: case GREATER: case GREATER_EQUAL: case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
res->m_op = invCondOp[m_op]; res->m_op = invCondOp[m_op];
return res; return res;
case AND: case OR: case XOR: case NOT: case ADD: case AND: case OR: case XOR: case NOT: case ADD:
case SUB: case MUL: case DIV: case SHR: case SHL: case MOD: case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
return UnaryOperator::Create(NEGATION, res); return UnaryOperator::Create(NEGATION, res);
case DBL_AND: case DBL_OR: case DBL_AND: case DBL_OR:
res->m_op = invCondOp[m_op]; res->m_op = invCondOp[m_op];
res->m_lhs=m_lhs->inverse (); res->m_lhs=m_lhs->inverse ();
res->m_rhs=m_rhs->inverse (); res->m_rhs=m_rhs->inverse ();
return res; return res;
default: default:
fprintf(stderr,"BinaryOperator::inverse attempt on unhandled op %d\n",m_op); fprintf(stderr,"BinaryOperator::inverse attempt on unhandled op %d\n",m_op);
} /* eos */ } /* eos */
assert(false); assert(false);
return res; return res;
@ -849,35 +849,19 @@ Expr *AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId)
{ {
eReg otherRegi; /* high or low part of long register */ eReg otherRegi; /* high or low part of long register */
if (ident.idType == LONG_VAR) if (ident.idType != LONG_VAR)
{ return this;
otherRegi = otherLongRegi (regi, ident.idNode.longIdx, locId); otherRegi = locId->getPairedRegisterAt(ident.idNode.longIdx,regi);
delete this; bool long_was_signed = locId->id_arr[ident.idNode.longIdx].isSigned();
return new RegisterNode(locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi),WORD_REG,locId); delete this;
} return new RegisterNode(locId->newByteWordReg(long_was_signed ? TYPE_WORD_SIGN : TYPE_WORD_UNSIGN,otherRegi),WORD_REG,locId);
return this;
} }
eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
{
ID *id = &locTbl->id_arr[idx];
if ((id->loc == REG_FRAME) and ((id->type == TYPE_LONG_SIGN) or
(id->type == TYPE_LONG_UNSIGN)))
{
if (id->longId().h() == regi)
return (id->longId().l());
else if (id->longId().l() == regi)
return (id->longId().h());
}
return rUNDEF; // Cristina: please check this!
}
QString Constant::walkCondExpr(Function *, int *) const QString Constant::walkCondExpr(Function *, int *) const
{ {
if (kte.kte < 1000) if (kte.kte < 1000)
return QString::number(kte.kte); return QString::number(kte.kte);
else return "0x" + QString::number(kte.kte,16);
return "0x" + QString::number(kte.kte,16);
} }
int Constant::hlTypeSize(Function *) const int Constant::hlTypeSize(Function *) const
@ -885,11 +869,6 @@ int Constant::hlTypeSize(Function *) const
return kte.size; return kte.size;
} }
hlType Constant::expType(Function *pproc) const
{
return TYPE_CONST;
}
QString FuncNode::walkCondExpr(Function *pProc, int *numLoc) const QString FuncNode::walkCondExpr(Function *pProc, int *numLoc) const
{ {
return pProc->writeCall(call.proc,*call.args, numLoc); return pProc->writeCall(call.proc,*call.args, numLoc);

View File

@ -158,9 +158,9 @@ void Project::writeGlobSymTable()
else { /* first defined */ else { /* first defined */
switch (sym.size) { switch (sym.size) {
case 1: ostr<<"uint8_t\t"; break; case 1: ostr<<"uint8_t\t"; break;
case 2: ostr<<"int\t"; break; case 2: ostr<<"int16_t\t"; break;
case 4: if (sym.type == TYPE_PTR) case 4: if (sym.type == TYPE_PTR)
ostr<<"int\t*"; ostr<<"int32_t\t*";
else else
ostr<<"char\t*"; ostr<<"char\t*";
break; break;

View File

@ -477,7 +477,7 @@ bool LibCheck(Function & pProc)
if ((numFunc == 0) or (i=searchPList(ht[h].htSym)) != NIL) if ((numFunc == 0) or (i=searchPList(ht[h].htSym)) != NIL)
{ {
pProc.flg |= PROC_ISLIB; /* It's a lib function */ pProc.flg |= PROC_ISLIB; /* It's a lib function */
pProc.callingConv(CConv::C); pProc.callingConv(CConv::eCdecl);
if (i != NIL) if (i != NIL)
{ {
/* Allocate space for the arg struct, and copy the hlType to /* Allocate space for the arg struct, and copy the hlType to
@ -534,7 +534,7 @@ bool LibCheck(Function & pProc)
pProc.args.numArgs = 0; /* With no args */ pProc.args.numArgs = 0; /* With no args */
} }
return (bool)((pProc.flg & PROC_ISLIB) != 0); return pProc.isLibrary();
} }
@ -548,8 +548,7 @@ void grab(int n, FILE *_file)
} }
} }
uint16_t uint16_t readFileShort(FILE *f)
readFileShort(FILE *f)
{ {
uint8_t b1, b2; uint8_t b1, b2;

View File

@ -7,27 +7,29 @@
#include "msvc_fixes.h" #include "msvc_fixes.h"
#include <boost/range/algorithm.hpp> #include <boost/range/algorithm.hpp>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <algorithm> #include <algorithm>
#include <list> #include <list>
#include <cassert>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
namespace {
typedef std::list<int> nodeList; /* dfsLast index to the node */ typedef std::list<int> nodeList; /* dfsLast index to the node */
#define ancestor(a,b) ((a->dfsLastNum < b->dfsLastNum) and (a->dfsFirstNum < b->dfsFirstNum))
/* there is a path on the DFST from a to b if the a was first visited in a /* there is a path on the DFST from a to b if the a was first visited in a
* dfs, and a was later visited than b when doing the last visit of each * dfs, and a was later visited than b when doing the last visit of each
* node. */ * node. */
bool inline ancestor(BB *a,BB *b)
{
return (a->dfsLastNum < b->dfsLastNum) and (a->dfsFirstNum < b->dfsFirstNum);
}
/* Checks if the edge (p,s) is a back edge. If node s was visited first /** Checks if the edge (p,s) is a back edge. If node s was visited first
* during the dfs traversal (ie. s has a smaller dfsFirst number) or s == p, * during the dfs traversal (ie. s has a smaller dfsFirst number) or s == p,
* then it is a backedge. * then it is a backedge.
* Also incrementes the number of backedges entries to the header node. */ * Also incrementes the number of backedges entries to the header node. */
static bool isBackEdge (BB * p,BB * s) bool isBackEdge (BB * p,BB * s)
{ {
if (p->dfsFirstNum >= s->dfsFirstNum) if (p->dfsFirstNum >= s->dfsFirstNum)
{ {
@ -38,9 +40,9 @@ static bool isBackEdge (BB * p,BB * s)
} }
/* Finds the common dominator of the current immediate dominator /** Finds the common dominator of the current immediate dominator
* currImmDom and its predecessor's immediate dominator predImmDom */ * currImmDom and its predecessor's immediate dominator predImmDom */
static int commonDom (int currImmDom, int predImmDom, Function * pProc) int commonDom (int currImmDom, int predImmDom, Function * pProc)
{ {
if (currImmDom == NO_DOM) if (currImmDom == NO_DOM)
return (predImmDom); return (predImmDom);
@ -57,67 +59,44 @@ static int commonDom (int currImmDom, int predImmDom, Function * pProc)
} }
return (currImmDom); return (currImmDom);
} }
/* Finds the immediate dominator of each node in the graph pProc->cfg.
* Adapted version of the dominators algorithm by Hecht and Ullman; finds
* immediate dominators only.
* Note: graph should be reducible */
void Function::findImmedDom ()
{
BB * currNode;
for (size_t currIdx = 0; currIdx < numBBs; currIdx++)
{
currNode = m_dfsLast[currIdx];
if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */
continue;
for (BB * inedge : currNode->inEdges)
{
size_t predIdx = inedge->dfsLastNum;
if (predIdx < currIdx)
currNode->immedDom = commonDom (currNode->immedDom, predIdx, this);
}
}
}
/* Inserts the node n to the list l. */
static void insertList (nodeList &l, int n)
{
l.push_back(n);
}
/* Returns whether or not the node n (dfsLast numbering of a basic block) /* Returns whether or not the node n (dfsLast numbering of a basic block)
* is on the list l. */ * is on the list l. */
static bool inList (const nodeList &l, int n) bool inList (const nodeList &l, int n)
{ {
return std::find(l.begin(),l.end(),n)!=l.end(); return std::find(l.begin(),l.end(),n)!=l.end();
} }
/* Frees space allocated by the list l. */
static void freeList (nodeList &l)
{
l.clear();
}
/* Returns whether the node n belongs to the queue list q. */ /* Returns whether the node n belongs to the queue list q. */
static bool inInt(BB * n, queue &q) bool inInt(BB * n, queue &q)
{ {
return std::find(q.begin(),q.end(),n)!=q.end(); return std::find(q.begin(),q.end(),n)!=q.end();
} }
/** Recursive procedure to find nodes that belong to the interval (ie. nodes
* from G1). */
void findNodesInInt (queue &intNodes, int level, interval *Ii)
{
if (level == 1)
{
for(BB *en : Ii->nodes)
{
appendQueue(intNodes,en);
}
}
else
{
for(BB *en : Ii->nodes)
{
findNodesInInt(intNodes,level-1,en->correspInt);
}
}
}
/* Finds the follow of the endless loop headed at node head (if any). /* Finds the follow of the endless loop headed at node head (if any).
* The follow node is the closest node to the loop. */ * The follow node is the closest node to the loop. */
static void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head) void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head)
{ {
head->loopFollow = MAX; head->loopFollow = MAX;
for( int loop_node : loopNodes) for( int loop_node : loopNodes)
{ {
for (TYPEADR_TYPE &typeaddr: pProc->m_dfsLast[loop_node]->edges) for (const TYPEADR_TYPE &typeaddr: pProc->m_dfsLast[loop_node]->edges)
{ {
int succ = typeaddr.BBptr->dfsLastNum; int succ = typeaddr.BBptr->dfsLastNum;
if ((not inList(loopNodes, succ)) and (succ < head->loopFollow)) if ((not inList(loopNodes, succ)) and (succ < head->loopFollow))
@ -130,7 +109,7 @@ static void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head)
//static void findNodesInLoop(BB * latchNode,BB * head,PPROC pProc,queue *intNodes) //static void findNodesInLoop(BB * latchNode,BB * head,PPROC pProc,queue *intNodes)
/* Flags nodes that belong to the loop determined by (latchNode, head) and /* Flags nodes that belong to the loop determined by (latchNode, head) and
* determines the type of loop. */ * determines the type of loop. */
static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &intNodes) void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &intNodes)
{ {
int i, headDfsNum, intNodeType; int i, headDfsNum, intNodeType;
nodeList loopNodes; nodeList loopNodes;
@ -141,7 +120,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
/* Flag nodes in loop headed by head (except header node) */ /* Flag nodes in loop headed by head (except header node) */
headDfsNum = head->dfsLastNum; headDfsNum = head->dfsLastNum;
head->loopHead = headDfsNum; head->loopHead = headDfsNum;
insertList (loopNodes, headDfsNum); loopNodes.push_back(headDfsNum);
for (i = headDfsNum + 1; i < latchNode->dfsLastNum; i++) for (i = headDfsNum + 1; i < latchNode->dfsLastNum; i++)
{ {
if (pProc->m_dfsLast[i]->flg & INVALID_BB) /* skip invalid BBs */ if (pProc->m_dfsLast[i]->flg & INVALID_BB) /* skip invalid BBs */
@ -150,14 +129,14 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
immedDom = pProc->m_dfsLast[i]->immedDom; immedDom = pProc->m_dfsLast[i]->immedDom;
if (inList (loopNodes, immedDom) and inInt(pProc->m_dfsLast[i], intNodes)) if (inList (loopNodes, immedDom) and inInt(pProc->m_dfsLast[i], intNodes))
{ {
insertList (loopNodes, i); loopNodes.push_back(i);
if (pProc->m_dfsLast[i]->loopHead == NO_NODE)/*not in other loop*/ if (pProc->m_dfsLast[i]->loopHead == NO_NODE)/*not in other loop*/
pProc->m_dfsLast[i]->loopHead = headDfsNum; pProc->m_dfsLast[i]->loopHead = headDfsNum;
} }
} }
latchNode->loopHead = headDfsNum; latchNode->loopHead = headDfsNum;
if (latchNode != head) if (latchNode != head)
insertList (loopNodes, latchNode->dfsLastNum); loopNodes.push_back(latchNode->dfsLastNum);
/* Determine type of loop and follow node */ /* Determine type of loop and follow node */
intNodeType = head->nodeType; intNodeType = head->nodeType;
@ -218,7 +197,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
} }
/* Check if couldn't find it, then it is a strangely formed /* Check if couldn't find it, then it is a strangely formed
* loop, so it is safer to consider it an endless loop */ * loop, so it is safer to consider it an endless loop */
if (pbb->dfsLastNum <= head->dfsLastNum) if (pbb->dfsLastNum <= head->dfsLastNum)
{ {
head->loopType = eNodeHeaderType::ENDLESS_TYPE; head->loopType = eNodeHeaderType::ENDLESS_TYPE;
@ -237,32 +216,79 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
findEndlessFollow (pProc, loopNodes, head); findEndlessFollow (pProc, loopNodes, head);
} }
freeList(loopNodes); loopNodes.clear();
} }
/** \returns whether the BB indexed by s is a successor of the BB indexed by \arg h
//static void findNodesInInt (queue **intNodes, int level, interval *Ii) * \note that h is a case node.
/* Recursive procedure to find nodes that belong to the interval (ie. nodes */
* from G1). */ bool successor (int s, int h, Function * pProc)
static void findNodesInInt (queue &intNodes, int level, interval *Ii)
{ {
if (level == 1) BB * header = pProc->m_dfsLast[h];
auto iter = std::find_if(header->edges.begin(),
header->edges.end(),
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
return iter!=header->edges.end();
}
/** Recursive procedure to tag nodes that belong to the case described by
* the list l, head and tail (dfsLast index to first and exit node of the
* case). */
void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
{
int current; /* index to current node */
pBB->traversed = DFS_CASE;
current = pBB->dfsLastNum;
if ((current != tail) and (pBB->nodeType != MULTI_BRANCH) and (inList (l, pBB->immedDom)))
{ {
for(BB *en : Ii->nodes) l.push_back(current);
pBB->caseHead = head;
for(TYPEADR_TYPE &edge : pBB->edges)
{ {
appendQueue(intNodes,en); if (edge.BBptr->traversed != DFS_CASE)
tagNodesInCase (edge.BBptr, l, head, tail);
} }
} }
else }
/** Flags all nodes in the list l as having follow node f, and deletes all
* nodes from the list. */
void flagNodes (nodeList &l, int f, Function * pProc)
{
for(int idx : l)
{ {
for(BB *en : Ii->nodes) pProc->m_dfsLast[idx]->ifFollow = f;
}
l.clear();
}
} // end of anonymouse namespace
/** Finds the immediate dominator of each node in the graph pProc->cfg.
* Adapted version of the dominators algorithm by Hecht and Ullman; finds
* immediate dominators only.
* Note: graph should be reducible */
void Function::findImmedDom ()
{
BB * currNode;
for (size_t currIdx = 0; currIdx < numBBs; currIdx++)
{
currNode = m_dfsLast[currIdx];
if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */
continue;
for (BB * inedge : currNode->inEdges)
{ {
findNodesInInt(intNodes,level-1,en->correspInt); size_t predIdx = inedge->dfsLastNum;
if (predIdx < currIdx)
currNode->immedDom = commonDom (currNode->immedDom, predIdx, this);
} }
} }
} }
/* Algorithm for structuring loops */ /** Algorithm for structuring loops */
void Function::structLoops(derSeq *derivedG) void Function::structLoops(derSeq *derivedG)
{ {
interval *Ii; interval *Ii;
@ -278,8 +304,7 @@ void Function::structLoops(derSeq *derivedG)
for(auto & elem : *derivedG) for(auto & elem : *derivedG)
{ {
level++; level++;
Ii = elem.Ii; for (Ii = elem.Ii; Ii!=nullptr; Ii = Ii->next) /* for all intervals Ii of Gi */
while (Ii) /* for all intervals Ii of Gi */
{ {
latchNode = nullptr; latchNode = nullptr;
intNodes.clear(); intNodes.clear();
@ -321,45 +346,6 @@ void Function::structLoops(derSeq *derivedG)
latchNode->flg |= IS_LATCH_NODE; latchNode->flg |= IS_LATCH_NODE;
} }
} }
/* Next interval */
Ii = Ii->next;
}
/* Next derived sequence */
}
}
/* Returns whether the BB indexed by s is a successor of the BB indexed by
* h. Note that h is a case node. */
static bool successor (int s, int h, Function * pProc)
{
BB * header = pProc->m_dfsLast[h];
auto iter = std::find_if(header->edges.begin(),
header->edges.end(),
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
return iter!=header->edges.end();
}
/* Recursive procedure to tag nodes that belong to the case described by
* the list l, head and tail (dfsLast index to first and exit node of the
* case). */
static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
{
int current; /* index to current node */
pBB->traversed = DFS_CASE;
current = pBB->dfsLastNum;
if ((current != tail) and (pBB->nodeType != MULTI_BRANCH) and (inList (l, pBB->immedDom)))
{
insertList (l, current);
pBB->caseHead = head;
for(TYPEADR_TYPE &edge : pBB->edges)
{
if (edge.BBptr->traversed != DFS_CASE)
tagNodesInCase (edge.BBptr, l, head, tail);
} }
} }
} }
@ -387,9 +373,7 @@ void Function::structCases()
if ((not successor(j, i, this)) and (m_dfsLast[j]->immedDom == i)) if ((not successor(j, i, this)) and (m_dfsLast[j]->immedDom == i))
{ {
if (exitNode == NO_NODE) if (exitNode == NO_NODE)
{
exitNode = j; exitNode = j;
}
else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size()) else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size())
exitNode = j; exitNode = j;
} }
@ -398,7 +382,7 @@ void Function::structCases()
/* Tag nodes that belong to the case by recording the /* Tag nodes that belong to the case by recording the
* header field with caseHeader. */ * header field with caseHeader. */
insertList (caseNodes, i); caseNodes.push_back(i);
m_dfsLast[i]->caseHead = i; m_dfsLast[i]->caseHead = i;
for(TYPEADR_TYPE &pb : caseHeader->edges) for(TYPEADR_TYPE &pb : caseHeader->edges)
{ {
@ -411,20 +395,6 @@ void Function::structCases()
} }
} }
/* Flags all nodes in the list l as having follow node f, and deletes all
* nodes from the list. */
static void flagNodes (nodeList &l, int f, Function * pProc)
{
nodeList::iterator p;
for(int idx : l)
{
pProc->m_dfsLast[idx]->ifFollow = f;
}
l.clear();
}
/* Structures if statements */ /* Structures if statements */
void Function::structIfs () void Function::structIfs ()
{ {
@ -436,7 +406,7 @@ void Function::structIfs ()
unresolved /* List of unresolved if nodes */ unresolved /* List of unresolved if nodes */
; ;
BB * currNode, /* Pointer to current node */ BB * currNode, /* Pointer to current node */
* pbb; * pbb;
/* Linear scan of nodes in reverse dfsLast order */ /* Linear scan of nodes in reverse dfsLast order */
for (curr = numBBs - 1; curr >= 0; curr--) for (curr = numBBs - 1; curr >= 0; curr--)
@ -455,7 +425,7 @@ void Function::structIfs ()
{ {
if (m_dfsLast[desc]->immedDom == curr) if (m_dfsLast[desc]->immedDom == curr)
{ {
insertList (domDesc, desc); domDesc.push_back(desc);
pbb = m_dfsLast[desc]; pbb = m_dfsLast[desc];
if ((pbb->inEdges.size() - pbb->numBackEdges) >= followInEdges) if ((pbb->inEdges.size() - pbb->numBackEdges) >= followInEdges)
{ {
@ -474,9 +444,9 @@ void Function::structIfs ()
flagNodes (unresolved, follow, this); flagNodes (unresolved, follow, this);
} }
else else
insertList (unresolved, curr); unresolved.push_back(curr);
} }
freeList (domDesc); domDesc.clear();
} }
} }
bool Function::removeInEdge_Flag_and_ProcessLatch(BB *pbb,BB *a,BB *b) bool Function::removeInEdge_Flag_and_ProcessLatch(BB *pbb,BB *a,BB *b)
@ -653,8 +623,7 @@ void Function::compoundCond()
} }
} }
/** Structuring algorithm to find the structures of the graph pProc->cfg */
/* Structuring algorithm to find the structures of the graph pProc->cfg */
void Function::structure(derSeq *derivedG) void Function::structure(derSeq *derivedG)
{ {
/* Find immediate dominators of the graph */ /* Find immediate dominators of the graph */

View File

@ -22,6 +22,9 @@
using namespace boost; using namespace boost;
using namespace boost::adaptors; using namespace boost::adaptors;
using namespace std;
namespace
{
struct ExpStack struct ExpStack
{ {
Function *func; Function *func;
@ -49,6 +52,57 @@ struct ExpStack
} }
}; };
ExpStack g_exp_stk;
/** Returns a string with the source operand of Icode */
Expr *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
{
const LLOperand * src_op = ll_insn.get(SRC);
if (src_op->isImmediate()) /* immediate operand ll_insn.testFlags(I)*/
{
//if (ll_insn.testFlags(B))
return new Constant(src_op->getImm2(), src_op->byteWidth());
}
// otherwise
return AstIdent::id (ll_insn, SRC, pProc, i, duIcode, du);
}
/** Returns the destination operand */
Expr *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
{
Expr *n;
n = AstIdent::id (ll_insn, DST, pProc, i, duIcode, du);
/** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/
return (n);
}
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the expression exp given */
void forwardSubsLong (int longIdx, Expr *_exp, ICODE &picode, ICODE &ticode, int *numHlIcodes)
{
bool res;
if (_exp == nullptr) /* In case expression popped is NULL */
return;
/* Insert on rhs of ticode, if possible */
res = Expr::insertSubTreeLongReg (_exp, ticode.hlU()->asgn.m_rhs, longIdx);
if (res)
{
picode.invalidate();
(*numHlIcodes)--;
}
else
{
/* Try to insert it on lhs of ticode*/
res = Expr::insertSubTreeLongReg (_exp, ticode.hlU()->asgn.m_lhs, longIdx);
if (res)
{
picode.invalidate();
(*numHlIcodes)--;
}
}
}
} // end of anonymous namespace
/*************************************************************************** /***************************************************************************
* Expression stack functions * Expression stack functions
**************************************************************************/ **************************************************************************/
@ -92,8 +146,6 @@ bool ExpStack::empty()
return expStk.empty(); return expStk.empty();
} }
using namespace std;
ExpStack g_exp_stk;
/* Returns the index of the local variable or parameter at offset off, if it /* Returns the index of the local variable or parameter at offset off, if it
* is in the stack frame provided. */ * is in the stack frame provided. */
@ -104,28 +156,6 @@ size_t STKFRAME::getLocVar(int off)
} }
/* Returns a string with the source operand of Icode */
static Expr *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
{
const LLOperand * src_op = ll_insn.get(SRC);
if (src_op->isImmediate()) /* immediate operand ll_insn.testFlags(I)*/
{
//if (ll_insn.testFlags(B))
return new Constant(src_op->getImm2(), src_op->byteWidth());
}
// otherwise
return AstIdent::id (ll_insn, SRC, pProc, i, duIcode, du);
}
/* Returns the destination operand */
static Expr *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
{
Expr *n;
n = AstIdent::id (ll_insn, DST, pProc, i, duIcode, du);
/** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/
return (n);
}
/* Eliminates all condition codes and generates new hlIcode instructions */ /* Eliminates all condition codes and generates new hlIcode instructions */
void Function::elimCondCodes () void Function::elimCondCodes ()
{ {
@ -563,7 +593,7 @@ void Function::genDU1 ()
} }
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs of picode. */ /* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs of picode. */
void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, ICODE &picode, ICODE &ticode, int &numHlIcodes) const
{ {
bool res; bool res;
UnaryOperator *lhs_unary; UnaryOperator *lhs_unary;
@ -579,16 +609,16 @@ void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode,
return; return;
/* Insert on rhs of ticode, if possible */ /* Insert on rhs of ticode, if possible */
res = Expr::insertSubTreeReg (ticode->hlU()->asgn.rhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this); res = Expr::insertSubTreeReg (ticode.hlU()->asgn.m_rhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
if (res) if (res)
{ {
picode->invalidate(); picode.invalidate();
numHlIcodes--; numHlIcodes--;
} }
else else
{ {
/* Try to insert it on lhs of ticode*/ /* Try to insert it on lhs of ticode*/
RegisterNode *op = dynamic_cast<RegisterNode *>(ticode->hlU()->asgn.m_lhs); RegisterNode *op = dynamic_cast<RegisterNode *>(ticode.hlU()->asgn.m_lhs);
if(op) if(op)
{ {
eReg inserted = id_arr[lhs_reg->regiIdx].id.regi; eReg inserted = id_arr[lhs_reg->regiIdx].id.regi;
@ -599,44 +629,17 @@ void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode,
return; return;
} }
} }
res = Expr::insertSubTreeReg (ticode->hlU()->asgn.m_lhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this); res = Expr::insertSubTreeReg (ticode.hlU()->asgn.m_lhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
if (res) if (res)
{ {
picode->invalidate(); picode.invalidate();
numHlIcodes--; numHlIcodes--;
} }
} }
} }
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the expression exp given */ /** Returns whether the elements of the expression rhs are all x-clear from
static void forwardSubsLong (int longIdx, Expr *_exp, iICODE picode, iICODE ticode, int *numHlIcodes)
{
bool res;
if (_exp == nullptr) /* In case expression popped is NULL */
return;
/* Insert on rhs of ticode, if possible */
res = Expr::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.rhs, longIdx);
if (res)
{
picode->invalidate();
(*numHlIcodes)--;
}
else
{
/* Try to insert it on lhs of ticode*/
res = Expr::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.m_lhs, longIdx);
if (res)
{
picode->invalidate();
(*numHlIcodes)--;
}
}
}
/* Returns whether the elements of the expression rhs are all x-clear from
* instruction f up to instruction t. */ * instruction f up to instruction t. */
bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs) bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs)
{ {
@ -679,7 +682,7 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE
return; */ return; */
assert(pProc==g_exp_stk.func); assert(pProc==g_exp_stk.func);
_exp = g_exp_stk.pop(); _exp = g_exp_stk.pop();
if (callee->flg & PROC_ISLIB) /* library function */ if (callee->isLibrary() ) /* library function */
{ {
if (callee->args.numArgs > 0) if (callee->args.numArgs > 0)
{ {
@ -732,7 +735,7 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE
callee->args.adjustForArgType (numArgs, _exp->expType (pProc)); callee->args.adjustForArgType (numArgs, _exp->expType (pProc));
} }
} }
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc); res = picode->newStkArg (_exp, picode->ll()->getOpcode(), pProc);
/* Do not update the size of k if the expression was a segment register /* Do not update the size of k if the expression was a segment register
* in a near call */ * in a near call */
if (res == false) if (res == false)
@ -747,11 +750,11 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE
/** Eliminates extraneous intermediate icode instructions when finding /** Eliminates extraneous intermediate icode instructions when finding
* expressions. Generates new hlIcodes in the form of expression trees. * expressions. Generates new hlIcodes in the form of expression trees.
* For HLI_CALL hlIcodes, places the arguments in the argument list. */ * For HLI_CALL hlIcodes, places the arguments in the argument list. */
void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) const void LOCAL_ID::processTargetIcode(ICODE &picode, int &numHlIcodes, ICODE &ticode,bool isLong) const
{ {
bool res; bool res;
HLTYPE &p_hl(*picode->hlU()); HLTYPE &p_hl(*picode.hlU());
HLTYPE &t_hl(*ticode->hlU()); HLTYPE &t_hl(*ticode.hlU());
AstIdent *lhs_ident = dynamic_cast<AstIdent *>(p_hl.asgn.lhs()); AstIdent *lhs_ident = dynamic_cast<AstIdent *>(p_hl.asgn.lhs());
switch (t_hl.opcode) switch (t_hl.opcode)
@ -761,11 +764,11 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
if(isLong) if(isLong)
{ {
forwardSubsLong (lhs_ident->ident.idNode.longIdx, forwardSubsLong (lhs_ident->ident.idNode.longIdx,
p_hl.asgn.rhs, picode,ticode, p_hl.asgn.m_rhs, picode,ticode,
&numHlIcodes); &numHlIcodes);
} }
else else
this->forwardSubs (lhs_ident, p_hl.asgn.rhs, picode, ticode, numHlIcodes); this->forwardSubs (lhs_ident, p_hl.asgn.m_rhs, picode, ticode, numHlIcodes);
break; break;
case HLI_JCOND: case HLI_PUSH: case HLI_RET: case HLI_JCOND: case HLI_PUSH: case HLI_RET:
@ -773,7 +776,7 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
{ {
assert(lhs_ident); assert(lhs_ident);
res = Expr::insertSubTreeLongReg ( res = Expr::insertSubTreeLongReg (
p_hl.asgn.rhs, p_hl.asgn.m_rhs,
t_hl.exp.v, t_hl.exp.v,
lhs_ident->ident.idNode.longIdx); lhs_ident->ident.idNode.longIdx);
} }
@ -783,20 +786,20 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
assert(lhs_reg); assert(lhs_reg);
res = Expr::insertSubTreeReg ( res = Expr::insertSubTreeReg (
t_hl.exp.v, t_hl.exp.v,
p_hl.asgn.rhs, p_hl.asgn.m_rhs,
id_arr[lhs_reg->regiIdx].id.regi, id_arr[lhs_reg->regiIdx].id.regi,
this); this);
} }
if (res) if (res)
{ {
picode->invalidate(); picode.invalidate();
numHlIcodes--; numHlIcodes--;
} }
break; break;
case HLI_CALL: /* register arguments */ case HLI_CALL: /* register arguments */
newRegArg ( picode, ticode); newRegArg ( picode, ticode);
picode->invalidate(); picode.invalidate();
numHlIcodes--; numHlIcodes--;
break; break;
default: default:
@ -843,11 +846,11 @@ void Pascal_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE pico
while(k<cb) while(k<cb)
{ {
_exp = g_exp_stk.pop(); _exp = g_exp_stk.pop();
if (pp->flg & PROC_ISLIB) /* library function */ if (pp->isLibrary() ) /* library function */
{ {
if (pp->args.numArgs > 0) if (pp->args.numArgs > 0)
_exp = func->adjustActArgType(_exp, pp->args[numArgs].type); _exp = func->adjustActArgType(_exp, pp->args[numArgs].type);
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), func); res = picode->newStkArg (_exp, picode->ll()->getOpcode(), func);
} }
else /* user function */ else /* user function */
{ {
@ -857,9 +860,10 @@ void Pascal_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE pico
{ {
fprintf(stderr,"Would try to adjustForArgType with null _exp\n"); fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
} }
pp->args.adjustForArgType (numArgs,_exp->expType (func)); else
pp->args.adjustForArgType (numArgs,_exp->expType (func));
} }
res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), func); res = picode->newStkArg (_exp, picode->ll()->getOpcode(), func);
} }
if (res == false) if (res == false)
k += _exp->hlTypeSize (func); k += _exp->hlTypeSize (func);
@ -880,7 +884,6 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
ID *_retVal; // function return value ID *_retVal; // function return value
Expr *_exp; // expression pointer - for HLI_POP and HLI_CALL */ Expr *_exp; // expression pointer - for HLI_POP and HLI_CALL */
//Expr *lhs; // exp ptr for return value of a HLI_CALL */
iICODE ticode; // Target icode */ iICODE ticode; // Target icode */
HLTYPE *ti_hl=nullptr; HLTYPE *ti_hl=nullptr;
uint8_t regi; uint8_t regi;
@ -891,18 +894,18 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++) for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
{ {
ICODE &_ic(*picode); ICODE &_ic(*picode);
HLTYPE &_icHl(*picode->hlU()); HLTYPE &_icHl(*_ic.hlU());
numHlIcodes++; numHlIcodes++;
if (picode->du1.getNumRegsDef() == 1) /* uint8_t/uint16_t regs */ if (_ic.du1.getNumRegsDef() == 1) /* uint8_t/uint16_t regs */
{ {
/* Check for only one use of this register. If this is /* Check for only one use of this register. If this is
* the last definition of the register in this BB, check * the last definition of the register in this BB, check
* that it is not liveOut from this basic block */ * that it is not liveOut from this basic block */
if (picode->du1.numUses(0)==1) if (_ic.du1.numUses(0)==1)
{ {
/* Check that this register is not liveOut, if it /* Check that this register is not liveOut, if it
* is the last definition of the register */ * is the last definition of the register */
regi = picode->du1.regi[0]; regi = _ic.du1.regi[0];
/* Check if we can forward substitute this register */ /* Check if we can forward substitute this register */
switch (_icHl.opcode) switch (_icHl.opcode)
@ -911,16 +914,16 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
/* Replace rhs of current icode into target /* Replace rhs of current icode into target
* icode expression */ * icode expression */
ticode = picode->du1.idx[0].uses.front(); ticode = _ic.du1.idx[0].uses.front();
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
((ticode->hl()->opcode != HLI_CALL) and ((ticode->hl()->opcode != HLI_CALL) and
(ticode->hl()->opcode != HLI_RET))) (ticode->hl()->opcode != HLI_RET)))
continue; continue;
if (_icHl.asgn.rhs->xClear (make_iterator_range(picode.base(),picode->du1.idx[0].uses[0]), if (_icHl.asgn.m_rhs->xClear (make_iterator_range(picode.base(),_ic.du1.idx[0].uses[0]),
end(), locals)) end(), locals))
{ {
locals.processTargetIcode(picode.base(), numHlIcodes, ticode,false); locals.processTargetIcode(_ic, numHlIcodes, *ticode,false);
} }
break; break;
@ -929,9 +932,9 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
// pop X // pop X
// lab1: // lab1:
// call F() <- somehow this is marked as user of POP ? // call F() <- somehow this is marked as user of POP ?
ticode = picode->du1.idx[0].uses.front(); ticode = _ic.du1.idx[0].uses.front();
ti_hl = ticode->hlU(); ti_hl = ticode->hlU();
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
((ti_hl->opcode != HLI_CALL) and ((ti_hl->opcode != HLI_CALL) and
(ti_hl->opcode != HLI_RET))) (ti_hl->opcode != HLI_RET)))
continue; continue;
@ -939,7 +942,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
_exp = g_exp_stk.pop(); /* pop last exp pushed */ _exp = g_exp_stk.pop(); /* pop last exp pushed */
switch (ticode->hl()->opcode) { switch (ticode->hl()->opcode) {
case HLI_ASSIGN: case HLI_ASSIGN:
locals.forwardSubs(_icHl.expr(), _exp, picode.base(), ticode, numHlIcodes); locals.forwardSubs(_icHl.expr(), _exp, _ic, *ticode, numHlIcodes);
break; break;
case HLI_JCOND: case HLI_PUSH: case HLI_RET: case HLI_JCOND: case HLI_PUSH: case HLI_RET:
@ -952,7 +955,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
&locals); &locals);
if (res) if (res)
{ {
picode->invalidate(); _ic.invalidate();
numHlIcodes--; numHlIcodes--;
} }
} }
@ -970,25 +973,25 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
break; break;
case HLI_CALL: case HLI_CALL:
ticode = picode->du1.idx[0].uses.front(); ticode = _ic.du1.idx[0].uses.front();
ti_hl = ticode->hlU(); ti_hl = ticode->hlU();
_retVal = &_icHl.call.proc->retVal; _retVal = &_icHl.call.proc->retVal;
switch (ti_hl->opcode) switch (ti_hl->opcode)
{ {
case HLI_ASSIGN: case HLI_ASSIGN:
assert(ti_hl->asgn.rhs); assert(ti_hl->asgn.m_rhs);
_exp = _icHl.call.toAst(); _exp = _icHl.call.toAst();
res = Expr::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals); res = Expr::insertSubTreeReg (ti_hl->asgn.m_rhs,_exp, _retVal->id.regi, &locals);
if (not res) if (not res)
Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals); Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals);
//TODO: HERE missing: 2 regs //TODO: HERE missing: 2 regs
picode->invalidate(); _ic.invalidate();
numHlIcodes--; numHlIcodes--;
break; break;
case HLI_PUSH: case HLI_RET: case HLI_PUSH: case HLI_RET:
ti_hl->expr( _icHl.call.toAst() ); ti_hl->expr( _icHl.call.toAst() );
picode->invalidate(); _ic.invalidate();
numHlIcodes--; numHlIcodes--;
break; break;
@ -997,13 +1000,13 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
res = Expr::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals); res = Expr::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
if (res) /* was substituted */ if (res) /* was substituted */
{ {
picode->invalidate(); _ic.invalidate();
numHlIcodes--; numHlIcodes--;
} }
else /* cannot substitute function */ else /* cannot substitute function */
{ {
auto lhs = AstIdent::idID(_retVal,&locals,picode.base()); auto lhs = AstIdent::idID(_retVal,&locals,picode.base());
picode->setAsgn(lhs, _exp); _ic.setAsgn(lhs, _exp);
} }
break; break;
default: default:
@ -1016,34 +1019,34 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
} }
} }
else if (picode->du1.getNumRegsDef() == 2) /* long regs */ else if (_ic.du1.getNumRegsDef() == 2) /* long regs */
{ {
/* Check for only one use of these registers */ /* Check for only one use of these registers */
if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1)) if ((_ic.du1.numUses(0) == 1) and (_ic.du1.numUses(1) == 1))
{ {
regi = picode->du1.regi[0]; //TODO: verify that regi actually should be assigned this regi = _ic.du1.regi[0]; //TODO: verify that regi actually should be assigned this
switch (_icHl.opcode) switch (_icHl.opcode)
{ {
case HLI_ASSIGN: case HLI_ASSIGN:
/* Replace rhs of current icode into target /* Replace rhs of current icode into target
* icode expression */ * icode expression */
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) if (_ic.du1.idx[0].uses[0] == _ic.du1.idx[1].uses[0])
{ {
ticode = picode->du1.idx[0].uses.front(); ticode = _ic.du1.idx[0].uses.front();
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
((ticode->hl()->opcode != HLI_CALL) and ((ticode->hl()->opcode != HLI_CALL) and
(ticode->hl()->opcode != HLI_RET))) (ticode->hl()->opcode != HLI_RET)))
continue; continue;
locals.processTargetIcode(picode.base(), numHlIcodes, ticode,true); locals.processTargetIcode(_ic, numHlIcodes, *ticode,true);
} }
break; break;
case HLI_POP: case HLI_POP:
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) if (_ic.du1.idx[0].uses[0] == _ic.du1.idx[1].uses[0])
{ {
ticode = picode->du1.idx[0].uses.front(); ticode = _ic.du1.idx[0].uses.front();
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
((ticode->hl()->opcode != HLI_CALL) and ((ticode->hl()->opcode != HLI_CALL) and
(ticode->hl()->opcode != HLI_RET))) (ticode->hl()->opcode != HLI_RET)))
continue; continue;
@ -1052,7 +1055,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
switch (ticode->hl()->opcode) { switch (ticode->hl()->opcode) {
case HLI_ASSIGN: case HLI_ASSIGN:
forwardSubsLong (dynamic_cast<AstIdent *>(_icHl.expr())->ident.idNode.longIdx, forwardSubsLong (dynamic_cast<AstIdent *>(_icHl.expr())->ident.idNode.longIdx,
_exp, picode.base(), ticode, &numHlIcodes); _exp, _ic, *ticode, &numHlIcodes);
break; break;
case HLI_JCOND: case HLI_PUSH: case HLI_JCOND: case HLI_PUSH:
res = Expr::insertSubTreeLongReg (_exp, res = Expr::insertSubTreeLongReg (_exp,
@ -1060,7 +1063,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
dynamic_cast<AstIdent *>(_icHl.asgn.lhs())->ident.idNode.longIdx); dynamic_cast<AstIdent *>(_icHl.asgn.lhs())->ident.idNode.longIdx);
if (res) if (res)
{ {
picode->invalidate(); _ic.invalidate();
numHlIcodes--; numHlIcodes--;
} }
break; break;
@ -1073,7 +1076,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
break; break;
case HLI_CALL: /* check for function return */ case HLI_CALL: /* check for function return */
ticode = picode->du1.idx[0].uses.front(); ticode = _ic.du1.idx[0].uses.front();
switch (ticode->hl()->opcode) switch (ticode->hl()->opcode)
{ {
case HLI_ASSIGN: case HLI_ASSIGN:
@ -1082,33 +1085,33 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
AstIdent::Long(&locals, DST, AstIdent::Long(&locals, DST,
ticode,HIGH_FIRST, picode.base(), ticode,HIGH_FIRST, picode.base(),
eDEF, *(++iICODE(ticode))->ll())); eDEF, *(++iICODE(ticode))->ll()));
ticode->hlU()->asgn.rhs = _exp; ticode->hlU()->asgn.m_rhs = _exp;
picode->invalidate(); _ic.invalidate();
numHlIcodes--; numHlIcodes--;
break; break;
case HLI_PUSH: case HLI_PUSH:
case HLI_RET: case HLI_RET:
ticode->hlU()->expr( _icHl.call.toAst() ); ticode->hlU()->expr( _icHl.call.toAst() );
picode->invalidate(); _ic.invalidate();
numHlIcodes--; numHlIcodes--;
break; break;
case HLI_JCOND: case HLI_JCOND:
_exp = _icHl.call.toAst(); _exp = _icHl.call.toAst();
_retVal = &picode->hl()->call.proc->retVal; _retVal = &_ic.hl()->call.proc->retVal;
res = Expr::insertSubTreeLongReg (_exp, res = Expr::insertSubTreeLongReg (_exp,
ticode->hlU()->exp.v, ticode->hlU()->exp.v,
locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base())); locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base()));
if (res) /* was substituted */ if (res) /* was substituted */
{ {
picode->invalidate(); _ic.invalidate();
numHlIcodes--; numHlIcodes--;
} }
else /* cannot substitute function */ else /* cannot substitute function */
{ {
auto lhs = locals.createId(_retVal,picode.base()); auto lhs = locals.createId(_retVal,picode.base());
picode->setAsgn(lhs, _exp); _ic.setAsgn(lhs, _exp);
} }
break; break;
default: default:
@ -1129,8 +1132,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
{ {
g_exp_stk.processExpPush(numHlIcodes, *picode); g_exp_stk.processExpPush(numHlIcodes, *picode);
} }
else if(picode->du1.getNumRegsDef()!=0) else if(_ic.du1.getNumRegsDef()!=0)
printf("Num def %d\n",picode->du1.getNumRegsDef()); printf("Num def %d\n",_ic.du1.getNumRegsDef());
/* For HLI_CALL instructions that use arguments from the stack, /* For HLI_CALL instructions that use arguments from the stack,
* pop them from the expression stack and place them on the * pop them from the expression stack and place them on the
@ -1144,11 +1147,11 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
/* If we could not substitute the result of a function, /* If we could not substitute the result of a function,
* assign it to the corresponding registers */ * assign it to the corresponding registers */
if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.getNumRegsDef() > 0)) if ( not _icHl.call.proc->isLibrary() and (not _ic.du1.used(0)) and (_ic.du1.getNumRegsDef() > 0))
{ {
_exp = new FuncNode(_icHl.call.proc, _icHl.call.args); _exp = new FuncNode(_icHl.call.proc, _icHl.call.args);
auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base()); auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base());
picode->setAsgn(lhs, _exp); _ic.setAsgn(lhs, _exp);
} }
} }
} }

View File

@ -25,12 +25,11 @@ extern SYMTAB symtab; /* Global symbol table */
extern STATS stats; /* cfg statistics */ extern STATS stats; /* cfg statistics */
extern OPTION option; /* Command line options */ extern OPTION option; /* Command line options */
static char *initargs(int argc, char *argv[]); static void displayTotalStats();
static void displayTotalStats(void);
/**************************************************************************** /****************************************************************************
* main * main
***************************************************************************/ ***************************************************************************/
void setupOptions(QCoreApplication &app) { void setupOptions(const QCoreApplication &app) {
//[-a1a2cmsi] //[-a1a2cmsi]
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription("dcc"); parser.setApplicationDescription("dcc");
@ -80,7 +79,7 @@ void setupOptions(QCoreApplication &app) {
option.Interact = false; option.Interact = false;
option.Calls = parser.isSet(boolOpts[2]); option.Calls = parser.isSet(boolOpts[2]);
option.filename = args.first(); option.filename = args.first();
option.CustomEntryPoint = parser.value(entryPointOption).toUInt(0,16); option.CustomEntryPoint = parser.value(entryPointOption).toUInt(nullptr,16);
if(parser.isSet(targetFileOption)) if(parser.isSet(targetFileOption))
asm1_name = asm2_name = parser.value(targetFileOption); asm1_name = asm2_name = parser.value(targetFileOption);
else if(option.asm1 or option.asm2) { else if(option.asm1 or option.asm2) {

View File

@ -11,36 +11,37 @@
#include "dcc.h" #include "dcc.h"
static std::map<eErrorId,std::string> errorMessage = static const std::map<eErrorId,std::string> errorMessage =
{ {
{INVALID_ARG ,"Invalid option -%c\n"}, {INVALID_ARG ,"Invalid option -%c\n"},
{INVALID_OPCODE ,"Invalid instruction %02X at location %06lX\n"}, {INVALID_OPCODE ,"Invalid instruction %02X at location %06lX\n"},
{INVALID_386OP ,"Don't understand 80386 instruction %02X at location %06lX\n"}, {INVALID_386OP ,"Don't understand 80386 instruction %02X at location %06lX\n"},
{FUNNY_SEGOVR ,"Segment override with no memory operand at location %06lX\n"}, {FUNNY_SEGOVR ,"Segment override with no memory operand at location %06lX\n"},
{FUNNY_REP ,"REP prefix without a string instruction at location %06lX\n"}, {FUNNY_REP ,"REP prefix without a string instruction at location %06lX\n"},
{CANNOT_OPEN ,"Cannot open %s\n"}, {CANNOT_OPEN ,"Cannot open %s\n"},
{CANNOT_READ ,"Error while reading %s\n"}, {CANNOT_READ ,"Error while reading %s\n"},
{MALLOC_FAILED ,"malloc of %ld bytes failed\n"}, {MALLOC_FAILED ,"malloc of %ld bytes failed\n"},
{NEWEXE_FORMAT ,"Don't understand new EXE format\n"}, {NEWEXE_FORMAT ,"Don't understand new EXE format\n"},
{NO_BB ,"Failed to find a BB for jump to %ld in proc %s\n"}, {NO_BB ,"Failed to find a BB for jump to %ld in proc %s\n"},
{INVALID_SYNTHETIC_BB,"Basic Block is a synthetic jump\n"}, {INVALID_SYNTHETIC_BB,"Basic Block is a synthetic jump\n"},
{INVALID_INT_BB ,"Failed to find a BB for interval\n"}, {INVALID_INT_BB ,"Failed to find a BB for interval\n"},
{IP_OUT_OF_RANGE ,"Instruction at location %06lX goes beyond loaded image\n"}, {IP_OUT_OF_RANGE ,"Instruction at location %06lX goes beyond loaded image\n"},
{DEF_NOT_FOUND ,"Definition not found for condition code usage at opcode %d\n"}, {DEF_NOT_FOUND ,"Definition not found for condition code usage at opcode %d\n"},
{JX_NOT_DEF ,"JX use, definition not supported at opcode #%d\n"}, {JX_NOT_DEF ,"JX use, definition not supported at opcode #%d\n"},
{NOT_DEF_USE ,"%x: Def - use not supported. Def op = %d, use op = %d.\n"}, {NOT_DEF_USE ,"%x: Def - use not supported. Def op = %d, use op = %d.\n"},
{REPEAT_FAIL ,"Failed to construct repeat..until() condition.\n"}, {REPEAT_FAIL ,"Failed to construct repeat..until() condition.\n"},
{WHILE_FAIL ,"Failed to construct while() condition.\n"}, {WHILE_FAIL ,"Failed to construct while() condition.\n"},
}; };
/**************************************************************************** /****************************************************************************
fatalError: displays error message and exits the program. fatalError: displays error message and exits the program.
****************************************************************************/ ****************************************************************************/
void fatalError(eErrorId errId, ...) void fatalError(eErrorId errId, ...)
{ va_list args; {
//#ifdef __UNIX__ /* ultrix */ va_list args;
//#ifdef __UNIX__ /* ultrix */
#if 0 #if 0
int errId; int errId;
va_start(args); va_start(args);
errId = va_arg(args, int); errId = va_arg(args, int);
@ -49,10 +50,12 @@ void fatalError(eErrorId errId, ...)
#endif #endif
if (errId == USAGE) if (errId == USAGE)
fprintf(stderr,"Usage: dcc [-a1a2cmpsvVi][-o asmfile] DOS_executable\n"); fprintf(stderr,"Usage: dcc [-a1a2cmpsvVi][-o asmfile] DOS_executable\n");
else { else {
auto msg_iter = errorMessage.find(errId);
assert(msg_iter!=errorMessage.end());
fprintf(stderr, "dcc: "); fprintf(stderr, "dcc: ");
vfprintf(stderr, errorMessage[errId].c_str(), args); vfprintf(stderr, msg_iter->second.c_str(), args);
} }
va_end(args); va_end(args);
exit((int)errId); exit((int)errId);
@ -63,10 +66,11 @@ void fatalError(eErrorId errId, ...)
reportError: reports the warning/error and continues with the program. reportError: reports the warning/error and continues with the program.
****************************************************************************/ ****************************************************************************/
void reportError(eErrorId errId, ...) void reportError(eErrorId errId, ...)
{ va_list args; {
//#ifdef __UNIX__ /* ultrix */ va_list args;
//#ifdef __UNIX__ /* ultrix */
#if 0 #if 0
int errId; int errId;
va_start(args); va_start(args);
errId = va_arg(args, int); errId = va_arg(args, int);
@ -74,6 +78,8 @@ void reportError(eErrorId errId, ...)
va_start(args, errId); va_start(args, errId);
#endif #endif
fprintf(stderr, "dcc: "); fprintf(stderr, "dcc: ");
vfprintf(stderr, errorMessage[errId].c_str(), args); auto msg_iter = errorMessage.find(errId);
assert(msg_iter!=errorMessage.end());
vfprintf(stderr, msg_iter->second.c_str(), args);
va_end(args); va_end(args);
} }

View File

@ -532,7 +532,7 @@ QString AssignType::writeOut(Function *pProc, int *numLoc) const
{ {
return QString("%1 = %2;\n") return QString("%1 = %2;\n")
.arg(m_lhs->walkCondExpr (pProc, numLoc)) .arg(m_lhs->walkCondExpr (pProc, numLoc))
.arg(rhs->walkCondExpr (pProc, numLoc)); .arg(m_rhs->walkCondExpr (pProc, numLoc));
} }
QString CallType::writeOut(Function *pProc, int *numLoc) const QString CallType::writeOut(Function *pProc, int *numLoc) const
{ {
@ -553,7 +553,7 @@ void HLTYPE::set(Expr *l, Expr *r)
//assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks //assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
assert(dynamic_cast<UnaryOperator *>(l)); assert(dynamic_cast<UnaryOperator *>(l));
asgn.m_lhs=l; asgn.m_lhs=l;
asgn.rhs=r; asgn.m_rhs=r;
} }
/* Returns a string with the contents of the current high-level icode. /* Returns a string with the contents of the current high-level icode.
* Note: this routine does not output the contens of HLI_JCOND icodes. This is * Note: this routine does not output the contens of HLI_JCOND icodes. This is

View File

@ -213,12 +213,12 @@ void Function::findIdioms()
/* Check if number of parameter bytes match their calling convention */ /* Check if number of parameter bytes match their calling convention */
if ((flg & PROC_HLL) and (not args.empty())) if ((flg & PROC_HLL) and (not args.empty()))
{ {
args.m_minOff += (flg & PROC_FAR ? 4 : 2); args.m_minOff += ((flg & PROC_FAR)!=0 ? 4 : 2);
delta = args.maxOff - args.m_minOff; delta = args.maxOff - args.m_minOff;
if (cbParam != delta) if (cbParam != delta)
{ {
cbParam = delta; cbParam = delta;
callingConv(CConv::UNKNOWN); callingConv(CConv::eUnknown);
} }
} }
} }

View File

@ -147,13 +147,13 @@ bool Idiom18::match(iICODE picode)
break; break;
case 1: /* register variable */ case 1: /* register variable */
/* Check previous instruction for a MOV */ /* Check previous instruction for a MOV */
if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi)) if ( m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi)
{ {
return true; return true;
} }
break; break;
case 2: /* local */ case 2: /* local */
if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off)) if (m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off)
{ {
return true; return true;
} }

View File

@ -41,7 +41,7 @@ int Idiom3::action()
{ {
if (m_icodes[0]->ll()->testFlags(I) ) if (m_icodes[0]->ll()->testFlags(I) )
{ {
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C); m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::eCdecl);
} }
else else
{ {
@ -99,7 +99,7 @@ int Idiom17::action()
{ {
if (m_icodes[0]->ll()->testFlags(I)) if (m_icodes[0]->ll()->testFlags(I))
{ {
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C); m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::eCdecl);
for(size_t idx=1; idx<m_icodes.size(); ++idx) for(size_t idx=1; idx<m_icodes.size(); ++idx)
{ {
m_icodes[idx]->invalidate(); m_icodes[idx]->invalidate();

View File

@ -148,7 +148,7 @@ int Idiom4::action()
if(m_param_count) if(m_param_count)
{ {
m_func->cbParam = (int16_t)m_param_count; m_func->cbParam = (int16_t)m_param_count;
m_func->callingConv(CConv::PASCAL); m_func->callingConv(CConv::ePascal);
} }
return 1; return 1;
} }

View File

@ -10,6 +10,11 @@
#include "msvc_fixes.h" #include "msvc_fixes.h"
#include <cstring> #include <cstring>
#include <QtCore/QDebug>
static const int LOCAL_ID_DELTA = 25;
static const int IDX_ARRAY_DELTA = 5;
bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
{ {
@ -54,9 +59,14 @@ ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false)
assert((t==TYPE_LONG_SIGN) or (t==TYPE_LONG_UNSIGN)); assert((t==TYPE_LONG_SIGN) or (t==TYPE_LONG_UNSIGN));
} }
eReg ID::getPairedRegister(eReg first) const {
if (longId().h() == first)
return (longId().l());
else if (longId().l() == first)
return (longId().h());
return rUNDEF;
}
#define LOCAL_ID_DELTA 25
#define IDX_ARRAY_DELTA 5
/* Creates a new identifier node of type t and returns it. /* Creates a new identifier node of type t and returns it.
* Arguments: locSym : local long symbol table * Arguments: locSym : local long symbol table
@ -65,8 +75,7 @@ ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false)
* ix : index into icode array where this var is used */ * ix : index into icode array where this var is used */
void LOCAL_ID::newIdent(hlType t, frameType f) void LOCAL_ID::newIdent(hlType t, frameType f)
{ {
ID newid(t,f); id_arr.emplace_back(t,f);
id_arr.push_back(newid);
} }
@ -74,19 +83,16 @@ void LOCAL_ID::newIdent(hlType t, frameType f)
* TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */ * TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */
int LOCAL_ID::newByteWordReg(hlType t, eReg regi) int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
{ {
int idx;
/* Check for entry in the table */ /* Check for entry in the table */
auto found=std::find_if(id_arr.begin(),id_arr.end(),[t,regi](ID &el)->bool { auto found=std::find_if(id_arr.begin(),id_arr.end(),[t,regi](ID &el)->bool {
return ((el.type == t) and (el.id.regi == regi)); return ((el.type == t) and (el.id.regi == regi));
}); });
if(found!=id_arr.end()) if(found!=id_arr.end())
return found-id_arr.begin(); return found-id_arr.begin();
/* Not in table, create new identifier */ /* Not in table, create new identifier */
newIdent (t, REG_FRAME); newIdent (t, REG_FRAME);
idx = id_arr.size() - 1; id_arr.back().id.regi = regi;
id_arr[idx].id.regi = regi; return id_arr.size() - 1;
return (idx);
} }
@ -99,11 +105,8 @@ int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
void LOCAL_ID::flagByteWordId (int off) void LOCAL_ID::flagByteWordId (int off)
{ {
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool { auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool {
//if (((en.type == TYPE_WORD_SIGN) or (en.type == TYPE_BYTE_SIGN)) and //if (((en.type == TYPE_WORD_SIGN) or (en.type == TYPE_BYTE_SIGN)) and
if ((en.typeBitsize()<=16) and return ((en.typeBitsize()<=16) and (en.id.bwId.off == off) and (en.id.bwId.regOff == 0));
(en.id.bwId.off == off) and (en.id.bwId.regOff == 0))
return true;
return false;
}); });
if(found==id_arr.end()) if(found==id_arr.end())
{ {
@ -117,23 +120,21 @@ void LOCAL_ID::flagByteWordId (int off)
* TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */ * TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */
int LOCAL_ID::newByteWordStk(hlType t, int off, uint8_t regOff) int LOCAL_ID::newByteWordStk(hlType t, int off, uint8_t regOff)
{ {
int idx;
/* Check for entry in the table */ /* Check for entry in the table */
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off,regOff](ID &el)->bool { auto found=std::find_if(id_arr.begin(),id_arr.end(),[off,regOff](ID &el)->bool {
if ((el.id.bwId.off == off) and (el.id.bwId.regOff == regOff)) if ((el.id.bwId.off == off) and (el.id.bwId.regOff == regOff))
return true; return true;
return false; return false;
}); });
if(found!=id_arr.end()) if(found!=id_arr.end())
return found-id_arr.begin(); //return Index to found element return found-id_arr.begin(); //return Index to found element
/* Not in table, create new identifier */ /* Not in table, create new identifier */
newIdent (t, STK_FRAME); newIdent (t, STK_FRAME);
idx = id_arr.size() - 1; ID &last_id(id_arr.back());
id_arr[idx].id.bwId.regOff = regOff; last_id.id.bwId.regOff = regOff;
id_arr[idx].id.bwId.off = off; last_id.id.bwId.off = off;
return (idx); return id_arr.size()-1;
} }
@ -152,9 +153,9 @@ int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t)
for (size_t idx = 0; idx < id_arr.size(); idx++) for (size_t idx = 0; idx < id_arr.size(); idx++)
{ {
if (/*(locSym->id[idx].type == t) and Not checking type */ if (/*(locSym->id[idx].type == t) and Not checking type */
(id_arr[idx].id.bwGlb.seg == seg) and (id_arr[idx].id.bwGlb.seg == seg) and
(id_arr[idx].id.bwGlb.off == off) and (id_arr[idx].id.bwGlb.off == off) and
(id_arr[idx].id.bwGlb.regi == regi)) (id_arr[idx].id.bwGlb.regi == regi))
return (idx); return (idx);
} }
@ -181,7 +182,7 @@ int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_)
for (idx = 0; idx < id_arr.size(); idx++) for (idx = 0; idx < id_arr.size(); idx++)
{ {
ID &entry(id_arr[idx]); ID &entry(id_arr[idx]);
if(not entry.isLong() or (entry.loc != REG_FRAME)) if(not entry.isLongRegisterPair())
continue; continue;
if (/*(locSym->id[idx].type == t) and Not checking type */ if (/*(locSym->id[idx].type == t) and Not checking type */
(entry.longId().h() == regH) and (entry.longId().h() == regH) and
@ -189,23 +190,22 @@ int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_)
{ {
/* Check for occurrence in the list */ /* Check for occurrence in the list */
if (entry.idx.inList(ix_)) if (entry.idx.inList(ix_))
return (idx); return idx;
else else
{ {
/* Insert icode index in list */ /* Insert icode index in list */
entry.idx.push_back(ix_); entry.idx.push_back(ix_);
return (idx); return idx;
} }
} }
} }
/* Not in the table, create new identifier */ /* Not in the table, create new identifier */
id_arr.push_back(ID(t, LONGID_TYPE(regH,regL))); id_arr.emplace_back(t, LONGID_TYPE(regH,regL));
id_arr.back().idx.push_back(ix_); id_arr.back().idx.push_back(ix_);
return (id_arr.size() - 1); return (id_arr.size() - 1);
} }
/* Returns an identifier conditional expression node of type TYPE_LONG or /** \returns an identifier conditional expression node of type TYPE_LONG or TYPE_WORD_SIGN */
* TYPE_WORD_SIGN */
AstIdent * LOCAL_ID::createId(const ID *retVal, iICODE ix_) AstIdent * LOCAL_ID::createId(const ID *retVal, iICODE ix_)
{ {
return AstIdent::idID(retVal,this,ix_); return AstIdent::idID(retVal,this,ix_);
@ -222,15 +222,15 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
for (idx = 0; idx < id_arr.size(); idx++) for (idx = 0; idx < id_arr.size(); idx++)
{ {
if (/*(locSym->id[idx].type == t) and Not checking type */ if (/*(locSym->id[idx].type == t) and Not checking type */
(id_arr[idx].id.longGlb.seg == seg) and (id_arr[idx].id.longGlb.seg == seg) and
(id_arr[idx].id.longGlb.offH == offH) and (id_arr[idx].id.longGlb.offH == offH) and
(id_arr[idx].id.longGlb.offL == offL)) (id_arr[idx].id.longGlb.offL == offL))
return (idx); return (idx);
} }
printf("%d",t); printf("%d",t);
/* Not in the table, create new identifier */ /* Not in the table, create new identifier */
id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL))); id_arr.emplace_back(t, LONGGLB_TYPE(seg,offH,offL));
return (id_arr.size() - 1); return id_arr.size() - 1;
} }
@ -240,23 +240,20 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
* TYPE_LONG_(UN)SIGN and returns the index to this new entry. */ * TYPE_LONG_(UN)SIGN and returns the index to this new entry. */
int LOCAL_ID::newLongIdx( int16_t seg, int16_t offH, int16_t offL,uint8_t regi, hlType t) int LOCAL_ID::newLongIdx( int16_t seg, int16_t offH, int16_t offL,uint8_t regi, hlType t)
{ {
size_t idx;
/* Check for entry in the table */ /* Check for entry in the table */
for (idx = 0; idx < id_arr.size(); idx++) for (size_t idx = 0; idx < id_arr.size(); idx++)
{ {
if (/*(locSym->id[idx].type == t) and Not checking type */ if (/*(locSym->id[idx].type == t) and Not checking type */
(id_arr[idx].id.longGlb.seg == seg) and (id_arr[idx].id.longGlb.seg == seg) and
(id_arr[idx].id.longGlb.offH == offH) and (id_arr[idx].id.longGlb.offH == offH) and
(id_arr[idx].id.longGlb.offL == offL) and (id_arr[idx].id.longGlb.offL == offL) and
(id_arr[idx].id.longGlb.regi == regi)) (id_arr[idx].id.longGlb.regi == regi))
return (idx); return (idx);
} }
/* Not in the table, create new identifier */ /* Not in the table, create new identifier */
id_arr.push_back(ID(t,LONGGLB_TYPE(seg,offH,offL,regi))); id_arr.emplace_back(t,LONGGLB_TYPE(seg,offH,offL,regi));
idx = id_arr.size() - 1; return id_arr.size() - 1;
return (idx);
} }
@ -272,8 +269,8 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
if(id_arr[idx].loc!=STK_FRAME) if(id_arr[idx].loc!=STK_FRAME)
continue; continue;
if ((id_arr[idx].type == t) and if ((id_arr[idx].type == t) and
(id_arr[idx].longStkId().offH == offH) and (id_arr[idx].longStkId().offH == offH) and
(id_arr[idx].longStkId().offL == offL)) (id_arr[idx].longStkId().offL == offL))
return (idx); return (idx);
} }
@ -282,7 +279,7 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
flagByteWordId (offL); flagByteWordId (offL);
/* Create new identifier */ /* Create new identifier */
id_arr.push_back(ID(t,LONG_STKID_TYPE(offH,offL))); id_arr.emplace_back(t,LONG_STKID_TYPE(offH,offL));
return (id_arr.size() - 1); return (id_arr.size() - 1);
} }
@ -294,7 +291,7 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
{ {
size_t idx = ~0; //WARNING: clients of this method might propagate this bogus value! size_t idx = ~0; //WARNING: clients of this method might propagate this bogus value!
const LLOperand *pmH, *pmL; const LLOperand *pmH, *pmL;
LLInst &p_ll(*pIcode->ll()); LLInst &p_ll(*pIcode->ll());
if (f == LOW_FIRST) if (f == LOW_FIRST)
{ {
pmL = p_ll.get(sd); pmL = p_ll.get(sd);
@ -334,7 +331,7 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
else /* (pm->regi >= INDEXBASE and pm->off = 0) => indexed and no off */ else /* (pm->regi >= INDEXBASE and pm->off = 0) => indexed and no off */
printf ("long not supported, idx and no off\n"); printf ("long not supported, idx and no off\n");
return (idx); return idx;
} }
@ -356,22 +353,22 @@ bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc
pmLdst = &atOffset.m_dst; pmLdst = &atOffset.m_dst;
pmHsrc = &pIcode->ll()->src(); pmHsrc = &pIcode->ll()->src();
pmLsrc = &atOffset.src(); pmLsrc = &atOffset.src();
// if ((longId.offH == pmHsrc->off) and (longId.offL == pmLsrc->off)) // if ((longId.offH == pmHsrc->off) and (longId.offL == pmLsrc->off))
// { // {
// asgn.lhs = AstIdent::LongIdx (i); // asgn.lhs = AstIdent::LongIdx (i);
// if ( not pIcode->ll()->testFlags(NO_SRC) ) // if ( not pIcode->ll()->testFlags(NO_SRC) )
// { // {
// asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset); // asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
// } // }
// return true; // return true;
// } // }
// else if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off)) // else if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off))
// { // {
// asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset); // asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
// asgn.rhs = AstIdent::LongIdx (i); // asgn.rhs = AstIdent::LongIdx (i);
// return true; // return true;
// } // }
if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off)) if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off))
{ {
@ -403,7 +400,7 @@ bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc
* pProc : ptr to current procedure record * pProc : ptr to current procedure record
* rhs, lhs : return expressions if successful. */ * rhs, lhs : return expressions if successful. */
bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i, bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
Function * pProc, Assignment &asgn, LLInst &atOffset) Function * pProc, Assignment &asgn, LLInst &atOffset)
{ {
/* pointers to LOW_LEVEL icodes */ /* pointers to LOW_LEVEL icodes */
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc; const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
@ -431,25 +428,19 @@ bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
return false; return false;
} }
/* Given an index into the local identifier table for a long register /* Given an index into the local identifier table for a long register
* variable, determines whether regi is the high or low part, and returns * variable, determines whether regi is the high or low part, and returns
* the other part */ * the other part */
eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl) eReg LOCAL_ID::getPairedRegisterAt(int idx,eReg regi) const
{ {
ID *id; eReg res=rUNDEF; // Cristina: please check this!
const ID *id = &id_arr[idx];
id = &locTbl->id_arr[idx]; if (id->isLongRegisterPair())
if ((id->loc == REG_FRAME) and ((id->type == TYPE_LONG_SIGN) or
(id->type == TYPE_LONG_UNSIGN)))
{ {
if (id->longId().h() == regi) res = id->getPairedRegister(regi);
return (id->longId().l());
else if (id->longId().l() == regi)
return (id->longId().h());
} }
return rUNDEF; // Cristina: please check this! qWarning() << "Cannot find paired register";
return res;
} }
@ -472,9 +463,9 @@ void LOCAL_ID::propLongId (uint8_t regL, uint8_t regH, const QString &name)
if (rid.id.regi == regL) if (rid.id.regi == regL)
{ {
strcpy (rid.macro, "LO"); strcpy (rid.macro, "LO");
} }
else // if (rid.id.regi == regH) else // if (rid.id.regi == regH)
{ {
strcpy (rid.macro, "HI"); strcpy (rid.macro, "HI");
} }
} }

View File

@ -7,15 +7,15 @@
#include "CallGraph.h" #include "CallGraph.h"
#include "msvc_fixes.h" #include "msvc_fixes.h"
#include <inttypes.h>
#include <string.h>
#include <stdlib.h> /* For exit() */
#include <sstream>
#include <stdio.h>
#include <algorithm>
#include <deque>
#include <QMap> #include <QMap>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <inttypes.h>
#include <cstring>
#include <cstdlib> /* For exit() */
#include <cstdio>
#include <sstream>
#include <algorithm>
#include <deque>
using namespace std; using namespace std;
@ -129,14 +129,13 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
// Danger! Dcc will likely fall over in this code. // Danger! Dcc will likely fall over in this code.
// So we act as though we have done with this proc // So we act as though we have done with this proc
// pProc->flg &= ~TERMINATES; // Not sure about this // pProc->flg &= ~TERMINATES; // Not sure about this
done = true;
// And mark it as a library function, so structure() won't choke on it // And mark it as a library function, so structure() won't choke on it
flg |= PROC_ISLIB; flg |= PROC_ISLIB;
return; return;
} }
if (option.VeryVerbose) if (option.VeryVerbose)
{ {
qDebug() << "Parsing proc" << name << "at"<< QString::number(pstate->IP,16).toUpper(); qDebug() << "Parsing proc" << name << "at" << QString::number(pstate->IP,16).toUpper();
} }
while (not done ) while (not done )
@ -146,6 +145,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
break; break;
LLInst *ll = _Icode.ll(); LLInst *ll = _Icode.ll();
pstate->IP += (uint32_t)ll->numBytes; pstate->IP += (uint32_t)ll->numBytes;
setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes); setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes);
process_operands(_Icode,pstate); process_operands(_Icode,pstate);
@ -181,6 +181,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
case iJCXZ: case iJCXZ:
{ {
STATE StCopy; STATE StCopy;
uint32_t lastIp = pstate->IP - 2;
int ip = Icode.size()-1; /* Index of this jump */ int ip = Icode.size()-1; /* Index of this jump */
ICODE &prev(*(++Icode.rbegin())); /* Previous icode */ ICODE &prev(*(++Icode.rbegin())); /* Previous icode */
bool fBranch = false; bool fBranch = false;
@ -201,6 +202,8 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
} }
StCopy = *pstate; StCopy = *pstate;
//printf("From %X condJump to %X\n", lastIp, pstate->IP);
/* Straight line code */ /* Straight line code */
this->FollowCtrl (pcallGraph, &StCopy); // recurrent ? this->FollowCtrl (pcallGraph, &StCopy); // recurrent ?
@ -547,6 +550,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
static uint8_t i2r[4] = {rSI, rDI, rBP, rBX}; static uint8_t i2r[4] = {rSI, rDI, rBP, rBX};
ICODE _Icode; ICODE _Icode;
uint32_t lastIp = pstate->IP - 1;
uint32_t cs, offTable, endTable; uint32_t cs, offTable, endTable;
uint32_t i, k, seg, target; uint32_t i, k, seg, target;
@ -554,7 +558,19 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
{ {
if (pIcode.ll()->getOpcode() == iJMPF) if (pIcode.ll()->getOpcode() == iJMPF)
pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3)); pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
pstate->IP = pIcode.ll()->src().getImm2();
pstate->IP = pIcode.ll()->src().getImm2();
//printf("From seg:%04X JMP(F) to %X\n", lastIp, pstate->IP);
if (pstate->IP == 0xFFFF0)
{
/* Nasty (wrong) trick use to reset, consider it as terminating */
pIcode.ll()->setFlags(TERMINATES);
pstate->setState( rCS, 0);
pstate->IP = 0;
}
int64_t i = pIcode.ll()->src().getImm2(); int64_t i = pIcode.ll()->src().getImm2();
if (i < 0) if (i < 0)
{ {
@ -678,6 +694,7 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
ICODE &last_insn(Icode.back()); ICODE &last_insn(Icode.back());
STATE localState; /* Local copy of the machine state */ STATE localState; /* Local copy of the machine state */
uint32_t lastIp = pstate->IP - 2;
uint32_t off; uint32_t off;
/* For Indirect Calls, find the function address */ /* For Indirect Calls, find the function address */
bool indirect = false; bool indirect = false;
@ -771,10 +788,13 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
pstate->IP = pIcode.ll()->src().getImm2(); pstate->IP = pIcode.ll()->src().getImm2();
if (pIcode.ll()->getOpcode() == iCALLF) if (pIcode.ll()->getOpcode() == iCALLF)
pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3)); pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
x.state = *pstate; x.state = *pstate;
/* Insert new procedure in call graph */ /* Insert new procedure in call graph */
pcallGraph->insertCallGraph (this, iter); - pcallGraph->insertCallGraph (this, iter);
//printf("From %X CALL to %X\n", lastIp, pstate->IP);
/* Process new procedure */ /* Process new procedure */
x.FollowCtrl (pcallGraph, pstate); x.FollowCtrl (pcallGraph, pstate);

View File

@ -88,7 +88,7 @@ void CALL_GRAPH::write()
/* Updates the argument table by including the register(s) (ie. lhs of /* Updates the argument table by including the register(s) (ie. lhs of
* picode) and the actual expression (ie. rhs of picode). * picode) and the actual expression (ie. rhs of picode).
* Note: register(s) are only included once in the table. */ * Note: register(s) are only included once in the table. */
void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const void LOCAL_ID::newRegArg(ICODE &picode, ICODE &ticode) const
{ {
AstIdent *lhs; AstIdent *lhs;
STKFRAME * call_args_stackframe, *target_stackframe; STKFRAME * call_args_stackframe, *target_stackframe;
@ -101,13 +101,13 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
eReg regH; /* Registers involved in arguments */ eReg regH; /* Registers involved in arguments */
/* Flag ticode as having register arguments */ /* Flag ticode as having register arguments */
tproc = ticode->hl()->call.proc; tproc = ticode.hl()->call.proc;
tproc->flg |= REG_ARGS; tproc->flg |= REG_ARGS;
/* Get registers and index into target procedure's local list */ /* Get registers and index into target procedure's local list */
call_args_stackframe = ticode->hl()->call.args; call_args_stackframe = ticode.hl()->call.args;
target_stackframe = &tproc->args; target_stackframe = &tproc->args;
lhs = dynamic_cast<AstIdent *>(picode->hl()->asgn.lhs()); lhs = dynamic_cast<AstIdent *>(picode.hl()->asgn.lhs());
RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs); RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
assert(lhs); assert(lhs);
type = lhs->ident.type(); type = lhs->ident.type();
@ -188,13 +188,13 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
/* Do ps (actual arguments) */ /* Do ps (actual arguments) */
STKSYM newsym; STKSYM newsym;
newsym.setArgName(call_args_stackframe->size()); newsym.setArgName(call_args_stackframe->size());
newsym.actual = picode->hl()->asgn.rhs; newsym.actual = picode.hl()->asgn.m_rhs;
newsym.regs = lhs; newsym.regs = lhs;
/* Mask off high and low register(s) in picode */ /* Mask off high and low register(s) in picode */
switch (type) { switch (type) {
case REGISTER: case REGISTER:
id = &id_arr[lhs_reg->regiIdx]; id = &id_arr[lhs_reg->regiIdx];
picode->du.def.clrReg(id->id.regi); picode.du.def.clrReg(id->id.regi);
if (id->id.regi < rAL) if (id->id.regi < rAL)
newsym.type = TYPE_WORD_SIGN; newsym.type = TYPE_WORD_SIGN;
else else
@ -202,8 +202,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
break; break;
case LONG_VAR: case LONG_VAR:
id = &id_arr[lhs->ident.idNode.longIdx]; id = &id_arr[lhs->ident.idNode.longIdx];
picode->du.def.clrReg(id->longId().h()); picode.du.def.clrReg(id->longId().h());
picode->du.def.clrReg(id->longId().l()); picode.du.def.clrReg(id->longId().l());
newsym.type = TYPE_LONG_SIGN; newsym.type = TYPE_LONG_SIGN;
break; break;
default: default:

View File

@ -5,12 +5,11 @@
#include "CallGraph.h" #include "CallGraph.h"
#include "project.h" #include "project.h"
#include "Procedure.h" #include "Procedure.h"
using namespace std; using namespace std;
//Project g_proj;
QString asm1_name, asm2_name; /* Assembler output filenames */ QString asm1_name, asm2_name; /* Assembler output filenames */
SYMTAB symtab; /* Global symbol table */
STATS stats; /* cfg statistics */ STATS stats; /* cfg statistics */
//PROG prog; /* programs fields */
OPTION option; /* Command line options */ OPTION option; /* Command line options */
Project *Project::s_instance = nullptr; Project *Project::s_instance = nullptr;
Project::Project() : callGraph(nullptr) Project::Project() : callGraph(nullptr)
@ -40,7 +39,7 @@ bool Project::valid(ilFunction iter)
ilFunction Project::funcIter(Function *to_find) ilFunction Project::funcIter(Function *to_find)
{ {
auto iter=std::find_if(pProcList.begin(),pProcList.end(), auto iter=std::find_if(pProcList.begin(),pProcList.end(),
[to_find](const Function &f)->bool {return to_find==&f;}); [to_find](const Function &f)->bool {return to_find==&f;});
assert(iter!=pProcList.end()); assert(iter!=pProcList.end());
return iter; return iter;
} }
@ -49,8 +48,8 @@ ilFunction Project::findByEntry(uint32_t entry)
{ {
/* Search procedure list for one with appropriate entry point */ /* Search procedure list for one with appropriate entry point */
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(), ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
[entry](const Function &f) { return f.procEntry==entry; }); [entry](const Function &f) { return f.procEntry==entry; });
return iter; return iter;
} }
ilFunction Project::createFunction(FunctionType *f,const QString &name) ilFunction Project::createFunction(FunctionType *f,const QString &name)
@ -59,7 +58,7 @@ ilFunction Project::createFunction(FunctionType *f,const QString &name)
return (++pProcList.rbegin()).base(); return (++pProcList.rbegin()).base();
} }
int Project::getSymIdxByAdd(uint32_t adr) int Project::getSymIdxByAddr(uint32_t adr)
{ {
size_t i; size_t i;
for (i = 0; i < symtab.size(); i++) for (i = 0; i < symtab.size(); i++)
@ -98,8 +97,6 @@ Project *Project::get()
s_instance=new Project; s_instance=new Project;
return s_instance; return s_instance;
} }
SourceMachine *Project::machine() SourceMachine *Project::machine()
{ {
return nullptr; return nullptr;

View File

@ -69,8 +69,8 @@ static bool isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off)
// preincrement because pIcode is not checked here // preincrement because pIcode is not checked here
iICODE icodes[] = { ++pIcode,++pIcode,++pIcode }; iICODE icodes[] = { ++pIcode,++pIcode,++pIcode };
if ( icodes[1]->ll()->match(iCMP) and if ( icodes[1]->ll()->match(iCMP) and
(isJCond ((llIcode)icodes[0]->ll()->getOpcode())) and (isJCond (icodes[0]->ll()->getOpcode())) and
(isJCond ((llIcode)icodes[2]->ll()->getOpcode()))) (isJCond (icodes[2]->ll()->getOpcode())))
{ {
off = initial_icode; off = initial_icode;
advance(off,2); advance(off,2);
@ -500,7 +500,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
* JX lab * JX lab
* => HLI_JCOND (regH:regL X 0) lab * => HLI_JCOND (regH:regL X 0) lab
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */ * This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
else if (pIcode->ll()->match(iOR) and (next1 != pEnd) and (isJCond ((llIcode)next1->ll()->getOpcode()))) else if (pIcode->ll()->match(iOR) and (next1 != pEnd) and (isJCond (next1->ll()->getOpcode())))
{ {
if (pLocId.longId().srcDstRegMatch(pIcode,pIcode)) if (pLocId.longId().srcDstRegMatch(pIcode,pIcode))
{ {

View File

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* dcc project scanner module * dcc project scanner module
* Implements a simple state driven scanner to convert 8086 machine code into * Implements a simple state driven scanner to convert 8086 machine code into
* I-code * I-code
* (C) Cristina Cifuentes, Jeff Ledermann * (C) Cristina Cifuentes, Jeff Ledermann
@ -19,7 +19,6 @@
#define S_EXT 0x000200 /* sign extend */ #define S_EXT 0x000200 /* sign extend */
#define OP386 0x000400 /* 386 op-code */ #define OP386 0x000400 /* 386 op-code */
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */ #define NSP 0x000800 /* NOT_HLL if SP is src or dst */
// defined in Enums.h #define ICODEMASK 0xFF00FF /* Masks off parser flags */
static void rm(int i); static void rm(int i);
static void modrm(int i); static void modrm(int i);
@ -51,276 +50,276 @@ static void none1(int i);
static void none2(int i); static void none2(int i);
static void checkInt(int i); static void checkInt(int i);
#define iZERO (llIcode)0 // For neatness #define IC llIcode
#define IC llIcode
static struct { struct StateTabelEntry {
void (*state1)(int); void (*state1)(int);
void (*state2)(int); void (*state2)(int);
uint32_t flg; uint32_t flg;
llIcode opcode; llIcode opcode;
} stateTable[] = { };
{ modrm, none2, B , iADD }, /* 00 */ static const StateTabelEntry stateTable[] = {
{ modrm, none2, 0 , iADD }, /* 01 */ { modrm, none2, B , iADD }, /* 00 */
{ modrm, none2, TO_REG | B , iADD }, /* 02 */ { modrm, none2, 0 , iADD }, /* 01 */
{ modrm, none2, TO_REG , iADD }, /* 03 */ { modrm, none2, TO_REG | B , iADD }, /* 02 */
{ data1, axImp, B , iADD }, /* 04 */ { modrm, none2, TO_REG , iADD }, /* 03 */
{ data2, axImp, 0 , iADD }, /* 05 */ { data1, axImp, B , iADD }, /* 04 */
{ segop, none2, NO_SRC , iPUSH }, /* 06 */ { data2, axImp, 0 , iADD }, /* 05 */
{ segop, none2, NO_SRC , iPOP }, /* 07 */ { segop, none2, NO_SRC , iPUSH }, /* 06 */
{ modrm, none2, B , iOR }, /* 08 */ { segop, none2, NO_SRC , iPOP }, /* 07 */
{ modrm, none2, NSP , iOR }, /* 09 */ { modrm, none2, B , iOR }, /* 08 */
{ modrm, none2, TO_REG | B , iOR }, /* 0A */ { modrm, none2, NSP , iOR }, /* 09 */
{ modrm, none2, TO_REG | NSP , iOR }, /* 0B */ { modrm, none2, TO_REG | B , iOR }, /* 0A */
{ data1, axImp, B , iOR }, /* 0C */ { modrm, none2, TO_REG | NSP , iOR }, /* 0B */
{ data2, axImp, 0 , iOR }, /* 0D */ { data1, axImp, B , iOR }, /* 0C */
{ segop, none2, NO_SRC , iPUSH }, /* 0E */ { data2, axImp, 0 , iOR }, /* 0D */
{ none1, none2, OP386 , iZERO }, /* 0F */ { segop, none2, NO_SRC , iPUSH }, /* 0E */
{ modrm, none2, B , iADC }, /* 10 */ { none1, none2, OP386 , iINVALID }, /* 0F */
{ modrm, none2, NSP , iADC }, /* 11 */ { modrm, none2, B , iADC }, /* 10 */
{ modrm, none2, TO_REG | B , iADC }, /* 12 */ { modrm, none2, NSP , iADC }, /* 11 */
{ modrm, none2, TO_REG | NSP , iADC }, /* 13 */ { modrm, none2, TO_REG | B , iADC }, /* 12 */
{ data1, axImp, B , iADC }, /* 14 */ { modrm, none2, TO_REG | NSP , iADC }, /* 13 */
{ data2, axImp, 0 , iADC }, /* 15 */ { data1, axImp, B , iADC }, /* 14 */
{ segop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 16 */ { data2, axImp, 0 , iADC }, /* 15 */
{ segop, none2, NOT_HLL | NO_SRC , iPOP }, /* 17 */ { segop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 16 */
{ modrm, none2, B , iSBB }, /* 18 */ { segop, none2, NOT_HLL | NO_SRC , iPOP }, /* 17 */
{ modrm, none2, NSP , iSBB }, /* 19 */ { modrm, none2, B , iSBB }, /* 18 */
{ modrm, none2, TO_REG | B , iSBB }, /* 1A */ { modrm, none2, NSP , iSBB }, /* 19 */
{ modrm, none2, TO_REG | NSP , iSBB }, /* 1B */ { modrm, none2, TO_REG | B , iSBB }, /* 1A */
{ data1, axImp, B , iSBB }, /* 1C */ { modrm, none2, TO_REG | NSP , iSBB }, /* 1B */
{ data2, axImp, 0 , iSBB }, /* 1D */ { data1, axImp, B , iSBB }, /* 1C */
{ segop, none2, NO_SRC , iPUSH }, /* 1E */ { data2, axImp, 0 , iSBB }, /* 1D */
{ segop, none2, NO_SRC , iPOP }, /* 1F */ { segop, none2, NO_SRC , iPUSH }, /* 1E */
{ modrm, none2, B , iAND }, /* 20 */ { segop, none2, NO_SRC , iPOP }, /* 1F */
{ modrm, none2, NSP , iAND }, /* 21 */ { modrm, none2, B , iAND }, /* 20 */
{ modrm, none2, TO_REG | B , iAND }, /* 22 */ { modrm, none2, NSP , iAND }, /* 21 */
{ modrm, none2, TO_REG | NSP , iAND }, /* 23 */ { modrm, none2, TO_REG | B , iAND }, /* 22 */
{ data1, axImp, B , iAND }, /* 24 */ { modrm, none2, TO_REG | NSP , iAND }, /* 23 */
{ data2, axImp, 0 , iAND }, /* 25 */ { data1, axImp, B , iAND }, /* 24 */
{ prefix, none2, 0 , (IC)rES}, /* 26 */ { data2, axImp, 0 , iAND }, /* 25 */
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAA }, /* 27 */ { prefix, none2, 0 , (IC)rES}, /* 26 */
{ modrm, none2, B , iSUB }, /* 28 */ { none1, axImp, NOT_HLL | B|NO_SRC , iDAA }, /* 27 */
{ modrm, none2, 0 , iSUB }, /* 29 */ { modrm, none2, B , iSUB }, /* 28 */
{ modrm, none2, TO_REG | B , iSUB }, /* 2A */ { modrm, none2, 0 , iSUB }, /* 29 */
{ modrm, none2, TO_REG , iSUB }, /* 2B */ { modrm, none2, TO_REG | B , iSUB }, /* 2A */
{ data1, axImp, B , iSUB }, /* 2C */ { modrm, none2, TO_REG , iSUB }, /* 2B */
{ data2, axImp, 0 , iSUB }, /* 2D */ { data1, axImp, B , iSUB }, /* 2C */
{ prefix, none2, 0 , (IC)rCS}, /* 2E */ { data2, axImp, 0 , iSUB }, /* 2D */
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAS }, /* 2F */ { prefix, none2, 0 , (IC)rCS}, /* 2E */
{ modrm, none2, B , iXOR }, /* 30 */ { none1, axImp, NOT_HLL | B|NO_SRC , iDAS }, /* 2F */
{ modrm, none2, NSP , iXOR }, /* 31 */ { modrm, none2, B , iXOR }, /* 30 */
{ modrm, none2, TO_REG | B , iXOR }, /* 32 */ { modrm, none2, NSP , iXOR }, /* 31 */
{ modrm, none2, TO_REG | NSP , iXOR }, /* 33 */ { modrm, none2, TO_REG | B , iXOR }, /* 32 */
{ data1, axImp, B , iXOR }, /* 34 */ { modrm, none2, TO_REG | NSP , iXOR }, /* 33 */
{ data2, axImp, 0 , iXOR }, /* 35 */ { data1, axImp, B , iXOR }, /* 34 */
{ prefix, none2, 0 , (IC)rSS}, /* 36 */ { data2, axImp, 0 , iXOR }, /* 35 */
{ none1, axImp, NOT_HLL | NO_SRC , iAAA }, /* 37 */ { prefix, none2, 0 , (IC)rSS}, /* 36 */
{ modrm, none2, B , iCMP }, /* 38 */ { none1, axImp, NOT_HLL | NO_SRC , iAAA }, /* 37 */
{ modrm, none2, NSP , iCMP }, /* 39 */ { modrm, none2, B , iCMP }, /* 38 */
{ modrm, none2, TO_REG | B , iCMP }, /* 3A */ { modrm, none2, NSP , iCMP }, /* 39 */
{ modrm, none2, TO_REG | NSP , iCMP }, /* 3B */ { modrm, none2, TO_REG | B , iCMP }, /* 3A */
{ data1, axImp, B , iCMP }, /* 3C */ { modrm, none2, TO_REG | NSP , iCMP }, /* 3B */
{ data2, axImp, 0 , iCMP }, /* 3D */ { data1, axImp, B , iCMP }, /* 3C */
{ prefix, none2, 0 , (IC)rDS}, /* 3E */ { data2, axImp, 0 , iCMP }, /* 3D */
{ none1, axImp, NOT_HLL | NO_SRC , iAAS }, /* 3F */ { prefix, none2, 0 , (IC)rDS}, /* 3E */
{ regop, none2, 0 , iINC }, /* 40 */ { none1, axImp, NOT_HLL | NO_SRC , iAAS }, /* 3F */
{ regop, none2, 0 , iINC }, /* 41 */ { regop, none2, 0 , iINC }, /* 40 */
{ regop, none2, 0 , iINC }, /* 42 */ { regop, none2, 0 , iINC }, /* 41 */
{ regop, none2, 0 , iINC }, /* 43 */ { regop, none2, 0 , iINC }, /* 42 */
{ regop, none2, NOT_HLL , iINC }, /* 44 */ { regop, none2, 0 , iINC }, /* 43 */
{ regop, none2, 0 , iINC }, /* 45 */ { regop, none2, NOT_HLL , iINC }, /* 44 */
{ regop, none2, 0 , iINC }, /* 46 */ { regop, none2, 0 , iINC }, /* 45 */
{ regop, none2, 0 , iINC }, /* 47 */ { regop, none2, 0 , iINC }, /* 46 */
{ regop, none2, 0 , iDEC }, /* 48 */ { regop, none2, 0 , iINC }, /* 47 */
{ regop, none2, 0 , iDEC }, /* 49 */ { regop, none2, 0 , iDEC }, /* 48 */
{ regop, none2, 0 , iDEC }, /* 4A */ { regop, none2, 0 , iDEC }, /* 49 */
{ regop, none2, 0 , iDEC }, /* 4B */ { regop, none2, 0 , iDEC }, /* 4A */
{ regop, none2, NOT_HLL , iDEC }, /* 4C */ { regop, none2, 0 , iDEC }, /* 4B */
{ regop, none2, 0 , iDEC }, /* 4D */ { regop, none2, NOT_HLL , iDEC }, /* 4C */
{ regop, none2, 0 , iDEC }, /* 4E */ { regop, none2, 0 , iDEC }, /* 4D */
{ regop, none2, 0 , iDEC }, /* 4F */ { regop, none2, 0 , iDEC }, /* 4E */
{ regop, none2, NO_SRC , iPUSH }, /* 50 */ { regop, none2, 0 , iDEC }, /* 4F */
{ regop, none2, NO_SRC , iPUSH }, /* 51 */ { regop, none2, NO_SRC , iPUSH }, /* 50 */
{ regop, none2, NO_SRC , iPUSH }, /* 52 */ { regop, none2, NO_SRC , iPUSH }, /* 51 */
{ regop, none2, NO_SRC , iPUSH }, /* 53 */ { regop, none2, NO_SRC , iPUSH }, /* 52 */
{ regop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 54 */ { regop, none2, NO_SRC , iPUSH }, /* 53 */
{ regop, none2, NO_SRC , iPUSH }, /* 55 */ { regop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 54 */
{ regop, none2, NO_SRC , iPUSH }, /* 56 */ { regop, none2, NO_SRC , iPUSH }, /* 55 */
{ regop, none2, NO_SRC , iPUSH }, /* 57 */ { regop, none2, NO_SRC , iPUSH }, /* 56 */
{ regop, none2, NO_SRC , iPOP }, /* 58 */ { regop, none2, NO_SRC , iPUSH }, /* 57 */
{ regop, none2, NO_SRC , iPOP }, /* 59 */ { regop, none2, NO_SRC , iPOP }, /* 58 */
{ regop, none2, NO_SRC , iPOP }, /* 5A */ { regop, none2, NO_SRC , iPOP }, /* 59 */
{ regop, none2, NO_SRC , iPOP }, /* 5B */ { regop, none2, NO_SRC , iPOP }, /* 5A */
{ regop, none2, NOT_HLL | NO_SRC , iPOP }, /* 5C */ { regop, none2, NO_SRC , iPOP }, /* 5B */
{ regop, none2, NO_SRC , iPOP }, /* 5D */ { regop, none2, NOT_HLL | NO_SRC , iPOP }, /* 5C */
{ regop, none2, NO_SRC , iPOP }, /* 5E */ { regop, none2, NO_SRC , iPOP }, /* 5D */
{ regop, none2, NO_SRC , iPOP }, /* 5F */ { regop, none2, NO_SRC , iPOP }, /* 5E */
{ none1, none2, NOT_HLL | NO_OPS , iPUSHA}, /* 60 */ { regop, none2, NO_SRC , iPOP }, /* 5F */
{ none1, none2, NOT_HLL | NO_OPS , iPOPA }, /* 61 */ { none1, none2, NOT_HLL | NO_OPS , iPUSHA}, /* 60 */
{ memOnly, modrm, TO_REG | NSP , iBOUND}, /* 62 */ { none1, none2, NOT_HLL | NO_OPS , iPOPA }, /* 61 */
{ none1, none2, OP386 , iZERO }, /* 63 */ { memOnly, modrm, TO_REG | NSP , iBOUND}, /* 62 */
{ none1, none2, OP386 , iZERO }, /* 64 */ { none1, none2, OP386 , iINVALID }, /* 63 */
{ none1, none2, OP386 , iZERO }, /* 65 */ { none1, none2, OP386 , iINVALID }, /* 64 */
{ none1, none2, OP386 , iZERO }, /* 66 */ { none1, none2, OP386 , iINVALID }, /* 65 */
{ none1, none2, OP386 , iZERO }, /* 67 */ { none1, none2, OP386 , iINVALID }, /* 66 */
{ data2, none2, NO_SRC , iPUSH }, /* 68 */ { none1, none2, OP386 , iINVALID }, /* 67 */
{ modrm, data2, TO_REG | NSP , iIMUL }, /* 69 */ { data2, none2, NO_SRC , iPUSH }, /* 68 */
{ data1, none2, S_EXT | NO_SRC , iPUSH }, /* 6A */ { modrm, data2, TO_REG | NSP , iIMUL }, /* 69 */
{ modrm, data1, TO_REG | NSP | S_EXT , iIMUL }, /* 6B */ { data1, none2, S_EXT | NO_SRC , iPUSH }, /* 6A */
{ strop, memImp, NOT_HLL | B|IM_OPS , iINS }, /* 6C */ { modrm, data1, TO_REG | NSP | S_EXT , iIMUL }, /* 6B */
{ strop, memImp, NOT_HLL | IM_OPS , iINS }, /* 6D */ { strop, memImp, NOT_HLL | B|IM_OPS , iINS }, /* 6C */
{ strop, memImp, NOT_HLL | B|IM_OPS , iOUTS }, /* 6E */ { strop, memImp, NOT_HLL | IM_OPS , iINS }, /* 6D */
{ strop, memImp, NOT_HLL | IM_OPS , iOUTS }, /* 6F */ { strop, memImp, NOT_HLL | B|IM_OPS , iOUTS }, /* 6E */
{ dispS, none2, NOT_HLL , iJO }, /* 70 */ { strop, memImp, NOT_HLL | IM_OPS , iOUTS }, /* 6F */
{ dispS, none2, NOT_HLL , iJNO }, /* 71 */ { dispS, none2, NOT_HLL , iJO }, /* 70 */
{ dispS, none2, 0 , iJB }, /* 72 */ { dispS, none2, NOT_HLL , iJNO }, /* 71 */
{ dispS, none2, 0 , iJAE }, /* 73 */ { dispS, none2, 0 , iJB }, /* 72 */
{ dispS, none2, 0 , iJE }, /* 74 */ { dispS, none2, 0 , iJAE }, /* 73 */
{ dispS, none2, 0 , iJNE }, /* 75 */ { dispS, none2, 0 , iJE }, /* 74 */
{ dispS, none2, 0 , iJBE }, /* 76 */ { dispS, none2, 0 , iJNE }, /* 75 */
{ dispS, none2, 0 , iJA }, /* 77 */ { dispS, none2, 0 , iJBE }, /* 76 */
{ dispS, none2, 0 , iJS }, /* 78 */ { dispS, none2, 0 , iJA }, /* 77 */
{ dispS, none2, 0 , iJNS }, /* 79 */ { dispS, none2, 0 , iJS }, /* 78 */
{ dispS, none2, NOT_HLL , iJP }, /* 7A */ { dispS, none2, 0 , iJNS }, /* 79 */
{ dispS, none2, NOT_HLL , iJNP }, /* 7B */ { dispS, none2, NOT_HLL , iJP }, /* 7A */
{ dispS, none2, 0 , iJL }, /* 7C */ { dispS, none2, NOT_HLL , iJNP }, /* 7B */
{ dispS, none2, 0 , iJGE }, /* 7D */ { dispS, none2, 0 , iJL }, /* 7C */
{ dispS, none2, 0 , iJLE }, /* 7E */ { dispS, none2, 0 , iJGE }, /* 7D */
{ dispS, none2, 0 , iJG }, /* 7F */ { dispS, none2, 0 , iJLE }, /* 7E */
{ immed, data1, B , iZERO }, /* 80 */ { dispS, none2, 0 , iJG }, /* 7F */
{ immed, data2, NSP , iZERO }, /* 81 */ { immed, data1, B , iINVALID }, /* 80 */
{ immed, data1, B , iZERO }, /* 82 */ /* ?? */ { immed, data2, NSP , iINVALID }, /* 81 */
{ immed, data1, NSP | S_EXT , iZERO }, /* 83 */ { immed, data1, B , iINVALID }, /* 82 */ /* ?? */
{ modrm, none2, TO_REG | B , iTEST }, /* 84 */ { immed, data1, NSP | S_EXT , iINVALID }, /* 83 */
{ modrm, none2, TO_REG | NSP , iTEST }, /* 85 */ { modrm, none2, TO_REG | B , iTEST }, /* 84 */
{ modrm, none2, TO_REG | B , iXCHG }, /* 86 */ { modrm, none2, TO_REG | NSP , iTEST }, /* 85 */
{ modrm, none2, TO_REG | NSP , iXCHG }, /* 87 */ { modrm, none2, TO_REG | B , iXCHG }, /* 86 */
{ modrm, none2, B , iMOV }, /* 88 */ { modrm, none2, TO_REG | NSP , iXCHG }, /* 87 */
{ modrm, none2, 0 , iMOV }, /* 89 */ { modrm, none2, B , iMOV }, /* 88 */
{ modrm, none2, TO_REG | B , iMOV }, /* 8A */ { modrm, none2, 0 , iMOV }, /* 89 */
{ modrm, none2, TO_REG , iMOV }, /* 8B */ { modrm, none2, TO_REG | B , iMOV }, /* 8A */
{ segrm, none2, NSP , iMOV }, /* 8C */ { modrm, none2, TO_REG , iMOV }, /* 8B */
{ memOnly, modrm, TO_REG | NSP , iLEA }, /* 8D */ { segrm, none2, NSP , iMOV }, /* 8C */
{ segrm, none2, TO_REG | NSP , iMOV }, /* 8E */ { memOnly, modrm, TO_REG | NSP , iLEA }, /* 8D */
{ memReg0, none2, NO_SRC , iPOP }, /* 8F */ { segrm, none2, TO_REG | NSP , iMOV }, /* 8E */
{ none1, none2, NO_OPS , iNOP }, /* 90 */ { memReg0, none2, NO_SRC , iPOP }, /* 8F */
{ regop, axImp, 0 , iXCHG }, /* 91 */ { none1, none2, NO_OPS , iNOP }, /* 90 */
{ regop, axImp, 0 , iXCHG }, /* 92 */ { regop, axImp, 0 , iXCHG }, /* 91 */
{ regop, axImp, 0 , iXCHG }, /* 93 */ { regop, axImp, 0 , iXCHG }, /* 92 */
{ regop, axImp, NOT_HLL , iXCHG }, /* 94 */ { regop, axImp, 0 , iXCHG }, /* 93 */
{ regop, axImp, 0 , iXCHG }, /* 95 */ { regop, axImp, NOT_HLL , iXCHG }, /* 94 */
{ regop, axImp, 0 , iXCHG }, /* 96 */ { regop, axImp, 0 , iXCHG }, /* 95 */
{ regop, axImp, 0 , iXCHG }, /* 97 */ { regop, axImp, 0 , iXCHG }, /* 96 */
{ alImp, axImp, SRC_B | S_EXT , iSIGNEX}, /* 98 */ { regop, axImp, 0 , iXCHG }, /* 97 */
{axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX}, /* 99 */ { alImp, axImp, SRC_B | S_EXT , iSIGNEX}, /* 98 */
{ dispF, none2, TO_REG , iCALLF }, /* 9A */ // TO_REG set to use SRC when processing setAddress {axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX}, /* 99 */
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT }, /* 9B */ { dispF, none2, TO_REG , iCALLF }, /* 9A */ // TO_REG set to use SRC when processing setAddress
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF}, /* 9C */ { none1, none2, FLOAT_OP| NO_OPS , iWAIT }, /* 9B */
{ none1, none2, NOT_HLL | NO_OPS , iPOPF }, /* 9D */ { none1, none2, NOT_HLL | NO_OPS , iPUSHF}, /* 9C */
{ none1, none2, NOT_HLL | NO_OPS , iSAHF }, /* 9E */ { none1, none2, NOT_HLL | NO_OPS , iPOPF }, /* 9D */
{ none1, none2, NOT_HLL | NO_OPS , iLAHF }, /* 9F */ { none1, none2, NOT_HLL | NO_OPS , iSAHF }, /* 9E */
{ dispM, axImp, B , iMOV }, /* A0 */ { none1, none2, NOT_HLL | NO_OPS , iLAHF }, /* 9F */
{ dispM, axImp, 0 , iMOV }, /* A1 */ { dispM, axImp, B , iMOV }, /* A0 */
{ dispM, axImp, TO_REG | B , iMOV }, /* A2 */ { dispM, axImp, 0 , iMOV }, /* A1 */
{ dispM, axImp, TO_REG , iMOV }, /* A3 */ { dispM, axImp, TO_REG | B , iMOV }, /* A2 */
{ strop, memImp, B | IM_OPS , iMOVS }, /* A4 */ { dispM, axImp, TO_REG , iMOV }, /* A3 */
{ strop, memImp, IM_OPS , iMOVS }, /* A5 */ { strop, memImp, B | IM_OPS , iMOVS }, /* A4 */
{ strop, memImp, B | IM_OPS , iCMPS }, /* A6 */ { strop, memImp, IM_OPS , iMOVS }, /* A5 */
{ strop, memImp, IM_OPS , iCMPS }, /* A7 */ { strop, memImp, B | IM_OPS , iCMPS }, /* A6 */
{ data1, axImp, B , iTEST }, /* A8 */ { strop, memImp, IM_OPS , iCMPS }, /* A7 */
{ data2, axImp, 0 , iTEST }, /* A9 */ { data1, axImp, B , iTEST }, /* A8 */
{ strop, memImp, B | IM_OPS , iSTOS }, /* AA */ { data2, axImp, 0 , iTEST }, /* A9 */
{ strop, memImp, IM_OPS , iSTOS }, /* AB */ { strop, memImp, B | IM_OPS , iSTOS }, /* AA */
{ strop, memImp, B | IM_OPS , iLODS }, /* AC */ { strop, memImp, IM_OPS , iSTOS }, /* AB */
{ strop, memImp, IM_OPS , iLODS }, /* AD */ { strop, memImp, B | IM_OPS , iLODS }, /* AC */
{ strop, memImp, B | IM_OPS , iSCAS }, /* AE */ { strop, memImp, IM_OPS , iLODS }, /* AD */
{ strop, memImp, IM_OPS , iSCAS }, /* AF */ { strop, memImp, B | IM_OPS , iSCAS }, /* AE */
{ regop, data1, B , iMOV }, /* B0 */ { strop, memImp, IM_OPS , iSCAS }, /* AF */
{ regop, data1, B , iMOV }, /* B1 */ { regop, data1, B , iMOV }, /* B0 */
{ regop, data1, B , iMOV }, /* B2 */ { regop, data1, B , iMOV }, /* B1 */
{ regop, data1, B , iMOV }, /* B3 */ { regop, data1, B , iMOV }, /* B2 */
{ regop, data1, B , iMOV }, /* B4 */ { regop, data1, B , iMOV }, /* B3 */
{ regop, data1, B , iMOV }, /* B5 */ { regop, data1, B , iMOV }, /* B4 */
{ regop, data1, B , iMOV }, /* B6 */ { regop, data1, B , iMOV }, /* B5 */
{ regop, data1, B , iMOV }, /* B7 */ { regop, data1, B , iMOV }, /* B6 */
{ regop, data2, 0 , iMOV }, /* B8 */ { regop, data1, B , iMOV }, /* B7 */
{ regop, data2, 0 , iMOV }, /* B9 */ { regop, data2, 0 , iMOV }, /* B8 */
{ regop, data2, 0 , iMOV }, /* BA */ { regop, data2, 0 , iMOV }, /* B9 */
{ regop, data2, 0 , iMOV }, /* BB */ { regop, data2, 0 , iMOV }, /* BA */
{ regop, data2, NOT_HLL , iMOV }, /* BC */ { regop, data2, 0 , iMOV }, /* BB */
{ regop, data2, 0 , iMOV }, /* BD */ { regop, data2, NOT_HLL , iMOV }, /* BC */
{ regop, data2, 0 , iMOV }, /* BE */ { regop, data2, 0 , iMOV }, /* BD */
{ regop, data2, 0 , iMOV }, /* BF */ { regop, data2, 0 , iMOV }, /* BE */
{ shift, data1, B , iZERO }, /* C0 */ { regop, data2, 0 , iMOV }, /* BF */
{ shift, data1, NSP | SRC_B , iZERO }, /* C1 */ { shift, data1, B , iINVALID }, /* C0 */
{ data2, none2, 0 , iRET }, /* C2 */ { shift, data1, NSP | SRC_B , iINVALID }, /* C1 */
{ none1, none2, NO_OPS , iRET }, /* C3 */ { data2, none2, 0 , iRET }, /* C2 */
{ memOnly, modrm, TO_REG | NSP , iLES }, /* C4 */ { none1, none2, NO_OPS , iRET }, /* C3 */
{ memOnly, modrm, TO_REG | NSP , iLDS }, /* C5 */ { memOnly, modrm, TO_REG | NSP , iLES }, /* C4 */
{ memReg0, data1, B , iMOV }, /* C6 */ { memOnly, modrm, TO_REG | NSP , iLDS }, /* C5 */
{ memReg0, data2, 0 , iMOV }, /* C7 */ { memReg0, data1, B , iMOV }, /* C6 */
{ data2, data1, 0 , iENTER}, /* C8 */ { memReg0, data2, 0 , iMOV }, /* C7 */
{ none1, none2, NO_OPS , iLEAVE}, /* C9 */ { data2, data1, 0 , iENTER}, /* C8 */
{ data2, none2, 0 , iRETF }, /* CA */ { none1, none2, NO_OPS , iLEAVE}, /* C9 */
{ none1, none2, NO_OPS , iRETF }, /* CB */ { data2, none2, 0 , iRETF }, /* CA */
{ const3, none2, NOT_HLL , iINT }, /* CC */ { none1, none2, NO_OPS , iRETF }, /* CB */
{ data1,checkInt, NOT_HLL , iINT }, /* CD */ { const3, none2, NOT_HLL , iINT }, /* CC */
{ none1, none2, NOT_HLL | NO_OPS , iINTO }, /* CE */ { data1,checkInt, NOT_HLL , iINT }, /* CD */
{ none1, none2, NOT_HLL | NO_OPS , iIRET }, /* Cf */ { none1, none2, NOT_HLL | NO_OPS , iINTO }, /* CE */
{ shift, const1, B , iZERO }, /* D0 */ { none1, none2, NOT_HLL | NO_OPS , iIRET }, /* Cf */
{ shift, const1, SRC_B , iZERO }, /* D1 */ { shift, const1, B , iINVALID }, /* D0 */
{ shift, none1, B , iZERO }, /* D2 */ { shift, const1, SRC_B , iINVALID }, /* D1 */
{ shift, none1, SRC_B , iZERO }, /* D3 */ { shift, none1, B , iINVALID }, /* D2 */
{ data1, axImp, NOT_HLL , iAAM }, /* D4 */ { shift, none1, SRC_B , iINVALID }, /* D3 */
{ data1, axImp, NOT_HLL , iAAD }, /* D5 */ { data1, axImp, NOT_HLL , iAAM }, /* D4 */
{ none1, none2, 0 , iZERO }, /* D6 */ { data1, axImp, NOT_HLL , iAAD }, /* D5 */
{ memImp, axImp, NOT_HLL | B| IM_OPS , iXLAT }, /* D7 */ { none1, none2, 0 , iINVALID }, /* D6 */
{ escop, none2, FLOAT_OP , iESC }, /* D8 */ { memImp, axImp, NOT_HLL | B| IM_OPS , iXLAT }, /* D7 */
{ escop, none2, FLOAT_OP , iESC }, /* D9 */ { escop, none2, FLOAT_OP , iESC }, /* D8 */
{ escop, none2, FLOAT_OP , iESC }, /* DA */ { escop, none2, FLOAT_OP , iESC }, /* D9 */
{ escop, none2, FLOAT_OP , iESC }, /* DB */ { escop, none2, FLOAT_OP , iESC }, /* DA */
{ escop, none2, FLOAT_OP , iESC }, /* DC */ { escop, none2, FLOAT_OP , iESC }, /* DB */
{ escop, none2, FLOAT_OP , iESC }, /* DD */ { escop, none2, FLOAT_OP , iESC }, /* DC */
{ escop, none2, FLOAT_OP , iESC }, /* DE */ { escop, none2, FLOAT_OP , iESC }, /* DD */
{ escop, none2, FLOAT_OP , iESC }, /* Df */ { escop, none2, FLOAT_OP , iESC }, /* DE */
{ dispS, none2, 0 , iLOOPNE}, /* E0 */ { escop, none2, FLOAT_OP , iESC }, /* Df */
{ dispS, none2, 0 , iLOOPE}, /* E1 */ { dispS, none2, 0 , iLOOPNE}, /* E0 */
{ dispS, none2, 0 , iLOOP }, /* E2 */ { dispS, none2, 0 , iLOOPE}, /* E1 */
{ dispS, none2, 0 , iJCXZ }, /* E3 */ { dispS, none2, 0 , iLOOP }, /* E2 */
{ data1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* E4 */ { dispS, none2, 0 , iJCXZ }, /* E3 */
{ data1, axImp, NOT_HLL | NO_SRC , iIN }, /* E5 */ { data1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* E4 */
{ data1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* E6 */ { data1, axImp, NOT_HLL | NO_SRC , iIN }, /* E5 */
{ data1, axImp, NOT_HLL | NO_SRC , iOUT }, /* E7 */ { data1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* E6 */
{ dispN, none2, 0 , iCALL }, /* E8 */ { data1, axImp, NOT_HLL | NO_SRC , iOUT }, /* E7 */
{ dispN, none2, 0 , iJMP }, /* E9 */ { dispN, none2, 0 , iCALL }, /* E8 */
{ dispF, none2, 0 , iJMPF }, /* EA */ { dispN, none2, 0 , iJMP }, /* E9 */
{ dispS, none2, 0 , iJMP }, /* EB */ { dispF, none2, 0 , iJMPF }, /* EA */
{ none1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* EC */ { dispS, none2, 0 , iJMP }, /* EB */
{ none1, axImp, NOT_HLL | NO_SRC , iIN }, /* ED */ { none1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* EC */
{ none1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* EE */ { none1, axImp, NOT_HLL | NO_SRC , iIN }, /* ED */
{ none1, axImp, NOT_HLL | NO_SRC , iOUT }, /* EF */ { none1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* EE */
{ none1, none2, NOT_HLL | NO_OPS , iLOCK }, /* F0 */ { none1, axImp, NOT_HLL | NO_SRC , iOUT }, /* EF */
{ none1, none2, 0 , iZERO }, /* F1 */ { none1, none2, NOT_HLL | NO_OPS , iLOCK }, /* F0 */
{ prefix, none2, 0 , iREPNE}, /* F2 */ { none1, none2, 0 , iINVALID }, /* F1 */
{ prefix, none2, 0 , iREPE }, /* F3 */ { prefix, none2, 0 , iREPNE}, /* F2 */
{ none1, none2, NOT_HLL | NO_OPS , iHLT }, /* F4 */ { prefix, none2, 0 , iREPE }, /* F3 */
{ none1, none2, NO_OPS , iCMC }, /* F5 */ { none1, none2, NOT_HLL | NO_OPS , iHLT }, /* F4 */
{ arith, none1, B , iZERO }, /* F6 */ { none1, none2, NO_OPS , iCMC }, /* F5 */
{ arith, none1, NSP , iZERO }, /* F7 */ { arith, none1, B , iINVALID }, /* F6 */
{ none1, none2, NO_OPS , iCLC }, /* F8 */ { arith, none1, NSP , iINVALID }, /* F7 */
{ none1, none2, NO_OPS , iSTC }, /* F9 */ { none1, none2, NO_OPS , iCLC }, /* F8 */
{ none1, none2, NOT_HLL | NO_OPS , iCLI }, /* FA */ { none1, none2, NO_OPS , iSTC }, /* F9 */
{ none1, none2, NOT_HLL | NO_OPS , iSTI }, /* FB */ { none1, none2, NOT_HLL | NO_OPS , iCLI }, /* FA */
{ none1, none2, NO_OPS , iCLD }, /* FC */ { none1, none2, NOT_HLL | NO_OPS , iSTI }, /* FB */
{ none1, none2, NO_OPS , iSTD }, /* FD */ { none1, none2, NO_OPS , iCLD }, /* FC */
{ trans, none1, B , iZERO }, /* FE */ { none1, none2, NO_OPS , iSTD }, /* FD */
{ trans, none1, NSP , iZERO } /* FF */ { trans, none1, B , iINVALID }, /* FE */
{ trans, none1, NSP , iINVALID } /* FF */
} ; } ;
static uint16_t SegPrefix, RepPrefix; static uint16_t SegPrefix, RepPrefix;
static const uint8_t *pInst; /* Ptr. to current uint8_t of instruction */ static const uint8_t *pInst; /* Ptr. to current uint8_t of instruction */
static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */ static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */
static void decodeBranchTgt(x86_insn_t &insn) static void decodeBranchTgt(x86_insn_t &insn)
@ -338,7 +337,7 @@ static void decodeBranchTgt(x86_insn_t &insn)
pIcode->ll()->replaceSrc((uint32_t)addr); pIcode->ll()->replaceSrc((uint32_t)addr);
pIcode->ll()->setFlags(I); pIcode->ll()->setFlags(I);
// PROG &prog(Project::get()->prog); // PROG &prog(Project::get()->prog);
// long off = (short)getWord(); /* Signed displacement */ // long off = (short)getWord(); /* Signed displacement */
// assert(addr==(uint32_t)(off + (unsigned)(pInst - prog.image()))); // assert(addr==(uint32_t)(off + (unsigned)(pInst - prog.image())));
} }
@ -538,7 +537,7 @@ eErrorId scan(uint32_t ip, ICODE &p)
int op; int op;
p = ICODE(); p = ICODE();
p.type = LOW_LEVEL_ICODE; p.type = LOW_LEVEL_ICODE;
p.ll()->label = ip; /* ip is absolute offset into image*/ p.ll()->label = ip; /* ip is absolute offset into image*/
if (ip >= (uint32_t)prog.cbImage) if (ip >= (uint32_t)prog.cbImage)
{ {
return (IP_OUT_OF_RANGE); return (IP_OUT_OF_RANGE);
@ -557,13 +556,13 @@ eErrorId scan(uint32_t ip, ICODE &p)
do do
{ {
op = *pInst++; /* First state - trivial */ op = *pInst++; /* First state - trivial */
/* Convert to Icode.opcode */ /* Convert to Icode.opcode */
p.ll()->set(stateTable[op].opcode,stateTable[op].flg & ICODEMASK); p.ll()->set(stateTable[op].opcode,stateTable[op].flg & ICODEMASK);
(*stateTable[op].state1)(op); /* Second state */ (*stateTable[op].state1)(op); /* Second state */
(*stateTable[op].state2)(op); /* Third state */ (*stateTable[op].state2)(op); /* Third state */
} while (stateTable[op].state1 == prefix); /* Loop if prefix */ } while (stateTable[op].state1 == prefix); /* Loop if prefix */
if(p.insn.group == x86_insn_t::insn_controlflow) if(p.insn.group == x86_insn_t::insn_controlflow)
{ {
if(p.insn.x86_get_branch_target()) if(p.insn.x86_get_branch_target())
@ -571,7 +570,7 @@ eErrorId scan(uint32_t ip, ICODE &p)
} }
// LLOperand conv = convertOperand(*p.insn.get_dest()); // LLOperand conv = convertOperand(*p.insn.get_dest());
// assert(conv==p.ll()->dst); // assert(conv==p.ll()->dst);
if (p.ll()->getOpcode()) if (p.ll()->getOpcode()!=iINVALID)
{ {
/* Save bytes of image used */ /* Save bytes of image used */
p.ll()->numBytes = (uint8_t)((pInst - prog.image()) - ip); p.ll()->numBytes = (uint8_t)((pInst - prog.image()) - ip);
@ -591,8 +590,8 @@ eErrorId scan(uint32_t ip, ICODE &p)
static bool relocItem(const uint8_t *p) static bool relocItem(const uint8_t *p)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
int i; int i;
uint32_t off = p - prog.image(); uint32_t off = p - prog.image();
for (i = 0; i < prog.cReloc; i++) for (i = 0; i < prog.cReloc; i++)
if (prog.relocTable[i] == off) if (prog.relocTable[i] == off)
@ -623,9 +622,9 @@ static int signex(uint8_t b)
/**************************************************************************** /****************************************************************************
* setAddress - Updates the source or destination field for the current * setAddress - Updates the source or destination field for the current
* icode, based on fdst and the TO_REG flag. * icode, based on fdst and the TO_REG flag.
* Note: fdst == true is for the r/m part of the field (dest, unless TO_REG) * Note: fdst == true is for the r/m part of the field (dest, unless TO_REG)
* fdst == false is for reg part of the field * fdst == false is for reg part of the field
***************************************************************************/ ***************************************************************************/
static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off) static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
{ {
@ -635,19 +634,19 @@ static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off
/* Set segment. A later procedure (lookupAddr in proclist.c) will /* Set segment. A later procedure (lookupAddr in proclist.c) will
* provide the value of this segment in the field segValue. * provide the value of this segment in the field segValue.
*/ */
if (seg) /* segment override */ if (seg) /* segment override */
{ {
pm->seg = pm->segOver = (eReg)seg; pm->seg = pm->segOver = (eReg)seg;
} }
else else
{ /* no override, check indexed register */ { /* no override, check indexed register */
if ((reg >= INDEX_BX_SI) and (reg == INDEX_BP_SI or reg == INDEX_BP_DI or reg == INDEX_BP)) if ((reg >= INDEX_BX_SI) and (reg == INDEX_BP_SI or reg == INDEX_BP_DI or reg == INDEX_BP))
{ {
pm->seg = rSS; /* indexed on bp */ pm->seg = rSS; /* indexed on bp */
} }
else else
{ {
pm->seg = rDS; /* any other indexed reg */ pm->seg = rDS; /* any other indexed reg */
} }
} }
@ -658,7 +657,7 @@ static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off
pm->regi = Machine_X86::subRegL(pm->regi); pm->regi = Machine_X86::subRegL(pm->regi);
} }
if (seg) /* So we can catch invalid use of segment overrides */ if (seg) /* So we can catch invalid use of segment overrides */
{ {
SegPrefix = 0; SegPrefix = 0;
} }
@ -674,7 +673,7 @@ static void rm(int i)
uint8_t rm = *pInst++ & 7; uint8_t rm = *pInst++ & 7;
switch (mod) { switch (mod) {
case 0: /* No disp unless rm == 6 */ case 0: /* No disp unless rm == 6 */
if (rm == 6) { if (rm == 6) {
setAddress(i, true, SegPrefix, 0, getWord()); setAddress(i, true, SegPrefix, 0, getWord());
pIcode->ll()->setFlags(WORD_OFF); pIcode->ll()->setFlags(WORD_OFF);
@ -683,16 +682,16 @@ static void rm(int i)
setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, 0); setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, 0);
break; break;
case 1: /* 1 uint8_t disp */ case 1: /* 1 uint8_t disp */
setAddress(i, true, SegPrefix, rm+INDEX_BX_SI, (uint16_t)signex(*pInst++)); setAddress(i, true, SegPrefix, rm+INDEX_BX_SI, (uint16_t)signex(*pInst++));
break; break;
case 2: /* 2 uint8_t disp */ case 2: /* 2 uint8_t disp */
setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, getWord()); setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, getWord());
pIcode->ll()->setFlags(WORD_OFF); pIcode->ll()->setFlags(WORD_OFF);
break; break;
case 3: /* reg */ case 3: /* reg */
setAddress(i, true, 0, rm + rAX, 0); setAddress(i, true, 0, rm + rAX, 0);
break; break;
} }
@ -718,7 +717,7 @@ static void modrm(int i)
****************************************************************************/ ****************************************************************************/
static void segrm(int i) static void segrm(int i)
{ {
int reg = REG(*pInst) + rES; int reg = REG(*pInst) + rES;
if (reg > rDS or (reg == rCS and (stateTable[i].flg & TO_REG))) if (reg > rDS or (reg == rCS and (stateTable[i].flg & TO_REG)))
pIcode->ll()->setOpcode((llIcode)0); // setCBW because it has that index pIcode->ll()->setOpcode((llIcode)0); // setCBW because it has that index
@ -787,7 +786,7 @@ static void memImp(int i)
static void memOnly(int ) static void memOnly(int )
{ {
if ((*pInst & 0xC0) == 0xC0) if ((*pInst & 0xC0) == 0xC0)
pIcode->ll()->setOpcode((llIcode)0); pIcode->ll()->setOpcode(iINVALID);
} }
@ -797,7 +796,7 @@ static void memOnly(int )
static void memReg0(int i) static void memReg0(int i)
{ {
if (REG(*pInst) or (*pInst & 0xC0) == 0xC0) if (REG(*pInst) or (*pInst & 0xC0) == 0xC0)
pIcode->ll()->setOpcode((llIcode)0); pIcode->ll()->setOpcode(iINVALID);
else else
rm(i); rm(i);
} }
@ -814,7 +813,7 @@ static void immed(int i)
rm(i); rm(i);
if (pIcode->ll()->getOpcode() == iADD or pIcode->ll()->getOpcode() == iSUB) if (pIcode->ll()->getOpcode() == iADD or pIcode->ll()->getOpcode() == iSUB)
pIcode->ll()->clrFlags(NOT_HLL); /* Allow ADD/SUB SP, immed */ pIcode->ll()->clrFlags(NOT_HLL); /* Allow ADD/SUB SP, immed */
} }
@ -826,7 +825,7 @@ static void shift(int i)
static llIcode shiftTable[8] = static llIcode shiftTable[8] =
{ {
(llIcode)iROL, (llIcode)iROR, (llIcode)iRCL, (llIcode)iRCR, (llIcode)iROL, (llIcode)iROR, (llIcode)iRCL, (llIcode)iRCR,
(llIcode)iSHL, (llIcode)iSHR, (llIcode)0, (llIcode)iSAR}; (llIcode)iSHL, (llIcode)iSHR, (llIcode)0, (llIcode)iSAR};
pIcode->ll()->setOpcode(shiftTable[REG(*pInst)]); pIcode->ll()->setOpcode(shiftTable[REG(*pInst)]);
rm(i); rm(i);
@ -841,8 +840,8 @@ static void trans(int i)
{ {
static llIcode transTable[8] = static llIcode transTable[8] =
{ {
(llIcode)iINC, iDEC, (llIcode)iCALL, (llIcode)iCALLF, iINC, iDEC, iCALL, iCALLF,
(llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0 iJMP, iJMPF,iPUSH, (llIcode)0
}; };
LLInst *ll = pIcode->ll(); LLInst *ll = pIcode->ll();
// if(transTable[REG(*pInst)]==iPUSH) { // if(transTable[REG(*pInst)]==iPUSH) {
@ -868,8 +867,8 @@ static void arith(int i)
uint8_t opcode; uint8_t opcode;
static llIcode arithTable[8] = static llIcode arithTable[8] =
{ {
iTEST, (llIcode)0, iNOT, iNEG, iTEST, iINVALID, iNOT, iNEG,
iMUL , iIMUL, iDIV, iIDIV iMUL , iIMUL, iDIV, iIDIV
}; };
opcode = arithTable[REG(*pInst)]; opcode = arithTable[REG(*pInst)];
pIcode->ll()->setOpcode((llIcode)opcode); pIcode->ll()->setOpcode((llIcode)opcode);
@ -884,7 +883,7 @@ static void arith(int i)
else if (not (opcode == iNOT or opcode == iNEG)) else if (not (opcode == iNOT or opcode == iNEG))
{ {
pIcode->ll()->replaceSrc( pIcode->ll()->m_dst ); pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
setAddress(i, true, 0, rAX, 0); /* dst = AX */ setAddress(i, true, 0, rAX, 0); /* dst = AX */
} }
else if (opcode == iNEG or opcode == iNOT) else if (opcode == iNEG or opcode == iNOT)
pIcode->ll()->setFlags(NO_SRC); pIcode->ll()->setFlags(NO_SRC);
@ -919,7 +918,7 @@ static void data2(int )
* but this field is being used as the number of bytes to allocate * but this field is being used as the number of bytes to allocate
* on the stack. The procedure level is stored in the immediate * on the stack. The procedure level is stored in the immediate
* field. There is no source operand; therefore, the flag flg is * field. There is no source operand; therefore, the flag flg is
* set to NO_OPS. */ * set to NO_OPS. */
if (pIcode->ll()->getOpcode() == iENTER) if (pIcode->ll()->getOpcode() == iENTER)
{ {
pIcode->ll()->m_dst.off = getWord(); pIcode->ll()->m_dst.off = getWord();
@ -946,7 +945,7 @@ static void dispN(int )
{ {
//PROG &prog(Project::get()->prog); //PROG &prog(Project::get()->prog);
/*long off = (short)*/getWord(); /* Signed displacement */ /*long off = (short)*/getWord(); /* Signed displacement */
/* Note: the result of the subtraction could be between 32k and 64k, and /* Note: the result of the subtraction could be between 32k and 64k, and
still be positive; it is an offset from prog.Image. So this must be still be positive; it is an offset from prog.Image. So this must be
@ -960,7 +959,7 @@ static void dispN(int )
***************************************************************************/ ***************************************************************************/
static void dispS(int ) static void dispS(int )
{ {
/*long off =*/ signex(*pInst++); /* Signed displacement */ /*long off =*/ signex(*pInst++); /* Signed displacement */
// decodeBranchTgt(); // decodeBranchTgt();
} }
@ -985,7 +984,7 @@ static void dispF(int i)
****************************************************************************/ ****************************************************************************/
static void prefix(int ) static void prefix(int )
{ {
if (pIcode->ll()->getOpcode() == iREPE or pIcode->ll()->getOpcode() == iREPNE) if ((pIcode->ll()->getOpcode() == iREPE) or (pIcode->ll()->getOpcode() == iREPNE))
RepPrefix = pIcode->ll()->getOpcode(); RepPrefix = pIcode->ll()->getOpcode();
else else
SegPrefix = pIcode->ll()->getOpcode(); SegPrefix = pIcode->ll()->getOpcode();
@ -993,8 +992,8 @@ static void prefix(int )
inline void BumpOpcode(LLInst &ll) inline void BumpOpcode(LLInst &ll)
{ {
llIcode ic((llIcode)ll.getOpcode()); llIcode ic(ll.getOpcode());
ic = (llIcode)(((int)ic)+1); // Bump this icode via the int type ic = (llIcode)(((int)ic)+1); // Bump this icode via the int type
ll.setOpcode(ic); ll.setOpcode(ic);
} }

View File

@ -6,11 +6,11 @@
#include "msvc_fixes.h" #include "msvc_fixes.h"
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <malloc.h>
#include <memory.h> #include <memory.h>
#include <string.h> #include <string.h>
#include <algorithm> #include <algorithm>
@ -22,7 +22,7 @@
void saveFile(FILE *fl, const PerfectHash &p_hash, PatternCollector *coll); /* Save the info */ void saveFile(FILE *fl, const PerfectHash &p_hash, PatternCollector *coll); /* Save the info */
int numKeys; /* Number of useful codeview symbols */ static int numKeys; /* Number of useful codeview symbols */
static void printUsage(bool longusage) { static void printUsage(bool longusage) {
@ -59,6 +59,9 @@ int main(int argc, char *argv[])
collector = new TPL_PatternCollector; collector = new TPL_PatternCollector;
} else if(arg2.endsWith(".lib")) { } else if(arg2.endsWith(".lib")) {
collector = new LIB_PatternCollector; collector = new LIB_PatternCollector;
} else {
qCritical() << "Unsupported file type.";
return -1;
} }
if ((srcfile = fopen(argv[1], "rb")) == NULL) if ((srcfile = fopen(argv[1], "rb")) == NULL)
{ {

View File

@ -5,14 +5,13 @@
/* Descended from xansi; thanks Geoff! thanks Glenn! */ /* Descended from xansi; thanks Geoff! thanks Glenn! */
#include "parsehdr.h" #include "parsehdr.h"
#include <malloc.h> /* For debugging */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <algorithm> #include <algorithm>
dword userval; static dword userval;
namespace {
/* the IGNORE byte */ /* the IGNORE byte */
byte slosh; byte slosh;
byte last_slosh; byte last_slosh;
@ -51,7 +50,7 @@ PH_ARG_STRUCT *pArg; /* Pointer to the arguements array */
int numArg; /* How many elements saved so far */ int numArg; /* How many elements saved so far */
int allocArg; /* How many elements allocated so far */ int allocArg; /* How many elements allocated so far */
int headArg; /* Head of the arguements linked list */ int headArg; /* Head of the arguements linked list */
}
// DO Callback // DO Callback
boolT phDoCB(int id, char *data) { boolT phDoCB(int id, char *data) {
/* return callback(hDCX, id, data, userval);*/ /* return callback(hDCX, id, data, userval);*/