We weren't properly handling the case where a 64-bit value is
multipled with itself in multiplyRR, leading to wrong code. Also,
addCarryCR didn't know how to handle constants more than 8-bits wide.
Previously, loading an arbitrary 32-bit constant required up to four
instructions (128 bytes), since we did so one byte at a time via
immediate-mode operations.
The preferred way to load constants on ARM is via PC-relative
addressing, but this is challenging because immediate memory offsets
are limited to 4096 bytes in either direction. We frequently need to
compile methods which are larger than 4096, or even 8192, bytes, so we
must intersperse code and data if we want to use PC-relative loads
everywhere.
This commit enables pervasive PC-relative loads by handling the
following cases:
1. Method is shorter than 4096 bytes: append data table to end
2. Method is longer than 4096 bytes, but no basic block is longer
than 4096 bytes: insert data tables as necessary after blocks, taking
care to minimize the total number of tables
3. Method is longer than 4096 bytes, and some blocks are longer than
4096 bytes: split large basic blocks and insert data tables as above
We need to prefix instructions of the form "mov R,M" with a REX byte
when R is %spl, %bpl, %sil, or %dil. Such moves are unencodable on
32-bit x86, and, because of the order in which we pick registers,
pretty rare on 64-bit systems, which is why this took so long to
notice.
This allows the assembler to see the operand types of the comparison
and the condition for jumping in the same operation, which is
essential for generating efficient code in cases such as
multiple-precision compare-and-branch.
We now use SingleRead::successor in pickTarget, where we use it to
determine the prefered target site for the successor without requiring
the target to conform to that preference. The previous code made the
preference a hard requirement, which is not desirable or even possible
in general.
The SingleRead::successor field is used (when non-null) to further
constrain the SiteMask in SingleRead::intersect based on reads of
successor values (as in the cases of moves and condensed-addressing
combine and translate instructions).