2016-10-02 18:58:05 +00:00
|
|
|
# plat/osxppc/descr
|
|
|
|
|
|
|
|
var w=4
|
|
|
|
var wa=4
|
|
|
|
var p={w}
|
|
|
|
var pa={w}
|
|
|
|
var s=2
|
|
|
|
var sa={s}
|
|
|
|
var l={w}
|
|
|
|
var la={w}
|
|
|
|
var f={w}
|
|
|
|
var fa={w}
|
|
|
|
var d=8
|
|
|
|
var da={d}
|
|
|
|
var x=8
|
|
|
|
var xa={x}
|
|
|
|
var ARCH=powerpc
|
|
|
|
var PLATFORM=osxppc
|
|
|
|
var PLATFORMDIR={EM}/share/ack/{PLATFORM}
|
|
|
|
var CPP_F=-D__unix
|
2016-11-22 22:16:30 +00:00
|
|
|
var ALIGN=-a0:4 -a1:4 -a2:4096 -a3:4 -b0:0x129c
|
Enable top and make other tweaks in plat/osxppc/descr
David Given made top for PowerPC. Copy the asopt phase (running top)
from linuxppc to osxppc.
Remove CC_ALIGN=-Vr to become compatible with Apple's gcc. Apple uses
left adjustment for bitfields; the first bitfield is on the left side
(the big end), not the right side.
Remove unused variables C_LIB and OLD_C_LIB; the file libc-ansi.a
doesn't exist.
Change MACHOPT_F from -m10 to -m3. This means to use no more than 3
adds and shifts to optimize a multiply by a constant. I pick -m3
because -m4 can use too many instructions. At -m4, the compiler
rewrites
n * 14
as
s = n << 1
(s << 3) + (0 - s)
This means (n * 16 - n * 2), but even at ack -O6, the compiler doesn't
rewrite (a + (0 - b)) as (a - b). The compiler emits 5 instructions:
2 of rlinmw for 2 left shifts, then addi to load 0 in a register, subf
to subtract from that 0, then add. These 5 instructions cost 5 cycles
on the MPC7450, using the cycle counts from mach/powerpc/ncg/table.
At -m3, (n * 14) becomes 2 instructions: addi to load 14 in a register
and mullw to multiply. This also costs 5 cycles (because mullw costs
4 cycles), but uses less space.
2016-11-29 01:58:51 +00:00
|
|
|
var MACHOPT_F=-m3
|
Write a powerpc.descr for ego and use it with osxppc.
No change to linuxppc and qemuppc. They continue to run ego without
any descr file.
I copied m68020.descr to powerpc.descr and changed some numbers. My
numbers are guesses; I know little about PowerPC cycle counts, and
almost nothing about ego. This powerpc.descr causes most of the
example programs to shrink in size (without descr -> with descr):
65429 -> 57237 hilo_b.osxppc -8192
36516 -> 32420 hilo_c.osxppc -4096
55782 -> 51686 hilo_mod.osxppc -4096
20096 -> 20096 hilo_p.osxppc 0
8813 -> 8813 mandelbrot_c.osxppc 0
93355 -> 89259 paranoia_c.osxppc -4096
92751 -> 84559 startrek_c.osxppc -8192
(Each file has 2 Mach segments, then a symbol table. Each segment
takes a multiple of 4096 bytes. When the code shrinks, we lose a
multiple of 4096 bytes.)
I used "ack -mosxppc -O6 -c.so" to examine the assembly code for
hilo.mod and mandelbrot.c, both without and with descr. This reveals
optimizations made only with descr, from 2 ego phases: SP (stack
pollution) and RA (register allocation). In hilo.mod, SP deletes some
instructions that remove items from the stack. These items get
removed when the function returns. In both hilo.mod and mandelbrot.c,
RA moves some values into local variables, so ncg can make them into
register variables. This shrinks code size, probably because register
variables get preserved across function calls. More values stay in
registers, and ncg emits shorter code.
I believe that the ego descr file uses (time,space) tuples but the ncg
table uses (space,time) tuples. This is confusing. Perhaps I am
wrong, and some or all tuples are backwards. My time values are the
cycle counts in latency from the MPC7450 Reference Manual (but not
including complications like "store serialization").
In powerpc.descr, I give the cost for saving and restoring registers
as if I was using chains of stw and lwz instructions. Actually ncg
uses single stmw and lmw instructions with at least 2 instructions.
The (time,space) for stmw and lmw would be much less than the
(time,space) for chains of stw and lwz. But this ignores the pipeline
of the MPC7450. The chains of stw and lwz may run faster than stmw
and lmw in the pipeline, because the throughput may be better than the
latency. By using the wrong values for (time,space), I'm trying to
tell ego that stmw and lmw are not better than chains of stw and lwz.
2016-11-30 20:29:19 +00:00
|
|
|
var EGO_PLAT_FLAGS=-M{EM}/share/ack/ego/{ARCH}.descr
|
2016-10-02 18:58:05 +00:00
|
|
|
|
|
|
|
# Override the setting in fe so that files compiled for osxppc can see
|
|
|
|
# the platform-specific headers.
|
|
|
|
|
2016-11-08 22:13:51 +00:00
|
|
|
var C_INCLUDES=-I{EM}/share/ack/osx/include -I{EM}/share/ack/include/ansi
|
2016-10-02 18:58:05 +00:00
|
|
|
|
|
|
|
name be
|
|
|
|
from .m.g
|
|
|
|
to .s
|
|
|
|
program {EM}/lib/ack/linuxppc/ncg
|
|
|
|
mapflag -gdb GF=-gdb
|
|
|
|
args {GF?} <
|
|
|
|
stdout
|
|
|
|
need .e
|
|
|
|
end
|
Enable top and make other tweaks in plat/osxppc/descr
David Given made top for PowerPC. Copy the asopt phase (running top)
from linuxppc to osxppc.
Remove CC_ALIGN=-Vr to become compatible with Apple's gcc. Apple uses
left adjustment for bitfields; the first bitfield is on the left side
(the big end), not the right side.
Remove unused variables C_LIB and OLD_C_LIB; the file libc-ansi.a
doesn't exist.
Change MACHOPT_F from -m10 to -m3. This means to use no more than 3
adds and shifts to optimize a multiply by a constant. I pick -m3
because -m4 can use too many instructions. At -m4, the compiler
rewrites
n * 14
as
s = n << 1
(s << 3) + (0 - s)
This means (n * 16 - n * 2), but even at ack -O6, the compiler doesn't
rewrite (a + (0 - b)) as (a - b). The compiler emits 5 instructions:
2 of rlinmw for 2 left shifts, then addi to load 0 in a register, subf
to subtract from that 0, then add. These 5 instructions cost 5 cycles
on the MPC7450, using the cycle counts from mach/powerpc/ncg/table.
At -m3, (n * 14) becomes 2 instructions: addi to load 14 in a register
and mullw to multiply. This also costs 5 cycles (because mullw costs
4 cycles), but uses less space.
2016-11-29 01:58:51 +00:00
|
|
|
name asopt
|
|
|
|
from .s
|
|
|
|
to .so
|
|
|
|
program {EM}/lib/ack/linuxppc/top
|
|
|
|
args
|
|
|
|
optimizer
|
|
|
|
stdin
|
|
|
|
stdout
|
|
|
|
end
|
2016-10-02 18:58:05 +00:00
|
|
|
name as
|
|
|
|
from .s.so
|
|
|
|
to .o
|
|
|
|
program {EM}/lib/ack/linuxppc/as
|
|
|
|
args - -o > <
|
|
|
|
prep cond
|
|
|
|
end
|
|
|
|
name led
|
|
|
|
from .o.a
|
|
|
|
to .out
|
|
|
|
program {EM}/lib/ack/em_led
|
|
|
|
mapflag -l* LNAME={PLATFORMDIR}/lib*
|
|
|
|
mapflag -fp FLOATS={EM}/{LIB}fp
|
|
|
|
args {ALIGN} {SEPID?} \
|
|
|
|
(.e:{HEAD}={PLATFORMDIR}/boot.o) \
|
|
|
|
({RTS}:.ocm.b={PLATFORMDIR}/c-ansi.o) \
|
|
|
|
({RTS}:.c={PLATFORMDIR}/c-ansi.o) \
|
|
|
|
({RTS}:.mod={PLATFORMDIR}/modula2.o) \
|
|
|
|
({RTS}:.p={PLATFORMDIR}/pascal.o) \
|
|
|
|
-o > < \
|
|
|
|
(.p:{TAIL}={PLATFORMDIR}/libpascal.a) \
|
|
|
|
(.b:{TAIL}={PLATFORMDIR}/libbasic.a) \
|
|
|
|
(.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \
|
|
|
|
(.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \
|
|
|
|
(.ocm.b.mod.c.p:{TAIL}={PLATFORMDIR}/libc.a) \
|
|
|
|
{FLOATS?} \
|
|
|
|
(.e:{TAIL}={PLATFORMDIR}/libem.a \
|
|
|
|
{PLATFORMDIR}/libsys.a \
|
|
|
|
{PLATFORMDIR}/libend.a)
|
|
|
|
linker
|
|
|
|
end
|
|
|
|
name cv
|
|
|
|
from .out
|
|
|
|
to .exe
|
|
|
|
program {EM}/lib/ack/cvmach
|
|
|
|
args -m18 < >
|
|
|
|
outfile osxppc.exe
|
|
|
|
end
|