em libmon vanished decades ago (or never existed), and also ass appears to have
a different idea of what the em opcodes are to everything else and gets
confused.
This drops 124 bytes from the mandelbrot command (from 15015 to 14891
bytes) but has almost no effect on performance; the command takes
about 144 seconds (in YAZE-AG) both before and after optimizing libfp.
Old .o files stop working if they use floating point. One must
recompile those files. Old files don't call libfp in the correct way,
and may use symbols that I removed from libem. I don't keep old
symbols in libem/flp.s, because a program that pulls both libfp and
flp.s would get "multiply defined" errors in the linker.
I teach mach/i80/ncg/table to use libfp by copying or adapting the
patterns from mach/i86/ncg/table. I did not test all the patterns,
but I did use `ack -mcpm -fp -O4` to compile examples/mandelbrot.c,
then I ran it in the emulator YAZE-AG. It worked, but it was slow.
This library is for software floating point. The i80 back end has
never implemented floating point, and might not be ready for libfp.
This commit only builds libfp without using it.
I edit first/build.lua and plat/build.lua to allow `ack -c.s`, then
use FP.script to edit the assembly code. I edit FP.script so it
writes the edited assembly code to stdout, not to the input file.
Add more page numbers from PowerPC version 2.01. Remove "xnop" not in
2.01, add "mtcr" from 2.01. Add "lwarx" and the other instructions
from Book II. I did not try all the newly added instructions, but
these seem to work: dcbt, dcbtst, icibi, isync, lwarx, stwcx., mftb,
mftbu
In man/powerpc_as.6 (not installed), add a summary of the registers
and addressing modes (like in i386_as.6), describe short forms, update
description of hi16/ha16, add CAVEATS about instructions that some
processors can't run.
Using '-' might fail on platforms like FreeBSD. Commit 50a7031
stopped using '-' in the B compiler and ego. I now stop using '-' in
mcg, because I can now check that mcg still works.
If X < 0, then lowering the addi might cause the code to use the stack
space before allocating it. This is a bug because an asynchronous
signal handler can overwrite the unallocated stack space.
Tests pass if one edits the top build.lua to uncomment "qemuppc" from
both vars.plats and vars.plats_with_tests, and one leaves mcg in
plat/qemuppc/descr.
Add or correct some EM instructions in treebuilder.c:
- "lof", "stf": handle negative offsets in load() and store().
- "cuu": add using IR_FROMUI.
- "lim", "sim": keep an entire word in ".ignmask", to be compatible
with mach/powerpc/libem/trp.s and ncg. We also keep a word in
".ignmask" in ncg for both i386 and m68020.
- "trp": pass trap number in register. See comment in
helper_function_with_arg().
- "sig": push the old value of .trppc on the stack.
- "and ?", "ior ?", "xor ?", "com ?", "cms ?", "set ?", "inn ?":
connect to helper functions in libem.
- "blm", "bls": drop call to memmove() and use new helper ".bls4",
because tests/plat/structcopy_e.c can't call memmove().
- "xor s", "cms s": if s is large, fall back on helper function.
- "rol", "ror": add by decomposing each rotate into 4 IR ops.
- "rck s", "bls s": make fatal unless s is word size.
- "loi": push multiple loads in the correct order.
- "dup s", "exg s": if s is large, fall back on helper.
- "dus": add using new helper ".dus4".
- "lxl", "lxa": follow the static chain, not the dynamic chain.
- "lor 1": materialise the stack before pushing the stack pointer.
- "lor 2", "str 2": make fatal.
- "los", "sts": drop calls to memcpy() and use helpers ".los4" and
and ".sts4", so lang/m2/libm2/LtoUset.e starts working.
- "gto": correctly read descriptor.
Change mach/powerpc/mcg/table:
- ANY.L: add for "asp -8".
- LOAD.L: work around register corruption.
- COMPAREUL.I: add for "cms 8".
In the instruction list, put /* kills xer */ for sraw, srawi, subfic;
and correct the (now unused) "addi." and "lfdu".
Change MACHOPT_F from -m3 to -m2. This changes the code for 15 * i
from
slwi r3,r4,4
subfic r5,r4,0
add r3,r3,r5
to
mulli r3,r4,15
If the sequence "slwi subfic addi" takes 3 cycles and 12 bytes, and
mulli takes 3 cycles and 4 bytes, then mulli is better.
Copy and adapt code from mach/{i386,m68020}/ncg/mach.c to pass the
debugging stabs from EM to assembly. The next tools (as, led, cv)
already know how to put the stabs in the Mach-o executable.
Modify the function prolog/prologue so gdb uses fp, not sp, for N_LSYM
and N_PSYM stabs. Simplify prolog() by reducing differences between
stabs and no stabs, and zero and nonzero framesize. For files without
stabs, the new prolog has the same number of instructions and memory
accesses as the old prolog, and to run at about the same speed on my
PowerPC Mac.
This is enough to see some info for global and local variables in gdb
for Mac OS X. I still can't get a backtrace; gdb gets confused
because EM and ncg don't link 0(sp) to the previous stack frame.
I don't expect `ack -mlinuxppc -g` to work with gdb for Linux, because
we prepend underscores to the symbol table, which is correct for
Mach-o but wrong for ELF.
This simplifies parts of the PowerPC table and causes ncg to better
decide whether to push sp or fp to the real stack, or coerce it to
REG3, or coerce it to REG-REG3, or move it to a regvar. These better
decisions remove extra _mr_ instructions.
The idea comes from mach/powerpc/arm/table, where SP has a property
STACKPOINTER and LB has LOCALBASE. I don't need two properties, so I
make one property SPFP for both registers.
When I wrote fef 8, I forgot to test denormalized numbers. Oops. Now
fix two of my mistakes:
- When checking for zero, `extrwi r6, r3, 22, 12` needs to be
`extrwi r6, r3, 20, 12`. There are only 20 bits to extract.
- After the multiplication by 2**64, I forgot to put the fraction in
[0.5, 1) or (-1, 0.5] by setting IEEE exponent = 1022.
Teach fif 8 about signed zero and NaN.
In ncg/table, change cmf so NaN is not equal to any value, and comment
why ordered comparisons don't work with NaN. Also add cost for
fctwiz, remove extra `uses REG`.
Edit comment in cfu8.s because the conditional branch might be before
or after fctwiz.
With my PowerBook G4, a program that converts values from 1.0 to
4000000.0 runs in about 0.32s with the old .cfu8 and 0.29s with this
shrunken .cfu8
Leave a comment about other ways to implement .cfu8
This reduces code size, because ncg emits too many "addi sp, sp, X"
instructions when unstacking things. Now top lowers "addi sp, sp, X"
by lifting other instructions. This sometimes creates chances to
merge or delete _addi_ instructions. If no such chance is found, the
_addi_ remains uselessly lowered.
Edit ncg/table to remove something that top now does.
Edit ncg/mach.c to remove some spaces after commas. This removes a
whitespace difference between *.s and *.so files, because top removes
the space.