This patch adds LirWriter.insSkip(), LIns.overwriteWithSkip(),
and LirReader.peek()
I extracted the insSkip() changes from bug 545406 so I could use insSkip() and
overwriteWithSkip(). LirReader.read() uses its own size array because of
the special case for LIR_start, but other cases use a shared insSizes[]
array.
I added LirReader.peek() so that when erasing an instruction during a LirReader
iteration, I can find the skipTo instruction to use. It is the next one that
will be read.
--HG--
extra : convert_revision : 3c560f9f45413de8c5ed10cab4584a8c1b1e4e3f
Adds LIR_callv for calls to helper functions that return void.
Added a ValidateWriter check that LIR_callv to be paired with ARGTYPE_V,
plus checks for the other obvious pairings, plus a check that callv must
not call a _pure=1 function.
getCallOpcode() returns LIR_callv for ARGTYPE_V, as expected. This means that
some calls will return LTy_V from LIns::retType(), as expected, but unlike
before. This in turn can cause a ValidateWriter error if an instruction uses
the result of a void call. (after all, that's the point).
Each backend was modified to not assign a register or save the result of a void
call.
--HG--
extra : convert_revision : f1076b3fa633922ce95c24ac622934be4815376d
Changed all the register iteration loops to use lsbSet/msbSet functions
that use fast find-first-bit intrinsics when available. Typical loops of
the form:
for (Register r = FirstReg; r <= LastReg; r = nextReg(r))
if (predicate(r))
/* use r */
were transformed by replacing the per-iteration predicate with a single
mask calculation, then iterating through only the 1 bits in the mask:
RegisterMask set = /* calculate predicate with bitmask ops */;
for (Register r = lsReg(set); set; r = lsNextReg(set))
/* use r */
Iteration can be low-to-hi with lsReg/lsNextReg, or hi-to-low with msReg/msNextReg.
Primitives are provided for 32 and 64-bit masks. PPC and MIPS need a 64-bit
mask, for example, even on 32-bit systems.
Refactoring details:
I renamed msbSet() to msbSet32() as part of adding [msb|lsb]Set[32|64], which
affected the AccSet code trivially.
I used if (sizeof(RegisterMask) == 4) to choose between 32 and 64bit
implementations, counting on a sane compiler to strip out the provably dead
path. An alternative would be to move the definitions of lsReg() and msReg() to
NativeXXX.h, after the RegisterMask typedef, allowing backends to hardcode the
choice. Given we have six backends and one more on the way, it seemed better
to centralize the code and also avoid more ifdefs.
I moved the definitions of msbSet/lsbSet to nanojit.h, where other such helpers
already live. It didn't seem appropriate to keep adding to LIR.h since the
helpers will now be used in several places in nanojit.
RegAlloc::managed is now set in Assembler.cpp instead of each backend; six
lines of code replaced by one.
prevreg() was dead after these changes. Additionally, I hand-inlined nextreg()
in the other backends, because the usage was highly specialized -- those call
sites depended on nextreg being reg+1, (or reg+2) not some generic iteration.
I removed RegAlloc::countActive() since the only case was testing countActive()
== 0, which is equivalent to activeMask() == 0.
--HG--
extra : convert_revision : c7009f5cd83ea028b98f59e1f8830a76ba27c1dd
Patch to add 'j' (branch) variants of the exit-on-overflow instructions,
plus a few dependents:
32-bit:
LIR_addjovi
LIR_subjovi
LIR_muljovi
64-bit:
LIR_subq
LIR_addjovq
LIR_subjovq
--HG--
extra : convert_revision : 68023362b0833433a0bc0c3b5af8994894488f33