Compare commits
11 Commits
experiment
...
qt5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b58f315c98 | ||
|
|
7687c2b7d2 | ||
|
|
0abbce6f4e | ||
|
|
8ffdf657ec | ||
|
|
2232a76033 | ||
|
|
d6af9c1555 | ||
|
|
d7acc8cd4d | ||
|
|
a5f1d17e83 | ||
|
|
29efcd5be1 | ||
|
|
4656db9484 | ||
|
|
b33d7239e5 |
339
LICENSE
Normal file
339
LICENSE
Normal 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.
|
||||||
@ -6,6 +6,8 @@ To reflect those fixes, I've edited the original readme a bit.
|
|||||||
dcc Distribution
|
dcc Distribution
|
||||||
================
|
================
|
||||||
|
|
||||||
|
[](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)
|
||||||
|
|||||||
@ -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 */
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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 */
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
487
src/ast.cpp
487
src/ast.cpp
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
245
src/control.cpp
245
src/control.cpp
@ -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 */
|
||||||
|
|||||||
235
src/dataflow.cpp
235
src/dataflow.cpp
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
163
src/locident.cpp
163
src/locident.cpp
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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))
|
||||||
{
|
{
|
||||||
|
|||||||
601
src/scanner.cpp
601
src/scanner.cpp
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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);*/
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user