| Age | Commit message (Collapse) | Author | Files | Lines |
|
This guarantees the generated version.h will exist before attempting
to compile any c files that include it.
Several source files include the generated version.h, but not all
declare a proper make dependency.
$ grep -r 'version\.h' *.c
compile-i386.c:#include "version.h"
lib.c:#include "version.h"
options.c:#include "version.h"
This allows a sufficiently parallelized make invocation to encounter
ENOENT.
CC compile-i386.o
compile-i386.c:60:21: fatal error: version.h: No such file or directory
compilation terminated.
Makefile:253: recipe for target 'compile-i386.o' failed
make: *** [compile-i386.o] Error 1
Signed-off-by: Kyle Russell <bkylerussell@gmail.com>
[luc.vanoostenryck@gmail.com: modified so that only version.c depends on version.h]
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The idea being, of course, to be able for some functions to return
a bool, making clear what's their possible returned values.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The used '%Ld' is a non-portable GNU extension (whcih I suppose
predate the standization of '%lld').
Use the standard '%lld' instead.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
'fix-volatile-simplification', 'struct-asm-ops', 'restricted-pointers', 'fix-f2i-casts', 'symaddr-description', 'flush-stdout' and 'diet-simple' into tip
|
|
The compile date isn't very informative for a tool, the version is what really
matters. Additionally using __DATE__ makes the build unreprodicible.
Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
Acked-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Instead of doing it my hand, there is the expression_list_size() API we
can use here.
Signed-off-by: Martin Kepplinger <martink@posteo.de>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
This member seemed to be used for:
- current value of an enum during parsing
- index into the virtual frame
but is currently not used and never set, it's only
displayed in compile-i386 & show_parse (as zero since never
initialized).
Remove it to make struct symbol a bit more light.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
sort_array() locally allocates a list it. Let's free it before returning
in order to avoid memory to leak.
Signed-off-by: Martin Kepplinger <martink@posteo.de>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Some versions of gcc (e.g. v4.8.2) complain about ignoring the return
value of a call to the write(2) system call, since the system header
files have marked its declaration with the warn_unused_result attribute.
In order to suppress the compiler warning, check the return value from
'write' and, if it indicates an error (a negative return value), exit
the process using 'die' to display an error message. Replace a second
call to 'write', which does not provoke a compiler warning, with similar
code for consistency.
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
The old code was relicensed by Novafora Corporation, successor in interest to
Transmeta Corporation, in 2009. Other authors were also asked about the change
of their contributions to the MIT license and all with copyrightable changes
agreed to it.
Signed-off-by: Franz Schrober <franzschrober@yahoo.de>
Acked-by: Adam DiCarlo <adam@bikko.org>
Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
Acked-by: Alberto Bertogli <albertito@blitiri.com.ar>
Acked-by: Alecs King <alecs@perlchina.org>
Acked-by: Alexander Shishkin <alexander.shishckin@gmail.com>
Acked-by: Alexey Dobriyan <adobriyan@gmail.com>
Acked-by: Alexey Zaytsev <alexey.zaytsev@gmail.com>
Acked-by: Andries E. Brouwer <Andries.Brouwer@cwi.nl>
Acked-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Acked-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Acked-by: Ben Pfaff <blp@nicira.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Bernd Petrovitsch <bernd@petrovitsch.priv.at>
Acked-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Acked-by: Blue Swirl <blauwirbel@gmail.com>
Acked-by: Chris Forbes <chrisf@ijw.co.nz>
Acked-by: Chris Wedgwood <cw@f00f.org>
Acked-by: Christopher Li <sparse@chrisli.org>
Acked-by: Damien Lespiau <damien.lespiau@gmail.com>
Acked-by: Dan Carpenter <error27@gmail.com>
Acked-by: Dan McGee <dan@archlinux.org>
Acked-by: Daniel De Graaf <danieldegraaf@gmail.com>
Acked-by: Daniel Sheridan <dan.sheridan@postman.org.uk>
Acked-by: Dave Jones <davej@redhat.com>
Acked-by: David Given <dg@cowlark.com>
Acked-by: David Miller <davem@redhat.com>
Acked-by: David Mosberger-Tang <dmosberger@gmail.com>
Acked-by: David Olien <David.Olien@lsi.com>
Acked-by: Diego Elio Pettenò <flameeyes@flameeyes.eu>
Acked-by: Emil Medve <Emilian.Medve@Freescale.com>
Acked-by: Ethan Jackson <jacksone@nicira.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Frank Zago <fzago@systemfabricworks.com>
Acked-by: Frederic Crozat <fcrozat@suse.com>
Acked-by: Geoff Johnstone <geoff.johnstone@gmail.com>
Acked-by: Hannes Eder <hannes@hanneseder.net>
Acked-by: Jan Pokorný <pokorny_jan@seznam.cz>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Acked-by: Jiri Slaby <jslaby@suse.cz>
Acked-by: Joe Perches <joe@perches.com>
Acked-by: Joel Soete <rubisher@scarlet.be>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Acked-by: Josh Triplett <josh@kernel.org>
Acked-by: Kamil Dudka <kdudka@redhat.com>
Acked-by: Kim Phillips <kim.phillips@linaro.org>
Acked-by: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
Acked-by: Kovarththanan Rajaratnam <kovarththanan.rajaratnam@gmail.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Acked-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Acked-by: Martin Nagy <nagy.martin@gmail.com>
Acked-by: Masatake YAMATO <yamato@redhat.com>
Acked-by: Mauro Dreissig <mukadr@gmail.com>
Acked-by: Michael Büsch <m@bues.ch>
Acked-by: Michael Stefaniuc <mstefani@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Mika Kukkonen <mikukkon@iki.fi>
Acked-by: Mike Frysinger <vapier@gentoo.org>
Acked-by: Mitesh Shah <Mitesh.Shah@synopsys.com>
Acked-by: Morten Welinder <mortenw@gnome.org>
Acked-by: Namhyung Kim <namhyung@gmail.com>
Acked-by: Nicolas Kaiser <nikai@nikai.net>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Pavel Roskin <proski@gnu.org>
Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
Acked-by: Peter Jones <pjones@redhat.com>
Acked-by: Peter A Jonsson <pj@sics.se>
Acked-by: Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
Acked-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Acked-by: Randy Dunlap <rdunlap@xenotime.net>
Acked-by: Reinhard Tartler <siretart@tauware.de>
Ached-by: Richard Knutsson <richard.knutsson@gmail.com>
Acked-by: Rob Taylor <rob.taylor@codethink.co.uk>
Acked-by: Rui Saraiva <rmpsaraiva@gmail.com>
Acked-by: Ryan Anderson <ryan@michonline.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Acked-by: Samuel Bronson <naesten@gmail.com>
Acked-by: Santtu Hyrkkö <santtu.hyrkko@gmail.com>
Acked-by: Shakthi Kannan <shakthimaan@gmail.com>
Acked-by: Stephen Hemminger <shemminger@linux-foundation.org>
Acked-by: Thomas Schmid <Thomas.Schmid@br-automation.com>
Acked-by: Tilman Sauerbeck <tilman@code-monkey.de>
Acked-by: Vegard Nossum <vegardno@ifi.uio.no>
Acked-by: Xi Wang <xi.wang@gmail.com>
Acked-by: Yura Pakhuchiy <pakhuchiy@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
compile-i386 sometimes crashes due a use-after-free error. Since
f->pseudo_list is freed first, which invalidates some atom->op* in
f->atom_list. Further checks like `atom->op1->flags & STOR_WANTS_FREE'
will read garbage, which may lead to a double free.
This patch switches the cleanup order and frees f->atom_list first.
Those marked as STOR_WANTS_FREE won't appear in f->pseudo_list.
Signed-off-by: Xi Wang <xi.wang@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
Reviewed-by: Pekka Enberg <penberg@kernel.org>
|
|
Don't allocate val twice in emit_divide.
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
I've probably encountered a bug within compile-i386.c. It generates
an infinite loop for 'while' statement. My testing example and proposed
patch are enclosed.
Kamil
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Signed-off-by: David Given <dg@cowlark.com>
[negative value division fixed by alexey.zaytsev@gmal.com]
Signed-off-by: Alexey Zaytsev <alexey.zaytsev@gmail.com>
|
|
Turn FORCE_MOD into storage class specifier (that's how it's
actually used and that makes for much simpler logics).
Introduce explicit EXPR_FORCE_CAST for forced casts; handle it
properly.
Kill the idiocy in get_as() (we end up picking the oddest things
for address space - e.g. if we have int __attribute__((address_space(1))) *p,
we'll get warnings about removal of address space when we do things like
(unsigned short)*p. Fixed. BTW, that had caught a bunch of very odd
bogosities in the kernel and eliminated several false positives in there.
As the result, get_as() is gone now and evaluate_cast() got simpler.
Kill the similar idiocy in handling pointer assignments; while we are at it,
fix the qualifiers check for assignments to/from void * (you can't assign
const int * to void * - qualifiers on the left side should be no less than
on the right one; for normal codepath we get that checked, but the special
case of void * skips these checks).
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Expose the FORMAT_ATTR portability macro in lib.h, and use it on the various
printf-like functions in sparse.
Add a new SENTINEL_ATTR portability macro for the GCC sentinel attribute, and
use it on match_idents in parse.c.
match_oplist in expression.c should use SENTINEL_ATTR, but GCC does not accept
an integer 0 as a sentinel, only a pointer 0 like NULL.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
This removes the list of symbols for block statements, and instead makes
a declaration be a statement of its own.
This is necessary to correctly handle the case of mixed statements and
declarations correctly, since the order of declarations and statements
is meaningful.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Start off with
sparse_initialize(argc, argv);
which will return the number of filenames found. You can then use that,
or just check if *argv is NULL in a loop like
while (*argv)
list = sparse(argv);
where you get the declaration list for each file in turn.
|
|
This makes some needlessly global code static so that sparse don't
complain when self checking.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@looxix.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Much prettier than "input_streams[x].name", since most
users really don't want to know about the internals of
how the preprocessor lays out its stream tracking.
|
|
It's disgusting how intimate lib.c is with all the types,
and this is slowly trying to split things up a bit. Now
the intimate part is in allocate.c, but maybe we can get
to the point where each allocation user just declares its
own allocation strategy, and just uses the generic routines
in allocate.c
|
|
untyped "struct ptr_list **", we use properly typed ones.
|
|
I used to think I needed it. That's no longer the case: we just
follow the "bit_offset" in the type information.
There may be cases where we inadvertently cast the information
away, and those places will break now, but that's a bug really,
not an excuse for EXPR_BITFIELD.
|
|
This also makes our evaluation simplification only happen
for the implied ones. If you put an explicit cast somewhere,
it does _not_ get combined with an implied one.
|
|
It's always the same as bit_size now, and having it just confuses
things.
We now check whether we have examined a type by looking at the
"examined" bitfield, which allows us to set bit_size in the early
parsing phase.
|
|
We turn it into a proper (tmp = x, tmp ? tmp : y) at evaluation
time, so later phases never have to worry about the issue. But
some of the old code lingered.
|
|
Use FOR_EACH_PTR() instead, or the much fancier iterators
for basic blocks.
|
|
positional markers be hierarchical rather than a flat list.
This makes the data structure a bit more complex, but it simplifies
some of the code, and makes it possible to evaluate complex initializers
without going insane.
In particular, we how support
struct xxxx var = {
.a.b[10] = 1;
};
which we couldn't handle at all before (it had to
be written as
struct xxxx var = {
.a = {
.b = { [10] = 1; }
}
}
or similar.
The new code changes all array indexes and structure members
to EXPR_POS expressions offset from the "outer" scope (either
start of the symbol, or an outer EXPR_POS).
|
|
|
|
warn->warning
error->error_die
new error
lib.h:
warn->warning
error->error_die
new error
Add gcc format checking to warning/error/...
|
|
..and switch us entirely over to the new naming scheme.
All the nasty work of going through the users thanks to Chris Li.
|
|
Use the existing access macro instead.
|
|
In particular:
- we should only test (and not mark busy) the things a
register aliases when we allocate it. This bug kept
us from using %edx, because when we used %eax, we
bogusly marked the 64-bit combination %eax:%edx as
being busy, and refused to use %edx later.
- "get_reg_value()" should take a regclass, so that we
can allocate a new reg from a valid class.
|
|
into a 16-bit one, and into the "high byte" version.
|
|
|
|
If we are loading something into a register, and another
register has that value already cached, used the cached
register value.
|
|
|
|
This still does just mainly EXPR_SELECT, since that
is what I'm familiar with. It's also extremely lazy
about invalidating register content info, since any
code that hasn't been moved to the new format won't
do things properly.
Very much a work-in-progress, designed to eventually
allow us to generate some kind of half-readable code
from the SSA form.
|
|
Instead of using fixed register names, we keep track of
busy registers, and allocate them as needed.
Also changed EXPR_SELECT to actually use this.
|
|
We don't actually _use_ any of them yet, but this lists them,
and adds the information about which register conflicts with
which register (eg %al conflicts with %eax, but not with %ah)
|
|
code emitter. Don't make the code emission have to know
about symbol lists etc.
Thus the code emitter can do whatever it wants to do to
the symbols as they are encountered, as part of the main loop
rather than as a separate phase afterwards. Straightforward.
|
|
It gets them wrong right now: we can't just use "and" and "or",
we need to convert to canonical logical form (0/1) too.
But it's documentation.
|
|
They are valid now that we have a EXPR_SELECT type for
safe conditionals.
|
|
Make linearize.h show the right ops for the logical (as opposed to
binary) and/or EXPR_BINOP.
|
|
expression.
This is just a very high-level cost, mainly distinguishing
between "safe" and "unsafe" operations, so that we can
determine if we can turn a C conditional into a select
statement, or a logical op into one without short-ciruiting.
|
|
It's the same as a regular C conditional, except you could
evaluate both sides first. Right now we treat it exactly
the same as an EXPR_CONDITIONAL.
|
|
By virtue of attempting to be too smart, the conditional expression
handling ("x ? foo : bar") would evaluate both 'foo' and 'bar', and
then use the cmov instruction to determine the result, avoiding a
branch in the process.
Unfortunately this only makes sense for simple things (EXPR_VALUE,
EXPR_SYMBOL) and is quite wrong for everything else.
Changed so that 'if' statements and conditional expressions use
largely the same code.
|
|
* Mostly revert function call stack frame construction
("correctly generate push* instruction")
* Add comment regarding ABI-dictated function call argument size
* Clamp function call arg size to 32-bit minimum. This will copy
the correct value to the stack at the correct alignment, but
(SECURITY/FIXME) will also copy extra bits (24 bits for an
8-bit value, 16 bits for a 16-bit value).
* Add EXPR_FVALUE to the 'unhandled' portion of the master
emit-expression 'switch' statement.
|
|
Assumptions that values are 32-bit still remain in places, but
some simple test cases involving 8-bit and 16-bit variables
seem much more sane now.
|
|
Pay attention to size of function arguments when pushing them to stack.
Generate "pushb" for char, "pushw" for short, ...
[ Linus' note: this is likely "wrong". In a real x86 compiler, we'd
expand the width of the argument to 32 bits regardless, but from
a demonstration standpoint this is better ]
|
|
We already have a function that adds correct {b,w,l,q} suffix.
|
|
{'b', 'w', 'l', 'q'} instead of {ascii 8, ascii 16, ' ', '@'}
|
|
Quite frankly, anybody who uses assert() should be shot. It's
a fundamentally broken thing.
|
|
simplify_int_binop() was completely broken for comparisons - there the
signedness of (converted) arguments can not be obtained from type of
result. IOW, we had all comparisons in constant expressions done as
signed ones.
Fixed by introducing new primitives for unsigned versions of
comparions (SPECIAL_UNSIGNED_LT, etc.) and remapping in evaluate_compare()
once we know the types. That also fixes similar mess in compile-i386 and
linearize.
|
|
This teaches sparse what __alignof__ really means, instead of just using
the same code as "__sizeof__"
It gets rid of the warnings in ebtables that does:
struct ebt_entries {
...
char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)));
};
Which caused warning because sparse was evaluating __alignof__ as the same as sizeof,
and sizeof was 57 (ie non-power of 2).
This is just based on the existing code and a peek at the data
structures in expression and symbol.
|
|
Shown by running sparse on itself.
|
|
This actually showed a bug ("assignment in conditional")
in evaluate.c.
|
|
rename them lower cased to match standard C naming rules.
|
|
comparisons etc:
if (typeof(a) == int) {
...
(although right now I don't actually do the proper comparison
expansion and all comparisons return "true").
|
|
They were only used for the original pre-instruction
linearization.
|
|
|
|
This lets us get the type of comparison right.
|
|
This required making the inter-BB trampoline to be done
using indirection through a symbol, rather than as direct
pointers from one BB to another. Fix up code to match.
Avoid a few warnings by handling GOTO_BB in the case
statements.
|
|
|
|
|
|
We were using the output of show_ident() without remembering
that that function uses static storage.
|
|
|
|
The loop generator should be correct now; all that remains is to
actually generate the jumps based on the loop label info we now
store in the "loop stack".
|
|
The thing that remains is getting 'break' and 'continue' assigned
to the correct jump targets.
|
|
|
|
This doesn't actually get them _right_, but as long as they
end up being constant when used, we at least silently ignore
them until then.
|
|
Instead of assuming that all stack objects were 4 bytes in size,
we now properly account for both stack variables (sym->bit_size / 8)
and compiler temporaries (fixed 32 bits).
Function new_pseudo() became stack_alloc(), which takes a number of
bytes to allocate on the stack.
|
|
More properly describe what the variable represents, and also
prepare for upcoming stack allocation improvements.
|
|
Also create helpers for emitted labels (emit_label),
labels based on symbol pointer values (emit_labelsym),
and creating various struct storage types (new_val, new_labelsym).
Use these new helpers where appropriate.
|
|
|
|
rather than as multiple flags in struct atom. This allows us to
eliminate the final arg passed to {insn, emit_move, stor_op_name}.
Also, fix two memory leaks noticed during the cleanup.
|
|
Now, we just assume it's the ABI size (32 bits) rather than
care about the distinction between what we want to return up the
parse tree stack (possibly not 32 bits), and what the ABI gives
us (32 bits).
Also, add new file validation/test-be.c, to house a growing
collection of basic sanity checks I can run, to help avoid
regressions.
|
|
|
|
|
|
* properly emit '!', '~', '-'
* handle operand size in inc/dec
* simplify EXPR_ACCESS test in x86_address_gen()
|
|
|
|
|
|
* remove bogus "toplevel symbol" check I put in. Needs reworking.
* Don't emit subl/addl %esp stack frame adjustments, if no
stack frame exists.
|
|
toplevel STMT_COMPOUND.
If a function returns a value, then the C code must have explicit
'return' statements. Since we already emit a move when handling
return statements, that eliminates the need to ever emit a move for
the non-'return' case.
Of course, incorrect C code can still omit the return statement, in
which case you're left with a random %eax return value.
|
|
|
|
we don't have to.
|
|
Still needs some work.
|
|
smarter val storage.
* fix segfault in emit_symbol_expr_init. we don't yet properly
reference toplevel variables. workaround, print out "FIXME!" and
create a new pseudo.
* directly inline constants, instead of assigning them stack slots
as pseudos.
* properly emit cast expressions; quite easy with my type-aware
emit_move function. alas, since we assume values will fit into
a machine register, emit_move is [known-]broken for 64-bit ints.
* make asm comments in pseudo-pseudo copy prettier
|
|
func call return values.
|
|
Suggested by Arjan van de Ven.
|
|
|
|
* rename emit_move() to emit_copy() (it copies stack slotX -> slotY)
* create a size- and sign-aware emit_move()
* create opbits(), to help determine instruction suffix
based on memory operand
* update emit_compare() to be operand sign- and size-aware
* update emit_compare() to use SETcc instead of CMOVcc.
(suggested by Arjan van de Ven)
|
|
* fix comparison order. was using Intel not AT&T order of operands.
* replace nested-if tree of string comparisons with a switch
on expr->op value.
|
|
And remove code warning people it's wrong, as it should no longer be.
|
|
instead of char* arguments. This uses the previously-added
'atom' instructure. It also necessitates adding new struct storage
types: STOR_REG (machine register), STOR_VALUE (constant),
and STOR_LABEL (label / jump target).
Updated all insn() callers to provide struct storage arguments.
|
|
text buffers, update code to use a ptr_list of "atoms". Atoms
basically correspond to a single line of assembly. There are
ATOM_TEXT atoms for ASCII text (the only kind of atom currently
in use) and ATOM_INSN for instructions.
|
|
|
|
Here's what I have so far.
Comments welcome. It cannot be considered anywhere near complete, but
it acts like it generates x86 asm for a bunch of small test cases anyway :)
It started out as show-parse.c. The emit_xxx stuff is what I have
converted from show-parse pseudo-code into x86 code generation. The
x86_xxx stuff is the stuff that remains. FIXMEs abound.
I haven't actually tried to assmble anything yet. Just studying what
gcc generates, and then what I generate.
A few random notes in closing:
* function-at-a-time
* just does one subl and one addl for stack manipulation, which implies
that it has to output everything from post-function cleanup pass
(emit_func_post).
* however, x86_xxx stuff (not yet converted) will still print out
pseudocode. So your output will look like
function header
psuedocode (i.e. stuff not yet handled)
real x86 code
If you don't see any pseudocode... you may actually be lucky enough to
be able to compile your asm ;-)
|