From 8d7ceb6d6ccc4f503db9ff65babc6be102799692 Mon Sep 17 00:00:00 2001 From: cvs2hg Date: Wed, 26 Aug 1987 13:58:31 +0000 Subject: [PATCH] fixup commit for tag 'distr2' --- Makefile | 35 -- bin/em.pascal | 1 + doc/i80.doc | 118 +++--- doc/ncg.doc | 372 +++++++++--------- first/local.h.src | 2 +- h/out.h | 120 ------ h/ranlib.h | 25 -- lib/6805/descr | 29 -- lib/descr/ibm.nosid | 40 -- lib/descr/m68k2.macs | 39 -- lib/descr/nascom | 30 -- lib/descr/net86 | 32 -- lib/descr/sat86 | 34 -- mach/6500/as/Makefile | 53 --- mach/6800/as/Makefile | 53 --- mach/6805/as/Makefile | 53 --- mach/6809/as/Makefile | 53 --- mach/arm/as/Makefile | 53 --- mach/i386/as/Makefile | 53 --- mach/i80/as/Makefile | 53 --- mach/i80/libem/LIST | 1 - mach/i80/libem/flp.s | 33 -- mach/i80/ncg/table | 104 +---- mach/i86/as/Makefile | 53 --- mach/m68020/as/Makefile | 53 --- mach/m68k2/as/Makefile | 53 --- mach/m68k2/cg/mach.c | 135 +++---- mach/m68k2/cg/table | 391 +++---------------- mach/m68k2/dl/dl.c | 106 ------ mach/m68k2/libsys/times.s | 2 +- mach/m68k4/libsys/LIST | 12 - mach/ns/as/Makefile | 53 --- mach/pdp/as/Makefile | 53 --- mach/pdp/cg/peep.c | 135 ------- mach/pdp/libpc/makefile | 21 - mach/proto/as/Makefile | 53 --- mach/proto/as/comm0.h | 252 ------------ mach/proto/as/comm1.h | 122 ------ mach/proto/as/comm2.y | 424 --------------------- mach/proto/as/comm3.c | 50 --- mach/proto/as/comm4.c | 539 -------------------------- mach/proto/as/comm5.c | 528 ------------------------- mach/proto/as/comm6.c | 362 ------------------ mach/proto/as/comm7.c | 430 --------------------- mach/proto/as/comm8.c | 9 - mach/proto/cg/regvar.c | 4 + mach/proto/cg/types.h | 9 +- mach/proto/ncg/codegen.c | 5 +- mach/proto/ncg/move.c | 4 - mach/proto/ncg/subr.c | 91 ++--- mach/proto/ncg/types.h | 4 + mach/s2650/as/Makefile | 53 --- mach/vax4/as/Makefile | 53 --- mach/z80/as/Makefile | 53 --- mach/z80/libmon/putchr.nas.s | 28 -- mach/z80/libmon/putchr.s | 21 - mach/z80/libmon/subr.s | 197 ---------- mach/z80/libsys/putchr.nas.s | 28 -- mach/z80/libsys/putchr.s | 21 - mach/z80/libsys/subr.s | 197 ---------- mach/z8000/as/Makefile | 53 --- util/ack/.distr | 23 -- util/ack/pc/.distr | 2 - util/amisc/Makefile | 19 - util/amisc/anm.c | 310 --------------- util/amisc/asize.c | 106 ------ util/amisc/astrip.c | 213 ----------- util/cgg/bootgram.y | 2 +- util/ego/bo/Makefile | 60 --- util/ego/bo/bo.c | 318 ---------------- util/ego/ca/Makefile | 65 ---- util/ego/ca/ca.c | 271 ------------- util/ego/ca/ca.h | 15 - util/ego/ca/ca_put.c | 413 -------------------- util/ego/ca/ca_put.h | 9 - util/ego/cf/Makefile | 82 ---- util/ego/cf/cf.c | 520 ------------------------- util/ego/cf/cf.h | 16 - util/ego/cf/cf_idom.c | 138 ------- util/ego/cf/cf_idom.h | 15 - util/ego/cf/cf_loop.c | 400 ------------------- util/ego/cf/cf_loop.h | 14 - util/ego/cf/cf_succ.c | 250 ------------ util/ego/cf/cf_succ.h | 10 - util/ego/cj/Makefile | 60 --- util/ego/cj/cj.c | 355 ----------------- util/ego/cs/Makefile | 178 --------- util/ego/cs/cs.c | 78 ---- util/ego/cs/cs.h | 123 ------ util/ego/cs/cs_alloc.c | 44 --- util/ego/cs/cs_alloc.h | 24 -- util/ego/cs/cs_aux.c | 64 ---- util/ego/cs/cs_aux.h | 25 -- util/ego/cs/cs_avail.c | 203 ---------- util/ego/cs/cs_avail.h | 18 - util/ego/cs/cs_debug.c | 156 -------- util/ego/cs/cs_debug.h | 33 -- util/ego/cs/cs_elim.c | 283 -------------- util/ego/cs/cs_elim.h | 5 - util/ego/cs/cs_entity.c | 142 ------- util/ego/cs/cs_entity.h | 15 - util/ego/cs/cs_getent.c | 219 ----------- util/ego/cs/cs_getent.h | 8 - util/ego/cs/cs_kill.c | 372 ------------------ util/ego/cs/cs_kill.h | 24 -- util/ego/cs/cs_partit.c | 371 ------------------ util/ego/cs/cs_partit.h | 55 --- util/ego/cs/cs_profit.c | 207 ---------- util/ego/cs/cs_profit.h | 10 - util/ego/cs/cs_stack.c | 132 ------- util/ego/cs/cs_stack.h | 18 - util/ego/cs/cs_vnm.c | 321 ---------------- util/ego/cs/cs_vnm.h | 4 - util/ego/descr/descr.sed | 22 -- util/ego/descr/i86.descr | 15 - util/ego/descr/m68k2.descr | 103 ----- util/ego/descr/makedescrs | 5 - util/ego/descr/pdp.descr | 96 ----- util/ego/descr/vax2.descr | 117 ------ util/ego/descr/vax4.descr | 114 ------ util/ego/em_ego/em_ego | 68 ---- util/ego/ic/Makefile | 100 ----- util/ego/ic/ic.c | 520 ------------------------- util/ego/ic/ic.h | 70 ---- util/ego/ic/ic_aux.c | 459 ---------------------- util/ego/ic/ic_aux.h | 39 -- util/ego/ic/ic_io.c | 204 ---------- util/ego/ic/ic_io.h | 34 -- util/ego/ic/ic_lib.c | 274 ------------- util/ego/ic/ic_lib.h | 14 - util/ego/ic/ic_lookup.c | 414 -------------------- util/ego/ic/ic_lookup.h | 71 ---- util/ego/il/Makefile | 160 -------- util/ego/il/il.c | 312 --------------- util/ego/il/il.h | 161 -------- util/ego/il/il1_anal.c | 177 --------- util/ego/il/il1_anal.h | 17 - util/ego/il/il1_aux.c | 208 ---------- util/ego/il/il1_aux.h | 38 -- util/ego/il/il1_cal.c | 138 ------- util/ego/il/il1_cal.h | 31 -- util/ego/il/il1_formal.c | 141 ------- util/ego/il/il1_formal.h | 11 - util/ego/il/il2_aux.c | 720 ----------------------------------- util/ego/il/il2_aux.h | 38 -- util/ego/il/il3_aux.c | 63 --- util/ego/il/il3_aux.h | 15 - util/ego/il/il3_change.c | 584 ---------------------------- util/ego/il/il3_change.h | 41 -- util/ego/il/il3_subst.c | 122 ------ util/ego/il/il3_subst.h | 17 - util/ego/il/il_aux.c | 383 ------------------- util/ego/il/il_aux.h | 53 --- util/ego/lv/Makefile | 66 ---- util/ego/lv/lv.c | 588 ---------------------------- util/ego/lv/lv.h | 42 -- util/ego/ra/Makefile | 176 --------- util/ego/ra/itemtab.src | 21 - util/ego/ra/makeitems.c | 77 ---- util/ego/ra/ra.c | 548 -------------------------- util/ego/ra/ra.h | 136 ------- util/ego/ra/ra_allocl.c | 376 ------------------ util/ego/ra/ra_allocl.h | 19 - util/ego/ra/ra_aux.c | 40 -- util/ego/ra/ra_aux.h | 24 -- util/ego/ra/ra_interv.c | 228 ----------- util/ego/ra/ra_interv.h | 35 -- util/ego/ra/ra_items.c | 346 ----------------- util/ego/ra/ra_items.h | 31 -- util/ego/ra/ra_lifet.c | 74 ---- util/ego/ra/ra_lifet.h | 12 - util/ego/ra/ra_pack.c | 416 -------------------- util/ego/ra/ra_pack.h | 11 - util/ego/ra/ra_profits.c | 235 ------------ util/ego/ra/ra_profits.h | 11 - util/ego/ra/ra_xform.c | 565 --------------------------- util/ego/ra/ra_xform.h | 24 -- util/ego/share/Makefile | 264 ------------- util/ego/share/alloc.c | 237 ------------ util/ego/share/alloc.h | 54 --- util/ego/share/aux.c | 246 ------------ util/ego/share/aux.h | 66 ---- util/ego/share/cldefs.src | 69 ---- util/ego/share/cset.c | 277 -------------- util/ego/share/cset.h | 21 - util/ego/share/debug.c | 145 ------- util/ego/share/debug.h | 56 --- util/ego/share/def.h | 14 - util/ego/share/files.c | 17 - util/ego/share/files.h | 33 -- util/ego/share/get.c | 548 -------------------------- util/ego/share/get.h | 53 --- util/ego/share/global.c | 21 - util/ego/share/global.h | 51 --- util/ego/share/go.c | 152 -------- util/ego/share/go.h | 34 -- util/ego/share/init_glob.c | 57 --- util/ego/share/init_glob.h | 10 - util/ego/share/locals.c | 242 ------------ util/ego/share/locals.h | 39 -- util/ego/share/lset.c | 208 ---------- util/ego/share/lset.h | 16 - util/ego/share/makecldef.c | 83 ---- util/ego/share/makedepend | 11 - util/ego/share/makewlen.c | 4 - util/ego/share/map.c | 21 - util/ego/share/map.h | 38 -- util/ego/share/parser.c | 282 -------------- util/ego/share/parser.h | 13 - util/ego/share/pop_push.awk | 15 - util/ego/share/put.c | 437 --------------------- util/ego/share/put.h | 40 -- util/ego/share/show.c | 414 -------------------- util/ego/share/stack_chg.c | 104 ----- util/ego/share/stack_chg.h | 10 - util/ego/share/types.h | 414 -------------------- util/ego/sp/Makefile | 65 ---- util/ego/sp/sp.c | 240 ------------ util/ego/sr/Makefile | 131 ------- util/ego/sr/sr.c | 205 ---------- util/ego/sr/sr.h | 72 ---- util/ego/sr/sr_aux.c | 115 ------ util/ego/sr/sr_aux.h | 20 - util/ego/sr/sr_cand.c | 187 --------- util/ego/sr/sr_cand.h | 14 - util/ego/sr/sr_expr.c | 199 ---------- util/ego/sr/sr_expr.h | 13 - util/ego/sr/sr_iv.c | 183 --------- util/ego/sr/sr_iv.h | 7 - util/ego/sr/sr_reduce.c | 626 ------------------------------ util/ego/sr/sr_reduce.h | 5 - util/ego/sr/sr_xform.c | 178 --------- util/ego/sr/sr_xform.h | 19 - util/ego/ud/Makefile | 122 ------ util/ego/ud/ud.c | 557 --------------------------- util/ego/ud/ud.h | 21 - util/ego/ud/ud_aux.c | 55 --- util/ego/ud/ud_aux.h | 17 - util/ego/ud/ud_const.c | 246 ------------ util/ego/ud/ud_const.h | 24 -- util/ego/ud/ud_copy.c | 390 ------------------- util/ego/ud/ud_copy.h | 41 -- util/ego/ud/ud_defs.c | 378 ------------------ util/ego/ud/ud_defs.h | 51 --- util/ego/ud/ud_locals.h | 18 - util/led/Makefile | 142 ------- util/led/archive.c | 178 --------- util/led/assert.h | 18 - util/led/byte_order.c | 90 ----- util/led/const.h | 26 -- util/led/debug.h | 11 - util/led/defs.h | 10 - util/led/error.c | 71 ---- util/led/extract.c | 234 ------------ util/led/finish.c | 182 --------- util/led/mach.c | 24 -- util/led/main.c | 554 --------------------------- util/led/memory.c | 459 ---------------------- util/led/memory.h | 35 -- util/led/orig.h | 6 - util/led/output.c | 80 ---- util/led/read.c | 134 ------- util/led/relocate.c | 256 ------------- util/led/save.c | 104 ----- util/led/scan.c | 524 ------------------------- util/led/scan.h | 13 - util/led/sym.c | 132 ------- util/led/write.c | 297 --------------- 268 files changed, 445 insertions(+), 35281 deletions(-) delete mode 100644 Makefile create mode 100755 bin/em.pascal delete mode 100644 h/out.h delete mode 100644 h/ranlib.h delete mode 100644 lib/6805/descr delete mode 100644 lib/descr/ibm.nosid delete mode 100644 lib/descr/m68k2.macs delete mode 100644 lib/descr/nascom delete mode 100644 lib/descr/net86 delete mode 100644 lib/descr/sat86 delete mode 100644 mach/6500/as/Makefile delete mode 100644 mach/6800/as/Makefile delete mode 100644 mach/6805/as/Makefile delete mode 100644 mach/6809/as/Makefile delete mode 100644 mach/arm/as/Makefile delete mode 100644 mach/i386/as/Makefile delete mode 100644 mach/i80/as/Makefile delete mode 100644 mach/i80/libem/flp.s delete mode 100644 mach/i86/as/Makefile delete mode 100644 mach/m68020/as/Makefile delete mode 100644 mach/m68k2/as/Makefile delete mode 100644 mach/m68k2/dl/dl.c delete mode 100644 mach/ns/as/Makefile delete mode 100644 mach/pdp/as/Makefile delete mode 100644 mach/pdp/cg/peep.c delete mode 100644 mach/pdp/libpc/makefile delete mode 100644 mach/proto/as/Makefile delete mode 100644 mach/proto/as/comm0.h delete mode 100644 mach/proto/as/comm1.h delete mode 100644 mach/proto/as/comm2.y delete mode 100644 mach/proto/as/comm3.c delete mode 100644 mach/proto/as/comm4.c delete mode 100644 mach/proto/as/comm5.c delete mode 100644 mach/proto/as/comm6.c delete mode 100644 mach/proto/as/comm7.c delete mode 100644 mach/proto/as/comm8.c delete mode 100644 mach/s2650/as/Makefile delete mode 100644 mach/vax4/as/Makefile delete mode 100644 mach/z80/as/Makefile delete mode 100644 mach/z80/libmon/putchr.nas.s delete mode 100644 mach/z80/libmon/putchr.s delete mode 100644 mach/z80/libmon/subr.s delete mode 100644 mach/z80/libsys/putchr.nas.s delete mode 100644 mach/z80/libsys/putchr.s delete mode 100644 mach/z80/libsys/subr.s delete mode 100644 mach/z8000/as/Makefile delete mode 100644 util/ack/.distr delete mode 100644 util/ack/pc/.distr delete mode 100644 util/amisc/Makefile delete mode 100644 util/amisc/anm.c delete mode 100644 util/amisc/asize.c delete mode 100644 util/amisc/astrip.c delete mode 100644 util/ego/bo/Makefile delete mode 100644 util/ego/bo/bo.c delete mode 100644 util/ego/ca/Makefile delete mode 100644 util/ego/ca/ca.c delete mode 100644 util/ego/ca/ca.h delete mode 100644 util/ego/ca/ca_put.c delete mode 100644 util/ego/ca/ca_put.h delete mode 100644 util/ego/cf/Makefile delete mode 100644 util/ego/cf/cf.c delete mode 100644 util/ego/cf/cf.h delete mode 100644 util/ego/cf/cf_idom.c delete mode 100644 util/ego/cf/cf_idom.h delete mode 100644 util/ego/cf/cf_loop.c delete mode 100644 util/ego/cf/cf_loop.h delete mode 100644 util/ego/cf/cf_succ.c delete mode 100644 util/ego/cf/cf_succ.h delete mode 100644 util/ego/cj/Makefile delete mode 100644 util/ego/cj/cj.c delete mode 100644 util/ego/cs/Makefile delete mode 100644 util/ego/cs/cs.c delete mode 100644 util/ego/cs/cs.h delete mode 100644 util/ego/cs/cs_alloc.c delete mode 100644 util/ego/cs/cs_alloc.h delete mode 100644 util/ego/cs/cs_aux.c delete mode 100644 util/ego/cs/cs_aux.h delete mode 100644 util/ego/cs/cs_avail.c delete mode 100644 util/ego/cs/cs_avail.h delete mode 100644 util/ego/cs/cs_debug.c delete mode 100644 util/ego/cs/cs_debug.h delete mode 100644 util/ego/cs/cs_elim.c delete mode 100644 util/ego/cs/cs_elim.h delete mode 100644 util/ego/cs/cs_entity.c delete mode 100644 util/ego/cs/cs_entity.h delete mode 100644 util/ego/cs/cs_getent.c delete mode 100644 util/ego/cs/cs_getent.h delete mode 100644 util/ego/cs/cs_kill.c delete mode 100644 util/ego/cs/cs_kill.h delete mode 100644 util/ego/cs/cs_partit.c delete mode 100644 util/ego/cs/cs_partit.h delete mode 100644 util/ego/cs/cs_profit.c delete mode 100644 util/ego/cs/cs_profit.h delete mode 100644 util/ego/cs/cs_stack.c delete mode 100644 util/ego/cs/cs_stack.h delete mode 100644 util/ego/cs/cs_vnm.c delete mode 100644 util/ego/cs/cs_vnm.h delete mode 100644 util/ego/descr/descr.sed delete mode 100644 util/ego/descr/i86.descr delete mode 100644 util/ego/descr/m68k2.descr delete mode 100755 util/ego/descr/makedescrs delete mode 100644 util/ego/descr/pdp.descr delete mode 100644 util/ego/descr/vax2.descr delete mode 100644 util/ego/descr/vax4.descr delete mode 100755 util/ego/em_ego/em_ego delete mode 100644 util/ego/ic/Makefile delete mode 100644 util/ego/ic/ic.c delete mode 100644 util/ego/ic/ic.h delete mode 100644 util/ego/ic/ic_aux.c delete mode 100644 util/ego/ic/ic_aux.h delete mode 100644 util/ego/ic/ic_io.c delete mode 100644 util/ego/ic/ic_io.h delete mode 100644 util/ego/ic/ic_lib.c delete mode 100644 util/ego/ic/ic_lib.h delete mode 100644 util/ego/ic/ic_lookup.c delete mode 100644 util/ego/ic/ic_lookup.h delete mode 100644 util/ego/il/Makefile delete mode 100644 util/ego/il/il.c delete mode 100644 util/ego/il/il.h delete mode 100644 util/ego/il/il1_anal.c delete mode 100644 util/ego/il/il1_anal.h delete mode 100644 util/ego/il/il1_aux.c delete mode 100644 util/ego/il/il1_aux.h delete mode 100644 util/ego/il/il1_cal.c delete mode 100644 util/ego/il/il1_cal.h delete mode 100644 util/ego/il/il1_formal.c delete mode 100644 util/ego/il/il1_formal.h delete mode 100644 util/ego/il/il2_aux.c delete mode 100644 util/ego/il/il2_aux.h delete mode 100644 util/ego/il/il3_aux.c delete mode 100644 util/ego/il/il3_aux.h delete mode 100644 util/ego/il/il3_change.c delete mode 100644 util/ego/il/il3_change.h delete mode 100644 util/ego/il/il3_subst.c delete mode 100644 util/ego/il/il3_subst.h delete mode 100644 util/ego/il/il_aux.c delete mode 100644 util/ego/il/il_aux.h delete mode 100644 util/ego/lv/Makefile delete mode 100644 util/ego/lv/lv.c delete mode 100644 util/ego/lv/lv.h delete mode 100644 util/ego/ra/Makefile delete mode 100644 util/ego/ra/itemtab.src delete mode 100644 util/ego/ra/makeitems.c delete mode 100644 util/ego/ra/ra.c delete mode 100644 util/ego/ra/ra.h delete mode 100644 util/ego/ra/ra_allocl.c delete mode 100644 util/ego/ra/ra_allocl.h delete mode 100644 util/ego/ra/ra_aux.c delete mode 100644 util/ego/ra/ra_aux.h delete mode 100644 util/ego/ra/ra_interv.c delete mode 100644 util/ego/ra/ra_interv.h delete mode 100644 util/ego/ra/ra_items.c delete mode 100644 util/ego/ra/ra_items.h delete mode 100644 util/ego/ra/ra_lifet.c delete mode 100644 util/ego/ra/ra_lifet.h delete mode 100644 util/ego/ra/ra_pack.c delete mode 100644 util/ego/ra/ra_pack.h delete mode 100644 util/ego/ra/ra_profits.c delete mode 100644 util/ego/ra/ra_profits.h delete mode 100644 util/ego/ra/ra_xform.c delete mode 100644 util/ego/ra/ra_xform.h delete mode 100644 util/ego/share/Makefile delete mode 100644 util/ego/share/alloc.c delete mode 100644 util/ego/share/alloc.h delete mode 100644 util/ego/share/aux.c delete mode 100644 util/ego/share/aux.h delete mode 100644 util/ego/share/cldefs.src delete mode 100644 util/ego/share/cset.c delete mode 100644 util/ego/share/cset.h delete mode 100644 util/ego/share/debug.c delete mode 100644 util/ego/share/debug.h delete mode 100644 util/ego/share/def.h delete mode 100644 util/ego/share/files.c delete mode 100644 util/ego/share/files.h delete mode 100644 util/ego/share/get.c delete mode 100644 util/ego/share/get.h delete mode 100644 util/ego/share/global.c delete mode 100644 util/ego/share/global.h delete mode 100644 util/ego/share/go.c delete mode 100644 util/ego/share/go.h delete mode 100644 util/ego/share/init_glob.c delete mode 100644 util/ego/share/init_glob.h delete mode 100644 util/ego/share/locals.c delete mode 100644 util/ego/share/locals.h delete mode 100644 util/ego/share/lset.c delete mode 100644 util/ego/share/lset.h delete mode 100644 util/ego/share/makecldef.c delete mode 100755 util/ego/share/makedepend delete mode 100644 util/ego/share/makewlen.c delete mode 100644 util/ego/share/map.c delete mode 100644 util/ego/share/map.h delete mode 100644 util/ego/share/parser.c delete mode 100644 util/ego/share/parser.h delete mode 100644 util/ego/share/pop_push.awk delete mode 100644 util/ego/share/put.c delete mode 100644 util/ego/share/put.h delete mode 100644 util/ego/share/show.c delete mode 100644 util/ego/share/stack_chg.c delete mode 100644 util/ego/share/stack_chg.h delete mode 100644 util/ego/share/types.h delete mode 100644 util/ego/sp/Makefile delete mode 100644 util/ego/sp/sp.c delete mode 100644 util/ego/sr/Makefile delete mode 100644 util/ego/sr/sr.c delete mode 100644 util/ego/sr/sr.h delete mode 100644 util/ego/sr/sr_aux.c delete mode 100644 util/ego/sr/sr_aux.h delete mode 100644 util/ego/sr/sr_cand.c delete mode 100644 util/ego/sr/sr_cand.h delete mode 100644 util/ego/sr/sr_expr.c delete mode 100644 util/ego/sr/sr_expr.h delete mode 100644 util/ego/sr/sr_iv.c delete mode 100644 util/ego/sr/sr_iv.h delete mode 100644 util/ego/sr/sr_reduce.c delete mode 100644 util/ego/sr/sr_reduce.h delete mode 100644 util/ego/sr/sr_xform.c delete mode 100644 util/ego/sr/sr_xform.h delete mode 100644 util/ego/ud/Makefile delete mode 100644 util/ego/ud/ud.c delete mode 100644 util/ego/ud/ud.h delete mode 100644 util/ego/ud/ud_aux.c delete mode 100644 util/ego/ud/ud_aux.h delete mode 100644 util/ego/ud/ud_const.c delete mode 100644 util/ego/ud/ud_const.h delete mode 100644 util/ego/ud/ud_copy.c delete mode 100644 util/ego/ud/ud_copy.h delete mode 100644 util/ego/ud/ud_defs.c delete mode 100644 util/ego/ud/ud_defs.h delete mode 100644 util/ego/ud/ud_locals.h delete mode 100644 util/led/Makefile delete mode 100644 util/led/archive.c delete mode 100644 util/led/assert.h delete mode 100644 util/led/byte_order.c delete mode 100644 util/led/const.h delete mode 100644 util/led/debug.h delete mode 100644 util/led/defs.h delete mode 100644 util/led/error.c delete mode 100644 util/led/extract.c delete mode 100644 util/led/finish.c delete mode 100644 util/led/mach.c delete mode 100644 util/led/main.c delete mode 100644 util/led/memory.c delete mode 100644 util/led/memory.h delete mode 100644 util/led/orig.h delete mode 100644 util/led/output.c delete mode 100644 util/led/read.c delete mode 100644 util/led/relocate.c delete mode 100644 util/led/save.c delete mode 100644 util/led/scan.c delete mode 100644 util/led/scan.h delete mode 100644 util/led/sym.c delete mode 100644 util/led/write.c diff --git a/Makefile b/Makefile deleted file mode 100644 index bf4572b29..000000000 --- a/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -cmp: # compile everything and compare - (cd etc ; make cmp ) - (cd util ; make cmp ) - (cd lang ; make cmp ) - (cd mach ; make cmp ) - -install: # compile everything to machine code - (cd etc ; make install ) - (cd util ; make install ) - (cd lang/cem ; make install ) - (cd mach ; make install ) - (cd lang/pc ; make install ) - -clean: # remove all non-sources, except boot-files - (cd doc ; make clean ) - (cd man ; make clean ) - (cd h ; make clean ) - (cd etc ; make clean ) - (cd util ; make clean ) - (cd lang ; make clean ) - (cd mach ; make clean ) - -opr: # print all sources - make pr | opr - -pr: # print all sources - @( pr Makefile ; \ - (cd doc ; make pr ) ; \ - (cd man ; make pr ) ; \ - (cd h ; make pr ) ; \ - (cd etc ; make pr ) ; \ - (cd lang ; make pr ) ; \ - (cd util ; make pr ) ; \ - (cd mach ; make pr ) \ - ) diff --git a/bin/em.pascal b/bin/em.pascal new file mode 100755 index 000000000..c77dc1e7b --- /dev/null +++ b/bin/em.pascal @@ -0,0 +1 @@ +exec /usr/em/doc/em.doc/int/em /usr/em/doc/em.doc/int/tables ${1-e.out} core diff --git a/doc/i80.doc b/doc/i80.doc index 52bbbfe02..232e5aec8 100644 --- a/doc/i80.doc +++ b/doc/i80.doc @@ -1,3 +1,4 @@ +." $Header$ .RP .TL Back end table for the Intel 8080 micro-processor @@ -96,11 +97,15 @@ The 8080 microprocessor provides five flip-flops used as condition flags .br The sign bit S is set (cleared) by certain instructions when the most significant bit of the result of an operation equals one (zero). +.br The zero bit Z is set (cleared) by certain operations when the 8-bit result of an operation equals (does not equal) zero. +.br The parity bit P is set (cleared) if the 8-bit result of an operation includes an even (odd) number of ones. +.br C is the normal carry bit. +.br AC is an auxiliary carry that indicates whether there has been a carry out of bit 3 of the accumulator. This auxiliary carry is used only by the DAA instruction, which @@ -125,12 +130,14 @@ of register-pair HL. .NH 3 Register addressing .PP -With each instruction using register addressing, + +With each intruction using register addressing, only one register is specified (except for the MOV instruction), although in many of them the accumulator is implied as second operand. Examples are CMP E, which compares register E with the accumulator, and DCR B, which decrements register B. +.br A few instructions deal with 16 bit register-pairs: examples are DCX B, which decrements register-pair BC and the PUSH and POP instructions. @@ -166,7 +173,7 @@ The high order byte is stored at the highest address. THE 8080 BACK END TABLE .PP The back end table is designed as described in [5]. -For an overall design of a back end table I refer to this document. +So for an overall design of a back end table I refer to this document. .br This section deals with problems encountered in writing the 8080 back-end table. @@ -178,30 +185,30 @@ Constant definitions Word size (EM_WSIZE) and pointer size (EM_PSIZE) are both defined as two bytes. The hole between AB and LB (EM_BSIZE) is four bytes: only the -return address and the local base are saved. +return address and the localbase are saved. .NH 2 Registers and their properties .PP All properties have the default size of two bytes, because one-byte registers also cover two bytes when put on the real stack. .sp 1 -The next considerations led to the choice of register-pair BC -as local base. -Though saving the local base in memory would leave one more register-pair +The next considerations led to the choise of register-pair BC +as localbase. +Though saving the localbase in memory would leave one more register-pair available as scratch register, it would slow down instructions as 'lol' and 'stl' too much. -So a register-pair should be sacrificed as local base. +So a register-pair should be sacrificed as localbase. Because a back-end without a free register-pair HL is completely -broken-winged, the only reasonable choices are BC and DE. -Though the choice between them might seem arbitrary at first sight, +broken-winged, the only reasonable choises are BC and DE. +Though the choise between them might seem arbitrary at first sight, there is a difference between register-pairs BC and DE: the instruction XCHG exchanges the contents of register-pairs DE and HL. When DE and HL are both heavily used on the fake-stack, this instruction -is very useful. -Since it won't be useful too often to exchange HL with the local base +is very usefull. +Since it won't be usefull too often to exchange HL with the localbase and since an instruction exchanging BC and HL does not exist, BC is -chosen as local base. +chosen as localbase. .sp 1 Many of the register properties are never mentioned in the PATTERNS part of the table. @@ -212,7 +219,7 @@ The properties really used in the PATTERNS part are: the accumulator only .IP reg: any of the registers A, D, E, H or L. Of course the registers B and C which are -used as local base don't possess this property. +used as localbase don't possess this property. When there is a single register on the fake-stack, its value is always considered non-negative. .IP dereg: @@ -221,12 +228,12 @@ register-pair DE only register-pair HL only .IP hl_or_de: register-pairs HL and DE both have this property -.IP local base: +.IP localbase: used only once (i.e. in the EM-instruction 'str 0') .PP .sp 1 The stackpointer SP and the processor status word PSW have to be -defined explicitly because they are needed in some instructions +defined explicitely because they are needed in some instructions (i.e. SP in LXI, DCX and INX and PSW in PUSH and POP). .br It doesn't matter that the processor status word is not just register A @@ -245,6 +252,7 @@ Compared with many other back-end tables, there are only a small number of different tokens (four). Reasons are the limited addressing modes of the 8080 microprocessor, no index registers etc. +.br For example to translate the EM-instruction .DS lol 10 @@ -252,15 +260,16 @@ lol 10 the next 8080 instructions are generated: .DS L LXI H,10 /* load registers pair HL with value 10 */ -DAD B /* add local base (BC) to HL */ +DAD B /* add localbase (BC) to HL */ MOV E,M /* load E with byte pointed to by HL */ INX H /* increment HL */ MOV D,M /* load D with next byte */ .DE -Of course, instead of emitting code immediately, it could be postponed +Of course, instead of emitting code immmediately, it could be postponed by placing something like a {LOCAL,10} on the fake-stack, but some day the above mentioned code will have to be generated, so a LOCAL-token is -hardly useful. +hardly usefull. +.br See also the comment on the load instructions. .NH 2 Sets @@ -286,13 +295,13 @@ In fact it usually takes 3 extra time periods when this register indirect mode is used instead of register mode, but since the costs are not completely orthogonal this results in small deficiencies for the DCR, INR and MOV instructions. -Although it is not particularly useful these deficiencies are +Although it is not particularly usefull these deficiencies are corrected in the INSTRUCTIONS part, by treating the register indirect -mode separately. +mode seperately. .sp 1 The costs of the conditional call and return instructions really depend on whether or not the call resp. return is actually made. -However, this is not important to the behaviour of the back end. +Unimportant. .sp 1 Instructions not used in this table have been commented out. Of course many of them are used in the library routines. @@ -307,7 +316,7 @@ The TESTS section is only included to refrain .B cgg from complaining. .NH 2 -Stacking rules +Stackingrules .PP When, for example, the token {const2,10} has to be stacked while no free register-pair is available, the next code is generated: @@ -332,11 +341,12 @@ this instruction in fact exchanges the contents of these register-pairs. Before the coercion is carried out other appearances of DE and HL on the fake-stack will be moved to the real stack, because in -the INSTRUCTION-part is told that XCHG destroys the contents +the INSTRUCTION-part is told that XCHG destroyes the contents of both DE and HL. +.br The coercion transposing one register-pair to another one by emitting two MOV-instructions, will be used only if -one of the register-pairs is the local base. +one of the register-pairs is the localbase. .NH 2 Patterns .PP @@ -351,7 +361,7 @@ gen lhld {label,$1} yields hl .DE the 'uses'-clause could have been omitted because .B cgg -knows that LHLD destroys register-pair HL. +knows that LHLD destroyes register-pair HL. .sp 1 Since there is only one register with property 'hlreg', there is no difference between 'uses hlreg' (allocate a @@ -359,7 +369,7 @@ register with property 'hlreg') and 'kills hlreg' (remove all registers with property 'hlreg' from the fake-stack). The same applies for the property 'dereg'. .br -Consequently 'kills' is rarely used in this back-end table. +As a consequence 'kills' is rarely used in this back-end table. .NH 3 Group 1: Load instructions .PP @@ -375,6 +385,7 @@ To refrain .B cgg from emitting the code for 'lol 10' again, an extra pattern is included in the table for cases like this. +.br The same applies for two consecutive 'loe'-s or 'lil'-s. .sp 1 A bit tricky is 'lof'. @@ -390,7 +401,7 @@ knows that HL is destroyed). .sp 1 By lookahead, .B cgg -can make a clever choice between the first and +can make a clever choise between the first and second code rule of 'loi 4'. The same applies for several other instructions. .NH 3 @@ -404,12 +415,13 @@ Groups 3 and 4: Signed and unsigned integer arithmetic Since the 8080 instruction set doesn't provide multiply and divide instructions, special routines are made to accomplish these tasks. .sp 1 -Instead of providing four slightly differing routines for 16 bit signed or +Instead of providing four slighty differing routines for 16 bit signed or unsigned division, yielding the quotient or the remainder, the routines are merged. This saves space and assembly time when several variants are used in a particular program, at the cost of a little speed. +.br When the routine is called, bit 7 of register A indicates whether the operands should be considered as signed or as unsigned integers, and bit 0 of register A indicates whether the quotient or the @@ -424,15 +436,14 @@ provided, because this one will usually be much faster. .NH 3 Group 5: Floating point arithmetic .PP -Floating point is not implemented. +Floating points are not implemented. +.br Whenever an EM-instruction involving floating points is offered -to the code-generator, it calls the corresponding -library routine with the proper parameters. -Each floating point library routine calls 'eunimpl', -trapping with trap number 63. +to the code-generator, it generates the code 'call eunimpl', +which traps with trap number 63. Some of the Pascal and C library routines output floating point EM-instructions, so code has to be generated for them. -Of course this does not imply the code will ever be executed. +Of course this doesn't imply the code will ever be executed. .NH 3 Group 12: Compare instructions .PP @@ -457,6 +468,7 @@ gen mov a,%1.2 but the current version of .B cgg doesn't approve this. +.br In any case .B cgg chooses either DE or HL to store the result, using lookahead. @@ -469,7 +481,7 @@ If only 2 bytes have to be returned, register-pair DE is used. LIBRARY ROUTINES .PP Most of the library routines start with saving the return address -and the local base, so that the parameters are on the top of the stack +and the localbase, so that the parameters are on the top of the stack and the registers B and C are available as scratch registers. Since register-pair HL is needed to accomplish these tasks, and also to restore everything just before the routine returns, @@ -481,6 +493,7 @@ When a routine returns 2 bytes, they are usually returned in registers-pair DE. When it returns more than 2 bytes they are pushed onto the stack. .br + It would have been possible to let the 32 bit arithmetic routines return 2 bytes in DE and the remaining 2 bytes on the stack (this often would have saved some space and execution time), @@ -491,6 +504,7 @@ TRAPS Whenever a trap, for example trying to divide by zero, occurs in a program that originally was written in C or Pascal, a special trap handler is called. +.br This trap handler wants to write an appropriate error message on the monitor. It tries to read the message from a file (e.g. etc/pc_rt_errors in the @@ -535,11 +549,11 @@ for example by downloading or by storing it in ROM (Read Only Memory). .sp 1 Depending on the characteristics of the particular 8080 based system, some -adaptations have to be made: +adaptions have to be made: .IP 1) 10 In 'head_em': the base address, which is the address where the first 8080 instruction will be stored, and the initial value of the -stackpointer are set to 0x1000 and 0x8000 respectively. +stackpointer are set to 0x1000 and 0x8000 respectivally. .br Other systems require other values. .IP 2) @@ -560,12 +574,12 @@ If this is not the right way on your system, change it. .IP 5) In 'tail_em': the current version of the 8080 back-end has very limited I/O capabilities, because it was tested on a system that -had no knowledge of files. +had no knowlegde of files. So the implementation of the EM-instruction 'mon' is very simple; it can only do the following things: .RS .IP Monitor\ call\ 1: 40 -exit +Exit .IP Monitor\ call\ 3: read, always reads from the monitor. .br @@ -593,7 +607,7 @@ INTEL 8080 VERSUS ZILOG Z80 AND INTEL 8086 .NH 2 Introduction .PP -At about the same time I developed the back end +At about the same time I develloped the back end for the Intel 8080 and Intel 8085, Frans van Haarlem did the same job for the Zilog z80 microprocessor. Since the z80 processor is an extension of the 8080, @@ -601,8 +615,8 @@ any machine code offered to a 8080 processor can be offered to a z80 too. The assembly languages are quite different however. .br -During the developments of the back ends we have used -two micro-computers, both equipped with a z80 microprocessor. +During the devellopments of the back ends we have used +two micro-computers, both equiped with a z80 microprocessor. Of course the output of the 8080 back end is assembled by an 8080 assembler. This should assure I have never used any of the features that are potentially available in the z80 processor, @@ -618,7 +632,7 @@ I have also involved the 8086 micro-processor in this measurements. Differences between the 8080 and z80 processors .PP Except for some features that are less important concerning back ends, -there are two points where the z80 improves upon the 8080: +there are two points where the z80 improves the 8080: .IP First, 18 the z80 has two additional index registers, IX and IY. They are used as in @@ -648,10 +662,11 @@ Special routines are included to jump to near locations, saving 1 byte. Consequences for the 8080 and z80 back end .PP The most striking difference between the 8080 and z80 back ends -is the choice of the local base. -The writer of the z80 back end chose index register IY as local base, +is the choise of the localbase. +The writer of the z80 back end chose index register IY as localbase, because this results in the cheapest coding of EM-instructions like 'lol' and 'stl'. +.br The z80 instructions that load local 10, for example .DS LD E,(IY+10) @@ -664,7 +679,7 @@ Although the profit of the z80 might be not world-shocking, it should be noted that as a side effect it may save some pushing and popping since register pair HL is not used. .sp 1 -The choice of IY as local base has its drawbacks too. +The choise of IY as localbase has its drawbacks too. The root of the problem is that it is not possible to add IY to HL. For the EM-instruction @@ -684,7 +699,7 @@ This annoying push and pop instructions are also needed in some other instructions, for instance in 'lol' when the offset doesn't fit in one byte. .sp 1 -Beside the choice of the local base, I think there is no +Beside the choise of the localbase, I think there is no fundamental difference between the 8080 and z80 back ends, except of course that the z80 back end has register pair BC and, less important, index register IX available as scratch registers. @@ -700,6 +715,7 @@ some C programs and some Pascal programs. Then I produced 8080, z80 and 8086 code for them. Investigating the assembler listing I found the lengths of the different parts of the generated code. +.br I have checked two areas: .IP 1) 8 the entire text part @@ -726,7 +742,7 @@ The table below should be read as follows. For all programs I have computed the ratio of the code-lengths of the 8080, z80 and 8086. The averages of all Pascal/C programs are listed in the table, -standardized to '100' for the 8080. +standarized to '100' for the 8080. So the listed '107' indicates that the lengths of the text parts of the z80 programs that originally were Pascal programs, averaged 7 percent larger than in the corresponding 8080 programs. @@ -744,7 +760,7 @@ averaged 7 percent larger than in the corresponding 8080 programs. The most striking thing in this table is that the z80 back end appears to produce larger code than the 8080 back end. The reason is that the current z80 back end table is -not very sophisticated yet. +not very elaborate yet. For instance it doesn't look for any EM-pattern longer than one. So the table shows that the preparations in the 8080 back end table to produce faster code (like recognizing special EM-patterns @@ -752,7 +768,7 @@ and permitting one byte registers on the fake-stack) was not just for fun, but really improved the generated code significantly. .sp 1 -The table shows that the 8080 table is relatively better +The table shows that the 8080 table is relativelly better when only the plain user program is considered instead of the entire text part. This is not very surprising since the 8080 back end sometimes uses library routines where the z80 and especially the 8086 don't. @@ -781,7 +797,7 @@ An overview on the Amsterdam Compiler Kit. .IP [3] Tanenbaum, A.S., Stevenson, J.W., Keizer, E.G., and van Staveren, H. .br -Description of an experimental machine architecture for use with block +Desciption of an experimental machine architecture for use with block structured languages, .br Informatica report 81, Vrije Universiteit, Amsterdam, 1983. diff --git a/doc/ncg.doc b/doc/ncg.doc index 4abfdbad5..e5464b48e 100644 --- a/doc/ncg.doc +++ b/doc/ncg.doc @@ -57,7 +57,7 @@ and the assembly code of the machine at hand. .NH 1 What has changed since version 1 ? .PP -This chapter can be skipped by anyone not familiar with the first version. +This section can be skipped by anyone not familiar with the first version. It is not needed to understand the current version. .PP This paper describes the second version of the code generator system. @@ -116,39 +116,40 @@ Alternatively one can think of the real stack as an infinite extension at the bottom of the fake stack. Both ways, the concatenation of the real stack and the fake stack will be the stack as it would have been on a real EM machine (see figure). -.KF -.DS L -.ta 8 16 24 32 40 48 56 64 72 - EM machine target machine - - | | | | - | | | | - | | | | - | | | | - | | | real stack | - | | | | | - | | | | | growing - | EM stack | | | | - | | |_______________| \e|/ - | | | | - | | | | - | | | | - | | | fake stack | - | | | | - |_______________| |_______________| - - -.I - Relation between EM stack, real stack and fake stack. -.R -.DE -.KE +.TS +center; +cw(3.5c) cw(3c) cw(3.5c) +cw(3.5c) cw(3c) cw(3.5c) +|cw(3.5c)| cw(3c) |cw(3.5c)| . +EM machine target machine + + + + + + real stack + stack + grows +EM stack \s+2\(br\s0 + \s+2\(br\s0 + \s+2\(br\s0 _ + \s+2\(br\s0 + \s+2\(da\s0 + fake stack + + + +_ _ +.T& +ci s s. +Relation between EM stack, real stack and fake stack. +.TE During code generation tokens will be kept on the fake stack as long as possible but when they are moved to the real stack, by generating code for the push, -all tokens above\u*\d +all tokens above\v'-.25m'\(dg\v'.25m' .FS -* in this document the stack is assumed to grow downwards, +\(dg in this document the stack is assumed to grow downwards, although the top of the stack will mean the first element that will be popped. .FE @@ -233,7 +234,7 @@ to register variables in the rest of this document. .PP The front ends generate messages to the back ends telling them which local variables could go into registers. -The information given is the offset of the local, it's size and type +The information given is the offset of the local, its size and type and a scoring number, roughly the number of times it occurs. .PP The decision which variable to put in which register is taken by the @@ -297,8 +298,9 @@ at will to improve legibility. Identifiers used in the table have the same syntax as C identifiers, upper and lower case considered different, all characters significant. Here is a list of reserved words; all of these are unavailable as identifiers. -.DS L -.ta 14 28 42 56 +.TS +box; +l l l l l. ADDR STACK from reg_any test COERCIONS STACKINGRULES gen reg_float to INSTRUCTIONS TESTS highw reg_loop ufit @@ -309,7 +311,7 @@ PROPERTIES cost loww reusing REGISTERS defined move rom SETS exact pat samesign SIZEFACTOR example proc sfit -.DE +.TE C style comments are accepted. .DS /* this is a comment */ @@ -330,7 +332,7 @@ NAME=value .DE value being an integer or string. Three constants must be defined here: -.IP EM_WSIZE 10 +.IP EM_WSIZE 14 Number of bytes in a machine word. This is the number of bytes a \fBloc\fP instruction will put on the stack. @@ -360,21 +362,21 @@ This is given as FORMAT = string .DE The string must be a valid printf(III) format, -and defaults to "%d" or "%ld" depending on the wordsize of -the machine. For example on the PDP-11 one can use +and defaults to "%ld". +For example on the PDP-11 one can use .DS -FORMAT= "0%o" +FORMAT= "0%lo" .DE to satisfy the old UNIX assembler that reads octal unless followed by a period, and the ACK assembler that follows C conventions. .PP -Tables under control of programs like +Tables under control of source code control systems like .I sccs or .I rcs can put their id-string here, for example .DS -rcsid="$Header$" +rcsid="$\&Header$" .DE These strings, like all strings in the table, will eventually end up in the binary code generator produced. @@ -385,6 +387,7 @@ same order of magnitude. This can be done as .DS SIZEFACTOR = C\d3\u/C\d4\u +.sp TIMEFACTOR = C\d1\u/C\d2\u .DE Above numbers must be read as rational numbers. @@ -403,24 +406,24 @@ It consists of a list of user-defined identifiers optionally followed by the size of the property in parentheses, default EM_WSIZE. Example for the PDP-11: -.DS -.ta 8 16 24 32 40 -PROPERTIES /* The header word for this section */ - -GENREG /* All PDP registers */ -REG /* Normal registers (allocatable) */ -ODDREG /* All odd registers (allocatable) */ -REGPAIR(4) /* Register pairs for division */ -FLTREG(4) /* Floating point registers */ -DBLREG(8) /* Same, double precision */ -GENFREG(4) /* generic floating point */ -GENDREG(8) /* Same, double precision */ -FLTREGPAIR(8) /* register pair for modf */ -DBLREGPAIR(16) /* Same, double precision */ -LOCALBASE /* Guess what */ +.TS +l l. +PROPERTIES /* The header word for this section */ + +GENREG /* All PDP registers */ +REG /* Normal registers (allocatable) */ +ODDREG /* All odd registers (allocatable) */ +REGPAIR(4) /* Register pairs for division */ +FLTREG(4) /* Floating point registers */ +DBLREG(8) /* Same, double precision */ +GENFREG(4) /* generic floating point */ +GENDREG(8) /* Same, double precision */ +FLTREGPAIR(8) /* register pair for modf */ +DBLREGPAIR(16) /* Same, double precision */ +LOCALBASE /* Guess what */ STACKPOINTER PROGRAMCOUNTER -.DE +.TE Registers are allocated by asking for a property, so if for some reason in later parts of the table one particular register must be allocated it @@ -438,22 +441,22 @@ Syntax: : ident [ '(' string ')' ] [ '=' ident [ '+' ident ] ] .DE Example for the PDP-11: -.DS L -.ta 8 16 24 32 40 48 56 64 +.TS +l l. REGISTERS -r0,r2,r4 : GENREG,REG. -r1,r3 : GENREG,REG,ODDREG. -r01("r0")=r0+r1 : REGPAIR. -fr0("r0"),fr1("r1"),fr2("r2"),fr3("r3") : GENFREG,FLTREG. +r0,r2,r4 : GENREG,REG. +r1,r3 : GENREG,REG,ODDREG. +r01("r0")=r0+r1 : REGPAIR. +fr0("r0"),fr1("r1"),fr2("r2"),fr3("r3") : GENFREG,FLTREG. dr0("r0")=fr0,dr1("r1")=fr1, - dr2("r2")=fr2,dr3("r3")=fr3 : GENDREG,DBLREG. + dr2("r2")=fr2,dr3("r3")=fr3 : GENDREG,DBLREG. fr01("r0")=fr0+fr1,fr23("r2")=fr2+fr3 : FLTREGPAIR. dr01("r0")=dr0+dr1,dr23("r2")=dr2+dr3 : DBLREGPAIR. -lb("r5") : GENREG,LOCALBASE. -sp : GENREG,STACKPOINTER. -pc : GENREG,PROGRAMCOUNTER. -.DE +lb("r5") : GENREG,LOCALBASE. +sp : GENREG,STACKPOINTER. +pc : GENREG,PROGRAMCOUNTER. +.TE .PP The names in the left hand lists are names of registers as used in the table. @@ -525,20 +528,21 @@ Tokens should usually be declared for every addressing mode of the machine at hand and for every size directly usable in a machine instruction. Example for the PDP-11 (incomplete): -.DS L +.TS +l l. TOKENS -const2 = { INT num; } 2 cost(2,300) "$" num . -addr_local = { INT ind; } 2 . -addr_external = { ADDR off; } 2 "$" off. +const2 = { INT num; } 2 cost(2,300) "$" num . +addr_local = { INT ind; } 2 . +addr_external = { ADDR off; } 2 "$" off. -regdef2 = { GENREG reg; } 2 "*" reg. -regind2 = { GENREG reg; ADDR off; } 2 off "(" reg ")" . -reginddef2 = { GENREG reg; ADDR off; } 2 "*" off "(" reg ")" . +regdef2 = { GENREG reg; } 2 "*" reg. +regind2 = { GENREG reg; ADDR off; } 2 off "(" reg ")" . +reginddef2 = { GENREG reg; ADDR off; } 2 "*" off "(" reg ")" . regconst2 = { GENREG reg; ADDR off; } 2 . relative2 = { ADDR off; } 2 off . -reldef2 = { ADDR off; } 2 "*" off. -.DE +reldef2 = { ADDR off; } 2 "*" off. +.TE .PP Types allowed in the struct are ADDR, INT and all register properties. The type ADDR means a string and an integer, @@ -574,7 +578,7 @@ that can adjust the time/space tradeoff to all positions from 100% time to 100% space. .LP By supplying different code rules in certain situations -it is possible to get a code generator that can adjust it's +it is possible to get a code generator that can adjust its code to the need of the moment. This is probably most useful with small machines, experience has shown that on the larger micro's and mini's @@ -620,21 +624,21 @@ in the remainder of the table, but for clarity it is usually better not to. .LP Example for the PDP-11 (incomplete): -.DS L -.ta 8 16 24 32 40 48 56 64 +.TS +l l. SETS -src2 = GENREG + regdef2 + regind2 + reginddef2 + relative2 + - reldef2 + addr_external + const2 + LOCAL + ILOCAL + - autodec + autoinc . -dst2 = src2 - ( const2 + addr_external ) . -xsrc2 = src2 + ftoint . -src1 = regdef1 + regind1 + reginddef1 + relative1 + reldef1 . -dst1 = src1 . -src1or2 = src1 + src2 . -src4 = relative4 + regdef4 + DLOCAL + regind4 . -dst4 = src4 . -.DE +src2 = GENREG + regdef2 + regind2 + reginddef2 + relative2 + + \h'\w'= 'u'reldef2 + addr_external + const2 + LOCAL + ILOCAL + + \h'\w'= 'u'autodec + autoinc . +dst2 = src2 - ( const2 + addr_external ) . +xsrc2 = src2 + ftoint . +src1 = regdef1 + regind1 + reginddef1 + relative1 + reldef1 . +dst1 = src1 . +src1or2 = src1 + src2 . +src4 = relative4 + regdef4 + DLOCAL + regind4 . +dst4 = src4 . +.TE Permissible in the set construction are all the usual set operators, i.e. .IP + set union @@ -1154,9 +1158,10 @@ This can of course be done with .DS kills ALL .DE -or by ending the stack pattern with the word STACK, which is equivalent, +or by ending the stack pattern with the word STACK, if the stack pattern does not start with .I exact . +The latter does not erase the contents of registers. .PP It is unfortunate that this part is still present in the table but it is too much for now to let the @@ -1248,7 +1253,7 @@ The author of .I cgg could not get .I yacc -to be silent without it. +to accept his syntax without it. Sorry about this. .IP 2) a @@ -1366,20 +1371,19 @@ A list of examples for the PDP-11 is given here. Far from being complete it gives examples of most kinds of instructions. .DS -.ta 8 16 24 32 40 48 56 64 -pat loc yields {const2, $1} +.ta 7.5c +pat loc yields {const2, $1} -pat ldc yields {const2, loww($1)} - {const2, highw($1)} +pat ldc yields {const2, loww($1)} {const2, highw($1)} .DE These simple patterns just push one or more tokens onto the fake stack. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat lof -with REG yields {regind2,%1,$1} -with exact regconst2 yields {regind2,%1.reg,$1+%1.off} -with exact addr_external yields {relative2,$1+%1.off} -with exact addr_local yields {LOCAL, %1.ind + $1,2} +with REG yields {regind2,%1,$1} +with exact regconst2 yields {regind2,%1.reg,$1+%1.off} +with exact addr_external yields {relative2,$1+%1.off} +with exact addr_local yields {LOCAL, %1.ind + $1,2} .DE This pattern shows the possibility to do different things depending on the fake stack contents, @@ -1389,13 +1393,12 @@ not preceded by that can always be taken after a coercion, if necessary. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat lxl $1>3 -uses REG={LOCAL, SL, 2}, - REG={const2,$1-1} +uses REG={LOCAL, SL, 2}, REG={const2,$1-1} gen 1: move {regind2,%a, SL},%a - sob %b,{label,1b} yields %a + sob %b,{label,1b} yields %a .DE This rule shows register allocation with initialisation, and the use of a temporary label. @@ -1404,7 +1407,7 @@ of the static link, that is pushed by the Pascal compiler as the last argument of a function. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat stf with regconst2 xsrc2 kills allexeptcon @@ -1419,7 +1422,7 @@ part in a store instruction. The set allexeptcon contains all tokens that can be the destination of an indirect store. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat sde with exact FLTREG kills posextern @@ -1445,51 +1448,52 @@ The third rule is taken by default, resulting in two separate stores, nothing better exists on the PDP-11. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat sbi $1==2 with src2 REG - gen sub %1,%2 yields %2 + gen sub %1,%2 yields %2 with exact REG src2-REG gen sub %2,%1 - neg %1 yields %1 + neg %1 yields %1 .DE This rule for .I sbi has a normal first part, -and a hand optimized special case as it's second part. +and a hand optimized special case as its second part. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat mli $1==2 with ODDREG src2 - gen mul %2,%1 yields %1 + gen mul %2,%1 yields %1 with src2 ODDREG - gen mul %1,%2 yields %2 + gen mul %1,%2 yields %2 .DE This shows the general property for rules with commutative operators, heuristics or look ahead will have to decide which rule is the best. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat loc sli $1==1 && $2==2 with REG -gen asl %1 yields %1 +gen asl %1 yields %1 .DE A simple rule involving a longer EM-pattern, to make use of a specialized instruction available. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat loc loc cii $1==1 && $2==2 with src1or2 uses reusing %1,REG -gen movb %1,%a yields %a +gen movb %1,%a yields %a .DE A somewhat more complicated example of the same. Note the .I reusing clause. .DS -.ta 8 16 24 32 40 48 56 64 -pat loc loc loc cii $1>=0 && $2==2 && $3==4 leaving loc $1 loc 0 +.ta 7.5c +pat loc loc loc cii $1>=0 && $2==2 && $3==4 + leaving loc $1 loc 0 .DE Shows a trivial example of EM-replacement. This is a rule that could be done by the @@ -1498,40 +1502,40 @@ if word order in longs was defined in EM. On a `big-endian' machine the two replacement instructions would be the other way around. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat and $1==2 with const2 REG - gen bic {const2,~%1.num},%2 yields %2 + gen bic {const2,~%1.num},%2 yields %2 with REG const2 - gen bic {const2,~%2.num},%1 yields %1 + gen bic {const2,~%2.num},%1 yields %1 with REG REG gen com %1 - bic %1,%2 yields %2 + bic %1,%2 yields %2 .DE Shows the way you have to twist the table, if an .I and -instruction is not available on your machine. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat set $1==2 with REG uses REG={const2,1} -gen ash %1,%a yields %a +gen ash %1,%a yields %a .DE Shows the building of a word-size set. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat lae aar $2==2 && rom($1,3)==1 && rom($1,1)==0 - leaving adi 2 + leaving adi 2 pat lae aar $2==2 && rom($1,3)==1 && rom($1,1)!=0 - leaving adi 2 adp 0-rom($1,1) + leaving adi 2 adp 0-rom($1,1) .DE Two rules showing the use of the rom pseudo function, and some array optimalisation. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat bra with STACK gen jbr {label, $1} @@ -1540,7 +1544,7 @@ A simple jump. The stack pattern guarantees that everything will be stacked before the jump is taken. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat cal with STACK gen jsr pc,{label, $1} @@ -1548,9 +1552,9 @@ gen jsr pc,{label, $1} A simple call. Same comments as previous rule. .DS -.ta 8 16 24 32 40 48 56 64 -pat lfr $1==2 yields r0 -pat lfr $1==4 yields r1 r0 +.ta 7.5c +pat lfr $1==2 yields r0 +pat lfr $1==4 yields r1 r0 .DE Shows the return area conventions of the PDP-11 table. At this point a reminder: @@ -1560,7 +1564,7 @@ instruction, and some other instructions must leave the function return area intact. See the defining document for EM for exact information. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat ret $1==0 with STACK gen mov lb,sp @@ -1574,7 +1578,7 @@ In a table with register variables the part would just contain .I return . .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat blm with REG REG uses REG={const2,$1/2} @@ -1592,16 +1596,16 @@ It uses the marriage thesis from Hall, a thesis from combinatorial mathematics, to accomplish this. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c pat exg $1==2 -with src2 src2 yields %1 %2 +with src2 src2 yields %1 %2 .DE This rule shows the exchanging of two elements on the fake stack. .NH 2 Code rules using procedures .PP -To start this chapter it must be admitted at once that the -word procedure is chosen here mainly for it's advertising +To start this section it must be admitted at once that the +word procedure is chosen here mainly for its advertising value. It more resembles a glorified goto but this of course can not be admitted in the glossy brochures. @@ -1660,12 +1664,12 @@ The string `*' can be used as an equivalent for `[1]'. Just in case this is not clear, here is an example for a procedure to increment/decrement a register. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c incop REG:rw:cc . /* in the INSTRUCTIONS part of course */ proc incdec with REG -gen incop* %1 yields %1 +gen incop* %1 yields %1 .DE The procedure is called with parameter "inc" or "dec". .PP @@ -1676,18 +1680,18 @@ call '(' string [ ',' string ] ')' .DE which leads to the following large example: .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c proc bxx example beq with src2 src2 STACK gen cmp %2,%1 jxx* {label, $1} -pat blt call bxx("jlt") -pat ble call bxx("jle") -pat beq call bxx("jeq") -pat bne call bxx("jne") -pat bgt call bxx("jgt") -pat bge call bxx("jge") +pat blt call bxx("jlt") +pat ble call bxx("jle") +pat beq call bxx("jeq") +pat bne call bxx("jne") +pat bgt call bxx("jgt") +pat bge call bxx("jge") .DE .NH 2 Move definitions @@ -1852,38 +1856,38 @@ The next part of the table defines the coercions that are possible on the defined tokens. Example for the PDP-11: .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c COERCIONS from STACK uses REG -gen mov {autoinc,sp},%a yields %a +gen mov {autoinc,sp},%a yields %a from STACK uses DBLREG -gen movf {autoinc,sp},%a yields %a +gen movf {autoinc,sp},%a yields %a from STACK uses REGPAIR gen mov {autoinc,sp},%a.1 - mov {autoinc,sp},%a.2 yields %a + mov {autoinc,sp},%a.2 yields %a .DE These three coercions just deliver a certain type of register by popping it from the real stack. .DS -.ta 8 16 24 32 40 48 56 64 -from LOCAL yields {regind2,lb,%1.ind} +.ta 7.5c +from LOCAL yields {regind2,lb,%1.ind} -from DLOCAL yields {regind4,lb,%1.ind} +from DLOCAL yields {regind4,lb,%1.ind} -from REG yields {regconst2, %1, 0} +from REG yields {regconst2, %1, 0} .DE These three are zero-cost rewriting rules. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c from regconst2 %1.off==1 uses reusing %1,REG=%1.reg -gen inc %a yields %a +gen inc %a yields %a from regconst2 uses reusing %1,REG=%1.reg @@ -1892,7 +1896,7 @@ gen add {addr_external, %1.off},%a yields %a from addr_local uses REG gen mov lb,%a - add {const2, %1.ind},%a yields %a + add {const2, %1.ind},%a yields %a .DE The last three are three different cases of the coercion register+constant to register. @@ -1900,19 +1904,19 @@ Only in the last case is it always necessary to allocate an extra register, since arithmetic on the localbase is unthinkable. .DS -.ta 8 16 24 32 40 48 56 64 +.ta 7.5c from xsrc2 -uses reusing %1, REG=%1 yields %a +uses reusing %1, REG=%1 yields %a from longf4 -uses FLTREG=%1 yields %a +uses FLTREG=%1 yields %a from double8 -uses DBLREG=%1 yields %a +uses DBLREG=%1 yields %a from src1 uses REG={const2,0} -gen bisb %1,%a yields %a +gen bisb %1,%a yields %a .DE These examples show the coercion of different tokens to a register of the needed type. @@ -1921,14 +1925,14 @@ ensure bytes are not sign-extended. In EM it is defined that the result of a \fBloi\fP\ 1 instruction is an integer in the range 0..255. .DS -.ta 8 16 24 32 40 48 56 64 -from REGPAIR yields %1.2 %1.1 +.ta 7.5c +from REGPAIR yields %1.2 %1.1 -from regind4 yields {regind2,%1.reg,2+%1.off} - {regind2,%1.reg,%1.off} +from regind4 yields {regind2,%1.reg,2+%1.off} + {regind2,%1.reg,%1.off} -from relative4 yields {relative2,2+%1.off} - {relative2,%1.off} +from relative4 yields {relative2,2+%1.off} + {relative2,%1.off} .DE The last examples are splitting rules. .PP @@ -1953,7 +1957,7 @@ and TEM_PSIZE. The type 'int' is used for things like counters that won't require more than 16 bits precision. The type 'word' is used among others to assemble datawords and -is of type 'long' if TEM_WSIZE>2. +is of type 'long'. The type 'full' is used for addresses and is of type 'long' if TEM_WSIZE>2 or TEM_PSIZE>2. .PP @@ -2082,25 +2086,25 @@ If omitted no initialization is assumed. .NH 3 Example mach.h for the PDP-11 .DS L -.ta 8 16 24 32 40 48 56 +.ta 4c #define ex_ap(y) fprintf(codefile,"\et.globl %s\en",y) #define in_ap(y) /* nothing */ #define newplb(x) fprintf(codefile,"%s:\en",x) #define newilb(x) fprintf(codefile,"%s:\en",x) #define newdlb(x) fprintf(codefile,"%s:\en",x) -#define dlbdlb(x,y) fprintf(codefile,"%s=%s\en",x,y) +#define dlbdlb(x,y) fprintf(codefile,"%s=%s\en",x,y) #define newlbss(l,x) fprintf(codefile,"%s:.=.+%d.\en",l,x); -#define cst_fmt "$%d." -#define off_fmt "%d." -#define ilb_fmt "I%02x%x" -#define dlb_fmt "_%d" -#define hol_fmt "hol%d" +#define cst_fmt "$%d." +#define off_fmt "%d." +#define ilb_fmt "I%x_%x" +#define dlb_fmt "_%d" +#define hol_fmt "hol%d" -#define hol_off "%d.+hol%d" +#define hol_off "%ld.+hol%d" -#define con_cst(x) fprintf(codefile,"%d.\en",x) +#define con_cst(x) fprintf(codefile,"%ld.\en",x) #define con_ilb(x) fprintf(codefile,"%s\en",x) #define con_dlb(x) fprintf(codefile,"%s\en",x) @@ -2153,7 +2157,7 @@ mes(w_mesno) This function is called when a .B mes pseudo is seen that is not handled by the machine independent part. -Example below shows all you probably have to know about that. +The example below shows all you probably have to know about that. .IP - segname[] .br @@ -2212,7 +2216,7 @@ Example mach.c for the PDP-11 As an example of the sort of code expected, the mach.c for the PDP-11 is presented here. .DS L -.ta 8 16 24 32 40 48 56 64 +.ta 0.5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i /* * machine dependent back end routines for the PDP-11 */ @@ -2678,7 +2682,7 @@ otherwise the register is marked empty. .NH 4 DO_INSTR .PP -This prints an instruction and it's operands. +This prints an instruction and its operands. Only done on toplevel. .NH 4 DO_MOVE diff --git a/first/local.h.src b/first/local.h.src index 439d62dc7..9839d9c83 100644 --- a/first/local.h.src +++ b/first/local.h.src @@ -4,4 +4,4 @@ # define VERSION 3 /* 16 bits number */ /* The default machine used by ack, acc, apc */ -# define ACKM "vax2" +# define ACKM "pdp" diff --git a/h/out.h b/h/out.h deleted file mode 100644 index 6bcceaa15..000000000 --- a/h/out.h +++ /dev/null @@ -1,120 +0,0 @@ -/* $Header$ */ -/* - * output format for ACK assemblers - */ -#ifndef ushort -#define ushort unsigned short -#endif ushort - -struct outhead { - ushort oh_magic; /* magic number */ - ushort oh_stamp; /* version stamp */ - ushort oh_flags; /* several format flags */ - ushort oh_nsect; /* number of outsect structures */ - ushort oh_nrelo; /* number of outrelo structures */ - ushort oh_nname; /* number of outname structures */ - long oh_nemit; /* sum of all os_flen */ - long oh_nchar; /* size of string area */ -}; - -#define O_MAGIC 0x0201 /* magic number of output file */ -#define O_STAMP 0 /* version stamp */ - -#ifdef JOHAN -#define HF_BREV 0x0001 /* high order byte lowest address */ -#define HF_WREV 0x0002 /* high order word lowest address */ -#endif JOHAN -#define HF_LINK 0x0004 /* unresolved references left */ -#define HF_8086 0x0008 /* os_base specially encoded */ - -struct outsect { - long os_base; /* startaddress in machine */ - long os_size; /* section size in machine */ - long os_foff; /* startaddress in file */ - long os_flen; /* section size in file */ - long os_lign; /* section alignment */ -}; - -struct outrelo { - char or_type; /* type of reference */ - char or_sect; /* referencing section */ - ushort or_nami; /* referenced symbol index */ - long or_addr; /* referencing address */ -}; - -struct outname { - union { - char *on_ptr; /* symbol name (in core) */ - long on_off; /* symbol name (in file) */ - } on_u; -#define on_mptr on_u.on_ptr -#define on_foff on_u.on_off - ushort on_type; /* symbol type */ - ushort on_desc; /* debug info */ - long on_valu; /* symbol value */ -}; - -/* - * relocation type bits - */ -#define RELSZ 0x07 /* relocation length */ -#define RELO1 1 /* 1 byte */ -#define RELO2 2 /* 2 bytes */ -#define RELO4 4 /* 4 bytes */ -#define RELPC 0x08 /* pc relative */ -#ifndef JOHAN -#define RELBR 0x10 /* High order byte lowest address. */ -#define RELWR 0x20 /* High order word lowest address. */ -#endif JOHAN - -/* - * section type bits and fields - */ -#define S_TYP 0x007F /* undefined, absolute or relative */ -#define S_EXT 0x0080 /* external flag */ -#define S_ETC 0x7F00 /* for symbolic debug, bypassing 'as' */ - -/* - * S_TYP field values - */ -#define S_UND 0x0000 /* undefined item */ -#define S_ABS 0x0001 /* absolute item */ -#define S_MIN 0x0002 /* first user section */ -#define S_MAX S_TYP /* last user section */ - -/* - * S_ETC field values - */ -#define S_SCT 0x0100 /* section names */ -#define S_LIN 0x0200 /* hll source line item */ -#define S_FIL 0x0300 /* hll source file item */ -#define S_MOD 0x0400 /* ass source file item */ -#ifndef JOHAN -#define S_COM 0x1000 /* Common name. */ -#endif JOHAN - -/* - * structure format strings - */ -#define SF_HEAD "22222244" -#define SF_SECT "44444" -#define SF_RELO "1124" -#define SF_NAME "4224" - -/* - * structure sizes (bytes in file; add digits in SF_*) - */ -#define SZ_HEAD 20 -#define SZ_SECT 20 -#define SZ_RELO 8 -#define SZ_NAME 12 - -/* - * file access macros - */ -#define BADMAGIC(x) ((x).oh_magic!=O_MAGIC) -#define OFF_SECT(x) SZ_HEAD -#define OFF_EMIT(x) (OFF_SECT(x) + ((long)(x).oh_nsect * SZ_SECT)) -#define OFF_RELO(x) (OFF_EMIT(x) + (x).oh_nemit) -#define OFF_NAME(x) (OFF_RELO(x) + ((long)(x).oh_nrelo * SZ_RELO)) -#define OFF_CHAR(x) (OFF_NAME(x) + ((long)(x).oh_nname * SZ_NAME)) diff --git a/h/ranlib.h b/h/ranlib.h deleted file mode 100644 index cf76a86e5..000000000 --- a/h/ranlib.h +++ /dev/null @@ -1,25 +0,0 @@ -/* $Header$ */ - -#ifndef SYMDEF -# define SYMDEF "__.SYMDEF" -#endif SYMDEF - -/* - * Structure of the SYMDEF table of contents for an archive. - * SYMDEF begins with a long giving the number of ranlib - * structures that immediately follow, and then continues with a string - * table consisting of a long giving the number of bytes of - * strings that follow and then the strings themselves. - */ -struct ranlib { - union { - char *ran__ptr; /* symbol name (in core) */ - long ran__off; /* symbol name (in file) */ - } ran_u; -#define ran_ptr ran_u.ran__ptr -#define ran_off ran_u.ran__off - long ran_pos; /* library member is at this position */ -}; - -#define SZ_RAN 8 -#define SF_RAN "44" diff --git a/lib/6805/descr b/lib/6805/descr deleted file mode 100644 index 9690b2223..000000000 --- a/lib/6805/descr +++ /dev/null @@ -1,29 +0,0 @@ -# $Revision$ -var w=2 -var i=2 -var p=2 -var s=2 -var l=4 -var f=4 -var d=8 -var NAME=m6805 -var M=6805 -var LIB=lib/{M}/tail_ -var RT=lib/{M}/head_ -var INCLUDES=-I{EM}/include -I/usr/include -name asld - from .s.a - to .out - outfile a.out - program {EM}/lib/{M}/as - mapflag -l* LNAME={EM}/{LIB}* - mapflag -d* ASFL={ASFL?} -d* - args {ASFL?} (.e:{HEAD}={EM}/{RT}em) \ - ({RTS}:.b.c={EM}/{RT}cc) ({RTS}:.p={EM}/{RT}pc) -o > < \ - (.p:{TAIL}={EM}/{LIB}pc) \ - (.b:{TAIL}={EM}/{LIB}bc) \ - (.b.c:{TAIL}={EM}/{LIB}cc.1s {EM}/{LIB}cc.2g) \ - (.b.c.p:{TAIL}={EM}/{LIB}mon) \ - (.e:{TAIL}={EM}/{LIB}em) - linker -end diff --git a/lib/descr/ibm.nosid b/lib/descr/ibm.nosid deleted file mode 100644 index d334f57ba..000000000 --- a/lib/descr/ibm.nosid +++ /dev/null @@ -1,40 +0,0 @@ -# $Revision$ -var w=2 -var p=2 -var s=2 -var l=4 -var f=4 -var d=8 -var NAME=i8086 -var M=i86 -var LIB=lib/i86/tail_ -var LIBIBM=lib/ibm/tail_ -var RT=lib/i86/head_ -var RTIBM=lib/ibm/head_ -var CPP_F=-Dunix -var INCLUDES=-I{EM}/include -I{EM}/lib/ibm/include -name be - from .m.g - to .s - program {EM}/lib/{M}/cg - args < - stdout - need .e -end -name asld - from .s.a - to .out - outfile a.out - program {EM}/lib/{M}/as - mapflag -l* LNAME={EM}/{LIB}* - mapflag -i IFILE={EM}/{RT}i - args {IFILE?} (.e:{HEAD}={EM}/{RTIBM}em) \ - ({RTS}:.b.c={EM}/{RT}cc) ({RTS}:.p={EM}/{RT}pc) -o > < \ - (.p:{TAIL}={EM}/{LIB}pc) \ - (.b:{TAIL}={EM}/{LIB}bc) \ - (.b.c:{TAIL}={EM}/{LIB}cc.1s {EM}/{LIB}cc.2g) \ - (.e:{TAIL}={EM}/{LIBIBM}em) \ - (.b.c.p:{TAIL}={EM}/{LIBIBM}mon) \ - (.e:{TAIL}={EM}/{LIBIBM}em.vend) - linker -end diff --git a/lib/descr/m68k2.macs b/lib/descr/m68k2.macs deleted file mode 100644 index 203e7e31b..000000000 --- a/lib/descr/m68k2.macs +++ /dev/null @@ -1,39 +0,0 @@ -# $Revision$ -var w=2 -var p=4 -var s=2 -var l=4 -var f=4 -var d=8 -var NAME=m68k2 -var M=m68k2 -var LIBDIR=/lib/{M} -var LIB=lib/{M}/tail_ -var RT=lib/{M}/head_ -var INCLUDES=-I{EM}/include -I/usr/include -name be - from .m.g - to .s - program {EM}/lib/{M}/cg - args < - stdout - need .e -end -name asld - from .s.a - to .out - outfile a.out - program {EM}/lib/{M}/as - mapflag -l* LNAME={EM}/{LIB}* - args (.e:{HEAD}={EM}/{RT}em) \ -({RTS}:.b.c={EM}/{RT}cc) ({RTS}:.p={EM}/{RT}pc) -o > < \ -(.p.c.b:{TAIL}={EM}/{LIBDIR}/sys1.s) (.p:{TAIL}={EM}/{LIBDIR}/sys2.s) \ -(.c:{TAIL}={EM}/{LIBDIR}/write.s) \ -(.p:{TAIL}={EM}/{LIB}pc) \ -(.b:{TAIL}={EM}/{LIB}bc) \ -(.b.c:{TAIL}={EM}/{LIB}cc.1s {EM}/{LIB}cc.2g) \ -(.b.c:{TAIL}={EM}/{LIB}mon {EM}/{LIB}fake) \ -(.e:{TAIL}={EM}/{LIB}em.rt {EM}/{LIB}em.vend) - prep cond - linker -end diff --git a/lib/descr/nascom b/lib/descr/nascom deleted file mode 100644 index db67d2005..000000000 --- a/lib/descr/nascom +++ /dev/null @@ -1,30 +0,0 @@ -# $Revision$ -var w=1 -var p=2 -var s=1 -var l=2 -var f=4 -var d=8 -var NAME=nascom -var M=z80a -var LIB=lib/{M}/tail_ -var RT=lib/{M}/head_ -var INCLUDES=-I{EM}/include -I/usr/include -name be - from .m.g - to .s - program {EM}/lib/{M}/be - args < - stdout - need .e -end -name asld - from .s.a - to .out - outfile a.out - program {EM}/lib/z80/as - mapflag -l* LNAME={EM}/{LIB}* - args (.e:{HEAD}={EM}/{RT}em) ({RTS}:.b.c={EM}/{RT}cc) -o > \ -(.e:{TAIL}={EM}/{LIB}em.1 {EM}/{LIB}em.2) - linker -end diff --git a/lib/descr/net86 b/lib/descr/net86 deleted file mode 100644 index 27097aed5..000000000 --- a/lib/descr/net86 +++ /dev/null @@ -1,32 +0,0 @@ -var w=2 -var p=2 -var s=2 -var l=4 -var f=4 -var d=8 -var NAME=i8086 -var M=i86 -var LIB=mach/i86/lib/tail_ -var RT=mach/i86/lib/head_ -var INCLUDES=-I{EM}/include -I/usr/include -name be - from .m - to .s - program {EM}/lib/{M}_cg - args < - prop > - need .e -end -name asld - from .s.a - to a.out - program {EM}/lib/{M}_as - mapflag -l* LNAME={EM}/{LIB}* - mapflag -i IFILE={EM}/{RT}i - args {IFILE?} (.e:{HEAD}={EM}/{RT}em) \ -({RTS}:.c={EM}/{RT}cc) ({RTS}:.p={EM}/{RT}pc) -o > < \ -(.p:{TAIL}={EM}/{LIB}pc) (.c:{TAIL}={EM}/{LIB}cc.1s {EM}/{LIB}cc.2g) \ -(.c.p.e:{TAIL}={EM}/{LIB}netio) (.c.p.e:{TAIL}={EM}/{LIB}alo) \ -(.c.p:{TAIL}={EM}/{LIB}mon) (.e:{TAIL}={EM}/{LIB}em) - prop C -end diff --git a/lib/descr/sat86 b/lib/descr/sat86 deleted file mode 100644 index ecfa18d82..000000000 --- a/lib/descr/sat86 +++ /dev/null @@ -1,34 +0,0 @@ -var w=2 -var p=2 -var s=2 -var l=4 -var f=4 -var d=8 -var NAME=i8086 -var M=i86 -var LIB=mach/i86/lib/tail_ -var ALIB=mach/i86/lib/sat_tail_ -var RT=mach/i86/lib/head_ -var ART=mach/i86/lib/sat_head_ -var CCP_F=-Dunix -var INCLUDES=-I{EM}/include -I/usr/include -name be - from .m - to .s - program {EM}/lib/{M}_cg - args < - prop > - need .e -end -name asld - from .s.a - to a.out - program {EM}/lib/{M}_as - mapflag -l* LNAME={EM}/{LIB}* - args (.e:{HEAD}={EM}/{ART}em) \ -({RTS}:.c={EM}/{RT}cc) ({RTS}:.p={EM}/{RT}pc) -o > < \ -(.p:{TAIL}={EM}/{LIB}pc) (.c:{TAIL}={EM}/{LIB}cc.1s {EM}/{LIB}cc.2g) \ -(.c.p:{TAIL}={EM}/{ALIB}mon) (.c.p.e:{TAIL}={EM}/{LIB}alo) \ -(.e:{TAIL}={EM}/{LIB}em) - prop C -end diff --git a/mach/6500/as/Makefile b/mach/6500/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/6500/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/6800/as/Makefile b/mach/6800/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/6800/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/6805/as/Makefile b/mach/6805/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/6805/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/6809/as/Makefile b/mach/6809/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/6809/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/arm/as/Makefile b/mach/arm/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/arm/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/i386/as/Makefile b/mach/i386/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/i386/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/i80/as/Makefile b/mach/i80/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/i80/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/i80/libem/LIST b/mach/i80/libem/LIST index 9e3345cd7..237f88f8d 100644 --- a/mach/i80/libem/LIST +++ b/mach/i80/libem/LIST @@ -12,7 +12,6 @@ csb.s dup.s dvi2.s exg.s -flp.s inn.s ior.s lar2.s diff --git a/mach/i80/libem/flp.s b/mach/i80/libem/flp.s deleted file mode 100644 index 45e8c1f12..000000000 --- a/mach/i80/libem/flp.s +++ /dev/null @@ -1,33 +0,0 @@ -.define .adf4,.adf8,.sbf4,.sbf8,.mlf4,.mlf8,.dvf4,.dvf8 -.define .ngf4,.ngf8,.fif4,.fif8,.fef4,.fef8 -.define .zrf4,.zrf8 -.define .cfi,.cif,.cuf,.cff,.cfu -.define .cmf4,.cmf8 - -! Floating point is not implemented - -.adf4: -.adf8: -.sbf4: -.sbf8: -.mlf4: -.mlf8: -.dvf4: -.dvf8: -.ngf4: -.ngf8: -.fif4: -.fif8: -.fef4: -.fef8: -.zrf4: -.zrf8: -.cfi: -.cif: -.cuf: -.cff: -.cfu: -.cmf4: -.cmf8: - call eunimpl - ret diff --git a/mach/i80/ncg/table b/mach/i80/ncg/table index 76caa12f1..8c885046f 100644 --- a/mach/i80/ncg/table +++ b/mach/i80/ncg/table @@ -818,61 +818,15 @@ gen Call {label,".sri4"} /* Group 5: Floating point arithmetic */ /********************************************/ -pat adf $1==4 -with STACK -gen Call {label,".adf4"} - -pat adf $1==8 -with STACK -gen Call {label,".adf8"} - -pat sbf $1==4 -with STACK -gen Call {label,".sbf4"} - -pat sbf $1==8 -with STACK -gen Call {label,".sbf8"} - -pat mlf $1==4 -with STACK -gen Call {label,".mlf4"} - -pat mlf $1==8 -with STACK -gen Call {label,".mlf8"} +/* Floating points are not supported */ -pat dvf $1==4 -with STACK -gen Call {label,".dvf4"} - -pat dvf $1==8 -with STACK -gen Call {label,".dvf8"} - -pat ngf $1==4 -with STACK -gen Call {label,".ngf4"} - -pat ngf $1==8 -with STACK -gen Call {label,".ngf8"} - -pat fif $1==4 -with STACK -gen Call {label,".fif4"} - -pat fif $1==8 -with STACK -gen Call {label,".fif8"} - -pat fef $1==4 -with STACK -gen Call {label,".fef4"} - -pat fef $1==8 -with STACK -gen Call {label,".fef8"} +pat adf gen Call {label,"eunimpl"} +pat sbf gen Call {label,"eunimpl"} +pat mlf gen Call {label,"eunimpl"} +pat dvf gen Call {label,"eunimpl"} +pat ngf gen Call {label,"eunimpl"} +pat fif gen Call {label,"eunimpl"} +pat fef gen Call {label,"eunimpl"} /********************************************/ /* Group 6: Pointer arithmetic */ @@ -965,13 +919,7 @@ pat zre uses hlreg={const2,0} gen shld {label,$1} -pat zrf $1==4 -with STACK -gen Call {label,".zrf4"} - -pat zrf $1==8 -with STACK -gen Call {label,".zrf8"} +pat zrf gen Call {label,"eunimpl"} pat zer $1==2 yields {const2,0} @@ -1087,26 +1035,12 @@ with STACK uses areg={const1,0} gen Call {label,".cii"} -pat cfi -with STACK -gen Call {label,".cfi"} - -pat cif -with STACK -gen Call {label,".cif"} - -pat cuf -with STACK -gen Call {label,".cuf"} - -pat cff -with STACK -gen Call {label,".cff"} - -pat cfu -with STACK -gen Call {label,".cfu"} - +pat cfi gen Call {label,"eunimpl"} +pat cif gen Call {label,"eunimpl"} +pat cuf gen Call {label,"eunimpl"} +pat cff gen Call {label,"eunimpl"} +pat cfu gen Call {label,"eunimpl"} + /*****************************************/ /* Group 9: Logical instructions */ /*****************************************/ @@ -1392,13 +1326,7 @@ with STACK uses areg={const1,1} gen Call {label,".cmi4"} yields de -pat cmf $1==4 -with STACK -gen Call {label,".cmf4"} - -pat cmf $1==8 -with STACK -gen Call {label,".cmf8"} +pat cmf gen Call {label,"eunimpl"} pat cmu $1==2 with hl_or_de hl_or_de diff --git a/mach/i86/as/Makefile b/mach/i86/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/i86/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/m68020/as/Makefile b/mach/m68020/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/m68020/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/m68k2/as/Makefile b/mach/m68k2/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/m68k2/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/m68k2/cg/mach.c b/mach/m68k2/cg/mach.c index 65fb301e4..0487fe2e0 100644 --- a/mach/m68k2/cg/mach.c +++ b/mach/m68k2/cg/mach.c @@ -23,19 +23,6 @@ static char rcsid[] = "$Header$"; * machine dependent back end routines for the Motorola 68000 */ -#define IEEEFLOAT - -#ifdef IEEEFLOAT -#include "FP.h" -#include "trp.c" -#include "fcompact.c" -#include "dbl_extract.c" -#ifdef PRT_EXP_DEBUG -#include "prt_extend.c" -#endif -#endif IEEEFLOAT - - con_part(sz,w) register sz; word w; { while (part_size % sz) @@ -61,58 +48,24 @@ con_mult(sz) word sz; { fprintf(codefile,".long %s\n",str); } -#ifdef IEEEFLOAT -dbl_adjust(fl) -my_dbl *fl; -{ - EXTEND buf; - - /* special routine to strip SGL_BIAS */ - dbl_extract(fl,&buf); - /* standard routine to add DBL_BIAS */ - fcompact(&buf,fl,sizeof(double)); -} -#endif IEEEFLOAT - -con_float() -{ - register word sz; - register long *l; -#ifdef IEEEFLOAT - register my_dbl *md; -#endif IEEEFLOAT - double d; - char mesg[128]; - - sz = argval; - if (sz!= 4 && sz!= 8) { - sprintf(mesg,"con_float(): bad fcon size %d %D\nstr: %s\n\0", - sz,sz,str); - fatal(mesg); - } - - d = atof(str); - l = (long *) &d; - -#ifdef IEEEFLOAT - if (sz == 8) { - /* ATOF() RETURNS THE PROPER FORMAT FOR A FLOAT */ - /* BUT NOT FOR A DOUBLE. CORRECT THE FORMAT. */ - md = (my_dbl *) &d; - dbl_adjust(md); - } -#endif IEEEFLOAT - - while ( sz ) { - fprintf(codefile,"\t.word 0x%x,0x%x !float test %s\n", - (int)(*l)&0xFFFF,(int)(*l>>16)&0xFFFF,str); - sz -=4 ; - l++; +con_float() { + +static int been_here; + if (argval != 4 && argval != 8) + fatal("bad fcon size"); + fprintf(codefile,".long\t"); + if (argval == 8) + fprintf(codefile,"F_DUM,"); + fprintf(codefile,"F_DUM\n"); + if ( !been_here++) + { + fprintf(stderr,"Warning : dummy float-constant(s)\n"); } } #ifdef REGVARS + regscore(off,size,typ,score,totyp) long off; { @@ -140,6 +93,8 @@ regscore(off,size,typ,score,totyp) score -= 1; /* take save/restore into account */ return score; } + + struct regsav_t { char *rs_reg; /* e.g. "a3" or "d5" */ long rs_off; /* offset of variable */ @@ -148,10 +103,20 @@ struct regsav_t { int regnr; +int nr_a_regs,nr_d_regs; +int TEM_BSIZE; +static long nlocals; + +prolog(n) +{ nlocals = n; } + i_regsave() { regnr = 0; + nr_a_regs = 0; + nr_d_regs = 0; + TEM_BSIZE = 0; } #define MOVEM_LIMIT 2 @@ -160,9 +125,11 @@ i_regsave() * we simply use several move.l's. */ + save() { register struct regsav_t *p; + int i; if (regnr > MOVEM_LIMIT) { fprintf(codefile,"movem.l "); @@ -173,16 +140,37 @@ save() } fprintf(codefile,",-(sp)\n"); } else { - for (p = regsav; p < ®sav[regnr]; p++) { - fprintf(codefile,"move.l %s,-(sp)\n",p->rs_reg); + /* Note that the order in which the registers are saved + * is important; it is used by gto.s. + */ + for (i = 0; i < nr_a_regs; i++) { + fprintf(codefile,"move.l a%d,-(sp)\n",5-i); + } + for (i = 0; i < nr_d_regs; i++) { + fprintf(codefile,"move.l d%d,-(sp)\n",7-i); } } + /* Push a mask that indicates which registers were saved */ + assert(nr_d_regs < 8 && nr_a_regs < 8); + if (nr_d_regs == 0 && nr_a_regs == 0) { + fprintf(codefile,"clr.w -(sp)\n"); + } else { + fprintf(codefile,"move.w #%d,-(sp)\n", + nr_d_regs + (nr_a_regs<<3)); + } + + /* Compute AB - LB */ + TEM_BSIZE = 4 * (nr_d_regs + nr_a_regs) + 10; + + /* allocate space for local variables */ + fprintf(codefile,"tst.b -%D(sp)\nlink\ta6,#-%D\n",nlocals+40,nlocals); + /* initialise register-parameters */ for (p = regsav; p < ®sav[regnr]; p++) { if (p->rs_off >= 0) { fprintf(codefile,"move.%c %ld(a6),%s\n", (p->rs_size == 4 ? 'l' : 'w'), - p->rs_off, + p->rs_off + TEM_BSIZE, p->rs_reg); } } @@ -191,7 +179,10 @@ save() restr() { register struct regsav_t *p; + int i; + fprintf(codefile,"unlk a6\n"); + fprintf(codefile,"add.l #2,sp\n"); /* pop mask */ if (regnr > MOVEM_LIMIT) { fprintf(codefile,"movem.l (sp)+,"); for (p = regsav; ;) { @@ -201,11 +192,13 @@ restr() } putc('\n',codefile); } else { - for (p = ®sav[regnr-1]; p >= regsav; p--) { - fprintf(codefile,"move.l (sp)+,%s\n",p->rs_reg); + for (i = nr_d_regs - 1; i >= 0; i--) { + fprintf(codefile,"move.l (sp)+,d%d\n",7-i); + } + for (i = nr_a_regs - 1; i >= 0; i--) { + fprintf(codefile,"move.l (sp)+,a%d\n",5-i); } } - fprintf(codefile,"unlk a6\n"); fprintf(codefile,"rts\n"); } @@ -221,6 +214,12 @@ regsave(str,off,size) { assert (regnr < 9); regsav[regnr].rs_reg = str; + if (str[0] == 'a') { + nr_a_regs++; + } else { + assert(str[0] == 'd'); + nr_d_regs++; + } regsav[regnr].rs_off = off; regsav[regnr++].rs_size = size; fprintf(codefile, "!Local %ld into %s\n",off,str); @@ -233,11 +232,15 @@ regreturn() #endif +#ifndef REGVARS + prolog(nlocals) full nlocals; { fprintf(codefile,"tst.b -%D(sp)\nlink\ta6,#-%D\n",nlocals+40,nlocals); } +#endif + mes(type) word type ; { diff --git a/mach/m68k2/cg/table b/mach/m68k2/cg/table index 2a327bf7b..73778bcd8 100644 --- a/mach/m68k2/cg/table +++ b/mach/m68k2/cg/table @@ -1,4 +1,3 @@ -"$Header$" /* * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. * @@ -33,7 +32,6 @@ EM_WSIZE = 2 EM_PSIZE = 4 -EM_BSIZE = 8 @@ -114,8 +112,6 @@ ABS = {STRING addr;} 2 cost=(3,5) "%[addr]" ABS1 = {STRING addr;} 2 cost=(3,5) "%[addr]" IMMEDIATE = {INT cc;} 2 cost=(1,2) "#%[cc]" LOCAL_ADDR = {INT off;} 4 /* not really addressable */ -REGOFF_ADDR = {REGISTER reg; - INT off;} 4 /* not really addressable */ EXTERNAL_ADDR = {STRING off;} 4 cost=(4,4) "#%[off]" INDEX_ADDR = {REGISTER reg,ireg; INT di;} 4 @@ -156,15 +152,13 @@ ALT_MEM = ALTERABLE * MEMORY DATASCR = DATAREG * SCRATCH ADDSCR = ADDREG * SCRATCH MEM_ALL = ALL - DATAREG - DATAREG4 - ADDREG - IMMEDIATE - IMMEDIATE4 - - LOCAL_ADDR -REGOFF_ADDR - EXTERNAL_ADDR - DOUBLE - DOUBLEZERO + - LOCAL_ADDR - EXTERNAL_ADDR - DOUBLE - DOUBLEZERO ALL_ACCESSIBLE = IADDREG + IADDREG4 + IADDREG1 + INDEXED + INDEXED4 ANY1 = DISPL1 + ABS1 + IADDREG1 -DATA_ALT1 = ANY1 -DATA_ALT_1OR2 = DATA_ALT + DATA_ALT1 +DATA_ALT_1OR2 = DATA_ALT + ANY1 -REG4 = DATAREG4 + ADDREG DATA4 = DATAREG4 + IADDREG4 + DISPL4 + INDEXED4 + ABS4 + IMMEDIATE4 + DOUBLE MEMORY4 = DATA4 - DATAREG4 @@ -210,18 +204,13 @@ lil | | allocate(ADDREG = {DISPL4,LB,$1})| {IADDREG,%[a]} | | lof | ADDREG | | {DISPL,%[1],$1} | | ... | nocoercions: EXTERNAL_ADDR | | {ABS,%[1.off]+"+"+tostring($1)} | | ... | nocoercions: LOCAL_ADDR | | {DISPL,LB,%[1.off]+$1} | | -... | nocoercions: REGOFF_ADDR | | {DISPL,%[1.reg],%[1.off]+$1} | | ldf | ADDREG | | {DISPL4,%[1],$1} | | ... | nocoercions: EXTERNAL_ADDR | | {ABS4,%[1.off]+"+"+tostring($1)} | | ... | nocoercions: LOCAL_ADDR | | {DISPL4,LB,%[1.off]+$1} | | -... | nocoercions: REGOFF_ADDR | | {DISPL4,%[1.reg],%[1.off]+$1} | | lal | | | {LOCAL_ADDR,$1} | | | LOCAL_ADDR | allocate(ADDREG) "lea %[1.off](a6),%[a]" samecc | %[a] | | -| REGOFF_ADDR | allocate(ADDREG) - "lea %[1.off](%[1.reg]),%[a]" - samecc | %[a] | | lae | | | {EXTERNAL_ADDR,$1} | | | EXTERNAL_ADDR | allocate(ADDREG) "lea %[1.off],%[a]" @@ -230,33 +219,17 @@ lae | | | {EXTERNAL_ADDR,$1} | | /* For the lxl and lxa instructions we assume that the static link * (i.e. a pointer to the LB of the lexically enclosing subprogram) * is passed as zero-th actual parameter. The distance (in bytes) - * between LB and the zero-th parameter is the constant EM_BSIZE + * between LB and the zero-th parameter is the constant 8 */ lxl $1 == 0 | | | LB | | -lxl $1 == 1 | | | {DISPL4,LB,8} | | -lxl $1>1 | | - allocate(ADDREG,DATAREG = {IMMEDIATE,$1-1}) - "move.l a6,%[a]" - "1:" - "move.l 8(%[a]),%[a]" - "dbf %[b],1b" - erase(%[b]) | %[a] | | -lxa $1 == 0 | | - allocate(ADDREG = {IMMEDIATE4,8}) - "add.l a6,%[a]" - erase(%[a]) | %[a] | | -lxa $1 > 0 | | - allocate(ADDREG, DATAREG = {IMMEDIATE,$1-1}) - "move.l a6,%[a]" - "1:" - "move.l 8(%[a]),%[a]" - "dbf %[b],1b" - "add.l #8,%[a]" - erase(%[b]) | %[a] | | +lxl $1>=1 | STACK | + "move.w #$1,-(sp)" + "jsr .lxl" | A0 | | +lxa | STACK | "move.w #$1,-(sp)" + "jsr .lxa" | A0 | | loi $1 == 1 | ADDREG | | {IADDREG1, %[1]} | | ... | nocoercions: LOCAL_ADDR | | {DISPL1,LB,%[1.off]} | | -... | nocoercions: REGOFF_ADDR | | {DISPL1,%[1.reg],%[1.off]} | | ... | nocoercions: EXTERNAL_ADDR | | {ABS1,%[1.off]} | | loi $1 == 2 | ADDREG | | {IADDREG,%[1]} | | loi $1 == 4 | ADDREG | | {IADDREG4,%[1]} | | @@ -272,9 +245,7 @@ lae loi $2 == 6 | | remove(ALL) lae loi $2 == 8 | | remove(ALL) "move.l $1+4,-(sp)" "move.l $1,-(sp)" | | | -loi $1 == 6 | ADDREG | | {DISPL,%[1],4} {IADDREG4,%[1]} | | -loi $1 == 8 | ADDREG | | {DISPL4,%[1],4} {IADDREG4,%[1]} | | -loi $1 > 8 | ADDSCR | remove(ALL) +loi $1 > 4 | ADDSCR | remove(ALL) allocate(DATAREG4= {IMMEDIATE4,$1/2-1}) "add.l #$1,%[1]" "1:" @@ -328,12 +299,10 @@ lpi | | | {EXTERNAL_ADDR,$1} | | #ifdef REGVARS -stl inreg($1)==2 | nocoercions: ANY | remove(regvar($1)) +stl inreg($1)==2 | ANY | remove(regvar($1)) move(%[1],regvar($1)) | | | -... | STACK | - "move.w (sp)+,%(regvar($1)%)" | | | #endif -stl | nocoercions: ANY | remove(DISPL,%[reg] == LB && %[dis] == $1) +stl | ANY | remove(DISPL,%[reg] == LB && %[dis] == $1) remove(DISPL4,%[reg] == LB && (%[dis] == $1-2 || %[dis] == $1)) remove(DISPL1,%[reg] == LB && (%[dis] == $1 || @@ -343,8 +312,6 @@ stl | nocoercions: ANY | remove(DISPL,%[reg] == LB && %[dis] == $1) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) move(%[1],{DISPL,LB,$1}) | | | -... | STACK | - "move.w (sp)+,$1(a6)" | | | ste | ANY | remove(ABS) remove(ABS4) @@ -411,29 +378,6 @@ sti $1 == 1 ... | nocoercions: LOCAL_ADDR ANY1 | remove(MEM_ALL) move(%[2],{DISPL1,LB,%[1.off]}) | | | -... | nocoercions: REGOFF_ADDR DATAREG | - remove(MEM_ALL) - move(%[2], {DISPL1,%[1.reg],%[1.off]}) | | | -... | nocoercions: REGOFF_ADDR IADDREG | - remove(MEM_ALL) - move({DISPL,%[2.reg],1}, {DISPL1,%[1.reg],%[1.off]}) | | | -... | nocoercions: REGOFF_ADDR DISPL | - remove(MEM_ALL) - move({DISPL,%[2.reg],%[2.dis]+1}, {DISPL1,%[1.reg],%[1.off]}) | | | -... | nocoercions: REGOFF_ADDR INDEXED | - remove(MEM_ALL) - move({INDEXED,%[2.reg],%[2.ireg],%[2.di]+1}, - {DISPL1,%[1.reg],%[1.off]}) | | | -... | nocoercions: REGOFF_ADDR ABS | - remove(MEM_ALL) - move({ABS,%[2.addr]+"+1"}, {DISPL1,%[1.reg],%[1.off]}) | | | -... | nocoercions: REGOFF_ADDR IMMEDIATE | - remove(MEM_ALL) - move({IMMEDIATE,(%[2.cc]-((%[2.cc]>>8)<<8)+128)%256-128}, - {DISPL1,%[1.reg],%[1.off]}) | | | -... | nocoercions: REGOFF_ADDR ANY1 | - remove(MEM_ALL) - move(%[2],{DISPL1,%[1.reg],%[1.off]}) | | | ... | nocoercions: EXTERNAL_ADDR DATAREG | remove(MEM_ALL) move(%[2], {ABS1,%[1.off]}) | | | @@ -471,13 +415,10 @@ sts $1 == 2 | | remove(ALL) "jsr .sts" | | | #ifdef REGVARS -sdl inreg($1)==2 | nocoercions: ANY4 | remove(regvar($1)) +sdl inreg($1)==2 | ANY4 | remove(regvar($1)) move (%[1],regvar($1)) | | | -... | STACK | - "move.l (sp)+,%(regvar($1)%)" | | | #endif -sdl | nocoercions: ANY4 | - remove(DISPL,%[reg] == LB && (%[dis] == $1 || %[dis] == $1+2)) +sdl | ANY4 | remove(DISPL,%[reg] == LB && (%[dis] == $1 || %[dis] == $1+2)) remove(DISPL4,%[reg] == LB && (%[dis] >= $1-2 && %[dis] <= $1+2)) remove(DISPL1,%[reg] == LB && (%[dis] >= $1 && @@ -487,8 +428,6 @@ sdl | nocoercions: ANY4 | remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) move(%[1],{DISPL4,LB,$1}) | | | -... | STACK | - "move.l (sp)+,$1(a6)" | | | sde | ANY4 | remove(ABS) remove(ABS4) @@ -510,41 +449,6 @@ sdf | ADDREG ANY4 | remove(MEM_ALL) * local variables that are not register-variables. */ -ldl ldl adp sdl loi $1==$2 && $2==$4 && inreg($1)==2 && $3==1 && $5==1 | | - allocate(DATAREG={IMMEDIATE,0}) - remove(regvar($1)) - "move.b (%(regvar($1)%))+,%[a]" | %[a] | | -ldl ldl adp sdl loi $1==$2 && $2==$4 && inreg($1)==2 && $3==2 && $5==2 | | - allocate(DATAREG) - remove(regvar($1)) - "move.w (%(regvar($1)%))+,%[a]" | %[a] | | -ldl ldl adp sdl sti $1==$2 && $2==$4 && inreg($1)==2 && $3==1 && $5==1 | DATAREG | - remove(regvar($1)) - "move.b %[1],(%(regvar($1)%))+" | | | -ldl ldl adp sdl sti $1==$2 && $2==$4 && inreg($1)==2 && $3==2 && $5==2 | ANY | - remove(regvar($1)) - "move.w %[1],(%(regvar($1)%))+" | | | -ldl ldl adp sdl $1==$2 && $2==$4 && inreg($1)==2 | | - allocate(ADDREG=regvar($1)) | %[a] - | ldl $2 adp $3 sdl $2 | -lol inl $1==$2 && inreg($1)==2 | | - allocate(DATAREG=regvar($1)) | %[a] - | inl $2 | -lol inl $1==$2 | | - allocate(DATAREG={DISPL,LB,$1}) | %[a] - | inl $2 | -lol del $1==$2 && inreg($1)==2 | | - allocate(DATAREG=regvar($1)) | %[a] - | del $2 | -lol del $1==$2 | | - allocate(DATAREG={DISPL,LB,$1}) | %[a] - | del $2 | -loe ine $1==$2 | | - allocate(DATAREG={ABS,$1}) | %[a] - | ine $2 | -loe dee $1==$2 | | - allocate(DATAREG={ABS,$1}) | %[a] - | dee $2 | lol adi stl $1 == $3 && $2 == 2 && inreg($1)==2 | ANY | remove(regvar($1)) @@ -643,15 +547,14 @@ lol loc slu stl $1 == $4 && $2 == 1 && $3 == 2 && inreg($1)==2 | | remove(regvar($1)) "asl.w #1,%(regvar($1)%)" erase(regvar($1)) | | | +ldl ldl adp sdl $1 == $2 && $2 == $4 && inreg($1)==2 | | + remove(regvar($1)) + allocate(ADDREG=regvar($1)) + "add.l #$3,%(regvar($1)%)" + erase(regvar($1)) | %[a] | | ldl adp sdl $1 == $3 && inreg($1)==2 | | remove(regvar($1)) "add.l #$2,%(regvar($1)%)" erase(regvar($1)) | | | -ldl adp dup sdl loi inreg($1) == 2 && $1 == $4 && $3 == 4 && $5 == 4 | | | | - ldl $1 adp $2 sdl $1 ldl $1 loi 4 | -ldl loi ldl loi adp ldl sti $2==4&&$4==4&&$7==4&&$1==$3&&$1==$6&&inreg($1)==2 - | | remove(MEM_ALL) - allocate(ADDREG = {IADDREG4,regvar($1)}) - "add.l #$5,(%(regvar($1)%))" | %[a] | | loc ldl ads sdl $2 == $4 && $3 == 2 && inreg($2)==2 | | remove(regvar($2)) "add.l #$1,%(regvar($2)%)" @@ -666,12 +569,10 @@ ldc ldl ads sdl $2 == $4 && $3 == 4 && inreg($2)==2 | | erase(regvar($2)) | | | lil inc sil $1==$3 && inreg($1)==2 | | remove(MEM_ALL) - "add.w #1,(%(regvar($1)%))" - setcc({IADDREG,regvar($1)}) | | | + "add.w #1,(%(regvar($1)%))" | | | lil dec sil $1==$3 && inreg($1)==2 | | remove(MEM_ALL) - "sub.w #1,(%(regvar($1)%))" - setcc({IADDREG,regvar($1)}) | | | + "sub.w #1,(%(regvar($1)%))" | | | lol and stl $1 == $3 && $2 == 2 && inreg($1)==2 | ANY | remove(regvar($1)) "and.w %[1],%(regvar($1)%)" @@ -866,24 +767,12 @@ lol ngi stl $1 == $3 && $2 == 4 | | loe ngi ste $1 == $3 && $2 == 4 | | remove(MEM_ALL) "neg.l $1" | | | -loc sli $1 == 1 && $2 == 2 | DATASCR | - "add.w %[1],%[1]" - erase(%[1]) - setcc(%[1]) | %[1] | | -loc sli $1 > 1 && $1 <= 8 && $2 == 2 | DATASCR | +loc sli $1 >= 1 && $1 <= 8 && $2 == 2 | DATASCR | "asl.w #$1,%[1]" erase(%[1]) | %[1] | | -loc sli $1 == 1 && $2 == 4 | DATASCR4 | - "add.l %[1],%[1]" - erase(%[1]) - setcc(%[1]) | %[1] | | -loc sli $1 > 1 && $1 <= 8 && $2 == 4 | DATASCR4 | +loc sli $1 >= 1 && $1 <= 8 && $2 == 4 | DATASCR4 | "asl.l #$1,%[1]" erase(%[1]) | %[1] | | -lol loc sli ads inreg($1) == 2 && $2 == 1 && $3 == 2 && $4 == 2 | ADDSCR | - "add.w %(regvar($1)%),%[1]" - "add.w %(regvar($1)%),%[1]" - erase(%[1]) | %[1] | | lol loc sli stl $1 == $4 && $2 == 1 && $3 == 2 | | remove(MEM_ALL) "asl.w #1, $1(a6)" | | | @@ -1035,78 +924,16 @@ adu | | | | adi $1 | sbu | | | | sbi $1 | slu | | | | sli $1 | -/* Floating point stuff */ -adf $1==4 | | - remove(ALL) - "jsr .adf4" | | asp 8 lfr 4 | -adf $1==8 | | - remove(ALL) - "jsr .adf8" | | asp 16 lfr 4 loi 8 | -sbf $1==4 | | - remove(ALL) - "jsr .sbf4" | | asp 8 lfr 4 | -sbf $1==8 | | - remove(ALL) - "jsr .sbf8" | | asp 16 lfr 4 loi 8 | -mlf $1==4 | | - remove(ALL) - "jsr .mlf4" | | asp 8 lfr 4 | -mlf $1==8 | | - remove(ALL) - "jsr .mlf8" | | asp 16 lfr 4 loi 8 | -dvf $1==4 | | - remove(ALL) - "jsr .dvf4" | | asp 8 lfr 4 | -dvf $1==8 | | - remove(ALL) - "jsr .dvf8" | | asp 16 lfr 4 loi 8 | -ngf $1==4 | | - remove(ALL) - "jsr .ngf4" | | asp 4 lfr 4 | -ngf $1==8 | | - remove(ALL) - "jsr .ngf8" | | asp 16 lfr 4 loi 8 | -fif $1==4 | | - remove(ALL) - "jsr .fif4" | | asp 16 lfr 4 loi 8 | -fif $1==8 | | - remove(ALL) - "jsr .fif8" | | asp 16 lfr 4 loi 16 | -fef $1==4 | | - remove(ALL) - "jsr .fef4" | | asp 4 lfr 4 loi 8 | -fef $1==8 | | - remove(ALL) - "jsr .fef8" | | asp 8 lfr 4 loi 12 | - /* G R O U P VI : P O I N T E R A R I T H M E T I C */ -adp $1 >= 1 && $1 <= 8 - | nocoercions: EXTERNAL_ADDR | | {EXTERNAL_ADDR,%[1.off] + "+" - + tostring($1)} | | -... | nocoercions: LOCAL_ADDR | | {LOCAL_ADDR,%[1.off]+$1} | | -... | nocoercions: REGOFF_ADDR | | {REGOFF_ADDR,%[1.reg],%[1.off]+$1} | | -... | nocoercions: ADDREG | | {REGOFF_ADDR,%[1],$1} | | -... | ADDSCR | "add.l #$1,%[1]" - erase(%[1]) - setcc(%[1]) | %[1] | | -adp $1 >= 0-32767 && $1 <= 32767 - | nocoercions: EXTERNAL_ADDR | | {EXTERNAL_ADDR,%[1.off] + "+" - + tostring($1)} | | -... | nocoercions: LOCAL_ADDR | | {LOCAL_ADDR,%[1.off]+$1} | | -... | nocoercions: REGOFF_ADDR | | {REGOFF_ADDR,%[1.reg],%[1.off]+$1} | | -... | nocoercions: ADDREG | | {REGOFF_ADDR,%[1],$1} | | -... | ADDSCR | "lea $1(%[1]),%[1]" +adp $1 >= 1 && $1 <= 8 | ADDSCR | "add.l #$1,%[1]" erase(%[1]) setcc(%[1]) | %[1] | | -adp | nocoercions: EXTERNAL_ADDR | | {EXTERNAL_ADDR,%[1.off] + "+" - + tostring($1)} | | -... | ADDSCR | "add.l #$1,%[1]" +adp | ADDSCR | "lea $1(%[1]),%[1]" erase(%[1]) setcc(%[1]) | %[1] | | - /* The next patterns are for efficient translation of "*p++" in C */ ldl ldl adp sdl $1 == $2 && $2 == $4 | | allocate(ADDREG={DISPL4,LB,$1}) @@ -1175,12 +1002,10 @@ inc | DATASCR | "add.w #1,%[1]" #ifdef REGVARS lil inc sil $1==$3 && inreg($1) == 2 | | remove(MEM_ALL) - "add.w #1,(%(regvar($1)%))" - setcc({IADDREG,regvar($1)}) | | | + "add.w #1,(%(regvar($1)%))" | | | lil dec sil $1==$3 && inreg($1) == 2 | | remove(MEM_ALL) - "sub.w #1,(%(regvar($1)%))" - setcc({IADDREG,regvar($1)}) | | | + "sub.w #1,(%(regvar($1)%))" | | | #endif lil inc sil $1==$3 | | allocate(ADDREG={DISPL4,LB,$1}) remove(MEM_ALL) @@ -1293,7 +1118,6 @@ zer $1 > 12 | | remove(ALL) "1:" "clr -(sp)" "dbf %[a],1b" | | | -zrf | | | | zer $1 | @@ -1343,88 +1167,6 @@ loc loc ciu $1==4 && $2==2 | DATAREG4 | | %[1.1] | | loc loc cui $1==4 && $2==2 | DATAREG4 | | %[1.1] | | ... | ANY | | | | -/* Floating point stuff */ - -loc loc cif $1==2 && $2==4 | | - remove(ALL) - "move.w #$1,-(sp)" - "jsr .cif4" | | asp 4 lfr 4 | -loc loc cif $1==2 && $2==8 | | - remove(ALL) - "move.w #$1,-(sp)" - "jsr .cif8" | | asp 4 lfr 4 loi 8 | -loc loc cif $1==4 && $2==4 | | - remove(ALL) - "move.w #$1,-(sp)" - "jsr .cif4" | | asp 6 lfr 4 | -loc loc cif $1==4 && $2==8 | | - remove(ALL) - "move.w #$1,-(sp)" - "jsr .cif8" | | asp 6 lfr 4 loi 8 | -loc loc cuf $1==2 && $2==4 | | - remove(ALL) - "move.w #$1,-(sp)" - "jsr .cuf4" | | asp 4 lfr 4 | -loc loc cuf $1==2 && $2==8 | | - remove(ALL) - "move.w #$1,-(sp)" - "jsr .cuf8" | | asp 4 lfr 4 loi 8 | -loc loc cuf $1==4 && $2==4 | | - remove(ALL) - "move.w #$1,-(sp)" - "jsr .cuf4" | | asp 6 lfr 4 | -loc loc cuf $1==4 && $2==8 | | - remove(ALL) - "move.w #$1,-(sp)" - "jsr .cuf8" | | asp 6 lfr 4 loi 8 | -loc loc cfi $1==4 && $2==2 | | - remove(ALL) - "move.w #$1,-(sp)" - "move.w #$2,-(sp)" - "jsr .cfi" | | asp 8 lfr 2 | -loc loc cfi $1==4 && $2==4 | | - remove(ALL) - "move.w #$1,-(sp)" - "move.w #$2,-(sp)" - "jsr .cfi" | | asp 8 lfr 4 | -loc loc cfi $1==8 && $2==2 | | - remove(ALL) - "move.w #$1,-(sp)" - "move.w #$2,-(sp)" - "jsr .cfi" | | asp 12 lfr 2 | -loc loc cfi $1==8 && $2==4 | | - remove(ALL) - "move.w #$1,-(sp)" - "move.w #$2,-(sp)" - "jsr .cfi" | | asp 12 lfr 4 | -loc loc cfu $1==4 && $2==2 | | - remove(ALL) - "move.w #$1,-(sp)" - "move.w #$2,-(sp)" - "jsr .cfu" | | asp 8 lfr 2 | -loc loc cfu $1==4 && $2==4 | | - remove(ALL) - "move.w #$1,-(sp)" - "move.w #$2,-(sp)" - "jsr .cfu" | | asp 8 lfr 4 | -loc loc cfu $1==8 && $2==2 | | - remove(ALL) - "move.w #$1,-(sp)" - "move.w #$2,-(sp)" - "jsr .cfu" | | asp 12 lfr 2 | -loc loc cfu $1==8 && $2==4 | | - remove(ALL) - "move.w #$1,-(sp)" - "move.w #$2,-(sp)" - "jsr .cfu" | | asp 12 lfr 4 | -loc loc cff $1==8 && $2==4 | | - remove(ALL) - "jsr .cff4" | | asp 8 lfr 4 | -loc loc cff $1==4 && $2==8 | | - remove(ALL) - "jsr .cff8" | | asp 4 lfr 4 loi 8 | - - /* G R O U P IX : L O G I C A L */ and defined($1) && $1 == 2 | ANY DATASCR | @@ -1435,11 +1177,6 @@ and defined($1) && $1 == 2 | ANY DATASCR | "and %[2],%[1]" setcc(%[1]) erase(%[1]) | %[1] | | (2,2)+%[2] -lol loc and $2 == 255 && inreg($1) < 2 && $3 == 2 | | | {DISPL1,LB,$1+1} | | -lal loi and lal sti $1 == $4 && $2 == 1 && $3 == 2 && $5 == 1 && inreg($1) < 2 - | DATAREG | - remove(MEM_ALL) - "and.b %[1],$1(a6)" | | | loc lol and stl $2 == $4 && $3 == 2 && inreg($2) < 2 | | remove(MEM_ALL) "and.w #$1,$2(a6)" | | | (6,10) @@ -1519,10 +1256,6 @@ ior defined($1) && $1 == 2 | ANY DATASCR | "or %[2],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | (2,2)+%[2] -lal loi ior lal sti $1 == $4 && $2 == 1 && $3 == 2 && $5 == 1 && inreg($1) < 2 - | DATAREG | - remove(MEM_ALL) - "or.b %[1],$1(a6)" | | | loc lol ior stl $2 == $4 && $3 == 2 && inreg($2) < 2 | | remove(MEM_ALL) "or.w #$1,$2(a6)" | | | (6,10) @@ -1599,10 +1332,6 @@ xor defined($1) && $1 == 2 | DATAREG DATASCR | "eor %[2],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | (2,2)+%[2] -lal loi xor lal sti $1 == $4 && $2 == 1 && $3 == 2 && $5 == 1 && inreg($1) < 2 - | DATAREG | - remove(MEM_ALL) - "eor.b %[1],$1(a6)" | | | lol loc xor stl $1 == $4 && $3 == 2 | | remove(MEM_ALL) "eor.w #$2,$1(a6)" | | | (6,10) @@ -1854,15 +1583,6 @@ cms !defined($1) | ANY | remove(ALL) cmp | | remove(ALL) "jsr .cmp" | D1 | | -/* floating point */ - -cmf $1==4 | | - remove(ALL) - "jsr .cmf4" | | asp 8 lfr 2 | -cmf $1==8 | | - remove(ALL) - "jsr .cmf8" | | asp 16 lfr 2 | - cmi tlt and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" @@ -2245,22 +1965,22 @@ ldc cmi tgt loww(1)==0&&highw(1)==0 | DATA_ALT4 | allocate(DATAREG={IMMEDIATE,1} "clr %[a]" "1:" erase(%[a]) | %[a] | | -cmi zlt $1==4 | ANY4 REG4 STACK | +cmi zlt $1==4 | ANY4 DATAREG4 STACK | "cmp.l %[1],%[2]" "blt $2" | | | -cmi zle $1==4 | ANY4 REG4 STACK | +cmi zle $1==4 | ANY4 DATAREG4 STACK | "cmp.l %[1],%[2]" "ble $2" | | | -cmi zeq $1==4 | ANY4 REG4 STACK | +cmi zeq $1==4 | ANY4 DATAREG4 STACK | "cmp.l %[1],%[2]" "beq $2" | | | -cmi zne $1==4 | ANY4 REG4 STACK | +cmi zne $1==4 | ANY4 DATAREG4 STACK | "cmp.l %[1],%[2]" "bne $2" | | | -cmi zge $1==4 | ANY4 REG4 STACK | +cmi zge $1==4 | ANY4 DATAREG4 STACK | "cmp.l %[1],%[2]" "bge $2" | | | -cmi zgt $1==4 | ANY4 REG4 STACK | +cmi zgt $1==4 | ANY4 DATAREG4 STACK | "cmp.l %[1],%[2]" "bgt $2" | | | ldc cmi zlt loww(1)==0&&highw(1)==0 && $2==4 | DATA_ALT4 STACK | @@ -2506,21 +2226,6 @@ tgt | DATA_ALT | allocate(DATAREG={IMMEDIATE,1}) /* G R O U P XIII : B R A N C H */ bra | STACK | "bra $1" | | | -/* byte comparisons */ -loc beq $1 >= 0 && $1 < 128 | nocoercions: DATA_ALT1 | - remove(ALL) - "cmp.b #$1,%[1]" - "beq $2" | | | -... | DATA_ALT STACK | - "cmp #$1,%[1]" - "beq $2" | | | -loc bne $1 >= 0 && $1 < 128 | nocoercions: DATA_ALT1 | - remove(ALL) - "cmp.b #$1,%[1]" - "bne $2" | | | -... | DATA_ALT STACK | - "cmp #$1,%[1]" - "bne $2" | | | blt | IMMEDIATE DATA_ALT STACK | "cmp %[1],%[2]" "blt $1" | | | ... | ANY DATAREG STACK | "cmp %[1],%[2]" @@ -2758,12 +2463,8 @@ dus $1 == 2 | DATASCR | remove(ALL) exg | STACK | "move.w #$1,d0" "jsr .exg" | | | fil | | "move.l #$1,.filn" | | | -gto | STACK | allocate(ADDREG) - "lea $1,%[a]" - "move.l 4(%[a]),sp" - "move.l 8(%[a]),a6" - "move.l (%[a]),%[a]" - "jmp (%[a])" | | | +gto | STACK | "pea $1" + "jmp .gto" | | | lin | | "move.w #$1,.lino" | | | lni | | "add.w #1,.lino" | | | mon | STACK | "jsr .mon" | | | @@ -2772,7 +2473,7 @@ lim | | | {ABS4,".trpim"} | | lor $1 == 0 | | | LB | | lor $1 == 1 | STACK | "move.l sp,-(sp)" | | | lor $1 == 2 | | | {ABS4,".reghp"} | | -lpb | | | | adp 8 | +lpb | STACK | "jsr .lpb" | A0 | | rck $1 == 2 | | remove(ALL) "jsr .rck" | | | @@ -2788,6 +2489,27 @@ str $1 == 2 | | remove(ALL) trp | STACK | "jsr .trp" | | | +/* For several floating point instructions we generate an illegal + * instruction trap. + */ + +adf | | | | loc 18 trp | +sbf | | | | loc 18 trp | +mlf | | | | loc 18 trp | +dvf | | | | loc 18 trp | +ngf | | | | loc 18 trp | +fef | | | | loc 18 trp | +fif | | | | loc 18 trp | +zrf | | | | loc 18 trp | +cfi | | | | loc 18 trp | +cif | | | | loc 18 trp | +cuf | | | | loc 18 trp | +cff | | | | loc 18 trp | +cfu | | | | loc 18 trp | +cmf | | | | loc 18 trp | + + + /* C O E R C I O N S */ @@ -2858,7 +2580,6 @@ STACKS: (ANY, , "move.w %[1],-(sp)" setcc(%[1]), (2,4) + %[1]) (EXTERNAL_ADDR, , "pea %[1.off]" nocc) (LOCAL_ADDR, , "pea %[1.off](a6)" nocc) -(REGOFF_ADDR, , "pea %[1.off](%[1.reg])" nocc) (INDEX_ADDR, , "pea %[1.di](%[1.reg],%[1.ireg].w)" nocc) (IMMEDIATE4 %[cc] == 0, , "clr.l -(sp)") (IMMEDIATE4, , "pea %[1.cc]" nocc) diff --git a/mach/m68k2/dl/dl.c b/mach/m68k2/dl/dl.c deleted file mode 100644 index 91b44c64c..000000000 --- a/mach/m68k2/dl/dl.c +++ /dev/null @@ -1,106 +0,0 @@ -static char rcsid[] = "$Header$"; -#define MAXBYTE 24 -#include -char hex[] = "0123456789ABCDEF"; -FILE *fp, *fopen(); -char **s; -int bytes, bytcnt, checksum; -long pc; - - -main (argc,argv) -int argc; -char *argv[]; - { - if (argc != 2) fatal ("usage: %s filename\n",argv[0]); - if ((fp = fopen (*++argv,"r")) == NULL) - fatal ("can't open %s\n",*argv); - else { - s = argv; - convert (); - fclose (fp); - } - } - -convert () - { - int c; - do - { - pc = getword (); - pc = (pc << 16) | getword (); - bytes = getword (); - while (bytes != 0) - { - bytcnt = (bytes < MAXBYTE) ? bytes : MAXBYTE; - bytes -= bytcnt; - checksum = 0; - if (pc > 0xffffL) S2record (); else S1record (); - } - c = getc (fp); - ungetc (c, fp); - } - while (c != EOF); - printf ("S9030000FC\n"); - } - - -S2record () - { - printf ("S2"); - bytcnt += 4; - outbyte (bytcnt); - outbyte (pc); - record (); - } - -S1record () - { - printf ("S1"); - bytcnt += 3; - outbyte (bytcnt); - record (); - } - -record () - { - outbyte (pc << 8); - outbyte (pc << 16); - while (bytcnt != 0) - { - outbyte (getbyte ()); - pc ++; - } - outbyte (~checksum); - putchar ('\n'); - putchar (0); - putchar (0); - } - -outbyte (b) -int b; - { - checksum = (checksum + b) & 0377; - putchar (hex[(b>>4) & 017]); - putchar (hex[b & 017]); - -- bytcnt; - } - -getword () - { - int c; - c = getbyte (); - return ((getbyte () << 8) | c ); - } - -getbyte () - { - int c; - if ((c = getc (fp)) == EOF) fatal ("end of %s\n",*s); - return (c); - } -fatal (s,a) - { - printf (s,a); - exit (-1); - } diff --git a/mach/m68k2/libsys/times.s b/mach/m68k2/libsys/times.s index 6e74fe9aa..002f63be5 100644 --- a/mach/m68k2/libsys/times.s +++ b/mach/m68k2/libsys/times.s @@ -2,6 +2,6 @@ .extern _times .text _times: move.w #0x2B,d0 - move.l 4(sp),a0 + move.w 4(sp),a0 trap #0 rts diff --git a/mach/m68k4/libsys/LIST b/mach/m68k4/libsys/LIST index 2d595ec46..4fccdc161 100644 --- a/mach/m68k4/libsys/LIST +++ b/mach/m68k4/libsys/LIST @@ -2,20 +2,15 @@ tail_mon.a exit.s _exit.s access.s -acct.s alarm.s chdir.s chmod.s -chown.s chroot.s close.s creat.s -dup.s -dup2.s execl.s execve.s fork.s -ftime.s getegid.s getgid.s getpid.s @@ -25,16 +20,12 @@ gtty.s ioctl.s kill.s link.s -lock.s lseek.s mknod.s mount.s nice.s open.s pause.s -pipe.s -profil.s -ptrace.s read.s setgid.s setuid.s @@ -43,10 +34,8 @@ stime.s sync.s time.s times.s -umask.s umount.s unlink.s -utime.s write.s brk.s wait.s @@ -54,4 +43,3 @@ fstat.s signal.s call.s cleanup.s -errno.s diff --git a/mach/ns/as/Makefile b/mach/ns/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/ns/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/pdp/as/Makefile b/mach/pdp/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/pdp/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/pdp/cg/peep.c b/mach/pdp/cg/peep.c deleted file mode 100644 index 32d0d040b..000000000 --- a/mach/pdp/cg/peep.c +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef NORCSID -static char rcsid[] = "$Header$"; -#endif - -#include - -/* - * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. - * - * This product is part of the Amsterdam Compiler Kit. - * - * Permission to use, sell, duplicate or disclose this software must be - * obtained in writing. Requests for such permissions may be sent to - * - * Dr. Andrew S. Tanenbaum - * Wiskundig Seminarium - * Vrije Universiteit - * Postbox 7161 - * 1007 MC Amsterdam - * The Netherlands - * - * Author: Hans van Staveren - */ - -char buf[512]; -char *index(); - -main() { - register n,sa; - register char *p; - - sa=0; - for (;;) { - getline(buf); - if (n=stackadjust()) { - sa += n; - continue; - } - if (nullinstruction()) - continue; - if (sa) { - if (buf[0]=='t' && buf[1]=='s' && buf[2]=='t' && buf[3]==' ') { - sa -= 2; - buf[0]='m'; - buf[1]='o'; - buf[2]='v'; - strcat(buf,",(sp)+"); - } else if (buf[0]=='m' && buf[1]=='o' && buf[2]=='v' && - buf[3]==' ' && (p=index(&buf[5],','))!=0 && - p[1]=='-' && p[2]=='(' && p[3]=='s') { - sa -= 2; - p[1]=' '; - } - } - switch(sa) { - case 0:break; - case 2:puts("tst (sp)+");sa=0;break; - case 4:puts("cmp (sp)+,(sp)+");sa=0;break; - case 6:puts("add $06,sp");sa=0;break; - } - puts(buf); - } -} - -getline(buf) register char *buf; { - register c; - - while ((c=getchar())==' ' || c=='\t') - ; - if (c==EOF) - exit(0); - do *buf++=c; - while ((c=getchar())!='\n'); - *buf=0; -} - -stackadjust() { - - if (buf[0]=='t' && - buf[1]=='s' && - buf[2]=='t' && - buf[3]==' ' && - buf[4]=='(' && - buf[5]=='s' && - buf[6]=='p' && - buf[7]==')' && - buf[8]=='+') return(2); - if (buf[0]=='c' && - buf[1]=='m' && - buf[2]=='p' && - buf[3]==' ' && - buf[4]=='(' && - buf[5]=='s' && - buf[6]=='p' && - buf[7]==')' && - buf[8]=='+' && - buf[9]==',' && - buf[10]=='(' && - buf[11]=='s' && - buf[12]=='p' && - buf[13]==')' && - buf[14]=='+') return(4); - if (buf[0]=='a' && - buf[1]=='d' && - buf[2]=='d' && - buf[3]==' ' && - buf[4]=='$' && - buf[5]=='0' && - buf[6]=='6' && - buf[7]==',' && - buf[8]=='s' && - buf[9]=='p' && - buf[10]==0) return(6); - return(0); -} - -nullinstruction() { - register char *p; - - if (buf[4]=='$' && buf[5]=='0' && buf[6]=='0' && buf[7]==',') { - p=index(buf,'-'); - if (p!=0 && p[1]=='(') - return(0); - p=index(buf,'+'); - if (p!=0 && p[-1]==')') - return(0); - if (buf[0]=='b' && buf[1]=='i' && (buf[2]=='s' || buf[2]=='c')) - return(1); - if (buf[0]=='a' && buf[1]=='d' && buf[2]=='d') - return(1); - if (buf[0]=='s' && buf[1]=='u' && buf[2]=='b') - return(1); - } - return(0); -} diff --git a/mach/pdp/libpc/makefile b/mach/pdp/libpc/makefile deleted file mode 100644 index ddc6a8e63..000000000 --- a/mach/pdp/libpc/makefile +++ /dev/null @@ -1,21 +0,0 @@ -MAKEFILE=../../proto/libg/Makefile -MACHDEF="MACH=pdp -Rbe-p2" "SUF=s" "ASAR=ar" -PCDEF="PREF=pc" "SUB=" "SRC=lang/pc/libpc" -LIBDIR=../lib - -install: - make -f $(MAKEFILE) $(PCDEF) $(MACHDEF) cp - -cmp: - make -f $(MAKEFILE) $(PCDEF) $(MACHDEF) all - cmp head_pc $(LIBDIR)/head_pc - cmp tail_pc $(LIBDIR)/tail_pc - -clean: - -rm -f *.old *.[ce$(SUF)] tail* head* - -opr: - make pr | opr - -pr: - @pr Makefile diff --git a/mach/proto/as/Makefile b/mach/proto/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/proto/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/proto/as/comm0.h b/mach/proto/as/comm0.h deleted file mode 100644 index 7d05690f8..000000000 --- a/mach/proto/as/comm0.h +++ /dev/null @@ -1,252 +0,0 @@ -/* @(#)comm0.h 1.8 */ -/* - * All preprocessor based options/constants/functions - */ - -/* ========== ON/OFF options (use #define in mach0.c) ========== */ - -/* - * The following options are available, to be set/removed in "mach0.c": - * THREE_PASS: three passes needed for branch optimization - * BYTES_REVERSED: lowest target address for word high-order byte - * WORDS_REVERSED: lowest target address for long high-order byte - * LISTING: include listing facilities - * RELOCATION: relocatable code generated - * DEBUG: for debugging purposes only - * TMPDIR: directory for temporary files - * ASLD: combined assembler/linker - * AOUTSEEK: seek on a.out instead of multiple opens - */ - -/* ========== constants (use #undef, #define in mach0.c) ========== */ - -/* table sizes */ -#define STRINGMAX 200 /* <= 256 */ -#define BITMAX 2000 /* for short or long branches */ -#define SECTMAX 64 -#define NAMEMAX 80 -#define MEMINCR 2048 - -/* Some character constants for parsing */ -#define ASC_LPAR '[' -#define ASC_RPAR ']' -#define ASC_SQUO '\'' -#define ASC_DQUO '"' -#define ASC_COMM '!' -#define ISALPHA(c) (isalpha(c) || (c) == '_' || (c) == '.') -#define ISALNUM(c) (isalnum(c) || (c) == '_') - -#define GENLAB "I" /* compiler generated labels */ - -#define ushort unsigned short - -#define valu_t short /* type of expression values */ -#define addr_t ushort /* type of dot */ -#define word_t short /* type of keyword value */ -/* - * NOTE: word_t is introduced to reduce the tokenfile size for machines - * with large expressions but smaller opcodes (68000) - */ - -#define ALIGNWORD 1 -#define ALIGNSECT 1 - -#define machstart(x) /* nothing */ -#define machfinish(x) /* nothing */ - -#define SETBASE(sp) ((long)(sp)->s_base) - -#define VALWIDTH 4 - -/* ========== Machine dependent option/constant settings ========== */ - -#include "mach0.c" - -/* ========== default option setting ========== */ - -#ifndef NOLD -#define ASLD /* default ON */ -#endif - -#ifndef ASLD -#ifndef RELOCATION -separate linker only possible if relocation info produced -#endif RELOCATION -#endif ASLD - -#ifndef DEBUG -#define DEBUG 1 -#endif - -/* ========== Machine independent type declarations ========== */ - -#ifdef _include -_include -_include -_include -#else -#include -#include -#include -#endif - -#ifdef ASLD -#include "aar.h" -#endif -#include "out.h" - -#if DEBUG == 0 -#define assert(ex) /* nothing */ -#endif - -#if DEBUG == 1 -#define assert(ex) {if (!(ex)) assert1();} -#endif - -#if DEBUG == 2 -#define assert(ex) {if (!(ex)) assert2(__FILE__, __LINE__);} -#endif - -#define CTRL(x) ((x) & 037) - -#define lowb(z) ((int)(z) & 0xFF) -#define loww(z) ((int)(z) & 0xFFFF) - -#define fitb(x) ((((x) + 0x80) & ~0xFF) == 0) -#define fitw(x) ((((x) + 0x8000) & ~0xFFFF) == 0) - -#define fit(x) if (!(x)) nofit() - -#define PASS_1 0 -#define PASS_2 1 -#define PASS_3 2 - -#ifdef THREE_PASS -#define PASS_SYMB (pass != PASS_1) -#define PASS_RELO (pass != PASS_1) -#else -#define PASS_SYMB 1 -#define PASS_RELO 1 -#endif THREE_PASS - -#ifdef ASLD -#define RELOMOVE(a,b) /* empty */ -#else -#define RELOMOVE(a,b) {a = b; b = 0;} -#endif - -/* symbol table management */ -#define H_SIZE 256 /* hash size */ -#define H_KEY (0*H_SIZE) /* key symbol headers */ -#define H_LOCAL (1*H_SIZE) /* module symbol headers */ -#ifdef ASLD -#define H_GLOBAL (2*H_SIZE) /* external symbol headers */ -#define H_TOTAL (3*H_SIZE) -#else -#define H_TOTAL (2*H_SIZE) -#endif - -/* numeric label table management */ -#define FB_SIZE 10 -#define FB_HEAD (0*FB_SIZE) -#define FB_TAIL (1*FB_SIZE) -#define FB_BACK (2*FB_SIZE) -#define FB_FORW (3*FB_SIZE) - -/* miscellaneous */ -#define KEYDEFINE 0 -#define DOTGAIN DOTSCT->s_gain - -/* ========== type declarations ========== */ - -struct expr_t { - short typ; - valu_t val; -}; - -typedef struct expr_t expr_t; - -struct item_t { - struct item_t * - i_next; /* linked lists with same hash value */ - short i_type; - /* - * the i_type field is used for two different purposes: - * - the token type for keywords, returned by yylex() - * - the symbol type for IDENT and FBSYM tokens - */ - valu_t i_valu; /* symbol value */ - char *i_name; /* symbol name */ -}; - -typedef struct item_t item_t; - -struct sect_t { - short s_flag; /* some flag bits */ - addr_t s_base; /* section base */ - addr_t s_size; /* section size */ - addr_t s_comm; /* length of commons */ - addr_t s_zero; /* delayed emit1(0) */ - addr_t s_lign; /* section alignment */ - long s_foff; /* section file offset */ - item_t *s_item; /* points to section name */ -#ifdef THREE_PASS - addr_t s_gain; /* gain in PASS_2 */ -#endif -}; - -typedef struct sect_t sect_t; - -/* ========== flag field bits ========== */ - -/* s_flag bits: */ -#define BASED 1 /* at fixed position */ - -/* sflag bits: */ -#define SYM_EXT 001 /* external symbols */ -#define SYM_LOC 002 /* local symbols */ -#define SYM_LAB 004 /* local, compiler-generated labels */ -#define SYM_SMB 010 /* .symb symbols */ -#define SYM_LIN 020 /* .line and .file */ -#define SYM_SCT 040 /* section names */ -#define SYM_DEF 073 /* default value */ - -/* - * extra type bits out of S_ETC, internal use only -#ifndef DUK - * S_COM: - * - symbols declared by .comm -#endif DUK - * S_VAR: - * - type not known at end of PASS_1 (S_VAR|S_UND) - * - value not known at end of PASS_2 (S_VAR|S_ABS) - * S_DOT: - * - dot expression - */ -#ifndef DUK -#define S_COM 0x0100 -#endif DUK -#define S_VAR 0x0200 -#define S_DOT 0x0400 -/* should be tested by preprocessor - * due to error in preprocessor it cannot - * test performed at runtime now - * #if (S_ETC|S_COM|S_VAR|S_DOT) != S_ETC - * incorrect type bits - * #endif - */ - -/* parts of the a.out file */ -#define PARTEMIT 0 -#define PARTRELO 1 -#define PARTNAME 2 -#define PARTCHAR 3 -#define PARTS 4 - -#ifdef AOUTSEEK -#define AOUTPART(p) if(aoutpart!=p){aoutpart=p;fseek(aoutfile,aoutseek[p],0);} -#define AOUTPUTC(c,p) {putc(c,aoutfile);aoutseek[p]++;if(ferror(aoutfile))werror();} -#else -#define AOUTPART(p) /* empty */ -#define AOUTPUTC(c,p) {putc(c,aoutfile[p]);if(ferror(aoutfile[p]))werror();} -#endif diff --git a/mach/proto/as/comm1.h b/mach/proto/as/comm1.h deleted file mode 100644 index ca4333113..000000000 --- a/mach/proto/as/comm1.h +++ /dev/null @@ -1,122 +0,0 @@ -/* @(#)comm1.h 1.5 */ -/* - * variable declarations - */ - -#ifdef extern -#define INIT(x) = x -#else -#define INIT(x) /* empty */ -#endif - -extern short pass INIT(PASS_1); - /* PASS 1, 2 or 3 */ -extern short peekc; /* push back symbol (PASS_1) */ -extern short unresolved; /* number of unresolved references */ -extern short lineno; /* input line number */ -extern short hllino; /* high-level language line number */ -extern short nerrors; /* terminate at end of pass if set */ -extern short sflag INIT(SYM_DEF); - /* -s option (symbol table info) */ -extern char *progname; /* for error messages */ -extern char *modulename; /* for error messages */ - -#ifdef ASLD -extern short archmode; /* scanning archives */ -extern long archsize; /* size of individual archive entries */ -#else -extern short uflag; /* if 1 make undefineds extern */ - /* symbol table index for last S_UND */ -#endif - -#ifdef LISTING -extern short dflag; /* -d option (list mode) */ -#endif - -#ifdef ASLD -#ifdef RELOCATION -extern short rflag; /* -r option (relocation info) */ -#endif RELOCATION -#else -#define rflag 1 -extern valu_t relonami; -#endif ASLD - -#ifdef THREE_PASS -extern short bflag; /* -b option (no optimizations) */ -#endif - -extern char *aoutpath INIT("a.out"); -extern char temppath[50]; - -extern FILE *input; -extern FILE *tempfile; - -#ifdef AOUTSEEK -extern FILE *aoutfile; -extern int aoutpart INIT(-1); -extern long aoutseek[PARTS]; -#else -extern FILE *aoutfile[PARTS]; -#endif - -extern char stringbuf[STRINGMAX]; - /* contains last string value */ - -extern sect_t sect[SECTMAX]; - -/* - * specials for the location counter - */ -extern sect_t *DOTSCT; /* §[DOTTYP-S_MIN] or NULL */ -extern addr_t DOTVAL; /* DOTSCT->s_size + DOTSCT->s_base */ -extern short DOTTYP; /* S_MIN..S_MAX or S_UND */ - -extern item_t *hashtab[H_TOTAL]; -extern short hashindex; /* see item_search() */ - -extern item_t *fb_ptr[4*FB_SIZE]; - -#ifdef THREE_PASS -extern char bittab[BITMAX>>3]; - /* one bit per small-large decision */ -extern short nbits; /* number of decisions so far */ -#endif - -#ifdef LISTING -extern short listmode; /* -d option for current pass */ -extern short listtemp; /* listmode if .list seen */ -extern short listflag; /* copied from listtemp at '\n' */ -extern short listcolm; /* column on output */ -extern short listeoln INIT(1); - /* set by endline, tested by emit1 */ -extern FILE *listfile; /* copy of source text */ -extern char listpath[50]; -#endif - -#ifndef extern -extern item_t keytab[]; -extern struct outhead outhead; -#endif - -/* forward function declarations */ -extern char *libname(); -extern char *readident(); -extern char *remember(); -extern item_t *fb_shift(); -extern item_t *fb_alloc(); -extern item_t *item_alloc(); -extern item_t *item_search(); -extern valu_t load(); -extern FILE *ffcreat(); -extern FILE *fftemp(); - -/* some library functions used */ -extern long atol(); -extern char *mktemp(); -extern char *sbrk(); -extern char *getenv(); - -/* ========== Machine dependent C declarations ========== */ - -#include "mach1.c" diff --git a/mach/proto/as/comm2.y b/mach/proto/as/comm2.y deleted file mode 100644 index 0e5c37c89..000000000 --- a/mach/proto/as/comm2.y +++ /dev/null @@ -1,424 +0,0 @@ -/* @(#)comm2.y 1.7 */ - -/* - * delay inclusion of machine dependent stuff (see comm0.h) - */ -#define _include #include - -%{ -#include "comm0.h" -#include "comm1.h" -%} - -/* ========== Machine independent Yacc definitions ========== */ - -%union { - word_t y_word; - valu_t y_valu; - expr_t y_expr; - item_t *y_item; -#ifdef ASLD - char *y_strp; -#endif -}; - -#ifdef ASLD -%token MODULE -#endif -%token STRING -%token IDENT -%token FBSYM -%token CODE1 -%token CODE2 -%token CODE4 -%token NUMBER0 /* keep NUMBER* in this order */ -%token NUMBER1 -%token NUMBER2 -%token NUMBER3 -%token NUMBER -%token DOT -%token EXTERN -%token DATA -%token ASCII -%token SECTION -%token COMMON -%token BASE -%token SYMB -%token ALIGN -%token ASSERT -%token SPACE -%token LINE -%token FILe -%token LIST -%token OP_EQ -%token OP_NE -%token OP_LE -%token OP_GE -%token OP_LL -%token OP_RR -%token OP_OO -%token OP_AA - -%left OP_OO -%left OP_AA -%left '|' -%left '^' -%left '&' -%left OP_EQ OP_NE -%left '<' '>' OP_LE OP_GE -%left OP_LL OP_RR -%left '+' '-' -%left '*' '/' '%' -%nonassoc '~' - -%type absexp optabs1 optabs2 -%type expr -%type id_fb - -/* ========== Machine dependent Yacc definitions ========== */ - -#include "mach2.c" - -%% - -/* ========== Machine independent rules ========== */ - -#ifdef LISTING -#define LISTLINE(n) listline(n) -#else -#define LISTLINE(n) /* empty */ -#endif LISTING - -#ifdef ASLD -#define RELODONE /* empty */ -#else -#define RELODONE assert(relonami == 0) -#endif - -program : /* empty */ -#ifdef ASLD - | program MODULE /* not in PASS_1 */ - { newmodule($2);} -#endif - | program IDENT ':' - { newident($2, DOTTYP); newlabel($2);} - | program NUMBER ':' - { if ($2 < 0 || $2 > 9) { - serror("bad f/b label"); - $2 = 0; - } - newlabel(fb_shift((int)$2)); - } - | program CODE1 - { emit1((char)$2); LISTLINE(0);} - | program CODE2 - { emit2((short)$2); LISTLINE(0);} - | program CODE4 - { emit4((long)$2); LISTLINE(0);} - | program operation ';' - | program operation '\n' - { lineno++; LISTLINE(1); RELODONE;} - | program '#' NUMBER STRING '\n' - { lineno++; LISTLINE(1); RELODONE;} - | program error '\n' - { serror("syntax error"); yyerrok; - lineno++; LISTLINE(1); RELODONE; - } - ; -#undef LISTLINE -#undef RELODONE -operation - : /* empty */ - | IDENT '=' expr - { -#ifdef LISTING - if (listflag & 1) - listcolm += printx(VALWIDTH, $3.val); -#endif - newequate($1, $3.typ); - store($1, $3.val); - } -#ifdef LISTING - | LIST - { if ($1) - listtemp = listmode; - else if ((dflag & 01000) == 0) - listtemp = 0; - } -#endif - | SECTION IDENT - { newsect($2);} - | COMMON IDENT ',' absexp - { newcomm($2, $4);} - | BASE absexp - { if (pass == PASS_1) newbase($2);} - | ASSERT expr - { if ($2.val == 0 && pass == PASS_3) - warning("assertion failed"); - } - | SYMB STRING ',' expr optabs2 optabs2 - { if ((sflag & SYM_SMB) && PASS_SYMB) { -#ifndef ASLD - if ( - pass == PASS_3 - && - ($4.typ & S_TYP) == S_UND - ) { - serror("expression undefined"); - relonami = -1; - } -#endif - newsymb( - stringbuf+1, - (short)( - ($4.typ & (S_EXT|S_TYP)) - | - ((ushort)$5<<8) - ), - (short)$6, - $4.val - ); - } - } - | LINE optabs1 - { if ((sflag & SYM_LIN) && PASS_SYMB) { - if ($2) - hllino = (short)$2; - else - hllino++; - newsymb( - (char *)0, - (short)(DOTTYP | S_LIN), - (short)hllino, - (valu_t)DOTVAL - ); - } - } - | FILe STRING - { if ((sflag & SYM_LIN) && PASS_SYMB) { - hllino = 0; - newsymb( - stringbuf+1, - (short)(DOTTYP | S_FIL), - (short)0, - (valu_t)DOTVAL - ); - } - } - | EXTERN externlist - | ALIGN optabs1 - { align($2);} - | SPACE absexp - { if (DOTSCT == NULL) - nosect(); - DOTVAL += $2; - DOTSCT->s_zero += $2; - } - | DATA datalist - | ASCII STRING - { emitstr($1);} - ; -externlist - : IDENT - { $1->i_type |= S_EXT;} - | externlist ',' IDENT - { $3->i_type |= S_EXT;} - ; -datalist - : expr - { -#ifdef RELOCATION - if (rflag != 0 && PASS_RELO) -#ifdef DUK -#ifdef BYTES_REVERSED -#ifdef WORDS_REVERSED - newrelo($1.typ, - (int)$0 | RELBR | RELWR - ); -#else WORDS_REVERSED - newrelo($1.typ, (int)$0|RELBR); -#endif WORDS_REVERSED -#else BYTES_REVERSED -#ifdef WORDS_REVERSED - newrelo($1.typ, (int)$0|RELWR); -#else WORDS_REVERSED - newrelo($1.typ, (int)$0); -#endif WORDS_REVERSED -#endif BYTES_REVERSED -#else DUK - newrelo($1.typ, (int)$0); -#endif DUK -#endif - emitx($1.val, (int)$0); - } - | datalist ',' expr - { -#ifdef RELOCATION - if (rflag != 0 && PASS_RELO) -#ifdef DUK -#ifdef BYTES_REVERSED -#ifdef WORDS_REVERSED - newrelo($3.typ, - (int)$0 | RELBR | RELWR - ); -#else WORDS_REVERSED - newrelo($3.typ, (int)$0|RELBR); -#endif WORDS_REVERSED -#else BYTES_REVERSED -#ifdef WORDS_REVERSED - newrelo($3.typ, (int)$0|RELWR); -#else WORDS_REVERSED - newrelo($3.typ, (int)$0); -#endif WORDS_REVERSED -#endif BYTES_REVERSED -#else DUK - newrelo($3.typ, (int)$0); -#endif DUK -#endif - emitx($3.val, (int)$0); - } - ; -expr : error - { serror("expr syntax err"); - $$.val = 0; $$.typ = S_UND; - } - | NUMBER - { $$.val = $1; $$.typ = S_ABS;} - | id_fb - { $$.val = load($1); - $$.typ = $1->i_type & ~S_EXT; - } - | STRING - { if (stringbuf[0] != 1) - serror("too many chars"); - $$.val = stringbuf[1]; - $$.typ = S_ABS; - } - | ASC_LPAR expr ASC_RPAR - { $$ = $2;} - | expr OP_OO expr - { $$.val = ($1.val || $3.val); - $$.typ = combine($1.typ, $3.typ, 0); - } - | expr OP_AA expr - { $$.val = ($1.val && $3.val); - $$.typ = combine($1.typ, $3.typ, 0); - } - | expr '|' expr - { $$.val = ($1.val | $3.val); - $$.typ = combine($1.typ, $3.typ, 0); - } - | expr '^' expr - { $$.val = ($1.val ^ $3.val); - $$.typ = combine($1.typ, $3.typ, 0); - } - | expr '&' expr - { $$.val = ($1.val & $3.val); - $$.typ = combine($1.typ, $3.typ, 0); - } - | expr OP_EQ expr - { $$.val = ($1.val == $3.val); - $$.typ = combine($1.typ, $3.typ, '>'); - } - | expr OP_NE expr - { $$.val = ($1.val != $3.val); - $$.typ = combine($1.typ, $3.typ, '>'); - } - | expr '<' expr - { $$.val = ($1.val < $3.val); - $$.typ = combine($1.typ, $3.typ, '>'); - } - | expr '>' expr - { $$.val = ($1.val > $3.val); - $$.typ = combine($1.typ, $3.typ, '>'); - } - | expr OP_LE expr - { $$.val = ($1.val <= $3.val); - $$.typ = combine($1.typ, $3.typ, '>'); - } - | expr OP_GE expr - { $$.val = ($1.val >= $3.val); - $$.typ = combine($1.typ, $3.typ, '>'); - } - | expr OP_RR expr - { $$.val = ($1.val >> $3.val); - $$.typ = combine($1.typ, $3.typ, 0); - } - | expr OP_LL expr - { $$.val = ($1.val << $3.val); - $$.typ = combine($1.typ, $3.typ, 0); - } - | expr '+' expr - { $$.val = ($1.val + $3.val); - $$.typ = combine($1.typ, $3.typ, '+'); - } - | expr '-' expr - { $$.val = ($1.val - $3.val); - $$.typ = combine($1.typ, $3.typ, '-'); - } - | expr '*' expr - { $$.val = ($1.val * $3.val); - $$.typ = combine($1.typ, $3.typ, 0); - } - | expr '/' expr - { if ($3.val == 0) { - if (pass == PASS_3) - serror("divide by zero"); - $$.val = 0; - } else - $$.val = ($1.val / $3.val); - $$.typ = combine($1.typ, $3.typ, 0); - } - | expr '%' expr - { if ($3.val == 0) { - if (pass == PASS_3) - serror("divide by zero"); - $$.val = 0; - } else - $$.val = ($1.val % $3.val); - $$.typ = combine($1.typ, $3.typ, 0); - } - | '+' expr %prec '*' - { $$.val = $2.val; - $$.typ = combine(S_ABS, $2.typ, 0); - } - | '-' expr %prec '*' - { $$.val = -$2.val; - $$.typ = combine(S_ABS, $2.typ, 0); - } - | '~' expr - { $$.val = ~$2.val; - $$.typ = combine(S_ABS, $2.typ, 0); - } - | DOT - { $$.val = DOTVAL; - $$.typ = DOTTYP|S_DOT; - } - ; -id_fb : IDENT - | FBSYM - ; -absexp : expr - { if (($1.typ & ~S_EXT) != S_ABS) - serror("must be absolute"); - $$ = $1.val; - } - ; -optabs1 - : /* empty */ - { $$ = 0;} - | absexp - { $$ = $1;} - ; -optabs2 - : /* empty */ - { $$ = 0;} - | ',' absexp - { $$ = $2;} - ; - -/* ========== Machine dependent rules ========== */ - -#include "mach4.c" - -%% diff --git a/mach/proto/as/comm3.c b/mach/proto/as/comm3.c deleted file mode 100644 index 937114e72..000000000 --- a/mach/proto/as/comm3.c +++ /dev/null @@ -1,50 +0,0 @@ -/* @(#)comm3.c 1.1 */ -/* - * storage allocation for variables - */ - -#include "comm0.h" - -#define extern /* empty, to force storage allocation */ - -#include "comm1.h" - -struct outhead outhead = { - O_MAGIC, O_STAMP, 0 -#ifndef DUK -#ifdef BYTES_REVERSED - | HF_BREV -#endif -#ifdef WORDS_REVERSED - | HF_WREV -#endif -#endif DUK -}; - -#include "y.tab.h" - -item_t keytab[] = { - 0, EXTERN, 0, ".define", - 0, EXTERN, 0, ".extern", - 0, DOT, 0, ".", - 0, DATA, 1, ".data1", - 0, DATA, 2, ".data2", - 0, DATA, 4, ".data4", - 0, ASCII, 0, ".ascii", - 0, ASCII, 1, ".asciz", - 0, ALIGN, 0, ".align", - 0, ASSERT, 0, ".assert", - 0, SPACE, 0, ".space", - 0, COMMON, 0, ".comm", - 0, SECTION, 0, ".sect", - 0, BASE, 0, ".base", - 0, SYMB, 0, ".symb", - 0, LINE, 0, ".line", - 0, FILe, 0, ".file", -#ifdef LISTING - 0, LIST, 0, ".nolist", - 0, LIST, 1, ".list", -#endif -#include "mach3.c" - 0, 0, 0, 0 -}; diff --git a/mach/proto/as/comm4.c b/mach/proto/as/comm4.c deleted file mode 100644 index 14a1093f9..000000000 --- a/mach/proto/as/comm4.c +++ /dev/null @@ -1,539 +0,0 @@ -/* @(#)comm4.c 1.6 */ -/* - * Micro processor assembler framework written by - * Johan Stevenson, Vrije Universiteit, Amsterdam - * modified by - * Johan Stevenson, Han Schaminee and Hans de Vries - * Philips S&I, T&M, PMDS, Eindhoven - */ - -#include "comm0.h" -#include "comm1.h" -#include "y.tab.h" - -extern YYSTYPE yylval; - -/* ========== Machine independent C routines ========== */ - -stop() { -#if DEBUG < 2 - unlink(temppath); -#ifdef LISTING - unlink(listpath); -#endif -#endif - exit(nerrors != 0); -} - -main(argc, argv) -char **argv; -{ - register char *p; - register i; - static char sigs[] = { - SIGHUP, SIGINT, SIGQUIT, SIGTERM, 0 - }; - - /* this test should be performed by the - * preprocessor, but it cannot - */ - if ((S_ETC|S_COM|S_VAR|S_DOT) != S_ETC) - fatal("incorrect type bits"); - - progname = *argv++; argc--; - for (p = sigs; i = *p++; ) - if (signal(i, SIG_IGN) != SIG_IGN) - signal(i, stop); - for (i = 0; i < argc; i++) { - p = argv[i]; - if (*p++ != '-') - continue; - switch (*p++) { - case 'o': - if (*p != NULL) { - aoutpath = p; - break; - } - argv[i] = 0; - if (++i >= argc) - fatal("-o needs filename"); - aoutpath = argv[i]; - break; - case 'd': -#ifdef LISTING - dflag = 0; - while (*p >= '0' && *p <= '7') - dflag = (dflag << 3) + *p++ - '0'; - if ((dflag & 0777) == 0) - dflag |= 0700; - dflag &= ~4; -#endif - break; - case 's': - sflag = 0; - while (*p >= '0' && *p <= '7') - sflag = (sflag << 3) + *p++ - '0'; - break; - case 'r': -#ifdef RELOCATION -#ifdef ASLD - rflag = 1; -#endif ASLD -#endif RELOCATION - break; - case 'b': -#ifdef THREE_PASS - bflag = 1; -#endif - break; -#ifndef ASLD - case 'u': - case '\0': - uflag = 1; - break; -#endif - default: - continue; - } - argv[i] = 0; - } -#ifdef RELOCATION - if (rflag) - sflag |= SYM_SCT; -#endif RELOCATION - pass_1(argc, argv); -#ifdef THREE_PASS - pass_23(PASS_2); -#endif - pass_23(PASS_3); - stop(); -} - -/* ---------- pass 1: arguments, modules, archives ---------- */ - -pass_1(argc, argv) -char **argv; -{ - register i; - register char *p; - register item_t *ip; -#ifdef ASLD - char armagic[SZMAGIC]; -#else - register nfile = 0; -#endif - - tempfile = fftemp(temppath, "asTXXXXXX"); -#ifdef LISTING - listmode = dflag; - if (listmode & 0440) - listfile = fftemp(listpath, "asLXXXXXX"); -#endif - for (ip = keytab; ip->i_type; ip++) - item_insert(ip, H_KEY+hash(ip->i_name)); - machstart(PASS_1); - while (--argc >= 0) { - p = *argv++; - if (p == 0) - continue; -#ifdef ASLD - if (p[0] == '-' && p[1] == '\0') { - input = stdin; - parse("STDIN"); - continue; - } -#else - if (nfile != 0) - fatal("second source file %s", p); - nfile++; -#endif - if ((input = fopen(p, "r")) == NULL) - fatal("can't open %s", p); -#ifdef ASLD - if ( - fread(armagic, SZMAGIC, 1, input) == 1 - && - strncmp(armagic, ARMAGIC, SZMAGIC) == 0 - ) { - archive(); - fclose(input); - continue; - } - rewind(input); -#endif - parse(p); - fclose(input); - } - commfinish(); - machfinish(PASS_1); -#ifdef ASLD - if (unresolved) { - nerrors++; - fflush(stdout); - fprintf(stderr, "unresolved references:\n"); - for (i = 0; i < H_SIZE; i++) { - ip = hashtab[H_GLOBAL+i]; - while (ip != 0) { - if ((ip->i_type & (S_EXT|S_TYP)) == (S_EXT|S_UND)) - fprintf(stderr, "\t%s\n", ip->i_name); - ip = ip->i_next; - } - } - } -#else - if (unresolved) - outhead.oh_flags |= HF_LINK; - if (nfile == 0) - fatal("no source file"); -#endif -} - -#ifdef ASLD -archive() -{ - register long offset; - register i; - register long modsize; - char modhead[SZMHEAD]; - - archmode++; - offset = SZMAGIC; - for (;;) { - if (unresolved == 0) - break; - fseek(input, offset, 0); - if (fread(modhead, SZMHEAD, 1, input) != 1) - break; - if ( - strncmp(&modhead[OFF_BEG], STR_BEG, LEN_BEG) - || - strncmp(&modhead[OFF_END], STR_END, LEN_END) - ) - fatal("bad archive"); - offset += SZMHEAD; - modsize = atol(&modhead[OFF_SIZ]); - archsize = modsize; - if (needed()) { - fseek(input, offset, 0); - archsize = modsize; - for (i = 0; i < LEN_NAM; i++) - if (modhead[OFF_NAM+i] == ' ') - break; - modhead[OFF_NAM+i] = '\0'; - parse(remember(&modhead[OFF_NAM])); - } - offset += modsize; - } - archmode = 0; -} - -needed() -{ - register c, first; - register item_t *ip; - register need; - -#ifdef LISTING - register save; - - save = listflag; listflag = 0; -#endif - need = 0; - peekc = -1; - first = 1; - for (;;) { - c = nextchar(); - if (c == '\n') { - first = 1; - continue; - } - if (c == ' ' || c == '\t' || c == ',') - continue; - if (ISALPHA(c) == 0) - break; - if ((ip = item_search(readident(c))) == 0) { - if (first) - break; - continue; - } - if (first) { - if (ip != &keytab[KEYDEFINE]) - break; - first = 0; - } - if ((ip->i_type & S_TYP) == S_UND) { - need++; - break; - } - } -#ifdef LISTING - listflag = save; -#endif - return(need); -} -#endif ASLD - -parse(s) -char *s; -{ - register i; - register item_t *ip; - register char *p; - - for (p = s; *p; ) - if (*p++ == '/') - s = p; -#ifdef ASLD - yylval.y_strp = s; - putval(MODULE); -#endif - for (i = 0; i < FB_SIZE; i++) - fb_ptr[FB_BACK+i] = 0; - newmodule(s); - peekc = -1; - yyparse(); - /* - * Check for undefined symbols - */ -#ifdef ASLD - for (i = 0; i < H_SIZE; i++) { - while (ip = hashtab[H_LOCAL+i]) { - /* - * cleanup local queue - */ - hashtab[H_LOCAL+i] = ip->i_next; - /* - * make undefined references extern - */ - if ((ip->i_type & (S_VAR|S_TYP)) == S_UND) - ip->i_type |= S_EXT; - /* - * relink externals in global queue - */ - if (ip->i_type & S_EXT) - item_insert(ip, H_GLOBAL+i); - } - } -#else - for (i = 0; i < H_SIZE; i++) { - for (ip = hashtab[H_LOCAL+i]; ip; ip = ip->i_next) { - if (ip->i_type & S_EXT) - continue; - if (ip->i_type != S_UND) - continue; - if (uflag == 0) - serror("undefined symbol %s", ip->i_name); - ip->i_type |= S_EXT; - } - } -#endif - /* - * Check for undefined numeric labels - */ - for (i = 0; i < FB_SIZE; i++) { - if ((ip = fb_ptr[FB_FORW+i]) == 0) - continue; - serror("undefined label %d", i); - fb_ptr[FB_FORW+i] = 0; - } -} - -pass_23(n) -{ - register i; -#ifdef ASLD - register addr_t base = 0; -#endif - register sect_t *sp; - - if (nerrors) - stop(); - pass = n; -#ifdef LISTING - listmode >>= 3; - if (listmode & 4) - ffreopen(listpath, listfile); - listeoln = 1; -#endif -#ifdef THREE_PASS - nbits = 0; -#endif - for (i = 0; i < FB_SIZE; i++) - fb_ptr[FB_FORW+i] = fb_ptr[FB_HEAD+i]; - outhead.oh_nemit = 0; - for (sp = sect; sp < §[outhead.oh_nsect]; sp++) { -#ifdef ASLD - if (sp->s_flag & BASED) { - base = sp->s_base; - if (base % sp->s_lign) - fatal("base not aligned"); - } else { - base += (sp->s_lign - 1); - base -= (base % sp->s_lign); - sp->s_base = base; - } - base += sp->s_size; - base += sp->s_comm; -#endif - outhead.oh_nemit += sp->s_size - sp->s_zero; - } - if (pass == PASS_3) - setupoutput(); - for (sp = sect; sp < §[outhead.oh_nsect]; sp++) { - sp->s_size = 0; - sp->s_zero = 0; -#ifdef THREE_PASS - sp->s_gain = 0; -#endif - } - machstart(n); -#ifndef ASLD - newmodule(modulename); -#endif ASLD - ffreopen(temppath, tempfile); - yyparse(); - commfinish(); - machfinish(n); -} - -newmodule(s) -char *s; -{ - switchsect(S_UND); - modulename = s; - lineno = 1; - if ((sflag & (SYM_EXT|SYM_LOC|SYM_LAB)) && PASS_SYMB) - newsymb(s, S_MOD, (short)0, (valu_t)0); -#ifdef LISTING - listtemp = 0; - if (dflag & 01000) - listtemp = listmode; - listflag = listtemp; -#endif -} - -setupoutput() -{ - register sect_t *sp; - register long off; - struct outsect outsect; - -#ifdef AOUTSEEK -#define AOUTseek(p,o) {aoutseek[p]=o;} - aoutfile = ffcreat(aoutpath); -#else -#define AOUTseek(p,o) {fseek(aoutfile[p],o,0);} - aoutfile[PARTEMIT]=ffcreat(aoutpath); -#ifdef RELOCATION - aoutfile[PARTRELO]=ffcreat(aoutpath); -#endif - aoutfile[PARTNAME]=ffcreat(aoutpath); - aoutfile[PARTCHAR]=ffcreat(aoutpath); -#endif - /* - * header generation - */ - AOUTseek(PARTEMIT, 0); - putofmt((char *)&outhead, SF_HEAD, PARTEMIT); - /* - * section table generation - */ - off = SZ_HEAD; - off += (long)outhead.oh_nsect * SZ_SECT; - for (sp = sect; sp < §[outhead.oh_nsect]; sp++) { - sp->s_foff = off; - outsect.os_base = SETBASE(sp); - outsect.os_size = sp->s_size + sp->s_comm; - outsect.os_foff = sp->s_foff; - outsect.os_flen = sp->s_size - sp->s_zero; - outsect.os_lign = sp->s_lign; - off += outsect.os_flen; - putofmt((char *)&outsect, SF_SECT, PARTEMIT); - } -#ifdef RELOCATION - AOUTseek(PARTRELO, off); - off += (long)outhead.oh_nrelo * SZ_RELO; -#endif - if (sflag == 0) - return; - AOUTseek(PARTNAME, off); - off += (long)outhead.oh_nname * SZ_NAME; - AOUTseek(PARTCHAR, off); - outhead.oh_nchar = off; /* see newsymb() */ -#undef AOUTseek -} - -commfinish() -{ - register i; - register item_t *ip; - register sect_t *sp; - register valu_t addr; - - switchsect(S_UND); -#ifdef ASLD - /* - * assign .comm labels and produce .comm symbol table entries - */ - for (i = 0; ii_next) { - if ((ip->i_type & S_COM) == 0) - continue; - sp = §[(ip->i_type & S_TYP) - S_MIN]; - if (pass == PASS_1) { - addr = sp->s_size + sp->s_comm; - sp->s_comm += ip->i_valu; - ip->i_valu = addr; - } -#ifdef THREE_PASS - if (pass == PASS_2) - ip->i_valu -= sp->s_gain; -#endif - if ((sflag & SYM_EXT) && PASS_SYMB) - newsymb( - ip->i_name, - ip->i_type & (S_EXT|S_TYP), - (short)0, - load(ip) - ); - } -#endif - if (PASS_SYMB == 0) - return; -#ifndef ASLD - /* - * produce symbol table entries for undefined's - */ - for (i = 0; ii_next) { - if (ip->i_type != (S_EXT|S_UND)) - continue; - if (pass != PASS_3) - /* - * save symbol table index - * for possible relocation - */ - ip->i_valu = outhead.oh_nname; - if (sflag & SYM_SCT) - newsymb( - ip->i_name, - S_EXT|S_UND, - (short)0, - (valu_t)0 - ); - } -#endif ASLD - /* - * produce symbol table entries for sections - */ - if (sflag & SYM_SCT) - for (sp = sect; sp < §[outhead.oh_nsect]; sp++) { - ip = sp->s_item; - newsymb( - ip->i_name, - (short)(ip->i_type | S_SCT), - (short)0, - load(ip) - ); - } -} diff --git a/mach/proto/as/comm5.c b/mach/proto/as/comm5.c deleted file mode 100644 index 09a00d271..000000000 --- a/mach/proto/as/comm5.c +++ /dev/null @@ -1,528 +0,0 @@ -/* @(#)comm5.c 1.1 */ - -#include "comm0.h" -#include "comm1.h" -#include "y.tab.h" - -extern YYSTYPE yylval; - -yylex() -{ - register c; - - if (pass == PASS_1) { - /* scan the input file */ - do - c = nextchar(); - while (isspace(c) && c != '\n'); - if (ISALPHA(c)) - c = inident(c); - else if (isdigit(c)) - c = innumber(c); - else switch (c) { - case '=': - case '<': - case '>': - case '|': - case '&': - c = induo(c); break; - case ASC_SQUO: - case ASC_DQUO: - c = instring(c); break; - case ASC_COMM: - do - c = nextchar(); - while (c != '\n' && c != '\0'); - break; - case CTRL('A'): - c = CODE1; readcode(1); break; - case CTRL('B'): - c = CODE2; readcode(2); break; - case CTRL('C'): - c = CODE4; readcode(4); break; - } - - /* produce the intermediate token file */ - if (c <= 0) - return(0); - if (c <= 127) - putc(c, tempfile); - else - putval(c); - } else { - /* read from intermediate token file */ - c = getc(tempfile); - if (c == EOF) - return(0); - if (c > 127) { - c += 128; - c = getval(c); - } - } - return(c); -} - -putval(c) -{ - register valu_t v; - register n; - register char *p; - - assert(c >= 256 && c < 256+128); - switch (c) { - case CODE1: - n = 1; goto putnum; - case CODE2: - n = 2; goto putnum; - case CODE4: - n = 4; goto putnum; - case NUMBER: - v = yylval.y_valu; - for (n = 0; n < sizeof(v); n++) { - if (v == 0) - break; - v >>= 8; - } - c = NUMBER0 + n; - putnum: - putc(c-128, tempfile); - v = yylval.y_valu; - while (--n >= 0) - putc(v >> (n*8), tempfile); - return; - case IDENT: - case FBSYM: - n = sizeof(item_t *); - p = (char *) &yylval.y_item; break; -#ifdef ASLD - case MODULE: - n = sizeof(char *); - p = (char *) &yylval.y_strp; break; -#endif - case STRING: - p = stringbuf; - n = (*p & 0377) + 1; break; - case OP_EQ: - case OP_NE: - case OP_LE: - case OP_GE: - case OP_LL: - case OP_RR: - case OP_OO: - case OP_AA: - n = 0; break; - default: - n = sizeof(word_t); - p = (char *) &yylval.y_word; break; - } - putc(c-128, tempfile); - while (--n >= 0) - putc(*p++, tempfile); -} - -getval(c) -{ - register n; - register valu_t v; - register char *p; - - switch (c) { - case CODE1: - n = 1; goto getnum; - case CODE2: - n = 2; goto getnum; - case CODE4: - n = 4; goto getnum; - case NUMBER0: - n = 0; c = NUMBER; goto getnum; - case NUMBER1: - n = 1; c = NUMBER; goto getnum; - case NUMBER2: - n = 2; c = NUMBER; goto getnum; - case NUMBER3: - n = 3; c = NUMBER; goto getnum; - case NUMBER: - n = 4; - getnum: - v = 0; - while (--n >= 0) { - v <<= 8; - v |= getc(tempfile); - } - yylval.y_valu = v; - return(c); - case IDENT: - case FBSYM: - n = sizeof(item_t *); - p = (char *) &yylval.y_item; break; -#ifdef ASLD - case MODULE: - n = sizeof(char *); - p = (char *) &yylval.y_strp; break; -#endif - case STRING: - p = stringbuf; -#ifdef DUK - *p++ = n = getc(tempfile); - p[n] = '\0'; - break; -#else DUK - *p++ = n = getc(tempfile); break; -#endif DUK - case OP_EQ: - case OP_NE: - case OP_LE: - case OP_GE: - case OP_LL: - case OP_RR: - case OP_OO: - case OP_AA: - n = 0; break; - default: - n = sizeof(word_t); - p = (char *) &yylval.y_word; break; - } - while (--n >= 0) - *p++ = getc(tempfile); - return(c); -} - -/* ---------- lexical scan in pass 1 ---------- */ - -nextchar() -{ - register c; - - if (peekc != -1) { - c = peekc; - peekc = -1; - return(c); - } -#ifdef ASLD - if (archmode && --archsize < 0) - return(0); -#endif - if ((c = getc(input)) == EOF) - return(0); - if (isascii(c) == 0) - fatal("non-ascii character"); -#ifdef LISTING - if (listflag & 0440) - putc(c, listfile); -#endif - return(c); -} - -readcode(n) -{ - register c; - - yylval.y_valu = 0; - do { - if ( -#ifdef ASLD - (archmode && --archsize < 0) - || -#endif - (c = getc(input)) == EOF - ) - fatal("unexpected EOF in compact input"); - yylval.y_valu <<= 8; - yylval.y_valu |= c; - } while (--n); -} - -induo(c) -register c; -{ - static short duo[] = { - ('='<<8) | '=', OP_EQ, - ('<'<<8) | '>', OP_NE, - ('<'<<8) | '=', OP_LE, - ('>'<<8) | '=', OP_GE, - ('<'<<8) | '<', OP_LL, - ('>'<<8) | '>', OP_RR, - ('|'<<8) | '|', OP_OO, - ('&'<<8) | '&', OP_AA, - }; - register short *p; - - c = (c<<8) | nextchar(); - for (p = duo; *p; p++) - if (*p++ == c) - return(*p++); - peekc = c & 0377; - return(c>>8); -} - -inident(c) -char c; -{ - register char *p; - register item_t *ip; - - p = readident(c); - ip = item_search(p); - if (ip == 0) { - ip = item_alloc(S_UND); - ip->i_name = remember(p); - /* printf("ident %s %o\n", ip->i_name, ip); */ - unresolved++; - item_insert(ip, H_LOCAL + (hashindex%H_SIZE)); - } else if (hashindex < H_SIZE) { - assert(H_KEY == 0); - yylval.y_word = (word_t) ip->i_valu; - return(ip->i_type); - } - yylval.y_item = ip; - return(IDENT); -} - -char * -readident(c) -register c; -{ - static char name[NAMEMAX+1]; - register n = NAMEMAX; - register char *p = name; - - do { - if (--n >= 0) - *p++ = c; - c = nextchar(); - } while (ISALNUM(c)); - *p++ = '\0'; - peekc = c; - return(name); -} - -innumber(c) -register c; -{ - register char *p; - register radix; - static char num[20+1]; - - p = num; - radix = 20; - do { - if (--radix < 0) - fatal("number too long"); - if (isupper(c)) - c += ('a' - 'A'); - *p++ = c; - c = nextchar(); - } while (ISALNUM(c)); - peekc = c; - *p = '\0'; - c = *--p; - p = num; - radix = 10; - if (*p == '0') { - radix = 8; - p++; - if (*p == 'x') { - radix = 16; - p++; - } else if (*p == 'b') { - radix = 2; - p++; - } - } - if (radix != 16 && (c == 'f' || c == 'b')) - return(infbsym(num)); - yylval.y_valu = 0; - while (c = *p++) { - if (c > '9') - c -= ('a' - '9' - 1); - c -= '0'; - if (c >= radix) - serror("digit exceeds radix"); - yylval.y_valu = yylval.y_valu * radix + c; - } - return(NUMBER); -} - -instring(termc) -{ - register char *p; - register c; - - p = stringbuf+1; - for (;;) { - c = nextchar(); - if (c == '\n' || c == '\0') { - peekc = c; - serror("non-terminated string"); - break; - } - if (c == termc) - break; - if (c == '\\') - c = inescape(); -#ifdef DUK - if (p >= &stringbuf[STRINGMAX - 1]) -#else DUK - if (p >= &stringbuf[STRINGMAX]) -#endif DUK - fatal("string buffer overflow"); - *p++ = c; - } - stringbuf[0] = p - stringbuf - 1; -#ifdef DUK - *p = '\0'; -#endif DUK - return(STRING); -} - -inescape() -{ - register c, j, r; - - c = nextchar(); - if (c >= '0' && c <= '7') { - r = c - '0'; - for (j = 0; j < 2; j++) { - c = nextchar(); - if (c < '0' || c > '7') { - peekc = c; - return(r); - } - r <<= 3; - r += (c - '0'); - } - return(r); - } - switch (c) { - case 'b': return('\b'); - case 'f': return('\f'); - case 'n': return('\n'); - case 'r': return('\r'); - case 't': return('\t'); - case '\'': return('\''); - case '"': return('"'); - } - return(c); -} - -infbsym(p) -register char *p; -{ - register lab; - register item_t *ip; - - lab = *p++ - '0'; - if ((unsigned)lab < 10) { - if (*p++ == 'f') { - ip = fb_ptr[FB_FORW+lab]; - if (ip == 0) { - ip = fb_alloc(lab); - fb_ptr[FB_FORW+lab] = ip; - } - goto ok; - } - ip = fb_ptr[FB_BACK+lab]; - if (ip != 0 && *p == 0) - goto ok; - } - serror("bad numeric label"); - ip = fb_alloc(0); -ok: - yylval.y_item = ip; - return(FBSYM); -} - -hash(p) -register char *p; -{ - register unsigned h; - register c; - - h = 0; - while (c = *p++) { - h <<= 2; - h += c; - } - return(h % H_SIZE); -} - -item_t * -item_search(p) -register char *p; -{ - register h; - register item_t *ip; - - for (h = hash(p); h < H_TOTAL; h += H_SIZE) { - ip = hashtab[h]; - while (ip != 0) { - if (strcmp(p, ip->i_name) == 0) - goto done; - ip = ip->i_next; - } - } -done: - hashindex = h; - return(ip); -} - -item_insert(ip, h) -item_t *ip; -{ - ip->i_next = hashtab[h]; - hashtab[h] = ip; -} - -item_t * -item_alloc(typ) -{ - register item_t *ip; - static nleft = 0; - static item_t *next; - - if (--nleft < 0) { - next = (item_t *) sbrk(MEMINCR); - if ((int) next == -1) - fatal("out of memory"); - nleft += (MEMINCR / sizeof(item_t)); - } - ip = next++; - ip->i_next = 0; - ip->i_type = typ; - ip->i_name = 0; - ip->i_valu = 0; - return(ip); -} - -item_t * -fb_alloc(lab) -register lab; -{ - register item_t *ip, *p; - - ip = item_alloc(S_UND); - p = fb_ptr[FB_TAIL+lab]; - if (p == 0) - fb_ptr[FB_HEAD+lab] = ip; - else - p->i_next = ip; - fb_ptr[FB_TAIL+lab] = ip; - return(ip); -} - -item_t * -fb_shift(lab) -register lab; -{ - register item_t *ip; - - ip = fb_ptr[FB_FORW+lab]; - if (ip == 0) - if (pass == PASS_1) - ip = fb_alloc(lab); - else - ip = fb_ptr[FB_HEAD+lab]; - fb_ptr[FB_BACK+lab] = ip; - fb_ptr[FB_FORW+lab] = ip->i_next; - return(ip); -} diff --git a/mach/proto/as/comm6.c b/mach/proto/as/comm6.c deleted file mode 100644 index 624b143a1..000000000 --- a/mach/proto/as/comm6.c +++ /dev/null @@ -1,362 +0,0 @@ -/* @(#)comm6.c 1.7 */ -/* - * implement pseudo instructions - */ - -#include "comm0.h" -#include "comm1.h" -#include "y.tab.h" - -newequate(ip, typ) -register item_t *ip; -register short typ; -{ - typ &= ~S_EXT; - if (typ & S_COM) - typ = S_UND; - else if ((typ & S_VAR) && (typ & S_TYP) != S_ABS) - typ = S_UND; -#ifdef THREE_PASS - else if (pass == PASS_1 && typ == S_UND) - typ = S_VAR; - else if (pass == PASS_2 && (ip->i_type & S_TYP) == S_UND) - ip->i_type |= typ; -#endif THREE_PASS - if (typ == S_UND) - serror("illegal equate"); - if (pass == PASS_3) - assert((ip->i_type & S_TYP) == (typ & S_TYP)); - newident(ip, typ); -} - -newident(ip, typ) -register item_t *ip; -{ - register flag; -#ifdef GENLAB - static char genlab[] = GENLAB; -#endif GENLAB - - if (pass == PASS_1) { - /* printf("declare %s: %o\n", ip->i_name, typ); */ - if (ip->i_type & ~S_EXT) - serror("multiple declared"); - else - --unresolved; - ip->i_type |= typ; - } - if (PASS_SYMB == 0) - return; -#ifdef THREE_PASS - if (ip->i_type & S_EXT) - flag = SYM_EXT; - else - flag = SYM_LOC; -#else - flag = SYM_EXT|SYM_LOC; /* S_EXT not stable in PASS_1 */ -#endif THREE_PASS -#ifdef GENLAB - if (strncmp(ip->i_name, genlab, sizeof(genlab)-1) == 0) - flag = SYM_LAB; -#endif GENLAB - if (sflag & flag) - newsymb( - ip->i_name, - ip->i_type & (S_EXT|S_TYP), - (short)0, - load(ip) - ); -} - -newlabel(ip) -register item_t *ip; -{ -#ifdef THREE_PASS - register addr_t oldval = ip->i_valu; -#endif - - if (DOTSCT == NULL) - nosect(); - ip->i_type &= ~S_TYP; - ip->i_type |= DOTTYP; - if (store(ip, (valu_t) DOTVAL) == 0) - return; -#ifdef THREE_PASS - assert(pass != PASS_2 || oldval - ip->i_valu == DOTGAIN); -#endif -} - -newsect(ip) -register item_t *ip; -{ - register ushort typ; - register sect_t *sp = NULL; - - typ = ip->i_type & S_TYP; - if (typ == S_UND) { - /* - * new section - */ - assert(pass == PASS_1); - --unresolved; - typ = outhead.oh_nsect + S_MIN; - outhead.oh_nsect++; - if (outhead.oh_nsect > SECTMAX || typ > S_MAX) - fatal("too many sections"); - sp = §[typ - S_MIN]; - sp->s_item = ip; - sp->s_lign = ALIGNSECT; -#ifdef DUK - ip->i_type = typ; -#else DUK - ip->i_type = typ | S_EXT; -#endif DUK - ip->i_valu = 0; - } else if (typ >= S_MIN) { - sp = §[typ - S_MIN]; - if (sp->s_item != ip) - sp = NULL; - } - if (sp == NULL) - serror("multiple declared"); - else - switchsect(typ); -} - -newbase(base) -valu_t base; -{ -#ifdef ASLD - register sect_t *sp; - - if ((sp = DOTSCT) == NULL) - nosect(); - if (sp->s_flag & BASED) - serror("already based"); - sp->s_base = base; - sp->s_flag |= BASED; - DOTVAL += base; -#else - warning(".base ignored"); -#endif -} - -/* - * NOTE: A rather different solution is used for ASLD and NOLD: - * ASLD: - * - maximum length of .comm is recorded in i_valu during PASS_1 - * - address of .comm is recorded in i_valu in later passes: - * assigned at end of PASS_1, corrected for s_gain at end of PASS_2 - * - symbol table entries are produced in commfinish() - * NOLD: - * - i_valu cannot be used since it is needed for relocation info - * - only one .comm with a particular symbol is allowed per module - * - symbol table entries are produced in newcomm() - */ -newcomm(ip, val) -register item_t *ip; -valu_t val; -{ - if (pass == PASS_1) { - if (DOTSCT == NULL) - nosect(); - if (val == 0) - serror("bad size"); - /* printf("declare %s: %o\n", ip->i_name, DOTTYP); */ - if ((ip->i_type & ~S_EXT) == S_UND) { - --unresolved; - ip->i_type = S_COM|S_EXT|DOTTYP; -#ifdef ASLD - ip->i_valu = val; - } else if (ip->i_type == (S_COM|S_EXT|DOTTYP)) { - if (ip->i_valu < val) - ip->i_valu = val; -#endif - } else - serror("multiple declared"); - } -#ifndef ASLD - if (PASS_SYMB == 0) - return; - if (pass != PASS_3) - /* - * save symbol table index - * for possible relocation - */ - ip->i_valu = outhead.oh_nname; -#ifdef DUK - newsymb(ip->i_name, S_COM|S_EXT|DOTTYP, (short)0, val); -#else DUK - newsymb(ip->i_name, S_EXT|DOTTYP, (short)0, val); -#endif DUK -#endif -} - -switchsect(newtyp) -short newtyp; -{ - register sect_t *sp; - - if (sp = DOTSCT) - sp->s_size = DOTVAL - sp->s_base; - if (newtyp == S_UND) { - DOTSCT = NULL; - DOTTYP = newtyp; - return; - } - assert(newtyp >= S_MIN); - sp = §[newtyp - S_MIN]; - if (pass == PASS_3) { -#ifdef AOUTSEEK - aoutpart = -1; - aoutseek[PARTEMIT] = sp->s_foff + sp->s_size - sp->s_zero; -#else - fseek(aoutfile[PARTEMIT], sp->s_foff + sp->s_size - sp->s_zero, 0); -#endif - } - DOTVAL = sp->s_size + sp->s_base; - DOTSCT = sp; - DOTTYP = newtyp; -} - -align(bytes) -valu_t bytes; -{ - register valu_t gap; - register sect_t *sp; - - if ((sp = DOTSCT) == NULL) - nosect(); - if (bytes == 0) - bytes = ALIGNWORD; - if (sp->s_lign % bytes) - if (bytes % sp->s_lign) - serror("illegal alignment"); - else - sp->s_lign = bytes; - if (pass == PASS_1) - /* - * be pessimistic: biggest gap possible - */ - gap = bytes - 1; - else { - /* - * calculate gap correctly; - * will be the same in PASS_2 and PASS_3 - */ - if ((gap = DOTVAL % bytes) != 0) - gap = bytes - gap; -#ifdef THREE_PASS - if (pass == PASS_2) - /* - * keep track of gain with respect to PASS_1 - */ - DOTGAIN += (bytes - 1) - gap; -#endif - } - DOTVAL += gap; - sp->s_zero += gap; -} - -#ifdef RELOCATION -newrelo(s, n) -short s; -{ - struct outrelo outrelo; -#ifdef DUK - int iscomm; -#endif DUK - - if (rflag == 0) - return; - if (PASS_RELO == 0) - return; - s &= ~S_DOT; - assert((s & ~(S_COM|S_VAR|S_TYP)) == 0); -#ifndef THREE_PASS - if (s == S_UND) - serror("bad relocation"); -#endif - /* - * always relocation info if S_VAR to solve problems with: - * move b,d0 - * b=a - * a: .data2 0 - */ -#ifdef DUK - iscomm = s & S_COM; -#endif DUK - s &= ~S_COM; - if ((n & RELPC) == 0 && s == S_ABS) - return; - if ((n & RELPC) != 0 && s == DOTTYP) - return; - if (pass != PASS_3) { - outhead.oh_nrelo++; - return; - } - s &= ~S_VAR; - outrelo.or_type = (char)n; - outrelo.or_sect = (char)DOTTYP; -#ifndef ASLD -#ifdef DUK - if (s == S_UND || iscomm) { -#else DUK - if (s == S_UND) { -#endif DUK - assert(relonami != 0); - outrelo.or_nami = relonami-1; - relonami = 0; - } else -#endif - if (s < S_MIN) { - assert(s == S_ABS); - /* - * use first non existing entry (argh) - */ - outrelo.or_nami = outhead.oh_nname; - } else { - /* - * section symbols are at the end - */ - outrelo.or_nami = outhead.oh_nname - - outhead.oh_nsect - + (s - S_MIN) - ; - } - outrelo.or_addr = (long)DOTVAL; - putofmt((char *)&outrelo, SF_RELO, PARTRELO); -} -#endif - -newsymb(name, type, desc, valu) -register char *name; -short type; -short desc; -valu_t valu; -{ - struct outname outname; - - if (name && *name == 0) - name = 0; - assert(PASS_SYMB); - if (pass != PASS_3) { - if (name) - outhead.oh_nchar += strlen(name)+1; - outhead.oh_nname++; - return; - } - if (name) { - AOUTPART(PARTCHAR); - outname.on_foff = outhead.oh_nchar; - do { - AOUTPUTC(*name, PARTCHAR); - outhead.oh_nchar++; - } while (*name++); - } else - outname.on_foff = 0; - outname.on_type = type; - outname.on_desc = desc; - outname.on_valu = valu & ~((0xFFFFFFFF)<<(8*sizeof(valu_t))); - putofmt((char *)&outname, SF_NAME, PARTNAME); -} diff --git a/mach/proto/as/comm7.c b/mach/proto/as/comm7.c deleted file mode 100644 index 38612b77b..000000000 --- a/mach/proto/as/comm7.c +++ /dev/null @@ -1,430 +0,0 @@ -/* @(#)comm7.c 1.10 */ -/* - * miscellaneous - */ - -#include "comm0.h" -#include "comm1.h" -#include "y.tab.h" - -valu_t -load(ip) -register item_t *ip; -{ -#ifdef ASLD - register short typ; - - typ = ip->i_type & S_TYP; - if ((typ -= S_MIN) < 0) /* S_UND or S_ABS */ - return(ip->i_valu); - return(ip->i_valu + sect[typ].s_base); -#else -#ifdef DUK - if ((ip->i_type & S_TYP) == S_UND || (ip->i_type & S_COM)) { -#else DUK - if ((ip->i_type & S_TYP) == S_UND) { -#endif DUK - if (pass == PASS_3) { - if (relonami != 0) - serror("relocation error"); - relonami = ip->i_valu+1; - } - return(0); - } - return(ip->i_valu); -#endif -} - -store(ip, val) -register item_t *ip; -valu_t val; -{ -#ifdef ASLD - register short typ; - - typ = ip->i_type & S_TYP; - if ((typ -= S_MIN) >= 0) - val -= sect[typ].s_base; -#else - if ((ip->i_type & S_TYP) == S_UND) - return(0); -#endif - assert(pass != PASS_3 || (ip->i_type & S_VAR) || ip->i_valu == val); - ip->i_valu = val; - return(1); -} - -char * -remember(s) -register char *s; -{ - register char *p; - register n; - static nleft = 0; - static char *next; - - p = s; - n = 0; - do - n++; - while (*p++); - if ((nleft -= n) < 0) { - next = sbrk(MEMINCR); - if ((int) next == -1) - fatal("out of memory"); - nleft = (MEMINCR / sizeof(char)) - n; - assert(nleft >= 0); - } - p = next; - while (*p++ = *s++) - ; - s = next; - next = p; - return(s); -} - -combine(typ1, typ2, op) -register typ1, typ2; -{ - switch (op) { - case '+': - if (typ1 == S_ABS) - return(typ2); - if (typ2 == S_ABS) - return(typ1); - break; - case '-': - if (typ2 == S_ABS) - return(typ1); - if ((typ1 & ~S_DOT) == (typ2 & ~S_DOT) && typ1 != S_UND) - return(S_ABS|S_VAR); - break; - case '>': - if (typ1 == S_ABS && typ2 == S_ABS) - return(S_ABS); - if ( - ((typ1 & ~S_DOT) == (typ2 & ~S_DOT) && typ1 != S_UND) - || (typ1 == S_ABS) - || (typ2 == S_ABS) - ) - return(S_ABS|S_VAR); - break; - default: - if (typ1 == S_ABS && typ2 == S_ABS) - return(S_ABS); - break; - } - if (pass != PASS_1) - serror("illegal operator"); - return(S_UND); -} - -#ifdef LISTING -printx(ndig, val) -valu_t val; -{ - static char buf[8]; - register char *p; - register c, n; - - p = buf; n = ndig; - do { - *p++ = (int) val & 017; - val >>= 4; - } while (--n); - do { - c = "0123456789ABCDEF"[*--p]; - putchar(c); - } while (p > buf); - return(ndig); -} -#endif - -#ifdef LISTING -listline(textline) -{ - register c; - - if ((listflag & 4) && (c = getc(listfile)) != '\n' && textline) { - if (listcolm >= 24) - printf(" \\\n\t\t\t"); - else - do { - putchar('\t'); - listcolm += 8; - } while (listcolm < 24); - do { - assert(c != EOF); - putchar(c); - } while ((c = getc(listfile)) != '\n'); - } - if (listflag & 7) - putchar('\n'); - listeoln = 1; - listcolm = 0; - listflag = listtemp; -} -#endif LISTING - -/* ---------- code optimization ---------- */ - -#ifdef THREE_PASS -small(fitsmall, gain) -{ - register bit; - register char *p; - - if (DOTSCT == NULL) - nosect(); - if (bflag) - return(0); - if ((bit = nbits++) >= BITMAX) { - if (bit != BITMAX) - nbits--; /* prevent wraparound */ - else if (pass == PASS_1) - warning("bit table overflow"); - return(0); - } - p = &bittab[bit>>3]; - bit = 1 << (bit&7); - switch (pass) { - case PASS_1: - return(0); - case PASS_2: - if (fitsmall) { - DOTGAIN += gain; - *p |= bit; - } - return(fitsmall); - case PASS_3: - assert(fitsmall || (*p & bit) == 0); - return(*p & bit); - } -} -#endif - -/* ---------- output ---------- */ - -emit1(arg) -char arg; -{ -#ifdef LISTING - if (listeoln) { - if (listflag & 1) { - listcolm += printx(VALWIDTH, DOTVAL); - listcolm++; - putchar(' '); - } - listeoln = 0; - } - if (listflag & 2) - listcolm += printx(2, (valu_t) arg); -#endif - switch (pass) { - case PASS_1: - if (DOTSCT == NULL) - nosect(); - /* no break */ - case PASS_2: - DOTSCT->s_zero = 0; - break; - case PASS_3: - AOUTPART(PARTEMIT); - while (DOTSCT->s_zero) { - AOUTPUTC(0, PARTEMIT); - DOTSCT->s_zero--; - } - AOUTPUTC(arg, PARTEMIT); - break; - } - DOTVAL++; -} - -emit2(arg) -short arg; -{ -#ifdef BYTES_REVERSED - emit1((char)(arg>>8)); emit1((char)arg); -#else - emit1((char)arg); emit1((char)(arg>>8)); -#endif -} - -emit4(arg) -long arg; -{ -#ifdef WORDS_REVERSED - emit2((short)(arg>>16)); emit2((short)(arg)); -#else - emit2((short)(arg)); emit2((short)(arg>>16)); -#endif -} - -emitx(val, n) -valu_t val; -register n; -{ - switch (n) { - case 1: - emit1((char)val); break; - case 2: - emit2((short)val); break; - case 4: - emit4((long)val); break; - default: - assert(0); - } -} - -emitstr(zero) -{ - register i; - register char *p; - - p = stringbuf; - i = *p++ & 0377; - while (--i >= 0) - emit1(*p++); - if (zero) - emit1(0); -} - -/* ---------- Error checked file I/O ---------- */ - -ffreopen(s, f) -char *s; -FILE *f; -{ - if (freopen(s, "r", f) == NULL) - fatal("can't reopen %s", s); -} - -FILE * -ffcreat(s) -char *s; -{ - FILE *f; - - if ((f = fopen(s, "w")) == NULL) - fatal("can't create %s", s); - return(f); -} - -FILE * -fftemp(path, tail) -char *path; -{ - register char *dir; - - if ((dir = getenv("TMPDIR")) == NULL) -#ifdef TMPDIR - dir = TMPDIR; -#else - dir = "/tmp"; -#endif - sprintf(path, "%s/%s", dir, tail); - return(ffcreat(mktemp(path))); -} - -putofmt(p, s, part) -register char *p; -register char *s; -{ - register i; - register long l; - - AOUTPART(part); - while (i = *s++) { - switch (i -= '0') { -/* case 0: p++; break; */ - case 1: - l = (long) *((char *)p); p += sizeof(char ); - break; - case 2: - l = (long) *((short *)p); p += sizeof(short); - break; - case 4: - l = (long) *((long *)p); p += sizeof(long ); - break; - default: - assert(0); - } - while (--i >= 0) { - AOUTPUTC((int)l, part); - l >>= 8; - } - } -} - -/* ---------- Error handling ---------- */ - -yyerror(){} /* we will do our own error printing */ - -nosect() -{ - fatal("no sections"); -} - -werror() -{ - fatal("write error"); -} - -/* VARARGS1 */ -fatal(s, a1, a2, a3, a4) -char *s; -{ - nerrors++; - diag(" (fatal)\n", s, a1, a2, a3, a4); - stop(); -} - -#if DEBUG == 2 -assert2(file, line) -char *file; -{ - fatal("assertion failed (%s, %d)", file, line); -} -#endif - -#if DEBUG == 1 -assert1() -{ - diag(" (fatal)\n", "assertion failed"); - abort(); -} -#endif - -/* VARARGS1 */ -serror(s, a1, a2, a3, a4) -char *s; -{ - nerrors++; - diag("\n", s, a1, a2, a3, a4); -} - -/* VARARGS1 */ -warning(s, a1, a2, a3, a4) -char *s; -{ - diag(" (warning)\n", s, a1, a2, a3, a4); -} - -/* VARARGS1 */ -diag(tail, s, a1, a2, a3, a4) -char *tail, *s; -{ - fflush(stdout); - if (modulename) - fprintf(stderr, "\"%s\", line %d: ", modulename, lineno); - else - fprintf(stderr, "%s: ", progname); - fprintf(stderr, s, a1, a2, a3, a4); - fprintf(stderr, tail); -} - -nofit() -{ - if (pass == PASS_3) - warning("too big"); -} diff --git a/mach/proto/as/comm8.c b/mach/proto/as/comm8.c deleted file mode 100644 index 9575a9c13..000000000 --- a/mach/proto/as/comm8.c +++ /dev/null @@ -1,9 +0,0 @@ -/* @(#)comm8.c 1.1 */ - -#include "comm0.h" -#include "comm1.h" -#include "y.tab.h" - -/* ========== Machine dependent C routines ========== */ - -#include "mach5.c" diff --git a/mach/proto/cg/regvar.c b/mach/proto/cg/regvar.c index 196bf3b4b..a64417989 100644 --- a/mach/proto/cg/regvar.c +++ b/mach/proto/cg/regvar.c @@ -116,6 +116,10 @@ fixregvars(saveall) { } } f_regsave(); +#ifndef TEM_BSIZE + for(rv=rvlist;rv!=0;rv=rv->rv_next) + if (rv->rv_off >= 0) rv->rv_off += TEM_BSIZE; +#endif } isregvar(off) long off; { diff --git a/mach/proto/cg/types.h b/mach/proto/cg/types.h index a14f22601..dad9a51dc 100644 --- a/mach/proto/cg/types.h +++ b/mach/proto/cg/types.h @@ -20,7 +20,14 @@ typedef char * string; #define full int #endif +#if TEM_WSIZE>2 #define word long #ifndef WRD_FMT -#define WRD_FMT "%ld" +#define WRD_FMT "%D" #endif WRD_FMT +#else +#define word int +#ifndef WRD_FMT +#define WRD_FMT "%d" +#endif WRD_FMT +#endif diff --git a/mach/proto/ncg/codegen.c b/mach/proto/ncg/codegen.c index fd11d801f..510dd9146 100644 --- a/mach/proto/ncg/codegen.c +++ b/mach/proto/ncg/codegen.c @@ -392,14 +392,14 @@ if(Debug>1) fprintf(stderr,"Next tuple %d,%d,%d,%d\n", ntup = tup->p_next; for (i=0,t=0;ip_rar[i]); - if ( t2) fprintf(stderr,"Continuing match after coercions\n"); #endif t += codegen(codep,ply,FALSE,mincost-t,0); } - if ( t=&fakestack[0];tp--) if (tp->t_token==-1) { if(tp->t_att[0].ar==result.e_v.e_reg) diff --git a/mach/proto/ncg/move.c b/mach/proto/ncg/move.c index 34c90a144..4c2e7fa81 100644 --- a/mach/proto/ncg/move.c +++ b/mach/proto/ncg/move.c @@ -96,9 +96,7 @@ move(tp1,tp2,ply,toplevel,maxcost) token_p tp1,tp2; unsigned maxcost; { fakestack[stackheight] = *tp2; fakestack[stackheight+1] = *tp1; stackheight += 2; - tokpatlen += 2; t = codegen(&coderules[mp->m_cindex],ply,toplevel,maxcost,0); - tokpatlen -= 2; stackheight -= 2; return(t); } @@ -145,9 +143,7 @@ test(tp,ply,toplevel,maxcost) token_p tp; unsigned maxcost; { fakestack[stackheight] = *tp; stackheight++; - tokpatlen++; t = codegen(&coderules[mp->t_cindex],ply,toplevel,maxcost,0); - tokpatlen--; stackheight--; return(t); } diff --git a/mach/proto/ncg/subr.c b/mach/proto/ncg/subr.c index 4f3f25e66..b04086d57 100644 --- a/mach/proto/ncg/subr.c +++ b/mach/proto/ncg/subr.c @@ -392,66 +392,6 @@ tref(tp,amount) register token_p tp; { } #define MAXSAVE 10 -/* A few routines to save the top of the current stack, - restore it and check whether a certain register is present in the - saved stack -*/ -token_t aside[MAXSAVE] ; -int aside_length = -1 ; - -save_stack(tp) register token_p tp ; { - int i ; - - aside_length = &fakestack[stackheight-1] -tp; - assert(aside_length<=MAXSAVE); -#ifndef NDEBUG - if (aside_length!=0 && Debug>1) - fprintf(stderr,"Saving %d items from fakestack\n",aside_length); -#endif - for (i=1;i<=aside_length;i++) - aside[i-1] = tp[i]; - stackheight -= aside_length; -} - -in_stack(reg) { - register token_p tp ; - register i ; - register tkdef_p tdp ; - - for ( i=0, tp=aside ; it_token==-1) { - if(tp->t_att[0].ar==reg) - goto gotone ; - } else { - tdp = &tokens[tp->t_token]; - for(i=0;it_type[i]==EV_REG && - tp->t_att[i].ar==reg) - goto gotone ; - } - return 0 ; -gotone: -#ifndef NDEBUG - if ( Debug>2 ) - fprintf(stderr,"Register %d present on non-visible stack\n", - reg ) ; -#endif - return 1 ; -} - -rest_stack() { - register int i ; - - assert(aside_length!= -1); -#ifndef NDEBUG - if (aside_length!=0 && Debug>1) - fprintf(stderr,"Restoring %d items to fakestack(%d)\n", - aside_length,stackheight); -#endif - for (i=0;ic2_nsplit-1c2_codep],ply,toplevel,MAXINT,0); tokpatlen = tpl; - rest_stack(); + for (i=0;ic2_nsplit); } #endif MAXSPLIT unsigned docoerc(tp,cp,ply,toplevel,forced) token_p tp; register c3_p cp; { + token_t savestack[MAXSAVE]; + token_p stp; + register int i,diff; unsigned cost; int tpl; /* saved tokpatlen */ - save_stack(tp) ; + stp = &fakestack[stackheight-1]; + diff = stp -tp; + assert(diff<=MAXSAVE); +#ifndef NDEBUG + if (diff!=0 && Debug>1) + fprintf(stderr,"Saving %d items from fakestack\n",diff); +#endif + for (i=1;i<=diff;i++) + savestack[i-1] = tp[i]; + stackheight -= diff; tpl = tokpatlen; tokpatlen = 1; cost = codegen(&coderules[cp->c3_codep],ply,toplevel,MAXINT,forced); tokpatlen = tpl; - rest_stack() ; +#ifndef NDEBUG + if (diff!=0 && Debug>1) + fprintf(stderr,"Restoring %d items to fakestack(%d)\n",diff,stackheight); +#endif + for (i=0;i2 #define word long +#else +#define word int +#endif diff --git a/mach/s2650/as/Makefile b/mach/s2650/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/s2650/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/vax4/as/Makefile b/mach/vax4/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/vax4/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/z80/as/Makefile b/mach/z80/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/z80/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/mach/z80/libmon/putchr.nas.s b/mach/z80/libmon/putchr.nas.s deleted file mode 100644 index e0dbdeb67..000000000 --- a/mach/z80/libmon/putchr.nas.s +++ /dev/null @@ -1,28 +0,0 @@ -.define putchr -! output routine in monitor -CRT = 0x013B -! output a charcter -! entry: ascii character in a -putchr: - push hl - push bc - ld hl,tab - ld b,5 -1: cp (hl) - jr z,fetch - inc hl - inc hl - djnz 1b -2: call CRT - pop bc - pop hl - ret -fetch: inc hl - ld a,(hl) - jr 2b -! conversion table for nascom characters -tab: .byte 0x0D,0x00 - .byte 0x1B,0x1E - .byte 0x08,0x1D - .byte 0x0A,0x1F - .byte 0x7F,0x00 diff --git a/mach/z80/libmon/putchr.s b/mach/z80/libmon/putchr.s deleted file mode 100644 index db15bf216..000000000 --- a/mach/z80/libmon/putchr.s +++ /dev/null @@ -1,21 +0,0 @@ -.define putchr - -putchr: - push hl - push de - push bc - cp 0x0A - jr nz,1f - ld a,0x1F -1: - ld c,a -2: - in a,0xF1 - and 4 - jr z,2b - ld a,c - out 0xF0,a - pop bc - pop de - pop hl - ret diff --git a/mach/z80/libmon/subr.s b/mach/z80/libmon/subr.s deleted file mode 100644 index 253048892..000000000 --- a/mach/z80/libmon/subr.s +++ /dev/null @@ -1,197 +0,0 @@ -.define _read,_write,_ioctl,_getpid,_open,_close,_exit,_errno -_read: - ld (savebc),bc - push af - pop bc - ld (saveaf),bc ! save all registers in savereg - ld (savede),de - ld (savehl),hl - ld (saveix),ix - ex (sp),hl ! return address in hl - pop bc ! skip return address - pop bc ! get fd - ld a,b ! check fd = 0 - or c - jr nz,errrd - pop de ! get buffer - pop bc ! get count - ld ix,0 ! reset counter - push bc - push de - push ix - push hl ! return address - ex de,hl ! buffer to hl -1: ld a,b - or c - jr z,done ! done if count = 0 - call getchr - ld (hl),a - inc hl ! increment pointer - inc ix ! increment char counter - dec bc ! decrement count - cp 0xA - jr nz,1b ! done if char = CR -done: - ld bc,(saveaf) - push bc - pop af - ld bc,(savebc) - ld de,(savede) - ld hl,(savehl) - ld ix,(saveix) - ret -errrd: - push bc - push hl ! return address - ld bc,(saveaf) - push bc - pop af - ld bc,(savebc) - ld de,(savede) - ld hl,(savehl) - ld ix,(saveix) - ld ix,-1 - ret - -_write: - ld (savebc),bc - push af - pop bc - ld (saveaf),bc ! save all registers in savereg - ld (savede),de - ld (savehl),hl - ld (saveix),ix - ex (sp),hl ! return address in hl - pop de ! skip return address - pop de ! get fd - ld a,e ! check for fd = 1 - cp 1 - jr nz,errwr - ld a,d - or a - jr nz,errwr - pop de ! buffer in de - pop bc ! count in bc - push bc - push de - push de - push hl - ex de,hl ! buffer in hl - ld e,c - ld d,b ! count also in de -1: ld a,b - or c - jr z,exit - ld a,(hl) - call putchr - inc hl - dec bc - jr 1b -errwr: - push de - push hl - ld bc,(saveaf) - push bc - pop af - ld bc,(savebc) - ld de,(savede) - ld hl,(savehl) - ld ix,(saveix) - ld ix,-1 ! error in fd - ret -exit: - push de ! count on stack - ld bc,(saveaf) - push bc - pop af - ld bc,(savebc) - ld de,(savede) - ld hl,(savehl) - ld ix,(saveix) - pop ix ! return count to caller - ret - -_ioctl: - ret -_getpid: - ret - -! open return a file descriptor (0,1,2) -! depending on 'mode' -! mode 2 doesn't work!! -_open: - ld (savebc),bc - push af - pop bc - ld (saveaf),bc ! save all registers in savereg - ld (savede),de - ld (savehl),hl - ld (saveix),ix - pop bc ! return address - pop de ! name pointer - pop ix ! mode (0 for read, - ! 1 for write) - push ix - push de - push bc - ld bc,(saveaf) - push bc - pop af - ld bc,(savebc) - ld de,(savede) - ld hl,(savehl) - ld ix,(saveix) - ret ! return fd = 0 for read - ! fd = 1 for write - -_close: - ld ix,0 ! return succes - ret -_exit: -jp 0x38 -.data -_errno: - .word 0 -! output routine in monitor -CRT = 0x013B -! output a charcter -! entry: ascii character in a -.text -!putchr: -! push hl -! push bc -! ld hl,tab -! ld b,5 -!1: cp (hl) -! jr z,fetch -! inc hl -! inc hl -! djnz 1b -!2: call CRT -! pop bc -! pop hl -! ret -!fetch: inc hl -! ld a,(hl) -! jr 2b -!! conversion table for nascom characters -!tab: .byte 0x0D,0x00 -! .byte 0x1B,0x1E -! .byte 0x08,0x1D -! .byte 0x0A,0x1F -! .byte 0x7F,0x00 - -KBD = 0x69 -! get character from keyboard -getchr: - call KBD - jr nc,getchr - cp 0x1F - jr z,CR - cp 0x1D - jr z,BS - ret -CR: ld a,0xA - ret -BS: ld a,0x8 - ret diff --git a/mach/z80/libsys/putchr.nas.s b/mach/z80/libsys/putchr.nas.s deleted file mode 100644 index e0dbdeb67..000000000 --- a/mach/z80/libsys/putchr.nas.s +++ /dev/null @@ -1,28 +0,0 @@ -.define putchr -! output routine in monitor -CRT = 0x013B -! output a charcter -! entry: ascii character in a -putchr: - push hl - push bc - ld hl,tab - ld b,5 -1: cp (hl) - jr z,fetch - inc hl - inc hl - djnz 1b -2: call CRT - pop bc - pop hl - ret -fetch: inc hl - ld a,(hl) - jr 2b -! conversion table for nascom characters -tab: .byte 0x0D,0x00 - .byte 0x1B,0x1E - .byte 0x08,0x1D - .byte 0x0A,0x1F - .byte 0x7F,0x00 diff --git a/mach/z80/libsys/putchr.s b/mach/z80/libsys/putchr.s deleted file mode 100644 index db15bf216..000000000 --- a/mach/z80/libsys/putchr.s +++ /dev/null @@ -1,21 +0,0 @@ -.define putchr - -putchr: - push hl - push de - push bc - cp 0x0A - jr nz,1f - ld a,0x1F -1: - ld c,a -2: - in a,0xF1 - and 4 - jr z,2b - ld a,c - out 0xF0,a - pop bc - pop de - pop hl - ret diff --git a/mach/z80/libsys/subr.s b/mach/z80/libsys/subr.s deleted file mode 100644 index 253048892..000000000 --- a/mach/z80/libsys/subr.s +++ /dev/null @@ -1,197 +0,0 @@ -.define _read,_write,_ioctl,_getpid,_open,_close,_exit,_errno -_read: - ld (savebc),bc - push af - pop bc - ld (saveaf),bc ! save all registers in savereg - ld (savede),de - ld (savehl),hl - ld (saveix),ix - ex (sp),hl ! return address in hl - pop bc ! skip return address - pop bc ! get fd - ld a,b ! check fd = 0 - or c - jr nz,errrd - pop de ! get buffer - pop bc ! get count - ld ix,0 ! reset counter - push bc - push de - push ix - push hl ! return address - ex de,hl ! buffer to hl -1: ld a,b - or c - jr z,done ! done if count = 0 - call getchr - ld (hl),a - inc hl ! increment pointer - inc ix ! increment char counter - dec bc ! decrement count - cp 0xA - jr nz,1b ! done if char = CR -done: - ld bc,(saveaf) - push bc - pop af - ld bc,(savebc) - ld de,(savede) - ld hl,(savehl) - ld ix,(saveix) - ret -errrd: - push bc - push hl ! return address - ld bc,(saveaf) - push bc - pop af - ld bc,(savebc) - ld de,(savede) - ld hl,(savehl) - ld ix,(saveix) - ld ix,-1 - ret - -_write: - ld (savebc),bc - push af - pop bc - ld (saveaf),bc ! save all registers in savereg - ld (savede),de - ld (savehl),hl - ld (saveix),ix - ex (sp),hl ! return address in hl - pop de ! skip return address - pop de ! get fd - ld a,e ! check for fd = 1 - cp 1 - jr nz,errwr - ld a,d - or a - jr nz,errwr - pop de ! buffer in de - pop bc ! count in bc - push bc - push de - push de - push hl - ex de,hl ! buffer in hl - ld e,c - ld d,b ! count also in de -1: ld a,b - or c - jr z,exit - ld a,(hl) - call putchr - inc hl - dec bc - jr 1b -errwr: - push de - push hl - ld bc,(saveaf) - push bc - pop af - ld bc,(savebc) - ld de,(savede) - ld hl,(savehl) - ld ix,(saveix) - ld ix,-1 ! error in fd - ret -exit: - push de ! count on stack - ld bc,(saveaf) - push bc - pop af - ld bc,(savebc) - ld de,(savede) - ld hl,(savehl) - ld ix,(saveix) - pop ix ! return count to caller - ret - -_ioctl: - ret -_getpid: - ret - -! open return a file descriptor (0,1,2) -! depending on 'mode' -! mode 2 doesn't work!! -_open: - ld (savebc),bc - push af - pop bc - ld (saveaf),bc ! save all registers in savereg - ld (savede),de - ld (savehl),hl - ld (saveix),ix - pop bc ! return address - pop de ! name pointer - pop ix ! mode (0 for read, - ! 1 for write) - push ix - push de - push bc - ld bc,(saveaf) - push bc - pop af - ld bc,(savebc) - ld de,(savede) - ld hl,(savehl) - ld ix,(saveix) - ret ! return fd = 0 for read - ! fd = 1 for write - -_close: - ld ix,0 ! return succes - ret -_exit: -jp 0x38 -.data -_errno: - .word 0 -! output routine in monitor -CRT = 0x013B -! output a charcter -! entry: ascii character in a -.text -!putchr: -! push hl -! push bc -! ld hl,tab -! ld b,5 -!1: cp (hl) -! jr z,fetch -! inc hl -! inc hl -! djnz 1b -!2: call CRT -! pop bc -! pop hl -! ret -!fetch: inc hl -! ld a,(hl) -! jr 2b -!! conversion table for nascom characters -!tab: .byte 0x0D,0x00 -! .byte 0x1B,0x1E -! .byte 0x08,0x1D -! .byte 0x0A,0x1F -! .byte 0x7F,0x00 - -KBD = 0x69 -! get character from keyboard -getchr: - call KBD - jr nc,getchr - cp 0x1F - jr z,CR - cp 0x1D - jr z,BS - ret -CR: ld a,0xA - ret -BS: ld a,0x8 - ret diff --git a/mach/z8000/as/Makefile b/mach/z8000/as/Makefile deleted file mode 100644 index 012b03822..000000000 --- a/mach/z8000/as/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Header$ -EM = ../../.. -h = $(EM)/h -CDIR = $(EM)/mach/proto/nas -CPP = $(EM)/lib/cpp -DEF = - -FFLAG = -CFLAGS = $(FFLAG) -O -I$h $(DEF) -YFLAGS = -d -LDFLAGS = $(FFLAG) -i - -CSRC = $(CDIR)/comm3.c $(CDIR)/comm4.c $(CDIR)/comm5.c \ - $(CDIR)/comm6.c $(CDIR)/comm7.c $(CDIR)/comm8.c -COBJ = $(CDIR)/comm3.o $(CDIR)/comm4.o $(CDIR)/comm5.o \ - $(CDIR)/comm6.o $(CDIR)/comm7.o $(CDIR)/comm8.o -MACH = mach0.c mach1.c mach2.c mach3.c mach4.c mach5.c -COMM = $(CDIR)/comm0.h $(CDIR)/comm1.h $(CDIR)/comm2.y $(CSRC) - -all: as - -install:all - ../../install as - -cmp: - -../../compare as - -clean: - rm -f *.o as as.[cy] y.tab.h - -pr: $(MACH) - @pr -n $(MACH) - -opr: - make pr | opr -as: $(COBJ) as.o - $(CC) $(LDFLAGS) $(COBJ) as.o -o as - -as.y: $(CDIR)/comm2.y - $(CPP) -P -I$h $(DEF) $(CDIR)/comm2.y >as.y - @echo "expect 1 shift/reduce conflict" - -lint: $(CSRC) as.c - lint $(CSRC) as.c - -y.tab.h: as.c -$(COBJ): y.tab.h -$(COBJ) as.y: $(CDIR)/comm0.h mach0.c -$(COBJ) as.y: $(CDIR)/comm1.h mach1.c -as.y: mach2.c -comm3.o: mach3.c -as.y: mach4.c -comm8.o: mach5.c diff --git a/util/ack/.distr b/util/ack/.distr deleted file mode 100644 index 83d135be9..000000000 --- a/util/ack/.distr +++ /dev/null @@ -1,23 +0,0 @@ -Makefile -ack.h -data.c -data.h -dmach.c -dmach.h -files.c -grows.c -grows.h -intable.c -list.c -list.h -main.c -malloc.c -mktables.c -pc -rmach.c -run.c -scan.c -svars.c -trans.c -trans.h -util.c diff --git a/util/ack/pc/.distr b/util/ack/pc/.distr deleted file mode 100644 index df8c6bb91..000000000 --- a/util/ack/pc/.distr +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -em_pc.c diff --git a/util/amisc/Makefile b/util/amisc/Makefile deleted file mode 100644 index 3cf60e34b..000000000 --- a/util/amisc/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# @(#)Makefile 1.1 -EM = ../.. -h = $(EM)/h -CFLAGS = -n -O -I$h -ALL = anm asize astrip -OFILES = anm.o asize.o astrip.o -CFILES = anm.c asize.c astrip.c - -all: $(ALL) - -cp cmp: all - for i in $(ALL); do $@ $$i $$ROOT/usr/bin/$$i; done - -clean: ; rm -f $(ALL) $(OFILES) -get: ; getall -unget: ; ungetall - -print: $(CFILES) - pr -n Makefile $(CFILES) | lpr diff --git a/util/amisc/anm.c b/util/amisc/anm.c deleted file mode 100644 index da5dfc4f3..000000000 --- a/util/amisc/anm.c +++ /dev/null @@ -1,310 +0,0 @@ -#define DUK /* Modifications by Duk Bekema. */ - -/* @(#)anm.c 1.4 */ -/* $Header$ */ -/* -** print symbol tables for -** ACK object files -** -** anm [-gopruns] [name ...] -*/ -#define ushort unsigned short - -#include "out.h" - -#include -#include - -int numsort_flg; -int sectsort_flg; -int undef_flg; -int revsort_flg = 1; -int globl_flg; -int nosort_flg; -int arch_flg; -int prep_flg; -struct outhead hbuf; -struct outsect sbuf; -FILE *fi; -long off; -char *malloc(); -char *realloc(); -long s_base[S_MAX]; /* for specially encoded bases */ - -main(argc, argv) -char **argv; -{ - int narg; - int compare(); - - if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) { - argv++; - while (*++*argv) switch (**argv) { - case 'n': /* sort numerically */ - numsort_flg++; - continue; - - case 's': /* sort in section order */ - sectsort_flg++; - continue; - - case 'g': /* globl symbols only */ - globl_flg++; - continue; - - case 'u': /* undefined symbols only */ - undef_flg++; - continue; - - case 'r': /* sort in reverse order */ - revsort_flg = -1; - continue; - - case 'p': /* don't sort -- symbol table order */ - nosort_flg++; - continue; - - case 'o': /* prepend a name to each line */ - prep_flg++; - continue; - - default: /* oops */ - fprintf(stderr, "anm: invalid argument -%c\n", *argv[0]); - exit(1); - } - argc--; - } - if (argc == 0) { - argc = 1; - argv[1] = "a.out"; - } - narg = argc; - - while(argc--) { - struct outname *nbufp = NULL; - struct outname nbuf; - char *cbufp; - long fi_to_co; - long n; - unsigned readcount; - int i,j; - - fi = fopen(*++argv,"r"); - if (fi == NULL) { - fprintf(stderr, "anm: cannot open %s\n", *argv); - continue; - } - - getofmt((char *)&hbuf, SF_HEAD, fi); - if (BADMAGIC(hbuf)) { - fprintf(stderr, "anm: %s-- bad format\n", *argv); - fclose(fi); - continue; - } - if (narg > 1) - printf("\n%s:\n", *argv); - - n = hbuf.oh_nname; - if (n == 0) { - fprintf(stderr, "anm: %s-- no name list\n", *argv); - fclose(fi); - continue; - } - - if (hbuf.oh_nchar == 0) { - fprintf(stderr, "anm: %s-- no names\n", *argv); - fclose(fi); - continue; - } - if ((readcount = hbuf.oh_nchar) != hbuf.oh_nchar) { - fprintf(stderr, "anm: string area too big in %s\n", *argv); - exit(2); - } - - /* store special section bases */ - if (hbuf.oh_flags & HF_8086) { - for (i=0; i>12) & 03777760; - } - } - - if ((cbufp = (char *)malloc(readcount)) == NULL) { - fprintf(stderr, "anm: out of memory on %s\n", *argv); - exit(2); - } - fseek(fi, OFF_CHAR(hbuf), 0); - if (fread(cbufp, 1, readcount, fi) == 0) { - fprintf(stderr, "anm: read error on %s\n", *argv); - exit(2); - } - fi_to_co = cbufp - OFF_CHAR(hbuf); - - fseek(fi, OFF_NAME(hbuf), 0); - i = 0; - while (--n >= 0) { - getofmt((char *)&nbuf, SF_NAME, fi); - - if (nbuf.on_foff == 0) - continue; /* skip entries without names */ - - if (globl_flg && (nbuf.on_type&S_EXT)==0) - continue; - - if (undef_flg - && - ((nbuf.on_type&S_TYP)!=S_UND || (nbuf.on_type&S_ETC)!=0)) - continue; - - nbuf.on_mptr = nbuf.on_foff + fi_to_co; - - /* adjust value for specially encoded bases */ - if (hbuf.oh_flags & HF_8086) { - if (((nbuf.on_type&S_ETC) == 0) || - ((nbuf.on_type&S_ETC) == S_SCT)) { - j = nbuf.on_type&S_TYP; - if ((j>=S_MIN) && (j<=S_MAX)) - nbuf.on_valu += s_base[j]; - } - } - - if (nbufp == NULL) - nbufp = (struct outname *)malloc(sizeof(struct outname)); - else - nbufp = (struct outname *)realloc(nbufp, (i+1)*sizeof(struct outname)); - if (nbufp == NULL) { - fprintf(stderr, "anm: out of memory on %s\n", *argv); - exit(2); - } - nbufp[i++] = nbuf; - } - - if (nosort_flg==0) - qsort(nbufp, i, sizeof(struct outname), compare); - - for (n=0; non_type&S_TYP) > (p2->on_type&S_TYP)) - return(revsort_flg); - if ((p1->on_type&S_TYP) < (p2->on_type&S_TYP)) - return(-revsort_flg); - } - - if (numsort_flg) { - if (p1->on_valu > p2->on_valu) - return(revsort_flg); - if (p1->on_valu < p2->on_valu) - return(-revsort_flg); - } - - i = strcmp(p1->on_mptr, p2->on_mptr); - - if (i > 0) - return(revsort_flg); - if (i < 0) - return(-revsort_flg); - - return(0); -} - -getofmt(p, s, f) -register char *p; -register char *s; -register FILE *f; -{ - register i; - register long l; - - for (;;) { - switch (*s++) { -/* case '0': p++; continue; */ - case '1': - *p++ = getc(f); - continue; - case '2': - i = getc(f); - i |= (getc(f) << 8); -#ifndef DUK - *((short *)p)++ = i; -#else DUK - *((short *)p) = i; - p += sizeof(short); -#endif DUK - continue; - case '4': - l = (long)getc(f); - l |= ((long)getc(f) << 8); - l |= ((long)getc(f) << 16); - l |= ((long)getc(f) << 24); -#ifndef DUK - *((long *)p)++ = l; -#else DUK - *((long *)p) = l; - p += sizeof(long); -#endif DUK - continue; - default: - case '\0': - break; - } - break; - } -} diff --git a/util/amisc/asize.c b/util/amisc/asize.c deleted file mode 100644 index 5d2699f3d..000000000 --- a/util/amisc/asize.c +++ /dev/null @@ -1,106 +0,0 @@ -#define DUK /* Modifications by Duk Bekema. */ - -/* @(#)asize.c 1.2 */ -/* $Header$ */ -#define ushort unsigned short - -#include -#include "out.h" - -/* - asize -- determine object size - -*/ - -main(argc, argv) -char **argv; -{ - struct outhead buf; - struct outsect sbuf; - ushort nrsect; - long sum; - int gorp; - FILE *f; - - if (--argc == 0) { - argc = 1; - argv[1] = "a.out"; - } - gorp = argc; - - while(argc--) { - if ((f = fopen(*++argv, "r"))==NULL) { - fprintf(stderr, "asize: cannot open %s\n", *argv); - continue; - } - getofmt ((char *)&buf, SF_HEAD , f); - if(BADMAGIC(buf)) { - fprintf(stderr, "asize: %s-- bad format\n", *argv); - fclose(f); - continue; - } - nrsect = buf.oh_nsect; - if (nrsect == 0) { - fprintf(stderr, "asize: %s-- no sections\n", *argv); - fclose(f); - continue; - } - if (gorp > 1) - printf("%s: ", *argv); - - sum = 0; - while (nrsect-- > 0) { - getofmt ((char *)&sbuf, SF_SECT , f); - printf("%ld", sbuf.os_size); - sum += sbuf.os_size; - if (nrsect > 0) - putchar('+'); - } - printf(" = %ld = 0x%lx\n", sum, sum); - fclose(f); - } -} - -getofmt(p, s, f) -register char *p; -register char *s; -register FILE *f; -{ - register i; - register long l; - - for (;;) { - switch (*s++) { -/* case '0': p++; continue; */ - case '1': - *p++ = getc(f); - continue; - case '2': - i = getc(f); - i |= (getc(f) << 8); -#ifndef DUK - *((short *)p)++ = i; -#else DUK - *((short *)p) = i; - p += sizeof(short); -#endif DUK - continue; - case '4': - l = (long)getc(f); - l |= (long)(getc(f) << 8); - l |= ((long)getc(f) << 16); - l |= ((long)getc(f) << 24); -#ifndef DUK - *((long *)p)++ = l; -#else DUK - *((long *)p) = l; - p += sizeof(long); -#endif DUK - continue; - default: - case '\0': - break; - } - break; - } -} diff --git a/util/amisc/astrip.c b/util/amisc/astrip.c deleted file mode 100644 index f2ebb915b..000000000 --- a/util/amisc/astrip.c +++ /dev/null @@ -1,213 +0,0 @@ -#define DUK /* Modifications by Duk Bekema. */ - -/* @(#)astrip.c 1.1 */ -/* $Header$ */ -#define ushort unsigned short - -#include "out.h" -#include -#include - -/* - - astrip -- remove symbols and relocation bits - -*/ - -char *tname; -char *mktemp(); -FILE *fopen(); -FILE *tf; -struct outhead buf; - -main(argc, argv) -char **argv; -{ - int status; - - signal(SIGHUP, SIG_IGN); - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - tname = mktemp("/tmp/sXXXXX"); - while(--argc) { - if ((status = strip(argv[argc])) > 1) - break; - } - unlink(tname); - exit(status); -} - -strip(name) -char *name; -{ - long size; - FILE *f; - - if ((f = fopen(name,"r")) == NULL) { - fprintf(stderr, "astrip: cannot open %s\n", name); - return(1); - } - getofmt ((char *)&buf, SF_HEAD , f); - if(BADMAGIC(buf)) { - fprintf(stderr, "astrip: %s-- bad format\n", name); - fclose(f); - return(1); - } - size = OFF_RELO(buf) - SZ_HEAD; - buf.oh_flags &= ~HF_LINK; - buf.oh_nrelo = 0; - buf.oh_nname = 0; - buf.oh_nchar = 0; - - - if ((tf = fopen(tname,"w")) == NULL) { - fprintf(stderr, "astrip: cannot create temp file %s\n", tname); - fclose(f); - return(2); - } - fseek(tf, (long)0, 0); - putofmt((char *)&buf,SF_HEAD,tf,tname); - if(copy(name, tname, f, tf, size)) { - fclose(f); - fclose(tf); - return(1); - } - fclose(f); - fclose(tf); - size += SZ_HEAD; - if ((f = fopen(name,"w")) == NULL) { - fprintf(stderr, "astrip: cannot write %s\n", name); - return(1); - } - if ((tf = fopen(tname,"r")) == NULL) { - fprintf(stderr, "astrip: cannot read temp file %s\n", tname); - fclose(f); - return(2); - } - fseek(tf, (long)0, 0); - if(copy(tname, name, tf, f, size)) { - fclose(f); - fclose(tf); - return(2); - } - - fclose(f); - fclose(tf); - return(0); -} - -copy(fnam, tnam, fr, to, size) -char *fnam; -char *tnam; -long size; -FILE *fr,*to; -{ - register s, n; - char lbuf[512]; - - while(size != (long)0) { - s = 512; - if(size < 512) - s = (int) size; - n = fread(lbuf,1,s,fr); - if(n != s) { - fprintf(stderr, "astrip: unexpected eof on %s\n", fnam); - return(1); - } - n = fwrite(lbuf,1,s,to); - if(n != s) { - fprintf(stderr, "astrip: write error on %s\n", tnam); - return(1); - } - size -= (long)s; - } - return(0); -} - -getofmt(p, s, f) -register char *p; -register char *s; -register FILE *f; -{ - register i; - register long l; - - for (;;) { - switch (*s++) { -/* case '0': p++; continue; */ - case '1': - *p++ = getc(f); - continue; - case '2': - i = getc(f); - i |= (getc(f) << 8); -#ifndef DUK - *((short *)p)++ = i; -#else DUK - *((short *)p) = i; - p += sizeof(short); -#endif DUK - continue; - case '4': - l = (long)getc(f); - l |= (long)(getc(f) << 8); - l |= ((long)getc(f) << 16); - l |= ((long)getc(f) << 24); -#ifndef DUK - *((long *)p)++ = l; -#else DUK - *((long *)p) = l; - p += sizeof(long); -#endif DUK - continue; - default: - case '\0': - break; - } - break; - } -} - -putofmt(p, s, f, fnam) -register char *p; -register char *s; -register FILE *f; -char *fnam; -{ - register i,j; - register long l; - - while (j = *s++) { - switch (j -= '0') { -/* case 0: p++; break; */ - case 1: - i = *p++; putc(i,f); - break; - case 2: -#ifndef DUK - i = *((short *)p)++; -#else DUK - i = *((short *)p); - p += sizeof(short); -#endif DUK - putc(i,f); - i>>=8; putc(i,f); - break; - case 4: -#ifndef DUK - l = *((long *)p)++; -#else DUK - l = *((long *)p); - p += sizeof(long); -#endif DUK - putc(l,f); - l >>=8; putc(l,f); - l >>=8; putc(l,f); - l >>=8; putc(l,f); - break; - default: - break; - } - if (ferror(f)) fprintf(stderr, "astrip: write error on %s\n", fnam); - } -} diff --git a/util/cgg/bootgram.y b/util/cgg/bootgram.y index d2f720187..ddd438802 100644 --- a/util/cgg/bootgram.y +++ b/util/cgg/bootgram.y @@ -1835,7 +1835,7 @@ finishio() { if (bsize>=0) fprintf(hfile,"#define TEM_BSIZE %d\n",bsize); else - yyerror("EM_BSIZE undefined"); + fprintf(hfile,"extern int TEM_BSIZE;\n"); if (fmt!=0) fprintf(hfile,"#define WRD_FMT \"%s\"\n",fmt); fprintf(hfile,"#define MAXALLREG %d\n",maxallreg); diff --git a/util/ego/bo/Makefile b/util/ego/bo/Makefile deleted file mode 100644 index 043cb3824..000000000 --- a/util/ego/bo/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -bo.c - -OFILES=\ -bo.o - -HFILES= - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/get.o $(SHR)/put.o $(SHR)/alloc.o $(SHR)/global.o $(SHR)/debug.o \ -$(SHR)/files.o $(SHR)/map.o $(SHR)/lset.o $(SHR)/cset.o $(SHR)/aux.o \ -$(SHR)/stack_chg.o $(SHR)/go.o - -SHARE_MFILES=\ -$(SHR)/get.m $(SHR)/put.m $(SHR)/alloc.m $(SHR)/global.m $(SHR)/debug.m \ -$(SHR)/files.m $(SHR)/map.m $(SHR)/lset.m $(SHR)/cset.m $(SHR)/aux.m \ -$(SHR)/stack_chg.m $(SHR)/go.m - -bo: $(OFILES) - $(CC) -o bo $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -bo_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o bo -.c $(LDFLAGS) bo.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO - -bo.o: ../share/alloc.h -bo.o: ../share/aux.h -bo.o: ../share/debug.h -bo.o: ../share/def.h -bo.o: ../share/files.h -bo.o: ../share/get.h -bo.o: ../share/global.h -bo.o: ../share/go.h -bo.o: ../share/lset.h -bo.o: ../share/map.h -bo.o: ../share/put.h -bo.o: ../share/types.h -bo.o: ../../../h/em_mnem.h -bo.o: ../../../h/em_pseu.h -bo.o: ../../../h/em_spec.h diff --git a/util/ego/bo/bo.c b/util/ego/bo/bo.c deleted file mode 100644 index 693d67ed1..000000000 --- a/util/ego/bo/bo.c +++ /dev/null @@ -1,318 +0,0 @@ -/* B R A N C H O P T I M I Z A T I O N - * - * B O . C - */ - - -#include -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/files.h" -#include "../share/get.h" -#include "../share/put.h" -#include "../share/lset.h" -#include "../share/map.h" -#include "../share/alloc.h" -#include "../share/aux.h" -#include "../share/def.h" -#include "../share/go.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" - -#define LP_BLOCKS lp_extend->lpx_ra.lpx_blocks - -#define newbolpx() (lpext_p) newstruct(lpext_ra) -#define oldbolpx(x) oldstruct(lpext_ra,x) - -STATIC int Sbo; /* #optimizations found */ - -#define DLINK(l1,l2) l1->l_next=l2; l2->l_prev=l1 - -/* This module performs some very simple branch optimizations. - * - * I) Look for pairs of basic blocks (B1,B2), such that - * SUCC(b1) = {B2} and - * PRED(B2) = {B1}. - * In this case B1 and B2 can be combined into one block. - * This optimization is mainly succesful: - * 1) for switch statements in C, as the C compiler generates a branch - * over the entire switch. - * 2) for return statements, if the only way to return from a procedure - * is via a return statement somewhere in the middle of the procedure. - * II) Optimize while statements. Transformations like: - * 1: jmp 2 - * tst cond 1: - * beq 2f S - * S 2: - * jmp 1 tst cond - * 2: bneq 1 - * are done by this optimization. - */ - - - -STATIC line_p last_code(lines,skip_pseu) - line_p lines; - bool skip_pseu; -{ - /* Determine the last line of a list */ - - register line_p l; - - for (l = lines; l->l_next != (line_p) 0; l = l->l_next); - if (skip_pseu) { - while (INSTR(l) < sp_fmnem || INSTR(l) > sp_lmnem) l = PREV(l); - } - return l; -} - -STATIC short cc_tab[12] = - {op_blt,op_zlt,op_ble,op_zle,op_beq,op_zeq, - op_zne,op_bne,op_zgt,op_bgt,op_zge,op_bge}; - - -STATIC short rev_cond(cond) - short cond; -{ - register i; - - for (i = 0; i < 12; i++) { - if (cond == cc_tab[i]) return cc_tab[11-i]; - } - return op_nop; -} - -STATIC bool is_bcc(l) - line_p l; -{ - return rev_cond(INSTR(l)) != op_nop; -} - - -STATIC bo_optloop(p,b,x,bra,bcc) - proc_p p; - bblock_p b,x; - line_p bra,bcc; -{ - bblock_p prevb,n; - line_p l; - - if (b->b_start == bra) { - b->b_start = (line_p) 0; - } else { - PREV(bra)->l_next = (line_p) 0; - } - PREV(bra) = (line_p) 0; - bcc->l_instr = rev_cond(INSTR(bcc)); - n = x->b_next; - l = n->b_start; - if (l == (line_p) 0 || INSTR(l) != op_lab) { - l = newline(OPINSTRLAB); - l->l_instr = op_lab; - INSTRLAB(l) = freshlabel(); - if (n->b_start != (line_p) 0) { - DLINK(l,n->b_start); - } - n->b_start = l; - } - INSTRLAB(bcc) = INSTRLAB(l); - for (prevb = p->p_start; prevb != (bblock_p) 0 && prevb->b_next != x; - prevb = prevb->b_next); - if (prevb == (bblock_p) 0) { - p->p_start = x->b_next; - } else { - prevb->b_next = x->b_next; - l = last_instr(prevb); - if (l == (line_p) 0) { - prevb->b_start = bra; - } else { - if (INSTR(l) == op_bra && - INSTRLAB(l) == INSTRLAB(bra)) { - oldline(bra); - } else { - appnd_line(bra,l); - } - } - } - x->b_next = b->b_next; - b->b_next = x; -} - - - -STATIC bo_tryloop(p,loop) - proc_p p; - lset loop; -{ - Lindex i,j; - bblock_p b,x; - line_p bra,bcc; - - for (i = Lfirst(loop); i != (Lindex) 0; i = Lnext(i,loop)) { - b = (bblock_p) Lelem(i); - if (b->b_next != (bblock_p) 0 && !Lis_elem(b->b_next,loop)) { - j = Lfirst(b->b_succ); - if (j != (Lindex) 0 && - (bra = last_instr(b)) != (line_p) 0 && - INSTR(bra) == op_bra) { - x = (bblock_p) Lelem(j); /* single successor */ - if (Lis_elem(b->b_next,x->b_succ) && - is_bcc((bcc = last_instr(x)))) { -OUTVERBOSE("branch optimization proc %d block %d\n", curproc->p_id,x->b_id); - Sbo++; - bo_optloop(p,b,x,bra,bcc); - return; - } - } - } - } -} - - - -STATIC bo_loops(p) - proc_p p; -{ - Lindex i; - loop_p lp; - - for (i = Lfirst(p->p_loops); i != (Lindex) 0; i = Lnext(i,p->p_loops)) { - lp = (loop_p) (Lelem(i)); - bo_tryloop(p,lp->LP_BLOCKS); - } -} - -STATIC mv_code(b1,b2) - bblock_p b1,b2; -{ - line_p l,x; - - l = last_code(b2->b_start,TRUE); - DLINK(l,b1->b_start); - x = l->l_next; - if (INSTR(l) == op_bra) { - rm_line(l,b2); - } - if (INSTR(x) == op_lab) { - rm_line(x,b2); - } -} - -bo_switch(b) - bblock_p b; -{ - bblock_p s,x; - Lindex i; - line_p l; - - if (Lnrelems(b->b_succ) == 1) { - s = (bblock_p) Lelem(Lfirst(b->b_succ)); - if (b->b_start != (line_p) 0 && - s->b_start != (line_p) 0 && - Lnrelems(s->b_pred) == 1 && - (s->b_next == (bblock_p) 0 || - !Lis_elem(s->b_next,s->b_succ))) { - l = last_code(s->b_start,FALSE); - if (INSTR(l) == ps_end) { - if (PREV(l) == (line_p) 0) return; - PREV(l)->l_next = (line_p) 0; - PREV(l) = (line_p) 0; - } else { - l = (line_p) 0; - } -OUTVERBOSE("branch optimization in proc %d, block %d",curproc->p_id,b->b_id); - Sbo++; - Ldeleteset(b->b_succ); - b->b_succ = s->b_succ; - Ldeleteset(s->b_pred); - s->b_succ = Lempty_set(); - s->b_pred = Lempty_set(); - for (i = Lfirst(b->b_succ); i != (Lindex) 0; - i = Lnext(i,b->b_succ)) { - x = (bblock_p) Lelem(i); - Lremove(s,&x->b_pred); - Ladd(b,&x->b_pred); - if (x->b_idom == s) { - x->b_idom = b; - } - } - mv_code(s,b); - s->b_start = l; - } - } -} - -STATIC bo_extproc(p) - proc_p p; -{ - /* Allocate the extended data structures for procedure p */ - - register loop_p lp; - register Lindex pi; - - for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; - pi = Lnext(pi,p->p_loops)) { - lp = (loop_p) Lelem(pi); - lp->lp_extend = newbolpx(); - } -} - - -STATIC loop_blocks(p) - proc_p p; -{ - /* Compute the LP_BLOCKS sets for all loops of p */ - - register bblock_p b; - register Lindex i; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (i = Lfirst(b->b_loops); i != (Lindex) 0; - i = Lnext(i,b->b_loops)) { - Ladd(b,&(((loop_p) Lelem(i))->LP_BLOCKS)); - } - } -} - -STATIC bo_cleanproc(p) - proc_p p; -{ - /* Allocate the extended data structures for procedure p */ - - register loop_p lp; - register Lindex pi; - register bblock_p b; - - for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; - pi = Lnext(pi,p->p_loops)) { - lp = (loop_p) Lelem(pi); - oldbolpx(lp->lp_extend); - } -} - -bo_optimize(p) - proc_p p; -{ - bblock_p b; - - bo_extproc(p); - loop_blocks(p); - bo_loops(p); - for (b = p->p_start; b != 0; b = b->b_next) { - bo_switch(b); - } - bo_cleanproc(p); -} - - - -main(argc,argv) - int argc; - char *argv[]; -{ - go(argc,argv,no_action,bo_optimize,no_action,no_action); - report("branch optimizations", Sbo); - exit(0); -} diff --git a/util/ego/ca/Makefile b/util/ego/ca/Makefile deleted file mode 100644 index 9677363a9..000000000 --- a/util/ego/ca/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -ca.c ca_put.c - -OFILES=\ -ca.o ca_put.o - -HFILES=\ -ca.h ca_put.h - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/get.o $(SHR)/alloc.o $(SHR)/global.o $(SHR)/aux.o $(SHR)/debug.o \ -$(SHR)/lset.o $(SHR)/cset.o $(SHR)/files.o $(SHR)/map.o - -SHARE_MFILES=\ -$(SHR)/get.m $(SHR)/alloc.m $(SHR)/global.m $(SHR)/aux.m $(SHR)/debug.m \ -$(SHR)/lset.m $(SHR)/cset.m $(SHR)/files.m $(SHR)/map.m - -ca: $(OFILES) - $(CC) -o ca $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -ca_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o ca -.c $(LDFLAGS) ca.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO - -ca.o: ../share/alloc.h -ca.o: ../share/debug.h -ca.o: ../share/files.h -ca.o: ../share/get.h -ca.o: ../share/global.h -ca.o: ../share/lset.h -ca.o: ../share/map.h -ca.o: ../share/types.h -ca.o: ca.h -ca.o: ca_put.h -ca_put.o: ../../../h/em_flag.h -ca_put.o: ../../../h/em_mes.h -ca_put.o: ../../../h/em_mnem.h -ca_put.o: ../../../h/em_pseu.h -ca_put.o: ../../../h/em_spec.h -ca_put.o: ../share/alloc.h -ca_put.o: ../share/debug.h -ca_put.o: ../share/def.h -ca_put.o: ../share/map.h -ca_put.o: ../share/types.h -ca_put.o: ca.h diff --git a/util/ego/ca/ca.c b/util/ego/ca/ca.c deleted file mode 100644 index abf1779a7..000000000 --- a/util/ego/ca/ca.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * C O M P A C T A S S E M B L Y L A N G U A G E G E N E R A T I O N - * - */ - - -#include -#include "../share/types.h" -#include "ca.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/files.h" -#include "../share/map.h" -#include "../share/alloc.h" -#include "../share/get.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_mes.h" -#include "ca_put.h" - - -/* This phase transforms the Intermediate Code of the global optimizer - * to 'standard' compact assembly language, which will be processed - * by the code generator. - */ - - -short dlength; -dblock_p *dmap; - -char **dnames, **pnames; /* Dynamically allocated arrays of strings. - * pnames[i] contains a pointer to the name - * of the procedure with proc_id i. - */ - - -STATIC char **newnametab(tablen,namelen) - short tablen,namelen; -{ - register char **np, **tab; - - tab = (char **) newmap(tablen); - for (np = &tab[1]; np <= &tab[tablen]; np++) { - *np = (char *) newcore(namelen); - } - return tab; -} - - -STATIC line_p get_ca_lines(lf,p_out) - FILE *lf; - proc_p *p_out; -{ - /* Read lines of EM text and link them. - * Register messages are outputted immediately after the PRO. - */ - - line_p head, *pp, l; - line_p headm, *mp; - arg_p a; - - curinp = lf; /* EM input file */ - pp = &head; - mp = &headm; - headm = (line_p) 0; - while (TRUE) { - l = read_line(p_out); - if (feof(curinp)) break; - assert (l != (line_p) 0); - if (INSTR(l) == ps_end && INSTR(head) != ps_pro) { - /* Delete end pseudo after data-unit */ - oldline(l); - break; - } - if (INSTR(l) == ps_mes && l->l_a.la_arg->a_a.a_offset == ms_reg) { - /* l is a register message */ - if (l->l_a.la_arg->a_next == (arg_p) 0) { - /* register message without arguments */ - oldline(l); - } else { - *mp = l; - mp = &l->l_next; - } - } else { - *pp = l; - pp = &l->l_next; - } - if (INSTR(l) == ps_end) { - break; - } - } - *pp = (line_p) 0; - if (head != (line_p) 0 && INSTR(head) == ps_pro) { - /* append register message without arguments to list */ - l = newline(OPLIST); - l->l_instr = ps_mes; - a = ARG(l) = newarg(ARGOFF); - a->a_a.a_offset = ms_reg; - *mp = l; - l->l_next = head->l_next; - head->l_next = headm; - } else { - assert(headm == (line_p) 0); - } - return head; -} - -STATIC int makedmap(dbl) - dblock_p dbl; -{ - /* construct the dmap table */ - - dblock_p d; - int cnt; - - /* determine the length of the table */ - - cnt = 0; - for (d = dbl; d != (dblock_p) 0; d = d->d_next) cnt++; - dmap = (dblock_p *) newmap(cnt); - for (d = dbl; d != (dblock_p) 0; d = d->d_next) { - assert(d->d_id) <= cnt; - dmap[d->d_id] = d; - } - return cnt; -} - - - -STATIC getdnames(dumpd) - FILE *dumpd; -{ - /* Read the names of the datalabels from - * the dump file. - */ - - char str[IDL+1]; - char *s; - int id; - register int i; - - dnames = (char **) newnametab(dlength,IDL); - for (;;) { - if (fscanf(dumpd,"%d %s",&id,str) == EOF) return; - assert(id <= dlength); - s = dnames[id]; - for (i = 0; i < IDL; i++) { - *s++ = str[i]; - } - } -} - -STATIC getpnames(dumpp) - FILE *dumpp; -{ - /* Read the names of the procedures from - * the dump file. - */ - - char str[IDL+1]; - char *s; - int id; - register int i; - - pnames = (char **) newnametab(plength,IDL); - for (;;) { - if (fscanf(dumpp,"%d %s",&id,str) == EOF) return; - assert(id <= plength); - s = pnames[id]; - for (i = 0; i < IDL; i++) { - *s++ = str[i]; - } - } -} - - -STATIC bool name_exists(name,endp,endd) - char *name; - proc_p endp; - dblock_p endd; -{ - /* Search the proctable (from fproc to endp) - * and the data block table (from fdblock to endd) - * to see if the name is already in use. - */ - - proc_p p; - dblock_p d; - - for (p = fproc; p != endp; p = p->p_next) { - if (strncmp(name,pnames[p->p_id],IDL) == 0) return TRUE; - } - for (d = fdblock; d != endd; d = d->d_next) { - if (strncmp(name,dnames[d->d_id],IDL) == 0) return TRUE; - } - return FALSE; -} - - - -static int nn = 0; - -STATIC new_name(s) - char *s; -{ - s[0] = '_'; - s[1] = 'I'; - s[2] = 'I'; - sprintf(&s[3],"%d",nn); - nn++; -} - - - -STATIC uniq_names() -{ - /* The names of all internal procedures and data blocks - * are made different. As the optimizer combines several - * modules into one, there may be name conflicts between - * procedures or data blocks that were internal in - * different source modules. - */ - - proc_p p; - dblock_p d; - - for (p = fproc; p != (proc_p) 0; p = p->p_next) { - if (!(p->p_flags1 & PF_EXTERNAL) && - name_exists(pnames[p->p_id],p,fdblock)) { - new_name(pnames[p->p_id]); - } - } - for (d = fdblock; d != (dblock_p) 0; d = d->d_next) { - if (!(d->d_flags1 & DF_EXTERNAL) && - name_exists(dnames[d->d_id],(proc_p) 0,d) ) { - new_name(dnames[d->d_id]); - } - } -} -main(argc,argv) - int argc; - char *argv[]; -{ - /* CA does not output proctable etc. files. Instead, its - * pname2 and dname2 arguments contain the names of the - * dump files created by IC. - */ - FILE *f, *f2; /* The EM input and output. */ - FILE *df, *pf; /* The dump files */ - line_p lnp; - - fproc = getptable(pname); /* proc table */ - fdblock = getdtable(dname); /* data block table */ - dlength = makedmap(fdblock); /* allocate dmap table */ - df = openfile(dname2,"r"); - getdnames(df); - fclose(df); - pf = openfile(pname2,"r"); - getpnames(pf); - fclose(pf); - uniq_names(); - f = openfile(lname,"r"); - f2 = stdout; - cputmagic(f2); /* write magic number */ - while ((lnp = get_ca_lines(f,&curproc)) != (line_p) 0) { - cputlines(lnp,f2); - } - fclose(f); - fclose(f2); - exit(0); -} diff --git a/util/ego/ca/ca.h b/util/ego/ca/ca.h deleted file mode 100644 index adf7c876c..000000000 --- a/util/ego/ca/ca.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * C O M P A C T A S S E M B L Y L A N G U A G E G E N E R A T I O N - * - */ - - -#define PF_SYMOUT 01 -#define DF_SYMOUT 01 - -extern dblock_p *dmap; - -extern char **dnames; -extern char **pnames; - -extern byte em_flag[]; diff --git a/util/ego/ca/ca_put.c b/util/ego/ca/ca_put.c deleted file mode 100644 index 58cee1b67..000000000 --- a/util/ego/ca/ca_put.c +++ /dev/null @@ -1,413 +0,0 @@ -#include -#include "../share/types.h" -#include "ca.h" -#include "../share/debug.h" -#include "../share/def.h" -#include "../share/map.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_flag.h" -#include "../../../h/em_mes.h" -#include "../share/alloc.h" - -#define outbyte(b) putc(b,outfile) - -FILE *outfile; - -STATIC proc_p thispro; - -STATIC outinst(m) { - - outbyte( (byte) m ); -} - -STATIC coutshort(i) short i; { - - outbyte( (byte) (i&BMASK) ); - outbyte( (byte) (i>>8) ); -} - -STATIC coutint(i) short i; { - - if (i>= -sp_zcst0 && i< sp_ncst0-sp_zcst0) - outbyte( (byte) (i+sp_zcst0+sp_fcst0) ); - else { - outbyte( (byte) sp_cst2) ; - coutshort(i); - } -} - -STATIC coutoff(off) offset off; { - - if ((short) off == off) - coutint((short) off); - else { - outbyte( (byte) sp_cst4) ; - coutshort( (short) (off&0177777L) ); - coutshort( (short) (off>>16) ); - } -} - - -STATIC outsym(s,t) - char *s; - int t; -{ - register byte *p; - register unsigned num; - - if (s[0] == '.') { - num = atoi(&s[1]); - if (num < 256) { - outbyte( (byte) sp_dlb1) ; - outbyte( (byte) (num) ); - } else { - outbyte( (byte) sp_dlb2) ; - coutshort((short) num); - } - } else { - p= s; - while (*p && p < &s[IDL]) - p++; - num = p - s; - outbyte( (byte) t); - coutint((short) num); - p = s; - while (num--) - outbyte( (byte) *p++ ); - } -} - - -STATIC outdsym(dbl) - dblock_p dbl; -{ - outsym(dnames[dbl->d_id],sp_dnam); -} - - -STATIC outpsym(p) - proc_p p; -{ - outsym(pnames[p->p_id],sp_pnam); -} - - -STATIC outddef(id) short id; { - - dblock_p dbl; - - dbl = dmap[id]; - dbl->d_flags2 |= DF_SYMOUT; - if (dbl->d_flags1 & DF_EXTERNAL) { - outinst(ps_exa); - outdsym(dbl); - } -} - -STATIC outpdef(p) proc_p p; { - p->p_flags2 |= PF_SYMOUT; - if (p->p_flags1 & PF_EXTERNAL) { - outinst(ps_exp); - outpsym(p); - } -} - - -STATIC outdocc(obj) obj_p obj; { - dblock_p dbl; - - dbl = obj->o_dblock; - if ((dbl->d_flags2 & DF_SYMOUT) == 0) { - dbl->d_flags2 |= DF_SYMOUT; - if ((dbl->d_flags1 & DF_EXTERNAL) == 0) { - outinst(ps_ina); - outdsym(dbl); - } - } -} - - -STATIC outpocc(p) proc_p p; { - if ((p->p_flags2 & PF_SYMOUT) == 0) { - p->p_flags2 |= PF_SYMOUT; - if ((p->p_flags1 & PF_EXTERNAL) == 0) { - outinst(ps_inp); - outpsym(p); - } - } -} - - -STATIC coutobject(obj) - obj_p obj; -{ - /* In general, an object is defined by a global data - * label and an offset. There are two special cases: - * the label is omitted if the object is part of the current - * hol block; the offset is omitted if it is 0 and the label - * was not omitted. - */ - if (dnames[obj->o_dblock->d_id][0] == '\0') { - coutoff(obj->o_off); - } else { - if (obj->o_off == 0) { - outdsym(obj->o_dblock); - } else { - outbyte((byte) sp_doff); - outdsym(obj->o_dblock); - coutoff(obj->o_off); - } - } -} - - -STATIC cputstr(abp) register argb_p abp; { - register argb_p tbp; - register length; - - length = 0; - tbp = abp; - while (tbp!= (argb_p) 0) { - length += tbp->ab_index; - tbp = tbp->ab_next; - } - coutint(length); - while (abp != (argb_p) 0) { - for (length=0;lengthab_index;length++) - outbyte( (byte) abp->ab_contents[length] ); - abp = abp->ab_next; - } -} - - -STATIC outnum(n) - int n; -{ - if (n < 256) { - outbyte((byte) sp_ilb1); - outbyte((byte) n); - } else { - outbyte((byte) sp_ilb2); - coutshort((short) n); - } -} - - -STATIC numlab(n) - int n; -{ - if (n < sp_nilb0) { - outbyte((byte) (n + sp_filb0)); - } else { - outnum(n); - } -} - - -STATIC cputargs(lnp) - line_p lnp; -{ - register arg_p ap; - int cnt = 0; - ap = ARG(lnp); - while (ap != (arg_p) 0) { - switch(ap->a_type) { - case ARGOFF: - coutoff(ap->a_a.a_offset); - break; - case ARGOBJECT: - coutobject(ap->a_a.a_obj); - break; - case ARGPROC: - outpsym(ap->a_a.a_proc); - break; - case ARGINSTRLAB: - outnum(ap->a_a.a_instrlab); - break; - case ARGSTRING: - outbyte((byte) sp_scon); - cputstr(&ap->a_a.a_string); - break; - case ARGICN: - outbyte((byte) sp_icon); - goto casecon; - case ARGUCN: - outbyte((byte) sp_ucon); - goto casecon; - case ARGFCN: - outbyte((byte) sp_fcon); - casecon: - coutint(ap->a_a.a_con.ac_length); - cputstr(&ap->a_a.a_con.ac_con); - break; - default: - assert(FALSE); - } - ap = ap->a_next; - /* Avoid generating extremely long CON or ROM statements */ - if (cnt++ > 10 && ap != (arg_p) 0 && - (INSTR(lnp) == ps_con || INSTR(lnp) == ps_rom)) { - cnt = 0; - outbyte((byte) sp_cend); - outinst(INSTR(lnp)); - } - } -} - - - -STATIC outoperand(lnp) - line_p lnp; -{ - /* Output the operand of instruction lnp */ - - switch(TYPE(lnp)) { - case OPNO: - if ((em_flag[INSTR(lnp)-sp_fmnem]&EM_PAR) != PAR_NO) { - outbyte((byte) sp_cend); - } - break; - case OPSHORT: - if (INSTR(lnp) == ps_sym) { - outsym(dnames[SHORT(lnp)],sp_dnam); - } else { - coutint(SHORT(lnp)); - } - break; - case OPOFFSET: - coutoff(OFFSET(lnp)); - break; - case OPINSTRLAB: - if (INSTR(lnp) == op_lab) { - numlab(INSTRLAB(lnp)); - } else { - if (INSTR(lnp) < sp_fpseu) { - coutint(INSTRLAB(lnp)); - } else { - numlab(INSTRLAB(lnp)); - } - } - break; - case OPOBJECT: - coutobject(OBJ(lnp)); - break; - case OPPROC: - outpsym(PROC(lnp)); - break; - case OPLIST: - cputargs(lnp); - switch(INSTR(lnp)) { - case ps_con: - case ps_rom: - case ps_mes: - outbyte((byte) sp_cend); - /* list terminator */ - break; - } - break; - default: - assert(FALSE); - } -} - - -STATIC outvisibility(lnp) - line_p lnp; -{ - /* In EM names of datalabels and procedures can be made - * externally visible, so they can be used in other files. - * There are special EM pseudo-instructions to state - * explicitly that a certain identifier is externally - * visible (ps_exa,ps_exp) or invisible (ps_ina,ps_inp). - * If there is no such pseudo for a certain identifier, - * the identifier is external only if its first use - * in the current file is an applied occurrence. - * Unfortunately the global optimizer may change the - * order of defining and applied occurrences. - * In the first optimizer pass (ic) we record for each identifier - * whether it is external or not. If necessary we generate - * pseudo instructions here. - */ - - arg_p ap; - short instr; - - instr = INSTR(lnp); - switch(TYPE(lnp)) { - case OPOBJECT: - outdocc(OBJ(lnp)); - /* applied occurrence of a data label */ - break; - case OPSHORT: - if (instr == ps_sym) { - outddef(SHORT(lnp)); - /* defining occ. data label */ - } - break; - case OPPROC: - if (instr == ps_pro) { - outpdef(PROC(lnp)); - /* defining occ. procedure */ - } else { - outpocc(PROC(lnp)); - } - break; - case OPLIST: - for (ap = ARG(lnp); ap != (arg_p) 0; ap = ap->a_next) { - switch(ap->a_type) { - case ARGOBJECT: - outdocc(ap->a_a.a_obj); - break; - case ARGPROC: - outpocc(ap->a_a.a_proc); - break; - } - } - break; - } -} - - -cputlines(l,lf) - line_p l; - FILE *lf; -{ - /* Output the lines in Campact assembly language - * format. - */ - - line_p next,lnp; - - outfile = lf; - for (lnp = l; lnp != (line_p) 0; lnp = next) { - next = lnp->l_next; - outvisibility(lnp); /* take care of visibiltity rules */ - if (INSTR(lnp) != ps_sym && INSTR(lnp) != op_lab) { - outinst(INSTR(lnp)); - } - outoperand(lnp); - switch(INSTR(lnp)) { - case ps_pro: - thispro = PROC(lnp); - /* fall through ... */ - case ps_end: - coutoff(thispro->p_localbytes); - } - oldline(lnp); - } - if (lmap != (line_p *) 0) { - oldmap(lmap,llength); - lmap = (line_p *) 0; - } -} - -cputmagic(lf) - FILE *lf; -{ - /* write the magic number */ - - outfile = lf; - coutshort(sp_magic); -} diff --git a/util/ego/ca/ca_put.h b/util/ego/ca/ca_put.h deleted file mode 100644 index 46f86f97b..000000000 --- a/util/ego/ca/ca_put.h +++ /dev/null @@ -1,9 +0,0 @@ -/* C O M P A C T A S S E M B L Y G E N E R A T I O N - * - * C A _ P U T . C - * - */ - - -extern cputlines(); -extern cputmagic(); diff --git a/util/ego/cf/Makefile b/util/ego/cf/Makefile deleted file mode 100644 index 6fd7cc1fc..000000000 --- a/util/ego/cf/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -cf.c cf_succ.c cf_idom.c cf_loop.c - -OFILES=\ -cf.o cf_idom.o cf_loop.o cf_succ.o - -HFILES=\ -cf.h cf_succ.h cf_idom.h cf_loop.h - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/get.o $(SHR)/put.o $(SHR)/alloc.o $(SHR)/global.o \ -$(SHR)/debug.o $(SHR)/files.o $(SHR)/map.o $(SHR)/lset.o \ -$(SHR)/cset.o $(SHR)/aux.o - -SHARE_MFILES=\ -$(SHR)/get.m $(SHR)/put.m $(SHR)/alloc.m $(SHR)/global.m \ -$(SHR)/debug.m $(SHR)/files.m $(SHR)/map.m $(SHR)/lset.m \ -$(SHR)/cset.m $(SHR)/aux.m - -cf: $(OFILES) - $(CC) -o cf $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -cf_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o cf -.c $(LDFLAGS) cf.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO -cf.o: ../../../h/em_mnem.h -cf.o: ../share/alloc.h -cf.o: ../share/cset.h -cf.o: ../share/debug.h -cf.o: ../share/files.h -cf.o: ../share/get.h -cf.o: ../share/global.h -cf.o: ../share/lset.h -cf.o: ../share/map.h -cf.o: ../share/put.h -cf.o: ../share/types.h -cf.o: cf.h -cf.o: cf_idom.h -cf.o: cf_loop.h -cf.o: cf_succ.h -cf_idom.o: ../share/alloc.h -cf_idom.o: ../share/debug.h -cf_idom.o: ../share/lset.h -cf_idom.o: ../share/types.h -cf_idom.o: cf.h -cf_loop.o: ../share/alloc.h -cf_loop.o: ../share/debug.h -cf_loop.o: ../share/lset.h -cf_loop.o: ../share/types.h -cf_loop.o: cf.h -cf_succ.o: ../../../h/em_flag.h -cf_succ.o: ../../../h/em_mnem.h -cf_succ.o: ../../../h/em_pseu.h -cf_succ.o: ../../../h/em_spec.h -cf_succ.o: ../share/cset.h -cf_succ.o: ../share/debug.h -cf_succ.o: ../share/def.h -cf_succ.o: ../share/global.h -cf_succ.o: ../share/lset.h -cf_succ.o: ../share/map.h -cf_succ.o: ../share/types.h -cf_succ.o: cf.h diff --git a/util/ego/cf/cf.c b/util/ego/cf/cf.c deleted file mode 100644 index f1d70cb0b..000000000 --- a/util/ego/cf/cf.c +++ /dev/null @@ -1,520 +0,0 @@ -/* C O N T R O L F L O W - * - * M A I N R O U T I N E - */ - -#include -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/map.h" -#include "../share/files.h" -#include "../share/global.h" -#include "../share/alloc.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/get.h" -#include "../share/put.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_flag.h" -#include "../share/def.h" -#include "cf.h" -#include "cf_succ.h" -#include "cf_idom.h" -#include "cf_loop.h" - -#define newcfbx() (bext_p) newstruct(bext_cf) -#define oldcfbx(x) oldstruct(bext_cf,x) - -extern char em_flag[]; - -STATIC cset lpi_set; /* set of procedures used in LPI instruction */ -STATIC cset cai_set; /* set of all procedures doing a CAI */ - - -/* The procedure getbblocks reads the EM textfile and - * partitions every procedure into a number of basic blocks. - */ - -#define LABEL0 0 -#define LABEL 1 -#define NORMAL 2 -#define JUMP 3 -#define END 4 -#define AFTERPRO 5 -#define INIT 6 - - -/* These global variables are used by getbblocks and nextblock. */ - -STATIC bblock_p b, *bp; /* b is the current basic block, bp is - * the address where the next block has - * to be linked. - */ -STATIC line_p lnp, *lp; /* lnp is the current line, lp is - * the address where the next line - * has to be linked. - */ -STATIC short state; /* We use a finite state machine with the - * following states: - * LABEL0: after the first (successive) - * instruction label. - * LABEL1: after at least two successive - * instruction labels. - * NORMAL: after a normal instruction. - * JUMP: after a branch (conditional, - * unconditional or CSA/CSB). - * END: after an END pseudo - * AFTERPRO: after we've read a PRO pseudo - * INIT: initial state - */ - - -STATIC nextblock() -{ - /* allocate a new basic block structure and - * set b, bp and lp. - */ - - b = *bp = freshblock(); - bp = &b->b_next; - b->b_start = lnp; - b->b_succ = Lempty_set(); - b->b_pred = Lempty_set(); - b->b_extend = newcfbx(); /* basic block extension for CF */ - b->b_extend->bx_cf.bx_bucket = Lempty_set(); - b->b_extend->bx_cf.bx_semi = 0; - lp = &lnp->l_next; -#ifdef TRACE - fprintf(stderr,"new basic block, id = %d\n",lastbid); -#endif -} - - -STATIC short kind(lnp) - line_p lnp; -{ - /* determine if lnp is a label, branch, end or otherwise */ - - short instr; - byte flow; - - if ((instr = INSTR(lnp)) == op_lab) return (short) LABEL; - if (instr == ps_end) return (short) END; - if (instr > sp_lmnem) return (short) NORMAL; /* pseudo */ - if ((flow = (em_flag[instr-sp_fmnem] & EM_FLO)) == FLO_C || - flow == FLO_T) return (short) JUMP; /* conditional/uncond. jump */ - return (short) NORMAL; -} - - - -STATIC bool getbblocks(fp,kind_out,n_out,g_out,l_out) - FILE *fp; - short *kind_out; - short *n_out; - bblock_p *g_out; - line_p *l_out; -{ - bblock_p head = (bblock_p) 0; - line_p headl = (line_p) 0; - - curproc = (proc_p) 0; - /* curproc will get a value when we encounter a PRO pseudo. - * If there is no such pseudo, we're reading only data - * declarations or messages (outside any proc.). - */ - curinp = fp; - lastbid = (block_id) 0; /* block identier */ - state = INIT; /* initial state */ - bp = &head; - - for (;;) { -#ifdef TRACE - fprintf(stderr,"state = %d\n",state); -#endif - switch(state) { - case LABEL0: - nextblock(); - /* Fall through !! */ - case LABEL: - lbmap[INSTRLAB(lnp)] = b; - /* The lbmap table contains for each - * label_id the basic block of that label. - */ - lnp = read_line(&curproc); - state = kind(lnp); - if (state != END) { - *lp = lnp; - lp = &lnp->l_next; - } - break; - case NORMAL: - lnp = read_line(&curproc); - if ( (state = kind(lnp)) == LABEL) { - /* If we come accross a label - * here, it must be the beginning - * of a new basic block. - */ - state = LABEL0; - } else { - if (state != END) { - *lp = lnp; - lp = &lnp->l_next; - } - } - break; - case JUMP: - lnp = read_line(&curproc); - /* fall through ... */ - case AFTERPRO: - switch(state = kind(lnp)) { - case LABEL: - state = LABEL0; - break; - case JUMP: - case NORMAL: - nextblock(); - break; - } - break; - case END: - *lp = lnp; -#ifdef TRACE - fprintf(stderr,"at end of proc, %d blocks\n",lastbid); -#endif - if (head == (bblock_p) 0) { - *kind_out = LDATA; - *l_out = headl; - } else { - *kind_out = LTEXT; - *g_out = head; - *n_out = (short) lastbid; - /* number of basic blocks */ - } - return TRUE; - case INIT: - lnp = read_line(&curproc); - if (feof(curinp)) return FALSE; - if (INSTR(lnp) == ps_pro) { - state = AFTERPRO; - } else { - state = NORMAL; - headl = lnp; - lp = &lnp->l_next; - } - break; - } - } -} - - -STATIC interproc_analysis(p) - proc_p p; -{ - /* Interprocedural analysis of a procedure p determines: - * - all procedures called by p (the 'call graph') - * - the set of objects changed by p (directly) - * - whether p does a load-indirect (loi,lof etc.) - * - whether p does a store-indirect (sti, stf etc.) - * The changed/used variables information will be - * transitively closed, i.e. if P calls Q and Q changes - * a variable X, the P changes X too. - * (The same applies for used variables and for use/store - * indirect). - * The transitive closure will be computed by main - * after all procedures have been processed. - */ - - bblock_p b; - line_p lnp; - bool inloop; - - /* Allocate memory for structs and sets */ - - p->p_use = newuse(); - p->p_change = newchange(); - p->p_change->c_ext = Cempty_set(olength); - p->p_calling = Cempty_set(plength); - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - inloop = (Lnrelems(b->b_loops) > 0); - for (lnp = b->b_start; lnp != (line_p) 0; lnp = lnp->l_next) { - /* for all instructions of p do */ - switch(INSTR(lnp)) { - case op_cal: - Cadd(PROC(lnp)->p_id, &p->p_calling); - /* add called proc to p_calling */ - if (inloop) { - CALLED_IN_LOOP(PROC(lnp)); - } - break; - case op_cai: - Cadd(p->p_id,&cai_set); - break; - case op_lpi: - Cadd(PROC(lnp)->p_id, &lpi_set); - /* All procedures that have their names used - * in an lpi instruction, may be called via - * a cai instruction. - */ - PROC(lnp)->p_flags1 |= PF_LPI; - break; - case op_ste: - case op_sde: - case op_ine: - case op_dee: - case op_zre: - Cadd(OBJ(lnp)->o_id, &p->p_change->c_ext); - /* Add changed object to c_ext */ - break; - case op_lil: - case op_lof: - case op_loi: - case op_los: - case op_lar: - p->p_use->u_flags |= UF_INDIR; - /* p does a load-indirect */ - break; - case op_sil: - case op_stf: - case op_sti: - case op_sts: - case op_sar: - p->p_change->c_flags |= CF_INDIR; - /* p does a store-indirect */ - break; - case op_blm: - case op_bls: - p->p_use->u_flags |= UF_INDIR; - p->p_change->c_flags |= CF_INDIR; - /* p does both */ - break; - case op_mon: - printf("mon not yet implemented\n"); - break; - case op_lxl: - case op_lxa: - curproc->p_flags1 |= PF_ENVIRON; - break; - } - } - } -} - - -STATIC cf_cleanproc(p) - proc_p p; -{ - /* Remove the extended data structures of p */ - - register bblock_p b; - register Lindex pi; - loop_p lp; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - oldcfbx(b->b_extend); - } - for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; pi = Lnext(pi, - p->p_loops)) { - lp = (loop_p) Lelem(pi); - oldcflpx(lp->lp_extend); - } -} - - - -#define CHANGE_INDIR(ch) ((ch->c_flags & CF_INDIR) != 0) -#define USE_INDIR(us) ((us->u_flags & UF_INDIR) != 0) -#define CALLS_UNKNOWN(p) (p->p_flags1 & (byte) PF_CALUNKNOWN) -#define BODY_KNOWN(p) (p->p_flags1 & (byte) PF_BODYSEEN) -#define ENVIRON(p) (p->p_flags1 & (byte) PF_ENVIRON) - - -STATIC bool add_info(q,p) - proc_p q,p; -{ - /* Determine the consequences for used/changed variables info - * of the fact that p calls q. If e.g. q changes a variable X - * then p changes this variable too. This routine is an - * auxiliary routine of the transitive closure process. - * The returned value indicates if there was any change in - * the information of p. - */ - - change_p chp, chq; - use_p usp, usq; - bool diff = FALSE; - - chp = p->p_change; - chq = q->p_change; - usp = p->p_use; - usq = q->p_use; - - if (!BODY_KNOWN(q)) { - /* q is a procedure of which the body is not available - * as EM text. - */ - if (CALLS_UNKNOWN(p)) { - return FALSE; - /* p already called an unknown procedure */ - } else { - p->p_flags1 |= PF_CALUNKNOWN; - return TRUE; - } - } - if (CALLS_UNKNOWN(q)) { - /* q calls a procedure of which the body is not available - * as EM text. - */ - if (!CALLS_UNKNOWN(p)) { - p->p_flags1 |= PF_CALUNKNOWN; - diff = TRUE; - } - } - if (IS_CALLED_IN_LOOP(p) && !IS_CALLED_IN_LOOP(q)) { - CALLED_IN_LOOP(q); - diff = TRUE; - } - if (!Cis_subset(chq->c_ext, chp->c_ext)) { - /* q changes global variables (objects) that - * p did not (yet) change. Add all variables - * changed by q to the c_ext set of p. - */ - Cjoin(chq->c_ext, &chp->c_ext); - diff = TRUE; - } - if (CHANGE_INDIR(chq) && !CHANGE_INDIR(chp)) { - /* q does a change-indirect (sil etc.) - * and p did not (yet). - */ - chp->c_flags |= CF_INDIR; - diff = TRUE; - } - if (USE_INDIR(usq) && !USE_INDIR(usp)) { - /* q does a use-indirect (lil etc.) - * and p dis not (yet). - */ - usp->u_flags |= UF_INDIR; - diff = TRUE; - } - if (ENVIRON(q) && !ENVIRON(p)) { - /* q uses or changes local variables in its - * environment while p does not (yet). - */ - p->p_flags1 |= PF_ENVIRON; - diff = TRUE; - } - return diff; -} - - - -STATIC trans_clos(head) - proc_p head; -{ - /* Compute the transitive closure of the used/changed - * variable information. - */ - - register proc_p p,q; - Cindex i; - bool changes = TRUE; - - while(changes) { - changes = FALSE; - for (p = head; p != (proc_p) 0; p = p->p_next) { - if (!BODY_KNOWN(p)) continue; - for (i = Cfirst(p->p_calling); i != (Cindex) 0; - i = Cnext(i,p->p_calling)) { - q = pmap[Celem(i)]; - if (add_info(q,p)) { - changes = TRUE; - } - } - } - } -} - - - - -indir_calls() -{ - Cindex i; - proc_p p; - - for (i = Cfirst(cai_set); i != (Cindex) 0; i = Cnext(i,cai_set)) { - p = pmap[Celem(i)]; /* p does a CAI */ - Cjoin(lpi_set, &p->p_calling); - } - Cdeleteset(lpi_set); - Cdeleteset(cai_set); -} - - - -main(argc,argv) - int argc; - char *argv[]; -{ - FILE *f, *f2, *gf2; /* The EM input, EM output, basic block output */ - bblock_p g; - short n, kind; - line_p l; - - linecount = 0; - fproc = getptable(pname); /* proc table */ - fdblock = getdtable(dname); /* data block table */ - lpi_set = Cempty_set(plength); - cai_set = Cempty_set(plength); - if ((f = fopen(lname,"r")) == NULL) { - error("cannot open %s", lname); - } - if ((f2 = fopen(lname2,"w")) == NULL) { - error("cannot open %s", lname2); - } - if ((gf2 = fopen(bname2,"w")) == NULL) { - error("cannot open %s",bname2); - } - while (getbblocks(f,&kind,&n,&g,&l)) { - /* read EM text of one unit and - * (if it is a procedure) - * partition it into n basic blocks. - */ - if (kind == LDATA) { - putunit(LDATA,(proc_p) 0,l,gf2,f2); - } else { - curproc->p_start = g; - /* The global variable curproc points to the - * current procedure. It is set by getbblocks - */ - control_flow(g); /* compute pred and succ */ - dominators(g,n); /* compute immediate dominators */ - loop_detection(curproc); /* compute loops */ - interproc_analysis(curproc); - /* Interprocedural analysis */ - cf_cleanproc(curproc); - putunit(LTEXT,curproc,(line_p) 0,gf2,f2); - /* output control flow graph + text */ - } - } - fclose(f); - fclose(f2); - fclose(gf2); - indir_calls(); - trans_clos(fproc); - /* Compute transitive closure of used/changed - * variables information for every procedure. - */ - if ((f = fopen(dname2,"w")) == NULL) { - error("cannot open %s",dname2); - } - putdtable(fdblock,f); - if ((f = fopen(pname2,"w")) == NULL) { - error("cannot open %s",pname2); - } - putptable(fproc,f,TRUE); - exit(0); -} diff --git a/util/ego/cf/cf.h b/util/ego/cf/cf.h deleted file mode 100644 index 2a14b0fff..000000000 --- a/util/ego/cf/cf.h +++ /dev/null @@ -1,16 +0,0 @@ -/* C O N T R O L F L O W */ - -/* Macro's for extended data structures: */ - -#define B_SEMI b_extend->bx_cf.bx_semi -#define B_PARENT b_extend->bx_cf.bx_parent -#define B_BUCKET b_extend->bx_cf.bx_bucket -#define B_ANCESTOR b_extend->bx_cf.bx_ancestor -#define B_LABEL b_extend->bx_cf.bx_label - -#define LP_BLOCKS lp_extend->lpx_cf.lpx_blocks -#define LP_COUNT lp_extend->lpx_cf.lpx_count -#define LP_MESSY lp_extend->lpx_cf.lpx_messy - -#define newcflpx() (lpext_p) newstruct(lpext_cf) -#define oldcflpx(x) oldstruct(lpext_cf,x) diff --git a/util/ego/cf/cf_idom.c b/util/ego/cf/cf_idom.c deleted file mode 100644 index 6e9695593..000000000 --- a/util/ego/cf/cf_idom.c +++ /dev/null @@ -1,138 +0,0 @@ -/* C O N T R O L F L O W - * - * C F _ I D O M . C - */ - - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/lset.h" -#include "../share/alloc.h" -#include "cf.h" - - -/* The algorithm for finding dominators in a flowgraph - * that is used here, was developed by Thomas Lengauer - * and Robert E. Tarjan of Stanford University. - * The algorithm is described in their article: - * A Fast Algorithm for Finding Dominators - * in a Flowgraph - * which was published in: - * ACM Transactions on Programming Languages and Systems, - * Vol. 1, No. 1, July 1979, Pages 121-141. - */ - - -#define UNREACHABLE(b) (b->B_SEMI == (short) 0) - -short dfs_nr; -bblock_p *vertex; /* dynamically allocated array */ - - -STATIC dfs(v) - bblock_p v; -{ - /* Depth First Search */ - - Lindex i; - bblock_p w; - - v->B_SEMI = ++dfs_nr; - vertex[dfs_nr] = v->B_LABEL = v; - v->B_ANCESTOR = (bblock_p) 0; - for (i = Lfirst(v->b_succ); i != (Lindex) 0; i = Lnext(i,v->b_succ)) { - w = (bblock_p) Lelem(i); - if (w->B_SEMI == 0) { - w->B_PARENT = v; - dfs(w); - } - } -} - - - -STATIC compress(v) - bblock_p v; -{ - if (v->B_ANCESTOR->B_ANCESTOR != (bblock_p) 0) { - compress(v->B_ANCESTOR); - if (v->B_ANCESTOR->B_LABEL->B_SEMI < v->B_LABEL->B_SEMI) { - v->B_LABEL = v->B_ANCESTOR->B_LABEL; - } - v->B_ANCESTOR = v->B_ANCESTOR->B_ANCESTOR; - } -} - - - -STATIC bblock_p eval(v) - bblock_p v; -{ - if (v->B_ANCESTOR == (bblock_p) 0) { - return v; - } else { - compress(v); - return v->B_LABEL; - } -} - - - -STATIC linkblocks(v,w) - bblock_p v,w; -{ - w->B_ANCESTOR = v; -} - - - -dominators(r,n) - bblock_p r; - short n; -{ - /* Compute the immediate dominator of every basic - * block in the control flow graph rooted by r. - */ - - register short i; - Lindex ind, next; - bblock_p v,w,u; - - dfs_nr = 0; - vertex = (bblock_p *) newmap(n); - /* allocate vertex (dynamic array). All remaining - * initializations were done by the routine - * nextblock of get.c. - */ - dfs(r); - for (i = dfs_nr; i > 1; i--) { - w = vertex[i]; - for (ind = Lfirst(w->b_pred); ind != (Lindex) 0; - ind = Lnext(ind,w->b_pred)) { - v = (bblock_p) Lelem(ind); - if (UNREACHABLE(v)) continue; - u = eval(v); - if (u->B_SEMI < w->B_SEMI) { - w->B_SEMI = u->B_SEMI; - } - } - Ladd(w,&(vertex[w->B_SEMI]->B_BUCKET)); - linkblocks(w->B_PARENT,w); - for (ind = Lfirst(w->B_PARENT->B_BUCKET); ind != (Lindex) 0; - ind = next) { - next = Lnext(ind,w->B_PARENT->B_BUCKET); - v = (bblock_p) Lelem(ind); - Lremove(v,&w->B_PARENT->B_BUCKET); - u = eval(v); - v->b_idom = (u->B_SEMI < v->B_SEMI ? u : w->B_PARENT); - } - } - for (i = 2; i <= dfs_nr; i++) { - w = vertex[i]; - if (w->b_idom != vertex[w->B_SEMI]) { - w->b_idom = w->b_idom->b_idom; - } - } - r->b_idom = (bblock_p) 0; - oldmap(vertex,n); /* release memory for dynamic array vertex */ -} diff --git a/util/ego/cf/cf_idom.h b/util/ego/cf/cf_idom.h deleted file mode 100644 index 7a644abaa..000000000 --- a/util/ego/cf/cf_idom.h +++ /dev/null @@ -1,15 +0,0 @@ -/* C O N T R O L F L O W - * - * I M M E D I A T E D O M I N A T O R S - */ - - -extern dominator(); /* (bblock_p head, short n) - * Compute for every basic block its immediate - * dominator. The dominator relation is hence - * recorded as a tree in which every node contains - * a pointer to its parent, which is its - * immediate dominator. - * 'n' is the number of nodes (basic blocks) in - * the control flow graph. - */ diff --git a/util/ego/cf/cf_loop.c b/util/ego/cf/cf_loop.c deleted file mode 100644 index e0a6ffe13..000000000 --- a/util/ego/cf/cf_loop.c +++ /dev/null @@ -1,400 +0,0 @@ -/* C O N T R O L F L O W - * - * C F _ L O O P . C - */ - - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/lset.h" -#include "../share/alloc.h" -#include "../share/aux.h" -#include "cf.h" - -#define MARK_STRONG(b) b->b_flags |= BF_STRONG -#define MARK_FIRM(b) b->b_flags |= BF_FIRM -#define BF_MARK 04 -#define MARK(b) b->b_flags |= BF_MARK -#define MARKED(b) (b->b_flags&BF_MARK) -#define INSIDE_LOOP(b,lp) Lis_elem(b,lp->LP_BLOCKS) - - - -/* The algorithm to detect loops that is used here is taken - * from: Aho & Ullman, Principles of Compiler Design, section 13.1. - * The algorithm uses the dominator relation between nodes - * of the control flow graph: - * d DOM n => every path from the initial node to n goes through d. - * The dominator relation is recorded via the immediate dominator tree - * (b_idom field of bblock struct) from which the dominator relation - * can be easily computed (see procedure 'dom' below). - * The algorithm first finds 'back edges'. A back edge is an edge - * a->b in the flow graph whose head (b) dominates its tail (a). - * The 'natural loop' of back edge n->d consists of those nodes - * that can reach n without going through d. These nodes, plus d - * form the loop. - * The whole process is rather complex, because different back edges - * may result in the same loop and because loops may partly overlap - * each other (without one being nested inside the other). - */ - - - -STATIC bool same_loop(l1,l2) - loop_p l1,l2; -{ - /* Two loops are the same if: - * (1) they have the same number of basic blocks, and - * (2) the head of the back edge of the first loop - * also is part of the second loop, and - * (3) the tail of the back edge of the first loop - * also is part of the second loop. - */ - - return (l1->LP_COUNT == l2->LP_COUNT && - Lis_elem(l1->lp_entry, l2->LP_BLOCKS) && - Lis_elem(l1->lp_end, l2->LP_BLOCKS)); -} - - - -STATIC bool inner_loop(l1,l2) - loop_p l1,l2; -{ - /* Loop l1 is an inner loop of l2 if: - * (1) the first loop has fewer basic blocks than - * the second one, and - * (2) the head of the back edge of the first loop - * also is part of the second loop, and - * (3) the tail of the back edge of the first loop - * also is part of the second loop. - */ - - return (l1->LP_COUNT < l2->LP_COUNT && - Lis_elem(l1->lp_entry, l2->LP_BLOCKS) && - Lis_elem(l1->lp_end, l2->LP_BLOCKS)); -} - - - -STATIC insrt(b,lpb,s_p) - bblock_p b; - lset *lpb; - lset *s_p; -{ - /* Auxiliary routine used by 'natural_loop'. - * Note that we use a set rather than a stack, - * as Aho & Ullman do. - */ - - if (!Lis_elem(b,*lpb)) { - Ladd(b,lpb); - Ladd(b,s_p); - } -} - - -STATIC loop_p natural_loop(d,n) - bblock_p d,n; -{ - /* Find the basic blocks of the natural loop of the - * back edge 'n->d' (i.e. n->d is an edge in the control - * flow graph and d dominates n). The natural loop consists - * of those blocks which can reach n without going through d. - * We find these blocks by finding all predecessors of n, - * up to d. - */ - - loop_p lp; - bblock_p m; - lset loopblocks; - Lindex pi; - lset s; - - lp = newloop(); - lp->lp_extend = newcflpx(); - lp->lp_entry = d; /* loop entry block */ - lp->lp_end = n; /* tail of back edge */ - s = Lempty_set(); - loopblocks = Lempty_set(); - Ladd(d,&loopblocks); - insrt(n,&loopblocks,&s); - while ((pi = Lfirst(s)) != (Lindex) 0) { - m = (bblock_p) Lelem(pi); - Lremove(m,&s); - for (pi = Lfirst(m->b_pred); pi != (Lindex) 0; - pi = Lnext(pi,m->b_pred)) { - insrt((bblock_p) Lelem(pi),&loopblocks,&s); - } - } - lp->LP_BLOCKS = loopblocks; - lp->LP_COUNT = Lnrelems(loopblocks); - return lp; -} - - -STATIC loop_p org_loop(lp,loops) - loop_p lp; - lset loops; -{ - /* See if the loop lp was already found via another - * back edge; if so return this loop; else return 0. - */ - - register Lindex li; - - for (li = Lfirst(loops); li != (Lindex) 0; li = Lnext(li,loops)) { - if (same_loop((loop_p) Lelem(li), lp)) { -#ifdef DEBUG - /* printf("messy loop found\n"); */ -#endif - return (loop_p) Lelem(li); - } - } - return (loop_p) 0; -} - - - -STATIC collapse_loops(loops_p) - lset *loops_p; -{ - register Lindex li1, li2; - register loop_p lp1,lp2; - - for (li1 = Lfirst(*loops_p); li1 != (Lindex) 0; li1 = Lnext(li1,*loops_p)) { - lp1 = (loop_p) Lelem(li1); - lp1->lp_level = (short) 0; - for (li2 = Lfirst(*loops_p); li2 != (Lindex) 0; - li2 = Lnext(li2,*loops_p)) { - lp2 = (loop_p) Lelem(li2); - if (lp1 != lp2 && lp1->lp_entry == lp2->lp_entry) { - Ljoin(lp2->LP_BLOCKS,&lp1->LP_BLOCKS); - oldcflpx(lp2->lp_extend); - Lremove(lp2,loops_p); - } - } - } -} - - -STATIC loop_per_block(lp) - loop_p lp; -{ - bblock_p b; - - /* Update the b_loops sets */ - - register Lindex bi; - - for (bi = Lfirst(lp->LP_BLOCKS); bi != (Lindex) 0; - bi = Lnext(bi,lp->LP_BLOCKS)) { - b = (bblock_p) Lelem(bi); - Ladd(lp,&(b->b_loops)); - } -} - - - -STATIC loop_attrib(loops) - lset loops; -{ - /* Compute several attributes */ - - register Lindex li; - register loop_p lp; - loop_id lastlpid = 0; - - for (li = Lfirst(loops); li != (Lindex) 0; li = Lnext(li,loops)) { - lp = (loop_p) Lelem(li); - lp->lp_id = ++lastlpid; - loop_per_block(lp); - } -} - - - -STATIC nest_levels(loops) - lset loops; -{ - /* Compute the nesting levels of all loops of - * the current procedure. For every loop we just count - * all loops of which the former is an inner loop. - * The running time is quadratic in the number of loops - * of the current procedure. As this number tends to be - * very small, there is no cause for alarm. - */ - - register Lindex li1, li2; - register loop_p lp; - - for (li1 = Lfirst(loops); li1 != (Lindex) 0; li1 = Lnext(li1,loops)) { - lp = (loop_p) Lelem(li1); - lp->lp_level = (short) 0; - for (li2 = Lfirst(loops); li2 != (Lindex) 0; - li2 = Lnext(li2,loops)) { - if (inner_loop(lp,(loop_p) Lelem(li2))) { - lp->lp_level++; - } - } - } -} - - -STATIC cleanup(loops) - lset loops; -{ - /* Throw away the LP_BLOCKS sets */ - - register Lindex i; - - for (i = Lfirst(loops); i != (Lindex) 0; i = Lnext(i,loops)) { - Ldeleteset(((loop_p) Lelem(i))->LP_BLOCKS); - } -} - - -STATIC bool does_exit(b,lp) - bblock_p b; - loop_p lp; -{ - /* See if b may exit the loop, i.e. if it - * has a successor outside the loop - */ - - Lindex i; - - for (i = Lfirst(b->b_succ); i != (Lindex) 0; i = Lnext(i,b->b_succ)) { - if (!INSIDE_LOOP(Lelem(i),lp)) return TRUE; - } - return FALSE; -} - - -STATIC mark_succ(b,lp) - bblock_p b; - loop_p lp; -{ - Lindex i; - bblock_p succ; - - for (i = Lfirst(b->b_succ); i != (Lindex) 0; i = Lnext(i,b->b_succ)) { - succ = (bblock_p) Lelem(i); - if (succ != b && succ != lp->lp_entry && INSIDE_LOOP(succ,lp) && - !MARKED(succ)) { - MARK(succ); - mark_succ(succ,lp); - } - } -} - - -STATIC mark_blocks(lp) - loop_p lp; -{ - /* Mark the strong and firm blocks of a loop. - * The last set of blocks consists of the end-block - * of the loop (i.e. the head of the back edge - * of the natural loop) and its dominators - * (including the loop entry block, i.e. the - * tail of the back edge). - */ - - register bblock_p b; - - /* First mark all blocks that are the successor of a - * block that may exit the loop (i.e. contains a - * -possibly conditional- jump to somewhere outside - * the loop. - */ - - if (lp->LP_MESSY) return; /* messy loops are hopeless cases */ - for (b = lp->lp_entry; b != (bblock_p) 0; b = b->b_next) { - if (!MARKED(b) && does_exit(b,lp)) { - mark_succ(b,lp); - } - } - - /* Now find all firm blocks. A block is strong - * if it is firm and not marked. - */ - - for (b = lp->lp_end; ; b = b->b_idom) { - MARK_FIRM(b); - if (!MARKED(b)) { - MARK_STRONG(b); - } - if (b == lp->lp_entry) break; - } -} - - - -STATIC mark_loopblocks(loops) - lset loops; -{ - /* Determine for all loops which basic blocks - * of the loop are strong (i.e. are executed - * during every iteration) and which blocks are - * firm (i.e. executed during every iteration with - * the only possible exception of the last one). - */ - - Lindex i; - loop_p lp; - - for (i = Lfirst(loops); i != (Lindex) 0; i = Lnext(i,loops)) { - lp = (loop_p) Lelem(i); - mark_blocks(lp); - } -} - - - -loop_detection(p) - proc_p p; -{ - /* Find all natural loops of procedure p. Every loop is - * assigned a unique identifying number, a set of basic - * blocks, a loop entry block and a nesting level number. - * Every basic block is assigned a nesting level number - * and a set of loops it is part of. - */ - - lset loops; /* the set of all loops */ - loop_p lp,org; - register bblock_p b; - bblock_p s; - Lindex si; - - loops = Lempty_set(); - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (si = Lfirst(b->b_succ); si != (Lindex) 0; - si = Lnext(si,b->b_succ)) { - s = (bblock_p) Lelem(si); - if (dom(s,b)) { - /* 'b->s' is a back edge */ - lp = natural_loop(s,b); - if ((org = org_loop(lp,loops)) == (loop_p) 0) { - /* new loop */ - Ladd(lp,&loops); - } else { - /* Same loop, generated by several back - * edges; such a loop is called a messy - * loop. - */ - org->LP_MESSY = TRUE; - Ldeleteset(lp->LP_BLOCKS); - oldcflpx(lp->lp_extend); - oldloop(lp); - } - } - } - } - collapse_loops(&loops); - loop_attrib(loops); - nest_levels(loops); - mark_loopblocks(loops); /* determine firm and strong blocks */ - cleanup(loops); - p->p_loops = loops; -} diff --git a/util/ego/cf/cf_loop.h b/util/ego/cf/cf_loop.h deleted file mode 100644 index 473651025..000000000 --- a/util/ego/cf/cf_loop.h +++ /dev/null @@ -1,14 +0,0 @@ -/* C O N T R O L F L O W - * - * L O O P D E T E C T I O N - */ - -extern loop_detection(); /* (proc_p p) - * Detect all loops of procedure p. - * Every basic block of p is assigned - * a set of all loops it is part of. - * For every loop we record the number - * of blocks it contains, the loop entry - * block and its nesting level (0 = outer - * loop, 1 = loop within loop etc.). - */ diff --git a/util/ego/cf/cf_succ.c b/util/ego/cf/cf_succ.c deleted file mode 100644 index 7ec419bee..000000000 --- a/util/ego/cf/cf_succ.c +++ /dev/null @@ -1,250 +0,0 @@ -/* C O N T R O L F L O W - * - * C F _ S U C C . C - */ - - -#include -#include "../share/types.h" -#include "../share/def.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_flag.h" -#include "../../../h/em_mnem.h" -#include "cf.h" -#include "../share/map.h" - -extern char em_flag[]; - - -STATIC succeeds(succ,pred) - bblock_p succ, pred; -{ - assert(pred != (bblock_p) 0); - if (succ != (bblock_p) 0) { - Ladd(succ, &pred->b_succ); - Ladd(pred, &succ->b_pred); - } -} - - -#define IS_RETURN(i) (i == op_ret || i == op_rtt) -#define IS_CASE_JUMP(i) (i == op_csa || i == op_csb) -#define IS_UNCOND_JUMP(i) (i <= sp_lmnem && (em_flag[i-sp_fmnem] & EM_FLO) == FLO_T) -#define IS_COND_JUMP(i) (i <= sp_lmnem && (em_flag[i-sp_fmnem] & EM_FLO) == FLO_C) -#define TARGET(lnp) (lbmap[INSTRLAB(lnp)]) -#define ATARGET(arg) (lbmap[arg->a_a.a_instrlab]) - - - -STATIC arg_p skip_const(arg) - arg_p arg; -{ - assert(arg != (arg_p) 0); - switch(arg->a_type) { - case ARGOFF: - case ARGICN: - case ARGUCN: - break; - default: - error("bad case descriptor"); - } - return arg->a_next; -} - - -STATIC arg_p use_label(arg,b) - arg_p arg; - bblock_p b; -{ - if (arg->a_type == ARGINSTRLAB) { - /* arg is a non-null label */ - succeeds(ATARGET(arg),b); - } - return arg->a_next; -} - - - -STATIC case_flow(instr,desc,b) - short instr; - line_p desc; - bblock_p b; -{ - /* Analyse the case descriptor (given as a ROM pseudo instruction). - * Every instruction label appearing in the descriptor - * heads a basic block that is a successor of the block - * in which the case instruction appears (b). - */ - - register arg_p arg; - - assert(instr == op_csa || instr == op_csb); - assert(TYPE(desc) == OPLIST); - arg = ARG(desc); - arg = use_label(arg,b); - /* See if there is a default label. If so, then - * its block is a successor of b. Set arg to - * next argument. - */ - if (instr == op_csa) { - arg = skip_const(arg); /* skip lower bound */ - arg = skip_const(arg); /* skip lower-upper bound */ - while (arg != (arg_p) 0) { - /* All following arguments are case labels - * or zeroes. - */ - arg = use_label(arg,b); - } - } else { - /* csb instruction */ - arg = skip_const(arg); /* skip #entries */ - while (arg != (arg_p) 0) { - /* All following arguments are alternatively - * an index and an instruction label (possibly 0). - */ - arg = skip_const(arg); /* skip index */ - arg = use_label(arg,b); - } - } -} - - - -STATIC line_p case_descr(lnp) - line_p lnp; -{ - /* lnp is the instruction just before a csa or csb, - * so it is the instruction that pushes the address - * of a case descriptor on the stack. Find that - * descriptor, i.e. a rom pseudo instruction. - * Note that this instruction will always be part - * of the procedure in which the csa/csb occurs. - */ - - register line_p l; - dblock_p d; - obj_p obj; - dblock_id id; - - if (lnp == (line_p) 0 || (INSTR(lnp)) != op_lae) { - error("cannot find 'lae descr' before csa/csb"); - } - /* We'll first find the ROM and its dblock_id */ - obj = OBJ(lnp); - if (obj->o_off != (offset) 0) { - error("bad 'lae descr' before csa/csb"); - /* We require a descriptor to be an entire rom, - * not part of a rom. - */ - } - d = obj->o_dblock; - assert(d != (dblock_p) 0); - if (d->d_pseudo != DROM) { - error("case descriptor must be in rom"); - } - id = d->d_id; - /* We'll use the dblock_id to find the defining occurrence - * of the rom in the EM text (i.e. a rom pseudo). As all - * pseudos appear at the beginning of a procedure, we only - * have to look in its first basic block. - */ - assert(curproc != (proc_p) 0); - assert(curproc->p_start != (bblock_p) 0); - l = curproc->p_start->b_start; /* first instruction of curproc */ - while (l != (line_p) 0) { - if ((INSTR(l)) == ps_sym && - SHORT(l) == id) { - /* found! */ - assert((INSTR(l->l_next)) == ps_rom); - return l->l_next; - } - l = l->l_next; - } - error("cannot find rom pseudo for case descriptor"); - /* NOTREACHED */ -} - - - -STATIC last2_instrs(b,last_out,prev_out) - bblock_p b; - line_p *last_out,*prev_out; -{ - /* Determine the last and one-but-last instruction - * of basic block b. An end-pseudo is not regarded - * as an instruction. If the block contains only 1 - * instruction, prev_out is 0. - */ - - register line_p l1,l2; - - l2 = b->b_start; /* first instruction of b */ - assert(l2 != (line_p) 0); /* block can not be empty */ - if ((l1 = l2->l_next) == (line_p) 0 || INSTR(l1) == ps_end) { - *last_out = l2; /* single instruction */ - *prev_out = (line_p) 0; - } else { - while(l1->l_next != (line_p) 0 && INSTR(l1->l_next) != ps_end) { - l2 = l1; - l1 = l1->l_next; - } - *last_out = l1; - *prev_out = l2; - } -} - - - -control_flow(head) - bblock_p head; -{ - /* compute the successor and predecessor relation - * for every basic block. - */ - - register bblock_p b; - line_p lnp, prev; - short instr; - - for (b = head; b != (bblock_p) 0; b = b->b_next) { - /* for every basic block, in textual order, do */ - last2_instrs(b, &lnp, &prev); - /* find last and one-but-last instruction */ - instr = INSTR(lnp); - /* The last instruction of the basic block - * determines the set of successors of the block. - */ - if (IS_CASE_JUMP(instr)) { - case_flow(instr,case_descr(prev),b); - /* If lnp is a csa or csb, then the instruction - * just before it (i.e. prev) must be the - * instruction that pushes the address of the - * case descriptor. This descriptor is found - * and analysed in order to build the successor - * and predecessor sets of b. - */ - } else { - if (!IS_RETURN(instr)) { - if (IS_UNCOND_JUMP(instr)) { - succeeds(TARGET(lnp),b); - } else { - if (IS_COND_JUMP(instr)) { - succeeds(TARGET(lnp),b); - succeeds(b->b_next, b); - /* Textually next block is - * a successor of b. - */ - } else { - /* normal instruction */ - succeeds(b->b_next, b); - } - } - } - } - } -} diff --git a/util/ego/cf/cf_succ.h b/util/ego/cf/cf_succ.h deleted file mode 100644 index b475d1a77..000000000 --- a/util/ego/cf/cf_succ.h +++ /dev/null @@ -1,10 +0,0 @@ -/* C O N T R O L F L O W - * - * S U C C E S S O R / P R E D E C E S S O R R E L A T I O N S - */ - -extern control_flow(); /* (bblock_p head) - * Compute for every basic block - * its successors and predecessors - * in the control flow graph. - */ diff --git a/util/ego/cj/Makefile b/util/ego/cj/Makefile deleted file mode 100644 index 15f400c7e..000000000 --- a/util/ego/cj/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -cj.c - -OFILES=\ -cj.o - -HFILES= - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/get.o $(SHR)/put.o $(SHR)/alloc.o $(SHR)/global.o $(SHR)/debug.o \ -$(SHR)/files.o $(SHR)/map.o $(SHR)/lset.o $(SHR)/cset.o $(SHR)/aux.o \ -$(SHR)/stack_chg.o $(SHR)/go.o - -SHARE_MFILES=\ -$(SHR)/get.m $(SHR)/put.m $(SHR)/alloc.m $(SHR)/global.m $(SHR)/debug.m \ -$(SHR)/files.m $(SHR)/map.m $(SHR)/lset.m $(SHR)/cset.m $(SHR)/aux.m $(SHR)/stack_chg.m $(SHR)/go.m - -cj: $(OFILES) - $(CC) -o \ - cj $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -cj_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o cj -.c $(LDFLAGS) cj.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO - -cj.o: ../../../h/em_mnem.h -cj.o: ../../../h/em_spec.h -cj.o: ../share/alloc.h -cj.o: ../share/aux.h -cj.o: ../share/debug.h -cj.o: ../share/def.h -cj.o: ../share/files.h -cj.o: ../share/get.h -cj.o: ../share/global.h -cj.o: ../share/go.h -cj.o: ../share/lset.h -cj.o: ../share/map.h -cj.o: ../share/put.h -cj.o: ../share/stack_chg.h -cj.o: ../share/types.h diff --git a/util/ego/cj/cj.c b/util/ego/cj/cj.c deleted file mode 100644 index bc4a250bf..000000000 --- a/util/ego/cj/cj.c +++ /dev/null @@ -1,355 +0,0 @@ -/* C R O S S J U M P I N G - * - * CJ.H - * - */ - -#include -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/files.h" -#include "../share/get.h" -#include "../share/put.h" -#include "../share/lset.h" -#include "../share/map.h" -#include "../share/alloc.h" -#include "../share/aux.h" -#include "../share/def.h" -#include "../share/stack_chg.h" -#include "../share/go.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_spec.h" - - -/* Cross jumping performs optimzations like: - * - * if cond then goto L1; if cond then goto L1 - * S1; -----> S1; - * S2; goto L3; - * goto L2; L1: - * L1: S3; - * S3; L3: - * S2; S2; - * L2: - * - * CJ looks for two basic blocks b1 and b2 with the following properties: - * - there exists a basic block S such that SUCC(b1) = SUCC(b2) = {S} - * (so both have only 1 successor) - * - the last N (N > 0) instructions of b1 and b2, not counting a possible - * BRAnch instruction, are the same. - * As a result of the first condition, at least of the two blocks must end - * on an (unconditional) BRAnch instruction. If both end on a BRA, one block - * is chosen at random. Assume this block is b1. A new label L is put just - * before the N common instructions of block b2 (so this block is split - * into two). The BRA of b1 is changed into a BRA L. So dynamically the same - * instructions are executed in a slightly different order; yet the size of - * the code has become smaller. - */ - - -STATIC int Scj; /* number of optimizations found */ - - - -#define DLINK(l1,l2) l1->l_next=l2; l2->l_prev=l1 - - -STATIC bool same_instr(l1,l2) - line_p l1,l2; -{ - /* See if l1 and l2 are the same instruction */ - - if (l1 == 0 || l2 == 0 || TYPE(l1) != TYPE(l2)) return FALSE; - if (INSTR(l1) != INSTR(l2)) return FALSE; - switch(TYPE(l1)) { - case OPSHORT: return SHORT(l1) == SHORT(l2); - case OPOFFSET: return OFFSET(l1) == OFFSET(l2); - case OPPROC: return PROC(l1) == PROC(l2); - case OPOBJECT: return OBJ(l1) == OBJ(l2); - case OPINSTRLAB: return INSTRLAB(l1) == INSTRLAB(l2); - case OPNO: return TRUE; - default: return FALSE; - } -} - - - -STATIC line_p last_mnem(b) - bblock_p b; -{ - /* Determine the last line of a list */ - - register line_p l; - - for (l = b->b_start; l->l_next != (line_p) 0; l = l->l_next); - while (l != (line_p) 0 && (INSTR(l) < sp_fmnem || INSTR(l) > sp_lmnem)) { - l = PREV(l); - } - return l; -} - - -STATIC bool is_desirable(text) - line_p text; -{ - /* We avoid to generate a BRAnch in the middle of some expression, - * as the code generator will write the contents of the fakestack - * to the real stack if it encounters a BRA. We do not avoid to - * split the parameter-pushing code of a subroutine call into two, - * as the parameters are pushed on the real stack anyway. - * So e.g. "LOL a ; LOL b; ADI" will not be split, but - * "LOL a; LOL b; CAL f" may be split. - */ - - line_p l; - bool ok; - int stack_diff,pop,push; - - stack_diff = 0; - for (l = text; l != (line_p) 0; l = l->l_next) { - switch(INSTR(l)) { - case op_cal: - case op_asp: - case op_bra: - return TRUE; - } - line_change(l,&ok,&pop,&push); - /* printf("instr %d, pop %d, push %d, ok %d\n",INSTR(l),pop,push,ok); */ - if (!ok || (stack_diff -= pop) < 0) { - return FALSE; - } else { - stack_diff += push; - } - } - return TRUE; -} - - -STATIC cp_loops(b1,b2) - bblock_p b1,b2; -{ - /* Copy the loopset of b2 to b1 */ - - Lindex i; - loop_p lp; - for (i = Lfirst(b2->b_loops); i != (Lindex) 0; - i = Lnext(i,b2->b_loops)) { - lp = (loop_p) Lelem(i); - Ladd(lp,&b1->b_loops); - } -} - - -STATIC jump_cross(l1,l2,b1,b2) - line_p l1,l2; - bblock_p b1,b2; -{ - /* A cross-jump from block b2 to block b1 is found; the code in - * block b2 from line l2 up to the BRAnch is removed; block b1 is - * split into two; the second part consists of a new label - * followed by the code from l1 till the end of the block. - */ - - line_p l; - bblock_p b; - bblock_p s; - - /* First adjust the control flow graph */ - b = freshblock(); /* create a new basic block */ - b->b_succ = b1->b_succ; - /* SUCC(b1) = {b} */ - b1->b_succ = Lempty_set(); Ladd(b,&b1->b_succ); - /* SUCC(b2) = {b} */ - Ldeleteset(b2->b_succ); b2->b_succ = Lempty_set(); Ladd(b,&b2->b_succ); - /* PRED(b) = {b1,b2} */ - b->b_pred = Lempty_set(); Ladd(b1,&b->b_pred); Ladd(b2,&b->b_pred); - /* PRED(SUCC(b)) := PRED(SUCC(b)) - {b1,b2} + {b} */ - assert(Lnrelems(b->b_succ) == 1); - s = (bblock_p) Lelem(Lfirst(b->b_succ)); - Lremove(b1,&s->b_pred); Lremove(b2,&s->b_pred); Ladd(b,&s->b_pred); - cp_loops(b,b1); - b->b_idom = common_dom(b1,b2); - b->b_flags = b1->b_flags; - b->b_next = b1->b_next; - b1->b_next = b; - - /* Now adjust the EM text */ - l = PREV(l1); - if (l == (line_p) 0) { - b1->b_start = (line_p) 0; - } else { - l->l_next = (line_p) 0; - } - l = newline(OPINSTRLAB); - l->l_instr = op_lab; - INSTRLAB(l) = freshlabel(); - DLINK(l,l1); - b->b_start = l; - for (l = l2; INSTR(l) != op_bra; l = l->l_next) { - assert (l != (line_p) 0); - rm_line(l,b2); - } - INSTRLAB(l) = INSTRLAB(b->b_start); -} - - -STATIC bool try_tail(b1,b2) - bblock_p b1,b2; -{ - /* See if b1 and b2 end on the same sequence of instructions */ - - line_p l1,l2; - bblock_p b = (bblock_p) 0; - int cnt = 0; - /* printf("try block %d and %d\n",b1->b_id,b2->b_id); */ - - if (b1->b_start == (line_p) 0 || b2->b_start == (line_p) 0) return FALSE; - l1 = last_mnem(b1); - l2 = last_mnem(b2); - if (l1 == (line_p) 0 || l2 == (line_p) 0) return FALSE; - /* printf("consider:\n"); showinstr(l1); showinstr(l2); */ - if (INSTR(l1) == op_bra) { - b = b1; - l1 = PREV(l1); - } - if (INSTR(l2) == op_bra) { - b = b2; - l2 = PREV(l2); - } - assert(b != (bblock_p) 0); - while(same_instr(l1,l2)) { - cnt++; - l1 = PREV(l1); - l2 = PREV(l2); - /* printf("consider:\n"); showinstr(l1); showinstr(l2); */ - } - if (cnt >= 1) { - l1 = (l1 == 0 ? b1->b_start : l1->l_next); - l2 = (l2 == 0 ? b2->b_start : l2->l_next); - if (is_desirable(l1)) { - if (b == b1) { - jump_cross(l2,l1,b2,b1); - Scj++; - } else { - jump_cross(l1,l2,b1,b2); - Scj++; - } - return TRUE; - } - } - return FALSE; -} - - - -STATIC bool try_pred(b) - bblock_p b; -{ - /* See if there is any pair (b1,b2), both in PRED(b) for - * which we can perform cross jumping. - */ - - register bblock_p b1,b2; - register Lindex i,j; - lset s = b->b_pred; - - for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i,s)) { - b1 = (bblock_p) Lelem(i); - if (Lnrelems(b1->b_succ) != 1) continue; - for (j = Lfirst(s); j != (Lindex) 0; j = Lnext(j,s)) { - b2 = (bblock_p) Lelem(j); - if (b1 != b2 && Lnrelems(b2->b_succ) == 1) { - if (try_tail(b1,b2)) return TRUE; - } - } - } - return FALSE; -} - - - -cj_optimize(p) - proc_p p; -{ - /* Perform cross jumping for procedure p. - * In case cases a cross-jumping optimization which give - * new opportunities for further cross-jumping optimizations. - * Hence we repeat the whole process for the entire procedure, - * untill we find no further optimizations. - */ - - bblock_p b; - bool changes = TRUE; - - while(changes) { - changes = FALSE; - b = p->p_start; - while (b != (bblock_p) 0) { - if (try_pred(b)) { - changes = TRUE; - } else { - b = b->b_next; - } - } - } -} - - -main(argc,argv) - int argc; - char *argv[]; -{ - go(argc,argv,no_action,cj_optimize,no_action,no_action); - report("cross jumps",Scj); - exit(0); -} - - - -/****** - * Debugging stuff - */ - -extern char em_mnem[]; /* The mnemonics of the EM instructions. */ - -STATIC showinstr(lnp) line_p lnp; { - - /* Makes the instruction in `lnp' human readable. Only lines that - * can occur in expressions that are going to be eliminated are - * properly handled. - */ - if (lnp == 0) return; - if (INSTR(lnp) < sp_fmnem || INSTR(lnp) > sp_lmnem) { - printf("\t*** ?\n"); - return; - } - - printf("\t%s", &em_mnem[4 * (INSTR(lnp)-sp_fmnem)]); - switch (TYPE(lnp)) { - case OPNO: - break; - case OPSHORT: - printf(" %d", SHORT(lnp)); break; - case OPOBJECT: - printf(" %d", OBJ(lnp)->o_id); break; - case OPOFFSET: - printf(" %D", OFFSET(lnp)); break; - default: - printf(" ?"); break; - } - printf("\n"); -} /* showinstr */ - - -STATIC print_list(list,b1,b2,p) - line_p list; - bblock_p b1,b2; - proc_p p; -{ - line_p l; - printf("block %d and %d of proc %d:\n",b1->b_id,b2->b_id,p->p_id); - for (l = list; l != 0; l = l->l_next) { - showinstr(l); - } -} diff --git a/util/ego/cs/Makefile b/util/ego/cs/Makefile deleted file mode 100644 index 36b841ecf..000000000 --- a/util/ego/cs/Makefile +++ /dev/null @@ -1,178 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -cs.c cs_alloc.c cs_aux.c cs_avail.c cs_debug.c cs_elim.c \ -cs_entity.c cs_kill.c cs_partit.c cs_profit.c cs_getent.c \ -cs_stack.c cs_vnm.c - -OFILES=\ -cs.o cs_alloc.o cs_aux.o cs_avail.o cs_debug.o cs_elim.o \ -cs_entity.o cs_kill.o cs_partit.o cs_profit.o cs_getent.o \ -cs_stack.o cs_vnm.o - -HFILES=\ -cs.h cs_alloc.h cs_aux.h cs_avail.h cs_debug.h cs_elim.h \ -cs_entity.h cs_kill.h cs_partit.h cs_profit.h cs_getent.h \ -cs_stack.h cs_vnm.h - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/get.o $(SHR)/put.o $(SHR)/alloc.o $(SHR)/global.o $(SHR)/debug.o\ -$(SHR)/files.o $(SHR)/map.o $(SHR)/lset.o $(SHR)/cset.o $(SHR)/aux.o\ -$(SHR)/go.o - -SHARE_MFILES=\ -$(SHR)/get.m $(SHR)/put.m $(SHR)/alloc.m $(SHR)/global.m $(SHR)/debug.m\ -$(SHR)/files.m $(SHR)/map.m $(SHR)/lset.m $(SHR)/cset.m $(SHR)/aux.m\ -$(SHR)/go.m - -cs: $(OFILES) - $(CC) -o cs $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -cs_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o cs -.c $(LDFLAGS) cs.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO -cs.o: ../share/debug.h -cs.o: ../share/go.h -cs.o: ../share/types.h -cs.o: cs.h -cs.o: cs_aux.h -cs.o: cs_avail.h -cs.o: cs_debug.h -cs.o: cs_elim.h -cs.o: cs_entity.h -cs.o: cs_profit.h -cs.o: cs_stack.h -cs.o: cs_vnm.h -cs_alloc.o: ../share/alloc.h -cs_alloc.o: ../share/types.h -cs_alloc.o: cs.h -cs_aux.o: ../share/aux.h -cs_aux.o: ../share/debug.h -cs_aux.o: ../share/global.h -cs_aux.o: ../share/lset.h -cs_aux.o: ../share/types.h -cs_aux.o: cs.h -cs_aux.o: cs_entity.h -cs_avail.o: ../../../h/em_mnem.h -cs_avail.o: ../share/aux.h -cs_avail.o: ../share/debug.h -cs_avail.o: ../share/global.h -cs_avail.o: ../share/lset.h -cs_avail.o: ../share/types.h -cs_avail.o: cs.h -cs_avail.o: cs_alloc.h -cs_avail.o: cs_aux.h -cs_avail.o: cs_getent.h -cs_debug.o: ../../../h/em_spec.h -cs_debug.o: ../share/debug.h -cs_debug.o: ../share/lset.h -cs_debug.o: ../share/types.h -cs_debug.o: cs.h -cs_debug.o: cs_aux.h -cs_debug.o: cs_avail.h -cs_debug.o: cs_entity.h -cs_elim.o: ../../../h/em_mnem.h -cs_elim.o: ../../../h/em_reg.h -cs_elim.o: ../share/alloc.h -cs_elim.o: ../share/aux.h -cs_elim.o: ../share/debug.h -cs_elim.o: ../share/global.h -cs_elim.o: ../share/lset.h -cs_elim.o: ../share/types.h -cs_elim.o: cs.h -cs_elim.o: cs_alloc.h -cs_elim.o: cs_aux.h -cs_elim.o: cs_avail.h -cs_elim.o: cs_debug.h -cs_elim.o: cs_partit.h -cs_elim.o: cs_profit.h -cs_entity.o: ../share/debug.h -cs_entity.o: ../share/global.h -cs_entity.o: ../share/lset.h -cs_entity.o: ../share/types.h -cs_entity.o: cs.h -cs_entity.o: cs_aux.h -cs_getent.o: ../../../h/em_mnem.h -cs_getent.o: ../share/aux.h -cs_getent.o: ../share/debug.h -cs_getent.o: ../share/global.h -cs_getent.o: ../share/types.h -cs_getent.o: cs.h -cs_getent.o: cs_aux.h -cs_getent.o: cs_entity.h -cs_getent.o: cs_stack.h -cs_kill.o: ../../../h/em_mnem.h -cs_kill.o: ../share/aux.h -cs_kill.o: ../share/cset.h -cs_kill.o: ../share/debug.h -cs_kill.o: ../share/global.h -cs_kill.o: ../share/lset.h -cs_kill.o: ../share/types.h -cs_kill.o: cs.h -cs_kill.o: cs_aux.h -cs_kill.o: cs_avail.h -cs_kill.o: cs_debug.h -cs_kill.o: cs_entity.h -cs_partit.o: ../../../h/em_mnem.h -cs_partit.o: ../../../h/em_pseu.h -cs_partit.o: ../../../h/em_reg.h -cs_partit.o: ../../../h/em_spec.h -cs_partit.o: ../share/aux.h -cs_partit.o: ../share/debug.h -cs_partit.o: ../share/global.h -cs_partit.o: ../share/types.h -cs_partit.o: cs.h -cs_partit.o: cs_stack.h -cs_profit.o: ../../../h/em_mnem.h -cs_profit.o: ../../../h/em_spec.h -cs_profit.o: ../share/aux.h -cs_profit.o: ../share/cset.h -cs_profit.o: ../share/debug.h -cs_profit.o: ../share/global.h -cs_profit.o: ../share/lset.h -cs_profit.o: ../share/types.h -cs_profit.o: cs.h -cs_profit.o: cs_aux.h -cs_profit.o: cs_avail.h -cs_profit.o: cs_partit.h -cs_stack.o: ../share/aux.h -cs_stack.o: ../share/debug.h -cs_stack.o: ../share/global.h -cs_stack.o: ../share/types.h -cs_stack.o: cs.h -cs_stack.o: cs_aux.h -cs_valno.o: ../share/debug.h -cs_valno.o: ../share/types.h -cs_valno.o: cs.h -cs_vnm.o: ../../../h/em_mnem.h -cs_vnm.o: ../share/aux.h -cs_vnm.o: ../share/debug.h -cs_vnm.o: ../share/global.h -cs_vnm.o: ../share/types.h -cs_vnm.o: cs.h -cs_vnm.o: cs_alloc.h -cs_vnm.o: cs_aux.h -cs_vnm.o: cs_avail.h -cs_vnm.o: cs_entity.h -cs_vnm.o: cs_getent.h -cs_vnm.o: cs_kill.h -cs_vnm.o: cs_partit.h -cs_vnm.o: cs_stack.h diff --git a/util/ego/cs/cs.c b/util/ego/cs/cs.c deleted file mode 100644 index bc599246e..000000000 --- a/util/ego/cs/cs.c +++ /dev/null @@ -1,78 +0,0 @@ - -/* C O M M O N S U B E X P R E S S I O N E L I M I N A T I O N */ - - -#include -#include "../share/types.h" -#include "../share/lset.h" -#include "../share/debug.h" -#include "../share/go.h" -#include "cs.h" -#include "cs_aux.h" -#include "cs_avail.h" -#include "cs_debug.h" -#include "cs_elim.h" -#include "cs_entity.h" -#include "cs_profit.h" -#include "cs_stack.h" -#include "cs_vnm.h" - -int Scs; /* Number of optimizations found. */ - -STATIC cs_clear() -{ - clr_avails(); - clr_entities(); - clr_stack(); - - start_valnum(); -} - -STATIC cs_optimize(p) - proc_p p; -{ - /* Optimize all basic blocks of one procedure. */ - - register bblock_p rbp, bdone; - - avails = (avail_p) 0; - entities = Lempty_set(); - cs_clear(); - - rbp = p->p_start; - - while (rbp != (bblock_p) 0) { - /* First we build a list of common expressions with the - * value numbering algorithm. We take blocks in textual order - * as long as the next block can only be reached through the - * block we have just done. Note that if a block is preceded - * by itself, the number of predecessors is greater than 1, - * but the previous block can still be its immediate dominator. - */ - do { vnm(rbp); bdone = rbp; - OUTTRACE("basic block %d processed", bdone->b_id); - rbp = rbp->b_next; - } while (rbp != (bblock_p) 0 && rbp->b_idom == bdone && - Lnrelems(rbp->b_pred) == 1 - ); - OUTTRACE("value numbering completed", 0); - OUTAVAILS(); OUTENTITIES(); - - /* Now we put out the instructions without common - * subexpressions but with the use of temporaries, - * which will be local variables of procedure p. - */ - eliminate(p); - cs_clear(); - } -} - -main(argc, argv) - int argc; - char *argv[]; -{ - Scs = 0; - go(argc, argv, no_action, cs_optimize, cs_machinit, no_action); - report("Duplicate expressions eliminated", Scs); - exit(0); -} diff --git a/util/ego/cs/cs.h b/util/ego/cs/cs.h deleted file mode 100644 index b53f33081..000000000 --- a/util/ego/cs/cs.h +++ /dev/null @@ -1,123 +0,0 @@ -typedef short valnum; -typedef struct entity *entity_p; -typedef struct avail *avail_p; -typedef struct token *token_p; -typedef struct occur *occur_p; - -struct token { - valnum tk_vn; - offset tk_size; - line_p tk_lfirst; /* Textually first instruction, involved - * in pushing this token. - */ -}; - - /* We distinguish these entities. */ -#define ENCONST 0 -#define ENLOCAL 1 -#define ENEXTERNAL 2 -#define ENINDIR 3 -#define ENOFFSETTED 4 -#define ENALOCAL 5 -#define ENAEXTERNAL 6 -#define ENAOFFSETTED 7 -#define ENALOCBASE 8 -#define ENAARGBASE 9 -#define ENPROC 10 -#define ENFZER 11 -#define ENARRELEM 12 -#define ENLOCBASE 13 -#define ENHEAPPTR 14 -#define ENIGNMASK 15 - -struct entity { - valnum en_vn; - bool en_static; - byte en_kind; /* ENLOCAL, ENEXTERNAL, etc. */ - offset en_size; - union { - offset en__val; /* ENCONST. */ - offset en__loc; /* ENLOCAL, ENALOCAL. */ - obj_p en__ext; /* ENEXTERNAL, ENAEXTERNAL. */ - valnum en__ind; /* ENINDIR. */ - struct { - valnum en__base; - offset en__off; - } en_offs; /* ENOFFSETTED, ENAOFFSETTED. */ - offset en__levels; /* ENALOCBASE, ENAARGBASE. */ - proc_p en__pro; /* ENPROC. */ - struct { - valnum en__arbase; - valnum en__index; - valnum en__adesc; - } en_arr; /* ENARRELEM. */ - } en_inf; -}; - - /* Macros to increase ease of use. */ -#define en_val en_inf.en__val -#define en_loc en_inf.en__loc -#define en_ext en_inf.en__ext -#define en_ind en_inf.en__ind -#define en_base en_inf.en_offs.en__base -#define en_off en_inf.en_offs.en__off -#define en_levels en_inf.en__levels -#define en_pro en_inf.en__pro -#define en_arbase en_inf.en_arr.en__arbase -#define en_index en_inf.en_arr.en__index -#define en_adesc en_inf.en_arr.en__adesc - -struct occur { - line_p oc_lfirst; /* First instruction of expression. */ - line_p oc_llast; /* Last one. */ - bblock_p oc_belongs; /* Basic block it belongs to. */ -}; - - /* We distinguish these groups of instructions. */ -#define SIMPLE_LOAD 0 -#define EXPENSIVE_LOAD 1 -#define LOAD_ARRAY 2 -#define STORE_DIRECT 3 -#define STORE_INDIR 4 -#define STORE_ARRAY 5 -#define UNAIR_OP 6 -#define BINAIR_OP 7 -#define TERNAIR_OP 8 -#define KILL_ENTITY 9 -#define SIDE_EFFECTS 10 -#define FIDDLE_STACK 11 -#define IGNORE 12 -#define HOPELESS 13 -#define BBLOCK_END 14 - -struct avail { - avail_p av_before; /* Ptr to earlier discovered expressions. */ - byte av_instr; /* Operator instruction. */ - offset av_size; - line_p av_found; /* Line where expression is first found. */ - lset av_occurs; /* Set of recurrences of expression. */ - entity_p av_saveloc; /* Local where result is put in. */ - valnum av_result; - union { - valnum av__operand; /* EXPENSIVE_LOAD, UNAIR_OP. */ - struct { - valnum av__oleft; - valnum av__oright; - } av_2; /* BINAIR_OP. */ - struct { - valnum av__ofirst; - valnum av__osecond; - valnum av__othird; - } av_3; /* TERNAIR_OP. */ - } av_o; -}; - - /* Macros to increase ease of use. */ -#define av_operand av_o.av__operand -#define av_oleft av_o.av_2.av__oleft -#define av_oright av_o.av_2.av__oright -#define av_ofirst av_o.av_3.av__ofirst -#define av_osecond av_o.av_3.av__osecond -#define av_othird av_o.av_3.av__othird - -extern int Scs; /* Number of optimizations found. */ diff --git a/util/ego/cs/cs_alloc.c b/util/ego/cs/cs_alloc.c deleted file mode 100644 index e6cc18fea..000000000 --- a/util/ego/cs/cs_alloc.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "../share/types.h" -#include "../share/alloc.h" -#include "cs.h" - -occur_p newoccur(l1, l2, b) - line_p l1, l2; - bblock_p b; -{ - /* Allocate a new struct occur and initialize it. */ - - register occur_p rop; - - rop = (occur_p) newcore(sizeof(struct occur)); - rop->oc_lfirst = l1; rop->oc_llast = l2; rop->oc_belongs = b; - return rop; -} - -oldoccur(ocp) - occur_p ocp; -{ - oldcore((short *) ocp, sizeof(struct occur)); -} - -avail_p newavail() -{ - return (avail_p) newcore(sizeof(struct avail)); -} - -oldavail(avp) - avail_p avp; -{ - oldcore((short *) avp, sizeof(struct avail)); -} - -entity_p newentity() -{ - return (entity_p) newcore(sizeof(struct entity)); -} - -oldentity(enp) - entity_p enp; -{ - oldcore((short *) enp, sizeof(struct entity)); -} diff --git a/util/ego/cs/cs_alloc.h b/util/ego/cs/cs_alloc.h deleted file mode 100644 index 7390e9ae6..000000000 --- a/util/ego/cs/cs_alloc.h +++ /dev/null @@ -1,24 +0,0 @@ -extern occur_p newoccur(); /* (line_p l1, l2; bblock_p b) - * Returns a pointer to a new struct occur - * and initializes it. - */ - -extern oldoccur(); /* (occur_p ocp) - * Release the struct occur ocp points to. - */ - -extern avail_p newavail(); /* () - * Return a pointer to a new struct avail. - */ - -extern oldavail(); /* (avail_p avp) - * Release the struct avail avp points to. - */ - -extern entity_p newentity(); /* () - * Return a pointer to a new struct entity. - */ - -extern oldentity(); /* (entity_p enp) - * Release the struct entity enp points to. - */ diff --git a/util/ego/cs/cs_aux.c b/util/ego/cs/cs_aux.c deleted file mode 100644 index 296e5b0c0..000000000 --- a/util/ego/cs/cs_aux.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/aux.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "cs.h" -#include "cs_entity.h" - -offset array_elemsize(vn) - valnum vn; -{ - /* Vn is the valuenumber of an entity that points to - * an array-descriptor. The third element of this descriptor holds - * the size of the array-elements. - * IF we can find this entity, AND IF we can find the descriptor AND IF - * this descriptor is located in ROM, then we return the size. - */ - entity_p enp; - - enp = find_entity(vn); - - if (enp == (entity_p) 0) - return UNKNOWN_SIZE; - - if (enp->en_kind != ENAEXTERNAL) - return UNKNOWN_SIZE; - - if (enp->en_ext->o_dblock->d_pseudo != DROM) - return UNKNOWN_SIZE; - - return aoff(enp->en_ext->o_dblock->d_values, 2); -} - -occur_p occ_elem(i) - Lindex i; -{ - return (occur_p) Lelem(i); -} - -entity_p en_elem(i) - Lindex i; -{ - return (entity_p) Lelem(i); -} - -/* The value numbers associated with each distinct value - * start at 1. - */ - -STATIC valnum val_no; - -valnum newvalnum() -{ - /* Return a completely new value number. */ - - return ++val_no; -} - -start_valnum() -{ - /* Restart value numbering. */ - - val_no = 0; -} diff --git a/util/ego/cs/cs_aux.h b/util/ego/cs/cs_aux.h deleted file mode 100644 index 09be0d270..000000000 --- a/util/ego/cs/cs_aux.h +++ /dev/null @@ -1,25 +0,0 @@ -extern offset array_elemsize(); /* (valnum vm) - * Returns the size of array-elements, - * if vn is the valuenumber of the - * address of an array-descriptor. - */ - -extern occur_p occ_elem(); /* (Lindex i) - * Returns a pointer to the occurrence - * of which i is an index in a set. - */ - -extern entity_p en_elem(); /* (Lindex i) - * Returns a pointer to the entity - * of which i is an index in a set. - */ - -extern valnum newvalnum(); /* () - * Returns a completely new - * value number. - */ - -extern start_valnum(); /* () - * Restart value numbering. - */ - diff --git a/util/ego/cs/cs_avail.c b/util/ego/cs/cs_avail.c deleted file mode 100644 index 930b592f5..000000000 --- a/util/ego/cs/cs_avail.c +++ /dev/null @@ -1,203 +0,0 @@ -/* M O D U L E F O R A C C E S S S I N G T H E L I S T - * - * O F A V A I L A B L E E X P R E S S I O N S - */ - -#include "../../../h/em_mnem.h" -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/aux.h" -#include "../share/lset.h" -#include "../share/global.h" -#include "cs.h" -#include "cs_aux.h" -#include "cs_debug.h" -#include "cs_alloc.h" -#include "cs_getent.h" - -avail_p avails; /* The list of available expressions. */ - -STATIC bool commutative(instr) - int instr; -{ - /* Is instr a commutative operator? */ - - switch (instr) { - case op_adf: case op_adi: case op_adu: case op_and: - case op_cms: case op_ior: case op_mlf: case op_mli: - case op_mlu: - return TRUE; - default: - return FALSE; - } -} - -STATIC bool same_avail(kind, avp1, avp2) - byte kind; - avail_p avp1, avp2; -{ - /* Two expressions are the same if they have the same operator, - * the same size, and their operand(s) have the same value. - * Only if the operator is commutative, the order of the operands - * does not matter. - */ - if (avp1->av_instr != avp2->av_instr) return FALSE; - if (avp1->av_size != avp2->av_size) return FALSE; - - switch (kind) { - default: - assert(FALSE); - break; - case EXPENSIVE_LOAD: - case UNAIR_OP: - return avp1->av_operand == avp2->av_operand; - case BINAIR_OP: - if (commutative(avp1->av_instr & BMASK)) - return avp1->av_oleft == avp2->av_oleft && - avp1->av_oright == avp2->av_oright - || - avp1->av_oleft == avp2->av_oright && - avp1->av_oright == avp2->av_oleft - ; - else - return avp1->av_oleft == avp2->av_oleft && - avp1->av_oright == avp2->av_oright; - case TERNAIR_OP: - return avp1->av_ofirst == avp2->av_ofirst && - avp1->av_osecond == avp2->av_osecond && - avp1->av_othird == avp2->av_othird; - } - /* NOTREACHED */ -} - -STATIC check_local(avp) - avail_p avp; -{ - /* Check if the local in which the result of avp was stored, - * still holds this result. Update if not. - */ - if (avp->av_saveloc == (entity_p) 0) return; /* Nothing to check. */ - - if (avp->av_saveloc->en_vn != avp->av_result) { - OUTTRACE("save local changed value", 0); - avp->av_saveloc = (entity_p) 0; - } -} - -STATIC entity_p result_local(size, l) - offset size; - line_p l; -{ - /* If the result of an expression of size bytes is stored into a - * local for which a registermessage was generated, return a pointer - * to this local. - */ - line_p dummy; - entity_p enp; - - if (l == (line_p) 0) - return (entity_p) 0; - - if (INSTR(l)==op_stl && size==ws || INSTR(l)==op_sdl && size==2*ws) { - enp = getentity(l, &dummy); - if (is_regvar(enp->en_loc)) { - OUTTRACE("save local found, %D(LB)", enp->en_loc); - return enp; - } - } - - return (entity_p) 0; -} - -STATIC copy_avail(kind, src, dst) - int kind; - avail_p src, dst; -{ - /* Copy some attributes from src to dst. */ - - dst->av_instr = src->av_instr; - dst->av_size = src->av_size; - - switch (kind) { - default: - assert(FALSE); - break; - case EXPENSIVE_LOAD: - case UNAIR_OP: - dst->av_operand = src->av_operand; - break; - case BINAIR_OP: - dst->av_oleft = src->av_oleft; - dst->av_oright = src->av_oright; - break; - case TERNAIR_OP: - dst->av_ofirst = src->av_ofirst; - dst->av_osecond = src->av_osecond; - dst->av_othird = src->av_othird; - break; - } -} - -avail_p av_enter(avp, ocp, kind) - avail_p avp; - occur_p ocp; - int kind; -{ - /* Put the available expression avp in the list, - * if it is not already there. - * Add ocp to the set of occurrences of this expression. - */ - register avail_p ravp; - line_p last = ocp->oc_llast; - - for (ravp = avails; ravp != (avail_p) 0; ravp = ravp->av_before) { - if (same_avail(kind, ravp, avp)) { /* It was there. */ - Ladd(ocp, &ravp->av_occurs); - /* Can we still use the local in which - * the result was stored? - */ - check_local(ravp); - return ravp; - } - } - /* A new available axpression. */ - ravp = newavail(); - - /* Remember local, if any, that holds result. */ - if (avp->av_instr != (byte) INSTR(last)) { - /* Only possible when instr is the implicit AAR in - * a LAR or SAR. - */ - ravp->av_saveloc = (entity_p) 0; - } else { - ravp->av_saveloc = result_local(avp->av_size, last->l_next); - } - ravp->av_found = last; - ravp->av_result = kind == EXPENSIVE_LOAD? avp->av_operand: newvalnum(); - copy_avail(kind, avp, ravp); - oldoccur(ocp); - ravp->av_before = avails; - avails = ravp; - return ravp; -} - -clr_avails() -{ - /* Throw away the information about the available expressions. */ - - register avail_p ravp, next; - register Lindex i; - register lset s; - - for (ravp = avails; ravp != (avail_p) 0; ravp = next) { - next = ravp->av_before; - - s = ravp->av_occurs; - for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i, s)) { - oldoccur(occ_elem(i)); - } - Ldeleteset(s); - oldavail(ravp); - } - avails = (avail_p) 0; -} diff --git a/util/ego/cs/cs_avail.h b/util/ego/cs/cs_avail.h deleted file mode 100644 index 2275df8c3..000000000 --- a/util/ego/cs/cs_avail.h +++ /dev/null @@ -1,18 +0,0 @@ -extern avail_p avails; /* The set of available expressions. */ - -extern avail_p av_enter(); /* (avail_p avp, occur_p ocp, byte kind) - * Puts the available expression in avp - * in the list of available expressions, - * if it is not already there. Add ocp to set of - * occurrences of this expression. - * If we have a new expression, we test whether - * the result is saved. When this expression - * recurs,we test if we can still use the - * variable into which it was saved. - * (Kind is the kind of the expression.) - * Returns a pointer into the list. - */ - -extern clr_avails(); /* Release all space occupied by the old list - * of available expressions. - */ diff --git a/util/ego/cs/cs_debug.c b/util/ego/cs/cs_debug.c deleted file mode 100644 index 0d4cdbdfc..000000000 --- a/util/ego/cs/cs_debug.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include "../../../h/em_spec.h" -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/lset.h" -#include "cs.h" -#include "cs_aux.h" -#include "cs_avail.h" -#include "cs_entity.h" - -#ifdef VERBOSE - -extern char em_mnem[]; /* The mnemonics of the EM instructions. */ - -STATIC showinstr(lnp) - line_p lnp; -{ - /* Makes the instruction in `lnp' human readable. Only lines that - * can occur in expressions that are going to be eliminated are - * properly handled. - */ - if (INSTR(lnp) < sp_fmnem && INSTR(lnp) > sp_lmnem) { - fprintf(stderr,"*** ?\n"); - return; - } - - fprintf(stderr,"%s", &em_mnem[4 * (INSTR(lnp)-sp_fmnem)]); - switch (TYPE(lnp)) { - case OPNO: - break; - case OPSHORT: - fprintf(stderr," %d", SHORT(lnp)); - break; - case OPOBJECT: - fprintf(stderr," %d", OBJ(lnp)->o_id); - break; - case OPOFFSET: - fprintf(stderr," %D", OFFSET(lnp)); - break; - default: - fprintf(stderr," ?"); - break; - } - fprintf(stderr,"\n"); -} - -SHOWOCCUR(ocp) - occur_p ocp; -{ - /* Shows all instructions in an occurrence. */ - - register line_p lnp, next; - - if (verbose_flag) { - for (lnp = ocp->oc_lfirst; lnp != (line_p) 0; lnp = next) { - next = lnp == ocp->oc_llast ? (line_p) 0 : lnp->l_next; - - showinstr(lnp); - } - } -} - -#endif - -#ifdef TRACE - -SHOWAVAIL(avp) - avail_p avp; -{ - /* Shows an available expression. */ - showinstr(avp->av_found); - fprintf(stderr,"result %d,", avp->av_result); - fprintf(stderr,"occurred %d times\n", Lnrelems(avp->av_occurs) + 1); - -} - -OUTAVAILS() -{ - register avail_p ravp; - - fprintf(stderr,"AVAILABLE EXPRESSIONS\n"); - - for (ravp = avails; ravp != (avail_p) 0; ravp = ravp->av_before) { - SHOWAVAIL(ravp); - fprintf(stderr,"\n"); - } -} - -STATIC char *enkinds[] = { - "constant", - "local", - "external", - "indirect", - "offsetted", - "address of local", - "address of external", - "address of offsetted", - "address of local base", - "address of argument base", - "procedure", - "floating zero", - "array element", - "local base", - "heap pointer", - "ignore mask" -}; - -OUTENTITIES() -{ - register Lindex i; - - fprintf(stderr,"ENTITIES\n"); - for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) { - register entity_p rep = en_elem(i); - - fprintf(stderr,"%s,", enkinds[rep->en_kind]); - fprintf(stderr,"size %D,", rep->en_size); - fprintf(stderr,"valno %d,", rep->en_vn); - switch (rep->en_kind) { - case ENCONST: - fprintf(stderr,"$%D\n", rep->en_val); - break; - case ENLOCAL: - case ENALOCAL: - fprintf(stderr,"%D(LB)\n", rep->en_loc); - break; - case ENINDIR: - fprintf(stderr,"*%d\n", rep->en_ind); - break; - case ENOFFSETTED: - case ENAOFFSETTED: - fprintf(stderr,"%D(%d)\n", rep->en_off, rep->en_base); - break; - case ENALOCBASE: - case ENAARGBASE: - fprintf(stderr,"%D levels\n", rep->en_levels); - break; - case ENARRELEM: - fprintf(stderr,"%d[%d], ",rep->en_arbase,rep->en_index); - fprintf(stderr,"rom at %d\n", rep->en_adesc); - break; - } - fprintf(stderr,"\n"); - } -} - -/* XXX */ -OUTTRACE(s, n) - char *s; -{ - fprintf(stderr,"trace: "); - fprintf(stderr,s, n); - fprintf(stderr,"\n"); -} - -#endif TRACE diff --git a/util/ego/cs/cs_debug.h b/util/ego/cs/cs_debug.h deleted file mode 100644 index 194aa62dd..000000000 --- a/util/ego/cs/cs_debug.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifdef VERBOSE - -extern SHOWOCCUR(); /* (occur_p ocp) - * Shows all lines in an occurrence. - */ - -#else - -#define SHOWOCCUR(x) - -#endif - -#ifdef TRACE - -extern OUTAVAILS(); /* () - * Prints all available expressions. - */ - -extern OUTENTITIES(); /* () - * Prints all entities. - */ - -extern SHOWAVAIL(); /* (avail_p avp) - * Shows an available expression. - */ - -#else TRACE - -#define OUTAVAILS() -#define OUTENTITIES() -#define SHOWAVAIL(x) - -#endif TRACE diff --git a/util/ego/cs/cs_elim.c b/util/ego/cs/cs_elim.c deleted file mode 100644 index 33f295fe2..000000000 --- a/util/ego/cs/cs_elim.c +++ /dev/null @@ -1,283 +0,0 @@ -#include "../../../h/em_reg.h" -#include "../../../h/em_mnem.h" -#include "../share/types.h" -#include "../share/alloc.h" -#include "../share/lset.h" -#include "../share/aux.h" -#include "../share/global.h" -#include "../share/debug.h" -#include "cs.h" -#include "cs_avail.h" -#include "cs_alloc.h" -#include "cs_aux.h" -#include "cs_debug.h" -#include "cs_profit.h" -#include "cs_partit.h" -#include "cs_debug.h" - -STATIC dlink(l1, l2) - line_p l1, l2; -{ - /* Doubly link the lines in l1 and l2. */ - - if (l1 != (line_p) 0) - l1->l_next = l2; - if (l2 != (line_p) 0) - l2->l_prev = l1; -} - -STATIC remove_lines(first, last) - line_p first, last; -{ - /* Throw away the lines between and including first and last. - * Don't worry about any pointers; the (must) have been taken care of. - */ - register line_p lnp, next; - - last->l_next = (line_p) 0; /* Delimit the list. */ - for (lnp = first; lnp != (line_p) 0; lnp = next) { - next = lnp->l_next; - oldline(lnp); - } -} - -STATIC bool contained(ocp1, ocp2) - occur_p ocp1, ocp2; -{ - /* Determine whether ocp1 is contained within ocp2. */ - - register line_p lnp, next; - - for (lnp = ocp2->oc_lfirst; lnp != (line_p) 0; lnp = next) { - next = lnp != ocp2->oc_llast ? lnp->l_next : (line_p) 0; - - if (lnp == ocp1->oc_llast) return TRUE; - } - return FALSE; -} - -STATIC delete(ocp, start) - occur_p ocp; - avail_p start; -{ - /* Delete all occurrences that are contained within ocp. - * They must have been entered in the list before start: - * if an expression is contained with an other, its operator line - * appears before the operator line of the other because EM-expressions - * are postfix. - */ - register avail_p ravp; - register Lindex i, next; - - for (ravp = start; ravp != (avail_p) 0; ravp = ravp->av_before) { - for (i = Lfirst(ravp->av_occurs); i != (Lindex) 0; i = next) { - next = Lnext(i, ravp->av_occurs); - - if (contained(occ_elem(i), ocp)) { - OUTTRACE("delete contained occurrence", 0); -# ifdef TRACE - SHOWOCCUR(occ_elem(i)); -# endif - oldoccur(occ_elem(i)); - Lremove(Lelem(i), &ravp->av_occurs); - } - } - } -} - -STATIC complete_aar(lnp, instr, descr_vn) - line_p lnp; - int instr; - valnum descr_vn; -{ - /* Lnp is an instruction that loads the address of an array-element. - * Instr tells us what effect we should achieve; load (instr is op_lar) - * or store (instr is op_sar) this array-element. Descr_vn is the - * valuenumber of the address of the descriptor of this array. - * We append a loi or sti of the correct number of bytes. - */ - register line_p lindir; - - lindir = int_line(array_elemsize(descr_vn)); - lindir->l_instr = instr == op_lar ? op_loi : op_sti; - dlink(lindir, lnp->l_next); - dlink(lnp, lindir); -} - -STATIC replace(ocp, tmp, avp) - occur_p ocp; - offset tmp; - avail_p avp; -{ - /* Replace the lines in the occurrence in ocp by a load of the - * temporary with offset tmp. - */ - register line_p lol, first, last; - - assert(avp->av_size == ws || avp->av_size == 2*ws); - - first = ocp->oc_lfirst; last = ocp->oc_llast; - - lol = int_line(tmp); - lol->l_instr = avp->av_size == ws ? op_lol : op_ldl; - dlink(lol, last->l_next); - - if (first->l_prev == (line_p) 0) ocp->oc_belongs->b_start = lol; - dlink(first->l_prev, lol); - - if (avp->av_instr == (byte) op_aar) { - /* There may actually be a LAR or a SAR instruction; in that - * case we have to complete the array-instruction. - */ - register int instr = INSTR(last); - - if (instr != op_aar) complete_aar(lol, instr, avp->av_othird); - } - - /* Throw away the by now useless lines. */ - remove_lines(first, last); -} - -STATIC append(avp, tmp) - avail_p avp; - offset tmp; -{ - /* Avp->av_found points to a line with an operator in it. This - * routine emits a sequence of instructions that saves the result - * in a local with offset tmp. In most cases we just append - * avp->av_found with stl/sdl tmp and lol/ldl tmp depending on - * avp->av_size. If however the operator is an aar contained - * within a lar or sar, we must first generate the aar. - */ - register line_p stl, lol; - - assert(avp->av_size == ws || avp->av_size == 2*ws); - - stl = int_line(tmp); - stl->l_instr = avp->av_size == ws ? op_stl : op_sdl; - lol = int_line(tmp); - lol->l_instr = avp->av_size == ws ? op_lol : op_ldl; - - dlink(lol, avp->av_found->l_next); - dlink(stl, lol); - dlink(avp->av_found, stl); - - if (avp->av_instr == (byte) op_aar) { - register int instr = INSTR(avp->av_found); - - if (instr != op_aar) { - complete_aar(lol, instr, avp->av_othird); - avp->av_found->l_instr = op_aar; - } - } -} - -STATIC set_replace(avp, tmp) - avail_p avp; - offset tmp; -{ - /* Avp->av_occurs is now a set of occurrences, each of which will be - * replaced by a reference to a local. - * Each time we eliminate an expression, we delete from our - * list those expressions that are physically contained in them, - * because we cannot eliminate them again. - */ - register Lindex i; - register lset s = avp->av_occurs; - - for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i, s)) { - OUTVERBOSE("eliminate duplicate", 0); - SHOWOCCUR(occ_elem(i)); - Scs++; - delete(occ_elem(i), avp->av_before); - replace(occ_elem(i), tmp, avp); - } -} - -STATIC int reg_score(enp) - entity_p enp; -{ - /* Enp is a local that will go into a register. - * We return its score upto now. - */ - assert(is_regvar(enp->en_loc)); - return regv_arg(enp->en_loc, 4); -} - -STATIC line_p gen_mesreg(off, avp, pp) - offset off; - avail_p avp; - proc_p pp; -{ - /* Generate a register message for the local that will hold the - * result of the expression in avp, at the appropriate place in - * the procedure in pp. - */ - register line_p reg; - - reg = reg_mes(off, (short) avp->av_size, regtype(avp->av_instr), 0); - appnd_line(reg, pp->p_start->b_start); - - return reg; -} - -STATIC change_score(mes, score) - line_p mes; - int score; -{ - /* Change the score in the register message in mes to score. */ - - register arg_p ap = ARG(mes); - - ap = ap->a_next; /* Offset. */ - ap = ap->a_next; /* Size. */ - ap = ap->a_next; /* Type. */ - ap = ap->a_next; /* Score. */ - - ap->a_a.a_offset = score; -} - -eliminate(pp) - proc_p pp; -{ - /* Eliminate costly common subexpressions within procedure pp. - * We scan the available expressions in - with respect to time found - - * reverse order, to find largest first, e.g. `A + B + C' before - * `A + B'. - * We do not eliminate an expression when the size - * is not one of ws or 2*ws, because then we cannot use lol or ldl. - * Code is appended to the first occurrence of the expression - * to store the result into a local. - */ - register avail_p ravp; - register int score; - register offset tmp; - register line_p mes; - - for (ravp = avails; ravp != (avail_p) 0; ravp = ravp->av_before) { - - if (ravp->av_size != ws && ravp->av_size != 2*ws) continue; - - if (ravp->av_saveloc == (entity_p) 0) { - /* We save it ourselves. */ - score = 2; /* Stl and lol. */ - } else { - score = reg_score(ravp->av_saveloc); - } - if (desirable(ravp)) { - score += Lnrelems(ravp->av_occurs); - OUTTRACE("temporary local score %d", score); - if (ravp->av_saveloc != (entity_p) 0) { - tmp = ravp->av_saveloc->en_loc; - mes = find_mesreg(tmp); - OUTVERBOSE("re-using %D(LB)", tmp); - } else { - tmp = tmplocal(pp, ravp->av_size); - mes = gen_mesreg(tmp, ravp, pp); - append(ravp, tmp); - } - change_score(mes, score); - set_replace(ravp, tmp); - } - } -} diff --git a/util/ego/cs/cs_elim.h b/util/ego/cs/cs_elim.h deleted file mode 100644 index 5d108e5db..000000000 --- a/util/ego/cs/cs_elim.h +++ /dev/null @@ -1,5 +0,0 @@ -extern eliminate(); /* (proc_p pp) - * Eliminate some of the recurrences of expressions - * that were found by the valuenumbering - * algorithm. - */ diff --git a/util/ego/cs/cs_entity.c b/util/ego/cs/cs_entity.c deleted file mode 100644 index f3e95ca9b..000000000 --- a/util/ego/cs/cs_entity.c +++ /dev/null @@ -1,142 +0,0 @@ -/* F U N C T I O N S F O R A C C E S S I N G T H E S E T - * - * O F E N T I T I E S - */ - -#include "../share/types.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/debug.h" -#include "cs.h" -#include "cs_alloc.h" -#include "cs_aux.h" - -lset entities; /* Our pseudo symbol-table. */ - -entity_p find_entity(vn) - valnum vn; -{ - /* Try to find the entity with valuenumber vn. */ - - register Lindex i; - - for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) { - if (en_elem(i)->en_vn == vn) - return en_elem(i); - } - - return (entity_p) 0; -} - -STATIC bool same_entity(enp1, enp2) - entity_p enp1, enp2; -{ - if (enp1->en_kind != enp2->en_kind) return FALSE; - if (enp1->en_size != enp2->en_size) return FALSE; - if (enp1->en_size == UNKNOWN_SIZE) return FALSE; - - switch (enp1->en_kind) { - case ENCONST: - return enp1->en_val == enp2->en_val; - case ENLOCAL: - case ENALOCAL: - return enp1->en_loc == enp2->en_loc; - case ENEXTERNAL: - case ENAEXTERNAL: - return enp1->en_ext == enp2->en_ext; - case ENINDIR: - return enp1->en_ind == enp2->en_ind; - case ENOFFSETTED: - case ENAOFFSETTED: - return enp1->en_base == enp2->en_base && - enp1->en_off == enp2->en_off; - case ENALOCBASE: - case ENAARGBASE: - return enp1->en_levels == enp2->en_levels; - case ENPROC: - return enp1->en_pro == enp2->en_pro; - case ENARRELEM: - return enp1->en_arbase == enp2->en_arbase && - enp1->en_index == enp2->en_index && - enp1->en_adesc == enp2->en_adesc; - default: - return TRUE; - } -} - -STATIC copy_entity(src, dst) - entity_p src, dst; -{ - dst->en_static = src->en_static; - dst->en_kind = src->en_kind; - dst->en_size = src->en_size; - - switch (src->en_kind) { - case ENCONST: - dst->en_val = src->en_val; - break; - case ENLOCAL: - case ENALOCAL: - dst->en_loc = src->en_loc; - break; - case ENEXTERNAL: - case ENAEXTERNAL: - dst->en_ext = src->en_ext; - break; - case ENINDIR: - dst->en_ind = src->en_ind; - break; - case ENOFFSETTED: - case ENAOFFSETTED: - dst->en_base = src->en_base; - dst->en_off = src->en_off; - break; - case ENALOCBASE: - case ENAARGBASE: - dst->en_levels = src->en_levels; - break; - case ENPROC: - dst->en_pro = src->en_pro; - break; - case ENARRELEM: - dst->en_arbase = src->en_arbase; - dst->en_index = src->en_index; - dst->en_adesc = src->en_adesc; - break; - } -} - -entity_p en_enter(enp) - register entity_p enp; -{ - /* Put the entity in enp in the entity set, if it is not already there. - * Return pointer to stored entity. - */ - register Lindex i; - register entity_p new; - - for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) { - if (same_entity(en_elem(i), enp)) - return en_elem(i); - } - /* A new entity. */ - new = newentity(); - new->en_vn = newvalnum(); - copy_entity(enp, new); - Ladd(new, &entities); - - return new; -} - -clr_entities() -{ - /* Throw away all pseudo-symboltable information. */ - - register Lindex i; - - for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) { - oldentity(en_elem(i)); - } - Ldeleteset(entities); - entities = Lempty_set(); -} diff --git a/util/ego/cs/cs_entity.h b/util/ego/cs/cs_entity.h deleted file mode 100644 index 413de8121..000000000 --- a/util/ego/cs/cs_entity.h +++ /dev/null @@ -1,15 +0,0 @@ -extern lset entities; /* The pseudo-symboltable. */ - -extern entity_p find_entity(); /* (valnum vn) - * Tries to find an entity with value number vn. - */ - -extern entity_p en_enter(); /* (entity_p enp) - * Enter the entity in enp in the set of - * entities if it was not already there. - */ - -extern clr_entities(); /* () - * Release all space occupied by our - * pseudo-symboltable. - */ diff --git a/util/ego/cs/cs_getent.c b/util/ego/cs/cs_getent.c deleted file mode 100644 index b345f21af..000000000 --- a/util/ego/cs/cs_getent.c +++ /dev/null @@ -1,219 +0,0 @@ -#include "../../../h/em_mnem.h" -#include "../share/types.h" -#include "../share/aux.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "cs.h" -#include "cs_aux.h" -#include "cs_entity.h" -#include "cs_stack.h" - -#define WS1 0 -#define WS2 1 -#define PS 2 -#define ARGW 3 -#define ARDESC3 4 - -STATIC struct inf_entity { - byte inf_instr; /* Key. */ - byte inf_used; /* Kind of entity used by key. */ - byte inf_size; /* Indication of the size. */ -} inf_table[] = { - op_adp, ENAOFFSETTED, PS, - op_dee, ENEXTERNAL, WS1, - op_del, ENLOCAL, WS1, - op_ine, ENEXTERNAL, WS1, - op_inl, ENLOCAL, WS1, - op_lae, ENAEXTERNAL, PS, - op_lal, ENALOCAL, PS, - op_lar, ENARRELEM, ARDESC3, - op_ldc, ENCONST, WS2, - op_lde, ENEXTERNAL, WS2, - op_ldf, ENOFFSETTED, WS2, - op_ldl, ENLOCAL, WS2, - op_lil, ENINDIR, WS1, - op_lim, ENIGNMASK, WS1, - op_loc, ENCONST, WS1, - op_loe, ENEXTERNAL, WS1, - op_lof, ENOFFSETTED, WS1, - op_loi, ENINDIR, ARGW, - op_lol, ENLOCAL, WS1, - op_lpi, ENPROC, PS, - op_lxa, ENAARGBASE, PS, - op_lxl, ENALOCBASE, PS, - op_sar, ENARRELEM, ARDESC3, - op_sde, ENEXTERNAL, WS2, - op_sdf, ENOFFSETTED, WS2, - op_sdl, ENLOCAL, WS2, - op_sil, ENINDIR, WS1, - op_ste, ENEXTERNAL, WS1, - op_stf, ENOFFSETTED, WS1, - op_sti, ENINDIR, ARGW, - op_stl, ENLOCAL, WS1, - op_zer, ENCONST, ARGW, - op_zre, ENEXTERNAL, WS1, - op_zrf, ENFZER, ARGW, - op_zrl, ENLOCAL, WS1, - op_nop /* Delimitor. */ -}; - -#define INFKEY(ip) (ip->inf_instr & BMASK) -#define ENKIND(ip) ip->inf_used -#define SIZEINF(ip) ip->inf_size - -STATIC struct inf_entity *getinf(n) - int n; -{ - struct inf_entity *ip; - - for (ip = &inf_table[0]; INFKEY(ip) != op_nop; ip++) { - if (INFKEY(ip) == n) return ip; - } - return (struct inf_entity *) 0; -} - -entity_p getentity(lnp, l_out) - line_p lnp, *l_out; -{ - /* Build the entities where lnp refers to, and enter them. - * If a token needs to be popped, the first line that pushed - * it is stored in *l_out. - * The main entity lnp refers to, is returned. - */ - struct entity en; - struct token tk; - struct inf_entity *ip; - valnum vn; - offset indexsize; - struct token adesc, index, arbase; - - *l_out = lnp; - - /* Lor is a special case. */ - if (INSTR(lnp) == op_lor) { - en.en_static = FALSE; - en.en_size = ps; - switch (off_set(lnp)) { - default: - assert(FALSE); - break; - case 0: - en.en_kind = ENLOCBASE; - break; - case 1: - return (entity_p) 0; - case 2: - en.en_kind = ENHEAPPTR; - break; - } - return en_enter(&en); - } - - if ( (ip = getinf(INSTR(lnp))) == (struct inf_entity *) 0) - return (entity_p) 0; /* It does not refer to any entity. */ - - /* Lil and sil refer to two entities. */ - if (INSTR(lnp) == op_lil || INSTR(lnp) == op_sil) { - en.en_static = FALSE; - en.en_kind = ENLOCAL; - en.en_size = ps; /* Local must be a pointer. */ - en.en_loc = off_set(lnp); - vn = en_enter(&en)->en_vn; - } - - en.en_static = FALSE; - en.en_kind = ENKIND(ip); - - /* Fill in the size of the entity. */ - switch (SIZEINF(ip)) { - default: - assert(FALSE); - break; - case WS1: - en.en_size = ws; - break; - case WS2: - en.en_size = 2*ws; - break; - case PS: - en.en_size = ps; - break; - case ARGW: - if (TYPE(lnp) != OPNO) { - en.en_size = off_set(lnp); - } else { - Pop(&tk, (offset) ws); - *l_out = tk.tk_lfirst; - en.en_size = UNKNOWN_SIZE; - } - break; - case ARDESC3: - assert(en.en_kind == ENARRELEM); - if (TYPE(lnp) != OPNO) { - indexsize = off_set(lnp); - } else { - Pop(&tk, (offset) ws); - indexsize = UNKNOWN_SIZE; - } - Pop(&adesc, (offset) ps); - en.en_adesc = adesc.tk_vn; - Pop(&index, indexsize); - en.en_index = index.tk_vn; - Pop(&arbase, (offset) ps); - en.en_arbase = arbase.tk_vn; - *l_out = arbase.tk_lfirst; - en.en_size = array_elemsize(adesc.tk_vn); - break; - } - - /* Fill in additional information. */ - switch (en.en_kind) { - case ENFZER: - en.en_static = TRUE; - break; - case ENCONST: - en.en_static = TRUE; - en.en_val = off_set(lnp); - break; - case ENALOCAL: - en.en_static = TRUE; - case ENLOCAL: - en.en_loc = off_set(lnp); - break; - case ENAEXTERNAL: - en.en_static = TRUE; - case ENEXTERNAL: - en.en_ext = OBJ(lnp); - break; - case ENINDIR: - if (INSTR(lnp) == op_loi || INSTR(lnp) == op_sti) { - Pop(&tk, (offset) ps); - *l_out = tk.tk_lfirst; - vn = tk.tk_vn; - } - en.en_ind = vn; - break; - case ENAOFFSETTED: - en.en_static = TRUE; - case ENOFFSETTED: - Pop(&tk, (offset) ps); - *l_out = tk.tk_lfirst; - en.en_base = tk.tk_vn; - en.en_off = off_set(lnp); - break; - case ENALOCBASE: - case ENAARGBASE: - en.en_static = TRUE; - en.en_levels = off_set(lnp); - break; - case ENPROC: - en.en_pro = PROC(lnp); - break; - case ENARRELEM: - /* We gathered the information in the previous switch. - */ - break; - } - - return en_enter(&en); -} diff --git a/util/ego/cs/cs_getent.h b/util/ego/cs/cs_getent.h deleted file mode 100644 index 53eb5ea75..000000000 --- a/util/ego/cs/cs_getent.h +++ /dev/null @@ -1,8 +0,0 @@ -extern entity_p getentity(); /* (line_p lnp, *l_out) - * Extract the entity lnp refers and enter it - * in the table of entities. The main entity - * lnp refers to is returned; sometimes there - * is more than one entity. The first line that - * was involved in pushing it is returned - * through l_out. - */ diff --git a/util/ego/cs/cs_kill.c b/util/ego/cs/cs_kill.c deleted file mode 100644 index ce424432f..000000000 --- a/util/ego/cs/cs_kill.c +++ /dev/null @@ -1,372 +0,0 @@ -#include "../../../h/em_mnem.h" -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/aux.h" -#include "../share/map.h" -#include "cs.h" -#include "cs_aux.h" -#include "cs_debug.h" -#include "cs_avail.h" -#include "cs_entity.h" - -STATIC base_valno(enp) - entity_p enp; -{ - /* Return the value number of the (base) address of an indirectly - * accessed entity. - */ - switch (enp->en_kind) { - default: - assert(FALSE); - break; - case ENINDIR: - return enp->en_ind; - case ENOFFSETTED: - return enp->en_base; - case ENARRELEM: - return enp->en_arbase; - } - /* NOTREACHED */ -} - -STATIC entity_p find_base(vn) - valnum vn; -{ - /* Vn is the valuenumber of the (base) address of an indirectly - * accessed entity. Return the entity that holds this address - * recursively. - */ - register Lindex i; - register avail_p ravp; - - for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) { - register entity_p renp = en_elem(i); - - if (renp->en_vn == vn) { - switch (renp->en_kind) { - case ENAEXTERNAL: - case ENALOCAL: - case ENALOCBASE: - case ENAARGBASE: - return renp; - case ENAOFFSETTED: - return find_base(renp->en_base); - } - } - } - - /* We couldn't find it among the entities. - * Let's try the available expressions. - */ - for (ravp = avails; ravp != (avail_p) 0; ravp = ravp->av_before) { - if (ravp->av_result == vn) { - if (ravp->av_instr == (byte) op_aar) - return find_base(ravp->av_ofirst); - if (ravp->av_instr == (byte) op_ads) - return find_base(ravp->av_oleft); - } - } - - /* Bad luck. */ - return (entity_p) 0; -} - -STATIC bool obj_overlap(op1, op2) - obj_p op1, op2; -{ - /* Op1 and op2 point to two objects in the same datablock. - * Obj_overlap returns whether these objects might overlap. - */ - obj_p tmp; - - if (op1->o_off > op2->o_off) { - /* Exchange them. */ - tmp = op1; op1 = op2; op2 = tmp; - } - return op1->o_size == UNKNOWN_SIZE || - op1->o_off + op1->o_size > op2->o_off; -} - -#define same_datablock(o1, o2) ((o1)->o_dblock == (o2)->o_dblock) - -STATIC bool addr_local(enp) - entity_p enp; -{ - /* Is enp the address of a stack item. */ - - if (enp == (entity_p) 0) return FALSE; - - return enp->en_kind == ENALOCAL || enp->en_kind == ENALOCBASE || - enp->en_kind == ENAARGBASE; -} - -STATIC bool addr_external(enp) - entity_p enp; -{ - /* Is enp the address of an external. */ - - return enp != (entity_p) 0 && enp->en_kind == ENAEXTERNAL; -} - -STATIC kill_external(obp, indir) - obj_p obp; - int indir; -{ - /* A store is done via the object in obp. If this store is direct - * we kill directly accessed entities in the same data block only - * if they overlap with obp, otherwise we kill everything in the - * data block. Indirectly accessed entities of which it can not be - * proven taht they are not in the same data block, are killed in - * both cases. - */ - register Lindex i; - - OUTTRACE("kill external", 0); - for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) { - entity_p enp = en_elem(i); - entity_p base; - - switch (enp->en_kind) { - case ENEXTERNAL: - if (!same_datablock(enp->en_ext, obp)) - break; - if (!indir && !obj_overlap(enp->en_ext, obp)) - break; - OUTTRACE("kill %d", enp->en_vn); - enp->en_vn = newvalnum(); - break; - case ENINDIR: - case ENOFFSETTED: - case ENARRELEM: - /* We spare its value number if we are sure - * that its (base) address points into the - * stack or into another data block. - */ - base = find_base(base_valno(enp)); - if (addr_local(base)) - break; - if (addr_external(base) && - !same_datablock(base->en_ext, obp) - ) - break; - OUTTRACE("kill %d", enp->en_vn); - enp->en_vn = newvalnum(); - break; - } - } -} - -STATIC bool loc_overlap(enp1, enp2) - entity_p enp1, enp2; -{ - /* Enp1 and enp2 point to two locals. Loc_overlap returns whether - * they overlap. - */ - entity_p tmp; - - assert(enp1->en_kind == ENLOCAL && enp2->en_kind == ENLOCAL); - - if (enp1->en_loc > enp2->en_loc) { - /* Exchange them. */ - tmp = enp1; enp1 = enp2; enp2 = tmp; - } - if (enp1->en_loc < 0 && enp2->en_loc >= 0) - return FALSE; /* Locals and parameters do not overlap. */ - else return enp1->en_size == UNKNOWN_SIZE || - enp1->en_loc + enp1->en_size > enp2->en_loc; -} - -STATIC kill_local(enp, indir) - entity_p enp; - bool indir; -{ - /* This time a store is done into an ENLOCAL. */ - - register Lindex i; - - OUTTRACE("kill local", 0); - for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) { - entity_p rep = en_elem(i); - entity_p base; - - switch (rep->en_kind) { - case ENLOCAL: - if (indir) { - /* Kill locals that might be stored into - * via a pointer. Note: enp not used. - */ - if (!is_regvar(rep->en_loc)) { - OUTTRACE("kill %d", rep->en_vn); - rep->en_vn = newvalnum(); - } - } else if (loc_overlap(rep, enp)) { - /* Only kill overlapping locals. */ - OUTTRACE("kill %d", rep->en_vn); - rep->en_vn = newvalnum(); - } - break; - case ENINDIR: - case ENOFFSETTED: - case ENARRELEM: - if (!is_regvar(enp->en_loc)) { - base = find_base(base_valno(rep)); - if (!addr_external(base)) { - OUTTRACE("kill %d", rep->en_vn); - rep->en_vn = newvalnum(); - } - } - break; - } - } -} - -STATIC kill_sim() -{ - /* A store is done into the ENIGNMASK. */ - - register Lindex i; - - OUTTRACE("kill sim", 0); - for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) { - register entity_p rep = en_elem(i); - - if (rep->en_kind == ENIGNMASK) { - OUTTRACE("kill %d", rep->en_vn); - rep->en_vn = newvalnum(); - return; /* There is only one ignoremask. */ - } - } -} - -kill_direct(enp) - entity_p enp; -{ - /* A store will be done into enp. We must forget the values of all the - * entities this one may overlap with. - */ - switch (enp->en_kind) { - default: - assert(FALSE); - break; - case ENEXTERNAL: - kill_external(enp->en_ext, FALSE); - break; - case ENLOCAL: - kill_local(enp, FALSE); - break; - case ENIGNMASK: - kill_sim(); - break; - } -} - -kill_indir(enp) - entity_p enp; -{ - /* An indirect store is done, in an ENINDIR, - * an ENOFFSETTED or an ENARRELEM. - */ - entity_p p; - - /* If we can find the (base) address of this entity, then we can spare - * the entities that are provably not pointed to by the address. - * We will also make use of the MES 3 pseudo's, generated by - * the front-end. When a MES 3 is generated for a local, this local - * will not be referenced indirectly. - */ - if ((p = find_base(base_valno(enp))) == (entity_p) 0) { - kill_much(); /* Kill all entities without registermessage. */ - } else { - switch (p->en_kind) { - case ENAEXTERNAL: - /* An indirect store into global data. */ - kill_external(p->en_ext, TRUE); - break; - case ENALOCAL: - case ENALOCBASE: - case ENAARGBASE: - /* An indirect store into stack data. */ - kill_local(p, TRUE); - break; - } - } -} - -kill_much() -{ - /* Kills all killable entities, - * except the locals for which a registermessage was generated. - */ - register Lindex i; - - OUTTRACE("kill much", 0); - for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) { - register entity_p rep = en_elem(i); - - if (rep->en_static) continue; - if (rep->en_kind == ENLOCAL && is_regvar(rep->en_loc)) continue; - OUTTRACE("kill %d", rep->en_vn); - rep->en_vn = newvalnum(); - } -} - -STATIC bool bad_procflags(pp) - proc_p pp; -{ - /* Return whether the flags about the procedure in pp indicate - * that we have little information about it. It might be that - * we haven't seen the text of pp, or that we have seen that pp - * calls a procedure which we haven't seen the text of. - */ - return !(pp->p_flags1 & PF_BODYSEEN) || (pp->p_flags1 & PF_CALUNKNOWN); -} - -STATIC kill_globset(s) - cset s; -{ - /* S is a set of global variables that might be changed. - * We act as if a direct store is done into each of them. - */ - register Cindex i; - - OUTTRACE("kill globset", 0); - for (i = Cfirst(s); i != (Cindex) 0; i = Cnext(i,s)) { - kill_external(omap[Celem(i)], FALSE); - } -} - -kill_call(pp) - proc_p pp; -{ - /* Kill everything that might be destroyed by calling - * the procedure in pp. - */ - if (bad_procflags(pp)) { - /* We don't know enough about this procedure. */ - kill_much(); - } else if (pp->p_change->c_flags & CF_INDIR) { - /* The procedure does an indirect store. */ - kill_much(); - } else { - /* Procedure might affect global data. */ - kill_globset(pp->p_change->c_ext); - } -} - -kill_all() -{ - /* Kills all entities. */ - - register Lindex i; - - OUTTRACE("kill all entities", 0); - for (i = Lfirst(entities); i != (Lindex) i; i = Lnext(i, entities)) { - entity_p enp = en_elem(i); - - OUTTRACE("kill %d", enp->en_vn); - enp->en_vn = newvalnum(); - } -} diff --git a/util/ego/cs/cs_kill.h b/util/ego/cs/cs_kill.h deleted file mode 100644 index 96d831d22..000000000 --- a/util/ego/cs/cs_kill.h +++ /dev/null @@ -1,24 +0,0 @@ -extern kill_call(); /* (proc_p pp) - * Kill all entities that might have an other value - * after execution of the procedure in pp. - */ - -extern kill_much(); /* () - * Kill all killable entities except those for which - * a register message was generated. - * Constants, addresses, etc are not killable. - */ - -extern kill_indir(); /* (entity_p enp) - * Kill all entities that might have an other value - * after indirect assignment to the entity in enp. - */ - -extern kill_direct(); /* (entity_p enp) - * Kill all entities that might have an other value - * after direct assignment to the entity in enp. - */ - -extern kill_all(); /* () - * Kill all entities. - */ diff --git a/util/ego/cs/cs_partit.c b/util/ego/cs/cs_partit.c deleted file mode 100644 index 977a10a45..000000000 --- a/util/ego/cs/cs_partit.c +++ /dev/null @@ -1,371 +0,0 @@ -/* Functions to partition the huge set of EM-instructions. */ - -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_reg.h" -#include "../../../h/em_spec.h" -#include "../share/types.h" -#include "../share/aux.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "cs.h" -#include "cs_stack.h" - -#define XXX (-1) -#define ARGW 0 -#define WS 1 -#define PS 2 -#define FEF 3 -#define FIF 4 -#define CVT 5 - -#define ANY 0 -#define PTR 1 -#define FLT 2 - -STATIC struct { - byte i_group; /* Group of instruction. */ - byte i_op1; /* Indication of size of operand of unary operator. */ - /* Idem for 1st operand of binary operator. */ - byte i_op2; /* Idem for 2nd operand of binary operator. */ - byte i_av; /* Idem for result of operators. */ - byte i_regtype; /* ANY, PTR, FLT. */ -} info[] = { - XXX, XXX, XXX, XXX, XXX, -/* aar */ TERNAIR_OP, XXX, XXX, PS, PTR, -/* adf */ BINAIR_OP, ARGW, ARGW, ARGW, FLT, -/* adi */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* adp */ EXPENSIVE_LOAD, XXX, XXX, XXX, PTR, -/* ads */ BINAIR_OP, PS, ARGW, PS, PTR, -/* adu */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* and */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* asp */ FIDDLE_STACK, XXX, XXX, XXX, XXX, -/* ass */ FIDDLE_STACK, XXX, XXX, XXX, XXX, -/* beq */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* bge */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* bgt */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* ble */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* blm */ HOPELESS, XXX, XXX, XXX, XXX, -/* bls */ HOPELESS, XXX, XXX, XXX, XXX, -/* blt */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* bne */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* bra */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* cai */ SIDE_EFFECTS, XXX, XXX, XXX, XXX, -/* cal */ SIDE_EFFECTS, XXX, XXX, XXX, XXX, -/* cff */ TERNAIR_OP, XXX, XXX, CVT, FLT, -/* cfi */ TERNAIR_OP, XXX, XXX, CVT, ANY, -/* cfu */ TERNAIR_OP, XXX, XXX, CVT, ANY, -/* cif */ TERNAIR_OP, XXX, XXX, CVT, FLT, -/* cii */ TERNAIR_OP, XXX, XXX, CVT, ANY, -/* ciu */ TERNAIR_OP, XXX, XXX, CVT, ANY, -/* cmf */ BINAIR_OP, ARGW, ARGW, WS, ANY, -/* cmi */ BINAIR_OP, ARGW, ARGW, WS, ANY, -/* cmp */ BINAIR_OP, PS, PS, WS, ANY, -/* cms */ BINAIR_OP, ARGW, ARGW, WS, ANY, -/* cmu */ BINAIR_OP, ARGW, ARGW, WS, ANY, -/* com */ UNAIR_OP, ARGW, XXX, ARGW, ANY, -/* csa */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* csb */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* cuf */ TERNAIR_OP, XXX, XXX, CVT, FLT, -/* cui */ TERNAIR_OP, XXX, XXX, CVT, ANY, -/* cuu */ TERNAIR_OP, XXX, XXX, CVT, ANY, -/* dch */ UNAIR_OP, PS, XXX, PS, PTR, -/* dec */ UNAIR_OP, WS, XXX, WS, ANY, -/* dee */ KILL_ENTITY, XXX, XXX, XXX, XXX, -/* del */ KILL_ENTITY, XXX, XXX, XXX, XXX, -/* dup */ FIDDLE_STACK, XXX, XXX, XXX, XXX, -/* dus */ FIDDLE_STACK, XXX, XXX, XXX, XXX, -/* dvf */ BINAIR_OP, ARGW, ARGW, ARGW, FLT, -/* dvi */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* dvu */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* exg */ FIDDLE_STACK, XXX, XXX, XXX, XXX, -/* fef */ UNAIR_OP, ARGW, XXX, FEF, XXX, -/* fif */ BINAIR_OP, ARGW, ARGW, FIF, XXX, -/* fil */ IGNORE, XXX, XXX, XXX, XXX, -/* gto */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* inc */ UNAIR_OP, WS, XXX, WS, ANY, -/* ine */ KILL_ENTITY, XXX, XXX, XXX, XXX, -/* inl */ KILL_ENTITY, XXX, XXX, XXX, XXX, -/* inn */ BINAIR_OP, ARGW, WS, WS, ANY, -/* ior */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* lae */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* lal */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* lar */ LOAD_ARRAY, XXX, XXX, XXX, ANY, -/* ldc */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* lde */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* ldf */ EXPENSIVE_LOAD, XXX, XXX, XXX, ANY, -/* ldl */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* lfr */ FIDDLE_STACK, XXX, XXX, XXX, XXX, -/* lil */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* lim */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* lin */ IGNORE, XXX, XXX, XXX, XXX, -/* lni */ IGNORE, XXX, XXX, XXX, XXX, -/* loc */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* loe */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* lof */ EXPENSIVE_LOAD, XXX, XXX, XXX, ANY, -/* loi */ EXPENSIVE_LOAD, XXX, XXX, XXX, ANY, -/* lol */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* lor */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* los */ FIDDLE_STACK, XXX, XXX, XXX, XXX, -/* lpb */ UNAIR_OP, PS, XXX, PS, PTR, -/* lpi */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* lxa */ EXPENSIVE_LOAD, XXX, XXX, XXX, PTR, -/* lxl */ EXPENSIVE_LOAD, XXX, XXX, XXX, PTR, -/* mlf */ BINAIR_OP, ARGW, ARGW, ARGW, FLT, -/* mli */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* mlu */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* mon */ HOPELESS, XXX, XXX, XXX, XXX, -/* ngf */ UNAIR_OP, ARGW, XXX, ARGW, FLT, -/* ngi */ UNAIR_OP, ARGW, XXX, ARGW, ANY, -/* nop */ IGNORE, XXX, XXX, XXX, XXX, -/* rck */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* ret */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* rmi */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* rmu */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* rol */ BINAIR_OP, ARGW, WS, ARGW, ANY, -/* ror */ BINAIR_OP, ARGW, WS, ARGW, ANY, -/* rtt */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* sar */ STORE_ARRAY, XXX, XXX, XXX, XXX, -/* sbf */ BINAIR_OP, ARGW, ARGW, ARGW, FLT, -/* sbi */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* sbs */ BINAIR_OP, PS, PS, ARGW, ANY, -/* sbu */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* sde */ STORE_DIRECT, XXX, XXX, XXX, XXX, -/* sdf */ STORE_INDIR, XXX, XXX, XXX, XXX, -/* sdl */ STORE_DIRECT, XXX, XXX, XXX, XXX, -/* set */ UNAIR_OP, WS, XXX, ARGW, ANY, -/* sig */ FIDDLE_STACK, XXX, XXX, XXX, XXX, -/* sil */ STORE_INDIR, XXX, XXX, XXX, XXX, -/* sim */ STORE_DIRECT, XXX, XXX, XXX, XXX, -/* sli */ BINAIR_OP, ARGW, WS, ARGW, ANY, -/* slu */ BINAIR_OP, ARGW, WS, ARGW, ANY, -/* sri */ BINAIR_OP, ARGW, WS, ARGW, ANY, -/* sru */ BINAIR_OP, ARGW, WS, ARGW, ANY, -/* ste */ STORE_DIRECT, XXX, XXX, XXX, XXX, -/* stf */ STORE_INDIR, XXX, XXX, XXX, XXX, -/* sti */ STORE_INDIR, XXX, XXX, XXX, XXX, -/* stl */ STORE_DIRECT, XXX, XXX, XXX, XXX, -/* str */ HOPELESS, XXX, XXX, XXX, XXX, -/* sts */ HOPELESS, XXX, XXX, XXX, XXX, -/* teq */ UNAIR_OP, WS, XXX, WS, ANY, -/* tge */ UNAIR_OP, WS, XXX, WS, ANY, -/* tgt */ UNAIR_OP, WS, XXX, WS, ANY, -/* tle */ UNAIR_OP, WS, XXX, WS, ANY, -/* tlt */ UNAIR_OP, WS, XXX, WS, ANY, -/* tne */ UNAIR_OP, WS, XXX, WS, ANY, -/* trp */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* xor */ BINAIR_OP, ARGW, ARGW, ARGW, ANY, -/* zeq */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* zer */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* zge */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* zgt */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* zle */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* zlt */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* zne */ BBLOCK_END, XXX, XXX, XXX, XXX, -/* zre */ KILL_ENTITY, XXX, XXX, XXX, XXX, -/* zrf */ SIMPLE_LOAD, XXX, XXX, XXX, XXX, -/* zrl */ KILL_ENTITY, XXX, XXX, XXX, XXX -}; - -#define GROUP(n) (info[n].i_group) -#define OP1SIZE(l) (info[INSTR(l)].i_op1) -#define OP2SIZE(l) (info[INSTR(l)].i_op2) -#define AVSIZE(l) (info[INSTR(l)].i_av) -#define REGTYPE(n) (info[n].i_regtype) - -int instrgroup(lnp) - line_p lnp; -{ - if (INSTR(lnp) == op_lor && SHORT(lnp) == 1) { - /* We can't do anything with the stackpointer. */ - return FIDDLE_STACK; - } - if (INSTR(lnp) < sp_fmnem || INSTR(lnp) > sp_lmnem) { - VI((short) INSTR(lnp)); - return IGNORE; - } - return GROUP(INSTR(lnp)); -} - -bool stack_group(instr) - int instr; -{ - /* Is this an instruction that only does something to the top of - * the stack? - */ - switch (GROUP(instr)) { - case SIMPLE_LOAD: - case EXPENSIVE_LOAD: - case LOAD_ARRAY: - case UNAIR_OP: - case BINAIR_OP: - case TERNAIR_OP: - return TRUE; - default: - return FALSE; - } -} - -STATIC offset argw(lnp) - line_p lnp; -{ - /* Some EM-instructions have their argument either on the same line, - * or on top of the stack. We give up when the argument is on top of - * the stack. - */ - struct token dummy; - - if (TYPE(lnp) != OPNO) { - return off_set(lnp); - } else { - Pop(&dummy, (offset) ws); - return UNKNOWN_SIZE; - } -} - -offset op11size(lnp) - line_p lnp; -{ - /* Returns the size of the first argument of - * the unary operator in lnp. - */ - - switch (OP1SIZE(lnp)) { - case ARGW: - return argw(lnp); - case WS: - return ws; - case PS: - return ps; - default: - assert(FALSE); - } - /* NOTREACHED */ -} - -offset op12size(lnp) - line_p lnp; -{ - /* Same for first of binary. */ - - switch (OP1SIZE(lnp)) { - case ARGW: - return argw(lnp); - case PS: - return ps; - default: - assert(FALSE); - } - /* NOTREACHED */ -} - -offset op22size(lnp) - line_p lnp; -{ - switch (OP2SIZE(lnp)) { - case ARGW: - return argw(lnp); - case WS: - return ws; - case PS: - return ps; - default: - assert(FALSE); - } - /* NOTREACHED */ -} - -/* Ternary operators are op_aar and conversions between types and/or sizes. */ - -offset op13size(lnp) - line_p lnp; -{ - /* When the instruction is a conversion, the size of the first - * operand is the value of the second operand. - * We only handle the most likely case, namely that the second operand - * was pushed by a loc-instruction. - */ - if (INSTR(lnp) == op_aar) return ps; - - if (lnp->l_prev != (line_p) 0 && - lnp->l_prev->l_prev != (line_p) 0 && - INSTR(lnp->l_prev->l_prev) == op_loc - ) - return off_set(lnp->l_prev->l_prev); - else - return UNKNOWN_SIZE; -} - -offset op23size(lnp) - line_p lnp; -{ - if (INSTR(lnp) == op_aar) - return argw(lnp); - else - return ws; -} - -offset op33size(lnp) - line_p lnp; -{ - if (INSTR(lnp) == op_aar) - return ps; - else - return ws; -} - -offset avsize(lnp) - line_p lnp; -{ - /* Returns the size of the result of the instruction in lnp. - * If the instruction is a conversion this size is given on the stack. - * We only handle the case that this value was pushed by a loc. - */ - offset size; - - switch (AVSIZE(lnp)) { - case ARGW: - return argw(lnp); - case WS: - return ws; - case PS: - return ps; - case FEF: - if ((size = argw(lnp)) != UNKNOWN_SIZE) - return size + ws; - else - return UNKNOWN_SIZE; - case FIF: - if ((size = argw(lnp)) != UNKNOWN_SIZE) - return size + size; - else - return UNKNOWN_SIZE; - case CVT: - if (lnp->l_prev != (line_p) 0 && - INSTR(lnp->l_prev) == op_loc - ) - return off_set(lnp->l_prev); - else - return UNKNOWN_SIZE; - default: - assert(FALSE); - break; - } - /* NOTREACHED */ -} - -int regtype(instr) - byte instr; -{ - switch (REGTYPE(instr & BMASK)) { - case ANY: - return reg_any; - case PTR: - return reg_pointer; - case FLT: - return reg_float; - default: - assert(FALSE); - } - /* NOTREACHED */ -} diff --git a/util/ego/cs/cs_partit.h b/util/ego/cs/cs_partit.h deleted file mode 100644 index 16f3cbdaa..000000000 --- a/util/ego/cs/cs_partit.h +++ /dev/null @@ -1,55 +0,0 @@ -/* These routines partition the huge set of EM-instructions in - * "manageable chunks. - */ - -extern int instrgroup(); /* (line_p lnp) - * Return the group into which the instruction - * in lnp belongs to. - */ - -extern bool stack_group(); /* (int instr) - * Return whether instr is an instruction that - * only changes the state of the stack, i.e. - * is a "true" operator. - */ - -extern offset op11size(); /* (line_p lnp) - * Return the size of the operand of the unary - * operator in lnp. - */ - -extern offset op12size(); /* (line_p lnp) - * Return the size of the first operand of the - * binary operator in lnp. - */ - -extern offset op22size(); /* (line_p lnp) - * Return the size of the second operand of the - * binary operator in lnp. - */ - -extern offset op13size(); /* (line_p lnp) - * Return the size of the first operand of the - * ternary operator in lnp. - */ - -extern offset op23size(); /* (line_p lnp) - * Return the size of the second operand of the - * ternary operator in lnp. - */ - -extern offset op33size(); /* (line_p lnp) - * Return the size of the third operand of the - * ternary operator in lnp. - */ - -extern offset avsize(); /* (line_p lnp) - * Return the size of the result of the - * operator in lnp. - */ - -extern int regtype(); /* (byte instr) - * Return in what kind of machine-register - * the result of instr should be stored: - * pointer, float, or any. - */ diff --git a/util/ego/cs/cs_profit.c b/util/ego/cs/cs_profit.c deleted file mode 100644 index aa2b15ac5..000000000 --- a/util/ego/cs/cs_profit.c +++ /dev/null @@ -1,207 +0,0 @@ -#include -#include "../../../h/em_mnem.h" -#include "../../../h/em_spec.h" -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/aux.h" -#include "../share/cset.h" -#include "../share/lset.h" -#include "cs.h" -#include "cs_aux.h" -#include "cs_debug.h" -#include "cs_avail.h" -#include "cs_partit.h" - -STATIC cset addr_modes; -STATIC cset cheaps; -STATIC cset forbidden; -STATIC short LX_threshold; -STATIC short AR_limit; -STATIC bool DO_sli; - -STATIC get_instrs(f, s_p) - FILE *f; - cset *s_p; -{ - /* Read a set of instructions from inputfile f into *s_p. - * Such a set must be delimited by a number lower than - * the number of the first EM mnemonic. - */ - int instr; - - fscanf(f, "%d", &instr); - while (instr >= sp_fmnem) { - Cadd((Celem_t) instr, s_p); - fscanf(f, "%d", &instr); - } -} - -STATIC choose_cset(f, s_p) - FILE *f; - cset *s_p; -{ - /* Read two compact sets of EM instructions from inputfile f. - * Choose the first if we optimize with respect to time, - * the second if we optimize with respect to space, as - * indicated by time_space_ratio. - */ - cset cs1, cs2; /* Two dummy sets. */ - - *s_p = Cempty_set((short) sp_lmnem); - - cs1 = Cempty_set((short) sp_lmnem); - get_instrs(f, &cs1); - cs2 = Cempty_set((short) sp_lmnem); - get_instrs(f, &cs2); - - Ccopy_set(time_space_ratio >= 50 ? cs1 : cs2, s_p); - - Cdeleteset(cs1); Cdeleteset(cs2); - } - -cs_machinit(f) - FILE *f; -{ - char s[100]; - int time, space; - - /* Find piece that is relevant for this phase. */ - do { - while (getc(f) != '\n'); - fscanf(f, "%s", s); - } while (strcmp(s, "%%CS")); - - /* Choose a set of instructions which must only be eliminated - * if they are at the root of another expression. - */ - choose_cset(f, &addr_modes); - - /* Choose a set of cheap instructions; i.e. instructions that - * are cheaper than a move to save the result of such an - * instruction. - */ - choose_cset(f, &cheaps); - - /* Read how many lexical levels back an LXL/LXA instruction - * must at least look before it will be eliminated. - */ - fscanf(f, "%d %d", &time, &space); - LX_threshold = time_space_ratio >= 50 ? time : space; - - /* Read what the size of an array-element may be, - * before we think that it is to big to replace - * a LAR/SAR of it by AAR LOI/STI . - */ - fscanf(f, "%d", &space); - AR_limit = space; - - /* Read whether we must eliminate an SLI instruction - * when it is part of an array-index computation. - */ - fscanf(f, "%d %d", &time, &space); - DO_sli = time_space_ratio >= 50 ? time : space; - - /* Read a set of instructions which we do not want to eliminate. - * Note: only instructions need be given that may in principle - * be eliminated, but for which better code can be generated - * when they stay, and with which is not dealt in the common - * decision routines. - */ - choose_cset(f, &forbidden); -} - -STATIC bool is_index(lnp) - line_p lnp; -{ - /* Return whether the SLI-instruction in lnp is part of - * an array-index computation. - */ - return lnp->l_prev != (line_p) 0 && INSTR(lnp->l_prev) == op_loc && - lnp->l_next != (line_p) 0 && INSTR(lnp->l_next) == op_ads; -} - -STATIC bool gains(avp) - avail_p avp; -{ - /* Return whether we can gain something, when we eliminate - * an expression such as in avp. We just glue together some - * heuristics with some user-supplied stuff. - */ - if (Cis_elem(avp->av_instr & BMASK, forbidden)) - return FALSE; - - if (avp->av_instr == (byte) op_lxa || avp->av_instr == (byte) op_lxl) - return off_set(avp->av_found) >= LX_threshold; - - if (avp->av_instr == (byte) op_sli) - return !is_index(avp->av_found) || DO_sli; - - if (Cis_elem(avp->av_instr & BMASK, addr_modes)) - return instrgroup(avp->av_found->l_prev) != SIMPLE_LOAD; - - if (Cis_elem(avp->av_instr & BMASK, cheaps)) - return avp->av_saveloc != (entity_p) 0; - - return TRUE; -} - -STATIC bool okay_lines(avp, ocp) - avail_p avp; - occur_p ocp; -{ - register line_p lnp, next; - - for (lnp = ocp->oc_lfirst; lnp != (line_p) 0; lnp = next) { - next = lnp != ocp->oc_llast ? lnp->l_next : (line_p) 0; - - if (INSTR(lnp) < sp_fmnem || INSTR(lnp) > sp_lmnem) - return FALSE; - if (!stack_group(INSTR(lnp))) { - /* Check for SAR-instruction. */ - if (INSTR(lnp) != op_sar || next != (line_p) 0) - return FALSE; - } - } - /* All lines in this occurrence can in principle be eliminated; - * no stores, messages, calls etc. - * We now check whether it is desirable to treat a LAR or a SAR - * as an AAR LOI/STI. This depends on the size of the array-elements. - */ - if (INSTR(ocp->oc_llast) == op_lar || INSTR(ocp->oc_llast) == op_sar) { - if (avp->av_instr == (byte) op_aar && time_space_ratio < 50) { - return array_elemsize(avp->av_othird) <= AR_limit; - } - } - return TRUE; -} - -bool desirable(avp) - avail_p avp; -{ - register Lindex i, next; - - if (!gains(avp)) { - OUTTRACE("no gain", 0); - SHOWAVAIL(avp); - return FALSE; - } - - /* Walk through the occurrences to see whether it is okay to - * eliminate them. If not, remove them from the set. - */ - for (i = Lfirst(avp->av_occurs); i != (Lindex) 0; i = next) { - next = Lnext(i, avp->av_occurs); - - if (!okay_lines(avp, occ_elem(i))) { - OUTTRACE("may not eliminate", 0); -# ifdef TRACE - SHOWOCCUR(occ_elem(i)); -# endif - oldoccur(occ_elem(i)); - Lremove(Lelem(i), &avp->av_occurs); - } - } - - return Lnrelems(avp->av_occurs) > 0; -} diff --git a/util/ego/cs/cs_profit.h b/util/ego/cs/cs_profit.h deleted file mode 100644 index 535b6b904..000000000 --- a/util/ego/cs/cs_profit.h +++ /dev/null @@ -1,10 +0,0 @@ -extern cs_machinit(); /* (FILE *f) - * Read phase-specific information from f. - */ - -extern bool desirable(); /* (avail_p avp) - * Return whether it is desirable to eliminate - * the recurrences of the expression in avp. - * At the same time delete the recurrences - * for which it is not allowed. - */ diff --git a/util/ego/cs/cs_stack.c b/util/ego/cs/cs_stack.c deleted file mode 100644 index 2070dad6c..000000000 --- a/util/ego/cs/cs_stack.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * S T A C K M O D U L E - */ -#include "../share/types.h" -#include "../share/global.h" -#include "../share/debug.h" -#include "../share/aux.h" -#include "cs.h" -#include "cs_aux.h" - -#define STACK_DEPTH 50 - -STATIC struct token Stack[STACK_DEPTH]; -STATIC token_p free_token; - -#define Delete_top() {--free_token; } -#define Empty_stack() {free_token = &Stack[0]; } -#define Stack_empty() (free_token == &Stack[0]) -#define Top (free_token - 1) - -Push(tkp) - token_p tkp; -{ - if (tkp->tk_size == UNKNOWN_SIZE) { - Empty_stack(); /* The contents of the Stack is useless. */ - } else { - assert(free_token < &Stack[STACK_DEPTH]); - - free_token->tk_vn = tkp->tk_vn; - free_token->tk_size = tkp->tk_size; - free_token++->tk_lfirst = tkp->tk_lfirst; - } -} - -#define WORD_MULTIPLE(n) ((n / ws) * ws + ( n % ws ? ws : 0 )) - -Pop(tkp, size) - token_p tkp; - offset size; -{ - /* Pop a token with given size from the valuenumber stack into tkp. */ - - /* First simple case. */ - if (size != UNKNOWN_SIZE && !Stack_empty() && size == Top->tk_size) { - tkp->tk_vn = Top->tk_vn; - tkp->tk_size = size; - tkp->tk_lfirst = Top->tk_lfirst; - Delete_top(); - return; - } - /* Now we're in trouble: we must pop something that is not there! - * We just put a dummy into tkp and pop tokens until we've - * popped size bytes. - */ - /* Create dummy. */ - tkp->tk_vn = newvalnum(); - tkp->tk_lfirst = (line_p) 0; - - /* Now fiddle with the Stack. */ - if (Stack_empty()) return; - if (size == UNKNOWN_SIZE) { - Empty_stack(); - return; - } - if (size > Top->tk_size) { - while (!Stack_empty() && size >= Top->tk_size) { - size -= Top->tk_size; - Delete_top(); - } - } - /* Now Stack_empty OR size < Top->tk_size. */ - if (!Stack_empty()) { - if (Top->tk_size - size < ws) { - Delete_top(); - } else { - Top->tk_vn = newvalnum(); - Top->tk_size -= WORD_MULTIPLE(size); - } - } -} - -Dup(lnp) - line_p lnp; -{ - /* Duplicate top bytes on the Stack. */ - - register token_p bottom = Top; - register token_p oldtop = Top; - register offset nbytes = off_set(lnp); - struct token dummy; - - /* Find the bottom of the bytes to be duplicated. - * It is possible that we cannot find it. - */ - while (bottom > &Stack[0] && bottom->tk_size < nbytes) { - nbytes -= bottom->tk_size; - bottom--; - } - - if (bottom < &Stack[0]) { - /* There was nothing. */ - dummy.tk_vn = newvalnum(); - dummy.tk_size = nbytes; - dummy.tk_lfirst = lnp; - Push(&dummy); - } else { - if (bottom->tk_size < nbytes) { - /* Not enough, bottom == &Stack[0]. */ - dummy.tk_vn = newvalnum(); - dummy.tk_size = nbytes - bottom->tk_size; - dummy.tk_lfirst = lnp; - Push(&dummy); - } else if (bottom->tk_size > nbytes) { - /* Not integral # tokens. */ - dummy.tk_vn = newvalnum(); - dummy.tk_size = nbytes; - dummy.tk_lfirst = lnp; - Push(&dummy); - bottom++; - } - /* Bottom points to lowest token to be dupped. */ - while (bottom <= oldtop) { - Push(bottom++); - Top->tk_lfirst = lnp; - } - } -} - -clr_stack() -{ - free_token = &Stack[0]; -} diff --git a/util/ego/cs/cs_stack.h b/util/ego/cs/cs_stack.h deleted file mode 100644 index cd43c6577..000000000 --- a/util/ego/cs/cs_stack.h +++ /dev/null @@ -1,18 +0,0 @@ -extern Push(); /* (token_p tkp) - * Push the token in tkp on the fake-stack. - */ - -extern Pop(); /* (token_p tkp; offset size) - * Pop a token of size bytes from the fake-stack - * into tkp. If such a token is not there - * we put a dummy in tkp and adjust the fake-stack. - */ - -extern Dup(); /* (line_p lnp) - * Reflect the changes made by the dup-instruction - * in lnp to the EM-stack into the fake-stack. - */ - -extern clr_stack(); /* () - * Clear the fake-stack. - */ diff --git a/util/ego/cs/cs_vnm.c b/util/ego/cs/cs_vnm.c deleted file mode 100644 index 0fbe05aa5..000000000 --- a/util/ego/cs/cs_vnm.c +++ /dev/null @@ -1,321 +0,0 @@ - -/* V A L U E N U M B E R I N G M E T H O D */ - -#include "../../../h/em_mnem.h" -#include "../share/types.h" -#include "../share/global.h" -#include "../share/debug.h" -#include "../share/aux.h" -#include "cs.h" -#include "cs_alloc.h" -#include "cs_aux.h" -#include "cs_entity.h" -#include "cs_avail.h" -#include "cs_stack.h" -#include "cs_kill.h" -#include "cs_partit.h" -#include "cs_getent.h" - -STATIC push_entity(enp, lfirst) - entity_p enp; - line_p lfirst; -{ - /* Build token and Push it. */ - - struct token tk; - - tk.tk_vn = enp->en_vn; - tk.tk_size = enp->en_size; - tk.tk_lfirst = lfirst; - Push(&tk); -} - -STATIC put_expensive_load(bp, lnp, lfirst, enp) - bblock_p bp; - line_p lnp, lfirst; - entity_p enp; -{ - struct avail av; - occur_p ocp; - - av.av_instr = INSTR(lnp); - av.av_size = enp->en_size; - av.av_operand = enp->en_vn; - - ocp = newoccur(lfirst, lnp, bp); - - av_enter(&av, ocp, EXPENSIVE_LOAD); -} - -STATIC put_aar(bp, lnp, lfirst, enp) - bblock_p bp; - line_p lnp, lfirst; - entity_p enp; -{ - /* Enp points to an ENARRELEM. We do as if its address was computed. */ - - struct avail av; - occur_p ocp; - - assert(enp->en_kind == ENARRELEM); - av.av_instr = op_aar; - av.av_size = ps; - av.av_ofirst = enp->en_arbase; - av.av_osecond = enp->en_index; - av.av_othird = enp->en_adesc; - - ocp = newoccur(lfirst, lnp, bp); - - av_enter(&av, ocp, TERNAIR_OP); -} - -STATIC push_avail(avp, lfirst) - avail_p avp; - line_p lfirst; -{ - struct token tk; - - tk.tk_vn = avp->av_result; - tk.tk_size = avp->av_size; - tk.tk_lfirst = lfirst; - Push(&tk); -} - -STATIC push_unair_op(bp, lnp, tkp1) - bblock_p bp; - line_p lnp; - token_p tkp1; -{ - struct avail av; - occur_p ocp; - - av.av_instr = INSTR(lnp); - av.av_size = avsize(lnp); - av.av_operand = tkp1->tk_vn; - - ocp = newoccur(tkp1->tk_lfirst, lnp, bp); - - push_avail(av_enter(&av, ocp, UNAIR_OP), tkp1->tk_lfirst); -} - -STATIC push_binair_op(bp, lnp, tkp1, tkp2) - bblock_p bp; - line_p lnp; - token_p tkp1, tkp2; -{ - struct avail av; - occur_p ocp; - - av.av_instr = INSTR(lnp); - av.av_size = avsize(lnp); - av.av_oleft = tkp1->tk_vn; - av.av_oright = tkp2->tk_vn; - - ocp = newoccur(tkp1->tk_lfirst, lnp, bp); - - push_avail(av_enter(&av, ocp, BINAIR_OP), tkp1->tk_lfirst); -} - -STATIC push_ternair_op(bp, lnp, tkp1, tkp2, tkp3) - bblock_p bp; - line_p lnp; - token_p tkp1, tkp2, tkp3; -{ - struct avail av; - occur_p ocp; - - av.av_instr = INSTR(lnp); - av.av_size = avsize(lnp); - av.av_ofirst = tkp1->tk_vn; - av.av_osecond = tkp2->tk_vn; - av.av_othird = tkp3->tk_vn; - - ocp = newoccur(tkp1->tk_lfirst, lnp, bp); - - push_avail(av_enter(&av, ocp, TERNAIR_OP), tkp1->tk_lfirst); -} - -STATIC fiddle_stack(lnp) - line_p lnp; -{ - /* The instruction in lnp does something to the valuenumber-stack. */ - - struct token dummy; - offset size; - - /* Partly initialize dummy. */ - dummy.tk_lfirst = lnp; - - switch (INSTR(lnp)) { - default: - assert(FALSE); - break; - case op_lor: - dummy.tk_vn = newvalnum(); dummy.tk_size = ps; - Push(&dummy); - break; - case op_asp: - if ((size = off_set(lnp)) > 0) { - Pop(&dummy, size); - } else { - dummy.tk_vn = newvalnum(); - dummy.tk_size = size; - Push(&dummy); - } - break; - case op_dup: - Dup(lnp); - break; - case op_ass: - case op_dus: - case op_exg: - case op_los: - /* Don't waste effort. */ - clr_stack(); - break; - case op_sig: - Pop(&dummy, (offset) ps); - break; - case op_lfr: - dummy.tk_vn = newvalnum(); - dummy.tk_size = off_set(lnp); - Push(&dummy); - break; - } -} - -STATIC proc_p find_proc(vn) - valnum vn; -{ - /* Find the procedure-identifier with valuenumber vn. */ - - entity_p enp; - - enp = find_entity(vn); - - if (enp != (entity_p) 0 && enp->en_kind == ENPROC) - return enp->en_pro; - - return (proc_p) 0; -} - -STATIC side_effects(lnp) - line_p lnp; -{ - /* Lnp contains a cai or cal instruction. We try to find the callee - * and see what side-effects it has. - */ - struct token tk; - proc_p pp; - - if (INSTR(lnp) == op_cai) { - Pop(&tk, (offset) ps); - pp = find_proc(tk.tk_vn); - } else { - assert(INSTR(lnp) == op_cal); - pp = PROC(lnp); - } - if (pp != (proc_p) 0) { - kill_call(pp); - } else { - kill_much(); - } -} - -hopeless(instr) - int instr; -{ - /* The effect of `instr' is too difficult to - * compute. We assume worst case behaviour. - */ - switch (instr) { - default: - assert(FALSE); - break; - case op_mon: - case op_str: - /* We can't even trust "static" entities. */ - kill_all(); - clr_stack(); - break; - case op_blm: - case op_bls: - case op_sts: - kill_much(); - clr_stack(); - break; - } -} - -vnm(bp) - bblock_p bp; -{ - register line_p lnp; - register entity_p rep; - line_p lfirst; - struct token tk, tk1, tk2, tk3; - - for (lnp = bp->b_start; lnp != (line_p) 0; lnp = lnp->l_next) { - - rep = getentity(lnp, &lfirst); - switch (instrgroup(lnp)) { - case SIMPLE_LOAD: - push_entity(rep, lfirst); - break; - case LOAD_ARRAY: - put_aar(bp, lnp, lfirst, rep); - /* Fall through ... */ - case EXPENSIVE_LOAD: - push_entity(rep, lfirst); - put_expensive_load(bp, lnp, lfirst, rep); - break; - case STORE_DIRECT: - kill_direct(rep); - Pop(&tk, rep->en_size); - rep->en_vn = tk.tk_vn; - break; - case STORE_ARRAY: - put_aar(bp, lnp, lfirst, rep); - /* Fall through ... */ - case STORE_INDIR: - kill_indir(rep); - Pop(&tk, rep->en_size); - rep->en_vn = tk.tk_vn; - break; - case UNAIR_OP: - Pop(&tk1, op11size(lnp)); - push_unair_op(bp, lnp, &tk1); - break; - case BINAIR_OP: - Pop(&tk2, op22size(lnp)); - Pop(&tk1, op12size(lnp)); - push_binair_op(bp, lnp, &tk1, &tk2); - break; - case TERNAIR_OP: - Pop(&tk3, op33size(lnp)); - Pop(&tk2, op23size(lnp)); - Pop(&tk1, op13size(lnp)); - push_ternair_op(bp, lnp, &tk1, &tk2, &tk3); - break; - case KILL_ENTITY: - kill_direct(rep); - break; - case SIDE_EFFECTS: - side_effects(lnp); - break; - case FIDDLE_STACK: - fiddle_stack(lnp); - break; - case IGNORE: - break; - case HOPELESS: - hopeless(INSTR(lnp)); - break; - case BBLOCK_END: - break; - default: - assert(FALSE); - break; - } - } -} diff --git a/util/ego/cs/cs_vnm.h b/util/ego/cs/cs_vnm.h deleted file mode 100644 index cf4be2835..000000000 --- a/util/ego/cs/cs_vnm.h +++ /dev/null @@ -1,4 +0,0 @@ -extern vnm(); /* (bblock_p bp) - * Performs the valuenumbering algorithm on the basic - * block in bp. - */ diff --git a/util/ego/descr/descr.sed b/util/ego/descr/descr.sed deleted file mode 100644 index 993a63d84..000000000 --- a/util/ego/descr/descr.sed +++ /dev/null @@ -1,22 +0,0 @@ -s/.*:// -s/(// -s/)// -s/,/ / -s/cases// -s/case// -s/sizes// -s/size// -s/\-\>// -s/pointer/2/g -s/general/0/g -s/fitbyte/1/ -s/default/0/ -s/in_0_63/2/ -s/in_0_8/3/ -s/no/0/g -s/yes/1/g -s/ //g -s/ +/ /g -s/^ // -s/ $// -/^$/d diff --git a/util/ego/descr/i86.descr b/util/ego/descr/i86.descr deleted file mode 100644 index 4dc7545cd..000000000 --- a/util/ego/descr/i86.descr +++ /dev/null @@ -1,15 +0,0 @@ - -wordsize: 2 -pointersize: 2 -%%UD -access costs of global variables: - (1 size) - default -> (4,2) -access costs of local variables: - (1 size) - default -> (4,2) -%%SR -overflow harmful?: no -array bound harmful?: no -%%SP -global stack pollution allowed?: yes diff --git a/util/ego/descr/m68k2.descr b/util/ego/descr/m68k2.descr deleted file mode 100644 index 893312feb..000000000 --- a/util/ego/descr/m68k2.descr +++ /dev/null @@ -1,103 +0,0 @@ -wordsize: 2 -pointersize: 4 -%%RA -general registers: 5 -address registers: 4 -floating point registers: 0 - -register score parameters: - local variable: - (2 cases) - pointer,pointer - (1 size) - default -> (6,3) - general,general - (1 size) - default -> (4,2) - address of local variable: - (2 cases) - pointer,pointer - (1 size) - default -> (0,0) - general,pointer - (1 size) - default -> (2,2) - constant: - (2 sizes) - in_0_8 -> (0,0) - default -> (2,2) - double constant: - (1 size) - default -> (-1,-1) - address of global variable: - (1 size) - default -> (4,4) - address of procedure: - (1 size) - default -> (2,4) - -opening cost parameters: - local variable: - (2 cases) - pointer - (1 size) - default -> (6,4) - general - (1 size) - default -> (8,4) - address of local variable: - (2 cases) - pointer - (1 size) - default -> (4,2) - general - (1 size) - general -> (4,2) - constant: - (1 size) - default -> (4,4) - double constant: - (1 size) - default -> (1000,1000) - address of global variable: - (1 size) - default -> (6,6) - address of procedure: - (1 size) - default -> (6,6) - -register save costs: - (11 cases) - 0 -> (0,0) - 1 -> (12,4) - 2 -> (24,8) - 3 -> (34,8) - 4 -> (42,8) - 5 -> (50,8) - 6 -> (58,8) - 7 -> (66,8) - 8 -> (84,8) - 9 -> (92,8) - 0 -> (0,0) -%%UD -access costs of global variables: - (1 size) - default -> (7,4) -access costs of local variables: - (1 size) - default -> (4,2) -%%SR -overflow harmful?: no -array bound harmful?: no -%%CS -#include "../../../h/em_mnem.h" -first time then space: -addressing modes: op_adp op_lof op_ldf op_loi op_dch op_lpb -1 - op_adp op_lof op_ldf op_loi op_dch op_lpb -1 -cheap operations: -1 -1 -lexical tresholds: 1 1 -indirection limit: 8 -do sli if index?: yes yes -forbidden operators: -1 -1 -%%SP -global stack pollution allowed?: no diff --git a/util/ego/descr/makedescrs b/util/ego/descr/makedescrs deleted file mode 100755 index 85d8fcf9b..000000000 --- a/util/ego/descr/makedescrs +++ /dev/null @@ -1,5 +0,0 @@ -for i in *.descr -do -m=`basename $i .descr` -../../../lib/cpp -P -I../../../h $i | sed -f descr.sed > ../../../lib/ego/${m}descr -done diff --git a/util/ego/descr/pdp.descr b/util/ego/descr/pdp.descr deleted file mode 100644 index c8bd382d5..000000000 --- a/util/ego/descr/pdp.descr +++ /dev/null @@ -1,96 +0,0 @@ -wordsize: 2 -pointersize: 2 -%%RA -general registers: 2 -address registers: 0 -floating point registers: 0 - -register score parameters: - local variable: - (2 cases) - pointer,general - (1 size) - default -> (6,3) - general,general - (1 size) - default -> (4,2) - address of local variable: - (2 cases) - pointer,general - (1 size) - default -> (0,0) - general,general - (1 size) - default -> (2,2) - constant: - (1 sizes) - default -> (2,2) - double constant: - (1 size) - default -> (-1,-1) - address of global variable: - (1 size) - default -> (4,2) - address of procedure: - (1 size) - default -> (2,2) - -opening cost parameters: - local variable: - (2 cases) - pointer - (1 size) - default -> (6,4) - general - (1 size) - default -> (6,4) - address of local variable: - (2 cases) - pointer - (1 size) - default -> (10,6) - general - (1 size) - general -> (10,6) - constant: - (1 size) - default -> (4,4) - double constant: - (1 size) - default -> (1000,1000) - address of global variable: - (1 size) - default -> (6,4) - address of procedure: - (1 size) - default -> (6,4) - -register save costs: - (4 cases) - 0 -> (0,0) - 1 -> (12,0) - 2 -> (24,0) - 0 -> (0,0) -%%UD -access costs of global variables: - (1 size) - default -> (4,2) -access costs of local variables: - (1 size) - default -> (4,2) -%%SR -overflow harmful?: no -array bound harmful?: no -%%CS -#include "../../../h/em_mnem.h" -first time then space: -addressing modes: op_adp op_lof op_ldf op_loi op_dch op_lpb -1 - op_adp op_lof op_ldf op_loi op_dch op_lpb -1 -cheap operations: op_cii op_cui op_cfi op_ciu op_cff op_cuu op_cif -1 - op_cii op_cui op_cfi op_ciu op_cff op_cuu op_cif -1 -lexical tresholds: 1 1 -indirection limit: 8 -do sli if index?: yes yes -forbidden operators: -1 -1 -%%SP -global stack pollution allowed?: no diff --git a/util/ego/descr/vax2.descr b/util/ego/descr/vax2.descr deleted file mode 100644 index 8dfc9ace3..000000000 --- a/util/ego/descr/vax2.descr +++ /dev/null @@ -1,117 +0,0 @@ -wordsize: 2 -pointersize: 4 -%%RA -general registers: 3 -address registers: 4 -floating point registers: 0 - -register score parameters: - local variable: - (2 cases) - pointer,pointer - (2 sizes) - fitbyte -> (5,2) - default -> (4,3) - general,general - (2 sizes) - fitbyte -> (3,1) - default -> (2,2) - address of local variable: - (2 cases) - pointer,pointer - (2 sizes) - fitbyte -> (0,1) - default -> (0,2) - general,pointer - (2 sizes) - fitbyte -> (0,1) - default -> (0,2) - constant: - (3 sizes) - in_0_63 -> (0,0) - fitbyte -> (0,1) - default -> (1,2) - double constant: - (1 size) - default -> (-1,-1) - address of global variable: - (1 size) - default -> (2,4) - address of procedure: - (1 size) - default -> (2,4) - -opening cost parameters: - local variable: - (2 cases) - pointer - (2 sizes) - fitbyte -> (10,4) - default -> (9,5) - general - (2 sizes) - fitbyte -> (8,4) - default -> (7,5) - address of local variable: - (2 cases) - pointer - (2 sizes) - fitbyte -> (0,4) - default -> (0,5) - general - (2 sizes) - fitbyte -> (0,4) - general -> (0,5) - constant: - (3 sizes) - in_0_63 -> (4,2) - fitbyte -> (5,3) - default -> (6,4) - double constant: - (1 size) - default -> (1000,1000) - address of global variable: - (1 size) - default -> (6,7) - address of procedure: - (1 size) - default -> (6,7) - -register save costs: - (9 cases) - 0 -> (0,0) - 1 -> (1,0) - 2 -> (2,0) - 3 -> (3,0) - 4 -> (4,0) - 5 -> (5,0) - 6 -> (6,0) - 7 -> (7,0) - 0 -> (0,0) -%%UD -access costs of global variables: - (1 size) - default -> (7,4) -access costs of local variables: - (2 sizes) - fitbyte -> (3,1) - default -> (2,2) -%%SR -overflow harmful?: no -array bound harmful?: no - -%%CS -#include "../../../h/em_mnem.h" -first time then space: -addressing modes: op_adp op_lof op_ldf op_loi op_dch op_lpb -1 - op_adp op_lof op_ldf op_loi op_dch op_lpb -1 -cheap operations: op_cii op_cui op_cfi op_ciu op_cff op_cuu op_cif - op_cmi op_cmf op_cmu op_cms op_cmp -1 - op_cii op_cui op_cfi op_ciu op_cff op_cuu op_cif - op_cmi op_cmf op_cmu op_cms op_cmp -1 -lexical tresholds: 1 1 -indirection limit: 8 -do sli if index?: no no -forbidden operators: -1 -1 -%%SP -global stack pollution allowed?: yes diff --git a/util/ego/descr/vax4.descr b/util/ego/descr/vax4.descr deleted file mode 100644 index 524c5f873..000000000 --- a/util/ego/descr/vax4.descr +++ /dev/null @@ -1,114 +0,0 @@ -wordsize: 4 -pointersize: 4 -%%RA -general registers: 8 -address registers: 0 -floating point registers: 0 - -register score parameters: - local variable: - (2 cases) - pointer,general - (2 sizes) - fitbyte -> (5,2) - default -> (4,3) - general,general - (2 sizes) - fitbyte -> (3,1) - default -> (2,2) - address of local variable: - (2 cases) - pointer,general - (2 sizes) - fitbyte -> (0,1) - default -> (0,2) - general,general - (2 sizes) - fitbyte -> (0,1) - default -> (0,2) - constant: - (3 sizes) - in_0_63 -> (0,0) - fitbyte -> (0,1) - default -> (1,2) - double constant: - (1 size) - default -> (-1,-1) - address of global variable: - (1 size) - default -> (2,4) - address of procedure: - (1 size) - default -> (2,4) - -opening cost parameters: - local variable: - (2 cases) - pointer - (2 sizes) - fitbyte -> (10,4) - default -> (9,5) - general - (2 sizes) - fitbyte -> (8,4) - default -> (7,5) - address of local variable: - (2 cases) - pointer - (2 sizes) - fitbyte -> (0,4) - default -> (0,5) - general - (2 sizes) - fitbyte -> (0,4) - general -> (0,5) - constant: - (3 sizes) - in_0_63 -> (4,2) - fitbyte -> (5,3) - default -> (6,4) - double constant: - (1 size) - default -> (1000,1000) - address of global variable: - (1 size) - default -> (6,7) - address of procedure: - (1 size) - default -> (6,7) - -register save costs: - (8 cases) - 0 -> (0,0) - 1 -> (3,1) - 2 -> (7,3) - 3 -> (20,4) - 4 -> (20,4) - 5 -> (20,4) - 6 -> (20,4) - 0 -> (0,0) -%%UD -access costs of global variables: - (1 size) - default -> (7,4) -access costs of local variables: - (2 sizes) - fitbyte -> (3,1) - default -> (2,2) -%%SR -overflow harmful?: no -array bound harmful?: no - -%%CS -#include "../../../h/em_mnem.h" -first time then space: -addressing modes: op_adp op_lof op_ldf op_loi op_dch op_lpb -1 - op_adp op_lof op_ldf op_loi op_dch op_lpb -1 -cheap operations: op_cii op_cui op_cfi op_ciu op_cff op_cuu op_cif -1 - op_cii op_cui op_cfi op_ciu op_cff op_cuu op_cif -1 -lexical tresholds: 1 1 -indirection limit: 8 -do sli if index?: no no -forbidden operators: -1 -1 -%%SP -global stack pollution allowed?: no diff --git a/util/ego/em_ego/em_ego b/util/ego/em_ego/em_ego deleted file mode 100755 index 0db2b0453..000000000 --- a/util/ego/em_ego/em_ego +++ /dev/null @@ -1,68 +0,0 @@ -TMP=/usr/tmp/ego -DDUMP=$TMP.dd.$$ -PDUMP=$TMP.pd.$$ -PHASES='' -FLAGS='' - - -while : -do - case $# in - 0) break ;; - esac - A="$1" - shift - case $A in - *.m|*.ma) ICARG="$ICARG $A"; continue;; - -P) OPT="$1"; shift; continue;; - -IL) PHASES="$PHASES il cf " ; continue;; - -CS) PHASES="$PHASES cs " ; continue;; - -SR) PHASES="$PHASES sr " ; continue;; - -UD) PHASES="$PHASES ud " ; continue;; - -LV) PHASES="$PHASES lv " ; continue;; - -RA) PHASES="$PHASES ra " ; continue;; - -SP) PHASES="$PHASES sp " ; continue;; - -BO) PHASES="$PHASES bo " ; continue;; - -CJ) PHASES="$PHASES cj " ; continue;; - -*) FLAGS="$FLAGS $A"; continue;; - esac -done -if test "$PHASES" -then : -else PHASES='cj bo sp ' -fi -PASSES="ic cf $PHASES ca" -OUTFILES="$PDUMP $DDUMP" -c=1 -if test "$ICARG" -then : -else -exit 0 -fi -for i in $PASSES -do INFILES=$OUTFILES - OUTFILES="$TMP.p.$c.$$ $TMP.d.$c.$$ $TMP.l.$c.$$ $TMP.b.$c.$$" - trap "rm -f $INFILES $OUTFILES $PDUMP $DDUMP; exit 1" 1 2 15 - case $i in - ic) if $OPT/ic $INFILES - - $OUTFILES $ICARG - then : - else exit 1 - fi ;; - ca) if $OPT/ca $INFILES $PDUMP $DDUMP - - - then - rm -f $INFILES $PDUMP $DDUMP - else - rm -f $INFILES $PDUMP $DDUMP - exit 1 - fi;; - *) if $OPT/$i $INFILES $OUTFILES $FLAGS - then - rm -f $INFILES - else - rm -f $INFILES - exit 1 - fi ;; - esac - c=`expr $c + 1` -done -exit 0 diff --git a/util/ego/ic/Makefile b/util/ego/ic/Makefile deleted file mode 100644 index cf4fd7980..000000000 --- a/util/ego/ic/Makefile +++ /dev/null @@ -1,100 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -ic.c ic_aux.c ic_lib.c ic_lookup.c ic_io.c - -OFILES=\ -ic.o ic_aux.o ic_lookup.o ic_io.o ic_lib.o - -HFILES=\ -ic.h ic_aux.h ic_lib.h ic_lookup.h ic_io.h - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/put.o $(SHR)/alloc.o $(SHR)/global.o $(SHR)/debug.o \ -$(SHR)/files.o $(SHR)/map.o $(SHR)/lset.o $(SHR)/cset.o $(SHR)/aux.o - -SHARE_MFILES=\ -$(SHR)/put.m $(SHR)/alloc.m $(SHR)/global.m $(SHR)/debug.m \ -$(SHR)/files.m $(SHR)/map.m $(SHR)/lset.m $(SHR)/cset.m $(SHR)/aux.m - -ic: $(OFILES) - $(CC) -o ic $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -ic_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o ic -.c $(LDFLAGS) ic.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO -ic.o: ../../../h/em_flag.h -ic.o: ../../../h/em_mes.h -ic.o: ../../../h/em_pseu.h -ic.o: ../../../h/em_spec.h -ic.o: ../share/alloc.h -ic.o: ../share/aux.h -ic.o: ../share/debug.h -ic.o: ../share/def.h -ic.o: ../share/files.h -ic.o: ../share/global.h -ic.o: ../share/map.h -ic.o: ../share/put.h -ic.o: ../share/types.h -ic.o: ic.h -ic.o: ic_aux.h -ic.o: ic_io.h -ic.o: ic_lib.h -ic.o: ic_lookup.h -ic_aux.o: ../../../h/em_mnem.h -ic_aux.o: ../../../h/em_pseu.h -ic_aux.o: ../../../h/em_spec.h -ic_aux.o: ../share/alloc.h -ic_aux.o: ../share/aux.h -ic_aux.o: ../share/debug.h -ic_aux.o: ../share/def.h -ic_aux.o: ../share/global.h -ic_aux.o: ../share/types.h -ic_aux.o: ic.h -ic_aux.o: ic_aux.h -ic_aux.o: ic_io.h -ic_aux.o: ic_lookup.h -ic_io.o: ../../../h/em_pseu.h -ic_io.o: ../../../h/em_spec.h -ic_io.o: ../share/alloc.h -ic_io.o: ../share/debug.h -ic_io.o: ../share/types.h -ic_io.o: ic.h -ic_io.o: ic_io.h -ic_io.o: ic_lookup.h -ic_lib.o: ../../../h/em_mes.h -ic_lib.o: ../../../h/em_pseu.h -ic_lib.o: ../../../h/em_spec.h -ic_lib.o: ../share/debug.h -ic_lib.o: ../share/files.h -ic_lib.o: ../share/global.h -ic_lib.o: ../share/types.h -ic_lib.o: ic.h -ic_lib.o: ic_io.h -ic_lib.o: ic_lib.h -ic_lib.o: ic_lookup.h -ic_lookup.o: ../../../h/em_spec.h -ic_lookup.o: ../share/alloc.h -ic_lookup.o: ../share/debug.h -ic_lookup.o: ../share/map.h -ic_lookup.o: ../share/types.h -ic_lookup.o: ic.h -ic_lookup.o: ic_lookup.h diff --git a/util/ego/ic/ic.c b/util/ego/ic/ic.c deleted file mode 100644 index 9f63771b0..000000000 --- a/util/ego/ic/ic.c +++ /dev/null @@ -1,520 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * I C . C - */ - -#include -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/def.h" -#include "../share/map.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_flag.h" -#include "../../../h/em_mes.h" -#include "ic.h" -#include "ic_lookup.h" -#include "ic_aux.h" -#include "ic_io.h" -#include "ic_lib.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/files.h" -#include "../share/put.h" -#include "../share/aux.h" - - -/* Global variables */ - - -dblock_p db; -dblock_p curhol = (dblock_p) 0; /* hol block in current scope */ -dblock_p ldblock; /* last dblock */ -proc_p lproc; /* last proc */ -short tabval; /* used by table1, table2 and table3 */ -offset tabval2; -char string[IDL+1]; -line_p firstline; /* first line of current procedure */ -line_p lastline; /* last line read */ -int labelcount; /* # labels in current procedure */ -short fragm_type = DUNKNOWN; /* fragm. type: DCON, DROM or DUNKNOWN */ -short fragm_nr = 0; /* fragment number */ -obj_id lastoid = 0; -proc_id lastpid = 0; -dblock_id lastdid = 0; -lab_id lastlid = 0; - -offset mespar = UNKNOWN_SIZE; - /* argumument of ps_par message of current procedure */ - - -extern process_lines(); -extern int readline(); -extern line_p readoperand(); -extern line_p inpseudo(); - - -main(argc,argv) - int argc; - char *argv[]; -{ - /* The input files must be legal EM Compact - * Assembly Language files, as produced by the EM Peephole - * Optimizer. - * Their file names are passed as arguments. - * The output consists of the files: - * - lfile: the EM code in Intermediate Code format - * - dfile: the data block table file - * - pfile: the proc table file - * - pdump: the names of all procedures - * - ddump: the names of all data blocks - */ - - FILE *lfile, *dfile, *pfile, *pdump, *ddump; - - lfile = openfile(lname2,"w"); - pdump = openfile(argv[1],"w"); - ddump = openfile(argv[2],"w"); - while (next_file(argc,argv) != NULL) { - /* Read all EM input files, process the code - * and concatenate all output. - */ - process_lines(lfile); - dump_procnames(prochash,NPROCHASH,pdump); - dump_dblocknames(symhash,NSYMHASH,ddump); - /* Save the names of all procedures that were - * first come accross in this file. - */ - cleanprocs(prochash,NPROCHASH,PF_EXTERNAL); - cleandblocks(symhash,NSYMHASH,DF_EXTERNAL); - /* Make all procedure names that were internal - * in this input file invisible. - */ - } - fclose(lfile); - fclose(pdump); - fclose(ddump); - - - /* remove the remainder of the hashing tables */ - cleanprocs(prochash,NPROCHASH,0); - cleandblocks(symhash,NSYMHASH,0); - /* Now write the datablock table and the proctable */ - dfile = openfile(dname2,"w"); - putdtable(fdblock, dfile); - pfile = openfile(pname2,"w"); - putptable(fproc, pfile,FALSE); -} - - - -/* Value returned by readline */ - -#define NORMAL 0 -#define WITH_OPERAND 1 -#define EOFILE 2 -#define PRO_INSTR 3 -#define END_INSTR 4 -#define DELETED_INSTR 5 - - -STATIC add_end() -{ - /* Add an end-pseudo to the current instruction list */ - - lastline->l_next = newline(OPNO); - lastline = lastline->l_next; - lastline->l_instr = ps_end; -} - - -process_lines(fout) - FILE *fout; -{ - line_p lnp; - short instr; - bool eof; - - /* Read and process the code contained in the current file, - * on a per procedure basis. - * On the fly, fragments are formed. Recall that two - * successive CON pseudos are allocated consecutively - * in a single fragment, unless these CON pseudos are - * separated in the assembly language program by one - * of: ROM, BSS, HOL and END (and of course EndOfFile). - * The same is true for ROM pseudos. - * We keep track of a fragment type (DROM after a ROM - * pseudo, DCON after a CON and DUNKNOWN after a HOL, - * BSS, END or EndOfFile) and a fragment number (which - * is incremented every time we enter a new fragment). - * Every data block is assigned such a number - * when we come accross its defining occurrence. - */ - - eof = FALSE; - firstline = (line_p) 0; - lastline = (line_p) 0; - while (!eof) { - linecount++; /* for error messages */ - switch(readline(&instr, &lnp)) { - /* read one line, see what kind it is */ - case WITH_OPERAND: - /* instruction with operand, e.g. LOL 10 */ - lnp = readoperand(instr); - lnp->l_instr = instr; - /* Fall through! */ - case NORMAL: - VL(lnp); - if (lastline != (line_p) 0) { - lastline->l_next = lnp; - } - lastline = lnp; - break; - case EOFILE: - eof = TRUE; - fragm_type = DUNKNOWN; - if (firstline != (line_p) 0) { - add_end(); - putlines(firstline,fout); - firstline = (line_p) 0; - } - break; - case PRO_INSTR: - VL(lnp); - labelcount = 0; - if (firstline != lnp) { - /* If PRO is not the first - * instruction: - */ - add_end(); - putlines(firstline,fout); - firstline = lnp; - } - lastline = lnp; - break; - case END_INSTR: - curproc->p_nrformals = mespar; - mespar = UNKNOWN_SIZE; - assert(lastline != (line_p) 0); - lastline->l_next = lnp; - putlines(firstline,fout); - /* write and delete code */ - firstline = (line_p) 0; - lastline = (line_p) 0; - cleaninstrlabs(); - /* scope of instruction labels ends here, - * so forget about them. - */ - fragm_type = DUNKNOWN; - break; - case DELETED_INSTR: - /* EXP, INA etc. are deleted */ - break; - default: - error("illegal readline"); - } - } -} - - - -int readline(instr_out, lnp_out) - short *instr_out; - line_p *lnp_out; -{ - register line_p lnp; - short n; - - /* Read one line. If it is a normal EM instruction without - * operand, we can allocate a line struct for it here. - * If so, return a pointer to it via lnp_out, else just - * return the instruction code via instr_out. - */ - - VA((short *) instr_out); - VA((short *) lnp_out); - switch(table1()) { - /* table1 sets string, tabval or tabval2 and - * returns an indication of what was read. - */ - case ATEOF: - return EOFILE; - case INST: - *instr_out = tabval; /* instruction code */ - return WITH_OPERAND; - case DLBX: - /* data label defining occurrence, precedes - * a data block. - */ - db = block_of_lab(string); - /* global variable, used by inpseudo */ - lnp = newline(OPSHORT); - SHORT(lnp) = (short) db->d_id; - lnp->l_instr = ps_sym; - *lnp_out = lnp; - if (firstline == (line_p) 0) { - firstline = lnp; - /* only a pseudo (e.g. PRO) or data label - * can be the first instruction. - */ - } - return NORMAL; - case ILBX: - /* instruction label defining occurrence */ - labelcount++; - lnp = newline(OPINSTRLAB); - lnp->l_instr = op_lab; - INSTRLAB(lnp) = instr_lab(tabval); - *lnp_out = lnp; - return NORMAL; - case PSEU: - n = tabval; - lnp = inpseudo(n); /* read a pseudo */ - if (lnp == (line_p) 0) return DELETED_INSTR; - *lnp_out = lnp; - lnp->l_instr = n; - if (firstline == (line_p) 0) { - firstline = lnp; - /* only a pseudo (e.g. PRO) or data label - * can be the first instruction. - */ - } - if (n == ps_end) return END_INSTR; - if (n == ps_pro) return PRO_INSTR; - return NORMAL; - } - /* NOTREACHED */ -} - - -line_p readoperand(instr) - short instr; -{ - /* Read the operand of the given instruction. - * Create a line struct and return a pointer to it. - */ - - - register line_p lnp; - short flag; - - VI(instr); - flag = em_flag[ instr - sp_fmnem] & EM_PAR; - if (flag == PAR_NO) { - return (newline(OPNO)); - } - switch(table2()) { - case sp_cend: - return(newline(OPNO)); - case CSTX1: - /* constant */ - /* If the instruction has the address - * of an external variable as argument, - * the constant must be regarded as an - * offset in the current hol block, - * so an object must be created. - * Similarly, the instruction may have - * an instruction label as argument. - */ - switch(flag) { - case PAR_G: - lnp = newline(OPOBJECT); - OBJ(lnp) = - object((char *) 0,(offset) tabval, - opr_size(instr)); - break; - case PAR_B: - lnp = newline(OPINSTRLAB); - INSTRLAB(lnp) = instr_lab(tabval); - break; - default: - lnp = newline(OPSHORT); - SHORT(lnp) = tabval; - break; - } - break; -#ifdef LONGOFF - case CSTX2: - /* double constant */ - lnp = newline(OPOFFSET); - OFFSET(lnp) = tabval2; - break; -#endif - case ILBX: - /* applied occurrence instruction label */ - lnp = newline(OPINSTRLAB); - INSTRLAB(lnp) = instr_lab(tabval); - break; - case DLBX: - /* applied occurrence data label */ - lnp = newline(OPOBJECT); - OBJ(lnp) = object(string, (offset) 0, - opr_size(instr) ); - break; - case VALX1: - lnp = newline(OPOBJECT); - OBJ(lnp) = object(string, (offset) tabval, - opr_size(instr) ); - break; -#ifdef LONGOFF - case VALX2: - lnp = newline(OPOBJECT); - OBJ(lnp) = object(string,tabval2, - opr_size(instr) ); - break; -#endif - case sp_pnam: - lnp = newline(OPPROC); - PROC(lnp) = proclookup(string,OCCURRING); - VP(PROC(lnp)); - break; - default: - assert(FALSE); - } - return lnp; -} - - - -line_p inpseudo(n) - short n; -{ - int m; - line_p lnp; - byte pseu; - short nlast; - - /* Read the (remainder of) a pseudo instruction, the instruction - * code of which is n. The END pseudo may be deleted (return 0). - * The pseudos INA, EXA, INP and EXP (visibility pseudos) must - * also be deleted, although the effects they have on the - * visibility of global names and procedure names must first - * be recorded in the datablock or procedure table. - */ - - - switch(n) { - case ps_hol: - case ps_bss: - case ps_rom: - case ps_con: - if (lastline == (line_p) 0 || !is_datalabel(lastline)) { - if (n == ps_hol) { - /* A HOL need not be preceded - * by a label. - */ - curhol = db = block_of_lab((char *) 0); - } else { - assert(lastline != (line_p) 0); - nlast = INSTR(lastline); - if (n == nlast && - (n == ps_rom || n == ps_con)) { - /* Two successive roms/cons are - * combined into one data block - * if the second is not preceded by - * a data label. - */ - lnp = arglist(0); - pseu = (byte) (n == ps_rom?DROM:DCON); - combine(db,lastline,lnp,pseu); - oldline(lnp); - return (line_p) 0; - } else { - error("datablock without label"); - } - } - } - VD(db); - m = (n == ps_hol || n == ps_bss ? 3 : 0); - lnp = arglist(m); - /* Read the arguments, 3 for hol or bss and a list - * of undetermined length for rom and con. - */ - dblockdef(db,n,lnp); - /* Fill in d_pseudo, d_size and d_values fields of db */ - if (fragm_type != db->d_pseudo & BMASK) { - /* Keep track of fragment numbers, - * enter a new fragment. - */ - fragm_nr++; - switch(db->d_pseudo) { - case DCON: - case DROM: - fragm_type = db->d_pseudo; - break; - default: - fragm_type = DUNKNOWN; - break; - } - } - db->d_fragmnr = fragm_nr; - return lnp; - case ps_ina: - getsym(DEFINING); - /* Read and lookup a symbol. As this must be - * the first occurrence of the symbol and we - * say it's a defining occurrence, getsym will - * automatically make it internal (according to - * the EM visibility rules). - * The result (a dblock pointer) is voided. - */ - return (line_p) 0; - case ps_inp: - getproc(DEFINING); /* same idea */ - return (line_p) 0; - case ps_exa: - getsym(OCCURRING); - return (line_p) 0; - case ps_exp: - getproc(OCCURRING); - return (line_p) 0; - case ps_pro: - curproc = getproc(DEFINING); - /* This is a real defining occurrence of a proc */ - curproc->p_localbytes = get_off(); - curproc->p_flags1 |= PF_BODYSEEN; - /* Record the fact that we came accross - * the body of this procedure. - */ - lnp = newline(OPPROC); - PROC(lnp) = curproc; - lnp->l_instr = (byte) ps_pro; - return lnp; - case ps_end: - curproc->p_nrlabels = labelcount; - lnp = newline(OPNO); - get_off(); - /* Void # localbytes, which we already know - * from the PRO instruction. - */ - return lnp; - case ps_mes: - lnp = arglist(0); - switch((int) aoff(ARG(lnp),0)) { - case ms_err: - error("ms_err encountered"); - case ms_opt: - error("ms_opt encountered"); - case ms_emx: - ws = aoff(ARG(lnp),1); - ps = aoff(ARG(lnp),2); - break; - case ms_ext: - /* this message was already processed - * by the lib package - */ - case ms_src: - /* Don't bother about linecounts */ - oldline(lnp); - return (line_p) 0; - case ms_par: - mespar = aoff(ARG(lnp),1); - /* #bytes of parameters of current proc */ - break; - } - return lnp; - default: - assert(FALSE); - } - /* NOTREACHED */ -} diff --git a/util/ego/ic/ic.h b/util/ego/ic/ic.h deleted file mode 100644 index bca89f157..000000000 --- a/util/ego/ic/ic.h +++ /dev/null @@ -1,70 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * G L O B A L C O N S T A N T S & V A R I A B L E S - */ - - -/* Data structures for Intermediate Code generation */ - -typedef struct sym *sym_p; -typedef struct prc *prc_p; -typedef struct num *num_p; - - -struct sym { - sym_p sy_next; /* link */ - char sy_name[IDL]; /* name of the symbol */ - dblock_p sy_dblock; /* pointer to dblock struct */ -}; -struct prc { - prc_p pr_next; /* link */ - char pr_name[IDL]; /* name of the procedure */ - proc_p pr_proc; /* pointer tto proc struct */ -}; - - -struct num { - num_p n_next; /* link */ - unsigned n_number; /* EM repr. e.g. 120 in 'BRA *120' */ - lab_id n_labid; /* sequential integer repr. of IC */ -}; - - - -/* macros used by ic_lib.c and ic_io.c: */ - -#define ARCHIVE 0 -#define NO_ARCHIVE 1 - - -/* - * The next constants are close to sp_cend for fast switches - */ -#define INST 256 /* instruction: number in tabval */ -#define PSEU 257 /* pseudo: number in tabval */ -#define ILBX 258 /* label: number in tabval */ -#define DLBX 259 /* symbol: name in string[] */ -#define CSTX1 260 /* short constant: stored in tabval */ -#define CSTX2 261 /* offset: value in tabval2 */ -#define VALX1 262 /* symbol+short: in string[] and tabval */ -#define VALX2 263 /* symbol+offset: in string[] and tabval2 */ -#define ATEOF 264 /* bumped into end of file */ - -/* Global variables */ - -extern dblock_p db; -extern dblock_p curhol; /* hol block in current scope */ -extern dblock_p ldblock; /* last dblock processed so far */ -extern proc_p lproc; /* last proc processed so far */ -extern short tabval; /* used by table1, table2 and table3 */ -extern offset tabval2; -extern char string[]; -extern line_p lastline; /* last line read */ -extern int labelcount; /* # labels in current procedure */ -extern obj_id lastoid; /* last object identifier used */ -extern proc_id lastpid; /* last proc identifier used */ -extern lab_id lastlid; /* last label identifier used */ -extern dblock_id lastdid; /* last dblock identifier used */ - -extern byte em_flag[]; - diff --git a/util/ego/ic/ic_aux.c b/util/ego/ic/ic_aux.c deleted file mode 100644 index 211d05a39..000000000 --- a/util/ego/ic/ic_aux.c +++ /dev/null @@ -1,459 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * I C _ A U X . C - */ - - - -#include "../share/types.h" -#include "../share/global.h" -#include "../share/debug.h" -#include "../share/def.h" -#include "../share/aux.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_mnem.h" -#include "ic.h" -#include "ic_io.h" -#include "ic_lookup.h" -#include "../share/alloc.h" -#include "ic_aux.h" - - - -/* opr_size */ - -offset opr_size(instr) - short instr; -{ - switch(instr) { - case op_loe: - case op_ste: - case op_ine: - case op_dee: - case op_zre: - return (offset) ws; - case op_lde: - case op_sde: - return (offset) 2*ws; - case op_lae: - case op_fil: - return (offset) UNKNOWN_SIZE; - default: - error("illegal operand of opr_size: %d", instr); - } - /* NOTREACHED */ -} - - - -/* dblockdef */ - -STATIC offset argsize(arg) - arg_p arg; -{ - /* Compute the size (in bytes) that the given initializer - * will occupy. - */ - - offset s; - argb_p argb; - - switch(arg->a_type) { - case ARGOFF: - /* See if value fits in a short */ - if ((short) arg->a_a.a_offset == arg->a_a.a_offset) { - return ws; - } else { - return 2*ws; - } - case ARGINSTRLAB: - case ARGOBJECT: - case ARGPROC: - return ps; /* pointer size */ - case ARGSTRING: - /* strings are partitioned into pieces */ - s = 0; - for (argb = &arg->a_a.a_string; argb != (argb_p) 0; - argb = argb->ab_next) { - s += argb->ab_index; - } - return s; - case ARGICN: - case ARGUCN: - case ARGFCN: - return arg->a_a.a_con.ac_length; - default: - assert(FALSE); - } - /* NOTREACHED */ -} - - -STATIC offset blocksize(pseudo,args) - byte pseudo; - arg_p args; -{ - /* Determine the number of bytes of a datablock */ - - arg_p arg; - offset sum; - - switch(pseudo) { - case DHOL: - case DBSS: - if (args->a_type != ARGOFF) { - error("offset expected"); - } - return args->a_a.a_offset; - case DCON: - case DROM: - sum = 0; - for (arg = args; arg != (arg_p) 0; arg = arg->a_next) { - /* Add the sizes of all initializers */ - sum += argsize(arg); - } - return sum; - default: - assert(FALSE); - } - /* NOTREACHED */ -} - - -STATIC arg_p copy_arg(arg) - arg_p arg; -{ - /* Copy one argument */ - - arg_p new; - - assert(arg->a_type == ARGOFF); - new = newarg(ARGOFF); - new->a_a.a_offset = arg->a_a.a_offset; - return new; -} - - - -STATIC arg_p copy_rom(args) - arg_p args; -{ - /* Make a copy of the values of a rom, - * provided that the rom contains only integer values, - */ - - arg_p arg, arg2, argh; - - for (arg = args; arg != (arg_p) 0; arg = arg->a_next) { - if (arg->a_type != ARGOFF) { - return (arg_p) 0; - } - } - /* Now make the copy */ - arg2 = argh = copy_arg(args); - for (arg = args->a_next; arg != (arg_p) 0; arg = arg->a_next) { - arg2->a_next = copy_arg(arg); - arg2 = arg2->a_next; - } - return argh; -} - - - -dblockdef(db,n,lnp) - dblock_p db; - int n; - line_p lnp; -{ - /* Process a data block defining occurrence */ - - byte m; - - switch(n) { - case ps_hol: - m = DHOL; - break; - case ps_bss: - m = DBSS; - break; - case ps_con: - m = DCON; - break; - case ps_rom: - m = DROM; - break; - default: - assert(FALSE); - } - db->d_pseudo = m; - db->d_size = blocksize(m, ARG(lnp)); - if (m == DROM) { - /* We keep the values of a rom block in the data block - * table if the values consist of integers only. - */ - db->d_values = copy_rom(ARG(lnp)); - } -} - - - -/* combine */ - -combine(db,l1,l2,pseu) - dblock_p db; - line_p l1,l2; - byte pseu; -{ - /* Combine two successive ROMs/CONs (without a data label - * in between into a single ROM. E.g.: - * xyz - * rom 3,6,9,12 - * rom 7,0,2 - * is changed into: - * xyz - * rom 3,6,9,12,7,0,2 - */ - - arg_p v; - - db->d_size += blocksize(pseu,ARG(l2)); - /* db is the data block that was already assigned to the - * first rom/con. The second one is not assigned a new - * data block of course, as the two are combined into - * one instruction. - */ - if (pseu == DROM && db->d_values != (arg_p) 0) { - /* The values contained in a ROM are only copied - * to the data block if they may be useful to us - * (e.g. they certainly may not be strings). In our - * case it means that both ROMs must have useful - * arguments. - */ - for (v = db->d_values; v->a_next != (arg_p) 0; v = v->a_next); - /* The first rom contained useful arguments. v now points to - * its last argument. Append the arguments of the second - * rom to this list. If the second rom has arguments that are - * not useful, throw away the entire list (we want to copy - * everything or nothing). - */ - if ((v->a_next = copy_rom(ARG(l2))) == (arg_p) 0) { - oldargs(db->d_values); - db->d_values = (arg_p) 0; - } - } - for (v = ARG(l1); v->a_next != (arg_p) 0; v = v->a_next); - /* combine the arguments of both instructions. */ - v->a_next = ARG(l2); - ARG(l2) = (arg_p) 0; -} - - - -/* arglist */ - -STATIC arg_string(length,abp) - offset length; - register argb_p abp; -{ - - while (length--) { - if (abp->ab_index == NARGBYTES) - abp = abp->ab_next = newargb(); - abp->ab_contents[abp->ab_index++] = readchar(); - } -} - - -line_p arglist(n) - int n; -{ - line_p lnp; - register arg_p ap,*app; - bool moretocome; - offset length; - - - /* - * creates an arglist with n elements - * if n == 0 the arglist is variable and terminated by sp_cend - */ - - lnp = newline(OPLIST); - app = &ARG(lnp); - moretocome = TRUE; - do { - switch(table2()) { - default: - error("unknown byte in arglist"); - case CSTX1: - tabval2 = (offset) tabval; - case CSTX2: - *app = ap = newarg(ARGOFF); - ap->a_a.a_offset = tabval2; - app = &ap->a_next; - break; - case ILBX: - *app = ap = newarg(ARGINSTRLAB); - ap->a_a.a_instrlab = instr_lab((short) tabval); - app = &ap->a_next; - break; - case DLBX: - *app = ap = newarg(ARGOBJECT); - ap->a_a.a_obj = object(string,(offset) 0, (offset) 0); - /* The size of the object is unknown */ - app = &ap->a_next; - break; - case sp_pnam: - *app = ap = newarg(ARGPROC); - ap->a_a.a_proc = proclookup(string,OCCURRING); - app = &ap->a_next; - break; - case VALX1: - tabval2 = (offset) tabval; - case VALX2: - *app = ap = newarg(ARGOBJECT); - ap->a_a.a_obj = object(string, tabval2, (offset) 0); - app = &ap->a_next; - break; - case sp_scon: - *app = ap = newarg(ARGSTRING); - length = get_off(); - arg_string(length,&ap->a_a.a_string); - app = &ap->a_next; - break; - case sp_icon: - *app = ap = newarg(ARGICN); - goto casecon; - case sp_ucon: - *app = ap = newarg(ARGUCN); - goto casecon; - case sp_fcon: - *app = ap = newarg(ARGFCN); - casecon: - length = get_int(); - ap->a_a.a_con.ac_length = (short) length; - arg_string(get_off(),&ap->a_a.a_con.ac_con); - app = &ap->a_next; - break; - case sp_cend: - moretocome = FALSE; - } - if (n && (--n) == 0) - moretocome = FALSE; - } while (moretocome); - return(lnp); -} - - - -/* is_datalabel */ - -bool is_datalabel(l) - line_p l; -{ - VL(l); - return (l->l_instr == (byte) ps_sym); -} - - - -/* block_of_lab */ - -dblock_p block_of_lab(ident) - char *ident; -{ - dblock_p dbl; - - /* Find the datablock with the given name. - * Used for defining occurrences. - */ - - dbl = symlookup(ident,DEFINING); - VD(dbl); - if (dbl->d_pseudo != DUNKNOWN) { - error("identifier redeclared"); - } - return dbl; -} - - - -/* object */ - -STATIC obj_p make_object(dbl,off,size) - dblock_p dbl; - offset off; - offset size; -{ - /* Allocate an obj struct with the given attributes - * (if it did not exist already). - * Return a pointer to the found or newly created object struct. - */ - - obj_p obj, prev, new; - - /* See if the object was already present in the object list - * of the given datablock. If it is not yet present, find - * the right place to insert the new object. Note that - * the objects are sorted by offset. - */ - prev = (obj_p) 0; - for (obj = dbl->d_objlist; obj != (obj_p) 0; obj = obj->o_next) { - if (obj->o_off >= off) { - break; - } - prev = obj; - } - /* Note that the data block may contain several objects - * with the required offset; we also want the size to - * be the right one. - */ - while (obj != (obj_p) 0 && obj->o_off == off) { - if (obj->o_size == UNKNOWN_SIZE) { - obj->o_size = size; - return obj; - } else { - if (size == UNKNOWN_SIZE || obj->o_size == size) { - return obj; - /* This is the right one */ - } else { - prev = obj; - obj = obj->o_next; - } - } - } - /* Allocate a new object */ - new = newobject(); - new->o_id = ++lastoid; /* create a unique object id */ - new->o_off = off; - new->o_size = size; - new->o_dblock = dbl; - /* Insert the new object */ - if (prev == (obj_p) 0) { - dbl->d_objlist = new; - } else { - prev->o_next = new; - } - new->o_next = obj; - return new; -} - - - -obj_p object(ident,off,size) - char *ident; - offset off; - offset size; -{ - dblock_p dbl; - - /* Create an object struct (if it did not yet exist) - * for the object with the given size and offset - * within the datablock of the given name. - */ - - dbl = (ident == (char *) 0 ? curhol : symlookup(ident, OCCURRING)); - VD(dbl); - return(make_object(dbl,off,size)); -} diff --git a/util/ego/ic/ic_aux.h b/util/ego/ic/ic_aux.h deleted file mode 100644 index 887e43150..000000000 --- a/util/ego/ic/ic_aux.h +++ /dev/null @@ -1,39 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * A U X I L I A R Y R O U T I N E S - */ - - - -extern offset opr_size(); /* ( short instr ) - * size of operand of given instruction. - * The operand is an object , so the - * instruction can be loe, zre etc.. - */ -extern dblockdef(); /* (dblock_p db, int n, line_p lnp) - * Fill in d_pseudo, d_size and - * d_values fields of db. - */ -extern combine(); /* (dblock_p db;line_p l1,l2;byte pseu) - * Combine two successive ROMs or CONs - * (with no data label in between) - * into one ROM or CON. - */ -extern line_p arglist(); /* ( int m) - * Read a list of m arguments. If m - * is 0, then the list is of - * undetermined length; it is - * then terminated by a cend symbol. - */ -extern bool is_datalabel(); /* ( line_p l) - * TRUE if l is a data label defining - * occurrence (i.e. its l_instr - * field is ps_sym). - */ -extern dblock_p block_of_lab(); /* (char *ident) - * Find the datablock with - * the given name. - */ -extern obj_p object(); /* (char *ident,offset off,short size) - * Create an object struct. - */ diff --git a/util/ego/ic/ic_io.c b/util/ego/ic/ic_io.c deleted file mode 100644 index 017ff1e60..000000000 --- a/util/ego/ic/ic_io.c +++ /dev/null @@ -1,204 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * I C _ I O . C - */ - - - -#include -#include "../share/types.h" -#include "../share/debug.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" -#include "../../../h/arch.h" -#include "ic.h" -#include "ic_lookup.h" -#include "../share/alloc.h" -#include "ic_io.h" - - -STATIC short libstate; -STATIC long bytecnt; - -STATIC FILE *infile; /* The current EM input file */ - -STATIC int readbyte() -{ - if (libstate == ARCHIVE && bytecnt-- == 0L) { - /* If we're reading from an archive file, we'll - * have to count the number of characters read, - * to know where the current module ends. - */ - return EOF; - } - return getc(infile); -} - - - - -short readshort() { - register int l_byte, h_byte; - - l_byte = readbyte(); - h_byte = readbyte(); - if ( h_byte>=128 ) h_byte -= 256 ; - return l_byte | (h_byte*256) ; -} - -#ifdef LONGOFF -offset readoffset() { - register long l; - register int h_byte; - - l = readbyte(); - l |= ((unsigned) readbyte())*256 ; - l |= readbyte()*256L*256L ; - h_byte = readbyte() ; - if ( h_byte>=128 ) h_byte -= 256 ; - return l | (h_byte*256L*256*256L) ; -} -#endif - - -short get_int() { - - switch(table2()) { - default: error("int expected"); - case CSTX1: - return(tabval); - } -} - -char readchar() -{ - return(readbyte()); -} - - - -offset get_off() { - - switch (table2()) { - default: error("offset expected"); - case CSTX1: - return((offset) tabval); -#ifdef LONGOFF - case CSTX2: - return(tabval2); -#endif - } -} - -STATIC make_string(n) int n; { - register char *s; - extern char *sprintf(); - - s=sprintf(string,".%u",n); - assert(s == string); -} - -STATIC inident() { - register n; - register char *p = string; - register c; - - n = get_int(); - while (n--) { - c = readbyte(); - if (p<&string[IDL]) - *p++ = c; - } - *p++ = 0; -} - -int table3(n) int n; { - - switch (n) { - case sp_ilb1: tabval = readbyte(); return(ILBX); - case sp_ilb2: tabval = readshort(); return(ILBX); - case sp_dlb1: make_string(readbyte()); return(DLBX); - case sp_dlb2: make_string(readshort()); return(DLBX); - case sp_dnam: inident(); return(DLBX); - case sp_pnam: inident(); return(n); - case sp_cst2: tabval = readshort(); return(CSTX1); -#ifdef LONGOFF - case sp_cst4: tabval2 = readoffset(); return(CSTX2); -#endif - case sp_doff: if (table2()!=DLBX) error("symbol expected"); - switch(table2()) { - default: error("offset expected"); - case CSTX1: return(VALX1); -#ifdef LONGOFF - case CSTX2: return(VALX2); -#endif - } - default: return(n); - } -} - -int table1() { - register n; - - n = readbyte(); - if (n == EOF) - return(ATEOF); - if ((n <= sp_lmnem) && (n >= sp_fmnem)) { - tabval = n; - return(INST); - } - if ((n <= sp_lpseu) && (n >= sp_fpseu)) { - tabval = n; - return(PSEU); - } - if ((n < sp_filb0 + sp_nilb0) && (n >= sp_filb0)) { - tabval = n - sp_filb0; - return(ILBX); - } - return(table3(n)); -} - -int table2() { - register n; - - n = readbyte(); - if ((n < sp_fcst0 + sp_ncst0) && (n >= sp_fcst0)) { - tabval = n - sp_zcst0; - return(CSTX1); - } - return(table3(n)); -} - - - - -file_init(f,state,length) - FILE *f; - short state; - long length; -{ - short n; - - infile = f; - libstate = state; - bytecnt = length; - linecount = 0; - n = readshort(); - if (n != (short) sp_magic) { - error("wrong magic number: %d", n); - } -} - - - -arch_init(arch) - FILE *arch; -{ - short n; - - infile = arch; - n = readshort(); - if (n != ARMAG) { - error("wrong archive magic number: %d",n); - } -} diff --git a/util/ego/ic/ic_io.h b/util/ego/ic/ic_io.h deleted file mode 100644 index 30bb194fe..000000000 --- a/util/ego/ic/ic_io.h +++ /dev/null @@ -1,34 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * L O W L E V E L I / O R O U T I N E S - */ - - -extern int table1(); /* ( ) - * Read an instruction from the - * Compact Assembly Language input - * file (in 'neutral state'). - */ -extern int table2(); /* ( ) - * Read an instruction argument. - */ -extern int table3(); /* ( int ) - * Read 'Common Table' item. - */ -extern short get_int(); /* ( ) */ -extern offset get_off(); /* ( ) */ -extern char readchar(); /* ( ) */ -extern file_init(); /* (FILE *f, short state, long length) - * Input file initialization. All - * following read operations will read - * from the given file f. Also checks - * the magic number and sets global - * variable 'linecount' to 0. - * If the state is ARCHIVE, length - * specifies the length of the module. - */ -extern arch_init(); /* (FILE *arch) - * Same as file_init,but opens an - * archive file. So it checks the - * magic number for archives. - */ diff --git a/util/ego/ic/ic_lib.c b/util/ego/ic/ic_lib.c deleted file mode 100644 index 390ccec7d..000000000 --- a/util/ego/ic/ic_lib.c +++ /dev/null @@ -1,274 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * I C _ L I B . C - */ - - -#include -#include "../share/types.h" -#include "../share/debug.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_mes.h" -#include "../../../h/arch.h" -#include "ic.h" -#include "ic_lookup.h" -#include "ic_io.h" -#include "../share/global.h" -#include "../share/files.h" -#include "ic_lib.h" - - -STATIC skip_string(n) - offset n; -{ - /* Read a string of length n and void it */ - - while (n--) { - readchar(); - } -} - - -STATIC skip_arguments() -{ - /* Skip the arguments of a MES pseudo. The argument - * list is terminated by a sp_cend byte. - */ - - for (;;) { - switch(table2()) { - case sp_scon: - get_off(); /* void */ - /* fall through !!! */ - case sp_icon: - case sp_ucon: - case sp_fcon: - get_int(); /* void */ - skip_string(get_off()); - break; - case sp_cend: - return; - default: - break; - } - } -} - - - -STATIC bool proc_wanted(name) - char *name; -{ - /* See if 'name' is the name of an external procedure - * that has been used before, but for which no body - * has been given so far. - */ - - proc_p p; - - if (( p = proclookup(name,IMPORTING)) != (proc_p) 0 && - !(p->p_flags1 & PF_BODYSEEN)) { - return TRUE; - } else { - return FALSE; - } -} - - - -STATIC bool data_wanted(name) - char *name; -{ - /* See if 'name' is the name of an externally visible - * data block that has been used before, but for which - * no defining occurrence has been given yet. - */ - - dblock_p db; - - if ((db = symlookup(name,IMPORTING)) != (dblock_p) 0 && - db->d_pseudo == DUNKNOWN) { - return TRUE; - } else { - return FALSE; - } -} - - - -STATIC bool wanted_names() -{ - /* Read the names of procedures and data labels, - * appearing in a 'MES ms_ext' pseudo. Those are - * the names of entities that are imported by - * a library module. - * If any of them is wanted, return TRUE. - * A name is wanted if it is the name of a procedure - * or data block for which applied occurrences but - * no defining occurrence has been met. - */ - - for (;;) { - switch(table2()) { - case DLBX: - if (data_wanted(string)) { - return TRUE; - } - /* A data entity with the name - * string is available. - */ - break; - case sp_pnam: - if (proc_wanted(string)) { - return TRUE; - } - break; - case sp_cend: - return FALSE; - default: - error("wrong argument of MES %d", ms_ext); - } - } -} - - - -STATIC FILE *curfile = NULL; -STATIC bool useful() -{ - /* Determine if any entity imported by the current - * compact EM assembly file (which will usually be - * part of an archive file) is useful to us. - * The file must contain (before any other non-MES line) - * a 'MES ms_ext' pseudo that has as arguments the names - * of the entities imported. - */ - - for (;;) { - if (table1() != PSEU || tabval != ps_mes) { - error("cannot find MES %d in library file",ms_ext); - } - if (table2() != CSTX1) { - error("message number expected"); - } - if (tabval == ms_ext) { - /* This is the one we searched */ - return wanted_names(); - /* Read the names of the imported entities - * and check if any of them is wanted. - */ - } else { - skip_arguments(); /* skip remainder of this MES */ - } - } -} - - - -STATIC bool is_archive(name) - char *name; -{ - /* See if 'name' is the name of an archive file, i.e. it - * should end on ".a" and should at least be three characters - * long (i.e. the name ".a" is not accepted as an archive name!). - */ - - register char *p; - - for (p = name; *p; p++); - return (p > name+2) && (*--p == 'a') && (*--p == '.'); -} - - - -STATIC struct ar_hdr hdr; - -STATIC bool read_hdr() -{ - /* Read the header of an archive module */ - - - fread(&hdr, sizeof(hdr), 1, curfile); - return !feof(curfile); -} - - - -STATIC int argcnt = ARGSTART - 1; -STATIC short arstate = NO_ARCHIVE; - - -FILE *next_file(argc,argv) - int argc; - char *argv[]; -{ - /* See if there are more EM input files. The file names - * are given via argv. If a file is an archive file - * it is supposed to be a library of EM compact assembly - * files. A module (file) contained in this archive file - * is only used if it imports at least one procedure or - * datalabel for which we have not yet seen a defining - * occurrence, although we have seen a used occurrence. - */ - - long ptr; - - for (;;) { - /* This loop is only exited via a return */ - if (arstate == ARCHIVE) { - /* We were reading an archive file */ - if (ftell(curfile) & 1) { - /* modules in an archive file always - * begin on a word boundary, i.e. at - * an even address. - */ - fseek(curfile,1L,1); - } - if (read_hdr()) { /* read header of next module */ - ptr = ftell(curfile); /* file position */ - file_init(curfile,ARCHIVE,hdr.ar_size); - /* tell i/o package that we're reading - * an archive module of given length. - */ - if (useful()) { - /* re-initialize file, because 'useful' - * has read some bytes too. - */ - fseek(curfile,ptr,0); /* start module */ - file_init(curfile,ARCHIVE,hdr.ar_size); - return curfile; - } else { - /* skip this module */ - fseek(curfile, - ptr+hdr.ar_size,0); - } - } else { - /* done with this archive */ - arstate = NO_ARCHIVE; - } - } else { - /* open next file, close old */ - if (curfile != NULL) { - fclose(curfile); - } - argcnt++; - if (argcnt >= argc) { - /* done with all arguments */ - return NULL; - } - filename = argv[argcnt]; - if ((curfile = fopen(filename,"r")) == NULL) { - error("cannot open %s",filename); - } - if (is_archive(filename)) { - /* ends on '.a' */ - arstate = ARCHIVE; - arch_init(curfile); /* read magic ar number */ - } else { - file_init(curfile,NO_ARCHIVE,0L); - return curfile; - } - } - } -} diff --git a/util/ego/ic/ic_lib.h b/util/ego/ic/ic_lib.h deleted file mode 100644 index 75d0b22e9..000000000 --- a/util/ego/ic/ic_lib.h +++ /dev/null @@ -1,14 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * L I B R A R Y M A N A G E R - */ - - -extern FILE *next_file(); /* (int argc, char *argv[]) - * See if there are any more EM input files. - * 'argv' contains the names of the files - * that are passed as arguments to ic. - * If an argument is a library (archive - * file) only those modules that are useful - * are used. - */ diff --git a/util/ego/ic/ic_lookup.c b/util/ego/ic/ic_lookup.c deleted file mode 100644 index 6c0d2b80b..000000000 --- a/util/ego/ic/ic_lookup.c +++ /dev/null @@ -1,414 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * I C _ L O O K U P . C - */ - - -#include -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/map.h" -#include "../../../h/em_spec.h" -#include "ic.h" -#include "ic_lookup.h" -#include "../share/alloc.h" - - -sym_p symhash[NSYMHASH]; -prc_p prochash[NPROCHASH]; -num_p numhash[NNUMHASH]; - - - -#define newsym() (sym_p) newstruct(sym) -#define newprc() (prc_p) newstruct(prc) -#define newnum() (num_p) newstruct(num) - -#define oldsym(x) oldstruct(sym,x) -#define oldprc(x) oldstruct(prc,x) -#define oldnum(x) oldstruct(num,x) - - -/* instr_lab */ - - - - - -lab_id instr_lab(number) - short number; -{ - register num_p *npp, np; - - /* In EM assembly language, a label is an unsigned number, - * e.g. 120 in 'BRA *120'. In IC the labels of a procedure - * are represented by consecutive integer numbers, called - * lab_id. The mapping takes place here. - */ - - - npp = &numhash[number%NNUMHASH]; - while (*npp != (num_p) 0) { - if ((*npp)->n_number == number) { - return(*npp)->n_labid; - } else { - npp = &(*npp)->n_next; - } - } - - /* The label was not found in the hashtable, so - * create a new entry for it. - */ - - *npp = np = newnum(); - np->n_number = number; - np->n_labid = ++lastlid; - /* Assign a new label identifier to the num struct. - * lastlid is reset to 0 at the beginning of - * every new EM procedure (by cleaninstrlabs). - */ - return (np->n_labid); -} - - - -/* symlookup */ - -STATIC unsigned hash(string) char *string; { - register char *p; - register unsigned i,sum; - - for (sum=i=0,p=string;*p;i += 3) - sum ^= (*p++)<<(i&07); - return(sum); -} - -dblock_p symlookup(name, status) - char *name; - int status; -{ - /* Look up the name of a data block. The name can appear - * in either a defining or applied occurrence (status is - * DEFINING, OCCURRING resp.), or in a MES ms_ext instruction - * as the name of a data block imported by a library module - * (status is IMPORTING). Things get complicated, - * because a HOL pseudo need not be preceded by a - * data label, i.e. a hol block need not have a name. - */ - - - register sym_p *spp, sp; - register dblock_p dp; - - if (name == (char *) 0) { - assert(status == DEFINING); - dp = newdblock(); - } else { - spp = &symhash[hash(name)%NSYMHASH]; - while (*spp != (sym_p) 0) { - /* Every hashtable entry points to a list - * of synonyms (i.e. names with the same - * hash values). Try to find 'name' in its - * list. - */ - if (strncmp((*spp)->sy_name, name, IDL) == 0) { - /* found */ - return ((*spp)->sy_dblock); - } else { - spp = &(*spp)->sy_next; - } - } - /* The name is not found, so create a new entry for it. - * However, if the status is IMPORTING, we just return 0, - * indicating that we don't need this name. - */ - if (status == IMPORTING) return (dblock_p) 0; - *spp = sp = newsym(); - strncpy(sp->sy_name, name, IDL); - dp = sp->sy_dblock = newdblock(); - } - if (fdblock == (dblock_p) 0) { - fdblock = dp; - /* first data block */ - } else { - ldblock->d_next = dp; /* link to last dblock */ - } - ldblock = dp; - dp->d_pseudo = DUNKNOWN; /* clear all fields */ - dp->d_id = ++lastdid; - dp->d_size = 0; - dp->d_objlist = (obj_p) 0; - dp->d_values = (arg_p) 0; - dp->d_next = (dblock_p) 0; - dp->d_flags1 = 0; - dp->d_flags2 = 0; - if (status == OCCURRING) { - /* This is the first occurrence of the identifier, - * so if it is a used occurrence make the - * identifier externally visible, else make it - * internal. - */ - dp->d_flags1 |= DF_EXTERNAL; - } - return dp; -} - - - -/* getsym */ - -dblock_p getsym(status) - int status; -{ - if (table2() != DLBX) { - error("symbol expected"); - } - return(symlookup(string,status)); -} - - - -/* getproc */ - -proc_p getproc(status) - int status; -{ - if (table2() != sp_pnam) { - error("proc name expected"); - } - return(proclookup(string,status)); -} - - - -/* proclookup */ - -proc_p proclookup(name, status) - char *name; - int status; -{ - register prc_p *ppp, pp; - register proc_p dp; - - ppp = &prochash[hash(name)%NPROCHASH]; - while (*ppp != (prc_p) 0) { - /* Every hashtable entry points to a list - * of synonyms (i.e. names with the same - * hash values). Try to find 'name' in its - * list. - */ - if (strncmp((*ppp)->pr_name, name, IDL) == 0) { - /* found */ - return ((*ppp)->pr_proc); - } else { - ppp = &(*ppp)->pr_next; - } - } - /* The name is not found, so create a new entry for it, - * unless the status is IMPORTING, in which case we - * return 0, indicating we don't want this proc. - */ - if (status == IMPORTING) return (proc_p) 0; - *ppp = pp = newprc(); - strncpy(pp->pr_name, name, IDL); - dp = pp->pr_proc = newproc(); - if (fproc == (proc_p) 0) { - fproc = dp; /* first proc */ - } else { - lproc->p_next = dp; - } - lproc = dp; - dp->p_id = ++lastpid; /* create a unique proc_id */ - dp->p_next = (proc_p) 0; - dp->p_flags1 = 0; - dp->p_flags2 = 0; - if (status == OCCURRING) { - /* This is the first occurrence of the identifier, - * so if it is a used occurrence the make the - * identifier externally visible, else make it - * internal. - */ - dp->p_flags1 |= PF_EXTERNAL; - } - return dp; -} - - - -/* cleaninstrlabs */ - -cleaninstrlabs() -{ - register num_p *npp, np, next; - - for (npp = numhash; npp < &numhash[NNUMHASH]; npp++) { - for (np = *npp; np != (num_p) 0; np = next) { - next = np->n_next; - oldnum(np); - } - *npp = (num_p) 0; - } - /* Reset last label id (used by instr_lab). */ - lastlid = (lab_id) 0; -} - - - -/* dump_procnames */ - -dump_procnames(hash,n,f) - prc_p hash[]; - int n; - FILE *f; -{ - /* Save the names of the EM procedures in file f. - * Note that the Optimizer Intermediate Code does not - * use identifiers but proc_ids, object_ids etc. - * The names, however, can be used after optimization - * is completed, to reconstruct Compact Assembly Language. - * The output consists of tuples (proc_id, name). - * This routine is called once for every input file. - * To prevent names of external procedures being written - * more than once, the PF_WRITTEN flag is used. - */ - - register prc_p *pp, ph; - proc_p p; - char str[IDL+1]; - register int i; - -#define PF_WRITTEN 01 - - - for (pp = &hash[0]; pp < &hash[n]; pp++) { - /* Traverse the entire hash table */ - for (ph = *pp; ph != (prc_p) 0; ph = ph->pr_next) { - /* Traverse the list of synonyms */ - p = ph->pr_proc; - if ((p->p_flags2 & PF_WRITTEN) == 0) { - /* not been written yet */ - for(i = 0; i < IDL; i++) { - str[i] = ph->pr_name[i]; - } - str[IDL] = '\0'; - fprintf(f,"%d %s\n",p->p_id, str); - p->p_flags2 |= PF_WRITTEN; - } - } - } -} - - - -/* cleanprocs */ - -cleanprocs(hash,n,mask) - prc_p hash[]; - int n,mask; -{ - /* After an EM input file has been processed, the names - * of those procedures that are internal (i.e. not visible - * outside the file they are defined in) must be removed - * from the procedure hash table. This is accomplished - * by removing the 'prc struct' from its synonym list. - * After the final input file has been processed, all - * remaining prc structs are also removed. - */ - - register prc_p *pp, ph, x, next; - - for (pp = &hash[0]; pp < &hash[n]; pp++) { - /* Traverse the hash table */ - x = (prc_p) 0; - for (ph = *pp; ph != (prc_p) 0; ph = next) { - /* Traverse the synonym list. - * x points to the prc struct just before ph, - * or is 0 if ph is the first struct of - * the list. - */ - next = ph->pr_next; - if ((ph->pr_proc->p_flags1 & mask) == 0) { - if (x == (prc_p) 0) { - *pp = next; - } else { - x->pr_next = next; - } - oldprc(ph); /* delete the struct */ - } else { - x = ph; - } - } - } -} - - - -/* dump_dblocknames */ - -dump_dblocknames(hash,n,f) - sym_p hash[]; - int n; - FILE *f; -{ - /* Save the names of the EM data blocks in file f. - * The output consists of tuples (dblock_id, name). - * This routine is called once for every input file. - */ - - register sym_p *sp, sh; - dblock_p d; - char str[IDL+1]; - register int i; - -#define DF_WRITTEN 01 - - - for (sp = &hash[0]; sp < &hash[n]; sp++) { - /* Traverse the entire hash table */ - for (sh = *sp; sh != (sym_p) 0; sh = sh->sy_next) { - /* Traverse the list of synonyms */ - d = sh->sy_dblock; - if ((d->d_flags2 & DF_WRITTEN) == 0) { - /* not been written yet */ - for (i = 0; i < IDL; i++) { - str[i] = sh->sy_name[i]; - str[IDL] = '\0'; - } - fprintf(f,"%d %s\n",d->d_id, str); - d->d_flags2 |= DF_WRITTEN; - } - } - } -} - - - -/* cleandblocks */ - -cleandblocks(hash,n,mask) - sym_p hash[]; - int n,mask; -{ - /* After an EM input file has been processed, the names - * of those data blocks that are internal must be removed. - */ - - register sym_p *sp, sh, x, next; - - for (sp = &hash[0]; sp < &hash[n]; sp++) { - x = (sym_p) 0; - for (sh = *sp; sh != (sym_p) 0; sh = next) { - next = sh->sy_next; - if ((sh->sy_dblock->d_flags1 & mask) == 0) { - if (x == (sym_p) 0) { - *sp = next; - } else { - x->sy_next = next; - } - oldsym(sh); /* delete the struct */ - } else { - x = sh; - } - } - } -} diff --git a/util/ego/ic/ic_lookup.h b/util/ego/ic/ic_lookup.h deleted file mode 100644 index 6d7d287a2..000000000 --- a/util/ego/ic/ic_lookup.h +++ /dev/null @@ -1,71 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * L O O K - U P R O U T I N E S - */ - -/* During Intermediate Code generation data label names ('symbols'), - * procedure names and instruction labels (numbers) are translated - * to resp. a data block pointer, a proc pointer and a label identifier. - * We use three hash tables for this purpose (symhash, prochash, numhash). - * Every name/number is hashed to an index in a specific table. A table - * entry contains a list of structs (sym, prc, num), each one representing - * a 'synonym'. (Synonyms are names/numbers having the same hash value). - */ - - -/* status passed as argument to look_up routines: - * resp. used occurrence, defining occurrence, occurrence in - * a MES ms_ext pseudo. - */ - -#define OCCURRING 0 -#define DEFINING 1 -#define IMPORTING 2 - -#define NSYMHASH 127 -#define NPROCHASH 127 -#define NNUMHASH 37 - -extern sym_p symhash[]; -extern prc_p prochash[]; -extern num_p numhash[]; - -extern lab_id instr_lab(); /* ( short number) - * Maps EM labels to sequential - * integers. - */ -extern dblock_p symlookup(); /* (char *ident, int status) - * Look up the data block with - * the given name. - */ -extern dblock_p getsym(); /* ( int status) - * Read and look up a symbol. - * If this is the first occurrence - * of it, then make it external - * (if status=OCCURRING) or - * internal (if DEFINING). - */ -extern proc_p getproc(); /* (int status) - * Same as getsym, but for procedure - * names. - */ -extern proc_p proclookup(); /* ( char *ident, int status) - * Find (in the hashtable) the - * procedure with the given name. - */ -extern cleaninstrlabs(); /* ( ) - * Forget about all instruction labels. - */ -extern dump_procnames(); /* (prc_p hash[], int n, FILE *f) - * Save the names of the procedures - * in file f; hash is the hashtable - * used and n is its length. - */ -extern cleanprocs(); /* (prc_p hash[], int n,mask) - * Make the names of all procedures - * for which p_flags1&mask = 0 invisible - */ -extern cleandblocks(); /* (sym_p hash[], int n) - * Make the names of all data blocks - * for which d_flags1&mask = 0 invisible - */ diff --git a/util/ego/il/Makefile b/util/ego/il/Makefile deleted file mode 100644 index 5504f5023..000000000 --- a/util/ego/il/Makefile +++ /dev/null @@ -1,160 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -il.c il1_anal.c il1_cal.c il1_formal.c il1_aux.c il2_aux.c \ -il3_subst.c il3_change.c il3_aux.c il_aux.c - -OFILES=\ -il.o il1_anal.o il1_cal.o il1_formal.o il1_aux.o il2_aux.o \ -il3_change.o il3_subst.o il3_aux.o il_aux.o - -HFILES=\ -il.h il1_anal.h il1_cal.h il1_formal.h il1_aux.h il2_aux.h \ -il3_subst.h il3_change.h il3_aux.h il_aux.h - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/get.o $(SHR)/put.o $(SHR)/alloc.o $(SHR)/global.o $(SHR)/debug.o \ -$(SHR)/files.o $(SHR)/map.o $(SHR)/lset.o $(SHR)/cset.o $(SHR)/parser.o \ -$(SHR)/aux.o $(SHR)/go.o - -SHARE_MFILES=\ -$(SHR)/get.m $(SHR)/put.m $(SHR)/alloc.m $(SHR)/global.m $(SHR)/debug.m \ -$(SHR)/files.m $(SHR)/map.m $(SHR)/lset.m $(SHR)/cset.m $(SHR)/parser.m \ -$(SHR)/aux.m $(SHR)/go.m - -il: $(OFILES) - $(CC) -o il $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -il_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o il -.c $(LDFLAGS) il.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO - -il.o: ../../../h/em_mnem.h -il.o: ../../../h/em_pseu.h -il.o: ../share/alloc.h -il.o: ../share/debug.h -il.o: ../share/files.h -il.o: ../share/get.h -il.o: ../share/global.h -il.o: ../share/lset.h -il.o: ../share/map.h -il.o: ../share/put.h -il.o: ../share/types.h -il.o: il.h -il.o: il1_anal.h -il.o: il2_aux.h -il.o: il3_subst.h -il1_anal.o: ../../../h/em_mnem.h -il1_anal.o: ../../../h/em_pseu.h -il1_anal.o: ../share/alloc.h -il1_anal.o: ../share/debug.h -il1_anal.o: ../share/global.h -il1_anal.o: ../share/lset.h -il1_anal.o: ../share/put.h -il1_anal.o: ../share/types.h -il1_anal.o: il.h -il1_anal.o: il1_anal.h -il1_anal.o: il1_aux.h -il1_anal.o: il1_cal.h -il1_anal.o: il1_formal.h -il1_anal.o: il_aux.h -il1_aux.o: ../../../h/em_spec.h -il1_aux.o: ../share/alloc.h -il1_aux.o: ../share/debug.h -il1_aux.o: ../share/global.h -il1_aux.o: ../share/lset.h -il1_aux.o: ../share/types.h -il1_aux.o: il.h -il1_aux.o: il1_aux.h -il1_aux.o: il_aux.h -il1_cal.o: ../../../h/em_mnem.h -il1_cal.o: ../../../h/em_spec.h -il1_cal.o: ../share/alloc.h -il1_cal.o: ../share/debug.h -il1_cal.o: ../share/global.h -il1_cal.o: ../share/lset.h -il1_cal.o: ../share/parser.h -il1_cal.o: ../share/types.h -il1_cal.o: il.h -il1_cal.o: il1_aux.h -il1_cal.o: il1_cal.h -il1_formal.o: ../share/alloc.h -il1_formal.o: ../share/debug.h -il1_formal.o: ../share/global.h -il1_formal.o: ../share/lset.h -il1_formal.o: ../share/types.h -il1_formal.o: il.h -il1_formal.o: il1_aux.h -il1_formal.o: il1_formal.h -il2_aux.o: ../../../h/em_mnem.h -il2_aux.o: ../../../h/em_spec.h -il2_aux.o: ../share/alloc.h -il2_aux.o: ../share/debug.h -il2_aux.o: ../share/get.h -il2_aux.o: ../share/global.h -il2_aux.o: ../share/lset.h -il2_aux.o: ../share/types.h -il2_aux.o: il.h -il2_aux.o: il2_aux.h -il2_aux.o: il_aux.h -il3_aux.o: ../share/alloc.h -il3_aux.o: ../share/debug.h -il3_aux.o: ../share/global.h -il3_aux.o: ../share/types.h -il3_aux.o: il.h -il3_aux.o: il3_aux.h -il3_aux.o: il_aux.h -il3_change.o: ../../../h/em_mes.h -il3_change.o: ../../../h/em_mnem.h -il3_change.o: ../../../h/em_pseu.h -il3_change.o: ../../../h/em_spec.h -il3_change.o: ../share/alloc.h -il3_change.o: ../share/debug.h -il3_change.o: ../share/def.h -il3_change.o: ../share/get.h -il3_change.o: ../share/global.h -il3_change.o: ../share/lset.h -il3_change.o: ../share/put.h -il3_change.o: ../share/types.h -il3_change.o: il.h -il3_change.o: il3_aux.h -il3_change.o: il3_change.h -il3_change.o: il_aux.h -il3_subst.o: ../../../h/em_mnem.h -il3_subst.o: ../share/alloc.h -il3_subst.o: ../share/debug.h -il3_subst.o: ../share/get.h -il3_subst.o: ../share/global.h -il3_subst.o: ../share/lset.h -il3_subst.o: ../share/types.h -il3_subst.o: il.h -il3_subst.o: il3_aux.h -il3_subst.o: il3_change.h -il3_subst.o: il3_subst.h -il_aux.o: ../../../h/em_spec.h -il_aux.o: ../share/alloc.h -il_aux.o: ../share/debug.h -il_aux.o: ../share/global.h -il_aux.o: ../share/lset.h -il_aux.o: ../share/map.h -il_aux.o: ../share/types.h -il_aux.o: il.h -il_aux.o: il_aux.h diff --git a/util/ego/il/il.c b/util/ego/il/il.c deleted file mode 100644 index 13ab88ade..000000000 --- a/util/ego/il/il.c +++ /dev/null @@ -1,312 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N */ -#include -#include "../share/types.h" -#include "il.h" -#include "../share/debug.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/files.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../share/map.h" -#include "il_aux.h" -#include "il1_anal.h" -#include "il2_aux.h" -#include "il3_subst.h" -#include "../share/get.h" -#include "../share/put.h" -#include "../share/go.h" - -int calnr; -calcnt_p cchead; /* call-count info of current proc */ -STATIC short space = 0; - -STATIC char cname[] = "/usr/tmp/ego.i1.XXXXXX"; -STATIC char ccname[] = "/usr/tmp/ego.i2.XXXXXX"; - -/* For debugging only */ -STATIC char sname[] = "/usr/tmp/ego.i3.XXXXXX"; - -int Ssubst; -#ifdef VERBOSE -int Senv,Srecursive,Slocals,Sinstrlab,Sparsefails,Spremoved,Scals; -int Sbig_caller,Sdispensable,Schangedcallee,Sbigcallee,Sspace,Szeroratio; -#endif - -/* P A S S 1 - * - * Pass 1 reads and analyses the EM text and the CFG. - * It determines for every procedure if it may be expanded - * in line and how it uses its formal parameters. - * It also collects all calls appearing in the program and - * recognizes the actual parameters of every call. - * The call descriptors are put in a file (calfile). - */ - -pass1(lnam,bnam,cnam) - char *lnam, *bnam, *cnam; -{ - FILE *f, *gf, *cf, *ccf; /* The EM input, the basic block graph, - * the call-list file and the calcnt file. - */ - long laddr; - bblock_p g; - short kind; - line_p l; - - f = openfile(lnam,"r"); - gf = openfile(bnam,"r"); - cf = openfile(cnam,"w"); - ccf = openfile(ccname,"w"); - mesregs = Lempty_set(); - apriori(fproc); - /* use information from the procedure table to - * see which calls certainly cannot be expanded. - */ - while(TRUE) { - laddr = ftell(f); - if (!getunit(gf,f,&kind,&g,&l,&curproc,TRUE)) break; - /* Read the control flow graph and EM text of - * one procedure and analyze it. - */ - if (kind == LDATA) { - remunit(LDATA,(proc_p) 0,l); - continue; - } - /* OUTTRACE("flow graph of proc %d read",curproc->p_id); */ - assert(INSTR(g->b_start) == ps_pro); - curproc->p_start = g; - curproc->P_LADDR = laddr; - /* address of em text in em-file */ - /* address of graph in basic block file */ - curproc->P_SIZE = proclength(curproc); /* #instructions */ - if (BIG_PROC(curproc)) { - /* curproc is too large to be expanded in line */ - UNSUITABLE(curproc); - } - calnr = 0; - anal_proc(curproc,cf,ccf); - /* OUTTRACE("proc %d processed",curproc->p_id); */ - remunit(LTEXT,curproc,(line_p) 0); - /* remove control flow graph + text */ - /* OUTTRACE("graph of proc %d removed",curproc->p_id); */ - Ldeleteset(mesregs); - mesregs = Lempty_set(); - } - fclose(f); - fclose(gf); - fclose(cf); - fclose(ccf); -} - - - -/* P A S S 2 - * - * Pass 2 reads the calfile and determines which calls should - * be expanded in line. It does not use the EM text. - */ - - - -STATIC char cname2[] = "/usr/tmp/ego.i4.XXXXXX"; - -pass2(cnam,space) - char *cnam; - short space; -{ - FILE *cf, *cf2, *ccf; - call_p c,a; - - cf = openfile(cnam,"r"); - cf2 = openfile(cname2,"w"); - ccf = openfile(ccname,"r"); - while ((c = getcall(cf)) != (call_p) 0) { - /* process all calls */ - if (SUITABLE(c->cl_proc) && anal_params(c)) { - /* called proc. may be put in line */ - /* see which parameters may be put in line */ - assign_ratio(c); /* assign a rank */ - a = abstract(c); /* abstract essential info */ - append_abstract(a,a->cl_caller); - /* put it in call-list of calling proc. */ - putcall(c,cf2,(short) 0); - } else { - rem_call(c); - } - } - select_calls(fproc,ccf,space); - fclose(cf); unlink(cnam); - fclose(cf2); - fclose(ccf); unlink(ccname); - cf2 = openfile(cname2,"r"); - add_actuals(fproc,cf2); - cleancals(fproc); /* remove calls that were not selected */ - /* add actual parameters to each selected call */ - fclose(cf2); unlink(cname2); -} - - - -/* P A S S 3 - * - * pass 3 reads the substitution file and performs all - * substitutions described in that file. It reads the - * original EM text and produced a new (optimized) - * EM textfile. - */ - - -pass3(lnam,lnam2) - char *lnam,*lnam2; -{ - bool verbose = TRUE; - FILE *lfile, *lfilerand, *lfile2, *sfile; - call_p c,next; - line_p l,startscan,cal; - short lastcid; /* last call-id seen */ - - lfile = openfile(lnam, "r"); - lfilerand = openfile(lnam, "r"); - lfile2 = openfile(lnam2,"w"); - if (verbose) { - sfile = openfile(sname,"w"); - } - mesregs = Lempty_set(); - while ((l = get_text(lfile,&curproc)) != (line_p) 0) { - if (curproc == (proc_p) 0) { - /* Just a data-unit; no real instructions */ - putlines(l->l_next,lfile2); - oldline(l); - continue; - } - if (IS_DISPENSABLE(curproc)) { - liquidate(curproc,l->l_next); - } else { - startscan = l->l_next; - lastcid = 0; - for (c = curproc->P_CALS; c != (call_p) 0; c = next) { - next = c->cl_cdr; - cal = scan_to_cal(startscan,c->cl_id - lastcid); - assert (cal != (line_p) 0); - startscan = scan_to_cal(cal->l_next,1); - /* next CAL */ - lastcid = c->cl_id; - /* next CAL after current one */ - substitute(lfilerand,c,cal,l->l_next); - if (verbose) { - putcall(c,sfile,0); - } else { - rem_call(c); - } - } - } - putlines(l->l_next,lfile2); - Ldeleteset(mesregs); - mesregs = Lempty_set(); - oldline(l); - } - fclose(lfile); - fclose(lfile2); - if (verbose) { - fclose(sfile); - unlink(sname); - } -} - - -STATIC il_extptab(ptab) - proc_p ptab; -{ - /* Allocate space for extension of proctable entries. - * Also, initialise some of the fields just allocated. - */ - - register proc_p p; - - for (p = ptab; p != (proc_p) 0; p = p->p_next) { - p->p_extend = newilpx(); - p->P_ORGLABELS = p->p_nrlabels; - p->P_ORGLOCALS = p->p_localbytes; - } -} - -STATIC il_cleanptab(ptab) - proc_p ptab; -{ - /* De-allocate space for extensions */ - - register proc_p p; - - for (p = ptab; p != (proc_p) 0; p = p->p_next) { - oldilpx(p->p_extend); - } -} - -#ifdef VERBOSE -Sdiagnostics() -{ - /* print statictical information */ - - fprintf(stderr,"STATISTICS:\n"); - fprintf(stderr,"Info about procedures:\n"); - fprintf(stderr,"environment accessed: %d\n",Senv); - fprintf(stderr,"recursive: %d\n",Srecursive); - fprintf(stderr,"too many locals: %d\n",Slocals); - fprintf(stderr,"instr. lab in data block: %d\n",Sinstrlab); - fprintf(stderr,"procedures removed: %d\n",Spremoved); - fprintf(stderr,"\nInfo about calls:\n"); - fprintf(stderr,"total number of calls: %d\n",Scals); - fprintf(stderr,"total number of calls substituted: %d\n",Ssubst); - fprintf(stderr,"parser failed: %d\n",Sparsefails); - fprintf(stderr,"caller too big: %d\n",Sbig_caller); - fprintf(stderr,"caller dispensable: %d\n",Sdispensable); - fprintf(stderr,"callee is changed: %d\n",Schangedcallee); - fprintf(stderr,"callee too big: %d\n",Sbigcallee); - fprintf(stderr,"no space available: %d\n",Sspace); - fprintf(stderr,"zero ratio: %d\n",Szeroratio); -} -#endif - -il_flags(p) - char *p; -{ - if (*p++ == 's') { - while (*p != '\0') { - space = 10*space +*p++ -'0'; - } - } -} - -main(argc,argv) - int argc; - char *argv[]; -{ - FILE *f; - - go(argc,argv,no_action,no_action,no_action,il_flags); - il_extptab(fproc); /* add extended data structures */ - mktemp(cname); - mktemp(ccname); - mktemp(sname); - mktemp(cname2); - pass1(lname,bname,cname); /* grep calls, analyse procedures */ - pass2(cname,space); /* select calls to be expanded */ - pass3(lname,lname2); /* do substitutions */ - f = openfile(dname2,"w"); - il_cleanptab(fproc); /* remove extended data structures */ - putdtable(fdblock,f); - f = openfile(pname2,"w"); - putptable(fproc,f,FALSE); - report("inline substitutions",Ssubst); -#ifdef VERBOSE - if (verbose_flag) { - Sdiagnostics(); - } -#endif -#ifdef DEBUG - core_usage(); -#endif - exit(0); -} diff --git a/util/ego/il/il.h b/util/ego/il/il.h deleted file mode 100644 index 56f782155..000000000 --- a/util/ego/il/il.h +++ /dev/null @@ -1,161 +0,0 @@ -/* I N T E R N A L D A T A S T R U C T U R E S O F - * - * I N L I N E S U B S T I T U T I O N - * - */ - - -typedef struct actual *actual_p; -typedef struct calcnt *calcnt_p; -typedef short call_id; - -struct call { - proc_p cl_caller; /* calling procedure */ - call_id cl_id; /* uniquely denotes a CAL instruction */ - proc_p cl_proc; /* the called procedure */ - byte cl_looplevel; /* loop nesting level of the CAL */ - bool cl_flags; /* flag bits */ - short cl_ratio; /* indicates 'speed gain / size lost' */ - call_p cl_cdr; /* link to next call */ - call_p cl_car; /* link to nested calls */ - actual_p cl_actuals; /* actual parameter expr. trees */ -}; - -#define CLF_INLPARS 017 /* min(15,nr. of inline parameters) */ -#define CLF_SELECTED 020 /* is call selected for expansion? */ -#define CLF_EVER_EXPANDED 040 /* ever expanded? e.g. in a nested call. */ -#define CLF_FIRM 0100 /* indicates if the call takes place in a - * firm block of a loop (i.e. one that - * is always executed, except - * -perhaps- at the last iteration). - * Used for heuristics only. - */ - -struct actual { - line_p ac_exp; /* copy of EM text */ - /* 0 for actuals that are not inline */ - offset ac_size; /* number of bytes of parameter */ - bool ac_inl; /* TRUE if it may be expanded in line */ - actual_p ac_next; /* link */ -}; - - -struct formal { - offset f_offset; /* offsetin bytes */ - byte f_flags; /* flags FF_BAD etc. */ - byte f_type; /* SINGLE, DOUBLE,POINTER,UNKNOWN */ - formal_p f_next; /* link */ -}; - - -/* flags of formal: */ - -#define FF_BAD 01 -#define FF_REG 02 -#define FF_ONCEUSED 04 -#define FF_OFTENUSED 06 -#define USEMASK 014 - -/* types of formals: */ - -#define SINGLE 1 -#define DOUBLE 2 -#define POINTER 3 -#define UNKNOWN 4 - -/* 'call-count' information keeps track of the number - * of times one procedure calls another. Conceptually, - * it may be regarded as a two dimensional array, where - * calcnt[p,q] is the number of times p calls q. As this - * matrix would be very dense, we use a more efficient - * list representation. Every procedure has a list - * of calcnt structs. - */ - -struct calcnt { - proc_p cc_proc; /* the called procedure */ - short cc_count; /* # times proc. is called in the - * original text of the caller. - */ - calcnt_p cc_next; /* link */ -}; - - - - -extern int calnr; -extern calcnt_p cchead; /* calcnt info of current proc */ - -/* Macro's for extended data structures */ - -#define P_CALS p_extend->px_il.p_cals -#define P_SIZE p_extend->px_il.p_size -#define P_FORMALS p_extend->px_il.p_formals -#define P_NRCALLED p_extend->px_il.p_nrcalled -#define P_CCADDR p_extend->px_il.p_ccaddr -#define P_LADDR p_extend->px_il.p_laddr -#define P_ORGLABELS p_extend->px_il.p_orglabels -#define P_ORGLOCALS p_extend->px_il.p_orglocals - -/* flags2: */ - -#define PF_UNSUITABLE 01 -#define PF_NO_INLPARS 02 -#define PF_FALLTHROUGH 04 -#define PF_DISPENSABLE 010 -#define PF_CHANGED 020 - - -/* kinds of usages: */ - -#define USE 0 -#define CHANGE 1 -#define ADDRESS 2 - - - - -/* We do not expand calls if: - * - the called procedure has to many local variables - * - the calling procedure is already very large - * - the called procedure is to large. - */ - -#define MANY_LOCALS(p) (p->p_localbytes > LOCAL_THRESHOLD) -#define LOCAL_THRESHOLD 200 -#define BIG_CALLER(p) (p->P_SIZE > CALLER_THRESHOLD) -#define CALLER_THRESHOLD 500 -#define BIG_PROC(p) (p->P_SIZE > CALLEE_THRESHOLD) -#define CALLEE_THRESHOLD 100 - -#define FALLTHROUGH(p) (p->p_flags2 & PF_FALLTHROUGH) -#define DISPENSABLE(p) p->p_flags2 |= PF_DISPENSABLE -#define IS_DISPENSABLE(p) (p->p_flags2 & PF_DISPENSABLE) -#define SELECTED(c) c->cl_flags |= CLF_SELECTED -#define IS_SELECTED(c) (c->cl_flags & CLF_SELECTED) -#define EVER_EXPANDED(c) c->cl_flags |= CLF_EVER_EXPANDED -#define IS_EVER_EXPANDED(c) (c->cl_flags & CLF_EVER_EXPANDED) -#define UNSUITABLE(p) p->p_flags2 |= PF_UNSUITABLE -#define SUITABLE(p) (!(p->p_flags2&PF_UNSUITABLE)) -#define INLINE_PARS(p) (!(p->p_flags2&PF_NO_INLPARS)) -#define PARAMS_UNKNOWN(p) (p->p_nrformals == UNKNOWN_SIZE) - -extern int Ssubst; -#ifdef VERBOSE -extern int Senv,Srecursive,Slocals,Sinstrlab,Sparsefails,Spremoved,Scals; -extern int Sbig_caller,Sdispensable,Schangedcallee,Sbigcallee,Sspace,Szeroratio; -#endif - -/* extra core-allocation macros */ - -#define newcall() (call_p) newstruct(call) -#define newactual() (actual_p) newstruct(actual) -#define newformal() (formal_p) newstruct(formal) -#define newcalcnt() (calcnt_p) newstruct(calcnt) -#define newilpx() (pext_p) newstruct(pext_il) - -#define oldcall(x) oldstruct(call,x) -#define oldactual(x) oldstruct(actual,x) -#define oldformal(x) oldstruct(formal,x) -#define oldcalcnt(x) oldstruct(calcnt,x) -#define oldilpx(x) oldstruct(pext_il,x) diff --git a/util/ego/il/il1_anal.c b/util/ego/il/il1_anal.c deleted file mode 100644 index 2e8acd28c..000000000 --- a/util/ego/il/il1_anal.c +++ /dev/null @@ -1,177 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 1 _ A N A L . C - */ - -#include -#include "../share/types.h" -#include "il.h" -#include "../share/debug.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/aux.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "il1_aux.h" -#include "il1_formal.h" -#include "il1_cal.h" -#include "il1_anal.h" -#include "il_aux.h" -#include "../share/put.h" - -#define BODY_KNOWN(p) (p->p_flags1 & (byte) PF_BODYSEEN) -#define ENVIRON(p) (p->p_flags1 & (byte) PF_ENVIRON) -#define RETURN_BLOCK(b) (Lnrelems(b->b_succ) == 0) -#define LAST_BLOCK(b) (b->b_next == (bblock_p) 0) - -/* Daisy chain recursion not yet accounted for: */ -#define RECURSIVE(p) (Cis_elem(p->p_id,p->p_calling)) -/* -#define CALLS_UNKNOWN(p) (p->p_flags1 & (byte) PF_CALUNKNOWN) -*/ -#define CALLS_UNKNOWN(p) (FALSE) - - - -apriori(proctab) - proc_p proctab; -{ - /* For every procedure, see if we can determine - * from the information provided by the previous - * phases of the optimizer that it cannot or should not - * be expanded in line. This will reduce the length - * of the call list. - */ - - register proc_p p; - - for (p = proctab; p != (proc_p) 0; p = p->p_next) { - if (!BODY_KNOWN(p) || - ENVIRON(p) || RECURSIVE(p) || - PARAMS_UNKNOWN(p) || MANY_LOCALS(p)) { - UNSUITABLE(p); -#ifdef VERBOSE - if (BODY_KNOWN(p)) { - if (ENVIRON(p)) Senv++; - if (RECURSIVE(p)) Srecursive++; - if (MANY_LOCALS(p)) Slocals++; - } -#endif - } - } -} - - -STATIC check_labels(p,arglist) - proc_p p; - arg_p arglist; -{ - /* Check if any of the arguments contains an instruction - * label; if so, make p unsuitable. - */ - - arg_p arg; - - for (arg = arglist; arg != (arg_p) 0; arg = arg->a_next) { - if (arg->a_type == ARGINSTRLAB) { - UNSUITABLE(p); -#ifdef VERBOSE - Sinstrlab++; -#endif - break; - } - } -} - - - -STATIC anal_instr(p,b,cf) - proc_p p; - bblock_p b; - FILE *cf; -{ - /* Analyze the instructions of block b - * within procedure p. - * See which parameters are used, changed - * or have their address taken. Recognize - * the actual parameter expressions of - * the CAL instructions. - */ - - register line_p l; - - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - switch(INSTR(l)) { - case op_cal: - anal_cal(p,l,b,cf); - break; - case op_stl: - case op_inl: - case op_del: - case op_zrl: - formal(p,b,off_set(l),SINGLE,CHANGE); - /* see if the local is a parameter. - * If so, it is a one-word parameter - * that is stored into. - */ - break; - case op_sdl: - formal(p,b,off_set(l),DOUBLE,CHANGE); - break; - case op_lol: - formal(p,b,off_set(l),SINGLE,USE); - break; - case op_ldl: - formal(p,b,off_set(l),DOUBLE,USE); - break; - case op_sil: - case op_lil: - formal(p,b,off_set(l),POINTER,USE); - break; - case op_lal: - formal(p,b,off_set(l),UNKNOWN,ADDRESS); - break; - case ps_rom: - case ps_con: - case ps_bss: - case ps_hol: - check_labels(p,ARG(l)); - break; - } - } -} - - - -anal_proc(p,cf,ccf) - proc_p p; - FILE *cf,*ccf; -{ - /* Analyze a procedure; use information - * stored in its basic blocks or in - * its instructions. - */ - - register bblock_p b; - bool fallthrough = TRUE; - - cchead = (calcnt_p) 0; - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - if (RETURN_BLOCK(b) && !LAST_BLOCK(b)) { - fallthrough = FALSE; - /* p contains a RET instruction somewhere - * in the middle of its code. - */ - } - anal_instr(p,b,cf); /* analyze instructions */ - } - if (fallthrough) { - p->p_flags2 |= PF_FALLTHROUGH; - } - rem_indir_acc(p); - /* don't expand formal that may be accessed indirectly */ - p->P_CCADDR = putcc(cchead,ccf); - /* write calcnt info and remember disk address */ - remcc(cchead); -} diff --git a/util/ego/il/il1_anal.h b/util/ego/il/il1_anal.h deleted file mode 100644 index ed01629f5..000000000 --- a/util/ego/il/il1_anal.h +++ /dev/null @@ -1,17 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 1 _ A N A L . H - */ - -extern apriori(); /* (proc_p proctab) - * For every procedure, see if we can determine - * from the information provided by the previous - * phases of the optimizer that it cannot or should not - * be expanded in line. This will reduce the length - * of the call list. - */ -extern anal_proc(); /* (proc_p p, FILE *cf, *cff) - * Analyse a procedure. See which formal parameters - * it uses and which procedures it calls. - * cf and ccf are the call-file and the call-count file. - */ diff --git a/util/ego/il/il1_aux.c b/util/ego/il/il1_aux.c deleted file mode 100644 index b8602c024..000000000 --- a/util/ego/il/il1_aux.c +++ /dev/null @@ -1,208 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 1 _ A U X . C - */ - -#include "../share/types.h" -#include "il.h" -#include "../share/debug.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../../../h/em_spec.h" -#include "il_aux.h" -#include "il1_aux.h" - -#define CHANGE_INDIR(p) (p->p_change->c_flags & CF_INDIR) -#define USE_INDIR(p) (p->p_use->u_flags & UF_INDIR) - -#define IS_INSTR(c) (c >= sp_fmnem && c <= sp_lmnem) - - -bool same_size(t1,t2) - int t1, t2; -{ - /* See if the two types have the same size */ - - return tsize(t1) == tsize(t2); -} - - - -STATIC bool is_reg(off,s) - offset off; - int s; -{ - /* See if there is a register message - * for the local or parameter at offset off - * and size s. - */ - - Lindex i; - arg_p arg; - - for (i = Lfirst(mesregs); i != (Lindex) 0; i = Lnext(i,mesregs)) { - arg = ((line_p) Lelem(i))->l_a.la_arg->a_next; - if (arg->a_a.a_offset == off && - arg->a_next->a_a.a_offset == s) { - return TRUE; - } - } - return FALSE; -} - - -rem_actuals(acts) - actual_p acts; -{ - /* remove the actual-list */ - - actual_p a,next; - - for (a = acts; a != (actual_p) 0; a = next) { - next = a->ac_next; - /* REMOVE CODE OF a->ac_exp HERE */ - oldactual(a); - } -} - - - -remov_formals(p) - proc_p p; -{ - /* Remove the list of formals of p */ - - formal_p f, next; - - for (f = p->P_FORMALS; f != (formal_p) 0; f = next) { - next = f->f_next; - oldformal(f); - } - p->P_FORMALS = (formal_p) 0; -} - - - -rem_indir_acc(p) - proc_p p; -{ - /* Formals that may be accessed indirectly - * cannot be expanded in line, so they are - * removed from the formals list. - */ - - formal_p prev, f, next; - - if (!USE_INDIR(p) && !CHANGE_INDIR(p)) return; - /* Any formal for which we don't have - * a register message is now doomed. - */ - prev = (formal_p) 0; - for (f = p->P_FORMALS; f != (formal_p) 0; f = next) { - next = f->f_next; - if (!is_reg(f->f_offset,tsize(f->f_type))) { - if (prev == (formal_p) 0) { - p->P_FORMALS = next; - } else { - prev->f_next = next; - } - oldformal(f); - } - } -} - - - -bool par_overlap(off1,t1,off2,t2) - offset off1,off2; - int t1,t2; -{ - /* See if the parameter at offset off1 and type t1 - * overlaps the paramete at offset off2 and type t2. - */ - - if (off1 > off2) { - return off2 + tsize(t2) > off1; - } else { - if (off2 > off1) { - return off1 + tsize(t1) > off2; - } else { - return TRUE; - } - } -} - - - -short looplevel(b) - bblock_p b; -{ - /* determine the loop nesting level of basic block b; - * this is the highest nesting level of all blocks - * that b is part of. - * Note that the level of a loop is 0 for outer loops, - * so a block inside a loop with nesting level N has - * looplevel N+1. - */ - - Lindex i; - short max = 0; - - for (i = Lfirst(b->b_loops); i != (Lindex)0; i = Lnext(i,b->b_loops)) { - if (((loop_p) Lelem(i))->lp_level >= max) { - max = ((loop_p) Lelem(i))->lp_level + 1; - } - } - return max; -} - - - -short proclength(p) - proc_p p; -{ - /* count the number of EM instructions of p */ - - register short cnt; - register bblock_p b; - register line_p l; - - cnt = 0; - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - if (IS_INSTR(INSTR(l))) { - /* skip pseudo instructions */ - cnt++; - } - } - } - return cnt; -} - - - - - -line_p copy_code(l1,l2) - line_p l1,l2; -{ - /* copy the code between l1 and l2 */ - - line_p head, tail, l, lnp; - - head = (line_p) 0; - for (lnp = l1; ; lnp = lnp->l_next) { - l = duplicate(lnp); - if (head == (line_p) 0) { - head = tail = l; - PREV(l) = (line_p) 0; - } else { - tail->l_next = l; - PREV(l) = tail; - tail = l; - } - if (lnp == l2) break; - } - return head; -} diff --git a/util/ego/il/il1_aux.h b/util/ego/il/il1_aux.h deleted file mode 100644 index 9f7ee795f..000000000 --- a/util/ego/il/il1_aux.h +++ /dev/null @@ -1,38 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 1 _ A U X . H - */ - -extern bool same_size(); /* (int t1,t2) - * See if the two types t1 and t2 have - * the same size. - */ -extern rem_actuals(); /* (actual_p atcs) - * remove an actual-list from core. - */ -extern remov_formals(); /* (proc_p p) - * Remove the formals-list of p from core. - */ -extern rem_indir_acc(); /* (proc_p p) - * Remove formal that may be accessed - * indirectly from formal lists of p - */ -extern bool par_overlap(); /* (offset off1, int t1, offset off2, int t2) - * See if the formal at offset off1 and type t1 - * overlaps the formal at offset off2 - * and type t2. - */ -extern short looplevel(); /* (bblock_p b) - * Determine the loop nesting level of b. - */ -extern short proclength(); /* (proc_p p) - * Determine the number of EM instructions - * in p. Do not count pseudos. - */ - -extern line_p copy_code(); /* (line_p l1,l2) - * copy the code between l1 and l2. - * Pseudos may not be contained in - * the list of instructions. If l1==l2 - * the result is only one instruction. - */ diff --git a/util/ego/il/il1_cal.c b/util/ego/il/il1_cal.c deleted file mode 100644 index 7a694699b..000000000 --- a/util/ego/il/il1_cal.c +++ /dev/null @@ -1,138 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 1 _ C A L . C - */ - -#include -#include "../share/types.h" -#include "il.h" -#include "il1_cal.h" -#include "../share/debug.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_mnem.h" -#include "il1_aux.h" -#include "../share/parser.h" - -STATIC actual_p acts, *app; - -#define INIT_ACTS() {acts = (actual_p) 0; app = &acts;} -#define APPEND_ACTUAL(a) {*app = a; app = &a->ac_next;} - -STATIC make_actual(l1,l2,size) - line_p l1,l2; - offset size; -{ - /* Allocate a struct for a new actual parameter - * expression, the code of which extends from - * l1 to l2. - */ - - actual_p a; - - a = newactual(); - a->ac_exp = copy_code(l1,l2); - a->ac_size = size; - APPEND_ACTUAL(a); /* append it to actual-list */ -} - - - -STATIC bool chck_asp(p,l) - proc_p p; - line_p l; -{ - /* We require a call to a procedure p that has n formal - * parameters to be followed by an 'asp n' instruction - * (i.e. the caller should remove the actual parameters). - */ - - return (p->p_nrformals == 0 || (l != (line_p) 0 &&INSTR(l) == op_asp && - TYPE(l) == OPSHORT && SHORT(l) == p->p_nrformals)); -} - - - -STATIC inc_count(caller,callee) - proc_p caller, callee; -{ - /* Update the call-count information. - * Record the fact that there is one more call - * to 'callee', appearing in 'caller'. - */ - - calcnt_p cc; - - if (!SUITABLE(caller)) return; - /* if the calling routine is never expanded in line - * we do not need call-count information. - */ - for (cc = cchead; cc != (calcnt_p) 0; cc = cc->cc_next) { - if (cc->cc_proc == callee) { - cc->cc_count++; - /* #calls to callee from caller */ - return; - } - } - /* This is the first call from caller to callee. - * Allocate a new calcnt struct. - */ - cc = newcalcnt(); - cc->cc_proc = callee; - cc->cc_count = 1; - cc->cc_next = cchead; /* insert it at front of list */ - cchead = cc; -} - - - -anal_cal(p,call,b,cf) - proc_p p; - line_p call; - bblock_p b; - FILE *cf; -{ - /* Analyze a call instruction. If the called - * routine may be expanded in line, try to - * recognize the actual parameter expressions of - * the call and extend the call list. - */ - - call_p c; - line_p lnp; - proc_p callee; - -#ifdef VERBOSE - Scals++; -#endif - calnr++; - callee = PROC(call); - if (SUITABLE(callee)) { - /* The called procedure may be expanded */ - callee->P_NRCALLED++; /* #calls to callee from anywhere */ - INIT_ACTS(); - if (parse(PREV(call),callee->p_nrformals,&lnp,0,make_actual) && - chck_asp(callee,call->l_next)) { - /* succeeded in recognizing the actuals */ - c = newcall(); - c->cl_caller = p; - c->cl_id = calnr; - c->cl_proc = callee; - c->cl_looplevel = (byte) looplevel(b); - if (c->cl_looplevel > 0 && IS_FIRM(b)) { - c->cl_flags |= CLF_FIRM; - } - c->cl_actuals = acts; - inc_count(p,callee); - /* update call-count info */ - putcall(c,cf,(short) 0); /* write the call to the calfile */ - } else { -#ifdef VERBOSE - Sparsefails++; -#endif - rem_actuals(acts); - } - } -} diff --git a/util/ego/il/il1_cal.h b/util/ego/il/il1_cal.h deleted file mode 100644 index 191e7ae58..000000000 --- a/util/ego/il/il1_cal.h +++ /dev/null @@ -1,31 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 1 _ C A L . C - */ - -struct class { - byte src_class; - byte res_class; -}; - -typedef struct class *class_p; - -extern struct class classtab[]; - -#define NOCLASS 0 -#define CLASS1 1 -#define CLASS2 2 -#define CLASS3 3 -#define CLASS4 4 -#define CLASS5 5 -#define CLASS6 6 -#define CLASS7 7 -#define CLASS8 8 -#define CLASS9 9 - - -extern anal_cal(); /* (line_p call, bblock_p b) - * analyze a call instruction; - * try to recognize the actual parameter - * expressions. - */ diff --git a/util/ego/il/il1_formal.c b/util/ego/il/il1_formal.c deleted file mode 100644 index 1a616efcc..000000000 --- a/util/ego/il/il1_formal.c +++ /dev/null @@ -1,141 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 1 _ F O R M A L . C - */ - -#include "../share/types.h" -#include "il.h" -#include "../share/debug.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "il1_aux.h" -#include "il1_formal.h" - -#define NOT_USED(f) (!(f->f_flags & USEMASK)) -#define USED_ONCE(f) f->f_flags |= FF_ONCEUSED -#define USED_OFTEN(f) f->f_flags |= FF_OFTENUSED -#define BADFORMAL(f) f->f_flags |= FF_BAD - -#define OUTSIDE_LOOP(b) (Lnrelems(b->b_loops) == 0) -#define IS_FORMAL(x) (x >= 0) - - - -formal_p find_formal(p,type,off) - proc_p p; - int type; - offset off; -{ - /* Find a formal parameter of p - * If the formal overlaps with an existing formal - * or has an unknown type (i.e. its address is used) - * 0 is returned. - */ - - formal_p f,prev,nf; - - if (type == UNKNOWN) return (formal_p) 0; - prev = (formal_p) 0; - for (f = p->P_FORMALS; f != (formal_p) 0; f = f->f_next) { - if (f->f_offset >= off) break; - prev = f; - } - if (f != (formal_p) 0 && f->f_offset == off) { - return (same_size(f->f_type,type) ? f : (formal_p) 0); - } - if (f != (formal_p) 0 && par_overlap(off,type,f->f_offset,f->f_type)) { - return (formal_p) 0; - } - if (prev != (formal_p) 0 && par_overlap(prev->f_offset,prev->f_type, - off,type)) { - return (formal_p) 0; - } - nf = newformal(); - nf->f_type = type; - nf->f_offset = off; - if (prev == (formal_p) 0) { - p->P_FORMALS = nf; - } else { - prev->f_next = nf; - } - nf->f_next = f; - return nf; -} - - - -STATIC no_inl_pars(p) - proc_p p; -{ - /* p may not have any in line parameters */ - - p->p_flags2 |= PF_NO_INLPARS; - remov_formals(p); -} - - - -STATIC inc_use(f,b) - formal_p f; - bblock_p b; -{ - /* Increment the use count of formal f. - * The counter has only three states: not used, - * used once, used more than once. - * We count the number of times the formal - * is used dynamically (rather than statically), - * so if it is used in a loop, the counter - * is always set to more than once. - */ - - if (NOT_USED(f) && OUTSIDE_LOOP(b)) { - USED_ONCE(f); - } else { - USED_OFTEN(f); - } -} - - - -formal(p,b,off,type,usage) - proc_p p; - bblock_p b; - offset off; - int type, - usage; -{ - /* Analyze a reference to a parameter of p - * (occurring within basic block b). - * The parameter has offset off. If this - * offset is less than 0, it is not a - * parameter, but a local. - * The type can be SINGLE (1 word), DOUBLE - * (2 words), POINTER or UNKNOWN. - */ - - formal_p f; - - if (!IS_FORMAL(off) || !SUITABLE(p) || !INLINE_PARS(p)) return; - /* We are not interested in formal parameters of - * proccedures that will never be expanded in line, - * or whose parameters will not be expanded in line. - */ - f = find_formal(p,type,off); - /* Find the formal; if not found, create one; - * if inconsistent with previous formals (e.g. - * overlapping formals) then return 0; - * also fills in its type. - */ - if (f == (formal_p) 0) { - no_inl_pars(p); - /* parameters of p may not be expanded in line */ - } else { - if (usage == CHANGE) { - /* don't expand f in line */ - BADFORMAL(f); - } else { - inc_use(f,b); /* increment use count */ - } - } -} diff --git a/util/ego/il/il1_formal.h b/util/ego/il/il1_formal.h deleted file mode 100644 index 062043c7b..000000000 --- a/util/ego/il/il1_formal.h +++ /dev/null @@ -1,11 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 1 _ F O R M A L . C - */ - -extern formal(); /* (proc_p p; bblock_p b; offset off; - * int type, usage) - * Analyze a reference to a parameter of p. - * The type denotes its size (single,double, - * pointer). - */ diff --git a/util/ego/il/il2_aux.c b/util/ego/il/il2_aux.c deleted file mode 100644 index 1a82a0aea..000000000 --- a/util/ego/il/il2_aux.c +++ /dev/null @@ -1,720 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 2 _ A U X . C - */ - -#include -#include "../share/types.h" -#include "il.h" -#include "../share/debug.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_mnem.h" -#include "il_aux.h" -#include "il2_aux.h" -#include "../share/get.h" -#include "../share/aux.h" - -#define CHANGE_INDIR(p) (p->p_change->c_flags & CF_INDIR) -#define USE_INDIR(p) (p->p_use->u_flags & UF_INDIR) - -#define OFTEN_USED(f) ((f->f_flags&FF_OFTENUSED) == FF_OFTENUSED) -#define CHANGE_EXT(p) (Cnrelems(p->p_change->c_ext) > 0) -#define NOT_INLINE(a) (a->ac_inl = FALSE) -#define INLINE(a) (a->ac_inl = TRUE) - - -#define CHANGED(p) p->p_flags2 |= PF_CHANGED -#define IS_CHANGED(p) (p->p_flags2 & PF_CHANGED) - - - -STATIC bool match_pars(fm,act) - formal_p fm; - actual_p act; -{ - /* Check if every actual parameter has the same - * size as its corresponding formal. If not, the - * actual parameters should not be expanded in line. - */ - - while (act != (actual_p) 0) { - if (fm == (formal_p) 0 || tsize(fm->f_type) != act->ac_size) { - return FALSE; - } - act = act->ac_next; - fm = fm->f_next; - } - return (fm == (formal_p) 0 ? TRUE : FALSE); -} - - -STATIC bool change_act(p,act) - proc_p p; - actual_p act; -{ - /* See if a call to p migth change any of the - * operands of the actual parameter expression. - * If the parameter is to be expanded in line, - * we must be sure its value does not depend - * on the point in the program where it is - * evaluated. - */ - - line_p l; - - for (l = act->ac_exp; l != (line_p) 0; l = l->l_next) { - switch(INSTR(l)) { - case op_lil: - case op_lof: - case op_loi: - case op_los: - case op_ldf: - return TRUE; - /* assume worst case */ - case op_lol: - case op_ldl: - if (CHANGE_INDIR(p)) { - return TRUE; - } - break; - case op_loe: - case op_lde: - if (CHANGE_INDIR(p) || CHANGE_EXT(p)) { - return TRUE; - } - break; - } - } - return FALSE; -} - - - -STATIC bool is_simple(expr) - line_p expr; -{ - /* See if expr is something simple, i.e. a constant or - * a variable. So the expression must consist of - * only one instruction. - */ - - - if (expr->l_next == (line_p) 0) { - switch(INSTR(expr)) { - case op_loc: - case op_ldc: - case op_lol: - case op_ldl: - case op_loe: - case op_lde: - return TRUE; - } - } - return FALSE; -} - - - -STATIC bool too_expensive(fm,act) - formal_p fm; - actual_p act; -{ - /* If the formal parameter is used often and the - * actual parameter is not something simple - * (i.e. an expression, not a constant or variable) - * it may be too expensive too expand the parameter - * in line. - */ - - return (OFTEN_USED(fm) && !is_simple(act->ac_exp)); -} -bool anal_params(c) - call_p c; -{ - /* Determine which of the actual parameters of a - * call may be expanded in line. - */ - - proc_p p; - actual_p act; - formal_p form; - int inlpars = 0; - - p = c->cl_proc; /* the called procedure */ - if (!match_pars(p->P_FORMALS, c->cl_actuals)) return FALSE; - if (!INLINE_PARS(p)) { - for (act = c->cl_actuals; act != (actual_p) 0; - act = act->ac_next) { - NOT_INLINE(act); - } - return TRUE; /* "# of inline pars." field in cl_flags remains 0 */ - } - for (act = c->cl_actuals, form = p->P_FORMALS; act != (actual_p) 0; - act = act->ac_next, form = form->f_next) { - if (form->f_flags & FF_BAD || - change_act(p,act) || too_expensive(form,act)) { - NOT_INLINE(act); - } else { - INLINE(act); - inlpars++; - } - } - if (inlpars > 15) inlpars = 15; /* We've only got 4 bits! */ - c->cl_flags |= inlpars; /* number of inline parameters */ - return TRUE; -} - - -STATIC short space_saved(c) - call_p c; -{ - /* When a call gets expanded in line, the total size of the - * code usually gets incremented, because we have to - * duplicate the text of the called routine. However, we save - * ourselves a CAL instruction and possibly anASP instruction - * (if the called procedure has parameters). Moreover, if we - * can put some parameters in line, we don't have to push - * their results on the stack before doing the call, so we - * save some code here too. The routine estimates the amount of - * code saved, expressed in number of EM instructions. - */ - - return (1 + (c->cl_flags & CLF_INLPARS) + (c->cl_proc->p_nrformals>0)); -} - -STATIC short param_score(c) - call_p c; -{ - /* If a call has an inline parameter that is a constant, - * chances are high that other optimization techniques - * can do further optimizations, especially if the constant - * happens to be "0". So the call gets extra points for this. - */ - - register actual_p act; - line_p l; - short score = 0; - - for (act = c->cl_actuals; act != (actual_p) 0; act = act->ac_next) { - if (act->ac_inl) { - l = act->ac_exp; - if (l->l_next == (line_p) 0 && - (INSTR(l) == op_loc || INSTR(l) == op_ldc)) { - score += (off_set(l) == (offset) 0 ? 2 : 1); - /* 0's count for two! */ - } - } - } - return score; -} - - - - - -assign_ratio(c) - call_p c; -{ - /* This routine is one of the most important ones - * of the inline substitution phase. It assigns a number - * (a 'ratio') to a call, indicating how desirable - * it is to expand the call in line. - * Currently, a very simplified straightforward heuristic - * is used. - */ - - short ll, loopfact, ratio; - - ll = c->cl_proc->P_SIZE - space_saved(c); - if (ll <= 0) ll = 1; - ratio = 1000 / ll; - if (ratio == 0) ratio = 1; - /* Add points if the called procedure falls through - * it's end (no BRA needed) or has formal parameters - * (ASP can be deleted). - */ - if (c->cl_proc->p_flags2 & PF_FALLTHROUGH) { - ratio += 10; - } - if (c->cl_proc->p_nrformals > 0) { - ratio += 10; - } - if (c->cl_caller->p_localbytes == 0) { - ratio -= 10; - } - ratio += (10 *param_score(c)); - /* Extra points for constants as parameters */ - if (ratio <= 0) ratio = 1; - ll = c->cl_looplevel+1; - if (ll == 1 && !IS_CALLED_IN_LOOP(c->cl_caller)) ll = 0; - /* If the call is not in a loop and the called proc. is never called - * in a loop, ll is set to 0. - */ - loopfact = (ll > 3 ? 10 : ll*ll); - ratio *= loopfact; - if (c->cl_flags & CLF_FIRM) { - ratio = 2*ratio; - } - c->cl_ratio = ratio; -} - - -call_p abstract(c) - call_p c; -{ - /* Abstract information from the call that is essential - * for choosing the calls that will be expanded. - * Put the information is an 'abstracted call'. - */ - - call_p a; - - a = newcall(); - a->cl_caller = c->cl_caller; - a->cl_id = c->cl_id; - a->cl_proc = c->cl_proc; - a->cl_looplevel = c->cl_looplevel; - a->cl_ratio = c->cl_ratio; - a->cl_flags = c->cl_flags; - return a; -} - - - -STATIC adjust_counts(callee,ccf) - proc_p callee; - FILE *ccf; -{ - /* A call to callee is expanded in line; - * the text of callee is not removed, so - * every proc called by callee gets its - * P_NRCALLED field incremented. - */ - - calcnt_p cc, head; - - head = getcc(ccf,callee); /* get calcnt info of called proc */ - for (cc = head; cc != (calcnt_p) 0; cc = cc->cc_next) { - cc->cc_proc->P_NRCALLED += cc->cc_count; - } - remcc(head); /* remove calcnt info */ -} - - - -STATIC bool is_dispensable(callee,ccf) - proc_p callee; - FILE *ccf; -{ - /* A call to callee is expanded in line. - * Decrement its P_NRCALLED field and see if - * it can now be removed because it is no - * longer called. Procedures that ever have - * their address taken (via LPI) will never - * be removed, as they might be called indirectly. - */ - - if ((--callee->P_NRCALLED) == 0 && - (callee->p_flags1 & PF_LPI) == 0) { - DISPENSABLE(callee); - OUTTRACE("procedure %d can be removed",callee->p_id); -#ifdef VERBOSE - Spremoved++; -#endif - return TRUE; - } else { - adjust_counts(callee,ccf); - return FALSE; - } -} - - - - -STATIC call_p nested_calls(a) - call_p a; -{ - /* Get a list of all calls that will appear in the - * EM text if the call 'a' is expanded in line. - * These are the calls in the P_CALS list of the - * called procedure. - */ - - call_p c, cp, head, *cpp; - - head = (call_p) 0; - cpp = &head; - for (c = a->cl_proc->P_CALS; c != (call_p) 0; c = c->cl_cdr) { - cp = abstract(c); - cp->cl_looplevel += a->cl_looplevel; - cp->cl_flags = (byte) 0; - if (a->cl_flags & CLF_FIRM) { - cp->cl_flags |= CLF_FIRM; - } - assign_ratio(cp); - *cpp = cp; - cpp = &cp->cl_cdr; - } - return head; -} - - - - -STATIC call_p find_origin(c) - call_p c; -{ - /* c is a nested call. Find the original call. - * This origional must be in the P_CALS list - * of the calling procedure. - */ - - register call_p x; - - for (x = c->cl_caller->P_CALS; x != (call_p) 0; x = x->cl_cdr) { - if (x->cl_id == c->cl_id) return x; - } - assert(FALSE); - /* NOTREACHED */ -} - - - -STATIC selected(a) - call_p a; -{ - /* The call a is selected for in line expansion. - * Mark the call as being selected and get the - * calls nested in it; these will be candidates - * too now. - */ - - SELECTED(a); - EVER_EXPANDED(find_origin(a)); - a->cl_car = nested_calls(a); -} - - - - -STATIC compare(x,best,space) - call_p x, *best; - short space; -{ - /* See if x is better than the current best choice */ - - if (x != (call_p) 0 && !IS_CHANGED(x->cl_proc) && - x->cl_proc->P_SIZE - space_saved(x) <= space) { - if ((*best == (call_p) 0 && x->cl_ratio != 0) || - (*best != (call_p) 0 && x->cl_ratio > (*best)->cl_ratio )) { - *best = x; - } - } -} - - - - -STATIC call_p best_one(list,space) - call_p list; - short space; -{ - /* Find the best candidate of the list - * that has not already been selected. The - * candidate must fit in the given space. - * We look in the cdr as well as in the car - * direction. - */ - - call_p best = (call_p) 0; - call_p x,c; - - for (c = list; c != (call_p) 0; c = c->cl_cdr) { - if (IS_SELECTED(c)) { - compare(best_one(c->cl_car,space),&best,space); - } else { - compare(c,&best,space); - } - } - return best; -} - - - -STATIC singles(cals) - call_p cals; -{ - /* If a procedure is only called once, this call - * will be expanded in line, because it costs - * no extra space. - */ - - call_p c; - - for (c = cals; c != (call_p) 0; c = c->cl_cdr) { - if (IS_SELECTED(c)) { - singles(c->cl_car); - } else { - if (c->cl_proc->P_NRCALLED == 1 && - !IS_CHANGED(c->cl_proc) && - (c->cl_proc->p_flags1 & PF_LPI) == 0) { - c->cl_proc->P_NRCALLED = 0; - SELECTED(c); - EVER_EXPANDED(find_origin(c)); - DISPENSABLE(c->cl_proc); - CHANGED(c->cl_caller); - OUTTRACE("procedure %d can be removed", - c->cl_proc->p_id); -#ifdef VERBOSE - Spremoved++; -#endif - } - } - } -} - - - -STATIC single_calls(proclist) - proc_p proclist; -{ - proc_p p; - - for (p = proclist; p != (proc_p) 0; p = p->p_next) { - if (!BIG_CALLER(p) && !IS_DISPENSABLE(p)) { - /* Calls appearing in a large procedure or in - * a procedure that was already eliminated - * are not considered. - */ - singles(p->P_CALS); - } - } -} - - - - -select_calls(proclist,ccf,space) - proc_p proclist; - FILE *ccf; - short space ; -{ - /* Select all calls that are to be expanded in line. */ - - proc_p p,chp; - call_p best, x; - - for (;;) { - best = (call_p) 0; - chp = (proc_p) 0; /* the changed procedure */ - for (p = proclist; p != (proc_p) 0; p = p->p_next) { - if (!BIG_CALLER(p) && !IS_DISPENSABLE(p)) { - /* Calls appearing in a large procedure or in - * a procedure that was already eliminated - * are not considered. - */ - x = best_one(p->P_CALS,space); - compare(x,&best,space); - if (x == best) chp = p; - } - } - if (best == (call_p) 0) break; - if (!is_dispensable(best->cl_proc,ccf)) { - space -= (best->cl_proc->P_SIZE - space_saved(best)); - } - selected(best); - CHANGED(chp); - } - single_calls(proclist); -#ifdef VERBOSE - Sstat(proclist,space); -#endif -} - - - - -STATIC nonnested_calls(cfile) - FILE *cfile; -{ - register call_p c,a; - - while((c = getcall(cfile)) != (call_p) 0) { - /* find the call in the call list of the caller */ - for (a = c->cl_caller->P_CALS; - a != (call_p) 0 && c->cl_id != a->cl_id; a = a->cl_cdr); - assert(a != (call_p) 0 && a->cl_proc == c->cl_proc); - if (IS_EVER_EXPANDED(a)) { - a->cl_actuals = c->cl_actuals; - c->cl_actuals = (actual_p) 0; - } - rem_call(c); - } -} - - - -STATIC copy_pars(src,dest) - call_p src, dest; -{ - /* Copy the actual parameters of src to dest. */ - - actual_p as,ad, *app; - - app = &dest->cl_actuals; - for (as = src->cl_actuals; as != (actual_p) 0; as = as->ac_next) { - ad = newactual(); - ad->ac_exp = copy_expr(as->ac_exp); - ad->ac_size = as->ac_size; - ad->ac_inl = as->ac_inl; - *app = ad; - app = &ad->ac_next; - } -} - - - -STATIC nest_pars(cals) - call_p cals; -{ - /* Recursive auxiliary procedure of add_actuals. */ - - call_p c,org; - - for (c = cals; c != (call_p) 0; c = c->cl_cdr) { - if (IS_SELECTED(c)) { - org = find_origin(c); - copy_pars(org,c); - nest_pars(c->cl_car); - } - } -} - - - -add_actuals(proclist,cfile) - proc_p proclist; - FILE *cfile; -{ - /* Fetch the actual parameters of all selected calls. - * For all non-nested calls (i.e. those calls that - * appeared originally in the EM text), we get the - * parameters from the cal-file. - * For nested calls (i.e. calls - * that are a result of in line substitution) we - * get the parameters from the original call. - */ - - proc_p p; - call_p a; - - nonnested_calls(cfile); - for (p = proclist; p != (proc_p) 0; p = p->p_next) { - for (a = p->P_CALS; a != (call_p) 0; a = a->cl_cdr) { - nest_pars(a->cl_car); - } - } -} - - - -STATIC clean(cals) - call_p *cals; -{ - call_p c,next,*cpp; - - /* Recursive auxiliary routine of cleancals */ - - cpp = cals; - for (c = *cpp; c != (call_p) 0; c = next) { - next = c->cl_cdr; - if (IS_SELECTED(c)) { - clean(&c->cl_car); - cpp = &c->cl_cdr; - } else { - assert(c->cl_car == (call_p) 0); - oldcall(c); - *cpp = next; - } - } -} - - -cleancals(proclist) - proc_p proclist; -{ - /* Remove all calls in the P_CALS list of p - * that were not selected for in line expansion. - */ - - register proc_p p; - - for (p = proclist; p != (proc_p) 0; p = p->p_next) { - clean(&p->P_CALS); - } -} - - - - -append_abstract(a,p) - call_p a; - proc_p p; -{ - /* Append an abstract of a call-descriptor to - * the call-list of procedure p. - */ - - call_p c; - - if (p->P_CALS == (call_p) 0) { - p->P_CALS = a; - } else { - for (c = p->P_CALS; c->cl_cdr != (call_p) 0; c = c->cl_cdr); - c->cl_cdr = a; - } -} - - -#ifdef VERBOSE - -/* At the end, we traverse the entire call-list, to see why the - * remaining calls were not expanded inline. - */ - - -Sstatist(list,space) - call_p list; - short space; -{ - call_p c; - - for (c = list; c != (call_p) 0; c = c->cl_cdr) { - if (IS_SELECTED(c)) { - Sstatist(c->cl_car,space); - } else { - if (IS_CHANGED(c->cl_proc)) Schangedcallee++; - else if (BIG_PROC(c->cl_proc)) Sbigcallee++; - else if (c->cl_proc->P_SIZE > space) Sspace++; - else if (c->cl_ratio == 0) Szeroratio++; - else assert(FALSE); - } - } -} - -Sstat(proclist,space) - proc_p proclist; - short space; -{ - proc_p p; - - for (p = proclist; p != (proc_p) 0; p = p->p_next) { - if (BIG_CALLER(p)) Sbig_caller++; - else if (IS_DISPENSABLE(p)) Sdispensable++; - else Sstatist(p->P_CALS,space); - } -} -#endif diff --git a/util/ego/il/il2_aux.h b/util/ego/il/il2_aux.h deleted file mode 100644 index 73bded6dc..000000000 --- a/util/ego/il/il2_aux.h +++ /dev/null @@ -1,38 +0,0 @@ -extern bool anal_params(); /* (call_p c) - * See which parameters of the call - * may be expanded in line. - * If the formals and actuals do not - * match, return FALSE - */ -extern assign_ratio(); /* (call_p c) - * Assigna ratio number to the call, - * indicating how desirable it is to - * expand the call in line. - */ -extern call_p abstract(); /* (call_p c) - * Abstract essential information from - * the call. - */ -extern select_calls(); /* (call_p alist; FILE *ccf;short space) - * Select the best calls to be expanded. - * Every procedure gets a list of - * selected calls appearing in it. - * space is the amount of space that the - * program is allowed to grow - * (expressed in number of EM instructions). - */ -extern cleancals(); /* (proc_p plist) - * Remove all calls that were not selected. - */ -extern add_actuals(); /* (proc_p plist; FILE *cfile) - * Add the actual parameters to the descriptor abstracts - * of the selected calls. - * the calfile contains the full descriptors of all - * calls. - * These two are combined to yield a file of full - * descriptors of the selected calls. - */ -extern append_abstract(); /* (call_p a; proc_p p) - * Put the call-descriptor abstract in the p_cals - * list of p. - */ diff --git a/util/ego/il/il3_aux.c b/util/ego/il/il3_aux.c deleted file mode 100644 index 2572a892f..000000000 --- a/util/ego/il/il3_aux.c +++ /dev/null @@ -1,63 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 3 _ A U X . C - */ - - -#include "../share/types.h" -#include "il.h" -#include "../share/debug.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "il_aux.h" -#include "il3_aux.h" - - - -line_p last_line(lines) - line_p lines; -{ - /* Determine the last line of a list */ - - register line_p l; - - assert (lines != (line_p) 0); - for (l = lines; l->l_next != (line_p) 0; l = l->l_next); - return l; -} - - - -app_list(list,l) - line_p list,l; -{ - /* Append the list after line l */ - - line_p llast; - - assert(l != (line_p) 0); - assert (list != (line_p) 0); - llast = last_line(list); - llast->l_next = l->l_next; - if (l->l_next != (line_p) 0) { - PREV(l->l_next) = llast; - } - l->l_next = list; - PREV(list) = l; -} - - - -rem_line(l) - line_p l; -{ - /* Remove a line from the list */ - - if (PREV(l) != (line_p) 0) { - PREV(l)->l_next = l->l_next; - } - if (l->l_next != (line_p) 0) { - PREV(l->l_next) = PREV(l); - } - oldline(l); -} diff --git a/util/ego/il/il3_aux.h b/util/ego/il/il3_aux.h deleted file mode 100644 index afa8cdbd4..000000000 --- a/util/ego/il/il3_aux.h +++ /dev/null @@ -1,15 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 3 _ A U X . H - */ - -extern line_p last_line(); /* (line_p list) - * Find the last line of a list. - */ -extern app_list(); /* (line_p list,l) - * Put list after l - */ -extern rem_line(); /* (line_p l) - * Remove a line from a (doubly linked) - * list. - */ diff --git a/util/ego/il/il3_change.c b/util/ego/il/il3_change.c deleted file mode 100644 index 147ce7959..000000000 --- a/util/ego/il/il3_change.c +++ /dev/null @@ -1,584 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 3 _ C H A N G E . C - */ - - -#include -#include "../share/types.h" -#include "il.h" -#include "../share/debug.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/def.h" -#include "../share/lset.h" -#include "../share/aux.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_mes.h" -#include "../share/get.h" -#include "../share/put.h" -#include "il_aux.h" -#include "il3_change.h" -#include "il3_aux.h" - -/* chg_callseq */ - - - - -STATIC line_p par_expr(l,expr) - line_p l, expr; -{ - /* Find the first line of the expression of which - * l is the last line; expr contains a pointer - * to a copy of that expression; effectively we - * just have to tally lines. - */ - - line_p lnp; - - for (lnp = expr->l_next; lnp != (line_p) 0; lnp = lnp->l_next) { - assert(l != (line_p) 0); - l = PREV(l); - } - return l; -} - - - -STATIC rem_text(l1,l2) - line_p l1,l2; -{ - /* Remove the lines from l1 to l2 (inclusive) */ - - line_p l, lstop; - l = PREV(l1); - lstop = l2->l_next; - while (l->l_next != lstop) { - rem_line(l->l_next); - } -} - - - -STATIC store_tmp(p,l,size) - proc_p p; - line_p l; - offset size; -{ - /* Emit code to store a 'size'-byte value in a new - * temporary local variable in the stack frame of p. - * Put this code after line l. - */ - - line_p lnp; - - lnp = int_line(tmplocal(p,size)); /* line with operand temp. */ - if (size == ws) { - lnp->l_instr = op_stl; /* STL temp. */ - } else { - if (size == 2*ws) { - lnp->l_instr = op_sdl; /* SDL temp. */ - } else { - /* emit 'LAL temp; STI size' */ - lnp->l_instr = op_lal; - appnd_line(lnp,l); - l = lnp; - assert ((short) size == size); - lnp = newline(OPSHORT); - SHORT(lnp) = size; - lnp->l_instr = op_sti; - } - } - appnd_line(lnp,l); -} - - - -STATIC chg_actuals(c,cal) - call_p c; - line_p cal; -{ - /* Change the actual parameter expressions of the call. */ - - actual_p act; - line_p llast,lfirst,l; - - llast = PREV(cal); - for (act = c->cl_actuals; act != (actual_p) 0; act = act->ac_next) { - lfirst = par_expr(llast,act->ac_exp); - /* the code from lfirst to llast is a parameter expression */ - if (act->ac_inl) { - /* in line parameter; remove it */ - l = llast; - llast = PREV(lfirst); - rem_text(lfirst,l); - } else { - store_tmp(curproc,llast,act->ac_size); - /* put a "STL tmp" -like instruction after the code */ - llast = PREV(lfirst); - } - } -} - - - -STATIC rm_callpart(c,cal) - call_p c; - line_p cal; -{ - /* Remove the call part, consisting of a CAL, - * an optional ASP and an optional LFR. - */ - - line_p l; - - l= PREV(cal); - rem_line(cal); - if (c->cl_proc->p_nrformals > 0) { - /* called procedure has parameters */ - assert (INSTR(l->l_next) == op_asp); - rem_line(l->l_next); - } - if (INSTR(l->l_next) == op_lfr) { - rem_line(l->l_next); - } -} - - - -chg_callseq(c,cal,l_out) - call_p c; - line_p cal,*l_out; -{ - /* Change the calling sequence. The actual parameter - * expressions are changed (in line parameters are - * removed, all other ones now store their result - * in a temporary local of the caller); - * the sequence "CAL ; ASP ; LFR" is removed. - */ - - - chg_actuals(c,cal); - *l_out = PREV(cal); /* last instr. of new parameter part */ - rm_callpart(c,cal); -} - - -/* make_label */ - -line_p make_label(l,p) - line_p l; - proc_p p; -{ - /* Make sure that the instruction after l - * contains an instruction label. If this is - * not already the case, create a new label. - */ - - line_p lab; - - if (l->l_next != (line_p) 0 && INSTR(l->l_next) == op_lab) { - return l->l_next; - } - lab = newline(OPINSTRLAB); - lab->l_instr = op_lab; - p->p_nrlabels++; - INSTRLAB(lab) = p->p_nrlabels; - appnd_line(lab,l); - return lab; -} - - - -/* modify */ - -STATIC act_info(off,acts,ab_off,act_out,off_out) - offset off, ab_off, *off_out; - actual_p acts, *act_out; -{ - /* Find the actual parameter that corresponds to - * the formal parameter with the given offset. - * Return it via act_out. If the actual is not - * an in-line actual, determine which temporary - * local is used for it; return the offset of that - * local via off_out. - */ - - offset sum = 0, tmp = 0; - actual_p act; - - for (act = acts; act != (actual_p) 0; act = act->ac_next) { - if (!act->ac_inl) { - tmp -= act->ac_size; - } - if (sum >= off) { - /* found */ - *act_out = act; - if (!act->ac_inl) { - *off_out = tmp + sum - off + ab_off; - } else { - assert (sum == off); - } - return; - } - sum += act->ac_size; - } - assert(FALSE); -} - - - -STATIC store_off(off,l) - offset off; - line_p l; -{ - if (TYPE(l) == OPSHORT) { - assert ((short) off == off); - SHORT(l) = (short) off; - } else { - OFFSET(l) = off; - } -} - - - -STATIC inl_actual(l,expr) - line_p l, expr; -{ - /* Expand an actual parameter in line. - * A LOL or LDL instruction is replaced - * by an expression. - * A SIL or LIL is replaced by the expression - * followed by a STI or LOI. - */ - - line_p e, lnp, s; - short instr; - - instr = INSTR(l); - assert(expr != (line_p) 0); - e = copy_expr(expr); /* make a copy of expr. */ - if (instr == op_sil || instr == op_lil) { - s = int_line((offset) ws); - s->l_instr = (instr == op_sil ? op_sti : op_loi); - appnd_line(s,last_line(e)); - } else { - assert(instr == op_lol || instr == op_ldl); - } - lnp = PREV(l); - rem_line(l); - app_list(e,lnp); -} - - - -STATIC localref(l,c,ab_off,lb_off) - line_p l; - call_p c; - offset ab_off, lb_off; -{ - /* Change a reference to a local variable or parameter - * of the called procedure. - */ - - offset off, tmpoff; - actual_p act; - - off = off_set(l); - if (off < 0) { - /* local variable, only the offset changes */ - store_off(lb_off + off,l); - } else { - act_info(off,c->cl_actuals,ab_off,&act,&tmpoff); /* find actual */ - if (act->ac_inl) { - /* inline actual parameter */ - inl_actual(l,act->ac_exp); - } else { - /* parameter stored in temporary local */ - store_off(tmpoff,l); - } - } -} - - - -STATIC chg_mes(l,c,ab_off,lb_off) - line_p l; - call_p c; - offset ab_off, lb_off; -{ - /* The register messages of the called procedure - * must be changed. If the message applies to a - * local variable or to a parameter that is not - * expanded in line, the offset of the variable - * is changed; else the entire message is deleted. - */ - - offset off, tmpoff; - actual_p act; - arg_p arg; - - arg = ARG(l); - switch ((int) arg->a_a.a_offset) { - case ms_reg: - if ((arg = arg->a_next) != (arg_p) 0) { - /* "mes 3" without further argument is not changed */ - off = arg->a_a.a_offset; - if (off < 0) { - /* local variable */ - arg->a_a.a_offset += lb_off; - } else { - act_info(off,c->cl_actuals,ab_off,&act,&tmpoff); - if (act->ac_inl) { - /* in line actual */ - rem_line(l); - } else { - arg->a_a.a_offset = tmpoff; - } - } - } - break; - case ms_par: - rem_line(l); - break; - } -} - - - -STATIC chg_ret(l,c,lab) - line_p l,lab; - call_p c; -{ - /* Change the RET instruction appearing in the - * expanded text of a call. If the called procedure - * falls through, the RET is just deleted; else it - * is replaced by a branch. - */ - - line_p lnp, bra; - - lnp = PREV(l); - rem_line(l); - if (!FALLTHROUGH(c->cl_proc)) { - bra = newline(OPINSTRLAB); - bra->l_instr = op_bra; - INSTRLAB(bra) = INSTRLAB(lab); - appnd_line(bra,lnp); - } -} - - - -STATIC mod_instr(l,c,lab,ab_off,lb_off,lab_off) - line_p l,lab; - call_p c; - offset ab_off,lb_off; - int lab_off; -{ - if (TYPE(l) == OPINSTRLAB) { - INSTRLAB(l) += lab_off; - } else { - switch(INSTR(l)) { - case op_stl: - case op_inl: - case op_del: - case op_zrl: - case op_sdl: - case op_lol: - case op_ldl: - case op_sil: - case op_lil: - case op_lal: - localref(l,c,ab_off,lb_off); - break; - case op_ret: - chg_ret(l,c,lab); - break; - case ps_pro: - case ps_end: - case ps_sym: - case ps_hol: - case ps_bss: - case ps_con: - case ps_rom: - rem_line(l); - break; - case ps_mes: - chg_mes(l,c,ab_off,lb_off); - break; - } - } -} - - -modify(text,c,lab,ab_off,lb_off,lab_off) - line_p text,lab; - call_p c; - offset ab_off,lb_off; - int lab_off; -{ - /* Modify the EM text of the called procedure. - * References to locals and parameters are - * changed; RETs are either deleted or replaced - * by a BRA to the given label; PRO and END pseudos - * are removed; instruction labels are changed, in - * order to make them different from any label used - * by the caller; some messages need to be changed too. - * Note that the first line of the text is a dummy instruction. - */ - - register line_p l; - line_p next; - - for (l = text->l_next; l != (line_p) 0; l = next) { - next = l->l_next; - /* This is rather tricky. An instruction like - * LOL 2 may be replaced by a number of instructions - * (if the parameter is expanded in line). This inserted - * code, however, should not be modified! - */ - mod_instr(l,c,lab,ab_off,lb_off,lab_off); - } -} - - - -mod_actuals(nc,c,lab,ab_off,lb_off,lab_off) - call_p nc,c; - line_p lab; - offset ab_off,lb_off; - int lab_off; -{ - actual_p act; - line_p l, next, dum; - - dum = newline(OPNO); - PREV(dum) = (line_p) 0; - for (act = nc->cl_actuals; act != (actual_p) 0; act = act->ac_next) { - l = act->ac_exp; - assert(l != (line_p) 0); - /* Insert a dummy instruction before l */ - dum->l_next = l; - PREV(l) = dum; - while(l != (line_p) 0) { - next = l->l_next; - mod_instr(l,c,lab,ab_off,lb_off,lab_off); - l = next; - } - act->ac_exp = dum->l_next; - PREV(dum->l_next) = (line_p) 0; - } - oldline(dum); -} - - - -/* insert */ - -STATIC line_p first_nonpseudo(l) - line_p l; -{ - /* Find the first non-pseudo instruction of - * a list of instructions. - */ - - while (l != (line_p) 0 && INSTR(l) >= sp_fpseu && - INSTR(l) <= ps_last) l = l->l_next; - return l; -} - - - -insert(text,l,firstline) - line_p text,l,firstline; -{ - /* Insert the modified EM text of the called - * routine in the calling routine. Pseudos are - * put after the pseudos of the caller; all - * normal instructions are put at the place - * where the CAL originally was. - */ - - line_p l1,l2,lastpseu; - - l1 = text->l_next; - oldline(text); /* remove dummy head instruction */ - if (l1 == (line_p) 0) return; /* no text at all! */ - l2 = first_nonpseudo(l1); - if (l2 == (line_p) 0) { - /* modified code consists only of pseudos */ - app_list(l1,PREV(first_nonpseudo(firstline))); - } else { - if (l1 == l2) { - /* no pseudos */ - app_list(l2,l); - } else { - lastpseu = PREV(first_nonpseudo(firstline)); - PREV(l2)->l_next = (line_p) 0; /* cut link */ - app_list(l2,l); /* insert normal instructions */ - app_list(l1,lastpseu); - } - } -} - - - -liquidate(p,text) - proc_p p; - line_p text; -{ - /* All calls to procedure p were expanded in line, so - * p is no longer needed. However, we must not throw away - * any data declarations appearing in p. - * The proctable entry of p is not removed, as we do not - * want to create holes in this table; however the PF_BODYSEEN - * flag is cleared, so p gets the same status as a procedure - * whose body is unmkown. - */ - - line_p l, nextl, lastkept = (line_p) 0; - call_p c, nextc; - - for (l = text; l != (line_p) 0; l = nextl) { - nextl = l->l_next; - switch(INSTR(l)) { - case ps_sym: - case ps_hol: - case ps_bss: - case ps_con: - case ps_rom: - lastkept = l; - break; - default: - rem_line(l); - } - } - if (lastkept != (line_p) 0) { - /* There were some data declarations in p, - * so we'll turn p into a data-unit; we'll - * have to append an end-pseudo for this - * purpose. - */ - lastkept->l_next = newline(OPNO); - lastkept->l_next->l_instr = (byte) ps_end; - } - /* There may be some calls in the body of p that - * ought to be expanded in line. As p is removed - * anyway, there is no use in really performing - * these substitutions, so the call-descriptors - * are just thrown away. - */ - - for (c = p->P_CALS; c != (call_p) 0; c = nextc) { - nextc = c->cl_cdr; - rem_call(c); - } - /* change the proctable entry */ - p->p_flags1 &= (byte) ~PF_BODYSEEN; - oldchange(p->p_change); - olduse(p->p_use); -} diff --git a/util/ego/il/il3_change.h b/util/ego/il/il3_change.h deleted file mode 100644 index 835249412..000000000 --- a/util/ego/il/il3_change.h +++ /dev/null @@ -1,41 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 3 _ C H A N G E . C - */ - - -extern chg_callseq(); /* (call_p c; line_p cal, *l_out) - * Change the calling sequence of - * the call c. The parameters are - * changed and the sequence - * CAL - ASP - LFR is removed. - * cal points to the CAL instruction - * l_out indicates where the expanded - * text of the called routine must - * be put. - */ -extern line_p make_label(); /* (line_p l; proc_p p) - * Make sure that the instruction after - * l contains a label. If this is not - * already the case, create a new label. - */ -extern modify(); /* (line_p text; call_p c; line_p lab; - * offset ab_off, lb_off; int lab_off) - * Modify the EM text of the called - * procedure. - */ -extern mod_actuals(); /* (call_p nc,c; line_p lab; - * offset ab_off, lb_off; int lab_off) - * Modify the actual parameters of the - * call nc the same way as the text of - * call c would be modified. - */ -extern insert(); /* (line_p text,l,firstline) - * Insert the modified EM text. - * Pseudos are put after the pseudos - * of the caller. - */ -extern liquidate(); /* (proc_p p; line_p text) - * All calls to p were expanded in line, - * so p is no longer needed. - */ diff --git a/util/ego/il/il3_subst.c b/util/ego/il/il3_subst.c deleted file mode 100644 index a3601a36e..000000000 --- a/util/ego/il/il3_subst.c +++ /dev/null @@ -1,122 +0,0 @@ -/* I N L I N E S U B S T I T U T I O N - * - * I L 3 _ S U B S T . C - */ - -#include -#include "../share/types.h" -#include "il.h" -#include "../share/debug.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/get.h" -#include "../../../h/em_mnem.h" -#include "il_aux.h" -#include "il3_aux.h" -#include "il3_change.h" -#include "il3_subst.h" - -STATIC line_p fetch_text(lf,c) - FILE *lf; - call_p c; -{ - /* Read the EM text of the called procedure. - * We use random access I/O here. - */ - - line_p l; - proc_p p; - lset savmes; - - savmes = mesregs; - mesregs = Lempty_set(); - fseek(lf,c->cl_proc->P_LADDR,0); - l = get_text(lf,&p); - assert (p == c->cl_proc); - Ldeleteset(mesregs); - mesregs = savmes; - return l; -} - - - - -line_p scan_to_cal(lines,n) - line_p lines; - short n; -{ - /* Find the n-th CAL instruction */ - - register line_p l; - - for (l = lines; l != (line_p) 0; l = l->l_next) { - if (INSTR(l) == op_cal) { - if (--n == 0) return l; - } - } - return (line_p) 0; /* CAL not found */ -} - - - -substitute(lf,c,cal,firstline) - FILE *lf; - call_p c; - line_p cal,firstline; -{ - /* Perform in line substitution of the call described - * by c. The EM text of the called routine is fetched - * and modified, the calling sequence is changed, - * the modified routine is put at the place of the call - * and all global information (proctable etc.) is kept - * up to date. - */ - - line_p l, text, lab; - offset ab_off, lb_off; - line_p startscan, ncal; - short lastcid; - call_p nc; - - Ssubst++; - ab_off = - curproc->p_localbytes; - /* offset of temporaries for parameters - * that are not expanded in line. - */ - chg_callseq(c,cal,&l); - /* Change the calling sequence; l points to the place - * where the expanded text must be put - */ - text = fetch_text(lf,c); /* fetch EM text of called routine */ - lb_off = - curproc->p_localbytes; - /* offset of temps. for locals of called proc. */ - curproc->p_localbytes += c->cl_proc->P_ORGLOCALS; - /* locals of called routine are put in stack frame of caller */ - if (!FALLTHROUGH(c->cl_proc)) { - /* The called proc contains one or more RETurns - * somewhere in the middle of its text; these - * should be changed into a jump to the end - * of the text. We create a label for this - * purpose (if there was no one already). - */ - lab = make_label(l,curproc); - } - modify(text,c,lab,ab_off,lb_off,curproc->p_nrlabels); - curproc->p_nrlabels += c->cl_proc->P_ORGLABELS; - insert(text,l,firstline); - /* insert text; instructions are put after l, pseudos - * are put at beginning of caller. - */ - /* Now take care of the nested calls */ - startscan = l->l_next; - lastcid = 0; - for (nc = c->cl_car; nc != (call_p) 0; nc = nc->cl_cdr) { - mod_actuals(nc,c,lab,ab_off,lb_off,curproc->p_nrlabels); - ncal = scan_to_cal(startscan,nc->cl_id - lastcid); - assert(ncal != (line_p) 0); - startscan = scan_to_cal(ncal->l_next,1); - lastcid = nc->cl_id; - substitute(lf,nc,ncal,firstline); - } -} diff --git a/util/ego/il/il3_subst.h b/util/ego/il/il3_subst.h deleted file mode 100644 index d3e582f66..000000000 --- a/util/ego/il/il3_subst.h +++ /dev/null @@ -1,17 +0,0 @@ - -/* I N L I N E S U B S T I T U T I O N - * - * I L 3 _ S U B S T . H - */ - -extern line_p scan_to_cal(); /* (line_p lines; short n) - * Find the n-th cal instruction. - */ -extern substitute(); /* (FILE *lf;call_p c; line_ pcal,firstline) - * Perform in line substitution of the call described - * by c. The EM text of the called routine is fetched - * and modified, the calling sequence is changed, - * the modified routine is put at the place of the call - * and all global information (proctable etc.) is kept - * up to date. - */ diff --git a/util/ego/il/il_aux.c b/util/ego/il/il_aux.c deleted file mode 100644 index 8f3f1e558..000000000 --- a/util/ego/il/il_aux.c +++ /dev/null @@ -1,383 +0,0 @@ - -/* I N L I N E S U B S T I T U T I O N - * - * I L _ A U X . C - */ - -#include -#include "../share/types.h" -#include "il.h" -#include "../share/debug.h" -#include "../share/get.h" -#include "../share/put.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/map.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "il_aux.h" - - -int tsize(type) - int type; -{ - /* Determine the size of a variable of the - * given type. - */ - - switch(type) { - case SINGLE: return ws; - case DOUBLE: return 2*ws; - case POINTER: return ps; - default: assert(FALSE); - } - /* NOTREACHED */ -} - - - -line_p duplicate(lnp) - line_p lnp; -{ - /* Make a duplicate of an EM instruction. - * Pseudos may not be passed as argument. - */ - - line_p l; - - l = newline(TYPE(lnp)); - l->l_instr = INSTR(lnp); - switch(TYPE(l)) { - case OPNO: - break; - case OPSHORT: - SHORT(l) = SHORT(lnp); - break; - case OPOFFSET: - OFFSET(l) = OFFSET(lnp); - break; - case OPINSTRLAB: - INSTRLAB(l) = INSTRLAB(lnp); - break; - case OPOBJECT: - OBJ(l) = OBJ(lnp); - break; - case OPPROC: - PROC(l) = PROC(lnp); - break; - default: - assert(FALSE); /* cannot copy pseudo */ - } - return l; -} - - - - -line_p copy_expr(l1) - line_p l1; -{ - /* copy the expression */ - - line_p head, tail, l, lnp; - - head = (line_p) 0; - for (lnp = l1; lnp != (line_p) 0; lnp = lnp->l_next) { - l = duplicate(lnp); - if (head == (line_p) 0) { - head = tail = l; - PREV(l) = (line_p) 0; - } else { - tail->l_next = l; - PREV(l) = tail; - tail = l; - } - } - return head; -} - - - -rem_call(c) - call_p c; -{ - actual_p act, nexta; - call_p nc,nextc; - line_p l, nextl; - - for (act = c->cl_actuals; act != (actual_p) 0; act = nexta) { - nexta = act->ac_next; - for (l = act->ac_exp; l != (line_p) 0; l = nextl) { - nextl = l->l_next; - oldline(l); - } - oldactual(act); - } - nc = c->cl_car; - oldcall(c); - for (; nc != (call_p) 0; nc = nextc) { - /* Take care of nested calls */ - nextc = nc->cl_cdr; - rem_call(nc); - } -} - - - -/* rem_graph */ - -STATIC short remlines(l) - line_p l; -{ - - register line_p lnp; - line_p next; - - for (lnp = l; lnp != (line_p) 0; lnp = next) { - next = lnp->l_next; - oldline(lnp); - } -} - - - -remunit(kind,p,l) - short kind; - proc_p p; - line_p l; -{ - register bblock_p b; - bblock_p next; - Lindex pi; - loop_p lp; - - if (kind == LDATA) { - remlines(l); - return; - } - for (b = p->p_start; b != (bblock_p) 0; b = next) { - next = b->b_next; - remlines(b->b_start); - Ldeleteset(b->b_loops); - Ldeleteset(b->b_succ); - Ldeleteset(b->b_pred); - oldbblock(b); - } - for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; - pi = Lnext(pi,p->p_loops)) { - oldloop(Lelem(pi)); - } - Ldeleteset(p->p_loops); - oldmap(lmap,llength); - oldmap(lbmap,llength); - oldmap(bmap,blength); - oldmap(lpmap,lplength); -} -remcc(head) - calcnt_p head; -{ - calcnt_p cc, next; - - for (cc = head; cc != (calcnt_p) 0; cc = next) { - next = cc->cc_next; - oldcalcnt(cc); - } -} - - -/* Extra I/O routines */ - -call_p getcall(cf) - FILE *cf; -{ - /* read a call from the call-file */ - - call_p c; - proc_p voided; - actual_p act,*app; - short n,m; - - curinp = cf; - c = newcall(); - n = getshort(); /* void nesting level */ - if (feof(curinp)) return (call_p) 0; - c->cl_caller = pmap[getshort()]; - c->cl_id = getshort(); - c->cl_proc = pmap[getshort()]; - c->cl_looplevel = getbyte(); - c->cl_flags = getbyte(); - c->cl_ratio = getshort(); - app = &c->cl_actuals; - n = getshort(); - while(n--) { - act = newactual(); - m = getshort(); - act->ac_size = getoff(); - act->ac_inl = getbyte(); - act->ac_exp = getlines(cf,m,&voided); - *app = act; - app = &act->ac_next; - } - *app = (actual_p) 0; - return c; -} - - - -line_p get_text(lf,p_out) - FILE *lf; - proc_p *p_out; -{ - /* Read the EM text of one unit - * If it is a procedure, set p_out to - * the proc. just read. Else set p_out - * to 0. - */ - - line_p dumhead, l, lprev; - loop_p *oldlpmap = lpmap; - line_p *oldlmap = lmap; - short oldllength = llength; - short oldlastlabid = lastlabid; - - curinp = lf; - *p_out = (proc_p) 0; - dumhead = newline(OPNO); - /* The list of instructions is preceeded by a dummy - * line, to simplify list manipulation - */ - dumhead->l_instr = op_nop; /* just for fun */ - lprev = dumhead; - for (;;) { - l = read_line(p_out); - if (feof(curinp)) return (line_p) 0; - lprev->l_next = l; - PREV(l) = lprev; - if (INSTR(l) == ps_end) break; - if (INSTR(l) == ps_mes) { - message(l); - } - lprev = l; - } - /* The tables that map labels to instructions - * and labels to basic blocks are not used. - */ - if (*p_out != (proc_p) 0) { - oldmap(lmap,llength); - oldmap(lbmap,llength); - lmap = oldlmap; - lpmap = oldlpmap; - } - llength = oldllength; - lastlabid = oldlastlabid; - return dumhead; -} - - - -calcnt_p getcc(ccf,p) - FILE *ccf; - proc_p p; -{ - /* Get call-count info of procedure p */ - - calcnt_p head,cc,*ccp; - short i; - - fseek(ccf,p->p_extend->px_il.p_ccaddr,0); - curinp = ccf; - head = (calcnt_p) 0; - ccp = &head; - for (i = getshort(); i != (short) 0; i--) { - cc = *ccp = newcalcnt(); - cc->cc_proc = pmap[getshort()]; - cc->cc_count = getshort(); - ccp = &cc->cc_next; - } - return head; -} - - -/* The following routines are only used by the Inline Substitution phase */ - - -STATIC putactuals(alist,cfile) - actual_p alist; - FILE *cfile; -{ - /* output a list of actual parameters */ - - actual_p a,next; - line_p l; - int count; - - count = 0; - for (a = alist; a != (actual_p) 0; a = a->ac_next) count++; - outshort(count); /* number of actuals */ - for (a = alist; a != (actual_p) 0; a = next) { - next = a->ac_next; - count = 0; - for (l = a->ac_exp; l != (line_p) 0; l= l->l_next) count++; - outshort(count); /* length of actual */ - outoff(a->ac_size); - outbyte(a->ac_inl); - count = putlines(a->ac_exp,cfile); - oldactual(a); - } -} - - - -putcall(c,cfile,level) - call_p c; - FILE *cfile; - short level; -{ - /* output a call */ - - call_p nc,nextc; - - - curoutp = cfile; - outshort(level); /* nesting level */ - outshort(c->cl_caller->p_id); /* calling proc */ - outshort(c->cl_id); - outshort(c->cl_proc->p_id); /* called proc */ - outbyte(c->cl_looplevel); - outbyte(c->cl_flags); - outshort(c->cl_ratio); - putactuals(c->cl_actuals,cfile); - nc = c->cl_car; - oldcall(c); - for (; nc != (call_p) 0; nc = nextc) { - /* take care of nested calls */ - nextc = nc->cl_cdr; - putcall(nc,cfile,level+1); - } -} - -long putcc(head,ccf) - calcnt_p head; - FILE *ccf; -{ - /* Write call-count information to file ccf. - * Return the disk address of the info written. - */ - - calcnt_p cc; - long addr; - short cnt; - - addr = ftell(ccf); - curoutp = ccf; - cnt = 0; - for (cc = head; cc != (calcnt_p) 0;cc = cc->cc_next) cnt++; - outshort(cnt); - for (cc = head; cc != (calcnt_p) 0; cc = cc->cc_next) { - outproc(cc->cc_proc); - outshort(cc->cc_count); - } - return addr; -} diff --git a/util/ego/il/il_aux.h b/util/ego/il/il_aux.h deleted file mode 100644 index 798ab551e..000000000 --- a/util/ego/il/il_aux.h +++ /dev/null @@ -1,53 +0,0 @@ - -/* I N L I N E S U B S T I T U T I O N - * - * I L _ A U X . H - */ - -extern int tsize(); /* (int type) - * Determine the size of a variable of - * the given type. - */ -extern line_p duplicate(); /* (line_p lnp) - * Make a duplicate of the given EM - * instruction. Pseudos may not be - * passed as argumnets. - */ -extern line_p copy_expr(); /* (line_p l1) - * copy the expression l1. - * Pseudos may not be contained in - * the list of instructions. - */ -extern rem_call(); /* (call_p c) - * Remove a call from main memory. - */ -extern rem_graph(); /* (proc_p p) - * Remove the CFG and EM text of - * a procedure from core. - */ -extern remcc(); /* (calcnt_p head) - * Remove call-count info from core. - */ -extern call_p getcall(); /* (FILE *cf) - * Read a call from the call-file - */ -extern line_p get_text(); /* (FILE *lf; proc_p *p_out) - * Read the EM text of one procedure. - * The procedure read is returned via - * p_out. - */ -extern calcnt_p getcc(); /* (FILE *ccf; proc_p p) - * Read the call-count information - * of procedure p. - */ -extern putcall(); /* (call_p call; FILE *cfile; short level) - * Write the call - * with the given id to the given file. - * The level is the nesting level, used by - * putcall when it calls itself recurively. - * It should be 0 on outer levels. - */ -extern long putcc(); /* (calcnt_p head; FILE *ccf) - * Write call-count information to - * file ccf. - */ diff --git a/util/ego/lv/Makefile b/util/ego/lv/Makefile deleted file mode 100644 index 32298550d..000000000 --- a/util/ego/lv/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -lv.c - -OFILES=\ -lv.o - -HFILES=\ -lv.h - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/get.o $(SHR)/aux.o $(SHR)/put.o $(SHR)/map.o $(SHR)/alloc.o \ -$(SHR)/global.o $(SHR)/debug.o $(SHR)/lset.o $(SHR)/cset.o $(SHR)/parser.o \ -$(SHR)/files.o $(SHR)/locals.o $(SHR)/init_glob.o $(SHR)/go.o - -SHARE_MFILES=\ -$(SHR)/get.m $(SHR)/aux.m $(SHR)/put.m $(SHR)/map.m $(SHR)/alloc.m \ -$(SHR)/global.m $(SHR)/debug.m $(SHR)/lset.m $(SHR)/cset.m $(SHR)/parser.m \ -$(SHR)/files.m $(SHR)/locals.m $(SHR)/init_glob.m $(SHR)/go.m - -lv: $(OFILES) - $(CC) -o lv $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -lv_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o lv -.c $(LDFLAGS) lv.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO - -lv.o: ../../../h/em_mnem.h -lv.o: ../../../h/em_pseu.h -lv.o: ../../../h/em_spec.h -lv.o: ../share/alloc.h -lv.o: ../share/aux.h -lv.o: ../share/cset.h -lv.o: ../share/debug.h -lv.o: ../share/def.h -lv.o: ../share/files.h -lv.o: ../share/get.h -lv.o: ../share/global.h -lv.o: ../share/go.h -lv.o: ../share/init_glob.h -lv.o: ../share/locals.h -lv.o: ../share/lset.h -lv.o: ../share/map.h -lv.o: ../share/parser.h -lv.o: ../share/put.h -lv.o: ../share/types.h -lv.o: lv.h diff --git a/util/ego/lv/lv.c b/util/ego/lv/lv.c deleted file mode 100644 index d56d1febd..000000000 --- a/util/ego/lv/lv.c +++ /dev/null @@ -1,588 +0,0 @@ - -/* L I V E V A R I A B L E S A N A L Y S I S */ - -#include -#include "../share/types.h" -#include "lv.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/def.h" -#include "../share/files.h" -#include "../share/alloc.h" -#include "../share/map.h" -#include "../share/get.h" -#include "../share/put.h" -#include "../share/aux.h" -#include "../share/init_glob.h" -#include "../share/locals.h" -#include "../share/go.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" -#include "../share/parser.h" - -#define newlvbx() (bext_p) newstruct(bext_lv) -#define oldlvbx(x) oldstruct(bext_lv,x) - - -/* TEMPORARY: should be put in ../../../h/em_mes.h: */ -#define ms_liv 9 -#define ms_ded 10 - -short nrglobals; -short nrvars; - -STATIC int Slv; -STATIC bool mesgflag = FALSE; /* Suppress generation of live/dead info */ - - -STATIC clean_up() -{ - local_p *p; - - for (p = &locals[1]; p <= &locals[nrlocals]; p++) { - oldlocal(*p); - } - oldmap(locals,nrlocals); -} - - - -STATIC bool is_dir_use(l) - line_p l; -{ - /* See if l is a direct use of some variable - * (i.e. not through a pointer). A LIL is a - * direct use of some pointer variable - * (and an indirect use of some other variable). - * A SIL is also a direct use. - * A LOI, however, is not an direct use of a variable. - * An an increment/decrement instruction is regarded - * as a use here, and not as a definition, as the - * variable is first used and than defined. - */ - - switch(INSTR(l)) { - case op_dee: - case op_del: - case op_ine: - case op_inl: - case op_lde: - case op_ldl: - case op_lil: - case op_loe: - case op_lol: - case op_sil: - return TRUE; - default: - return FALSE; - } - /* NOTREACHED */ -} - - - -STATIC bool is_indir_use(l) - line_p l; -{ - /* See if instruction l uses some variable(s) indirectly, - * i.e. through a pointer or via a procedure call. - */ - - switch(INSTR(l)) { - case op_blm: - case op_bls: - case op_cai: - case op_cal: - case op_lar: - case op_ldf: - case op_lil: - case op_lof: - case op_loi: - case op_los: - case op_mon: - return TRUE; - default: - return FALSE; - } - /* NOTREACHED */ -} - - - -STATIC bool is_def(l) - line_p l; -{ - /* See if l does a direct definition */ - - switch(INSTR(l)) { - case op_sde: - case op_sdl: - case op_ste: - case op_stl: - case op_zre: - case op_zrl: - return TRUE; - default: - return FALSE; - } - /* NOTREACHED */ -} - - -STATIC def_use(p) - proc_p p; -{ - /* Compute DEF(b) and USE(b), for every basic block b - * of procedure p. DEF(b) contains the variables that - * are certain to be defined (assigned) in b - * before being used. USE(b) contains the variables - * that may be used in b, before being defined. - * (Note that uncertainty arises in the presence of - * pointers and procedure calls). - * We compute these sets, by scanning the text of - * the basic block from beginning till end. - */ - - register bblock_p b; - register line_p l; - short v; - bool found; - cset all_ind_uses; - - all_ind_uses = Cempty_set(nrvars); - for (v = 1; v < nrlocals; v++) { - if (!IS_REGVAR(locals[v])) { - Cadd(LOC_TO_VARNR(v),&all_ind_uses); - } - } - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - USE(b) = Cempty_set(nrvars); - DEF(b) = Cempty_set(nrvars); - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - if (is_def(l)) { - /* An direct definition (i.e. not - * through a pointer). - */ - var_nr(l,&v,&found); - if (found && !Cis_elem(v,USE(b))) { - /* We do maintain live-dead info - * for this variable, and it was - * not used earlier in b. - */ - Cadd(v, &DEF(b)); - } - } else { - if (is_dir_use(l)) { - var_nr(l,&v,&found); - if (found && !Cis_elem(v,DEF(b))) { - Cadd(v, &USE(b)); - } - } - if (is_indir_use(l)) { - /* Add variable that may be used - * by l to USE(b). - */ - Cjoin(all_ind_uses,&USE(b)); - } - } - } - } - Cdeleteset(all_ind_uses); -} - - - -STATIC unite_ins(bbset,setp) - lset bbset; - cset *setp; -{ - /* Take the union of L_IN(b), for all b in bbset, - * and put the result in setp. - */ - - Lindex i; - - Cclear_set(setp); - for (i = Lfirst(bbset); i != (Lindex) 0; i = Lnext(i,bbset)) { - Cjoin(L_IN((bblock_p) Lelem(i)), setp); - } -} - - - -STATIC solve_lv(p) - proc_p p; -{ - /* Solve the data flow equations for Live Variables, - * for procedure p. These equations are: - * (1) IN[b] = OUT[b] - DEF[b] + USE[b] - * (2) OUT(b) = IN(s1) + ... + IN(sn) ; - * where SUCC(b) = {s1, ... , sn} - */ - - register bblock_p b; - cset newout = Cempty_set(nrvars); - bool change = TRUE; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - L_IN(b) = Cempty_set(nrvars); - Ccopy_set(USE(b), &L_IN(b)); - L_OUT(b) = Cempty_set(nrvars); - } - while (change) { - change = FALSE; - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - unite_ins(b->b_succ,&newout); - if (!Cequal(newout,L_OUT(b))) { - change = TRUE; - Ccopy_set(newout, &L_OUT(b)); - Ccopy_set(newout, &L_IN(b)); - Csubtract(DEF(b), &L_IN(b)); - Cjoin(USE(b), &L_IN(b)); - } - } - } - Cdeleteset(newout); -} - - -STATIC live_variables_analysis(p) - proc_p p; -{ - make_localtab(p); - nrvars = nrglobals + nrlocals; - def_use(p); - solve_lv(p); -} - - -STATIC init_live_dead(b) - bblock_p b; -{ - /* For every register variable, see if it is - * live or dead at the end of b. - */ - - register short v; - local_p loc; - - for (v = 1; v <= nrlocals; v++) { - loc = locals[v]; - if (IS_REGVAR(loc) && Cis_elem(LOC_TO_VARNR(v),L_OUT(b))) { - LIVE(loc); - } else { - DEAD(loc); - } - } -} - - - -STATIC line_p make_mesg(mesg,loc) - short mesg; - local_p loc; -{ - /* Create a line for a message stating that - * local variable loc is live/dead. This message - * looks like: "mes ms_liv,off,size" or - * "mes ms_ded,off,size". - */ - - line_p l = newline(OPLIST); - register arg_p ap; - - l->l_instr = ps_mes; - ap = ARG(l) = newarg(ARGOFF); - ap->a_a.a_offset = mesg; - ap = ap->a_next = newarg(ARGOFF); - ap->a_a.a_offset = loc->lc_off; - ap = ap->a_next = newarg(ARGOFF); - ap->a_a.a_offset = loc->lc_size; - return l; -} - - - -STATIC block_entry(b,prev) - bblock_p b,prev; -{ - short v,vn; - local_p loc; - bool was_live, is_live; - - /* Generate a live/dead message for every register variable that - * was live at the end of prev, but dead at the beginning of b, - * or v.v. If prev = 0 (i.e. begin of procedure), parameters were - * live, normal local variables were dead. - */ - - for (v = 1; v <= nrlocals; v++) { - loc = locals[v]; - vn = LOC_TO_VARNR(v); - if (prev == (bblock_p) 0) { - was_live = loc->lc_off >= 0; - } else { - was_live = Cis_elem(vn,L_OUT(prev)); - } - is_live = Cis_elem(vn,L_IN(b)); - if (was_live != is_live) { - app_block(make_mesg((is_live?ms_liv:ms_ded),loc),b); - } - } -} - - - -STATIC app_block(l,b) - line_p l; - bblock_p b; -{ - line_p x = b->b_start; - - if (x != (line_p) 0 && INSTR(x) == ps_pro) { - /* start of procedure; append after pro pseudo ! */ - if ((l->l_next = x->l_next) != (line_p) 0) { - PREV(l->l_next) = l; - } - x->l_next = l; - PREV(l) = x; - } else { - if ((l->l_next = x) != (line_p) 0) { - PREV(l->l_next) = l; - } - b->b_start = l; - PREV(l) = (line_p) 0; - } -} - - - -STATIC definition(l,useless_out,v_out,mesgflag) - line_p l; - bool *useless_out; - short *v_out; - bool mesgflag; -{ - /* Process a definition. If the defined (register-) variable - * is live after 'l', then create a live-message and put - * it after 'l'. - */ - - short v; - bool found; - local_p loc; - - *useless_out = FALSE; - var_nr(l,&v,&found); - if (found && IS_LOCAL(v)) { - *v_out = v; - loc = locals[TO_LOCAL(v)]; - if (IS_REGVAR(loc)) { - if (IS_LIVE(loc)) { - if (!mesgflag) { - appnd_line(make_mesg(ms_liv,loc), l); - } - DEAD(loc); - } else { - *useless_out = TRUE; - } - } - } -} - - - - -STATIC use(l,mesgflag) - line_p l; - bool mesgflag; -{ - /* Process a use. If the defined (register-) variable - * is dead after 'l', then create a dead-message and put - * it after 'l'. - */ - - short v; - bool found; - local_p loc; - - var_nr(l,&v,&found); - if (found && IS_LOCAL(v)) { - loc = locals[TO_LOCAL(v)]; - if (IS_REGVAR(loc) && IS_DEAD(loc)) { - if (!mesgflag) { - appnd_line(make_mesg(ms_ded,loc), l); - } - LIVE(loc); - } - } -} - - - -STATIC nothing() { } /* No action to be undertaken at level 0 of parser */ - -STATIC rem_code(l1,l2,b) - line_p l1,l2; - bblock_p b; -{ - line_p l,x,y; - - x = PREV(l1); - y = l2->l_next; - for (l = l1; l != l2; l = l->l_next) { - oldline(l); - } - if (x == (line_p) 0) { - b->b_start = y; - } else { - x->l_next = y; - } - if (y != (line_p) 0) { - PREV(y) = x; - } -} - - - - -#define SIZE(v) ((offset) locals[TO_LOCAL(v)]->lc_size) - - - - -lv_mesg(p,mesgflag) - proc_p p; - bool mesgflag; -{ - /* Create live/dead messages for every possible register - * variable of p. A dead-message is put after a "use" of - * such a variable, if the variable becomes dead just - * after the use (i.e. this was its last use). - * A live message is put after a "definition" of such - * a variable, if the variable becomes live just - * after the definition (which will usually be the case). - * We traverse every basic block b of p from the last - * instruction of b backwards to the beginning of b. - * Initially, all variables that are dead at the end - * of b are marked dead. All others are marked live. - * If we come accross a definition of a variable X that - * was marked live, we put a live-message after the - * definition and mark X dead. - * If we come accross a use of a variable X that - * was marked dead, we put a dead-message after the - * use and mark X live. - * So at any point, the mark of X tells whether X is - * live or dead immediately before (!) that point. - * We also generate a message at the start of a basic block - * for every variable that was live at the end of the (textually) - * previous block, but dead at the entry of this block, or v.v. - * On the fly, useless assignments are removed. - */ - - register bblock_p b; - register line_p l; - line_p lnp, prev; - bblock_p prevb = (bblock_p) 0; - short v; - bool useless; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - block_entry(b,prevb); /* generate message at head of block */ - prevb = b; - if (!mesgflag) { - init_live_dead(b); - } - for (l = last_instr(b); l != (line_p) 0; l = prev) { - /* traverse backwards! */ - prev = PREV(l); - if (is_def(l)) { - definition(l,&useless,&v,mesgflag); - if (useless && /* assignment to dead var. */ - parse(prev,SIZE(v),&lnp,0,nothing)) { - /* The code "VAR := expression" can - * be removed. 'l' is the "STL VAR", - * lnp is the beginning of the EM code - * for the expression. - */ - prev = PREV(lnp); - rem_code(lnp,l,b); -OUTVERBOSE("useless assignment ,proc %d,local %d", curproc->p_id, - (int) locals[TO_LOCAL(v)]->lc_off); - Slv++; - } - } else { - if (is_dir_use(l)) { - use(l,mesgflag); - } - } - } - } -} - - -STATIC lv_extend(p) - proc_p p; -{ - /* Allocate extended data structures for Use Definition analysis */ - - register bblock_p b; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - b->b_extend = newlvbx(); - } -} - - -STATIC lv_cleanup(p) - proc_p p; -{ - /* Deallocate extended data structures for Use Definition analysis */ - - register bblock_p b; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - Cdeleteset(USE(b)); - Cdeleteset(DEF(b)); - Cdeleteset(L_IN(b)); - Cdeleteset(L_OUT(b)); - oldlvbx(b->b_extend); - } -} - -lv_flags(p) - char *p; -{ - switch(*p) { - case 'N': - mesgflag = TRUE; - break; - } -} - - -lv_optimize(p) - proc_p p; -{ - locals = (local_p *) 0; - lv_extend(p); - live_variables_analysis(p); - lv_mesg(p,mesgflag); - /* generate live-dead messages for regvars */ - lv_cleanup(p); - clean_up(); -} - - - -main(argc,argv) - int argc; - char *argv[]; -{ - go(argc,argv,init_globals,lv_optimize,no_action,lv_flags); - report("useless assignments deleted",Slv); - exit(0); -} diff --git a/util/ego/lv/lv.h b/util/ego/lv/lv.h deleted file mode 100644 index 27fc13597..000000000 --- a/util/ego/lv/lv.h +++ /dev/null @@ -1,42 +0,0 @@ -/* L I V E V A R I A B L E S A N A L Y S I S - * - * L V . H - */ - - -#define USE(b) (b)->b_extend->bx_lv.bx_use -#define DEF(b) (b)->b_extend->bx_lv.bx_def -#define L_IN(b) (b)->b_extend->bx_lv.bx_lin -#define L_OUT(b) (b)->b_extend->bx_lv.bx_lout - -extern short nrglobals; /* number of global variables for which - * ud-info is maintained. - */ -extern short nrvars; /* total number of variables (global + local) - * for which ud-info is maintained. - */ - -/* Every global variable for which ud-info is maintained has - * a 'global variable number' (o_globnr). Every useful local - * has a 'local variable number', which is its index in the - * 'locals' table. All these variables also have a - * 'variable number'. Conversions exist between these numbers. - */ - -#define TO_GLOBAL(v) (v) -#define TO_LOCAL(v) (v - nrglobals) -#define GLOB_TO_VARNR(v) (v) -#define LOC_TO_VARNR(v) (v + nrglobals) -#define IS_GLOBAL(v) (v <= nrglobals) -#define IS_LOCAL(v) (v > nrglobals) - -#define REGVAR(lc) lc->lc_flags |= LCF_REG -#define IS_REGVAR(lc) (lc->lc_flags & LCF_REG) -#define BADLC(lc) lc->lc_flags |= LCF_BAD -#define IS_BADLC(lc) (lc->lc_flags & LCF_BAD) -#define LIVE(lc) lc->lc_flags |= LCF_LIVE -#define DEAD(lc) lc->lc_flags &= ~LCF_LIVE -#define IS_LIVE(lc) (lc->lc_flags & LCF_LIVE) -#define IS_DEAD(lc) (!(lc->lc_flags & LCF_LIVE)) - - diff --git a/util/ego/ra/Makefile b/util/ego/ra/Makefile deleted file mode 100644 index 0922f804b..000000000 --- a/util/ego/ra/Makefile +++ /dev/null @@ -1,176 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -ra.c ra_items.c ra_lifet.c ra_allocl.c ra_profits.c \ -ra_interv.c ra_pack.c ra_xform.c ra_aux.c - -OFILES=\ -ra.o ra_items.o ra_lifet.o ra_allocl.o ra_profits.o \ -ra_interv.o ra_pack.o ra_xform.o ra_aux.o - -HFILES=\ -ra.h ra_items.h ra_lifet.h ra_allocl.h ra_profits.h \ -ra_interv.h ra_pack.h ra_xform.h ra_aux.h - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/aux.o $(SHR)/get.o $(SHR)/put.o $(SHR)/alloc.o $(SHR)/global.o \ -$(SHR)/debug.o $(SHR)/files.o $(SHR)/map.o $(SHR)/lset.o $(SHR)/cset.o \ -$(SHR)/go.o - -SHARE_MFILES=\ -$(SHR)/aux.m $(SHR)/get.m $(SHR)/put.m $(SHR)/alloc.m $(SHR)/global.m \ -$(SHR)/debug.m $(SHR)/files.m $(SHR)/map.m $(SHR)/lset.m $(SHR)/cset.m \ -$(SHR)/go.m - -ra: $(OFILES) - $(CC) -o ra $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -ra_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o ra -.c $(LDFLAGS) ra.o $(EMLIB)/em_data.a - -itemtab.h: itemtab.src makeitems $(EMH)/em_mnem.h - makeitems $(EMH)/em_mnem.h itemtab.src > itemtab.h - -makeitems: makeitems.c - $(CC) -o makeitems makeitems.c - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO - -ra.o: ../../../h/em_reg.h -ra.o: ../share/alloc.h -ra.o: ../share/debug.h -ra.o: ../share/files.h -ra.o: ../share/get.h -ra.o: ../share/global.h -ra.o: ../share/go.h -ra.o: ../share/lset.h -ra.o: ../share/map.h -ra.o: ../share/put.h -ra.o: ../share/types.h -ra.o: ra.h -ra.o: ra_allocl.h -ra.o: ra_items.h -ra.o: ra_pack.h -ra.o: ra_profits.h -ra.o: ra_xform.h -ra_allocl.o: ../../../h/em_mnem.h -ra_allocl.o: ../../../h/em_pseu.h -ra_allocl.o: ../../../h/em_reg.h -ra_allocl.o: ../../../h/em_spec.h -ra_allocl.o: ../share/alloc.h -ra_allocl.o: ../share/aux.h -ra_allocl.o: ../share/cset.h -ra_allocl.o: ../share/debug.h -ra_allocl.o: ../share/def.h -ra_allocl.o: ../share/global.h -ra_allocl.o: ../share/lset.h -ra_allocl.o: ../share/map.h -ra_allocl.o: ../share/types.h -ra_allocl.o: ra.h -ra_allocl.o: ra_allocl.h -ra_allocl.o: ra_aux.h -ra_allocl.o: ra_interv.h -ra_allocl.o: ra_items.h -ra_aux.o: ../../../h/em_mnem.h -ra_aux.o: ../../../h/em_pseu.h -ra_aux.o: ../../../h/em_reg.h -ra_aux.o: ../../../h/em_spec.h -ra_aux.o: ../share/alloc.h -ra_aux.o: ../share/debug.h -ra_aux.o: ../share/def.h -ra_aux.o: ../share/global.h -ra_aux.o: ../share/lset.h -ra_aux.o: ../share/types.h -ra_aux.o: ra.h -ra_aux.o: ra_aux.h -ra_interv.o: ../share/alloc.h -ra_interv.o: ../share/debug.h -ra_interv.o: ../share/global.h -ra_interv.o: ../share/lset.h -ra_interv.o: ../share/types.h -ra_interv.o: ../../../h/em_reg.h -ra_interv.o: ra.h -ra_interv.o: ra_interv.h -ra_items.o: ../../../h/em_mnem.h -ra_items.o: ../../../h/em_pseu.h -ra_items.o: ../../../h/em_reg.h -ra_items.o: ../../../h/em_spec.h -ra_items.o: ../share/alloc.h -ra_items.o: ../share/aux.h -ra_items.o: ../share/debug.h -ra_items.o: ../share/def.h -ra_items.o: ../share/global.h -ra_items.o: ../share/lset.h -ra_items.o: ../share/types.h -ra_items.o: itemtab.h -ra_items.o: ra.h -ra_items.o: ra_aux.h -ra_items.o: ra_items.h -ra_lifet.o: ../../../h/em_mnem.h -ra_lifet.o: ../../../h/em_pseu.h -ra_lifet.o: ../../../h/em_reg.h -ra_lifet.o: ../../../h/em_spec.h -ra_lifet.o: ../share/alloc.h -ra_lifet.o: ../share/aux.h -ra_lifet.o: ../share/debug.h -ra_lifet.o: ../share/def.h -ra_lifet.o: ../share/global.h -ra_lifet.o: ../share/lset.h -ra_lifet.o: ../share/types.h -ra_lifet.o: ra.h -ra_lifet.o: ra_aux.h -ra_lifet.o: ra_items.h -ra_lifet.o: ra_lifet.h -ra_pack.o: ../../../h/em_reg.h -ra_pack.o: ../share/alloc.h -ra_pack.o: ../share/aux.h -ra_pack.o: ../share/cset.h -ra_pack.o: ../share/debug.h -ra_pack.o: ../share/def.h -ra_pack.o: ../share/global.h -ra_pack.o: ../share/lset.h -ra_pack.o: ../share/types.h -ra_pack.o: ra.h -ra_pack.o: ra_aux.h -ra_pack.o: ra_interv.h -ra_profits.o: ../../../h/em_reg.h -ra_profits.o: ../share/debug.h -ra_profits.o: ../share/global.h -ra_profits.o: ../share/lset.h -ra_profits.o: ../share/types.h -ra_profits.o: ra.h -ra_profits.o: ra_aux.h -ra_profits.o: ra_profits.h -ra_xform.o: ../../../h/em_mes.h -ra_xform.o: ../../../h/em_mnem.h -ra_xform.o: ../../../h/em_pseu.h -ra_xform.o: ../../../h/em_reg.h -ra_xform.o: ../../../h/em_spec.h -ra_xform.o: ../share/alloc.h -ra_xform.o: ../share/aux.h -ra_xform.o: ../share/debug.h -ra_xform.o: ../share/def.h -ra_xform.o: ../share/global.h -ra_xform.o: ../share/lset.h -ra_xform.o: ../share/types.h -ra_xform.o: ra.h -ra_xform.o: ra_interv.h -ra_xform.o: ra_items.h -ra_xform.o: ra_xform.h diff --git a/util/ego/ra/itemtab.src b/util/ego/ra/itemtab.src deleted file mode 100644 index 4c3e5e09f..000000000 --- a/util/ego/ra/itemtab.src +++ /dev/null @@ -1,21 +0,0 @@ -op_cal PROC_ADDR 12 -op_dee GLOBL_ADDR 8 -op_del LOCALVAR 8 -op_ine GLOBL_ADDR 7 -op_inl LOCALVAR 7 -op_lae GLOBL_ADDR 2 -op_lal LOCAL_ADDR 2 -op_ldc DCONST 11 -op_lde GLOBL_ADDR 3 -op_ldl LOCALVAR 3 -op_lil LOCALVAR 1 -op_loc CONST 10 -op_loe GLOBL_ADDR 0 -op_lol LOCALVAR 0 -op_sde GLOBL_ADDR 6 -op_sdl LOCALVAR 6 -op_sil LOCALVAR 5 -op_ste GLOBL_ADDR 4 -op_stl LOCALVAR 4 -op_zre GLOBL_ADDR 9 -op_zrl LOCALVAR 9 diff --git a/util/ego/ra/makeitems.c b/util/ego/ra/makeitems.c deleted file mode 100644 index 8df2006ec..000000000 --- a/util/ego/ra/makeitems.c +++ /dev/null @@ -1,77 +0,0 @@ -#include - -/* MAKE ITEMS TABLE - * - * This program is used by the register allocation phase of the optimizer - * to make the file itemtab.h. It reads two files: - * - the em_mnem.h file, containing the definitions of the - * EM mnemonics - * - the item-file, containing tuples: - * (mnemonic, item_type) - * The output (standard output) is a C array. - */ - - -#define TRUE 1 -#define FALSE 0 - -convert(mnemfile,itemfile) - FILE *mnemfile, *itemfile; -{ - char mnem1[20], mnem2[20],def[20],itemtype[20]; - int newcl,opc,index; - - newcl = TRUE; - printf("struct item_descr itemtab[] = {\n"); - for (;;) { - fscanf(mnemfile,"%s%s%d",def,mnem1,&opc); - /* read a line like "#define op_aar 1" */ - if (feof(mnemfile)) break; - if (strcmp(def,"#define") != 0) { - error("bad mnemonic file, #define expected"); - } - if (newcl) { - fscanf(itemfile,"%s%s%d",mnem2,itemtype,&index); - /* read a line like "op_loc CONST 4" */ - } - if (feof(itemfile) || strcmp(mnem1,mnem2) != 0) { - /* there is no line for this mnemonic, so - * it has no type. - */ - printf("{NO_ITEM,0},\n"); - newcl = FALSE; - } else { - printf("{%s,%d},\n",itemtype,index); - newcl = TRUE; - } - } - printf("};\n"); -} - - - -error(s) - char *s; -{ - fprintf(stderr,"%s\n",s); - exit(-1); -} - - -main(argc,argv) - int argc; - char *argv[]; -{ - FILE *f1,*f2; - - if (argc != 3) { - error("usage: makeitems mnemfile itemfile"); - } - if ((f1 = fopen(argv[1],"r")) == NULL) { - error("cannot open mnemonic file"); - } - if ((f2 = fopen(argv[2],"r")) == NULL) { - error("cannot open item file"); - } - convert(f1,f2); -} diff --git a/util/ego/ra/ra.c b/util/ego/ra/ra.c deleted file mode 100644 index 48df6d096..000000000 --- a/util/ego/ra/ra.c +++ /dev/null @@ -1,548 +0,0 @@ -/* - * R E G I S T E R A L L O C A T I O N - * - */ - -#include -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/files.h" -#include "../share/get.h" -#include "../share/put.h" -#include "../share/lset.h" -#include "../share/map.h" -#include "../share/alloc.h" -#include "../share/go.h" -#include "../../../h/em_reg.h" -#include "ra.h" -#include "ra_items.h" -#include "ra_allocl.h" -#include "ra_profits.h" -#include "ra_pack.h" -#include "ra_xform.h" - - -#define newrabx() (bext_p) newstruct(bext_ra) -#define newralpx() (lpext_p) newstruct(lpext_ra) -#define oldrabx(x) oldstruct(bext_ra,x) -#define oldralpx(x) oldstruct(lpext_ra,x) - -short alloc_id; -static item_p items[NRITEMTYPES]; -int nrinstrs; -line_p *instrmap; - -cond_p alocaltab[NRREGTYPES][NRREGTYPES],alocaddrtab[NRREGTYPES][NRREGTYPES], - aconsttab,adconsttab,aglobaltab,aproctab; -cond_p olocaltab[NRREGTYPES],olocaddrtab[NRREGTYPES], - oconsttab,odconsttab,oglobaltab,oproctab; -cond_p regsav_cost; - -short regs_available[] = { - /* Actually machine dependent; this is for vax2 */ - 3, /* reg_any i.e. data regs */ - 0, /* reg_loop */ - 3, /* reg_pointer i.e. address reg. */ - 0 /* reg_float */ -} ; - -STATIC cond_p getcondtab(f) - FILE *f; -{ - int l,i; - cond_p tab; - - fscanf(f,"%d",&l); - tab = newcondtab(l); - for (i = 0; i < l; i++) { - fscanf(f,"%hd %hd %hd",&tab[i].mc_cond,&tab[i].mc_tval, - &tab[i].mc_sval); - } - assert(tab[l-1].mc_cond == DEFAULT); - return tab; -} - -get_atab(f,tab) - FILE *f; - cond_p tab[NRREGTYPES][NRREGTYPES]; -{ - int i,cnt,totyp,regtyp; - - fscanf(f,"%d",&cnt); - for (i = 0; i < cnt; i++) { - fscanf(f,"%d %d",®typ,&totyp); - assert(regtyp >= 0 && regtyp < NRREGTYPES); - assert(totyp >= 0 && totyp < NRREGTYPES); - tab[regtyp][totyp] = getcondtab(f); - } -} - - -get_otab(f,tab) - FILE *f; - cond_p tab[NRREGTYPES]; -{ - int i,cnt,regtyp; - - fscanf(f,"%d",&cnt); - for (i = 0; i < cnt; i++) { - fscanf(f,"%d",®typ); - assert(regtyp >= 0 && regtyp < NRREGTYPES); - tab[regtyp] = getcondtab(f); - } -} - - - -STATIC ra_machinit(f) - FILE *f; -{ - /* Read target machine dependent information for this phase */ - char s[100]; - - for (;;) { - while(getc(f) != '\n'); - fscanf(f,"%s",s); - if (strcmp(s,"%%RA") == 0)break; - } - fscanf(f,"%hd",®s_available[reg_any]); - fscanf(f,"%hd",®s_available[reg_pointer]); - fscanf(f,"%hd",®s_available[reg_float]); - get_atab(f,alocaltab); - get_atab(f,alocaddrtab); - aconsttab = getcondtab(f); - adconsttab = getcondtab(f); - aglobaltab = getcondtab(f); - aproctab = getcondtab(f); - get_otab(f,olocaltab); - get_otab(f,olocaddrtab); - oconsttab = getcondtab(f); - odconsttab = getcondtab(f); - oglobaltab = getcondtab(f); - oproctab = getcondtab(f); - regsav_cost = getcondtab(f); -} - - -STATIC bblock_p header(lp) - loop_p lp; -{ - /* Try to determine the 'header' block of loop lp. - * If 'e' is the entry block of loop L, then block 'b' is - * called the header block of L, iff: - * SUCC(b) = {e} & PRED(e) = {b} - * If lp has no header block, 0 is returned. - */ - - bblock_p x = lp->lp_entry->b_idom; - - if (x != (bblock_p) 0 && Lnrelems(x->b_succ) == 1 && - (bblock_p) Lelem(Lfirst(x->b_succ)) == lp->lp_entry) { - return x; - } - return (bblock_p) 0; -} - - -STATIC ra_extproc(p) - proc_p p; -{ - /* Allocate the extended data structures for procedure p */ - - register loop_p lp; - register Lindex pi; - register bblock_p b; - - for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; - pi = Lnext(pi,p->p_loops)) { - lp = (loop_p) Lelem(pi); - lp->lp_extend = newralpx(); - lp->LP_HEADER = header(lp); - } - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - b->b_extend = newrabx(); - } -} - - - - -STATIC ra_cleanproc(p) - proc_p p; -{ - /* Allocate the extended data structures for procedure p */ - - register loop_p lp; - register Lindex pi; - register bblock_p b; - - for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; - pi = Lnext(pi,p->p_loops)) { - lp = (loop_p) Lelem(pi); - oldralpx(lp->lp_extend); - } - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - oldrabx(b->b_extend); - } -} - - - -STATIC loop_blocks(p) - proc_p p; -{ - /* Compute the LP_BLOCKS sets for all loops of p */ - - register bblock_p b; - register Lindex i; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (i = Lfirst(b->b_loops); i != (Lindex) 0; - i = Lnext(i,b->b_loops)) { - Ladd(b,&(((loop_p) Lelem(i))->LP_BLOCKS)); - } - } -} - - - - -STATIC make_instrmap(p,map) - proc_p p; - line_p map[]; -{ - /* make the instructions map of procedure p */ - - register bblock_p b; - register line_p l; - register int i = 0; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - b->B_BEGIN = i; /* number of first instruction */ - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - map[i++] = l; - } - b->B_END = i-1; /* number of last instruction */ - } -} - - - -STATIC bool useful_item(item) - item_p item; -{ - /* See if it may be useful to put the item in a register. - * A local variable that is not a parameter may always be put - * in a register (as it need not be initialized). - * Other items must be used at least twice. - */ - - int nruses = Lnrelems(item->it_usage); - assert (nruses > 0); /* otherwise it would not be an item! */ - return nruses > 1 || (item->it_type == LOCALVAR && - item->i_t.it_off < 0); -} - - -STATIC item_p cat_items(items) - item_p items[]; -{ - /* Make one item list out of an array of itemlists. - * Remove items that are used only once. - */ - - register item_p it; - item_p *ip,head,next; - int t; - - - ip = &head; - for (t = 0; t < NRITEMTYPES;t++) { - for ( it = items[t]; it != (item_p) 0; it = next) { - next = it->it_next; - if (!it->it_desirable || !useful_item(it)) { - cleantimeset(it->it_usage); - olditem(it); - } else { - *ip = it; - ip = &it->it_next; - } - } - } - *ip = (item_p) 0; - return head; -} - - - - -STATIC clean_interval(list) - interv_p list; -{ - register interv_p x,next; - - for (x = list; x != (interv_p) 0; x = next) { - next = x->i_next; - oldinterval(x); - } -} - - - -STATIC cleantimeset(s) - lset s; -{ - register Lindex i; - register time_p t; - - for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i,s)) { - t = (time_p) Lelem(i); - oldtime(t); - } - Ldeleteset(s); -} - - - -STATIC clean_allocs(list) - alloc_p list; -{ - register alloc_p x,next; - - for (x = list; x != (alloc_p) 0; x = next) { - next = x->al_next; - clean_interval(x->al_timespan); - Cdeleteset(x->al_rivals); - Ldeleteset(x->al_inits); - clean_interval(x->al_busy); - clean_allocs(x->al_mates); - oldalloc(x); - } -} - - - -STATIC cleanitems(list) - item_p list; -{ - register item_p x,next; - - for (x = list; x != (item_p) 0; x = next ) { - next = x->it_next; - cleantimeset(x->it_usage); - olditem(x); - } -} - - -ra_initialize() -{ - init_replacements(ps,ws); -} - - -ra_optimize(p) - proc_p p; -{ - item_p itemlist; - alloc_p alloclist,packed,unpacked; - offset locls; - bool time_opt = (time_space_ratio == 100); - - ra_extproc(p); - loop_blocks(p); - alloc_id =0; - locls = p->p_localbytes; - build_itemlist(p,items,&nrinstrs); - instrmap = (line_p *) newmap(nrinstrs-1); /* map starts counting at 0 */ - make_instrmap(p,instrmap); - build_lifetimes(items); - /* print_items(items,p); */ - /* statistics(items); */ - itemlist = cat_items(items); /* make one list */ - alloclist = build_alloc_list(p,Lnrelems(p->p_loops), - itemlist); - build_rivals_graph(alloclist); - compute_profits(alloclist,time_opt); - /* print_allocs(alloclist); */ - pack(alloclist,time_opt,&packed,&unpacked,p); - stat_regusage(packed); - xform_proc(p,packed,nrinstrs,instrmap); - /* print_allocs(packed); */ - p->p_localbytes = locls; - /* don't really allocate dummy local variables! */ - rem_locals(p,packed); - rem_formals(p,packed); - /* remove storage for real locals that - *are always put in register . - */ - clean_allocs(unpacked); - clean_allocs(packed); - cleanitems(itemlist); - oldmap(instrmap,nrinstrs-1); - ra_cleanproc(p); -} - - - -main(argc,argv) - int argc; - char *argv[]; -{ - go(argc,argv,ra_initialize,ra_optimize,ra_machinit,no_action); - exit(0); -} - - -/***************************************************************************/ -/***************************************************************************/ -/***************************************************************************/ - -/* debugging stuff */ - - - -char *str_types[] = { - "local variable", - "addr. of local", - "addr. of external", - "addr. of procedure", - "constant", - "double constant" -}; - -char *str_regtypes[] = { - "any", - "loop", - "pointer", - "float" -}; - - -print_items(items,p) - item_p items[]; - proc_p p; -{ - int t; - item_p item; - interv_p iv; - - printf("BEGIN PROCEDURE %d\n",p->p_id); - for (t = 0; t < NRITEMTYPES;t++) { - for (item = items[t]; item != (item_p) 0;item = item->it_next) { - printf("\nitemtype = %s\n",str_types[t]); - if (t == GLOBL_ADDR) { - printf("id of external = %d\n", - item->i_t.it_obj->o_id); - } else { - printf("offset = %D\n", - item->i_t.it_off); - } - printf("regtype = %s\n",str_regtypes[item->it_regtype]); - printf("size = %d\n",item->it_size); - printf("#usages = %d\n", Lnrelems(item->it_usage)); - printf("lifetime = {"); - for (iv = item->it_lives; iv != (interv_p) 0; - iv = iv->i_next) { - printf("(%d,%d) ",iv->i_start,iv->i_stop); - } - printf("} \n"); - } - } - printf("END PROCEDURE %d\n\n",p->p_id); -} - - -print_allocs(list) - alloc_p list; -{ - alloc_p al,m; - item_p item; - short t; - interv_p iv; - - fprintf(stderr,"BEGIN ALLOCLIST of proc %d\n",curproc->p_id); - for (m = list ; m != (alloc_p) 0; m = m->al_next) { - for (al = m; al != (alloc_p) 0; al = al->al_mates) { - item = al->al_item; - t = item->it_type; - fprintf(stderr,"\nitem: [type = %s, ",str_types[t]); - switch(t) { - case GLOBL_ADDR: - fprintf(stderr,"id = %d]\n", item->i_t.it_obj->o_id); - break; - case PROC_ADDR: - fprintf(stderr,"id = %d]\n", item->i_t.it_proc->p_id); - break; - default: - fprintf(stderr,"offset = %D]\n", item->i_t.it_off); - } - fprintf(stderr,"#usages(static) = %d\n",al->al_susecount); - fprintf(stderr,"#usages(dyn) = %d\n",al->al_dusecount); - fprintf(stderr,"#inits = %d\n",Lnrelems(al->al_inits)); - fprintf(stderr,"timespan = {"); - for (iv = al->al_timespan; iv != (interv_p) 0; - iv = iv->i_next) { - fprintf(stderr,"(%d,%d) ",iv->i_start,iv->i_stop); - } - fprintf(stderr,"} \n"); - fprintf(stderr,"busy = {"); - for (iv = al->al_busy; iv != (interv_p) 0; - iv = iv->i_next) { - fprintf(stderr,"(%d,%d) ",iv->i_start,iv->i_stop); - } - fprintf(stderr,"} \n"); - fprintf(stderr,"profits = %d\n",al->al_profits); - fprintf(stderr,"dummy local = %D\n",al->al_dummy); - fprintf(stderr,"regnr = %d\n",al->al_regnr); - } - } -} - - -short regs_needed[4]; -stat_regusage(list) - alloc_p list; -{ - int i; - alloc_p x; - - for (i = 0; i < 4; i++) { - regs_needed[i] = 0; - } - for (x = list; x != (alloc_p) 0; x = x->al_next) { - regs_needed[x->al_regtype]++; - } - /* printf("data regs:%d\n",regs_needed[reg_any]); */ - /* printf("address regs:%d\n",regs_needed[reg_pointer]); */ -} - - - -int cnt_regtypes[reg_float+1]; - -statistics(items) - item_p items[]; -{ - register item_p item,next; - int t,r; - int cnt; - - printf("\nSTATISTICS\n"); - for (r = 0; r <= reg_float; r++) cnt_regtypes[r] = 0; - for (t = 0; t < NRITEMTYPES;t++) { - cnt = 0; - for (item = items[t]; item != (item_p) 0;item = next) { - if (useful_item(item)) { - cnt++; - cnt_regtypes[item->it_regtype]++; - } - next = item->it_next; - } - printf("#%s = %d\n",str_types[t],cnt); - } - for (r = 0; r <= reg_float; r++) { - printf("#%s = %d\n",str_regtypes[r],cnt_regtypes[r]); - } -} diff --git a/util/ego/ra/ra.h b/util/ego/ra/ra.h deleted file mode 100644 index 9a84cb1c2..000000000 --- a/util/ego/ra/ra.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * R E G I S T E R A L L O C A T I O N - * - */ - -/* TEMPORARY: should be put in ../../../h/em_mes.h: */ -#define ms_liv 9 -#define ms_ded 10 - -#define INFINITE 10000 -#define NRREGTYPES (reg_float+1) - -extern int nrinstrs; /* number of instructions of current procedure */ -extern line_p *instrmap; -/* Dynamic array: instrmap[i] points to i'th instruction */ - -extern cond_p alocaltab[NRREGTYPES][NRREGTYPES], - alocaddrtab[NRREGTYPES][NRREGTYPES], aconsttab, - adconsttab,aglobaltab,aproctab; -extern cond_p olocaltab[NRREGTYPES],olocaddrtab[NRREGTYPES], - oconsttab,odconsttab,oglobaltab,oproctab; -extern cond_p regsav_cost; - -/* Register Allocation */ -typedef struct item *item_p; -typedef struct allocation *alloc_p; -typedef struct interval *interv_p; -typedef struct time *time_p; - - - - -extern short regs_available[]; /* contains #registers of every type */ - - -/* A thing that can be put in a register is called an "item". The are several - * types of items: a local variable, the address of a local variable, - * the address of a global variable, the address of a procedure, - * a word-size constant and a doubleword- size constant. - */ - -#define LOCALVAR 0 -#define LOCAL_ADDR 1 -#define GLOBL_ADDR 2 -#define PROC_ADDR 3 -#define CONST 4 -#define DCONST 5 - -#define NO_ITEM 6 -#define NRITEMTYPES 6 - -struct item { - item_p it_next; /* link to next item is list */ - short it_type; /* its type; see above */ - short it_regtype; /* preferred type of register */ - short it_size; /* its size (in bytes) */ - short it_lastlive; /* temporary, used to build livetime */ - lset it_usage; /* all points in text where item is used*/ - interv_p it_lives; /* intervals during which item is live */ - bool it_desirable; /* should this item be put in reg.? */ - union { - obj_p it_obj; /* for GLOBL_ADDR */ - proc_p it_proc; /* for PROC_ADDR */ - offset it_off; /* for others */ - } i_t; -}; - - -/* A 'point in time' is defined by a (line,basic block) pair */ - -struct time { - line_p t_line; /* point in EM text */ - bblock_p t_bblock; /* its basic block */ -}; - - -struct interval { - short i_start; /* number of first instruction */ - short i_stop; /* number of last instruction */ - interv_p i_next; -}; - - -/* An item may be put in a register for the duration of a whole procedure - * or part of a procedure (e.g. a loop). So a possible "allocation" looks - * like: put item X in a register during the timespan T (which is a subset - * of the timespan of the entire procedure). The packing process deals - * with allocations, rather than items. One item may be part of several - * possible allocations. - */ - -struct allocation { - item_p al_item; /* the item to be put in a register */ - short al_id; /* unique identifying number */ - short al_regtype; /* the register type to be used */ - interv_p al_timespan; /* timespan during which item is in reg. */ - short al_profits; /* gains of putting item in register */ - cset al_rivals; /* set of allocations competing with it */ - short al_susecount; /* #usages during timespan (statically) */ - short al_dusecount; /* #usages (dynamically, estimate) */ - lset al_inits; /* points where reg. must be initialized */ - interv_p al_busy; /* used to compute rivals */ - short al_regnr; /* register nr.,if it is granted a reg. */ - offset al_dummy; /* dummy local variable,if granted a reg */ - alloc_p al_mates; /* link to allocations packed in same reg */ - alloc_p al_wholeproc; /* alloc. for whole proc as timespan */ - short al_cntrivals; /* # unpacked rivals ; used for cost estim. */ - bool al_isloop; /* true if timespan consists of loop */ - bool al_iswholeproc;/*true if timespan consists of whole proc*/ - alloc_p al_next; /* link to next one in a list */ -}; - -extern short alloc_id; /* last al_id used for current procedure */ - -#define LP_BLOCKS lp_extend->lpx_ra.lpx_blocks -#define LP_HEADER lp_extend->lpx_ra.lpx_header -#define B_BEGIN b_extend->bx_ra.bx_begin -#define B_END b_extend->bx_ra.bx_end - -#define DLINK(l1,l2) l1->l_next=l2; l2->l_prev=l1 - -struct item_descr { - int id_type; - int id_replindex; -} ; - -extern struct item_descr itemtab[]; - -#define newalloc() (alloc_p) newstruct(allocation) -#define oldalloc(a) oldstruct(allocation,a) -#define newitem() (item_p) newstruct(item) -#define olditem(i) oldstruct(item,i) -#define newtime() (time_p) newstruct(time) -#define oldtime(t) oldstruct(time,t) -#define newinterval() (interv_p) newstruct(interval) -#define oldinterval(i) oldstruct(interval,i) diff --git a/util/ego/ra/ra_allocl.c b/util/ego/ra/ra_allocl.c deleted file mode 100644 index 4b5bb8a65..000000000 --- a/util/ego/ra/ra_allocl.c +++ /dev/null @@ -1,376 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * R A _ A L L O C L I S T . C - */ - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/def.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/aux.h" -#include "../share/alloc.h" -#include "../share/map.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_reg.h" -#include "ra.h" -#include "ra_aux.h" -#include "ra_items.h" -#include "ra_allocl.h" -#include "ra_interv.h" - -STATIC count_usage(p,item,nrloops,sloopcnt,dloopcnt) - proc_p p; - item_p item; - short nrloops, sloopcnt[], dloopcnt[]; -{ - /* Determine how many times the item is used in every loop. - * We maintain a 'static' count and a 'dynamic' count. The dynamic - * count estimates the number of times the item is used during - * execution, i.e. it gives a higher mark to items used inside - * a loop. - */ - - lset loops; - loop_p l; - int i; - short lev; - Lindex ui,li; - time_p u; - - for (i = 0; i <= nrloops; i++) { - sloopcnt[i] = 0; - dloopcnt[i] = 0; - } - for (ui = Lfirst(item->it_usage); ui != (Lindex) 0; - ui = Lnext(ui,item->it_usage)) { - u = (time_p) Lelem(ui); - loops = u->t_bblock->b_loops; - lev = Lnrelems(loops); - /* set of loops in which this usage of item occurs */ - for (li = Lfirst(loops); li != (Lindex) 0; li=Lnext(li,loops)) { - l = (loop_p) Lelem(li); - sloopcnt[l->lp_id]++; - dloopcnt[l->lp_id] += - (IS_FIRM(u->t_bblock) ? loop_scale(lev) : 1); - } - } -} - - - -STATIC alloc_p cons_alloc(item,timespan,stat_usecount, - dyn_usecount,inits,wholeproc,isloop,iswholeproc) - item_p item; - interv_p timespan; - short stat_usecount,dyn_usecount; - lset inits; - alloc_p wholeproc; - bool isloop,iswholeproc; -{ - alloc_p x; - - x = newalloc(); - x->al_id = ++alloc_id; - x->al_item = item; - x->al_timespan = timespan; - x->al_susecount = stat_usecount; - x->al_dusecount = dyn_usecount; - x->al_inits = inits; - x->al_wholeproc = wholeproc; - x->al_isloop = isloop; - x->al_iswholeproc = iswholeproc; - return x; -} - - -STATIC insert_alloc(alloc,list_p) - alloc_p alloc, *list_p; -{ - alloc->al_next = *list_p; - *list_p = alloc; -} - - - -#define MUST_INIT(i,b) (i->it_type!=LOCALVAR ||contains(b->B_BEGIN,i->it_lives)) -#define MUST_UPDATE(i,b) (i->it_type==LOCALVAR &&contains(b->B_BEGIN,i->it_lives)) - -STATIC lset loop_inits(lp,item,header) - loop_p lp; - item_p item; - bblock_p header; -{ - /* Build the set of entry points to loop lp where item - * must be initialized - */ - - lset s = Lempty_set(); - if (header != (bblock_p) 0 && MUST_INIT(item,header)) { - Ladd(header,&s); - } - return s; -} - - - -#define IN_LOOP(b) (Lnrelems(b->b_loops) > 0) - -STATIC bblock_p init_point(item) - item_p item; -{ - /* Find the most appropriate point to initialize any register - * containing the item. We want to do the initialization as - * late as possible, to allow other items to be put in the - * same register, before this initialization. Yet, as we want - * to do the initialization only once, it must be done in a - * basic block that is a dominator of all points where the - * item is used (ultimately in the first block of the procedure). - * This basic block should not be part of loop. - */ - - bblock_p b,dom = 0; - Lindex ti; - time_p t; - - for (ti = Lfirst(item->it_usage); ti != (Lindex) 0; - ti = Lnext(ti,item->it_usage)) { - t = (time_p) Lelem(ti); - b = t->t_bblock; - dom = (dom == (bblock_p) 0 ? b : common_dom(dom,b)); - } - while (IN_LOOP(dom)) { - /* Find a dominator of dom (possibly - * dom itself) that is outside any loop. - */ - dom = dom->b_idom; - } - return dom; -} - - -STATIC add_blocks(b,s,span) - bblock_p b; - cset *s; - interv_p *span; -{ - Lindex pi; - - if (!Cis_elem(b->b_id,*s)) { - Cadd(b->b_id,s); - add_interval(b->B_BEGIN,b->B_END,span); - for (pi = Lfirst(b->b_pred); pi != (Lindex) 0; - pi = Lnext(pi,b->b_pred)) { - add_blocks((bblock_p) Lelem(pi),s,span); - } - } -} - - - -STATIC whole_lifetime(item,ini_out,span_out) - item_p item; - bblock_p *ini_out; - interv_p *span_out; -{ - /* Find the initialization point and the time_span of the item, if - * we put the item in a register during all its uses. - */ - - bblock_p b, ini = init_point(item); - cset s = Cempty_set(blength); - Lindex ti; - time_p t; - interv_p span = (interv_p) 0; - - for (ti = Lfirst(item->it_usage); ti != (Lindex) 0; - ti = Lnext(ti,item->it_usage)) { - t = (time_p) Lelem(ti); - b = t->t_bblock; - add_blocks(b,&s,&span); - } - if (!Cis_elem(ini->b_id,s)) { - add_interval(ini->B_BEGIN,ini->B_END,&span); - } - Cdeleteset(s); - *ini_out = ini; - *span_out = span; -} - - - - -STATIC lset proc_inits(p,item,ini) - proc_p p; - item_p item; - bblock_p ini; -{ - lset s = Lempty_set(); - - if (item->it_type != LOCALVAR || item->i_t.it_off >= 0) { - /* only local variables need not be initialized */ - Ladd(ini, &s); - } - return s; -} - - -STATIC bool updates_needed(lp,item) - loop_p lp; - item_p item; -{ - /* See if the value of item is live after the loop has - * been exited, i.e. must the item be updated after the loop? - */ - - Lindex bi,si; - bblock_p b,s; - - for (bi = Lfirst(lp->LP_BLOCKS); bi != (Lindex) 0; - bi = Lnext(bi,lp->LP_BLOCKS)) { - b = (bblock_p) Lelem(bi); - for (si = Lfirst(b->b_succ); si != (Lindex) 0; - si = Lnext(si,b->b_succ)) { - s = (bblock_p) Lelem(si); - if (!Lis_elem(s,lp->LP_BLOCKS) && MUST_UPDATE(item,s)) { - return TRUE; - } - } - } - return FALSE; -} - - - -STATIC short countuses(usage,b) - lset usage; - bblock_p b; -{ - short cnt = 0; - Lindex ti; - time_p t; - - for (ti = Lfirst(usage); ti != (Lindex) 0; ti = Lnext(ti,usage)) { - t = (time_p) Lelem(ti); - if (t->t_bblock == b) cnt++; - } - return cnt; -} - - - -STATIC allocs_of_item(p,item,loops,sloopcnt,dloopcnt,alloc_list_p) - proc_p p; - item_p item; - lset loops; - short *sloopcnt,*dloopcnt; /* dynamic arrays */ - alloc_p *alloc_list_p; -{ - register Lindex li; - loop_p lp; - bblock_p header,ini; - short susecount,dusecount; - interv_p lt; - alloc_p wholeproc; - - /* The whole procedure may be used as timespan. - The dynamic usecount of a procedure is taken to be the same - as its static usecount; this number is not very important, as - time-optimziation chooses loops first. - */ - whole_lifetime(item,&ini,<); - wholeproc = cons_alloc(item,lt,Lnrelems(item->it_usage), - Lnrelems(item->it_usage), proc_inits(p,item,ini), - (alloc_p) 0,FALSE,TRUE); - insert_alloc(wholeproc, alloc_list_p); - for (li = Lfirst(loops); li != (Lindex) 0; li = Lnext(li,loops)) { - lp = (loop_p) Lelem(li); - if (sloopcnt[lp->lp_id] != 0 && !updates_needed(lp,item)) { - /* Item is used within loop, so consider loop - * as a timespan during which item may be put in - * a register. - */ - if ((header = lp->LP_HEADER) == (bblock_p) 0 && - MUST_INIT(item,lp->lp_entry)) continue; - lt = loop_lifetime(lp); - susecount = sloopcnt[lp->lp_id]; - dusecount = dloopcnt[lp->lp_id]; - if (MUST_INIT(item,lp->lp_entry)) { - /* include header block in timespan */ - add_interval(header->B_BEGIN,header->B_END,<); - susecount += countuses(item->it_usage,header); - } else { - header = (bblock_p) 0; - } - insert_alloc(cons_alloc(item,lt,susecount,dusecount, - loop_inits(lp,item,header),wholeproc, - TRUE,FALSE), - alloc_list_p); - } - } -} - - - -alloc_p build_alloc_list(p,nrloops,itemlist) - proc_p p; - short nrloops; - item_p itemlist; -{ - short *sloopcnt,*dloopcnt; /* dynamic arrays */ - register item_p item; - alloc_p alloc_list = (alloc_p) 0; - - sloopcnt = (short *) newtable(nrloops); - dloopcnt = (short *) newtable(nrloops); - for (item = itemlist; item != (item_p) 0; item = item->it_next) { - count_usage(p,item,nrloops,sloopcnt,dloopcnt); - allocs_of_item(p,item,p->p_loops,sloopcnt,dloopcnt, - &alloc_list); - } - oldtable(sloopcnt,nrloops); - oldtable(dloopcnt,nrloops); - return alloc_list; -} - - - -build_rivals_graph(alloclist) - alloc_p alloclist; -{ - /* See which allocations in the list are rivals of each other, - * i.e. there is some point of time, falling in both - * timespans, at which the items of both allocations are live. - * Allocations with the same item (but different timespans) are - * not considered to be rivals. - * We use an auxiliary data structure "busy" for each allocation, - * indicating when the item is live during the timespan of the - * allocation. - */ - - register alloc_p alloc,x; - - for (alloc = alloclist; alloc != (alloc_p) 0; alloc = alloc->al_next) { - alloc->al_rivals = Cempty_set(alloc_id); - } - for (alloc = alloclist; alloc != (alloc_p) 0; alloc = alloc->al_next) { - alloc->al_busy = - (alloc->al_item->it_type == LOCALVAR ? - intersect(alloc->al_timespan,alloc->al_item->it_lives) : - copy_timespan(alloc->al_timespan)); - for (x = alloclist; x != alloc; x = x->al_next) { - if (x->al_item != alloc->al_item && - not_disjoint(alloc->al_busy,x->al_busy)) { - Cadd(x->al_id,&alloc->al_rivals); - Cadd(alloc->al_id,&x->al_rivals); - if (alloc->al_regtype == x->al_regtype) { - alloc->al_cntrivals++; - x->al_cntrivals++; - } - } - } - } -} diff --git a/util/ego/ra/ra_allocl.h b/util/ego/ra/ra_allocl.h deleted file mode 100644 index 1690b69bb..000000000 --- a/util/ego/ra/ra_allocl.h +++ /dev/null @@ -1,19 +0,0 @@ - -/* R E G I S T E R A L L O C A T I O N - * - * R A _ A L L O C L I S T . H - */ - -extern alloc_p build_alloc_list(); /* (proc_p p; short nrloops; - * item_p itemlist) - * Build a list of possible allocations - * for procedure p. An allocation - * essentially is a pair (item,timespan) - */ -extern build_rivals_graph(); /* (alloc_p alloclist) - /* See which allocations in the list are - * rivals of each other, i.e. there is - * some point of time, falling in both - * timespans, at which the items of - * both allocations are live. - */ diff --git a/util/ego/ra/ra_aux.c b/util/ego/ra/ra_aux.c deleted file mode 100644 index b44f32309..000000000 --- a/util/ego/ra/ra_aux.c +++ /dev/null @@ -1,40 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * A U X I L I A R Y R O U T I N E S - */ - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/def.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/alloc.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_reg.h" -#include "ra.h" -#include "ra_aux.h" - - -time_p cons_time(l,b) - line_p l; - bblock_p b; -{ - /* Construct a time */ - - time_p t = newtime(); - - t->t_line = l; - t->t_bblock = b; - return t; -} - - - - -short loop_scale(lev) - short lev; -{ - return (lev == 0 ? 1 : (lev > 3 ? 20 : 5 * lev)); -} diff --git a/util/ego/ra/ra_aux.h b/util/ego/ra/ra_aux.h deleted file mode 100644 index 374a60c2b..000000000 --- a/util/ego/ra/ra_aux.h +++ /dev/null @@ -1,24 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * A U X I L I A R Y R O U T I N E S - */ - -#define regv_size(off) regv_arg(off,2) - /* Fetch the size argument of the - * register message of the local with - * the given offset. - */ -#define regv_type(off) regv_arg(off,3) - /* Fetch the type argument of the - * register message of the local with - * the given offset. - */ -extern time_p cons_time(); /* (line_p l; bblock_p b) - * Construct a 'time' record with - * fields 'l' and 'b'. - */ -extern short loop_scale(); /* (short lev) - * Estimate how many times an item - * appearing in a loop of nesting - * level 'lev' will be used dynamically. - */ diff --git a/util/ego/ra/ra_interv.c b/util/ego/ra/ra_interv.c deleted file mode 100644 index 6be3271c1..000000000 --- a/util/ego/ra/ra_interv.c +++ /dev/null @@ -1,228 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * R A _ I N T E R V A L . C - */ - - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/alloc.h" -#include "../share/lset.h" -#include "../../../h/em_reg.h" -#include "ra.h" -#include "ra_interv.h" - -interv_p cons_interval(t_start,t_stop) - short t_start,t_stop; -{ - interv_p x; - - x = newinterval(); - x->i_start = t_start; - x->i_stop = t_stop; - return x; -} - - - -add_interval(t1,t2,list) - short t1,t2; - interv_p *list; -{ - /* Add interval (t1,t2) to the list of intervals (which is - * an in-out parameter!). The list is sorted in 'chronological' - * order. We attempt to keep the list as small as possible, by - * putting adjacent intervals in one interval. - */ - - register interv_p x1, x2, *q; - int adjacent = 0; - interv_p x; - - q = list; - x1 = (interv_p) 0; - for (x2 = *list; x2 != (interv_p) 0; x2 = x2->i_next) { - if (t2 < x2->i_start) break; - x1 = x2; - q = &x2->i_next; - } - /* Now interval (t1,t2) should be inserted somewhere in between - * x1 and x2. - */ - if (x1 != (interv_p) 0 && t1 == x1->i_stop + 1) { - /* join x1 and (t1,t2) */ - x1->i_stop = t2; - adjacent++; - } - if (x2 != (interv_p) 0 && t2 + 1 == x2->i_start) { - /* join (t1,t2) and x2 */ - x2->i_start = t1; - adjacent++; - } - if (adjacent == 0) { - /* no adjacents, allocate a new intervalfor (t1,t2) */ - x = cons_interval(t1,t2); - x->i_next = x2; - *q = x; - } else { - if (adjacent == 2) { - /* x1, (t1,t2) and x2 can be put in one interval */ - x1->i_stop = x2->i_stop; - x1->i_next = x2->i_next; - oldinterval(x2); - } - } -} - - - -interv_p loop_lifetime(lp) - loop_p lp; -{ - /* Determine the timespan of the loop, expressed as a list - * of intervals. - */ - - interv_p lt = 0; - register bblock_p b; - register Lindex bi; - - for (bi = Lfirst(lp->LP_BLOCKS); bi != (Lindex) 0; - bi = Lnext(bi,lp->LP_BLOCKS)) { - b = (bblock_p) Lelem(bi); - add_interval(b->B_BEGIN,b->B_END,<); - } - return lt; -} - - -interv_p proc_lifetime(p) - proc_p p; -{ - /* Determine the lifetime of an entire procedure */ - - register bblock_p b; - - for (b = p->p_start; b->b_next != (bblock_p) 0; b = b->b_next) ; - return cons_interval(0,b->B_END); -} - - - -STATIC set_min_max(iv1,iv2) - interv_p *iv1,*iv2; -{ - /* Auxiliary routine of intersect */ - - interv_p i1 = *iv1, i2 = *iv2; - - if (i1->i_start < i2->i_start) { - *iv1 = i1; - *iv2 = i2; - } else { - *iv1 = i2; - *iv2 = i1; - } -} - - - -interv_p intersect(list1,list2) - interv_p list1,list2; -{ - /* Intersect two lifetimes, each denoted by a list of intervals. - * We maintain two pointers, pmin and pmax, pointing to the - * next interval of each list. At any time, pmin points to the - * interval of which i_start is lowest; pmax points to the - * other interval (i.e. the next interval of the other list). - */ - - interv_p lt = 0; - interv_p pmin,pmax; - -#define BUMP(p) p = p->i_next -#define EMIT(t1,t2) add_interval(t1,t2,<) - - pmin = list1; - pmax = list2; - while (pmin != (interv_p) 0 && pmax != (interv_p) 0) { - set_min_max(&pmin,&pmax); - if (pmax->i_start > pmin->i_stop) { - /* e.g. (5,7) and (9,13) */ - BUMP(pmin); - } else { - if (pmax->i_stop < pmin->i_stop) { - /* e.g. (5,12) and (7,10) */ - EMIT(pmax->i_start,pmax->i_stop); - BUMP(pmax); - } else { - /* e.g. (5,8) and (7,12) */ - EMIT(pmax->i_start,pmin->i_stop); - if (pmax->i_stop == pmin->i_stop) { - /* e.g. (5,12) and (7,12) */ - BUMP(pmax); - } - BUMP(pmin); - } - } - } - return lt; -} - - - -bool not_disjoint(list1,list2) - interv_p list1,list2; -{ - /* See if list1 and list2 do overlap somewhere */ - - interv_p pmin,pmax; - - pmin = list1; - pmax = list2; - while (pmin != (interv_p) 0 && pmax != (interv_p) 0) { - set_min_max(&pmin,&pmax); - if (pmax->i_start > pmin->i_stop) { - /* e.g. (5,7) and (9,13) */ - BUMP(pmin); - } else { - return TRUE; /* not disjoint */ - } - } - return FALSE; /* disjoint */ -} - - - -bool contains(t,timespan) - short t; - interv_p timespan; -{ - register interv_p iv; - - for (iv = timespan; iv != (interv_p) 0; iv = iv->i_next) { - if (t <= iv->i_stop) return (t >= iv->i_start); - } - return FALSE; -} - - - -interv_p copy_timespan(list) - interv_p list; -{ - /* copy the time span */ - - interv_p x,y,head,*p; - - head = (interv_p) 0; - p = &head; - - for (x = list; x != (interv_p) 0; x = x->i_next) { - y = cons_interval(x->i_start,x->i_stop); - *p = y; - p = &y->i_next; - } - return head; -} diff --git a/util/ego/ra/ra_interv.h b/util/ego/ra/ra_interv.h deleted file mode 100644 index 14985cfad..000000000 --- a/util/ego/ra/ra_interv.h +++ /dev/null @@ -1,35 +0,0 @@ - -/* R E G I S T E R A L L O C A T I O N - * - * R A _ I N T E R V A L . H - */ - - -extern interv_p cons_interval();/* (short t_start,t_stop) - * construct an interval - */ -extern add_interval(); /* (short t1,t2; interv_p *list) - * Add interval (t1,t2) to the list of - * intervals (which is an in-out parameter!). - */ -extern interv_p loop_lifetime();/* (loop_p lp) - * Determine the timespan of the loop, - * expressed as a list of intervals. - */ -extern interv_p proc_lifetime();/* (proc_p p) - * Determine the timespan of a procedure, - * expressed as an interval. - */ -extern interv_p intersect(); /* (interv_p list1,list2) - * Intersect two lifetimes, each denoted - * by a list of intervals. - */ -extern bool not_disjoint(); /* (interv_p list1,list2) - * See if list1 and list2 do overlap somewhere. - */ -extern bool contains(); /* (short t;interv_p timespan) - * See if t is part of the timespan. - */ -extern interv_p copy_timespan();/* (interv_p list) - * Make a copy of the timespan. - */ diff --git a/util/ego/ra/ra_items.c b/util/ego/ra/ra_items.c deleted file mode 100644 index 08bbf75c5..000000000 --- a/util/ego/ra/ra_items.c +++ /dev/null @@ -1,346 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * R A _ I T E M S . C - */ - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/def.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/aux.h" -#include "../share/alloc.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_reg.h" -#include "ra.h" -#include "ra_aux.h" -#include "ra_items.h" - - -#include "itemtab.h" -/* Maps EM mnemonics onto item types, e.g. op_lol -> LOCALVAR, op_ldc->DCONST, - * generated from em_mmen.h and itemtab.src files. - */ - -#define SMALL_CONSTANT(c) (c >= 0 && c <= 8) -/* prevent small constants from being put in a register */ - - -clean_tab(items) - item_p items[]; -{ - int t; - - for (t = 0; t < NRITEMTYPES;t++) { - items[t] = (item_p) 0; - } -} - - - - -short item_type(l) - line_p l; -{ - int instr = INSTR(l); - int t; - - if (instr < sp_fmnem || instr > sp_lmnem) return NO_ITEM; - t = itemtab[instr - sp_fmnem].id_type; - if (t == CONST && SMALL_CONSTANT(off_set(l))) return NO_ITEM; - return t; -} - - - -bool is_item(l) - line_p l; -{ - return item_type(l) != NO_ITEM; -} - - -item_p item_of(off,items) - offset off; - item_p items[]; -{ - register item_p x; - - for (x = items[LOCALVAR]; x != (item_p) 0; x = x->it_next) { - if (off == x->i_t.it_off) { - if (!x->it_desirable) break; - /* don't put this item in reg */ - return x; - } - } - return (item_p) 0; -} - - - -fill_item(item,l) - item_p item; - line_p l; -{ - item->it_type = item_type(l); - item->it_desirable = TRUE; - switch(item->it_type) { - case GLOBL_ADDR: - item->i_t.it_obj = OBJ(l); - break; - case PROC_ADDR: - item->i_t.it_proc = PROC(l); - break; - default: - item->i_t.it_off = off_set(l); - } -} - - - -STATIC bool desirable(l) - line_p l; -{ - /* See if it is really desirable to put the item of line l - * in a register. We do not put an item in a register if it - * is used as 'address of array descriptor' of an array - * instruction. - */ - - if (l->l_next != (line_p) 0) { - switch(INSTR(l->l_next)) { - case op_aar: - case op_lar: - case op_sar: - return FALSE; - } - } - return TRUE; -} - - - -STATIC int cmp_items(a,b) - item_p a,b; -{ - /* This routine defines the <, = and > relations between items, - * used to sort them for fast lookup. - */ - - offset n1,n2; - - switch(a->it_type) { - case GLOBL_ADDR: - assert(b->it_type == GLOBL_ADDR); - n1 = (offset) a->i_t.it_obj->o_id; - n2 = (offset) b->i_t.it_obj->o_id; - break; - case PROC_ADDR: - assert(b->it_type == PROC_ADDR); - n1 = (offset) a->i_t.it_proc->p_id; - n2 = (offset) b->i_t.it_proc->p_id; - break; - default: - n1 = a->i_t.it_off; - n2 = b->i_t.it_off; - } - return (n1 == n2 ? 0 : (n1 > n2 ? 1 : -1)); -} - - - -bool same_item(a,b) - item_p a,b; -{ - return cmp_items(a,b) == 0; -} - - -STATIC bool lt_item(a,b) - item_p a,b; -{ - return cmp_items(a,b) == -1; -} - - - -/* build_itemlist() - * - * Build a list of all items used in the current procedure. An item - * is anything that can be put in a register (a local variable, a constant, - * the address of a local or global variable). - * For each type of item we use a sorted list containing all items of - * that type found so far. - * A local variable is only considered to be an item if there is a - * register message for it (indicating it is never accessed indirectly). - * For each item, we keep track of all places where it is used - * (either fetched or stored into). The usage of a local variable is also - * considered to be a usage of its address. - */ - - - -static item_p items[NRITEMTYPES]; /* items[i] points to the list of type i */ - - - -STATIC short reg_type(item) - item_p item; -{ - /* See which type of register the item should best be assigned to */ - - switch(item->it_type) { - case LOCALVAR: - return regv_type(item->i_t.it_off); - /* use type mentioned in reg. message for local */ - case LOCAL_ADDR: - case GLOBL_ADDR: - case PROC_ADDR: - return reg_pointer; - case CONST: - case DCONST: - return reg_any; - default: assert(FALSE); - } - /* NOTREACHED */ -} - - - -STATIC short item_size(item) - item_p item; -{ - /* Determine the size of the item (in bytes) */ - - switch(item->it_type) { - case LOCALVAR: - return regv_size(item->i_t.it_off); - /* use size mentioned in reg. message for local */ - case LOCAL_ADDR: - case GLOBL_ADDR: - case PROC_ADDR: - return ps; /* pointer size */ - case CONST: - return ws; /* word size */ - case DCONST: - return 2 * ws; /* 2 * word size */ - default: assert(FALSE); - } - /* NOTREACHED */ -} - - - -STATIC init_item(a,b) - item_p a,b; -{ - a->it_type = b->it_type; - switch(a->it_type) { - case GLOBL_ADDR: - a->i_t.it_obj = b->i_t.it_obj; - break; - case PROC_ADDR: - a->i_t.it_proc = b->i_t.it_proc; - break; - default: - a->i_t.it_off = b->i_t.it_off; - } - a->it_usage = Lempty_set(); - a->it_regtype = reg_type(b); - a->it_size = item_size(b); - a->it_desirable = b->it_desirable; -} - - - -STATIC add_item(item,t,items) - item_p item; - time_p t; - item_p items[]; -{ - /* See if there was already a list element for item. In any - * case record the fact that item is used at 't'. - */ - - register item_p x, *q; - - q = &items[item->it_type]; /* each type has its own list */ - for (x = *q; x != (item_p) 0; x = *q) { - if (same_item(x,item)) { - /* found */ - if (!item->it_desirable) { - x->it_desirable = FALSE; - } - Ladd(t,&x->it_usage); - return; /* done */ - } - if (lt_item(item,x)) break; - q = &x->it_next; - } - /* not found, allocate new item; q points to it_next field of - * the item after which the new item should be put. - */ - x = newitem(); - x->it_next = *q; - *q = x; - init_item(x,item); - Ladd(t,&x->it_usage); -} - - - -STATIC add_usage(l,b,items) - line_p l; - bblock_p b; - item_p items[]; -{ - /* An item is used at line l. Add it to the list of items. - * A local variable is only considered to be an item, if - * there is a register message for it; else its address - * is also considered to be an item. - */ - - struct item thisitem; - - fill_item(&thisitem,l); /* fill in some fields */ - if (!desirable(l)) { - thisitem.it_desirable = FALSE; /* don't put item in reg. */ - } - if (thisitem.it_type == LOCALVAR && !is_regvar(thisitem.i_t.it_off)) { - /* Use address of local instead of local itself */ - thisitem.it_type = LOCAL_ADDR; - thisitem.it_regtype = reg_pointer; - } - add_item(&thisitem,cons_time(l,b),items); -} - - - -build_itemlist(p,items,nrinstr_out) - proc_p p; - item_p items[]; - int *nrinstr_out; -{ - /* Make a list of all items used in procedure p. - * An item is anything that can be put in a register, - * such as a local variable, a constant etc. - * As a side effect, determine the number of instructions of p. - */ - - register line_p l; - register bblock_p b; - register cnt= 0; - - clean_tab(items); - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - if (is_item(l)) { - add_usage(l,b,items); - } - cnt++; - } - } - *nrinstr_out = cnt; -} diff --git a/util/ego/ra/ra_items.h b/util/ego/ra/ra_items.h deleted file mode 100644 index 2bbe23209..000000000 --- a/util/ego/ra/ra_items.h +++ /dev/null @@ -1,31 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * R A _ I T E M S . H - */ - -extern short item_type(); /* (line_p l) - * Determine the type of item (constant,local - * variable etc.) accessed by l. - */ -extern bool is_item(); /* (line_p l) - * See if l accesses an item - */ -extern item_p item_of(); /* (offset off;item_p items) - * Determine the descriptor of the item - * accessed by l; return 0 if not found - */ -extern fill_item(); /* (item_p item;line_p l) - * Compute the type and obj/off attributes - * of the item accessed by l and put them - * in the given item descriptor. - */ -extern bool same_item(); /* (item_p a,b) - * See if a and b are the same items. - */ -extern build_itemlist(); /* (proc_p p;item_p items[]; int *nrinstr_out) - * Determine all items accessed by procedure p - * and put them in the items lists. All items - * of type T must be put in list items[T]. - * Also determine the number of instructions - * of p. - */ diff --git a/util/ego/ra/ra_lifet.c b/util/ego/ra/ra_lifet.c deleted file mode 100644 index 24f4ca911..000000000 --- a/util/ego/ra/ra_lifet.c +++ /dev/null @@ -1,74 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * R A _ L I F E T I M E . C - */ - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/def.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/aux.h" -#include "../share/alloc.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_reg.h" -#include "ra.h" -#include "ra_aux.h" -#include "ra_items.h" -#include "ra_lifet.h" - - -#define MSG_OFF(l) aoff(ARG(l),1) -#define is_livemsg(l) (INSTR(l) == ps_mes && aoff(ARG(l),0) == ms_liv) -#define is_deadmsg(l) (INSTR(l) == ps_mes && aoff(ARG(l),0) == ms_ded) - -build_lifetimes(items) - item_p items[]; -{ - /* compute the it_lives attribute of every item; this is - * a list of intervals during which the item is live, - * i.e. its current value may be used. - * We traverse the EM text of the current procedure in - * lexical order. If we encounter a live-message, we store - * the number ('time') of the current instruction in the - * it_lastlive attribute of the concerning item. If we see - * a dead-message for that item, we know that the item is - * live in between these two pseudo's. If the first message - * appearing in the procedure is a dead-message, the item - * is live from time 0 (start of procedure) till now. (Note - * that it_lastlive is initially 0!). - * The lifetime ends on the last instruction before the - * dead-message that is not a live -or dead message. - */ - - register line_p l; - register short now; - item_p item; - short last_code; - - last_code = 0; - for (now = 0; now < nrinstrs; now++) { - l = instrmap[now]; - if (is_livemsg(l)) { - item = item_of(MSG_OFF(l),items); - /* A local variable that is never used is NOT an - * item; yet, there may be a register message for it... - */ - if(item != (item_p) 0) { - item->it_lastlive = last_code + 1; - } - } else { - if (is_deadmsg(l)) { - item = item_of(MSG_OFF(l),items); - if (item != (item_p) 0) { - add_interval(item->it_lastlive, - last_code, &item->it_lives); - } - } else { - last_code = now; - } - } - } -} diff --git a/util/ego/ra/ra_lifet.h b/util/ego/ra/ra_lifet.h deleted file mode 100644 index bf7ab87d8..000000000 --- a/util/ego/ra/ra_lifet.h +++ /dev/null @@ -1,12 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * R A _ L I F E T I M E . H - */ - - -extern build_lifetimes(); /* item_p items[]; - * compute the it_lives attribute of every - * item; this is a list of intervals - * during which the item is live, - * i.e. its current value may be used. - */ diff --git a/util/ego/ra/ra_pack.c b/util/ego/ra/ra_pack.c deleted file mode 100644 index 2fe69de2a..000000000 --- a/util/ego/ra/ra_pack.c +++ /dev/null @@ -1,416 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * R A _ P A C K . C - */ - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/def.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/alloc.h" -#include "../share/aux.h" -#include "../../../h/em_reg.h" -#include "ra.h" -#include "ra_aux.h" -#include "ra_interv.h" - - -short regs_occupied[NRREGTYPES]; /* #occupied registers for reg_pointer, - * reg_any etc. - */ -#define reg_available(t) (regs_available[t] > regs_occupied[t]) - -STATIC initregcount() -{ - int t; - - for (t = 0; t < NRREGTYPES; t++) { - regs_occupied[t] = 0; - } -} - -STATIC alloc_p make_dummy() -{ - alloc_p x; - - x = newalloc(); - /* x->al_profits = 0; */ - return x; -} - - -STATIC bool fits_in(a,b,cont_item) - alloc_p a,b; - bool *cont_item; -{ - /* See if allocation a can be assigned the same register as b. - * Both allocations should be of the same register-type. - * Note that there may be several other allocations (mates) assigned to - * the same register as b. A new candidate (i.e. 'a') is only - * allowed to join them if it is not the rival of any resident - * allocation. - */ - - *cont_item = FALSE; - if (a->al_regtype == b->al_regtype) { - while (b != (alloc_p) 0) { - if (Cis_elem(a->al_id,b->al_rivals)) break; - b = b->al_mates; - if (b != (alloc_p) 0 && a->al_item == b->al_item) { - *cont_item = TRUE; - } - } - } - return b == (alloc_p) 0; -} - - -STATIC alloc_p find_fitting_alloc(alloc,packed) - alloc_p alloc,packed; -{ - /* Try to find and already packed allocation that is assigned - * a register that may also be used for alloc. - * We prefer allocations that have the same item as alloc. - */ - - register alloc_p x; - alloc_p cand = (alloc_p) 0; - bool cont_item; - - for (x = packed->al_next; x != (alloc_p) 0; x = x->al_next) { - if (fits_in(alloc,x,&cont_item)) { - cand = x; - if (cont_item) break; - } - } - return cand; -} - - -STATIC bool room_for(alloc,packed) - alloc_p alloc,packed; -{ - /* See if there is any register available for alloc */ - - return reg_available(alloc->al_regtype) || - (find_fitting_alloc(alloc,packed) != (alloc_p) 0); -} - - - -STATIC alloc_p best_alloc(unpacked,packed,time_opt) - alloc_p unpacked,packed; - bool time_opt; -{ - /* Find the next best candidate */ - - register alloc_p x,best; - bool loops_only; - - for (loops_only = time_opt; ; loops_only = FALSE) { - /* If we're optimizing execution time, we first - * consider loops. - */ - best = unpacked; /* dummy */ - for (x = unpacked->al_next; x != (alloc_p) 0; x = x->al_next) { - if ((!loops_only || x->al_isloop) && - x->al_profits > best->al_profits && - room_for(x,packed)) { - best = x; - } - } - if (best != unpacked || !loops_only) break; - } - return (best == unpacked ? (alloc_p) 0 : best); -} - - - - -STATIC alloc_p choose_location(alloc,packed,p) - alloc_p alloc,packed; - proc_p p; -{ - /* Decide in which register to put alloc */ - - alloc_p fit; - offset dum; - - fit = find_fitting_alloc(alloc,packed); - if (fit == (alloc_p) 0) { - /* Take a brand new register; allocate a dummy local for it */ - alloc->al_regnr = regs_occupied[alloc->al_regtype]++; - dum = tmplocal(p,(offset) alloc->al_item->it_size); - alloc->al_dummy = dum; - } else { - alloc->al_regnr = fit->al_regnr; - alloc->al_dummy = fit->al_dummy; - } - return fit; -} - - - -STATIC update_lists(alloc,unpacked,packed,fit) - alloc_p alloc,unpacked,packed,fit; -{ - /* 'alloc' has been granted a register; move it from the 'unpacked' - * list to the 'packed' list. Also remove any allocation from 'unpacked' - * having: - * 1. the same item as 'alloc' and - * 2. a timespan that overlaps the timespan of alloc. - */ - - register alloc_p x,q,next; - - q = unpacked; /* dummy element at head of list */ - for (x = unpacked->al_next; x != (alloc_p) 0; x = next) { - next = x->al_next; - if (x->al_item == alloc->al_item && - not_disjoint(x->al_timespan, alloc->al_timespan)) { - /* this code kills two birds with one stone; - * x is either an overlapping allocation or - * alloc itself! - */ - q->al_next = x->al_next; - if (x == alloc) { - if (fit == (alloc_p) 0) { - x->al_next = packed->al_next; - packed->al_next = x; - } else { - x->al_mates = fit->al_mates; - fit->al_mates = x; - x->al_next = (alloc_p) 0; - } - } - } else { - q = x; - } - } -} - - - -STATIC short cum_profits(alloc) - alloc_p alloc; -{ - /* Add the profits of all allocations packed in the same - * register as alloc (i.e. alloc and all its 'mates'). - */ - - alloc_p m; - short sum = 0; - - for (m = alloc; m != (alloc_p) 0; m = m->al_mates) { - sum += m->al_profits; - } - return sum; -} - - - -STATIC alloc_p best_cumprofits(list,x_out,prev_out) - alloc_p list, *x_out, *prev_out; -{ - /* Find the allocation with the best cummulative profits */ - - register alloc_p x,prev,best_prev; - short best = 0, cum; - - prev = list; - for (x = list->al_next; x != (alloc_p) 0; x = x->al_next) { - cum = cum_profits(x); - if (cum > best) { - best = cum; - best_prev = prev; - } - prev = x; - } - if (best == 0) { - *x_out = (alloc_p) 0; - } else { - *x_out = best_prev->al_next; - *prev_out = best_prev; - } -} - - - -STATIC account_regsave(packed,unpacked) - alloc_p packed,unpacked; -{ - /* After all packing has been done, we check for every allocated - * register whether it is really advantageous to use this - * register. It may be possible that the cost of saving - * and restoring the register are higher than the profits of all - * allocations packed in the register. If so, we simply remove - * all these allocations. - * The cost of saving/restoring one extra register may depend on - * the number of registers already saved. - */ - - alloc_p x,prev,checked; - short time,space; - short tot_cost = 0,diff; - - initregcount(); - checked = make_dummy(); - while (TRUE) { - best_cumprofits(packed,&x,&prev); - if (x == (alloc_p) 0) break; - regs_occupied[x->al_regtype]++; - regsave_cost(regs_occupied,&time,&space); - diff = add_timespace(time,space) - tot_cost; - if (diff < cum_profits(x)) { - /* x is o.k. */ - prev->al_next = x->al_next; - x->al_next = checked->al_next; - checked->al_next = x; - tot_cost += diff; - } else { - break; - } - } - /* Now every allocation in 'packed' does not pay off, so - * it is moved to unpacked, indicating it will not be assigned - * a register. - */ - for (x = unpacked; x->al_next != (alloc_p) 0; x = x->al_next); - x->al_next = packed->al_next; - packed->al_next = checked->al_next; - oldalloc(checked); -} - - - -STATIC bool in_single_reg(item,packed) - item_p item; - alloc_p packed; -{ - /* See if item is allocated in only one register (i.e. not in - * several different registers during several parts of its lifetime. - */ - - register alloc_p x,m; - bool seen = FALSE; - - for (x = packed->al_next; x != (alloc_p) 0; x = x->al_next) { - for ( m = x; m != (alloc_p) 0; m = m->al_mates) { - if (m->al_item == item) { - if (seen) return FALSE; - seen = TRUE; - break; - } - } - } - return TRUE; -} - - - -STATIC alloc_p find_prev(alloc,list) - alloc_p alloc,list; -{ - register alloc_p x; - - assert ( alloc != (alloc_p) 0); - for (x = list; x->al_next != alloc ; x = x->al_next) - assert(x != (alloc_p) 0); - return x; -} - - -/* If an item is always put in the same register during different loops, - * we try to put it in that register during the whole procedure. - * The profits of the whole-procedure allocation are updated to prevent - * account_regsave from rejecting it. - */ - -STATIC repl_allocs(new,old,packed) - alloc_p new,old,packed; -{ - alloc_p x,next,prev,*p; - short prof = 0; - - new->al_regnr = old->al_regnr; - new->al_dummy = old->al_dummy; - prev = find_prev(old,packed); - new->al_next = old->al_next; - old->al_next = (alloc_p) 0; - prev->al_next = new; - new->al_mates = old; - p = &new->al_mates; - for (x = old; x != (alloc_p) 0; x = next) { - next = x->al_mates; - if (x->al_item == new->al_item) { - prof += x->al_profits; - *p = next; - oldalloc(x); - } else { - p = &x->al_mates; - } - } - new->al_profits = prof; -} - - - -STATIC assemble_allocs(packed) - alloc_p packed; -{ - register alloc_p x,m,next; - alloc_p e; - bool voidb; - - for (x = packed->al_next; x != (alloc_p) 0; x = next) { - next = x->al_next; - for ( m = x; m != (alloc_p) 0; m = m->al_mates) { - if (in_single_reg(m->al_item,packed) && - (e = m->al_wholeproc) != (alloc_p) 0 && - e->al_profits > 0 && - fits_in(e,x,&voidb)) { - repl_allocs(e,x,packed); - break; - } - } - } -} - -pack(alloclist,time_opt,packed_out,not_packed_out,p) - alloc_p alloclist, *packed_out,*not_packed_out; - bool time_opt; - proc_p p; -{ - /* This is the packing system. It decides which allations - * to grant a register. - * We use two lists: packed (for allocations that are assigned a - * register) and unpacked (allocations not yet assigned a register). - * The packed list is in fact '2-dimensional': the al_next field is - * used to link allations that are assigned different registers; - * the al_mates field links allocations that are assigned to - * the same registers (i.e. these allocations fit together). - */ - - register alloc_p x; - alloc_p packed,unpacked,fit; - - initregcount(); - packed = make_dummy(); - unpacked = make_dummy(); - unpacked->al_next = alloclist; - while ((x = best_alloc(unpacked,packed,time_opt)) != (alloc_p) 0) { - fit = choose_location(x,packed,p); - update_lists(x,unpacked,packed,fit); - } - assemble_allocs(packed); - account_regsave(packed,unpacked); - /* remove allocations that don't pay off against register - * save/restore costs. - */ - *packed_out = packed->al_next; - *not_packed_out = unpacked->al_next; - oldalloc(packed); - oldalloc(unpacked); -} diff --git a/util/ego/ra/ra_pack.h b/util/ego/ra/ra_pack.h deleted file mode 100644 index 5f593d54c..000000000 --- a/util/ego/ra/ra_pack.h +++ /dev/null @@ -1,11 +0,0 @@ - -/* R E G I S T E R A L L O C A T I O N - * - * R A _ P A C K . H - */ - -extern pack(); /* ( alloc_p alloclist, *packed_out,*not_packed_out; - * bool time_opt; proc_p p) - * This is the packing system. It decides which - * allations to grant a register. - */ diff --git a/util/ego/ra/ra_profits.c b/util/ego/ra/ra_profits.c deleted file mode 100644 index 3c725a035..000000000 --- a/util/ego/ra/ra_profits.c +++ /dev/null @@ -1,235 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * R A _ P R O F I T S . C - */ - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/lset.h" -#include "../share/global.h" -#include "../../../h/em_reg.h" -#include "ra.h" -#include "ra_aux.h" -#include "ra_profits.h" - -STATIC bool test_cond(cond,val) - short cond; - offset val; -{ - switch(cond) { - case DEFAULT: - return TRUE; - case FITBYTE: - return val >= -128 && val < 128; - case IN_0_63: - return val >= 0 && val <= 63; - case IN_0_8: - return val >= 0 && val <= 8; - } -} - -STATIC short map_value(tab,val,time) - struct cond_tab tab[]; - offset val; - bool time; -{ - cond_p p; - - for (p = &tab[0]; ; p++) { - if (test_cond(p->mc_cond,val)) { - return (time ? p->mc_tval : p->mc_sval); - } - } -} - - -STATIC short index_value(tab,n,time) - struct cond_tab tab[]; - short n; - bool time; -{ - cond_p p; - - p = &tab[n]; - return (time ? p->mc_tval : p->mc_sval); -} - - -allocscore(itemtyp,localtyp,size,off,totyp,time_out,space_out) - short itemtyp, localtyp,totyp,size; - offset off; - short *time_out, *space_out; -{ - cond_p m; - - if (localtyp == reg_loop) localtyp = reg_any; - if (size == ws || size ==ps && totyp == reg_pointer) { - switch(itemtyp) { - case LOCALVAR: - m = alocaltab[localtyp][totyp]; - break; - case LOCAL_ADDR: - m = alocaddrtab[localtyp][totyp]; - break; - case CONST: - m = aconsttab; - break; - case DCONST: - m = aconsttab; - break; - case GLOBL_ADDR: - m = aglobaltab; - break; - case PROC_ADDR: - m = aproctab; - break; - } - } else { - m = (cond_p) 0; - } - *time_out = (m == (cond_p) 0 ? -1 : map_value(m,off,TRUE)); - *space_out = (m == (cond_p) 0 ? -1 : map_value(m,off,FALSE)); - /* - printf("itemtyp = %d, localtyp = %d off = %D\n",itemtyp,localtyp,off); - printf("ALLOCSCORE = (%d,%d)\n",*time_out,*space_out); - */ -} - -opening_cost(itemtyp,localtyp,off,time_out,space_out) - short itemtyp, localtyp; - offset off; - short *time_out, *space_out; -{ - cond_p m; - - if (localtyp == reg_loop) localtyp = reg_any; - switch(itemtyp) { - case LOCALVAR: - m = olocaltab[localtyp]; - break; - case LOCAL_ADDR: - m = olocaddrtab[localtyp]; - break; - case CONST: - m = oconsttab; - break; - case DCONST: - m = oconsttab; - break; - case GLOBL_ADDR: - m = oglobaltab; - break; - case PROC_ADDR: - m = oproctab; - break; - } - *time_out = (m == (cond_p) 0 ? 1000 : map_value(m,off,TRUE)); - *space_out = (m == (cond_p) 0 ? 1000 : map_value(m,off,FALSE)); - /* - printf("itemtyp = %d, localtyp = %d off = %D\n",itemtyp,localtyp,off); - printf("OPEN_COST = (%d,%d)\n",*time_out,*space_out); - */ -} - - - - -regsave_cost(regs,time_out,space_out) - short regs[], *time_out, *space_out; -{ - /* Estimate the costs of saving and restoring the registers - * The array regs contains the number of registers of every - * possible type. - */ - - short n = regs[reg_any] + regs[reg_pointer] + regs[reg_float]; - /* #registers */ - - *time_out = index_value(regsav_cost,n,TRUE); - *space_out = index_value(regsav_cost,n,FALSE); - /* - printf("REGSAVE COST, n=%d, (%d,%d)\n",n,*time_out,*space_out); - */ -} - - - -STATIC short dyn_inits(inits) - lset inits; -{ - Lindex i; - short sum = 0; - bblock_p b; - - for (i = Lfirst(inits); i != (Lindex) 0; i = Lnext(i,inits)) { - b = (bblock_p) Lelem(i); - sum += loop_scale(Lnrelems(b->b_loops)); - } - return sum; -} - - - -compute_profits(alloclist,time_opt) - alloc_p alloclist; - bool time_opt; -{ - /* Compute the profits attribute of every allocation. - * If the item of an allocation may be put in several types - * of register, we choose only the most advanteagous one. - */ - - register alloc_p alloc; - short s,t,rtyp,maxsc; - item_p item; - short time,space,sc; - short otime,ospace; - offset off; - short cnt,nr_inits; - - for (alloc = alloclist; alloc != (alloc_p) 0; alloc = alloc->al_next) { - maxsc = 0; - item = alloc->al_item; - switch(item->it_type) { - case LOCALVAR: - case LOCAL_ADDR: - case CONST: - case DCONST: - off = item->i_t.it_off; - break; - default: - off = 0; - } - for (rtyp = item->it_regtype; ; rtyp = reg_any) { - allocscore( item->it_type, - item->it_regtype, - item->it_size, - off, - rtyp, - &time, - &space); - opening_cost( item->it_type, - item->it_regtype, - off, - &otime, - &ospace); - nr_inits = Lnrelems(alloc->al_inits); - s = alloc->al_susecount * space - - nr_inits*ospace; - if (!alloc->al_isloop && nr_inits > 0) { - /* might lead to increase of execution time */ - cnt = 0; - } else { - cnt = alloc->al_dusecount; - } - t = cnt * time - dyn_inits(alloc->al_inits) * otime; - sc = (time_opt ? t : s); - if (sc >= maxsc) { - maxsc = sc; - alloc->al_regtype = rtyp; - alloc->al_profits = sc; - } - if (rtyp == reg_any) break; - } - } -} diff --git a/util/ego/ra/ra_profits.h b/util/ego/ra/ra_profits.h deleted file mode 100644 index 443b3631d..000000000 --- a/util/ego/ra/ra_profits.h +++ /dev/null @@ -1,11 +0,0 @@ - -/* R E G I S T E R A L L O C A T I O N - * - * R A _ P R O F I T S . H - */ - -extern compute_profits();/* (alloc_p alloclist) - * Compute the profits attribute of every allocation. - */ -extern regsave_cost(); /* (short regs[], *time_out, *space_out) - */ diff --git a/util/ego/ra/ra_xform.c b/util/ego/ra/ra_xform.c deleted file mode 100644 index be3aa3130..000000000 --- a/util/ego/ra/ra_xform.c +++ /dev/null @@ -1,565 +0,0 @@ -/* R E G I S T E R A L L O C A T I O N - * - * R A _ X F O R M . C - */ - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/def.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/aux.h" -#include "../share/alloc.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_mes.h" -#include "../../../h/em_reg.h" -#include "ra.h" -#include "ra_interv.h" -#include "ra_xform.h" -#include "ra_items.h" - - -/* The replacement table is used to transform instructions that reference - * items other than local variables (i.e. the address of a local or global - * variable or a single/double constant; the transformation of an instruction - * that references a local variable is very simple). - * The generated code depends on the word and pointer size of the target - * machine. - */ - - -struct repl { - short r_instr; /* instruction */ - short r_op; /* operand */ -}; - -/* REGNR,NO and STOP should not equal the wordsize or pointer size - * of any machine. - */ -#define REGNR -3 -#define NO -2 -#define STOP -1 -#define PS 0 -#define PS2 1 -#define WS 2 -#define WS2 3 - -#define LOAD_POINTER op_nop -#define BLANK {0, STOP} - -#define NRREPLACEMENTS 13 -#define REPL_LENGTH 3 - -struct repl repl_tab[NRREPLACEMENTS][REPL_LENGTH] = { - /* 0 */ {{op_lil, REGNR}, BLANK, BLANK}, - /* 1 */ {{LOAD_POINTER,REGNR}, {op_loi,PS}, {op_loi,WS}}, - /* 2 */ {{LOAD_POINTER,REGNR}, BLANK, BLANK}, - /* 3 */ {{LOAD_POINTER,REGNR}, {op_loi,WS2}, BLANK}, - /* 4 */ {{op_sil,REGNR}, BLANK, BLANK}, - /* 5 */ {{LOAD_POINTER,REGNR}, {op_loi,PS}, {op_sti,WS}}, - /* 6 */ {{LOAD_POINTER,REGNR}, {op_sti,WS2}, BLANK}, - /* 7 */ {{op_lil,REGNR}, {op_inc,NO}, {op_sil,REGNR}}, - /* 8 */ {{op_lil,REGNR}, {op_dec,NO}, {op_sil,REGNR}}, - /* 9 */ {{op_zer,WS}, {op_sil,REGNR}, BLANK}, - /*10 */ {{op_lol,REGNR}, BLANK, BLANK}, - /*11 */ {{op_ldl,REGNR}, BLANK, BLANK}, - /*12 */ {{LOAD_POINTER,REGNR}, {op_cai,NO}, BLANK}, -}; - - - - -init_replacements(psize,wsize) - short psize,wsize; -{ - /* The replacement code to be generated depends on the - * wordsize and pointer size of the target machine. - * The replacement table is initialized with a description - * of which sizes to use. This routine inserts the real sizes. - * It also inserts the actual EM instruction to be used - * as a 'Load pointer' instruction. - */ - - register int i,j; - short load_pointer; - struct repl *r; - - assert (psize == wsize || psize == 2*wsize); - load_pointer = (psize == wsize ? op_lol : op_ldl); - for (i = 0; i < NRREPLACEMENTS; i++) { - for (j = 0; j < REPL_LENGTH; j++) { - r = &repl_tab[i][j]; - if (r->r_op == STOP) break; - if (r->r_instr == LOAD_POINTER) { - r->r_instr = load_pointer; - } - switch (r->r_op) { - /* initially r_op describes how to compute - * the real operand of the instruction. */ - case PS2: - r->r_op = 2*psize; - break; - case PS: - r->r_op = psize; - break; - case WS2: - r->r_op = 2*wsize; - break; - case WS: - r->r_op = wsize; - break; - case NO: - case REGNR: /* use offset of dummy local, - * will be filled in later. - */ - break; - default: assert(FALSE); - } - } - } -} - - - -STATIC int repl_index(l) - line_p l; -{ - return itemtab[INSTR(l) - sp_fmnem].id_replindex; -} - - - -STATIC bool is_current(alloc,t) - alloc_p alloc; - short t; -{ - /* Is time t part of alloc's timespan? */ - - return contains(t,alloc->al_timespan); -} - - -STATIC match_item(item,l) - item_p item; - line_p l; -{ - /* See if the item used by l is the same one as 'item' */ - struct item thisitem; - - fill_item(&thisitem,l); - if (item->it_type == LOCAL_ADDR && thisitem.it_type == LOCALVAR) { - /* The usage of a local variable is also considered to - * be the usage of the address of that variable. - */ - thisitem.it_type = LOCAL_ADDR; - } - return item->it_type == thisitem.it_type && same_item(item,&thisitem); -} - - - -STATIC alloc_p find_alloc(alloclist,l,t) - alloc_p alloclist; - line_p l; - short t; -{ - /* See if any of the allocations of the list applies to instruction - * l at time t. - */ - - register alloc_p alloc,m; - - for (alloc = alloclist; alloc != (alloc_p) 0; alloc = alloc->al_next) { - for (m = alloc; m != (alloc_p) 0; m = m->al_mates) { - if (is_current(m,t) && match_item(m->al_item,l)) { - return m; - } - } - } - return (alloc_p) 0; -} - - -STATIC replace_line(l,b,list) - line_p l,list; - bblock_p b; -{ - if (b->b_start == l) { - b->b_start = list; - } else { - PREV(l)->l_next = list; - } - PREV(list) = PREV(l); - while (list->l_next != (line_p) 0) { - list = list->l_next; - } - list->l_next = l->l_next; - if (l->l_next != (line_p) 0) { - PREV(l->l_next) = list; - } - oldline(l); -} - - -STATIC line_p repl_code(lnp,regnr) - line_p lnp; - offset regnr; -{ - line_p head,*q,l,prev = (line_p) 0; - int i,index; - struct repl *r; - - q = &head; - index = repl_index(lnp); - for (i = 0; i < REPL_LENGTH; i++) { - r = &repl_tab[index][i]; - if (r->r_op == STOP) break; /* replacement < REPL_LENGTH */ - switch(r->r_op) { - case REGNR: - l = int_line(regnr); - break; - case NO: - l = newline(OPNO); - break; - default: - l = newline(OPSHORT); - SHORT(l) = r->r_op; - break; - } - *q = l; - l->l_instr = r->r_instr; - PREV(l) = prev; - prev = l; - q = &l->l_next; - } - return head; -} - - - -STATIC apply_alloc(b,l,alloc) - bblock_p b; - line_p l; - alloc_p alloc; -{ - /* 'l' is an EM instruction using an item that will be put in - * a register. Generate new code that uses the register instead - * of the item. - * If the item is a local variable the new code is the same as - * the old code, except for the fact that the offset of the - * local is changed (it now uses the dummy local that will be - * put in a register by the code generator). - * If the item is a constant, the new code is a LOL or LDL. - * If the item is the address of a local or global variable, things - * get more complicated. The new code depends on the instruction - * that uses the item (i.e. l). The new code, which may consist of - * several instructions, is obtained by consulting a replacement - * table. - */ - - line_p newcode; - - if (alloc->al_item->it_type == LOCALVAR) { - SHORT(l) = alloc->al_dummy; - } else { - newcode = repl_code(l,alloc->al_dummy); - replace_line(l,b,newcode); - } -} - - - -STATIC int loaditem_tab[NRITEMTYPES][2] = -{ /* WS 2 * WS */ - /*LOCALVAR*/ op_lol, op_ldl, - /*LOCAL_ADDR*/ op_lal, op_lal, - /*GLOBL_ADDR*/ op_lae, op_lae, - /*PROC_ADDR*/ op_lpi, op_lpi, - /*CONST*/ op_loc, op_nop, - /*DCONST*/ op_nop, op_ldc -}; - - -STATIC line_p load_item(item) - item_p item; -{ - /* Generate an EM instruction that loads the item on the stack */ - - line_p l; - - switch (item->it_type) { - case GLOBL_ADDR: - l = newline(OPOBJECT); - OBJ(l) = item->i_t.it_obj; - break; - case PROC_ADDR: - l = newline(OPPROC); - PROC(l) = item->i_t.it_proc; - break; - default: - l = int_line(item->i_t.it_off); - } - l->l_instr = loaditem_tab[item->it_type][item->it_size == ws ? 0 : 1]; - assert(l->l_instr != op_nop); - return l; -} - - -STATIC line_p store_local(size,off) - short size; - offset off; -{ - line_p l = int_line(off); - - l->l_instr = (size == ws ? op_stl : op_sdl); - return l; -} - - - -STATIC line_p init_place(b) - bblock_p b; -{ - - register line_p l,prev; - - prev = (line_p) 0; - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - switch(INSTR(l)) { - case ps_mes: - case ps_pro: - case op_lab: - break; - default: - return prev; - } - prev =l; - } - return prev; -} - - - -STATIC append_code(l1,l2,b) - line_p l1,l2; - bblock_p b; -{ - /* Append instruction l1 and l2 at begin of block b */ - - line_p l; - - DLINK(l1,l2); - l = init_place(b); - if (l == (line_p) 0) { - l2->l_next = b->b_start; - b->b_start = l1; - PREV(l1) = (line_p) 0; - } else { - l2->l_next = l->l_next; - DLINK(l,l1); - } - if (l2->l_next != (line_p) 0) { - PREV(l2->l_next) = l2; - } -} - - - -STATIC emit_init_code(list) - alloc_p list; -{ - /* Emit initialization code for all packed allocations. - * This code looks like "dummy_local := item", e.g. - * "LOC 25 ; STL -10" in EM terminology. - */ - - register alloc_p alloc,m; - Lindex bi; - bblock_p b; - - for (alloc = list; alloc != (alloc_p) 0; alloc = alloc->al_next) { - for (m = alloc; m != (alloc_p) 0; m = m->al_mates) { - for (bi = Lfirst(m->al_inits); bi != (Lindex) 0; - bi = Lnext(bi,m->al_inits)) { - /* "inits" contains all initialization points */ - b = (bblock_p) Lelem(bi); - append_code(load_item(m->al_item), - store_local(m->al_item->it_size, - m->al_dummy), - b); - } - } - } -} - - - -STATIC emit_mesregs(p,alloclist) - proc_p p; - alloc_p alloclist; -{ - line_p l,m,x; - alloc_p alloc; - - - l = p->p_start->b_start; - x = l->l_next; - for (alloc = alloclist; alloc != (alloc_p) 0; alloc = alloc->al_next) { - m = reg_mes(alloc->al_dummy,alloc->al_item->it_size, - alloc->al_regtype,INFINITE); - DLINK(l,m); - l = m; - } - if (x != (line_p) 0) DLINK(l,x); -} - -#define is_mesreg(l) (INSTR(l) == ps_mes && aoff(ARG(l),0) == ms_reg) - - - -rem_mes(p) - proc_p p; -{ - register bblock_p b; - register line_p l,next; - offset m; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (l = b->b_start; l != (line_p) 0; l = next) { - next = l->l_next; - if ( INSTR(l) == ps_mes && - ((m = aoff(ARG(l),0)) == ms_liv || m == ms_ded)) { - /* remove live/dead messages */ - rm_line(l,b); - } - } - } -} - - - -xform_proc(p,alloclist,nrinstrs,instrmap) - proc_p p; - alloc_p alloclist; - short nrinstrs; - line_p instrmap[]; -{ - /* Transform every instruction of procedure p that uses an item - * at a point where the item is kept in a register. - */ - - register short now = 0; - register line_p l,next; - register bblock_p b; - alloc_p alloc; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (l = b->b_start; l != (line_p) 0; l = next) { - next = l->l_next; - if (is_mesreg(l) && ARG(l)->a_next != (arg_p) 0 && - aoff(ARG(l),4) != INFINITE) { - /* All register messages for local variables - * that were not assigned a register get - * their 'count' fields* set to 0. - */ - ARG(l)->a_next->a_next->a_next - ->a_next->a_a.a_offset = 0; - } - if (is_item(l) && - (alloc = find_alloc(alloclist,l,now)) - != (alloc_p) 0 ) { - apply_alloc(b,l,alloc); - } - now++; - } - } - emit_init_code(alloclist); - emit_mesregs(p,alloclist); - rem_mes(p); -} - - - - -STATIC bool always_in_reg(off,allocs,size_out) - offset off; - alloc_p allocs; - short *size_out; -{ - /* See if the local variable with the given offset is stored - * in a register during its entire lifetime. As a side effect, - * return the size of the local. - */ - - alloc_p alloc,m; - item_p item; - - for (alloc = allocs; alloc != (alloc_p) 0; alloc = alloc->al_next) { - for (m = alloc; m != (alloc_p) 0; m = m->al_mates) { - item = m->al_item; - if (m->al_iswholeproc && - item->it_type == LOCALVAR && - item->i_t.it_off == off) { - *size_out = item->it_size; - return TRUE; - } - } - } - return FALSE; -} - - -rem_locals(p,allocs) - proc_p p; - alloc_p allocs; -{ - /* Try to decrease the number of locals of procedure p, by - * looking at which locals are always stored in a register. - */ - - offset nrlocals = p->p_localbytes; - short size; - - while (nrlocals > 0) { - /* A local can only be removed if all locals with - * higher offsets are removed too. - */ - if (always_in_reg(-nrlocals,allocs,&size)) { - OUTVERBOSE("local %d removed from proc %d\n", - nrlocals,p->p_id); - nrlocals -= size; - } else { - break; - } - } - p->p_localbytes = nrlocals; -} -rem_formals(p,allocs) - proc_p p; - alloc_p allocs; -{ - /* Try to decrease the number of formals of procedure p, by - * looking at which formals are always stored in a register. - */ - - offset nrformals = p->p_nrformals; - offset off = 0; - short size; - - if (nrformals == UNKNOWN_SIZE) return; - while (off < nrformals) { - if (always_in_reg(off,allocs,&size)) { - OUTVERBOSE("formal %d removed from proc %d\n", - off,p->p_id); - off += size; - } else { - break; - } - } - if (nrformals == off) { - OUTVERBOSE("all formals of procedure %d removed\n",p->p_id,0); - p->p_nrformals = 0; - } -} diff --git a/util/ego/ra/ra_xform.h b/util/ego/ra/ra_xform.h deleted file mode 100644 index 05710f420..000000000 --- a/util/ego/ra/ra_xform.h +++ /dev/null @@ -1,24 +0,0 @@ - -/* R E G I S T E R A L L O C A T I O N - * - * R A _ X F O R M . H - */ - -extern init_replacements(); /* (short psize,wsize) - * This routine must be called once, before - * any call to xform_proc. It initializes - * a machine dependent table. - */ -extern xform_proc(); /* (proc_p p; alloc_p alloclist; - * short nrinstrs; line_p instrmap[]) - * Transform a procedure. Alloclist must - * contain the packed allocations (i.e. those - * allocations that are assigned a register). - */ -bool always_in_reg(); /* ( offset off; alloc_p allocs; - * short *size_out;) - * See if the local variable with the given - * offset is stored in a register during its - * entire lifetime. As a side effect, - * return the size of the local. - */ diff --git a/util/ego/share/Makefile b/util/ego/share/Makefile deleted file mode 100644 index 16ef097c7..000000000 --- a/util/ego/share/Makefile +++ /dev/null @@ -1,264 +0,0 @@ -EM=../../.. -EMH=$(EM)/h -EML=$(EM)/lib - -SRC=\ -types.h def.h debug.h debug.c global.h global.c files.h files.c go.h go.c\ -map.h map.c aux.h aux.c get.h get.c put.h put.c alloc.h alloc.c lset.h lset.c\ -cset.h cset.c parser.h parser.c stack_chg.h stack_chg.c locals.h locals.c\ -init_glob.h init_glob.c - -PRFILES=$(SRC) - -.SUFFIXES: .m -.c.m: - $(CC) -c.m $(CFLAGS) $< - -all:\ -classdefs.h pop_push.h wordlen.h alloc.o cset.o debug.o files.o go.o\ -global.o lset.o map.o parser.o get.o put.o aux.o stack_chg.o locals.o\ -init_glob.o - - -em_files:\ -classdefs.h pop_push.h wordlen.h alloc.m cset.m debug.m\ -files.m go.m global.m lset.m map.m parser.m get.m put.m aux.m stack_chg.m\ -locals.m init_glob.m - -classdefs.h: \ - makeclassdef \ - cldefs.src - makeclassdef $(EMH)/em_mnem.h cldefs.src > classdefs.h -makeclassdef: \ - makecldef.c - $(CC) -o makeclassdef makecldef.c - -pop_push.h: \ - $(EM)/etc/em_table pop_push.awk - awk -f pop_push.awk < $(EM)/etc/em_table > pop_push.h - -wordlen.h: makewordlen - makewordlen > wordlen.h - rm makewordlen -makewordlen: makewlen.c - $(CC) -o makewordlen makewlen.c -show: \ - show.c - $(CC) -o show show.c $(EML)/em_data.a -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO -alloc.o: alloc.h -alloc.o: debug.h -alloc.o: types.h -aux.o: ../../../h/em_mes.h -aux.o: ../../../h/em_pseu.h -aux.o: ../share/alloc.h -aux.o: ../share/aux.h -aux.o: ../share/debug.h -aux.o: ../share/global.h -aux.o: ../share/map.h -aux.o: ../share/types.h -cset.o: alloc.h -cset.o: cset.h -cset.o: debug.h -cset.o: global.h -cset.o: types.h -debug.o: ../../../h/em_spec.h -debug.o: debug.h -debug.o: def.h -debug.o: global.h -debug.o: types.h -get.o: ../../../h/em_flag.h -get.o: ../../../h/em_mes.h -get.o: ../../../h/em_mnem.h -get.o: ../../../h/em_pseu.h -get.o: ../../../h/em_spec.h -get.o: alloc.h -get.o: aux.h -get.o: cset.h -get.o: debug.h -get.o: def.h -get.o: get.h -get.o: global.h -get.o: lset.h -get.o: map.h -get.o: types.h -global.o: types.h -go.o: ../share/alloc.h -go.o: ../share/debug.h -go.o: ../share/files.h -go.o: ../share/get.h -go.o: ../share/global.h -go.o: ../share/lset.h -go.o: ../share/map.h -go.o: ../share/put.h -go.o: ../share/types.h -init_glob.o: ../share/alloc.h -init_glob.o: ../share/debug.h -init_glob.o: ../share/global.h -init_glob.o: ../share/map.h -init_glob.o: ../share/types.h -locals.o: ../../../h/em_mes.h -locals.o: ../../../h/em_mnem.h -locals.o: ../../../h/em_pseu.h -locals.o: ../../../h/em_spec.h -locals.o: alloc.h -locals.o: aux.h -locals.o: cset.h -locals.o: debug.h -locals.o: def.h -locals.o: get.h -locals.o: global.h -locals.o: locals.h -locals.o: lset.h -locals.o: types.h -lset.o: alloc.h -lset.o: debug.h -lset.o: lset.h -lset.o: types.h -map.o: map.h -map.o: types.h -parser.o: ../../../h/em_mnem.h -parser.o: ../../../h/em_spec.h -parser.o: alloc.h -parser.o: aux.h -parser.o: classdefs.h -parser.o: debug.h -parser.o: global.h -parser.o: lset.h -parser.o: types.h -put.o: ../../../h/em_pseu.h -put.o: ../../../h/em_spec.h -put.o: alloc.h -put.o: debug.h -put.o: def.h -put.o: global.h -put.o: lset.h -put.o: map.h -put.o: put.h -put.o: types.h -show.o: ../../../h/em_flag.h -show.o: ../../../h/em_pseu.h -show.o: ../../../h/em_spec.h -show.o: ../share/def.h -show.o: ../share/global.h -show.o: ../share/types.h -stack_chg.o: ../share/debug.h -stack_chg.o: ../share/global.h -stack_chg.o: ../share/types.h -stack_chg.o: ../../../h/em_mnem.h -stack_chg.o: ../../../h/em_spec.h -stack_chg.o: pop_push.h - -alloc.m: alloc.h -alloc.m: debug.h -alloc.m: types.h -aux.m: ../../../h/em_mes.h -aux.m: ../../../h/em_pseu.h -aux.m: ../share/alloc.h -aux.m: ../share/aux.h -aux.m: ../share/debug.h -aux.m: ../share/global.h -aux.m: ../share/map.h -aux.m: ../share/types.h -cset.m: alloc.h -cset.m: cset.h -cset.m: debug.h -cset.m: global.h -cset.m: types.h -debug.m: ../../../h/em_spec.h -debug.m: debug.h -debug.m: def.h -debug.m: global.h -debug.m: types.h -get.m: ../../../h/em_flag.h -get.m: ../../../h/em_mes.h -get.m: ../../../h/em_mnem.h -get.m: ../../../h/em_pseu.h -get.m: ../../../h/em_spec.h -get.m: alloc.h -get.m: aux.h -get.m: cset.h -get.m: debug.h -get.m: def.h -get.m: get.h -get.m: global.h -get.m: lset.h -get.m: map.h -get.m: types.h -global.m: types.h -go.m: ../share/alloc.h -go.m: ../share/debug.h -go.m: ../share/files.h -go.m: ../share/get.h -go.m: ../share/global.h -go.m: ../share/lset.h -go.m: ../share/map.h -go.m: ../share/put.h -go.m: ../share/types.h -init_glob.m: ../share/alloc.h -init_glob.m: ../share/debug.h -init_glob.m: ../share/global.h -init_glob.m: ../share/map.h -init_glob.m: ../share/types.h -locals.m: ../../../h/em_mes.h -locals.m: ../../../h/em_mnem.h -locals.m: ../../../h/em_pseu.h -locals.m: ../../../h/em_spec.h -locals.m: alloc.h -locals.m: aux.h -locals.m: cset.h -locals.m: debug.h -locals.m: def.h -locals.m: get.h -locals.m: global.h -locals.m: locals.h -locals.m: lset.h -locals.m: types.h -lset.m: alloc.h -lset.m: debug.h -lset.m: lset.h -lset.m: types.h -map.m: map.h -map.m: types.h -parser.m: ../../../h/em_mnem.h -parser.m: ../../../h/em_spec.h -parser.m: alloc.h -parser.m: aux.h -parser.m: classdefs.h -parser.m: debug.h -parser.m: global.h -parser.m: lset.h -parser.m: types.h -put.m: ../../../h/em_pseu.h -put.m: ../../../h/em_spec.h -put.m: alloc.h -put.m: debug.h -put.m: def.h -put.m: global.h -put.m: lset.h -put.m: map.h -put.m: put.h -put.m: types.h -show.m: ../../../h/em_flag.h -show.m: ../../../h/em_pseu.h -show.m: ../../../h/em_spec.h -show.m: ../share/def.h -show.m: ../share/global.h -show.m: ../share/types.h -stack_chg.m: ../share/debug.h -stack_chg.m: ../share/global.h -stack_chg.m: ../share/types.h -stack_chg.m: ../../../h/em_mnem.h -stack_chg.m: ../../../h/em_spec.h -stack_chg.m: pop_push.h diff --git a/util/ego/share/alloc.c b/util/ego/share/alloc.c deleted file mode 100644 index 1784420a7..000000000 --- a/util/ego/share/alloc.c +++ /dev/null @@ -1,237 +0,0 @@ -/* S H A R E D F I L E - * - * A L L O C . C - */ - - - -#include -#include "types.h" -#include "debug.h" -#include "alloc.h" - - -short * myalloc(); -short * malloc(); - -#ifdef DEBUG - -STATIC unsigned maxuse, curruse; - -short *newcore(size) - int size; -{ - if ((curruse += (unsigned) (size+2)) > maxuse) maxuse = curruse; - return myalloc(size); -} - -oldcore(p,size) - short *p; - int size; -{ - curruse -= (size+2); - free(p); -} - -coreusage() -{ - fprintf(stderr,"Maximal core usage (excl. buffers):%u\n",maxuse); -} - -#endif - - -/* - * The following two sizetables contain the sizes of the various kinds - * of line and argument structures. - * The assumption when making the tables was that every non-byte object - * had to be aligned on an even boundary. On machines where alignment - * is worse ( for example a long has to be aligned on a longword bound ) - * these tables should be revised. - * A wasteful but safe approach is to replace every line of them by - * sizeof(line_t) - * and - * sizeof(arg_t) - * respectively. - */ - -#ifndef NOTCOMPACT -int lsizetab[] = { - 2*sizeof(line_p)+2*sizeof(byte), - 2*sizeof(line_p)+2*sizeof(byte)+sizeof(short), - 2*sizeof(line_p)+2*sizeof(byte)+sizeof(offset), - 2*sizeof(line_p)+2*sizeof(byte)+sizeof(lab_id), - 2*sizeof(line_p)+2*sizeof(byte)+sizeof(obj_p), - 2*sizeof(line_p)+2*sizeof(byte)+sizeof(proc_p), - 2*sizeof(line_p)+2*sizeof(byte)+sizeof(arg_p), -}; - -int asizetab[] = { - sizeof(arg_p)+sizeof(short)+sizeof(offset), - sizeof(arg_p)+sizeof(short)+sizeof(lab_id), - sizeof(arg_p)+sizeof(short)+sizeof(obj_p), - sizeof(arg_p)+sizeof(short)+sizeof(proc_p), - sizeof(arg_p)+sizeof(short)+sizeof(argb_t), - sizeof(arg_p)+sizeof(short)+sizeof(short)+sizeof(argb_t), - sizeof(arg_p)+sizeof(short)+sizeof(short)+sizeof(argb_t), - sizeof(arg_p)+sizeof(short)+sizeof(short)+sizeof(argb_t) -}; -#else -int lsizetab[] = { - sizeof(struct line), - sizeof(struct line), - sizeof(struct line), - sizeof(struct line), - sizeof(struct line), - sizeof(struct line), - sizeof(struct line) -}; - -int asizetab[] = { - sizeof (struct arg), - sizeof (struct arg), - sizeof (struct arg), - sizeof (struct arg), - sizeof (struct arg), - sizeof (struct arg), - sizeof (struct arg), - sizeof (struct arg) -}; -#endif - -/* - * alloc routines: - * Two parts: - * 1) typed alloc and free routines - * 2) untyped raw core allocation - */ - -/* - * PART 1 - */ - -line_p newline(optyp) int optyp; { - register line_p lnp; - register kind=optyp; - - lnp = (line_p) newcore(lsizetab[kind]); - TYPE(lnp) = optyp; - return(lnp); -} - -oldline(lnp) register line_p lnp; { - register kind=TYPE(lnp)&BMASK; - - if (kind == OPLIST) - oldargs(ARG(lnp)); - oldcore((short *) lnp,lsizetab[kind]); -} - -arg_p newarg(kind) int kind; { - register arg_p ap; - - ap = (arg_p) newcore(asizetab[kind]); - ap->a_type = kind; - return(ap); -} - -oldargs(ap) register arg_p ap; { - register arg_p next; - - while (ap != (arg_p) 0) { - next = ap->a_next; - switch(ap->a_type) { - case ARGSTRING: - oldargb(ap->a_a.a_string.ab_next); - break; - case ARGICN: - case ARGUCN: - case ARGFCN: - oldargb(ap->a_a.a_con.ac_con.ab_next); - break; - } - oldcore((short *) ap,asizetab[ap->a_type]); - ap = next; - } -} - -oldargb(abp) register argb_p abp; { - register argb_p next; - - while (abp != (argb_p) 0) { - next = abp->ab_next; - oldcore((short *) abp,sizeof (argb_t)); - abp = next; - } -} - -oldobjects(op) register obj_p op; { - register obj_p next; - - while (op != (obj_p) 0) { - next = op->o_next; - oldcore((short *) op, sizeof(struct obj)); - op = next; - } -} - -olddblock(dbl) dblock_p dbl; { - oldobjects(dbl->d_objlist); - oldargs(dbl->d_values); - oldcore((short *) dbl, sizeof(struct dblock)); -} - - -short **newmap(length) short length; { - return((short **) newcore((length+1) * sizeof(short *))); -} - -oldmap(mp,length) short **mp, length; { - oldcore((short *) mp, (length+1) * sizeof(short *)); -} - - -cset newbitvect(n) short n; { - return((cset) newcore((n-1)*sizeof(int) + sizeof(struct bitvector))); - /* sizeof(struct bitvector) equals to the size of a struct with - * one short, followed by one ALLIGNED int. So the above statement - * also works e.g. on a VAX. - */ -} - -oldbitvect(s,n) cset s; short n; { - oldcore((short *) s, (n-1)*sizeof(int) + sizeof(struct bitvector)); -} - - -short *newtable(length) short length; { - return((short *) newcore((length+1) * sizeof(short))); -} - -oldtable(mp,length) short **mp, length; { - oldcore((short *) mp, (length+1) * sizeof(short)); -} - -cond_p newcondtab(l) int l; -{ - return (cond_p) newcore(l * (sizeof (struct cond_tab))); -} - -oldcondtab(tab) cond_p tab; -{ - int i; - for (i = 0; tab[i].mc_cond != DEFAULT; i++); - oldcore((short *) tab,((i+1) * sizeof (struct cond_tab))); -} - - -short *myalloc(size) register size; { - register short *p,*q; - - p = malloc(size); - if (p == 0) - error("out of memory"); - for(q=p;size>0;size -= sizeof(short)) - *q++ = 0; - return(p); -} diff --git a/util/ego/share/alloc.h b/util/ego/share/alloc.h deleted file mode 100644 index 61029a184..000000000 --- a/util/ego/share/alloc.h +++ /dev/null @@ -1,54 +0,0 @@ -/* I N T E R M E D I A T E C O D E - * - * C O R E A L L O C A T I O N A N D D E A L L O C A T I O N - */ - -#ifdef DEBUG -extern short *newcore(); -extern oldcore(); -#else -extern short *myalloc(); -#define newcore(size) myalloc(size) -#define oldcore(p,size) free(p) -#endif - -#define newstruct(t) (newcore (sizeof (struct t))) -#define oldstruct(t,p) oldcore((short *) p,sizeof (struct t)) - -extern line_p newline(); /* (byte optype) */ -extern arg_p newarg(); /* (byte argtype) */ -extern short **newmap(); /* (short length) */ -extern cset newbitvect(); /* (short nrbytes) */ -extern cond_p newcondtab(); - - -extern oldline() ; -extern oldargs() ; -extern oldargb() ; -extern oldobjects() ; -extern olddblock() ; -extern oldmap(); -extern oldbitvect(); /* (cset s, short nrbytes) */ -extern oldcondtab(); - -extern short *newtable(); -extern oldtable(); - -#define newdblock() (dblock_p) newstruct(dblock) -#define newobject() (obj_p) newstruct(obj) -#define newproc() (proc_p) newstruct(proc) -#define newargb() (argb_p) newstruct(argbytes) -#define newbblock() (bblock_p) newstruct(bblock) -#define newelem() (elem_p) newstruct(elemholder) -#define newloop() (loop_p) newstruct(loop) -#define newuse() (use_p) newstruct(use) -#define newchange() (change_p) newstruct(change) -#define newlocal() (local_p) newstruct(local) - -#define oldproc(x) oldstruct(proc,x) -#define oldbblock(x) oldstruct(bblock,x) -#define oldelem(x) oldstruct(elemholder,x) -#define oldloop(x) oldstruct(loop,x) -#define olduse(x) oldstruct(use,x) -#define oldchange(x) oldstruct(change,x) -#define oldlocal(x) oldstruct(local,x) diff --git a/util/ego/share/aux.c b/util/ego/share/aux.c deleted file mode 100644 index 2e4c8b361..000000000 --- a/util/ego/share/aux.c +++ /dev/null @@ -1,246 +0,0 @@ -/* S H A R E D F I L E - * - * A U X I L I A R Y R O U T I N E S - * - */ - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/alloc.h" -#include "../share/aux.h" -#include "../share/map.h" -#include "../share/lset.h" -#include "../../../h/em_mes.h" -#include "../../../h/em_pseu.h" - -offset off_set(lnp) - line_p lnp; -{ - switch(lnp->l_optype) { - case OPSHORT: - return (offset) SHORT(lnp); - case OPOFFSET: - return OFFSET(lnp); - default: - assert(FALSE); - } - /* NOTREACHED */ -} - - - - -offset aoff(ap,n) - register arg_p ap; -{ - while (n>0) { - if (ap != (arg_p) 0) - ap = ap->a_next; - n--; - } - if (ap == (arg_p) 0) - error("too few parameters"); - if (ap->a_type != ARGOFF) - error("offset expected"); - return(ap->a_a.a_offset); -} - - -offset tmplocal(p,size) - proc_p p; - offset size; -{ - /* Allocate a new local variable in the stack frame of p */ - - p->p_localbytes += size; - return -(p->p_localbytes); -} - - - - -line_p int_line(off) - offset off; -{ - /* Allocate a line struct of type OPSHORT or OPOFFSET, - * whichever one fits best. - */ - - line_p lnp; - - if ((short) off == off) { - /* fits in a short */ - lnp = newline(OPSHORT); - SHORT(lnp) = (short) off; - } else { - lnp = newline(OPOFFSET); - OFFSET(lnp) = off; - } - return lnp; -} - - - -line_p reg_mes(tmp,size,typ,score) - offset tmp; - short size; - int typ,score; -{ - /* Generate a register message */ - - line_p l; - arg_p a; - -#define NEXTARG(a,val) a->a_next = newarg(ARGOFF); a = a->a_next; \ - a->a_a.a_offset = val - l = newline(OPLIST); - l->l_instr = ps_mes; - a = ARG(l) = newarg(ARGOFF); - a->a_a.a_offset = ms_reg; - NEXTARG(a,tmp); - NEXTARG(a,size); - NEXTARG(a,typ); - NEXTARG(a,score); - return l; -} - - -bool dom(b1,b2) - bblock_p b1,b2; -{ - /* See if b1 dominates b2. Note that a block always - * dominates itself. - */ - - register bblock_p b; - - for (b = b2; b != (bblock_p) 0; b = b->b_idom) { - /* See if b1 is a (not necessarily proper) ancestor - * of b2 in the immediate dominator tree. - */ - if (b == b1) return TRUE; - } - return FALSE; -} - - -bblock_p common_dom(a,b) - bblock_p a,b; -{ - /* find a basic block that dominates a as well as b; - * note that a basic block also dominates itself. - */ - - assert (a != (bblock_p) 0); - assert (b != (bblock_p) 0); - if (dom(a,b)) { - return a; - } else { - if (dom(b,a)) { - return b; - } else { - return common_dom(a->b_idom,b->b_idom); - } - } -} - -#define R time_space_ratio - -short add_timespace(time,space) - short time,space; -{ - /* Add together a time and space, using the time_space_ratio - * parameter that may be set by the user, indicating the need - * to optimize for time, space or something in between. - */ - - return (R * time + (100 - R) * space) / 100; -} - - - -rm_line(l,b) - line_p l; - bblock_p b; -{ - if (b->b_start == l) { - b->b_start = l->l_next; - } else { - PREV(l)->l_next = l->l_next; - } - if (l->l_next != (line_p) 0) { - PREV(l->l_next) = PREV(l); - } - oldline(l); -} - - - - -appnd_line(l1,l2) - line_p l1,l2; -{ - /* Put l1 after l2 */ - - PREV(l1) = l2; - l1->l_next = l2->l_next; - l2->l_next = l1; - if (l1->l_next != (line_p) 0) { - PREV(l1->l_next) = l1; - } -} - - - -line_p last_instr(b) - bblock_p b; -{ - /* Determine the last line of a list */ - - register line_p l = b->b_start; - - if (l == (line_p) 0) return (line_p) 0; - while (l->l_next != (line_p) 0) l = l->l_next; - return l; -} - - - - -line_p find_mesreg(off) - offset off; -{ - /* Find the register message for the local with the given offset */ - - Lindex li; - line_p l; - - for (li = Lfirst(mesregs); li != (Lindex) 0; li = Lnext(li,mesregs)) { - l = (line_p) Lelem(li); - if (aoff(ARG(l),1) == off) return l; - } - return (line_p) 0; -} - - -bool is_regvar(off) - offset off; -{ - return find_mesreg(off) != (line_p) 0; -} - - - -offset regv_arg(off,n) - offset off; - int n; -{ - /* fetch the n'th argument of the register message of the - * local variable at offset off; - */ - - line_p x = find_mesreg(off); - assert (x != (line_p) 0); - return aoff(ARG(x),n); -} diff --git a/util/ego/share/aux.h b/util/ego/share/aux.h deleted file mode 100644 index 6a5243abb..000000000 --- a/util/ego/share/aux.h +++ /dev/null @@ -1,66 +0,0 @@ -/* S H A R E D - * - * A U X I L I A R Y R O U T I N E S - * - */ - - -extern offset off_set(); /* (line_p lnp) - * lnp has a SHORT or OFFSET operand. Return - * the value of this operand as an offset. - */ -extern offset aoff(); /* (arg_p list; int n) - * Determine the offset field of the - * n'th argument in the list (this argument - * must have type ARGOFF). Start counting at 0. - */ -extern offset tmplocal(); /* (proc_p p, offset size) - * Allocate a new local variable in the - * stack frame of p. - */ -line_p int_line(); /* (offset off) - * Allocate a line struct of type OPSHORT - * or OPOFFSET, whichever one fits best. - */ -extern line_p reg_mes(); /* (offset tmp; short size; int typ,score) - * Generate a register message with the - * given arguments. - */ -extern bool dom(); /* (bblock_p b1,b2) - /* See if b1 dominates b2. Note that a - * block always * dominates itself. - */ -extern bblock_p common_dom(); /* (bblock_p a,b) - * find a basic block that dominates a as - * well as b; note that a basic block also - * dominates itself. - */ -extern short add_timespace(); /* (short time,space) - * Add together a time and space, using - * the time_space_ratio parameter that - * may be set by the user. - */ -extern rm_line(); /* ( line_p l; bblock_p b) - * Remove line l from b basic block b. - */ - -extern appnd_line(); /* ( line_p l1,l2) - * Put line l1 after l2. - */ -extern line_p last_instr(); /* ( bblock_p b) - * Determine the last line of a basic block. - */ -extern line_p find_mesreg(); /* (offset off) - * Find the register message for the local - * with the given offset. - */ -extern bool is_regvar(); /* (offset off) - * See if there is a 'register message' - * for the local variable with the - * given offset. - */ -extern offset regv_arg(); /* (offset off; int n) - * Fetch the n'th argument of the - * register message of the local with - * the given offset. - */ diff --git a/util/ego/share/cldefs.src b/util/ego/share/cldefs.src deleted file mode 100644 index 23dc13806..000000000 --- a/util/ego/share/cldefs.src +++ /dev/null @@ -1,69 +0,0 @@ -op_aar 11 7 -op_adf 2 1 -op_adi 2 1 -op_adp 7 7 -op_ads 4 7 -op_adu 2 1 -op_and 2 1 -op_cff 10 1 -op_cfi 10 1 -op_cfu 10 1 -op_cif 10 1 -op_cii 10 1 -op_ciu 10 1 -op_cmf 2 5 -op_cmi 2 5 -op_cmp 8 5 -op_cms 2 5 -op_cmu 2 5 -op_com 1 1 -op_cuf 10 1 -op_cui 10 1 -op_cuu 10 1 -op_dec 5 5 -op_dup 1 2 -op_dvf 2 1 -op_dvi 2 1 -op_dvu 2 1 -op_fef 2 2 -op_fif 2 2 -op_inc 5 5 -op_ior 2 1 -op_lae 9 7 -op_lal 9 7 -op_ldc 9 6 -op_lde 9 6 -op_ldf 7 6 -op_ldl 9 6 -op_lil 9 5 -op_loc 9 5 -op_loe 9 5 -op_lof 7 5 -op_loi 7 12 -op_lol 9 5 -op_mlf 2 1 -op_mli 2 1 -op_mlu 2 1 -op_ngf 1 1 -op_ngi 1 1 -op_rmi 2 1 -op_rmu 2 1 -op_rol 3 1 -op_ror 3 1 -op_sbf 2 1 -op_sbi 2 1 -op_sbs 6 1 -op_sbu 2 1 -op_sli 3 1 -op_slu 3 1 -op_sri 3 1 -op_sru 3 1 -op_teq 5 5 -op_tge 5 5 -op_tgt 5 5 -op_tle 5 5 -op_tlt 5 5 -op_tne 5 5 -op_xor 2 1 -op_zer 9 1 -op_zrf 9 1 diff --git a/util/ego/share/cset.c b/util/ego/share/cset.c deleted file mode 100644 index 646fefed1..000000000 --- a/util/ego/share/cset.c +++ /dev/null @@ -1,277 +0,0 @@ -/* S H A R E D F I L E - * - * C S E T . C - */ - - -#include "types.h" -#include "cset.h" -#include "alloc.h" -#include "debug.h" -#include "global.h" - - -/* A set over a range of integers from 1 to N may be represented - * as a 'compact' set. Such a set is represented as a 'bitvector' - * record, containing the size of the set (i.e. N) and a row - * of words (the bitvector itself). An integer J (1 <= J <= N) is - * an element of the set iff the J-th bit of the vector is a '1'. - * Any redundant bits in the last word are garanteed to be zero bits. - * This package implements the usual operations on sets. - * The name of every operation is preceede by a 'C' to - * distinguish it from the operation on 'long' (list) - * sets whth a similar name. - */ - - -/* The two arithmetic operations 'divide by wordlength' and - * 'modulo wordlength' can be performed very efficiently - * if the word length (of the source machine) is 16. - */ - - - - -cset Cempty_set(n) - short n; -{ - cset s; - - s = newbitvect(DIVWL(n-1) + 1); - s->v_size = n; - return s; -} - - -bool Cis_elem(x,s) - Celem_t x; - cset s; -{ - short n; - int mask; - - assert(x>0 && x <= s->v_size); - n = DIVWL(x-1); - mask = (1 << MODWL(x-1)); - if ((s->v_bits[n] & mask) == 0) { - return FALSE; - } else { - return TRUE; - } -} - - - -Cadd(x,s_p) - Celem_t x; - cset *s_p; -{ - cset s; - short n; - int mask; - - s = *s_p; - assert(x>0 && x <= s->v_size); - n = DIVWL(x-1); - mask = (1 << MODWL(x-1)); - s->v_bits[n] |= mask; -} - - -Cremove(x,s_p) - Celem_t x; - cset *s_p; -{ - cset s; - short n; - int mask; - - s = *s_p; - assert(x>0 && x <= s->v_size); - n = DIVWL(x-1); - mask = (1 << MODWL(x-1)); - s->v_bits[n] &= ~mask; -} - - - -/* The operations first, next and elem can be used to iterate - * over a set. For example: - * for (i = Cfirst(s); i != (Cindex) 0; i = Cnext(i,s) { - * x = Celem(i); - * use x - * } - * which is like: - * 'for all elements x of s do' - * use x - * - * The implementation of first and next is not very fast. - * It could be made much more efficient (at the price of a - * higher complexity) by not using 'is_elem'. - * Iteration over a bitvector, however, is not supposed to - * be used very often. - */ - -Cindex Cfirst(s) - cset s; -{ - return Cnext((Cindex) 0,s); -} - - -Cindex Cnext(i,s) - Cindex i; - cset s; -{ - register short n; - - for (n = i+1; n <= s->v_size; n++) { - if (Cis_elem(n,s)) { - return (Cindex) n; - } - } - return (Cindex) 0; -} - - -Celem_t Celem(i) - Cindex i; -{ - return (Celem_t) i; -} - - - -Cjoin(s1,s2_p) - cset s1, *s2_p; -{ - /* Two sets are joined by or-ing their bitvectors, - * word by word. - */ - - cset s2; - short n; - register short i; - - s2 = *s2_p; - assert(s1->v_size == s2->v_size); - n = DIVWL(s1->v_size -1); /* #words -1 */ - for (i = 0; i <= n; i++) { - s2->v_bits[i] |= s1->v_bits[i]; - } -} - - - -Cintersect(s1,s2_p) - cset s1, *s2_p; -{ - /* Two sets are intersected by and-ing their bitvectors, - * word by word. - */ - - cset s2; - short n; - register short i; - - s2 = *s2_p; - assert(s1->v_size == s2->v_size); - n = DIVWL(s1->v_size -1); /* #words -1 */ - for (i = 0; i <= n; i++) { - s2->v_bits[i] &= s1->v_bits[i]; - } -} - - -Cdeleteset(s) - cset s; -{ - oldbitvect(s,DIVWL(s->v_size - 1) + 1); -} - - -bool Cis_subset(s1,s2) - cset s1,s2; -{ - /* See if s1 is a subset of s2 */ - - register short i; - - assert(s1->v_size == s2->v_size); - if (s1->v_size == 0) return TRUE; - for (i = 0; i <= DIVWL(s1->v_size-1); i++) { - if ((s1->v_bits[i] & ~(s2->v_bits[i])) != 0) { - return FALSE; - } - } - return TRUE; -} - - -Cclear_set(s_p) - cset *s_p; -{ - cset s; - register short i; - - s = *s_p; - assert (s != (cset) 0); - for (i = 0; i <= DIVWL(s->v_size-1); i++) { - s->v_bits[i] = 0; - } -} - - -Ccopy_set(s1,s2_p) - cset s1, *s2_p; -{ - cset s2; - register short i; - - s2 = *s2_p; - assert (s1->v_size == s2->v_size); - for (i = 0; i <= DIVWL(s1->v_size-1); i++) { - s2->v_bits[i] = s1->v_bits[i]; - } -} - - -Csubtract(s1,s2_p) - cset s1, *s2_p; -{ - cset s2; - register short i; - - s2 = *s2_p; - assert (s1->v_size == s2->v_size); - for (i = 0; i <= DIVWL(s1->v_size-1); i++) { - s2->v_bits[i] &= ~(s1->v_bits[i]); - } -} - - -bool Cequal(s1,s2) - cset s1, s2; -{ - register short i; - - assert (s1->v_size == s2->v_size); - for (i = 0; i <= DIVWL(s1->v_size-1); i++) { - if (s1->v_bits[i] != s2->v_bits[i]) return FALSE; - } - return TRUE; -} - -short Cnrelems(s) - cset s; -{ - register short n, cnt; - - cnt = 0; - for (n = 1; n <= s->v_size; n++) { - if (Cis_elem(n,s)) { - cnt++; - } - } - return cnt; -} diff --git a/util/ego/share/cset.h b/util/ego/share/cset.h deleted file mode 100644 index 1c7199c08..000000000 --- a/util/ego/share/cset.h +++ /dev/null @@ -1,21 +0,0 @@ -/* O P E R A T I O N S F O R - * C O M P A C T S E T S - */ - - -extern cset Cempty_set(); /* (short) */ -extern bool Cis_elem(); /* (Celem, cset) */ -extern Cadd(); /* (Celem, *cset) */ -extern Cremove(); /* (Celem, *cset) */ -extern Cindex Cfirst(); /* (cset) */ -extern Cindex Cnext(); /* (Cindex, cset) */ -extern Celem_t Celem(); /* (Cindex) */ -extern Cjoin(); /* (cset, *cset) */ -extern Cintersect(); /* (cset, *cset) */ -extern Cdeleteset(); /* (cset) */ -extern bool Cis_subset(); /* (cset, cset) */ -extern Cclearset(); /* (cset, *cset) */ -extern Ccopy_set(); /* (cset, *cset) */ -extern Csubtract(); /* (cset, *cset) */ -extern bool Cequal(); /* (cset, cset) */ -extern short Cnrelems(); /* (cset) */ diff --git a/util/ego/share/debug.c b/util/ego/share/debug.c deleted file mode 100644 index 104a30767..000000000 --- a/util/ego/share/debug.c +++ /dev/null @@ -1,145 +0,0 @@ -/* S H A R E D F I L E - * - * D E B U G . C - */ - - -#include -#include "types.h" -#include "def.h" -#include "debug.h" -#include "../../../h/em_spec.h" -#include "global.h" - - - -int linecount; /* # lines in this file */ -bool verbose_flag = FALSE; /* generate verbose output ? */ - -/* VARARGS1 */ -error(s,a) char *s,*a; { - - fprintf(stderr,"error on line %u",linecount); - if (filename != (char *) 0) { - fprintf(stderr," file %s",filename); - } - fprintf(stderr,": "); - fprintf(stderr,s,a); - fprintf(stderr,"\n"); - _cleanup(); - abort(); - exit(-1); -} - -#ifdef TRACE -/* VARARGS1 */ -OUTTRACE(s,n) - char *s; - int n; -{ - fprintf(stderr,"> "); - fprintf(stderr,s,n); - fprintf(stderr,"\n"); -} -#endif - -#ifdef VERBOSE -/* VARARGS1 */ -OUTVERBOSE(s,n1,n2) - char *s; - int n1,n2; -{ - if (verbose_flag) { - fprintf(stderr,"optimization: "); - fprintf(stderr,s,n1,n2); - fprintf(stderr,"\n"); - } -} -#endif - - - -#ifdef DEBUG -badassertion(file,line) char *file; unsigned line; { - - fprintf(stderr,"assertion failed file %s, line %u\n",file,line); - error("assertion"); -} -#endif -/* Valid Address */ - -VA(a) short *a; { - if (a == (short *) 0) error("VA: 0 argument"); - if ( ((unsigned) a & 01) == 01) { - /* MACHINE DEPENDENT TEST */ - error("VA: odd argument"); - } -} - - -/* Valid Instruction code */ - -VI(i) short i; { - if (i > ps_last) error("VI: illegal instr: %d", i); -} - - -/* Valid Line */ - -VL(l) line_p l; { - byte instr, optype; - - VA((short *) l); - instr = l->l_instr; - VI(instr); - optype = TYPE(l); - if (optype < OP_FIRST || optype > OP_LAST) { - error("VL: illegal optype: %d", optype); - } -} - - - -/* Valid Data block */ - -VD(d) dblock_p d; { - byte pseudo; - - VA((short *) d); - pseudo = d->d_pseudo; - if (pseudo < D_FIRST || pseudo > D_LAST) { - error("VD: illegal pseudo: %d",pseudo); - } -} - - -/* Valid Object */ - -VO(o) obj_p o; { - offset off; - - VA((short *) o); - off = o->o_off; - if (off < 0 || off > 10000) { - error("VO: unlikely offset: %d", off); - } -} - - - -/* Valid Proc */ - -VP(p) proc_p p; { - proc_id pid; - int nrlabs; - - VA((short *) p); - pid = p->p_id; - if (pid <0 || pid > 1000) { - error("VP: unlikely proc_id: %d", (int) pid); - } - nrlabs = p->p_nrlabels; - if (nrlabs < 0 || nrlabs > 500) { - error("VP: unlikely p_nrlabels: %d", nrlabs); - } -} diff --git a/util/ego/share/debug.h b/util/ego/share/debug.h deleted file mode 100644 index 72da2c683..000000000 --- a/util/ego/share/debug.h +++ /dev/null @@ -1,56 +0,0 @@ -/* D E B U G G I N G T O O L S */ - -/* TEMPORARY: */ -#define DEBUG - -extern int linecount; /* # lines in this file */ -extern bool verbose_flag; /* generate verbose output ? */ - -/* VARARGS 1 */ -error(); - - -#ifdef TRACE -extern OUTTRACE(); -#else -#define OUTTRACE(s,n) -#endif -#ifdef VERBOSE -extern OUTVERBOSE(); -#else -#define OUTVERBOSE(s,n1,n2) -#endif -#ifdef DEBUG - -/* Some (all?) Unix debuggers don't particularly like - * static procedures and variables. Therefor we make everything - * global when debugging. - */ - -#define STATIC - -#define assert(x) if(!(x)) badassertion(__FILE__,__LINE__) - -extern VI(); -extern VL(); -extern VD(); -extern VA(); -extern VO(); -extern VP(); - - - -#else /*DEBUG*/ - -#define assert(b) - -#define VI(i) -#define VL(l) -#define VD(d) -#define VA(a) -#define VO(o) -#define VP(p) - - -#define STATIC static -#endif diff --git a/util/ego/share/def.h b/util/ego/share/def.h deleted file mode 100644 index 07db9076d..000000000 --- a/util/ego/share/def.h +++ /dev/null @@ -1,14 +0,0 @@ -/* G L O B A L M A C R O D E F I N I T I O N S - * - * F O R A L L O P T I M I Z E R P A S S E S - */ - -#define MARK_DBLOCK 0 -#define MARK_OBJ 1 -#define MARK_ARG 2 - - -#define op_lab (sp_lmnem+1) -#define op_last op_lab -#define ps_sym (sp_lpseu+1) -#define ps_last ps_sym diff --git a/util/ego/share/files.c b/util/ego/share/files.c deleted file mode 100644 index 062306ede..000000000 --- a/util/ego/share/files.c +++ /dev/null @@ -1,17 +0,0 @@ -/* S H A R E D F I L E - * - * F I L E S . C - */ - -#include - -FILE *openfile(name,mode) - char *name,*mode; -{ - FILE *f; - - if ((f = fopen(name,mode)) == NULL) { - error("cannot open %s",name); - } - return f; -} diff --git a/util/ego/share/files.h b/util/ego/share/files.h deleted file mode 100644 index 494893b9c..000000000 --- a/util/ego/share/files.h +++ /dev/null @@ -1,33 +0,0 @@ -/* F I L E N A M E S */ - -/* The names of the input files of every phase are passed as - * arguments to the phase. First come the input file names, - * then the output file names. We use a one-letter convention - * to denote the type of file: - * p: procedure table file - * d: data table file - * l: EM text file (lines of EM instructions) - * b: basic block file (Control Flow Graph file) - */ - -/* The input file names */ - -#define pname argv[1] -#define dname argv[2] -#define lname argv[3] -#define bname argv[4] - -/* The output file names */ - -#define pname2 argv[5] -#define dname2 argv[6] -#define lname2 argv[7] -#define bname2 argv[8] - -#define ARGSTART 9 - -extern FILE *openfile(); /* (char *name, *mode) - * Open a file with the given name - * and mode; aborts if the file - * cannot be opened. - */ diff --git a/util/ego/share/get.c b/util/ego/share/get.c deleted file mode 100644 index 474e7b31e..000000000 --- a/util/ego/share/get.c +++ /dev/null @@ -1,548 +0,0 @@ -/* S H A R E D F I L E - * - * G E T . C - */ - -#include -#include "types.h" -#include "def.h" -#include "debug.h" -#include "global.h" -#include "lset.h" -#include "cset.h" -#include "get.h" -#include "alloc.h" -#include "map.h" -#include "aux.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_mes.h" - -FILE *curinp; -block_id lastbid; /* block identifying number */ -lab_id lastlabid; /* last label identifier */ - - -/* creating new identifying numbers, i.e. numbers that did not - * appear in the input. - */ - -bblock_p freshblock() -{ - bblock_p b; - b = newbblock(); - b->b_id = ++lastbid; - return b; -} - - -lab_id freshlabel() -{ - curproc->p_nrlabels++; - return ++lastlabid; -} - - -#define getmark() getbyte() - -short getshort() { - register int l_byte, h_byte; - - l_byte = getbyte(); - h_byte = getbyte(); - if ( h_byte>=128 ) h_byte -= 256 ; - return l_byte | (h_byte*256) ; -} - - -offset getoff() { - register long l; - register int h_byte; - - l = getbyte(); - l |= ((unsigned) getbyte())*256 ; - l |= getbyte()*256L*256L ; - h_byte = getbyte() ; - if ( h_byte>=128 ) h_byte -= 256 ; - return l | (h_byte*256L*256*256L) ; -} - -STATIC int getint() -{ - /* Read an integer from the input file. This routine is - * only used when reading a bitvector-set. We expect an - * integer to be either a short or a long. - */ - - if (sizeof(int) == sizeof(short)) { - return getshort(); - } else { - assert (sizeof(int) == sizeof(offset)); - return getoff(); - } -} - -/* getptable */ - -loop_p getloop(id) - loop_id id; -{ - /* Map a loop identifier onto a loop struct. - * If no struct was alocated yet for this identifier then - * allocate one now and update the loop-map table. - */ - - - assert (id > 0 && id <=lplength); - if (lpmap[id] == (loop_p) 0) { - lpmap[id] = newloop(); - lpmap[id]->lp_id = id; - } - return (lpmap[id]); -} - -bblock_p getblock(id) - block_id id; -{ - /* Map a basic block identifier onto a block struct - * If no struct was alocated yet for this identifier then - * allocate one now and update the block-map table. - */ - - - assert (id >= 0 && id <=blength); - if (id == 0) return (bblock_p) 0; - if (bmap[id] == (bblock_p) 0) { - bmap[id] = newbblock(); - bmap[id]->b_id = id; - } - return (bmap[id]); -} - - -lset getlset(p) - char *((*p) ()); -{ - /* Read a 'long' set. Such a set is represented externally - * as a sequence of identifying numbers terminated by a 0. - * The procedural parameter p maps such a number onto a - * pointer to a struct (bblock_p, loop_p etc.). - */ - - lset s; - int id; - - s = Lempty_set(); - while (id = getshort()) { - Ladd( (*p) (id), &s); - } - return s; -} - - -cset getcset() -{ - /* Read a 'compact' set. Such a set is represented externally - * a row of bytes (its bitvector) preceded by its length. - */ - - cset s; - register short i; - - s = Cempty_set(getshort()); - for (i = 0; i <= DIVWL(s->v_size-1);i++) { - s->v_bits[i] = getint(); - } - return s; -} - - -proc_p getptable(pname) - char *pname; -{ - short i; - proc_p head, p, *pp; - short all; - - if ((curinp = fopen(pname,"r")) == NULL) { - error("cannot open %s",pname); - } - - plength = getshort(); /* table is preceded by its length */ - assert(plength >= 0); - assert(plength < 1000); /* See if its a reasonable number */ - pmap = (proc_p *) newmap(plength); /* allocate the pmap table */ - - all = getshort(); - head = (proc_p) 0; - pp = &head; - for (i = 0; i < plength; i++) { - if (feof(curinp)) { - error("unexpected eof %s", pname); - } - p = newproc(); - p->p_id = getshort(); - assert(p->p_id > 0 && p->p_id <= plength); - pmap[p->p_id] = p; - p->p_flags1 = getbyte(); - if (p->p_flags1 & PF_BODYSEEN) { - p->p_nrlabels = getshort(); - p->p_localbytes = getoff(); - p->p_nrformals = getoff(); - if (all) { - p->p_change = newchange(); - p->p_change->c_ext = getcset(); - p->p_change->c_flags = getshort(); - p->p_use = newuse(); - p->p_use->u_flags = getshort(); - p->p_calling = getcset(); - } - } - *pp = p; - pp = &(p->p_next); - } - fclose(curinp); - OUTTRACE("have read proc table of length %d",plength); - return head; /* pointer to first structure of list */ -} - - - -/* getdtable */ - -dblock_p getdtable(dname) - char *dname; -{ - /* Read the data block table. Every data block may - * have a list of objects and a list of values (arguments), - * each of which is also represented by a structure. - * So the input file contains a mixture of dblock, - * obj and arg records, each one having its own - * attributes. A mark indicates which one comes next. - * We assume that the syntactic structure of the input - * is correct. - */ - - dblock_p head, d, *dp; - obj_p obj, *op; - arg_p arg, *ap; - /* dp, op an ap tell how the next dblock/obj/arg - * has to be linked. - */ - int n; - - head = (dblock_p) 0; - dp = &head; - if ((curinp = fopen(dname,"r")) == NULL) { - error("cannot open %s", dname); - } - olength = getshort(); - assert(olength >= 0); - assert(olength < 5000); /* See if its a reasonable number */ - /* total number of objects */ - omap = (obj_p *) newmap(olength); /* allocate omap table */ - - while (TRUE) { - n = getmark(); - if (feof(curinp)) break; - switch(n) { - case MARK_DBLOCK: - d = *dp = newdblock(); - op = &d->d_objlist; - ap = &d->d_values; - dp = &d->d_next; - d->d_id = getshort(); - d->d_pseudo = getbyte(); - d->d_size = getoff(); - d->d_fragmnr = getshort(); - d->d_flags1 = getbyte(); - break; - case MARK_OBJ: - obj = *op = newobject(); - op = &obj->o_next; - obj->o_dblock = d; - obj->o_id = getshort(); - assert(obj->o_id >0); - assert(obj->o_id <= olength); - omap[obj->o_id] = obj; - obj->o_size = getoff(); - obj->o_off = getoff(); - break; - case MARK_ARG: - arg = *ap = newarg(ARGOFF); - ap = &arg->a_next; - arg->a_a.a_offset = getoff(); - break; - default: - assert(FALSE); - } - } - OUTTRACE("have read data table, %d objects",olength); - return head; -} - - - -/* getbblocks */ - -STATIC argstring(length,abp) - short length; - register argb_p abp; -{ - - while (length--) { - if (abp->ab_index == NARGBYTES) - abp = abp->ab_next = newargb(); - abp->ab_contents[abp->ab_index++] = getbyte(); - } -} - - - -STATIC arg_p readargs() -{ - /* Read a list of arguments and allocate structures - * for them. Return a pointer to the head of the list. - */ - - arg_p head, arg, *ap; - byte t; - short length; - - ap = &head; - for (;;) { - /* every argument list is terminated by an - * ARGCEND byte in Intermediate Code. - */ - t = getbyte(); - if (t == (byte) ARGCEND) { - return head; - } - arg = *ap = newarg(t); - ap = &arg->a_next; - switch((short) t) { - case ARGOFF: - arg->a_a.a_offset = getoff(); - break; - case ARGINSTRLAB: - arg->a_a.a_instrlab = getshort(); - break; - case ARGOBJECT: - arg->a_a.a_obj = omap[getshort()]; - /* Read an object identifier (o_id) - * and use the omap table to obtain - * a pointer to the rigth obj struct. - */ - break; - case ARGPROC: - arg->a_a.a_proc = pmap[getshort()]; - /* Read a procedure identifier (p_id) */ - break; - case ARGSTRING: - length = getshort(); - argstring(length, &arg->a_a.a_string); - break; - case ARGICN: - case ARGUCN: - case ARGFCN: - length = getshort(); - arg->a_a.a_con.ac_length = length; - /* size of the constant */ - argstring(getshort(), - &arg->a_a.a_con.ac_con); - break; - default: - assert(FALSE); - } - } -} - - -line_p read_line(p_out) - proc_p *p_out; -{ - /* Read a line of EM code (i.e. one instruction) - * and its arguments (if any). - * In Intermediate Code, the first byte is the - * instruction code and the second byte denotes the kind - * of operand(s) that follow. - */ - - line_p lnp; - byte instr; - - instr = getbyte(); - if (feof(curinp)) return (line_p) 0; - lnp = newline(getbyte()); - linecount++; - lnp->l_instr = instr; - switch(TYPE(lnp)) { - /* read the operand(s) */ - case OPSHORT: - SHORT(lnp) = getshort(); - break; - case OPOFFSET: - OFFSET(lnp) = getoff(); - break; - case OPINSTRLAB: - INSTRLAB(lnp) = getshort(); - if (instr == op_lab) { - /* defining occurrence of an - * instruction label. - */ - lmap[INSTRLAB(lnp)] = lnp; - } - break; - case OPOBJECT: - OBJ(lnp) = omap[getshort()]; - break; - case OPPROC: - PROC(lnp) = pmap[getshort()]; - if ((instr & BMASK) == ps_pro) { - /* enter new procedure: allocate a - * label map and a label-block map table. - */ - *p_out = PROC(lnp); - llength = (*p_out)->p_nrlabels; - lmap = (line_p *) newmap(llength); - /* maps lab_id to line structure */ - lbmap = (bblock_p *) newmap(llength); - /* maps lab_id to bblock structure */ - lastlabid = llength; - } - break; - case OPLIST: - ARG(lnp) = readargs(); - break; - default: - assert(TYPE(lnp) == OPNO); - } - return lnp; -} - - -STATIC message(lnp) - line_p lnp; -{ - /* See if lnp is some useful message. - * (e.g. a message telling that a certain local variable - * will never be referenced indirectly, so it may be put - * in a register. If so, add it to the mesregs set.) - */ - - assert(ARG(lnp)->a_type == ARGOFF); - switch((int) aoff(ARG(lnp),0)) { - case ms_reg: - if (ARG(lnp)->a_next != (arg_p) 0) { - /* take only "mes 3" with further arguments */ - Ladd(lnp,&mesregs); - } - break; - case ms_err: - error("ms_err encountered"); - case ms_opt: - error("ms_opt encountered"); - case ms_emx: - ws = aoff(ARG(lnp),1); - ps = aoff(ARG(lnp),2); - break; - } -} - - - -line_p getlines(lf,n,p_out,collect_mes) - FILE *lf; - int n; - proc_p *p_out; - bool collect_mes; -{ - /* Read n lines of EM text and doubly link them. - * Also process messages. - */ - - line_p head, *pp, l, lprev; - - curinp = lf; /* EM input file */ - pp = &head; - lprev = (line_p) 0; - while (n--) { - l = *pp = read_line(p_out); - PREV(l) = lprev; - pp = &l->l_next; - lprev = l; - if (collect_mes && INSTR(l) == ps_mes) { - message(l); - } - } - *pp = (line_p) 0; - return head; -} - - - -bool getunit(gf,lf,kind_out,g_out,l_out,p_out,collect_mes) - FILE *gf,*lf; - short *kind_out; - bblock_p *g_out; - line_p *l_out; - proc_p *p_out; - bool collect_mes; -{ - /* Read control flow graph (gf) and EM text (lf) of the next procedure. - * A pointer to the proctable entry of the read procedure is - * returned via p_out. - * This routine also constructs the bmap and lpmap tables. - * Note that we allocate structs for basic blocks and loops - * at their first reference rather than at when we read them. - */ - - int n,i; - bblock_p head, *pp, b; - loop_p lp; - - curinp = gf; - blength = getshort(); /* # basic blocks in this procedure */ - if (feof(curinp)) return FALSE; - if (blength == 0) { - /* data unit */ - *kind_out = LDATA; - n = getshort(); - *l_out = getlines(lf,n,p_out,collect_mes); - return TRUE; - } - *kind_out = LTEXT; - bmap = (bblock_p *) newmap(blength); /* maps block_id on bblock_p */ - lplength = getshort(); /* # loops in this procedure */ - lpmap = (loop_p *) newmap(lplength); /* maps loop_id on loop_p */ - - /* Read the basic blocks and the EM text */ - pp = &head; /* we use a pointer-to-a-pointer to link the structs */ - for (i = 0; i < blength; i++) { - b = getblock(getshort()); - n = getshort(); /* #instructions in the block */ - b->b_succ = getlset(getblock); - b->b_pred = getlset(getblock); - b->b_idom = getblock(getshort()); - b->b_loops = getlset(getloop); - b->b_flags = getshort(); - b->b_start = getlines(lf,n,p_out,collect_mes); /* read EM text */ - *pp = b; - pp = &b->b_next; - curinp = gf; - } - lastbid = blength; /* last block_id */ - - /* read the information about loops */ - curproc->p_loops = Lempty_set(); - for (i = 0; i < lplength; i++) { - lp = getloop(getshort()); - lp->lp_level = getshort(); /* nesting level */ - lp->lp_entry = getblock(getshort()); /* entry block of the loop */ - lp->lp_end = getblock(getshort()); /* tail of back edge of loop */ - Ladd(lp,&curproc->p_loops); - } - *g_out = head; - return TRUE; -} diff --git a/util/ego/share/get.h b/util/ego/share/get.h deleted file mode 100644 index 0268a7297..000000000 --- a/util/ego/share/get.h +++ /dev/null @@ -1,53 +0,0 @@ -/* I N P U T R O U T I N E S */ - -extern FILE *curinp; /* current input file */ -extern block_id lastbid; /* block identifying number */ -extern lab_id lastlabid; /* last label identifier */ - -#define getbyte() getc(curinp) -extern short getshort(); /* () - * Read a short from curinp - */ -extern offset getoff(); /* () - * Read an offset from curinp - */ -extern line_p read_line(); /* ( proc_p *p_out) - * Read a line of EM code (i.e. one - * instruction) and its arguments - * (if any). If the instruction is a - * 'pro' pseudo, set p_out. - */ - -extern line_p getlines(); /* ( FILE *lf; int n; proc_p *p_out; - * bool collect_mes) - * Read n lines of EM text and doubly - * link them. Also process messages - * if required. - */ - -extern bblock_p freshblock(); /* () - * Allocate a bblock struct and assign - * it a brand new block_id. - */ -extern lab_id freshlabel(); /* () - * Get a brand new lab_id. - */ -extern dblock_p getdtable(); /* (char *dname) - * Read the data block table from - * the file with the given name. - */ -extern proc_p getptable(); /* (char *pname) - * Read the proc table from - * the file with the given name. - */ -extern bool getunit(); /* (FILE *gf,*lf; short kind_out; - * bblock_p g_out; line_p l_out; - * proc_p *p_out; bool collect_mes) - * Read the control flow graph - * (from file gf) and the EM text - * (from lf). If collect_mes is TRUE, - * all register messages will be - * collected and put in the global - * variable 'mesregs'. The proc read - * is returned in p_out. - */ diff --git a/util/ego/share/global.c b/util/ego/share/global.c deleted file mode 100644 index 37d8a00ff..000000000 --- a/util/ego/share/global.c +++ /dev/null @@ -1,21 +0,0 @@ -/* S H A R E D F I L E - * - * G L O B A L . C - */ - -#include "types.h" - -int ps = 0; -int ws = 0; - -proc_p curproc; /* current procedure */ - -char *filename; /* name of current input file */ - -lset mesregs; /* set of MES ms_reg pseudos */ - -short time_space_ratio = 50; - /* 0 if optimizing for space only, - * 100 if optimizing for time only, - * else something 'in between'. - */ diff --git a/util/ego/share/global.h b/util/ego/share/global.h deleted file mode 100644 index b8eb30f53..000000000 --- a/util/ego/share/global.h +++ /dev/null @@ -1,51 +0,0 @@ -/* G L O B A L V A R I A B L E S */ - -/* sizes of TARGET machine */ - -extern int ps; /* pointer size */ -extern int ws; /* word size */ - -/* sizes of SOURCE machine (i.e. machine on which - * the optimizer runs) - */ - -/* number of bits in a byte */ -#define BYTELENGTH 8 - -/* number of bits in a word, defined in automatically generated file */ -#include "../share/wordlen.h" - -#if BYTELENGTH==8 -#define DIVBL(a) ((a) >> 3) -#define MODBL(a) ((a) & 07) -#else -#define DIVBL(a) (a/BYTELENGTH) -#define MODBL(a) (a%BYTELENGTH) -#endif - -#if WORDLENGTH==16 -#define DIVWL(a) ((a) >> 4) -#define MODWL(a) ((a) & 017) -#else -#if WORDLENGTH==32 -#define DIVWL(a) ((a) >> 5) -#define MODWL(a) ((a) & 037) -#else -#define DIVWL(a) (a/WORDLENGTH) -#define MODWL(a) (a%WORDLENGTH) -#endif -#endif - - -#define UNKNOWN_SIZE (-1) - -extern proc_p curproc; /* current procedure */ - -extern char *filename; /* name of current input file */ - -extern lset mesregs; /* set of MES ms_reg pseudos */ - -extern short time_space_ratio; /* 0 if optimizing for space only, - * 100 if optimizing for time only, - * else something 'in between'. - */ diff --git a/util/ego/share/go.c b/util/ego/share/go.c deleted file mode 100644 index 5a5973581..000000000 --- a/util/ego/share/go.c +++ /dev/null @@ -1,152 +0,0 @@ -/* S H A R E D F I L E - * - * G O . C - * - */ - - -#include -#include "types.h" -#include "debug.h" -#include "global.h" -#include "files.h" -#include "get.h" -#include "put.h" -#include "lset.h" -#include "map.h" -#include "alloc.h" -#include "go.h" - - -STATIC bool report_flag = FALSE; /* report #optimizations found? */ -STATIC bool core_flag = FALSE; /* report core usage? */ - - -STATIC mach_init(machfile,phase_machinit) - char *machfile; - int (*phase_machinit)(); -{ - /* Read target machine dependent information */ - - FILE *f; - - f = openfile(machfile,"r"); - fscanf(f,"%d",&ws); - fscanf(f,"%d",&ps); - if (ws != ps && ps != 2*ws) error("illegal pointer size"); - phase_machinit(f); - fclose(f); -} - - - -go(argc,argv,initialize,optimize,phase_machinit,proc_flag) - int argc; - char *argv[]; - int (*initialize)(); - int (*optimize)(); - int (*phase_machinit)(); - int (*proc_flag)(); -{ - FILE *f, *gf, *f2, *gf2; /* The EM input and output and - * the basic block graphs input and output - */ - bblock_p g; - line_p l; - short kind; - int i; - char *p; - bool time_opt = FALSE; - - linecount = 0; - for (i = ARGSTART; i < argc; i++) { - p = argv[i]; - if (*p++ != '-') error("illegal argument"); - switch(*p) { - case 'S': - time_opt = FALSE; - break; - case 'T': - time_opt = TRUE; - break; - case 'M': - p++; - mach_init(p,phase_machinit); - break; - case 'C': - core_flag = TRUE; - break; - case 'Q': - report_flag = TRUE; - break; - case 'V': - verbose_flag = TRUE; - break; - default: - proc_flag(p); - break; - } - } - time_space_ratio = (time_opt ? 100 : 0); - fproc = getptable(pname); /* proc table */ - fdblock = getdtable(dname); /* data block table */ - initialize(); - if (optimize == no_action) return; - f = openfile(lname,"r"); - gf = openfile(bname,"r"); - f2 = openfile(lname2,"w"); - gf2 = openfile(bname2,"w"); - mesregs = Lempty_set(); - while (getunit(gf,f,&kind,&g,&l,&curproc,TRUE)) { - /* Read the control flow graph and EM text of - * one procedure and optimize it. - */ - if (kind == LDATA) { - putunit(LDATA, (proc_p) 0, l, gf2, f2); - continue; - } - OUTTRACE("flow graph of proc %d read",curproc->p_id); - curproc->p_start = g; - /* The global variable curproc points to the - * current procedure. It is set by getgraph - */ - optimize(curproc); - putunit(LTEXT,curproc,(line_p) 0,gf2,f2); - /* output control flow graph + text */ - OUTTRACE("graph of proc %d outputted",curproc->p_id); - Ldeleteset(mesregs); - mesregs = Lempty_set(); - } - fclose(f); - fclose(f2); - fclose(gf); - fclose(gf2); - f = openfile(dname2,"w"); - putdtable(fdblock,f); - fclose(f); - f = openfile(pname2,"w"); - putptable(fproc,f,TRUE); - fclose(f); - core_usage(); -} - - -no_action() { } - -core_usage() -{ - if (core_flag) { - coreusage(); - } -} - -report(s,n) - char *s; - int n; -{ - /* Report number of optimizations found, if report_flag is set */ - - if (report_flag) { - fprintf(stderr,"%s: %d\n",s,n); - } -} diff --git a/util/ego/share/go.h b/util/ego/share/go.h deleted file mode 100644 index 3c3bff1aa..000000000 --- a/util/ego/share/go.h +++ /dev/null @@ -1,34 +0,0 @@ -/* S H A R E D F I L E - * - * G O . H - * - */ - - -extern go(); /* ( int argc; char *argv[]; - * int (*initialize)(); int (*optimize)(); - * int (*phase_machinit)(); int (*proc_flag)() ) - * This is the main driving routine of the optimizer. - * It first processes the flags given as argument; - * for every flag it does not recognize itself, it - * calls 'proc_flag'; as soon as the -M flag is seen, - * it opens the machine descriptor file and - * reads phase-independend information (notably the - * wordsize and pointersize of the target machine); - * next it calls 'phase_machinit' with this file as - * parameter. Subsequently it calls 'initialize'. - * Finally, all procedures are read, one at a time, - * and 'optimize' is called with the current procedure - * as parameter. - */ -extern no_action(); /* () - * Parameter to be supplied for e.g. 'initialize' if - * no action is required. - */ -extern core_usage(); /* () - * Report core usage, if core_flag is set. - */ -extern report(); /* ( char *s; int n) - * Report number of optimizations found, if - * report_flag is set - */ diff --git a/util/ego/share/init_glob.c b/util/ego/share/init_glob.c deleted file mode 100644 index 088d679b1..000000000 --- a/util/ego/share/init_glob.c +++ /dev/null @@ -1,57 +0,0 @@ - -/* S H A R E D F I L E - * - * I N I T _ G L O B L S - * - */ - -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/alloc.h" -#include "../share/map.h" - - -extern short nrglobals; - -init_globals() -{ - /* Assign a 'global variable number (o_globnr) to - * every global variable for which we want to - * maintain ud-info. We do not maintain ud-info - * for a global variable if: - * - it is part of a ROM data block (so it will never be changed) - * - it's size is not known - * - it overlaps another variable (e.g. LOE X+2 ; LDE X) - */ - - dblock_p d; - obj_p obj, prev; - short nr = 1; - offset ill_zone, x; - - for (d = fdblock; d != (dblock_p) 0; d = d->d_next) { - ill_zone = (offset) 0; - for (obj = d->d_objlist; obj != (obj_p) 0; obj = obj->o_next) { - if (d->d_pseudo == DROM || - obj->o_size == UNKNOWN_SIZE) { - obj->o_globnr = 0; /* var. not considered */ - continue; - } - if (obj->o_off < ill_zone) { - obj->o_globnr = 0; /* var. not considered */ - if (prev != (obj_p) 0 && prev->o_globnr != 0) { - prev->o_globnr = 0; - nr--; - } - } else { - obj->o_globnr = nr++; - } - if ((x = obj->o_off + obj->o_size) > ill_zone) { - ill_zone = x; - } - prev = obj; - } - } - nrglobals = nr -1; -} diff --git a/util/ego/share/init_glob.h b/util/ego/share/init_glob.h deleted file mode 100644 index 984b847d9..000000000 --- a/util/ego/share/init_glob.h +++ /dev/null @@ -1,10 +0,0 @@ - -/* S H A R E D - * - * I N I T _ G L O B L S - * - */ - -extern init_globals(); /* Assign a 'global variable number (o_globnr) - * to every global variable. - */ diff --git a/util/ego/share/locals.c b/util/ego/share/locals.c deleted file mode 100644 index 64e3f4ca0..000000000 --- a/util/ego/share/locals.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * L O C A L S . C - */ - -#include -#include "types.h" -#include "debug.h" -#include "global.h" -#include "lset.h" -#include "cset.h" -#include "def.h" -#include "get.h" -#include "aux.h" -#include "alloc.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_mes.h" -#include "locals.h" - - -extern short nrglobals; - -short nrlocals; -local_p *locals; /* dynamic array */ - -STATIC localvar(off,size,locs,reg,score) - offset off; - short size; - local_p *locs; - bool reg; - offset score; -{ - /* process a reference to a local variable. - * A local is characterized by a (offset,size) pair. - * We first collect all locals in a list, sorted - * by offset. Later we will construct a table - * out of this list. - */ - - local_p lc, x, *prevp; - - prevp = locs; - for (lc = *locs; lc != (local_p) 0; lc = lc->lc_next) { - if (lc->lc_off == off && lc->lc_size == size) { - if (reg) { - REGVAR(lc); /* register variable */ - lc->lc_score = score; - } - return; /* local already present */ - } - if (lc->lc_off > off) break; - prevp = &lc->lc_next; - } - /* the local was not seen before; create an entry - * for it in the list. - */ - x = *prevp = newlocal(); - x->lc_off = off; - x->lc_size = size; - x->lc_next = lc; - if (reg) { - REGVAR(x); - x->lc_score = score; - } -} - - - -STATIC check_message(l,locs) - line_p l; - local_p *locs; -{ - /* See if l is a register message */ - - arg_p arg; - - arg = ARG(l); - if (aoff(arg,0) == ms_reg && arg->a_next != (arg_p) 0) { - localvar(aoff(arg,1), (short) aoff(arg,2), locs, TRUE, - aoff(arg,4)); - } -} - - - - -STATIC check_local_use(l,locs) - line_p l; - local_p *locs; -{ - short sz; - - switch(INSTR(l)) { - case op_lol: - case op_stl: - case op_inl: - case op_del: - case op_zrl: - sz = ws; - break; - case op_ldl: - case op_sdl: - sz = 2 * ws; - break; - case op_lil: - case op_sil: - sz = ps; - break; - case ps_mes: - check_message(l,locs); - /* fall through .. */ - default: - return; - } - localvar(off_set(l),sz,locs,FALSE,(offset) 0); -} - - -make_localtab(p) - proc_p p; -{ - /* Make a table of local variables. - * This table is used to associate a - * unique number with a local. If two - * locals overlap (e.g. LDL 4 and LDL 2) - * none of them is considered any further, - * i.e. we don't compute ud-info for them. - */ - - local_p prev, next, lc; - local_p locallist = (local_p) 0; - short cnt = 0; - offset x, ill_zone = 0; - register bblock_p b; - register line_p l; - - /* first make a list of all locals used */ - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - check_local_use(l,&locallist); - } - } - /* Now remove overlapping locals, count useful ones on the fly */ - for (lc = locallist; lc != (local_p) 0; lc = lc->lc_next) { - if (ill_zone != 0 && lc->lc_off < ill_zone) { - /* this local overlaps with a previous one */ - BADLC(lc); - if (!IS_BADLC(prev)) { - BADLC(prev); - cnt--; - } - } else { - cnt++; - } - x = lc->lc_off + lc->lc_size; - if (ill_zone == 0 || x > ill_zone) { - ill_zone = x; - } - prev = lc; - } - /* Now we know how many local variables there are */ - nrlocals = cnt; - locals = (local_p *) newmap(cnt); - cnt = 1; - for (lc = locallist; lc != (local_p) 0; lc = next) { - next = lc->lc_next; - if (IS_BADLC(lc)) { - oldlocal(lc); - } else { - locals[cnt++] = lc; - lc->lc_next = (local_p) 0; - } - } - assert (cnt == nrlocals+1); -} - - - -STATIC find_local(off,nr_out,found_out) - offset off; - short *nr_out; - bool *found_out; -{ - /* Try to find the local variable at the given - * offset. Return its local-number. - */ - - short v; - - for (v = 1; v <= nrlocals; v++) { - if (locals[v]->lc_off > off) break; - if (locals[v]->lc_off == off) { - *found_out = TRUE; - *nr_out = v; - return; - } - } - *found_out = FALSE; -} - - - - -var_nr(l,nr_out,found_out) - line_p l; - short *nr_out; - bool *found_out; -{ - /* Determine the number of the variable referenced - * by EM instruction l. - */ - - offset off; - short nr; - - switch(TYPE(l)) { - case OPOBJECT: - /* global variable */ - if (OBJ(l)->o_globnr == 0) { - /* We don't maintain ud-info for this var */ - *found_out = FALSE; - } else { - *nr_out = GLOB_TO_VARNR(OBJ(l)->o_globnr); - *found_out = TRUE; - } - return; - case OPSHORT: - off = (offset) SHORT(l); - break; - case OPOFFSET: - off = OFFSET(l); - break; - default: - assert(FALSE); - } - /* Its's a local variable */ - find_local(off,&nr,found_out); - if (*found_out) { - *nr_out = LOC_TO_VARNR(nr); - } -} diff --git a/util/ego/share/locals.h b/util/ego/share/locals.h deleted file mode 100644 index 3b101fda5..000000000 --- a/util/ego/share/locals.h +++ /dev/null @@ -1,39 +0,0 @@ - -/* - * L O C A L S . H - */ - -extern local_p *locals; /* table of locals, index is local-number */ -extern short nrlocals; /* number of locals for which we keep ud-info */ - -extern make_localtab(); /* (proc_p p) - * Analyse the text of procedure p to determine - * which local variable p has. Make a table of - * these variables ('locals') and count them - * ('nrlocals'). Also collect register messages. - */ -extern var_nr(); /* (line_p l; short *nr_out;bool *found_out) - * Compute the 'variable number' of the - * variable referenced by EM instruction l. - */ - -/* Every global variable for which ud-info is maintained has - * a 'global variable number' (o_globnr). Every useful local - * has a 'local variable number', which is its index in the - * 'locals' table. All these variables also have a - * 'variable number'. Conversions exist between these numbers. - */ - -#define TO_GLOBAL(v) (v) -#define TO_LOCAL(v) (v - nrglobals) -#define GLOB_TO_VARNR(v) (v) -#define LOC_TO_VARNR(v) (v + nrglobals) -#define IS_GLOBAL(v) (v <= nrglobals) -#define IS_LOCAL(v) (v > nrglobals) - -#define REGVAR(lc) lc->lc_flags |= LCF_REG -#define IS_REGVAR(lc) (lc->lc_flags & LCF_REG) -#define BADLC(lc) lc->lc_flags |= LCF_BAD -#define IS_BADLC(lc) (lc->lc_flags & LCF_BAD) - - diff --git a/util/ego/share/lset.c b/util/ego/share/lset.c deleted file mode 100644 index 85348dca3..000000000 --- a/util/ego/share/lset.c +++ /dev/null @@ -1,208 +0,0 @@ -/* L O N G S E T S - * - * L S E T . C - */ - - -#include "types.h" -#include "lset.h" -#include "alloc.h" -#include "debug.h" - - -/* A 'long' set is represented as a linear list of 'elemholder' - * records. Every such record contains a pointer to an element - * of the set and to the next elemholder. An empty set is - * represented as a null pointer. - * An element of a long set must be of some pointer type or, - * in any case, must have the size of a pointer. Note that - * the strict typing rules are not obeyed here. - * This package implements the usual operations on sets. - * The name of every operation is preceeded by a 'L' to - * distinguish it from the operation on 'compact' (bitvector) - * sets with a similar name. - */ - - -lset Lempty_set() -{ - return ((lset) 0); -} - - -bool Lis_elem(x,s) - register Lelem_t x; - register lset s; -{ - - /* Search the list to see if x is an element of s */ - while (s != (elem_p) 0) { - if (s->e_elem == x) { - return TRUE; - } - s = s->e_next; - } - return FALSE; -} - - -Ladd(x,s_p) - Lelem_t x; - lset *s_p; -{ - /* add x to a set. Note that the set is given as in-out - * parameter, because it may be changed. - */ - - elem_p t; - - if (!Lis_elem(x,*s_p)) { - t = newelem(); /* allocate a new elemholder */ - t->e_elem = x; - t->e_next = *s_p; /* insert it at the head of the list */ - *s_p = t; - } -} - - -Lremove(x,s_p) - Lelem_t x; - lset *s_p; -{ - /* Remove x from a set. If x was not an element of - * the set, nothing happens. - */ - - register elem_p *epp, ep; - lset s; - - s = *s_p; - epp = &s; - while ((ep = *epp) != (elem_p) 0) { - if (ep->e_elem == x) { - *epp = ep->e_next; - oldelem(ep); - break; - } else { - epp = &ep->e_next; - } - } - *s_p = s; -} - - -/* The operations first, next and elem can be used to iterate - * over a set. For example: - * for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i,s) { - * x = Lelem(i); - * use x - * } - * which is like: - * 'for all elements x of s do' - * use x - */ - - -Lindex Lfirst(s) - lset s; -{ - return ((Lindex) s); - /* Note that an index for long sets is just - * a pointer to an elemholder. - */ -} - - -Lindex Lnext(i,s) - Lindex i; - lset s; -{ - assert(i != (Lindex) 0); - return (i->e_next); -} - - -Lelem_t Lelem(i) - Lindex i; -{ - return (i->e_elem); -} - - - -Ljoin(s1,s2_p) - lset s1,*s2_p; -{ - /* Join two sets, assign the result to the second set - * and delete the first set (i.e. the value of the - * first set becomes undefined). - */ - - register elem_p *epp, ep; - lset s2; - - /* First all elements of s1 that are also an element of s2 - * are removed from the s1 list. The two resulting lists - * (for s1 and s2) are linked (s1 first). - * Note the usage of epp, which points to a pointer that - * points to the next elemholder record of the list. - */ - - s2 = *s2_p; - epp = &s1; - while ((ep = *epp) != (elem_p) 0) { - if (Lis_elem(ep->e_elem,s2)) { - /* remove an element */ - *epp = ep->e_next; - oldelem(ep); - } else { - epp = &ep->e_next; - } - } - *epp = s2; /* last record of s1 (or s1 itself) now points - * to first record of s2. - */ - *s2_p = s1; -} - - -Ldeleteset(s) - lset s; -{ - register elem_p ep, next; - - for (ep = s; ep != (elem_p) 0; ep = next) { - next = ep->e_next; - oldelem(ep); - } -} - - -bool Lis_subset(s1,s2) - lset s1,s2; -{ - /* See if s1 is a subset of s2 */ - - register Lindex i; - - for (i = Lfirst(s1); i != (Lindex) 0; i = Lnext(i,s1)) { - if (!Lis_elem(Lelem(i),s2)) return FALSE; - } - return TRUE; -} - - -short Lnrelems(s) - lset s; -{ - /* Compute the number of elements of a set */ - - register elem_p ep; - register short cnt; - - cnt = 0; - for (ep = s; ep != (elem_p) 0; ep = ep->e_next) { - cnt++; - } - return cnt; -} diff --git a/util/ego/share/lset.h b/util/ego/share/lset.h deleted file mode 100644 index 826b89444..000000000 --- a/util/ego/share/lset.h +++ /dev/null @@ -1,16 +0,0 @@ -/* O P E R A T I O N S F O R - * L O N G S E T S - */ - - -extern lset Lempty_set(); /* () */ -extern bool Lis_elem(); /* (Lelem_t, lset) */ -extern Ladd(); /* (Lelem_t, *lset) */ -extern Lremove(); /* (Lelem_t, *lset) */ -extern Lindex Lfirst(); /* (lset) */ -extern Lindex Lnext(); /* (Lindex, lset) */ -extern Lelem_t Lelem(); /* (Lindex) */ -extern Ljoin(); /* (lset, *lset) */ -extern Ldeleteset(); /* (lset) */ -extern bool Lis_subset(); /* (lset, lset) */ -extern short Lnrelems(); /* (lset) */ diff --git a/util/ego/share/makecldef.c b/util/ego/share/makecldef.c deleted file mode 100644 index f656b09be..000000000 --- a/util/ego/share/makecldef.c +++ /dev/null @@ -1,83 +0,0 @@ -#include - -/* MAKECLASSDEF - * - * This program is used by several phases of the optimizer - * to make the file classdefs.h. It reads two files: - * - the em_mnem,h file, containing the definitions of the - * EM mnemonics - * - the class-file, containing tuples: - * (mnemonic, src_class, res_class) - * where src_class and res_class are integers telling how - * to compute the number of bytes popped and pushed - * by the instruction. - * The output (standard output) is a C array. - */ - - -#define TRUE 1 -#define FALSE 0 - -convert(mnemfile,classfile) - FILE *mnemfile, *classfile; -{ - char mnem1[10], mnem2[10],def[10]; - int src,res,newcl,opc; - - newcl = TRUE; - printf("struct class classtab[] = {\n"); - printf("\tNOCLASS,\tNOCLASS,\n"); - /* EM mnemonics start at 1, arrays in C at 0 */ - for (;;) { - fscanf(mnemfile,"%s%s%d",def,mnem1,&opc); - /* read a line like "#define op_aar 1" */ - if (feof(mnemfile)) break; - if (strcmp(def,"#define") != 0) { - error("bad mnemonic file, #define expected"); - } - if (newcl) { - fscanf(classfile,"%s%d%d",mnem2,&src,&res); - /* read a line like "op_loc 8 1" */ - } - if (feof(classfile) || strcmp(mnem1,mnem2) != 0) { - /* there is no line for this mnemonic, so - * it has no class. - */ - printf("\tNOCLASS,\tNOCLASS,\n"); - newcl = FALSE; - } else { - printf("\tCLASS%d,\t\tCLASS%d,\n",src,res); - /* print a line like "CLASS8, CLASS1," */ - newcl = TRUE; - } - } - printf("};\n"); -} - - - -error(s) - char *s; -{ - fprintf(stderr,"%s\n",s); - exit(-1); -} - - -main(argc,argv) - int argc; - char *argv[]; -{ - FILE *f1,*f2; - - if (argc != 3) { - error("usage: makeclassdef mnemfile classfile"); - } - if ((f1 = fopen(argv[1],"r")) == NULL) { - error("cannot open mnemonic file"); - } - if ((f2 = fopen(argv[2],"r")) == NULL) { - error("cannot open class file"); - } - convert(f1,f2); -} diff --git a/util/ego/share/makedepend b/util/ego/share/makedepend deleted file mode 100755 index 733f55b6f..000000000 --- a/util/ego/share/makedepend +++ /dev/null @@ -1,11 +0,0 @@ -for file in *.c -do ofile=`basename $file .c`.o - grep '^# *include.*"' $file|sed "s/.*\"\(.*\)\".*/$ofile: \1/" -done | sort -u >depend -ed - Makefile <<'!' -/AUTOAUTOAUTO/+,$d -$r depend -w -q -! -rm depend diff --git a/util/ego/share/makewlen.c b/util/ego/share/makewlen.c deleted file mode 100644 index a26dc8908..000000000 --- a/util/ego/share/makewlen.c +++ /dev/null @@ -1,4 +0,0 @@ -main() -{ - printf("#define WORDLENGTH %d\n",sizeof(int) * 8); -} diff --git a/util/ego/share/map.c b/util/ego/share/map.c deleted file mode 100644 index 654588265..000000000 --- a/util/ego/share/map.c +++ /dev/null @@ -1,21 +0,0 @@ -/* M A P . C */ - -#include "types.h" -#include "map.h" - -short plength; -short olength; -short llength; -short blength; -short lplength; -line_p *lmap; -bblock_p *lbmap; -proc_p *pmap ; /* dynamically allocated array that maps - * every proc_id to a proc_p. - */ -obj_p *omap; /* maps obj_id to obj_p */ -loop_p *lpmap; /* maps loop_id to loop_p */ -bblock_p *bmap; /* maps block_id to bblock_p */ - -dblock_p fdblock; /* first dblock */ -proc_p fproc; /* first proc */ diff --git a/util/ego/share/map.h b/util/ego/share/map.h deleted file mode 100644 index 9c3a4655a..000000000 --- a/util/ego/share/map.h +++ /dev/null @@ -1,38 +0,0 @@ -/* M A P . H */ - -extern short plength; /* length of pmap, i.e. number of procs */ -extern short olength; /* length of omap, i.e. number of objects */ -extern short llength; /* length of lmap and lbmap, i.e. - * # instruction labels in current proc. - */ -extern short lplength; /* length of lpmap, i.e. number of loops - * in current procedure. - */ -extern short blength; /* length of bmap, i.e. number of basic blocks - * in current procedure. - */ - - -extern line_p *lmap; /* contains for every label_id its - * defining occurrence (line structure) - * label_id --> line_p - */ -extern bblock_p *lbmap; /* contains for every label_id its - * basic block. - * label_id --> bblock_p - */ -extern proc_p *pmap; /* contains for every proc_id its proc structure - * proc_id --> proc_p - */ -extern obj_p *omap; /* contains for every obj_id its object struct - * obj_id --> obj_p - */ -extern loop_p *lpmap; /* contains for every loop_id its loop struct - * loop_id --> loop_p - */ -extern bblock_p *bmap; /* contains for every block_id its bblock struct - * block_id --> bblock_p - */ - -extern dblock_p fdblock;/* first dblock, heads dblock list */ -extern proc_p fproc; /* first proc, heads proc table */ diff --git a/util/ego/share/parser.c b/util/ego/share/parser.c deleted file mode 100644 index 86624752d..000000000 --- a/util/ego/share/parser.c +++ /dev/null @@ -1,282 +0,0 @@ - -#include -#include "types.h" -#include "debug.h" -#include "alloc.h" -#include "global.h" -#include "lset.h" -#include "aux.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_mnem.h" - -struct class { - byte src_class; - byte res_class; -}; - -typedef struct class *class_p; - - -#define NOCLASS 0 -#define CLASS1 1 -#define CLASS2 2 -#define CLASS3 3 -#define CLASS4 4 -#define CLASS5 5 -#define CLASS6 6 -#define CLASS7 7 -#define CLASS8 8 -#define CLASS9 9 -#define CLASS10 10 -#define CLASS11 11 -#define CLASS12 12 - -#include "classdefs.h" -/* The file classdefs.h contains the table classtab. It is - * generated automatically from the file classdefs.src. - */ - -STATIC bool classes(instr,src_out,res_out) - int instr; - int *src_out, *res_out; -{ - /* Determine the classes of the given instruction */ - - class_p c; - - if (instr < sp_fmnem || instr > sp_lmnem) return FALSE; - c = &classtab[instr]; - if (c->src_class == NOCLASS) return FALSE; - *src_out = c->src_class; - *res_out = c->res_class; - return TRUE; -} - - - -STATIC bool uses_arg(class) - int class; -{ - /* See if a member of the given class uses - * an argument. - */ - - switch(class) { - case CLASS1: - case CLASS2: - case CLASS3: - case CLASS4: - case CLASS11: - case CLASS12: - return TRUE; - default: - return FALSE; - } - /* NOTREACHED */ -} - - - -STATIC bool uses_2args(class) - int class; -{ - /* See if a member of the given class uses - * 2 arguments. - */ - - return class == CLASS10; -} - - -STATIC bool parse_locs(l,c1_out,c2_out) - line_p l; - offset *c1_out, *c2_out; -{ - if (INSTR(l) == op_loc && INSTR(PREV(l)) == op_loc) { - *c1_out = off_set(l); - *c2_out = off_set(PREV(l)); - return TRUE; - } - return FALSE; -} - - - -STATIC bool check_args(l,src_class,res_class,arg1_out,arg2_out) - line_p l; - int src_class,res_class; - offset *arg1_out, *arg2_out; -{ - /* Several EM instructions have an argument - * giving the size of the operand(s) of - * the instruction. E.g. a 'adi 4' is a 4-byte - * addition. The size may also be put on the - * stack. In this case we give up our - * efforts to recognize the parameter expression. - * Some instructions (e.g. CIU) use 2 arguments - * that are both on the stack. In this case we - * check if both arguments are LOCs (the usual case), - * else we give up. - */ - - if (uses_2args(src_class) || uses_2args(res_class)) { - return parse_locs(PREV(l),arg1_out,arg2_out); - } - if (uses_arg(src_class) || uses_arg(res_class)) { - if (TYPE(l) == OPSHORT) { - *arg1_out = (offset) SHORT(l); - return TRUE; - } else { - if (TYPE(l) == OPOFFSET) { - *arg1_out = OFFSET(l); - } else { - return FALSE; - } - } - } - return TRUE; /* no argument needed */ -} - - - -STATIC offset nrbytes(class,arg1,arg2) - int class; - offset arg1,arg2; -{ - /* Determine the number of bytes of the given - * arguments and class. - */ - - offset n; - - switch(class) { - case CLASS1: - n = arg1; - break; - case CLASS2: - n = 2 * arg1; - break; - case CLASS3: - n = arg1 + ws; - break; - case CLASS4: - n = arg1 + ps; - break; - case CLASS5: - n = ws; - break; - case CLASS6: - n = 2 * ws; - break; - case CLASS7: - n = ps; - break; - case CLASS8: - n = 2 * ps; - break; - case CLASS9: - n = 0; - break; - case CLASS10: - n = arg2 + 2*ws; - break; - case CLASS11: - n = arg1 + 2*ps; - break; - case CLASS12: - n = (arg1 < ws ? ws : arg1); - break; - default: - assert(FALSE); - } - return n; -} - - - -STATIC attrib(l,expect_out,srcb_out,resb_out) - line_p l; - offset *expect_out, *srcb_out, *resb_out; -{ - /* Determine a number of attributes of an EM - * instruction appearing in an expression. - * If it is something we don't - * expect in such expression (e.g. a store) - * expect_out is set to FALSE. Else we - * determine the number of bytes popped from - * the stack by the instruction and the - * number of bytes pushed on the stack as - * result. - */ - - int src_class,res_class; - offset arg1, arg2; - - if (l == (line_p) 0 || !classes(INSTR(l),&src_class,&res_class) || - !check_args(l,src_class,res_class,&arg1,&arg2)) { - *expect_out = FALSE; - } else { - *expect_out = TRUE; - *srcb_out = nrbytes(src_class,arg1,arg2); - *resb_out = nrbytes(res_class,arg1,arg2); - } -} - - - -bool parse(l,nbytes,l_out,level,action0) - line_p l, *l_out; - offset nbytes; - int level; - int (*action0) (); -{ - /* This is a recursive descent parser for - * EM expressions. - * It tries to recognize EM code that loads exactly - * 'nbytes' bytes on the stack. - * 'l' is the last instruction of this code. - * As EM is essentially postfix, this instruction - * can be regarded as the root node of an expression - * tree. The EM code is traversed from right to left, - * i.e. top down. On success, TRUE is returned and - * 'l_out' will point to the first instruction - * of the recognized code. On toplevel, when an - * expression has been recognized, the procedure-parameter - * 'action0' is called, with parameters: the first and - * last instruction of the expression and the number of - * bytes recognized. - */ - - offset more, expected, sourcebytes,resultbytes; - line_p lnp; - - more = nbytes; /* #bytes to be recognized */ - while (more > 0) { - attrib(l,&expected,&sourcebytes,&resultbytes); - /* Get the attributes of EM instruction 'l'. - * 'expected' denotes if it is something we can use; - * 'sourcebytes' and 'resultbytes' are the number of - * bytes popped resp. pushed by the instruction - * (e.g. 'adi 2' pops 4 bytes and pushes 2 bytes). - */ - if (!expected || (more -= resultbytes) < 0) return FALSE; - if (sourcebytes == 0) { - /* a leaf of the expression tree */ - lnp = l; - } else { - if (!parse(PREV(l),sourcebytes,&lnp,level+1,action0)) { - return FALSE; - } - } - if (level == 0) { - /* at toplevel */ - (*action0) (lnp,l,resultbytes); - } - l = PREV(lnp); - } - /* Now we've recognized a number of expressions that - * together push nbytes on the stack. - */ - *l_out = lnp; - return TRUE; -} diff --git a/util/ego/share/parser.h b/util/ego/share/parser.h deleted file mode 100644 index b09c5f5a0..000000000 --- a/util/ego/share/parser.h +++ /dev/null @@ -1,13 +0,0 @@ -bool parse(); /* (line_p l, *l_out; offset nbytes; - * int level; int (*action0) ()) - * This is a recursive descent parser for - * EM expressions. - * It tries to recognize EM code that loads exactly - * 'nbytes' bytes on the stack. - * 'l' is the last instruction of this code. - * On toplevel, when an expression has been - * recognized, the procedure-parameter - * 'action0' is called, with parameters: the first and - * last instruction of the expression and the number of - * bytes recognized. - */ diff --git a/util/ego/share/pop_push.awk b/util/ego/share/pop_push.awk deleted file mode 100644 index 3c9a977c1..000000000 --- a/util/ego/share/pop_push.awk +++ /dev/null @@ -1,15 +0,0 @@ -BEGIN { - print "char *pop_push[]=" - print "{" - print "\"\"," - switch = 0 -} -/aar/ { - switch = 1 -} - { - if (switch) printf("\"%s\",\n",$3) -} -END { - print "};" -} diff --git a/util/ego/share/put.c b/util/ego/share/put.c deleted file mode 100644 index 5a7fe9b6c..000000000 --- a/util/ego/share/put.c +++ /dev/null @@ -1,437 +0,0 @@ -/* P U T . C */ - -#include -#include "types.h" -#include "global.h" -#include "debug.h" -#include "def.h" -#include "map.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" -#include "lset.h" -#include "alloc.h" -#include "put.h" - -FILE *curoutp; - - -/* The output can be either 'typed' or 'untyped'. Typed data - * consists of a value preceded by a byte specifying what kind - * of value it is (e.g. 2 bytes constant, 4 bytes constant, - * proc-id, lab-id, string etc.). Untyped data consists - * of the value only. We use typed data for the EM text and - * untyped data for all other files. - */ - -/* putlines */ - -STATIC putargs(ap) - register arg_p ap; -{ - while (ap != (arg_p) 0) { - outbyte((byte) ap->a_type & BMASK); - switch(ap->a_type) { - case ARGOFF: - outoff(ap->a_a.a_offset); - break; - case ARGINSTRLAB: - outlab(ap->a_a.a_instrlab); - break; - case ARGOBJECT: - outobject(ap->a_a.a_obj); - break; - case ARGPROC: - outproc(ap->a_a.a_proc); - break; - case ARGSTRING: - putstr(&ap->a_a.a_string); - break; - case ARGICN: - case ARGUCN: - case ARGFCN: - outshort(ap->a_a.a_con.ac_length); - putstr(&ap->a_a.a_con.ac_con); - break; - } - ap = ap->a_next; - } - outbyte((byte) ARGCEND); -} - - - -STATIC putstr(abp) register argb_p abp; { - register argb_p tbp; - register length; - - length = 0; - tbp = abp; - while (tbp!= (argb_p) 0) { - length += tbp->ab_index; - tbp = tbp->ab_next; - } - outshort(length); - while (abp != (argb_p) 0) { - for (length=0;lengthab_index;length++) - outbyte( (byte) abp->ab_contents[length] ); - abp = abp->ab_next; - } -} - - -outoff(off) offset off; { - - outshort( (short) (off&0177777L) ); - outshort( (short) (off>>16) ); -} - - -outshort(i) short i; { - - outbyte( (byte) (i&BMASK) ); - outbyte( (byte) (i>>8) ); -} - - -STATIC outint(i) - int i; -{ - /* Write an integer to the output file. This routine is - * only used when outputting a bitvector-set. We expect an - * integer to be either a short or a long. - */ - - if (sizeof(int) == sizeof(short)) { - outshort(i); - } else { - assert (sizeof(int) == sizeof(offset)); - outoff(i); - } -} - -STATIC outlab(lid) lab_id lid; { - outshort((short) lid); -} - - -STATIC outobject(obj) obj_p obj; { - outshort((short) obj->o_id); -} - - -STATIC outproc(p) proc_p p; { - outshort((short) p->p_id); -} - - -short putlines(l,lf) - line_p l; - FILE *lf; -{ - /* Output the list of em instructions headed by l. - * Return the number of instruction written. - */ - - register line_p lnp; - line_p next; - short instr; - short count= 0; - - curoutp = lf; /* Set f to the EM-text output file */ - for (lnp = l; lnp != (line_p) 0; lnp = next) { - VL(lnp); - count++; - next = lnp->l_next; - instr = INSTR(lnp); - outbyte((byte) instr); - outbyte((byte) TYPE(lnp)); - switch(TYPE(lnp)) { - case OPSHORT: - outshort(SHORT(lnp)); - break; - case OPOFFSET: - outoff(OFFSET(lnp)); - break; - case OPINSTRLAB: - outlab(INSTRLAB(lnp)); - break; - case OPOBJECT: - outobject(OBJ(lnp)); - break; - case OPPROC: - outproc(PROC(lnp)); - break; - case OPLIST: - putargs(ARG(lnp)); - break; - } - oldline(lnp); - } - return count; -} - - - - - -/* putdtable */ - -#define outmark(m) outbyte((byte) m) - - -STATIC putobjects(obj) - register obj_p obj; -{ - while (obj != (obj_p) 0) { - outmark(MARK_OBJ); - outshort(obj->o_id); - outoff(obj->o_size); - outoff(obj->o_off); - obj = obj->o_next; - } -} - - - -STATIC putvalues(arg) - register arg_p arg; -{ - while (arg != (arg_p) 0) { - assert(arg->a_type == ARGOFF); - outmark(MARK_ARG); - outoff(arg->a_a.a_offset); - arg = arg->a_next; - } -} -putdtable(head,df) - dblock_p head; - FILE *df; -{ - /* Write the datablock table to the data block file df. */ - - register dblock_p dbl; - register obj_p obj; - dblock_p next; - register short n = 0; - - curoutp = df; /* set f to the data block output file */ - /* Count the number of objects */ - for (dbl = head; dbl != (dblock_p) 0; dbl = dbl->d_next) { - for (obj = dbl->d_objlist; obj != (obj_p) 0; - obj = obj->o_next) { - n++; - } - } - outshort(n); /* The table is preceded by #objects . */ - for (dbl = head; dbl != (dblock_p) 0; dbl = next) { - next = dbl->d_next; - outmark(MARK_DBLOCK); - outshort(dbl->d_id); - outbyte(dbl->d_pseudo); - outoff(dbl->d_size); - outshort(dbl->d_fragmnr); - outbyte(dbl->d_flags1); - putobjects(dbl->d_objlist); - putvalues(dbl->d_values); - olddblock(dbl); - } - fclose(curoutp); - if (omap != (obj_p *) 0) { - oldmap(omap,olength); /* release memory for omap */ - } -} - - - -/* putptable */ - - - -STATIC outcset(s) - cset s; -{ - /* A 'compact' set is represented externally as a row of words - * (its bitvector) preceded by its length. - */ - - register short i; - - outshort(s->v_size); - for (i = 0; i <= DIVWL(s->v_size - 1); i++) { - outint(s->v_bits[i]); - } -} - - - -putptable(head,pf,all) - proc_p head; - FILE *pf; - bool all; -{ - register proc_p p; - proc_p next; - register short n = 0; - /* Write the proc table */ - - curoutp = pf; - /* Determine the number of procs */ - for (p = head; p != (proc_p) 0; p = p->p_next) { - n++; - } - outshort(n); /* The table is preceded by its length. */ - outshort ((all?1:0)); /* if all=false, only some of the attributes - are written. */ - for (p = head; p != (proc_p) 0; p = next) { - next = p->p_next; - outshort(p->p_id); - outbyte(p->p_flags1); - if (p->p_flags1 & PF_BODYSEEN) { - /* If we have no access to the EM text of the - * body of a procedure, we have no information - * about it whatsoever, so there is nothing - * to output in that case. - */ - outshort(p->p_nrlabels); - outoff(p->p_localbytes); - outoff(p->p_nrformals); - if (all) { - outcset(p->p_change->c_ext); - outshort(p->p_change->c_flags); - outshort(p->p_use->u_flags); - outcset(p->p_calling); - Cdeleteset(p->p_change->c_ext); - oldchange(p->p_change); - olduse(p->p_use); - Cdeleteset(p->p_calling); - } - } - oldproc(p); - } - fclose(curoutp); - if (pmap != (proc_p *) 0) { - oldmap(pmap,plength); /* release memory for pmap */ - } -} - - - -/* putunit */ - -STATIC outloop(l) - loop_p l; -{ - outshort((short) l->lp_id); -} - - -STATIC outblock(b) - bblock_p b; -{ - if (b == (bblock_p) 0) { - outshort((short) 0); - } else { - outshort((short) b->b_id); - } -} - - -STATIC outid(e,p) - Lelem_t e; - int (*p) (); -{ - /* Auxiliary routine used by outlset. */ - - /* NOSTRICT */ - (*p) (e); -} - - -STATIC outlset(s,p) - lset s; - int (*p) (); -{ - /* A 'long' set is represented externally as a - * a sequence of elements terminated by a 0 word. - * The procedural parameter p is a routine that - * prints an id (proc_id, obj_id etc.). - */ - - register Lindex i; - - for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i,s)) { - outid(Lelem(i),p); - } - outshort((short) 0); -} - - - -putunit(kind,p,l,gf,lf) - short kind; - proc_p p; - line_p l; - FILE *gf, *lf; -{ - register bblock_p b; - register short n = 0; - Lindex pi; - loop_p lp; - - curoutp = gf; - if (kind == LDATA) { - outshort(0); /* No basic blocks */ - n = putlines(l,lf); - curoutp = gf; - outshort(n); - return; - } - /* Determine the number of basic blocks */ - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - n++; - } - outshort(n); /* # basic blocks */ - outshort(Lnrelems(p->p_loops)); /* # loops */ - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - n = putlines(b->b_start,lf); - curoutp = gf; - outblock(b); /* put its block_id */ - outshort(n); /* #instructions of the block */ - outlset(b->b_succ, outblock); /* put succ set */ - outlset(b->b_pred, outblock); /* put pred set */ - outblock(b->b_idom); /* put id of immediate dominator */ - outlset(b->b_loops, outloop); /* put loop set */ - outshort(b->b_flags); - } - /* The Control Flow Graph of every procedure is followed - * by a description of the loops of the procedure. - * Every loop contains an id, an entry block and a level. - */ - for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; - pi = Lnext(pi,p->p_loops)) { - lp = (loop_p) Lelem(pi); - outloop(lp); /* id */ - outshort(lp->lp_level); /* nesting level */ - outblock(lp->lp_entry); /* loop entry block */ - outblock(lp->lp_end); - oldloop(lp); - } - Ldeleteset(p->p_loops); - /* We will now release the memory of the basic blocks. - * Note that it would be incorrect to release a basic block - * after it has been written, because there may be references - * to it from other (later) blocks. - */ - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - Ldeleteset(b->b_loops); - Ldeleteset(b->b_succ); - Ldeleteset(b->b_pred); - oldbblock(b); - } - /* Release the memory for the lmap, lbmap, bmap, lpmap tables */ - if (lmap != (line_p *) 0) oldmap(lmap,llength); - if (lbmap != (bblock_p *) 0) oldmap(lbmap,llength); - if (bmap != (bblock_p *) 0) oldmap(bmap,blength); - if (lpmap != (loop_p *) 0) oldmap(lpmap,lplength); - curoutp = lf; -} diff --git a/util/ego/share/put.h b/util/ego/share/put.h deleted file mode 100644 index 729058ae8..000000000 --- a/util/ego/share/put.h +++ /dev/null @@ -1,40 +0,0 @@ - /* O U T P U T R O U T I N E S */ - - -extern FILE *curoutp; /* current output file */ - -#define outbyte(b) putc(b,curoutp) -extern outshort(); /* (short i) - * Write a short to curoutp - */ -extern outoff(); /* (offset off) - * Write an offset to curoutp - */ - -extern putdtable(); /* (dblock_p head, FILE *df) - * Write the data block table to file df, - * preceded by its length. - */ -extern putptable(); /* (proc_p head, FILE *pf, bool all) - * Write the proc table to file pf, - * preceded by its length. If all=false, - * the fields computed by CF will not be - * written (used by the IC phase). - */ -extern putunit(); /* (short kind; proc_p p; line_p l; - * FILE *gf, *lf) - * If kind = LTEXT, then write - * the control flow graph to file gf, - * preceded by its length (#basic blocks); - * write the EM code of every basic block - * in the graph to file lf, preceded by - * the number of instructions in the block. - * Else, (kind = LDATA) just write the - * list of instructions (data declarations) - * to lf. - */ -extern short putlines(); /* (line_p l; FILE *lf) - * Output the list of em instructions - * headed by l. Return the number of - * instructions written. - */ diff --git a/util/ego/share/show.c b/util/ego/share/show.c deleted file mode 100644 index 684ac7550..000000000 --- a/util/ego/share/show.c +++ /dev/null @@ -1,414 +0,0 @@ -/* S H O W . C */ - -/* This program can be used to make the output of the 'cf' pass - * human readable. It will display either the procedure table, - * the datablock table, the basic block table or the EM text, - * depending on the flag that is passed as first argument. - */ - - - -#include -#include "../../../h/em_spec.h" -#include "../../../h/em_flag.h" -#include "../../../h/em_pseu.h" -#include "../share/types.h" -#include "../share/def.h" -#include "../share/global.h" - - -#define BMASK 0377 - - - - - - -extern byte em_flag[]; - -#define space1() printf(" ") -char format[] = " %-11s%d\n"; -char lformat[] = " %-11s%D\n"; -char sformat[] = " %-10s%s\n"; -char dformat[] = " %-11s%d\n"; -char oformat[] = " %-11s%D\n"; - - - -FILE *f; /* input file */ - - -#define getbyte() getc(f) - -short getshort() -{ - register n; - - n = getbyte(); - n |= getbyte() << 8; - return n; -} - -offset getoff() -{ - register offset n; - - n = (unsigned) getshort(); - n |= ((offset) getshort() ) << 16; - return n; -} - - -int getint() -{ - /* Read an integer from the input file. This routine is - * only used when reading a bitvector-set. We expect an - * integer to be either a short or a long. - */ - - if (sizeof(int) == sizeof(short)) { - return getshort(); - } else { - return getoff(); - } -} - - -/* VARARGS 1 */ -error(s,a) char *s,*a; { - - fprintf(stderr,"error"); - fprintf(stderr,": "); - fprintf(stderr,s,a); - fprintf(stderr,"\n"); - abort(); - exit(-1); -} - -main(argc, argv) - int argc; - char *argv[]; -{ - if (argc != 3 || argv[1][0] != '-') { - error("usage: %s -[ldpbc] filename",argv[0]); - } - if ((f = fopen(argv[2], "r")) == NULL) { - error("cannot open %s", argv[2]); - } - switch(argv[1][1]) { - case 'l': - showl(); - break; - case 'd': - showd(); - break; - case 'p': - showp(); - break; - case 'b': - showb(); - break; - case 'c': - showc(); - break; - default: - error("bad flag"); - } - - fclose(f); -} - - -showcset() -{ - /* print a compact (bitvector) set */ - - short size; - register short i,j; - int w, mask; - - size = getshort(); - /* # significant bits in bitvector */ - i = 1; - printf(" { "); - if (size == 0) { - printf("}\n"); - return; - } - for (;;) { - w = getint(); - mask = 1 ; - for (j = 1; j <= WORDLENGTH; j++) { - if (w & mask) { - printf("%d ",i); - } - if (i++ == size) { - printf ("}\n"); - return; - } - mask <<= 1; - } - } -} - - - -showp() -{ - byte b; - short n; - short all; - printf("total number of procs: %d\n\n",getshort()); - all = getshort(); - while (TRUE) { - n = getshort(); - if (feof(f)) break; - printf("PROC\n"); - printf(format,"id =",n); - printf(format,"flags1 =",b = getbyte()); - if (b & PF_BODYSEEN) { - printf(format,"# labels =",getshort()); - printf(lformat,"# locals =",getoff()); - printf(lformat,"# formals =",getoff()); - if (all == 1) { - printf(" changed ="); showcset(); - printf(format,"c_flags =",getshort()); - printf(format,"u_flags =",getshort()); - printf(" calling ="); showcset(); - } - } else { - printf(" body not available\n"); - } - } -} - - -char *pseudo[5] = {"hol", "bss", "rom", "con", "unknown" }; - -showd() -{ - short n; - printf("total number of objects: %d\n\n",getshort()); - while (TRUE) { - n = getbyte(); - if (feof(f)) break; - switch(n) { - case MARK_DBLOCK: - printf("DBLOCK\n"); - printf(format,"id =",getshort()); - printf(sformat,"pseudo =", - pseudo[(short) getbyte()]); - printf(lformat,"size =",getoff()); - printf(format,"fragment =",getshort()); - printf(format,"flags1 =", - (short) getbyte()); - break; - case MARK_OBJ: - printf(" OBJ\n"); - space1(); - printf(format,"id =",getshort()); - space1(); - printf(lformat,"size =",getoff()); - space1(); - printf(lformat,"offset =",getoff()); - break; - case MARK_ARG: - printf(" VALUE\n"); - space1(); - printf(lformat,"offset =",getoff()); - break; - } - } -} - - -/* The mnemonics of the EM instructions and pseudos */ - - -extern char em_mnem[]; -extern char em_pseu[]; -char lab_mnem[] = "instrlab"; -char sym_mnem[] = "datalab"; - -showinstr() -{ - short instr; - char *s; - - instr = (short) getbyte(); - if (feof(f)) return FALSE; - if (instr >= sp_fmnem && instr <= sp_lmnem) { - s = &(em_mnem[(instr-sp_fmnem) *4]); - } else { - if (instr == op_lab) { - s = lab_mnem; - } else { - if (instr == ps_sym) { - s = sym_mnem; - } else { - s = &(em_pseu[(instr-sp_fpseu)*4]); - } - } - } - printf("%s",s); - switch((short) getbyte()) { - case OPSHORT: - case OPOBJECT: - printf(" %d", getshort()); - break; - case OPPROC: - printf(" $%d",getshort()); - break; - case OPINSTRLAB: - printf(" *%d",getshort()); - break; - case OPOFFSET: - printf(" %D", getoff()); - break; - case OPLIST: - arglist(); - break; - } - printf("\n"); - return TRUE; -} - - -showl() -{ - while (showinstr()); -} - - - -arglist() -{ - short length; - for (;;) { - switch((short) getbyte()) { - case ARGOBJECT: - printf(" %d", getshort()); - break; - case ARGPROC: - printf(" $%d",getshort()); - break; - case ARGINSTRLAB: - printf(" *%d",getshort()); - break; - case ARGOFF: - printf(" %D", getoff()); - break; - case ARGICN: - case ARGUCN: - case ARGFCN: - printf(" %d",getshort()); - /* Fall through !! */ - case ARGSTRING: - length = getshort(); - putchar(' '); - putchar('"'); - while (length--) { - putchar(getbyte()); - } - putchar('"'); - break; - case ARGCEND: - return; - } - } -} - - - -showlset() -{ - register short x; - - printf("{ "); - while (x = getshort()) { - printf("%d ",x); - } - printf("}\n"); -} - - - - -showb() -{ - /* basic block file */ - - short n,m; - - while (TRUE) { - n = getshort(); - if (feof(f)) break; - if (n == 0) { - printf("Declaration Unit:\n"); - printf(dformat,"#instrs =",getshort()); - printf("\n"); - continue; - } - printf("Control Flow Graph:\n"); - printf("number of basic blocks: %d\n",n); - m = getshort(); /* #loops */ - while (n--) { - printf(" BASIC BLOCK\n"); - printf(dformat,"id =",getshort()); - printf(dformat,"# instrs =",getshort()); - printf(" succ ="); - showlset(); - printf(" pred ="); - showlset(); - printf(dformat,"idom =",getshort()); - printf(" loops ="); - showlset(); - printf(dformat,"flags =",getshort()); - } - printf("number of loops: %d\n",m); - while (m--) { - printf(" LOOP\n"); - printf(dformat,"id =",getshort()); - printf(dformat,"level =",getshort()); - printf(dformat,"entry =",getshort()); - printf(dformat,"end =",getshort()); - } - printf("\n"); - } -} - - -showc() -{ - int n,m,cnt,t; - - cnt = 1; - while(TRUE) { - t = getshort(); - if (feof(f)) break; - printf("CALL %d\n",cnt++); - printf(format,"nestlevel =",t); - printf(format,"calling p. =",getshort()); - printf(format,"call_id =",getshort()); - printf(format,"called p. =",getshort()); - printf(format,"looplevel =",getbyte()); - printf(format,"flags =",getbyte()); - printf(format,"ratio =",getshort()); - printf(" actuals:"); - n = getshort(); - if (n == 0) { - printf(" ---\n"); - } else { - while (n--) { - printf("\n"); - m = getshort(); - printf(oformat,"size =",getoff()); - printf(dformat,"inl =",getbyte()); - while (m--) { - printf(" "); - showinstr(); - } - } - } - } -} diff --git a/util/ego/share/stack_chg.c b/util/ego/share/stack_chg.c deleted file mode 100644 index 89a8056db..000000000 --- a/util/ego/share/stack_chg.c +++ /dev/null @@ -1,104 +0,0 @@ -/* S T A C K _ C H A N G E . C */ - - -#include -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../../../h/em_spec.h" -#include "../../../h/em_mnem.h" - -#include "pop_push.h" - -#define IS_LOC(l) (l!=(line_p) 0 && INSTR(l)==op_loc && TYPE(l)==OPSHORT) - -int stack_change(l,sign) - line_p l; - char sign; -{ - /* Interpret the string in the third column of the em_table file */ - - char *s; - bool argdef; - short arg; - int sum = 0; - line_p p = PREV(l); - line_p pp = (p == (line_p) 0 ? (line_p) 0 : PREV(p)); - short i = INSTR(l); - - if (i < sp_fmnem || i > sp_lmnem) { - return 0; - } else { - if (TYPE(l) == OPSHORT) { - arg = SHORT(l); - if (arg < ws) { - /* E.g. a LOI 1 loads word-size bytes, - * not 1 byte! - */ - arg = ws; - } - argdef = TRUE; - } else { - argdef = FALSE; - } - } - s = pop_push[i]; - if (*s == '0') return 0; - while (*s != '\0') { - if (*s++ == sign) { - switch(*s) { - case 'w': - sum += ws; - break; - case 'd': - sum += 2 * ws; - break; - case 'p': - sum += ps; - break; - case 'a': - if (!argdef) return -1; - sum += arg; - break; - case 'x': - if (IS_LOC(p)) { - sum += SHORT(p); - break; - } else { - return -1; - } - case 'y': - if (IS_LOC(pp)) { - sum += SHORT(pp); - break; - } else { - return -1; - } - case '?': - return -1; - default: - assert(FALSE); - } - } - s++; - } - return sum; -} - - - -line_change(l,ok_out,pop_out,push_out) - line_p l; - bool *ok_out; - int *pop_out,*push_out; -{ - short pop,push; - - pop = stack_change(l,'-'); - push = stack_change(l,'+'); - *ok_out = (pop != -1 && push != -1); - *pop_out = pop; - *push_out = push; -} - - diff --git a/util/ego/share/stack_chg.h b/util/ego/share/stack_chg.h deleted file mode 100644 index 52576264e..000000000 --- a/util/ego/share/stack_chg.h +++ /dev/null @@ -1,10 +0,0 @@ - -/* S T A C K _ C H A N G E . H */ - -extern line_change(); /* ( line_p l; bool *ok_out; int *pop_out,*push_out) - * Try to determine how the stack-height will be - * affected by the EM instruction l. 'ok_out' is set - * to false if we fail to do so. pop_out and - * push_out are set to the number of bytes popped - * and pushed. E.g. for an "ADI 2" 4 and 2 are returned. - */ diff --git a/util/ego/share/types.h b/util/ego/share/types.h deleted file mode 100644 index b89e41c87..000000000 --- a/util/ego/share/types.h +++ /dev/null @@ -1,414 +0,0 @@ -/* I N T E R N A L D A T A S T R U C T U R E S O F E G O */ - - -/* This file contains the definitions of the global data types. - */ - - -/* TEMPORARY: */ -#define LONGOFF - - -#define IDL 8 /* identifier length */ -#define DYNAMIC 1 -#define NARGBYTES 14 -#define BMASK 0377 - -typedef struct argbytes argb_t; -typedef char byte; -typedef byte bool; -typedef long offset; -typedef short obj_id; -typedef short proc_id; -typedef short dblock_id; -typedef short block_id; -typedef short loop_id; -typedef short lab_id; - - -typedef struct dblock *dblock_p; -typedef struct obj *obj_p; -typedef struct proc *proc_p; -typedef struct loop *loop_p; -typedef struct change *change_p; -typedef struct use *use_p; -typedef struct bblock *bblock_p; -typedef struct line *line_p; -typedef struct arg *arg_p; -typedef struct argbytes *argb_p; -typedef struct elemholder *elem_p; -typedef struct elemholder *lset; -typedef struct bitvector *cset; -typedef elem_p Lindex; -typedef short Cindex; -typedef char *Lelem_t; -typedef short Celem_t; - -typedef union pext_t *pext_p; -typedef union bext_t *bext_p; -typedef union lpext_t *lpext_p; - - -typedef struct call *call_p; -typedef struct formal *formal_p; - -/* Used-Definition Analysis */ -typedef struct local *local_p; - -typedef struct cond_tab *cond_p; - -#define TRUE 1 -#define FALSE 0 - -/* DATABLOCKS */ - -/* A datablock is a block of global data, declared by means of - * a hol, bss, con or rom pseudo. The declaration may be in a file - * that is inaccessible to EGO, in which case the pseudo is unknown. - * Successive rom or con pseudos that are garanteed to be in the - * same fragment (according to the EM definition) share the - * same fragment number. - */ - -#define DHOL 0 -#define DBSS 1 -#define DROM 2 -#define DCON 3 -#define DUNKNOWN 4 - - -/* The following constants are used by the debugging tools: */ -#define D_FIRST DHOL -#define D_LAST DUNKNOWN - - -struct dblock { - dblock_id d_id; /* unique integer */ - byte d_pseudo; /* one of DHOL,DBSS,DROM,DCON,DUNKNOWN */ - offset d_size; /* # bytes, -1 if unknown */ - obj_p d_objlist; /* list of objects of the data block */ - byte d_flags1; /* see below */ - byte d_flags2; /* free to be used by phases */ - arg_p d_values; /* values, in case of ROM */ - short d_fragmnr; /* fragment number */ - dblock_p d_next; /* link to next block */ -}; - - -#define DF_EXTERNAL 01 /* Is name visible outside its module? */ - -/* OBJECTS */ - -/* An object is a row of successive bytes in one datablock - * that are considered to be a whole. E.g. scalar variables, - * arrays, I/O buffers etc. are objects. - */ - -struct obj { - offset o_off; /* offset within the block */ - offset o_size; /* size of the object, 0 if not known */ - obj_id o_id; /* unique integer */ - dblock_p o_dblock; /* backlink to data block */ - short o_globnr; /* global variable number */ - obj_p o_next; /* link */ -}; - - -/* PROCEDURES */ - -struct proc { - proc_id p_id; /* unique integer */ - short p_nrlabels; /* #instruction labels in the proc */ - offset p_localbytes; /* #bytes for locals */ - offset p_nrformals; /* #bytes for formals */ - byte p_flags1; /* see below */ - byte p_flags2; /* free to be used by phases */ - bblock_p p_start; /* pointer to first basic block */ - cset p_calling; /* set of all procs called by this one */ - lset p_loops; /* information about loops */ - change_p p_change; /* variables changed by this proc */ - use_p p_use; /* variables used by this proc */ - pext_p p_extend; /* pointer to any further information */ - proc_p p_next; /* link */ -}; - - -union pext_t { - struct pext_il { - call_p p_cals; /* candidate calls for in line expansion */ - short p_size; /* length of proc (EM-instrs or bytes) */ - formal_p p_formals; /* description of formals */ - short p_nrcalled; /* # times proc is called (varying) */ - long p_ccaddr; /* address of calcnt info on disk */ - long p_laddr; /* address in EM-text file on disk */ - short p_orglabels; /* original #labels before substitution */ - offset p_orglocals; /* original #bytes for locals */ - } px_il; -} ; - -#define PF_EXTERNAL 01 /* proc is externally visible */ -#define PF_BODYSEEN 02 /* body of proc is available as EM text */ -#define PF_CALUNKNOWN 04 /* proc calls an unavailable procedure */ -#define PF_ENVIRON 010 /* proc does a lxa or lxl */ -#define PF_LPI 020 /* proc may be called indirect */ -#define PF_CALINLOOP 040 /* proc ever called in a loop? (transitively) */ - -#define CALLED_IN_LOOP(p) p->p_flags1 |= PF_CALINLOOP -#define IS_CALLED_IN_LOOP(p) (p->p_flags1 & PF_CALINLOOP) - - -/* LOOPS */ - - struct loop { - loop_id lp_id; /* unique integer */ - short lp_level; /* nesting level, 0=outermost loop, - * 1=loop within loop etc. */ - bblock_p lp_entry; /* unique entry block of loop */ - bblock_p lp_end; /* tail of back edge of natural loop */ - lpext_p lp_extend; /* pointer to any further information */ -}; - - - -union lpext_t { - struct lpext_cf { - lset lpx_blocks; - short lpx_count; - bool lpx_messy; - } lpx_cf; - struct lpext_sr { - lset lpx_blocks; /* basic blocks constituting the loop */ - bblock_p lpx_header; /* header block, 0 if no one allocated yet */ - bool lpx_done; /* TRUE if we've processed this loop */ - line_p lpx_instr; /* current last instruction in header block*/ - } lpx_sr; - struct lpext_ra { - lset lpx_blocks; /* basic blocks constituting the loop */ - bblock_p lpx_header; /* header block, 0 if no one allocated yet */ - } lpx_ra; -} ; - -/* CHANGED/USED VARIABLES INFORMATION */ - - -struct change { - cset c_ext; /* external variables changed */ - short c_flags; /* see below */ -}; - -struct use { - short u_flags; /* see below */ -}; - - -#define CF_INDIR 01 -#define UF_INDIR 01 - - -/* SETS */ - - -/* There are 2 set representations: - * - long (lset), which is essentially a list - * - compact (cset), which is essentially a bitvector - */ - - - struct elemholder { - char *e_elem; /* pointer to the element */ - elem_p e_next; /* link */ -}; - -struct bitvector { - short v_size; /* # significant bits */ - int v_bits[DYNAMIC];/* a row of bits */ -}; - - - -/* BASIC BLOCKS */ - - -/* Note that the b_succ and b_pred fields constitute the - * Control Flow Graph - */ - - - struct bblock { - block_id b_id; /* unique integer */ - line_p b_start; /* pointer to first instruction */ - lset b_succ; /* set of successor blocks */ - lset b_pred; /* set of predecessor blocks */ - bblock_p b_idom; /* immediate dominator */ - lset b_loops; /* set of loops it is in */ - short b_flags; /* see below */ - bext_p b_extend; /* pointer to any further information */ - bblock_p b_next; /* link to textually next block */ -}; - - -union bext_t { - struct bext_cf { - short bx_semi; /* dfs number of semi-dominator */ - bblock_p bx_parent; /* parent in dfs spanning tree */ - lset bx_bucket; /* set of vertices whose sdom is b */ - bblock_p bx_ancestor; /* ancestor of b in forest, */ - bblock_p bx_label; /* used by link/eval */ - } bx_cf; - struct bext_ud { - cset bx_gen; /* definition generated in b */ - cset bx_kill; /* defs. outside b killed by b */ - cset bx_in; /* defs. reaching beginning of b */ - cset bx_out; /* defs. reaching end of b */ - cset bx_cgen; /* generated copies */ - cset bx_ckill; /* killed copies */ - cset bx_cin; /* copies reaching begin of b */ - cset bx_cout; /* copies reaching end of b */ - cset bx_chgvars; /* variables changed by b */ - } bx_ud; - struct bext_lv { - cset bx_use; /* variables used before being defined */ - cset bx_def; /* variables defined before being used */ - cset bx_lin; /* variables live at entry of b */ - cset bx_lout; /* variables live at exit of b */ - } bx_lv; - struct bext_ra { - short bx_begin; /* number of first instruction of block */ - short bx_end; /* number of last instruction of block */ - } bx_ra; -} ; - - -#define BF_STRONG 01 -#define BF_FIRM 02 - -#define IS_STRONG(b) (b->b_flags&BF_STRONG) -#define IS_FIRM(b) (b->b_flags&BF_FIRM) - - -/* EM INSTRUCTIONS */ - -/* Kinds of operand types (l_optype field) */ - -#define OPNO 0 -#define OPSHORT 1 -#define OPOFFSET 2 -#define OPINSTRLAB 3 -#define OPOBJECT 4 -#define OPPROC 5 -#define OPLIST 6 - - -/* The following constants are used by the debugging tools: */ -#define OP_FIRST OPNO -#define OP_LAST OPLIST - -#define LDATA 0 -#define LTEXT 01 - -struct line { - line_p l_next; /* link */ - byte l_instr; /* instruction */ - byte l_optype; /* kind of operand, used as tag */ - line_p l_prev; /* backlink to previous instruction */ - union { - short la_short; /* short: LOC 5 */ - offset la_offset; /* offset: LDC 20 */ - lab_id la_instrlab; /* label: BRA *10 */ - obj_p la_obj; /* object: LOE X+2 */ - proc_p la_proc; /* proc: CAL F3 */ - arg_p la_arg; /* arguments: HOL 10,0,0 */ - } l_a; -}; - - -/* ARGUMENTS */ - - -/* String representation of a constant, partitioned into - * pieces of NARGBYTES bytes. - */ - -#define ARGOFF 0 -#define ARGINSTRLAB 1 -#define ARGOBJECT 2 -#define ARGPROC 3 -#define ARGSTRING 4 -#define ARGICN 5 -#define ARGUCN 6 -#define ARGFCN 7 -#define ARGCEND 8 - - -struct argbytes { - argb_p ab_next; - short ab_index; - char ab_contents[NARGBYTES]; -}; - - -struct arg { - arg_p a_next; /* link */ - short a_type; /* kind of argument */ - union { - offset a_offset; /* offset */ - lab_id a_instrlab; /* instruction label */ - proc_p a_proc; /* procedure */ - obj_p a_obj; /* object */ - argb_t a_string; /* string */ - struct { /* int/unsigned/float constant */ - short ac_length; /* size in bytes */ - argb_t ac_con; /* its string repres. */ - } a_con; - } a_a; -}; - - - -/* Macros to increase readability: */ - -#define INSTR(lnp) (lnp->l_instr & BMASK) -#define TYPE(lnp) lnp->l_optype -#define PREV(lnp) lnp->l_prev -#define SHORT(lnp) lnp->l_a.la_short -#define OFFSET(lnp) lnp->l_a.la_offset -#define INSTRLAB(lnp) lnp->l_a.la_instrlab -#define OBJ(lnp) lnp->l_a.la_obj -#define PROC(lnp) lnp->l_a.la_proc -#define ARG(lnp) lnp->l_a.la_arg - - -/* Data structures for Use-Definition and Live-Dead Analysis */ - -struct local { - offset lc_off; /* offset of local in stackframe */ - short lc_size; /* size of local in bytes */ - short lc_flags; /* see below */ - offset lc_score; /* score in register message, if regvar */ - local_p lc_next; /* link, only used when building the list */ -}; - -/* values of lc_flags */ - -#define LCF_BAD 01 -/* Set when no ud-info for this local is maintained, e.g. when it is - * overlapped by another local. - */ -#define LCF_REG 02 /* register variable */ -#define LCF_LIVE 04 /* use by live-dead message generation */ - - -struct cond_tab { - short mc_cond; /* Denotes a condition e.g. FITBYTE */ - short mc_tval; /* value for time optimization */ - short mc_sval; /* value for space optimization */ - short mc_dummy; /* allignment */ -}; - -/* conditions: */ - -#define DEFAULT 0 -#define FITBYTE 1 -#define IN_0_63 2 -#define IN_0_8 3 - diff --git a/util/ego/sp/Makefile b/util/ego/sp/Makefile deleted file mode 100644 index dcdac73f0..000000000 --- a/util/ego/sp/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -sp.c - -OFILES=\ -sp.o - -HFILES= - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/get.o $(SHR)/put.o $(SHR)/alloc.o $(SHR)/global.o $(SHR)/debug.o \ -$(SHR)/files.o $(SHR)/map.o $(SHR)/lset.o $(SHR)/cset.o $(SHR)/aux.o \ -$(SHR)/stack_chg.o $(SHR)/go.o - -SHARE_MFILES=\ -$(SHR)/get.m $(SHR)/put.m $(SHR)/alloc.m $(SHR)/global.m $(SHR)/debug.m \ -$(SHR)/files.m $(SHR)/map.m $(SHR)/lset.m $(SHR)/cset.m $(SHR)/aux.m \ -$(SHR)/stack_chg.m $(SHR)/go.m - -sp: $(OFILES) - $(CC) -o sp $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -sp_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o sp -.c $(LDFLAGS) sp.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO - -sp.o: ../share/alloc.h -sp.o: ../share/aux.h -sp.o: ../share/debug.h -sp.o: ../share/files.h -sp.o: ../share/get.h -sp.o: ../share/global.h -sp.o: ../share/go.h -sp.o: ../share/lset.h -sp.o: ../share/map.h -sp.o: ../share/put.h -sp.o: ../share/stack_chg.h -sp.o: ../share/types.h -sp.o: ../../../h/em_mnem.h -sp.o: ../../../h/em_spec.h -stack_chg.o: ../share/debug.h -stack_chg.o: ../share/global.h -stack_chg.o: ../share/types.h -stack_chg.o: ../../../h/em_mnem.h -stack_chg.o: ../../../h/em_spec.h -stack_chg.o: pop_push.h diff --git a/util/ego/sp/sp.c b/util/ego/sp/sp.c deleted file mode 100644 index 001c2022c..000000000 --- a/util/ego/sp/sp.c +++ /dev/null @@ -1,240 +0,0 @@ -/* S T A C K P O L L U T I O N - * - * S P . C - */ - - -#include -#include "../share/types.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/files.h" -#include "../share/get.h" -#include "../share/put.h" -#include "../share/lset.h" -#include "../share/map.h" -#include "../share/alloc.h" -#include "../share/aux.h" -#include "../share/go.h" -#include "../share/stack_chg.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_spec.h" - - -/* Stack pollution throws away the ASP instructions after a procedure call. - * This saves a lot of code, at the cost of some extra stack space. - * ASPs that are part of a loop are not removed. - */ - -#define BF_MARK 04 -#define MARK(b) b->b_flags |= BF_MARK -#define NOT_MARKED(b) (!(b->b_flags&BF_MARK)) -#define IN_LOOP(b) (Lnrelems(b->b_loops) > 0) - -STATIC int Ssp; /* number of optimizations */ - -/* According to the EM definition, the stack must be cleaned up - * before any return. However, for some backends it causes no harm - * if the stack is not cleaned up. If so, we can do Stack Pollution - * more globally. - */ - -STATIC int globl_sp_allowed; - - -#define IS_ASP(l) (INSTR(l) == op_asp && TYPE(l) == OPSHORT && SHORT(l) > 0) - - -STATIC sp_machinit(f) - FILE *f; -{ - /* Read target machine dependent information for this phase */ - char s[100]; - - for (;;) { - while(getc(f) != '\n'); - fscanf(f,"%s",s); - if (strcmp(s,"%%SP") == 0)break; - } - fscanf(f,"%d",&globl_sp_allowed); -} -comb_asps(l1,l2,b) - line_p l1,l2; - bblock_p b; -{ - assert(INSTR(l1) == op_asp); - assert(INSTR(l2) == op_asp); - assert(TYPE(l1) == OPSHORT); - assert(TYPE(l2) == OPSHORT); - - SHORT(l2) += SHORT(l1); - rm_line(l1,b); -} - - - - -stack_pollution(b) - bblock_p b; -{ - /* For every pair of successive ASP instructions in basic - * block b, try to combine the two into one ASP. - */ - - register line_p l; - line_p asp,next = b->b_start; - bool asp_seen = FALSE; - int stack_diff,pop,push; - bool ok; - - do { - stack_diff = 0; - for (l = next; l != (line_p) 0; l = next) { - next = l->l_next; - if (IS_ASP(l)) break; - if (asp_seen) { - if (INSTR(l) == op_ret) { - stack_diff -= SHORT(l); - } else { - line_change(l,&ok,&pop,&push); - if (!ok || (stack_diff -= pop) < 0) { - /* can't eliminate last ASP */ - asp_seen = FALSE; - } else { - stack_diff += push; - } - } - } - } - if (asp_seen) { - if (l == (line_p) 0) { - /* last asp of basic block */ - if (globl_sp_allowed && - NOT_MARKED(b) && !IN_LOOP(b)) { - Ssp++; - rm_line(asp,b); - } - } else { - /* try to combine with previous asp */ - if (SHORT(l) == stack_diff) { - Ssp++; - comb_asps(asp,l,b); - } - } - } - asp = l; - asp_seen = TRUE; /* use new ASP for next try! */ - } while (asp != (line_p) 0); -} - -STATIC bool block_save(b) - bblock_p b; -{ - - register line_p l; - int stack_diff,pop,push; - bool ok; - - stack_diff = 0; - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - if (INSTR(l) == op_ret) { - stack_diff -= SHORT(l); - break; - } - line_change(l,&ok,&pop,&push); - /* printf("instr %d, pop %d,push %d,ok %d\n",INSTR(l),pop,push,ok); */ - if (!ok || (stack_diff -= pop) < 0) { - return FALSE; - } else { - stack_diff += push; - } - } - return stack_diff >= 0; -} - - - -STATIC mark_pred(b) - bblock_p b; -{ - Lindex i; - bblock_p x; - - for (i = Lfirst(b->b_pred); i != (Lindex) 0; i = Lnext(i,b->b_pred)) { - x = (bblock_p) Lelem(i); - if (NOT_MARKED(x)) { - MARK(x); - mark_pred(x); - } - } -} - - - - - -STATIC mark_unsave_blocks(p) - proc_p p; -{ - register bblock_p b; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - if (NOT_MARKED(b) && !block_save(b)) { - MARK(b); - mark_pred(b); - } - } -} - - -sp_optimize(p) - proc_p p; -{ - register bblock_p b; - - mark_unsave_blocks(p); - for (b = p->p_start; b != 0; b = b->b_next) { - stack_pollution(b); - } -} - - - - -main(argc,argv) - int argc; - char *argv[]; -{ - go(argc,argv,no_action,sp_optimize,sp_machinit,no_action); - report("stack adjustments deleted",Ssp); - exit(0); -} - - - - -/***** DEBUGGING: - -debug_stack_pollution(p) - proc_p p; -{ - register bblock_p b; - register line_p l; - int lcnt,aspcnt,instr; - - for (b = p->p_start; b != 0; b = b->b_next) { - lcnt = 0; aspcnt = 0; - for (l = b->b_start; l != 0; l= l->l_next) { - instr = INSTR(l); - if (instr >= sp_fmnem && instr <= sp_lmnem) { - lcnt++; - if (instr == op_asp && off_set(l) > 0) { - aspcnt++; - } - } - } - printf("%d\t%d\n",aspcnt,lcnt); - } -} - -*/ diff --git a/util/ego/sr/Makefile b/util/ego/sr/Makefile deleted file mode 100644 index cabdd7d8e..000000000 --- a/util/ego/sr/Makefile +++ /dev/null @@ -1,131 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -sr.c sr_iv.c sr_reduce.c sr_cand.c sr_xform.c sr_expr.c sr_aux.c - -OFILES=\ -sr.o sr_expr.o sr_reduce.o sr_iv.o sr_cand.o sr_xform.o sr_aux.o - -HFILES=\ -sr.h sr_iv.h sr_reduce.h sr_cand.h sr_xform.h sr_expr.h sr_aux.h - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/get.o $(SHR)/put.o $(SHR)/alloc.o $(SHR)/global.o $(SHR)/debug.o \ -$(SHR)/files.o $(SHR)/map.o $(SHR)/lset.o $(SHR)/cset.o $(SHR)/aux.o \ -$(SHR)/go.o - -SHARE_MFILES=\ -$(SHR)/get.m $(SHR)/put.m $(SHR)/alloc.m $(SHR)/global.m $(SHR)/debug.m \ -$(SHR)/files.m $(SHR)/map.m $(SHR)/lset.m $(SHR)/cset.m $(SHR)/aux.m \ -$(SHR)/go.m - -sr: $(OFILES) - $(CC) -o sr $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -sr_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o sr -.c $(LDFLAGS) sr.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO - -sr.o: ../share/alloc.h -sr.o: ../share/debug.h -sr.o: ../share/files.h -sr.o: ../share/get.h -sr.o: ../share/global.h -sr.o: ../share/lset.h -sr.o: ../share/map.h -sr.o: ../share/put.h -sr.o: ../share/types.h -sr.o: sr.h -sr.o: sr_aux.h -sr.o: sr_iv.h -sr_aux.o: ../../../h/em_mnem.h -sr_aux.o: ../../../h/em_pseu.h -sr_aux.o: ../share/aux.h -sr_aux.o: ../share/debug.h -sr_aux.o: ../share/global.h -sr_aux.o: ../share/lset.h -sr_aux.o: ../share/types.h -sr_aux.o: sr.h -sr_aux.o: sr_aux.h -sr_aux.o: sr_xform.h -sr_cand.o: ../../../h/em_mnem.h -sr_cand.o: ../../../h/em_pseu.h -sr_cand.o: ../share/aux.h -sr_cand.o: ../share/cset.h -sr_cand.o: ../share/debug.h -sr_cand.o: ../share/global.h -sr_cand.o: ../share/lset.h -sr_cand.o: ../share/map.h -sr_cand.o: ../share/types.h -sr_cand.o: sr.h -sr_cand.o: sr_aux.h -sr_cand.o: sr_cand.h -sr_expr.o: ../../../h/em_mnem.h -sr_expr.o: ../share/aux.h -sr_expr.o: ../share/debug.h -sr_expr.o: ../share/global.h -sr_expr.o: ../share/lset.h -sr_expr.o: ../share/types.h -sr_expr.o: sr.h -sr_expr.o: sr_aux.h -sr_expr.o: sr_iv.h -sr_iv.o: ../../../h/em_mnem.h -sr_iv.o: ../../../h/em_pseu.h -sr_iv.o: ../share/alloc.h -sr_iv.o: ../share/aux.h -sr_iv.o: ../share/cset.h -sr_iv.o: ../share/debug.h -sr_iv.o: ../share/global.h -sr_iv.o: ../share/lset.h -sr_iv.o: ../share/types.h -sr_iv.o: sr.h -sr_iv.o: sr_aux.h -sr_iv.o: sr_cand.h -sr_iv.o: sr_iv.h -sr_reduce.o: ../../../h/em_mes.h -sr_reduce.o: ../../../h/em_mnem.h -sr_reduce.o: ../../../h/em_pseu.h -sr_reduce.o: ../../../h/em_reg.h -sr_reduce.o: ../share/alloc.h -sr_reduce.o: ../share/aux.h -sr_reduce.o: ../share/debug.h -sr_reduce.o: ../share/global.h -sr_reduce.o: ../share/lset.h -sr_reduce.o: ../share/types.h -sr_reduce.o: sr.h -sr_reduce.o: sr_aux.h -sr_reduce.o: sr_expr.h -sr_reduce.o: sr_reduce.h -sr_reduce.o: sr_xform.h -sr_xform.o: ../../../h/em_mnem.h -sr_xform.o: ../../../h/em_pseu.h -sr_xform.o: ../../../h/em_spec.h -sr_xform.o: ../share/alloc.h -sr_xform.o: ../share/aux.h -sr_xform.o: ../share/debug.h -sr_xform.o: ../share/def.h -sr_xform.o: ../share/get.h -sr_xform.o: ../share/global.h -sr_xform.o: ../share/lset.h -sr_xform.o: ../share/types.h -sr_xform.o: sr.h -sr_xform.o: sr_aux.h -sr_xform.o: sr_xform.h diff --git a/util/ego/sr/sr.c b/util/ego/sr/sr.c deleted file mode 100644 index da38ae427..000000000 --- a/util/ego/sr/sr.c +++ /dev/null @@ -1,205 +0,0 @@ -/* S T R E N G T H R E D U C T I O N */ - - -#include -#include "../share/types.h" -#include "sr.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/files.h" -#include "../share/get.h" -#include "../share/put.h" -#include "../share/lset.h" -#include "../share/map.h" -#include "../share/alloc.h" -#include "../share/go.h" -#include "sr_aux.h" -#include "sr_iv.h" - -/* Strength reduction tries to change expensive operators occurring - * in a loop into cheaper operators. The expensive operators considered - * are multiplication and array referencing. - * The transformations can be expressed in C as: - * - * [1]: for (i = e1; i <= e2; i++) - * print(118*i); - * becomes: - * for (i = e1, t = 118*e1; i <= e2; i++, t += 118) - * print(t); - * - * [2]: for (i = e1; i <= e2; i++) - * print(a[i]); - * becomes: - * for (i = e1, p = &a[i]; i <= e2; i++, p++) - * print(*p); - * The latter optimization is suppressed if array bound checking - * is required. - */ - -/* Machine and/or language dependent parameters: */ - -int ovfl_harmful; -int arrbound_harmful; - -int Ssr; /* #optimizations found */ - -sr_machinit(f) - FILE *f; -{ - /* Read target machine dependent information */ - char s[100]; - - - for (;;) { - while(getc(f) != '\n'); - fscanf(f,"%s",s); - if (strcmp(s,"%%SR") == 0)break; - } - fscanf(f,"%d",&ovfl_harmful); - fscanf(f,"%d",&arrbound_harmful); -} - -STATIC del_ivs(ivs) - lset ivs; -{ - /* Delete the set of iv structs */ - - Lindex i; - - for (i = Lfirst(ivs); i != (Lindex) 0; i = Lnext(i,ivs)) { - oldiv(Lelem(i)); - } - Ldeleteset(ivs); -} - - -STATIC do_loop(loop) - loop_p loop; -{ - lset ivs, vars; - - OUTTRACE("going to process loop %d",loop->lp_id); - induc_vars(loop,&ivs, &vars); - /* Build a set of iv_structs, one for every induction - * variable of the loop, i.e. a variable i that - * is changed only by i := i + c, where c is a loop constant. - * Also detects variables that are changed (including induction - * variables!). - */ - OUTTRACE("loop has %d induction variables",Lnrelems(ivs)); - if (Lnrelems(ivs) > 0) { - strength_reduction(loop,ivs,vars); - /* Perform strength reduction. Reduce: - * iv * c to addition - * a[iv] to indirection (*p) - * (unless array bound checking is required) - */ - } - del_ivs(ivs); - Ldeleteset(vars); -} - - - -STATIC loopblocks(p) - proc_p p; -{ - /* Compute the LP_BLOCKS sets for all loops of p */ - - register bblock_p b; - register Lindex i; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (i = Lfirst(b->b_loops); i != (Lindex) 0; - i = Lnext(i,b->b_loops)) { - Ladd(b,&(((loop_p) Lelem(i))->LP_BLOCKS)); - } - } -} - - - -STATIC opt_proc(p) - proc_p p; -{ - /* Optimize all loops of one procedure. We first do all - * outer loops at the lowest nesting level and proceed - * in the inwards direction. - */ - - Lindex i; - loop_p lp,outermost; - int min_level; - - for (;;) { - min_level = 1000; - for (i = Lfirst(p->p_loops); i != (Lindex) 0; - i = Lnext(i,p->p_loops)) { - lp = (loop_p) Lelem(i); - if (!lp->LP_DONE && lp->lp_level < min_level) { - min_level = lp->lp_level; - outermost = lp; - } - } - if (min_level == 1000) break; - do_loop(outermost); - outermost->LP_DONE = TRUE; - OUTTRACE("loop %d processed",outermost->lp_id); - } -} - - - -STATIC sr_extproc(p) - proc_p p; -{ - /* Allocate the extended data structures for procedure p */ - - register loop_p lp; - register Lindex pi; - - for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; - pi = Lnext(pi,p->p_loops)) { - lp = (loop_p) Lelem(pi); - lp->lp_extend = newsrlpx(); - } -} - - - -STATIC sr_cleanproc(p) - proc_p p; -{ - /* Remove the extended data structures for procedure p */ - - register loop_p lp; - register Lindex pi; - - - for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; - pi = Lnext(pi,p->p_loops)) { - lp = (loop_p) Lelem(pi); - oldsrlpx(lp->lp_extend); - } -} - - -sr_optimize(p) - proc_p p; -{ - sr_extproc(p); - loopblocks(p); - opt_proc(p); - sr_cleanproc(p); -} - - - -main(argc,argv) - int argc; - char *argv[]; -{ - go(argc,argv,no_action,sr_optimize,sr_machinit,no_action); - report("strength reductions",Ssr); - exit(0); -} diff --git a/util/ego/sr/sr.h b/util/ego/sr/sr.h deleted file mode 100644 index a472690af..000000000 --- a/util/ego/sr/sr.h +++ /dev/null @@ -1,72 +0,0 @@ -/* I N T E R N A L D A T A S T R U C T U R E S O F - * - * S T R E N G T H R E D U C T I O N - * - */ - - -typedef struct iv *iv_p; -typedef struct code_info *code_p; - -/* An induction variable */ - -struct iv { - offset iv_off; /* offset of the induction variable */ - line_p iv_incr; /* pointer to last instr. of EM-code that - * increments the induction variable */ - offset iv_step; /* step value */ -}; - - -/* All information about a reducible piece of code is collected in - * a single structure. - */ - -struct code_info { - loop_p co_loop; /* the loop the code is in */ - bblock_p co_block; /* the basic block the code is in */ - line_p co_lfirst; /* first instruction of the code */ - line_p co_llast; /* last instruction of the code */ - line_p co_ivexpr; /* start of linear expr. using iv */ - line_p co_endexpr; /* end of the expression */ - int co_sign; /* sign of iv in above expr */ - iv_p co_iv; /* the induction variable */ - offset co_temp; /* temporary variable */ - int co_tmpsize; /* size of the temp. variable (ws or ps)*/ - int co_instr; /* the expensive instruction (mli,lar..)*/ - union { - line_p co_loadlc; /* LOC lc instruction (for mult.)*/ - line_p co_desc; /* load address of descriptor - * (for lar etc.) */ - } c_o; -}; - -#define LOAD 0 -#define STORE 1 - -#define DLINK(l1,l2) l1->l_next=l2; l2->l_prev=l1 - -#define same_local(l1,l2) (off_set(l1) == off_set(l2)) - -#define LP_BLOCKS lp_extend->lpx_sr.lpx_blocks -#define LP_DONE lp_extend->lpx_sr.lpx_done -#define LP_HEADER lp_extend->lpx_sr.lpx_header -#define LP_INSTR lp_extend->lpx_sr.lpx_instr - -/* Parameters to be provided by environment: */ - -extern int ovfl_harmful; /* Does overflow during multiplication - * cause a trap ? - */ -extern int arrbound_harmful; /* Is it harmful to take the address of - * a non-existing array element ? - */ -extern int Ssr; /* #optimizations found */ - -/* core allocation macros */ -#define newiv() (iv_p) newstruct(iv) -#define newcinfo() (code_p) newstruct(code_info) -#define newsrlpx() (lpext_p) newstruct(lpext_sr) -#define oldiv(x) oldstruct(iv,x) -#define oldcinfo(x) oldstruct(code_info,x) -#define oldsrlpx(x) oldstruct(lpext_sr,x) diff --git a/util/ego/sr/sr_aux.c b/util/ego/sr/sr_aux.c deleted file mode 100644 index 9b6d5b082..000000000 --- a/util/ego/sr/sr_aux.c +++ /dev/null @@ -1,115 +0,0 @@ -/* S T R E N G T H R E D U C T I O N - * - * S R _ A U X . C - * - */ - - -#include "../share/types.h" -#include "sr.h" -#include "../share/debug.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/aux.h" -#include "sr_aux.h" -#include "sr_xform.h" - -#define INSIDE_LOOP(b,lp) Lis_elem(b,lp->LP_BLOCKS) - - -bool is_loopconst(lnp,vars) - line_p lnp; - lset vars; -{ - Lindex i; - - assert(TYPE(lnp) == OPSHORT || TYPE(lnp) == OPOFFSET); - if (!is_regvar(off_set(lnp))) return FALSE; - for (i = Lfirst(vars); i != (Lindex) 0; i = Lnext(i,vars)) { - if (same_local(Lelem(i),lnp)) { - return FALSE; /* variable was changed */ - } - } - return TRUE; -} - - -bool is_caddress(lnp,vars) - line_p lnp; - lset vars; /* variables changed in loop */ -{ - /* See if lnp is a single instruction (i.e. without arguments) - * that pushes a loop-invariant entity of size pointer-size (ps) - * on the stack. - */ - - if (lnp == (line_p) 0) return FALSE; - switch(INSTR(lnp)) { - case op_lae: - case op_lal: - return TRUE; - case op_lol: - return ps == ws && is_loopconst(lnp,vars); - case op_ldl: - return ps == 2*ws && is_loopconst(lnp,vars); - default: - return FALSE; - } - /* NOTREACHED */ -} - - - -STATIC arg_p find_arg(n,list) - int n; - arg_p list; -{ - /* Find the n-th element of the list */ - - while (--n) { - if (list == (arg_p) 0) break; - list = list->a_next; - } - return list; -} - - -int elemsize(lnp) - line_p lnp; -{ - /* lnp is an instruction that loads the address of an array - * descriptor. Find the size of the elements of the array. - * If this size cannot be determined (e.g. the descriptor may - * not be in a rom) then return UNKNOWN_SIZE. - */ - - dblock_p d; - arg_p v; - - assert (lnp != (line_p) 0); - if (INSTR(lnp) == op_lae) { - d = OBJ(lnp)->o_dblock; /* datablock */ - if (d->d_pseudo == DROM && - (v = find_arg(3,d->d_values)) != (arg_p) 0 && - v->a_type == ARGOFF) { - return (int) v->a_a.a_offset; - } - } - return UNKNOWN_SIZE; -} - - - -concatenate(list1,list2) - line_p list1,list2; -{ - /* Append list2 to the end of list1. list1 may not be empty. */ - - register line_p l; - - assert(list1 != (line_p) 0); - for (l =list1; l->l_next != (line_p) 0; l = l->l_next); - l->l_next = list2; -} diff --git a/util/ego/sr/sr_aux.h b/util/ego/sr/sr_aux.h deleted file mode 100644 index a58dfbd54..000000000 --- a/util/ego/sr/sr_aux.h +++ /dev/null @@ -1,20 +0,0 @@ -/* S R _ A U X . H */ - - -extern bool is_loopconst(); /* (line_p l; lset vars) - * See if l is a loop-constant. vars is the - * set of variables changed in the loop. - */ -extern bool is_caddress(); /* (line_p l) - * See if l loads a loop-invariant entity of - * size pointer-size. - */ -extern int elemsize(); /* (line_p l) - * l is an instruction that loads an array - * descriptor. Try to determine the size - * of the array elements. - */ -extern concatenate(); /* (line_p list1,list2) - * Append list2 to the end of list1 - */ -#define is_const(l) (INSTR(l) == op_loc) diff --git a/util/ego/sr/sr_cand.c b/util/ego/sr/sr_cand.c deleted file mode 100644 index 4dcd4ea0a..000000000 --- a/util/ego/sr/sr_cand.c +++ /dev/null @@ -1,187 +0,0 @@ -/* S T R E N G T H R E D U C T I O N - * - * S R _ C A N D . C - */ - - -#include "../share/types.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/map.h" -#include "../share/aux.h" -#include "sr.h" -#include "sr_aux.h" -#include "sr_cand.h" - - -/* A candidate induction variable of a loop (hereafter called candidate) is a - * local variable (of the current procedure) that is assigned a value - * precisely once within the loop. Furthermore, this assignment must - * take place in a firm block of the loop. - * We determine those locals that are assigned precisely once, within - * a firm block; - * - * We represent a local variable via an instruction that references it, - * e.g. LOL -6 represents the local variable at offset -6 with size=wordsize. - * We keep track of two sets: - * cand - the set of all candidate variables - * dismiss - a set of variables that may not be made a candidate - * (because they are assigned more than once, or because - * they are assigned outside a firm block). - * Only local variables for which a register message is given are considered. - */ - - -STATIC lset cand, /* set of candidates */ - dism; /* set of dismissed variables */ - - -#define ALL_LINES(lnp,list) lnp = list; lnp != (line_p) 0; lnp = lnp->l_next - - - -STATIC un_cand(lnp) - line_p lnp; -{ - /* remove the variable stored into by lnp from the list of - * candidates (if it was there anyway). - */ - - Lindex i, next; - - for (i = Lfirst(cand); i != (Lindex) 0; i = next) { - next = Lnext(i,cand); - if (same_local(lnp,Lelem(i))) { - OUTTRACE("remove candidate",0); - Lremove(Lelem(i), &cand); - } - } -} - - -STATIC bool is_cand(lnp) - line_p lnp; -{ - /* see if the variable stored into by lnp is a candate */ - - Lindex i; - - for (i = Lfirst(cand); i != (Lindex) 0; i = Lnext(i,cand)) { - if (same_local(lnp,Lelem(i))) { - return TRUE; - } - } - return FALSE; -} - - -STATIC make_cand(lnp) - line_p lnp; -{ - /* make the variable stored into by lnp a candidate */ - - - OUTTRACE("add a new candidate",0); - Ladd(lnp,&cand); -} - - - -STATIC do_dismiss(lnp) - line_p lnp; -{ - Ladd(lnp,&dism); -} - - -STATIC dismiss(lnp) - line_p lnp; -{ - /* The variable referenced by lnp is turned definitely into - * a non-candidate. - */ - - un_cand(lnp); /* remove it from the candidate set, - * if it was there in the first place. - */ - do_dismiss(lnp); /* add it to the set of dismissed variables */ -} - - -STATIC bool not_dismissed(lnp) - line_p lnp; -{ - Lindex i; - - for (i = Lfirst(dism); i != (Lindex) 0; i = Lnext(i,dism)) { - if (same_local(Lelem(i),lnp)) { - return FALSE; /* variable was dismissed */ - } - } - return TRUE; -} - - -STATIC try_cand(lnp,b) - line_p lnp; - bblock_p b; -{ - /* If the variable stored into by lnp was not already a candidate - * and was not dismissed, then it is made a candidate - * (unless the assignment takes places in a block that is not firm). - */ - - if (!is_regvar(off_set(lnp))) return; - if (is_cand(lnp) || !IS_FIRM(b)) { - dismiss(lnp); - } else { - if (not_dismissed(lnp)) { - make_cand(lnp); - } - } -} - - -candidates(lp,cand_out,vars_out) - loop_p lp; - lset *cand_out, *vars_out; -{ - /* Find the candidate induction variables. - */ - - bblock_p b; - line_p lnp; - Lindex i; - - OUTTRACE("find candidates of loop %d",lp->lp_id); - cand = Lempty_set(); - dism = Lempty_set(); - - for (i = Lfirst(lp->LP_BLOCKS); i != (Lindex) 0; - i = Lnext(i,lp->LP_BLOCKS)) { - b = (bblock_p) Lelem(i); - for ( ALL_LINES(lnp, b->b_start)) { - OUTTRACE("inspect instruction %d",INSTR(lnp)); - switch(INSTR(lnp)) { - case op_stl: - case op_inl: - case op_del: - OUTTRACE("it's a store local",0); - try_cand(lnp,b); - break; - case op_zrl: - OUTTRACE("it's a destroy local",0); - if (is_regvar(off_set(lnp))) { - dismiss(lnp); - } - break; - } - } - } - *cand_out = cand; - *vars_out = dism; -} diff --git a/util/ego/sr/sr_cand.h b/util/ego/sr/sr_cand.h deleted file mode 100644 index 578fb58a4..000000000 --- a/util/ego/sr/sr_cand.h +++ /dev/null @@ -1,14 +0,0 @@ -/* S T R E N G T H R E D U C T I O N - * - * S R _ C A N D . H - */ - - -extern candidates(); /* (loop_p lp; lset *iv_cand, *vars) - * Find candidate induction variables, - * i.e. local variables that are assigned - * a value precisely once within the loop, - * within a strong block. Also find the - * local variables that are changed within - * the loop, but that are not a candidate. - */ diff --git a/util/ego/sr/sr_expr.c b/util/ego/sr/sr_expr.c deleted file mode 100644 index d15ea8341..000000000 --- a/util/ego/sr/sr_expr.c +++ /dev/null @@ -1,199 +0,0 @@ -/* S T R E N G T H R E D U C T I O N - * - * S R _ E X P R . C - * - */ - - -#include -#include "../share/types.h" -#include "sr.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/aux.h" -#include "sr_aux.h" -#include "../share/lset.h" -#include "sr_iv.h" -#include "../../../h/em_mnem.h" - - - -#define ME_NONE 0 -#define ME_UNAIR 1 -#define ME_BINAIR 2 -#define ME_LOOPCONST 3 -#define ME_IV 4 - - - -STATIC iv_p last_iv; -STATIC int iv_sign; -STATIC lset ivars, loopvars; - -STATIC bool is_loadiv(lnp) - line_p lnp; -{ - /* See if lnp is a LOL iv instruction, where iv is an - * induction variable of the set ivars. If so, set the - * the global variable last_iv to its descriptor. - */ - - Lindex i; - iv_p iv; - offset off; - - if (INSTR(lnp) == op_lol) { - off = off_set(lnp); - for (i = Lfirst(ivars); i != (Lindex) 0; i = Lnext(i,ivars)) { - iv = (iv_p) Lelem(i); - if (iv->iv_off == off) { - last_iv = iv; - return TRUE; - } - } - } - return FALSE; -} - - - - -#define size_ok(l) (TYPE(l) == OPSHORT && SHORT(l) == ws) - - -STATIC int me_kind(l,sign_in,sign_out) - line_p l; - int sign_in, *sign_out; -{ - if (l != (line_p) 0) { - switch(INSTR(l)) { - case op_adi: - case op_adu: - if (size_ok(l)) { - *sign_out = sign_in; - return ME_BINAIR; - } - break; - case op_sbi: - case op_sbu: - if (size_ok(l)) { - *sign_out = - sign_in; - return ME_BINAIR; - } - break; - case op_ngi: - if (size_ok(l)) { - *sign_out = - sign_in; - return ME_UNAIR; - } - break; - case op_inc: - case op_dec: - *sign_out = sign_in; - return ME_UNAIR; - case op_loc: - return ME_LOOPCONST; - case op_lol: - if (is_loadiv(l)) { - iv_sign = sign_in; - return ME_IV; - } - if (is_loopconst(l,loopvars)) return ME_LOOPCONST; - } - } - return ME_NONE; -} - - - -STATIC bool match_expr(l,iv_allowed,lbegin,iv_seen,sign) - line_p l,*lbegin; - bool iv_allowed, *iv_seen; - int sign; -{ - /* This routine is a top down parser for simple - * EM expressions. It recognizes expressions that - * have as operators + and - (unary - is also allowed) - * and that have as operands a number of loop constants - * (either a constant or a variable that is not - * changed within the loop) and at most one induction - * variable. - * The parameter iv_allowed is propagated downwards - * in the expression tree, indicating whether the - * subexpression may use an induction variable as - * operand. The parameter iv_seen is propagated - * upwards, indicating if the subexpression has used - * an induction variable. The parameter sign is - * propagated downwards; it indicates the sign of - * the subexpression. lbegin will point to the - * beginning of the recognized subexpression - * (it is an out parameter). Note that we scan the - * EM text from right to left (i.e. top down). - */ - - line_p l1; - bool iv_insubexpr; - int sign2; - - switch(me_kind(l,sign,&sign2)) { - case ME_UNAIR: - /* unairy operator, match one subexpression */ - if (match_expr(PREV(l),iv_allowed,&l1,&iv_insubexpr,sign2)) { - *lbegin = l1; - *iv_seen = iv_insubexpr; - return TRUE; - } - return FALSE; - case ME_BINAIR: - /* binairy operator, match two subexpressions */ - if (match_expr(PREV(l), iv_allowed, &l1, &iv_insubexpr,sign2)) { - l = PREV(l1); - iv_allowed = iv_allowed && !iv_insubexpr; - if (match_expr(l,iv_allowed,&l1, - &iv_insubexpr,sign)) { - *lbegin = l1; - *iv_seen = !iv_allowed || iv_insubexpr; - return TRUE; - } - } - return FALSE; /* subexpression not recognized */ - case ME_LOOPCONST: - *lbegin = l; /* expression is a loop constant */ - *iv_seen = FALSE; - return TRUE; - case ME_IV: - if (iv_allowed) { - *iv_seen = TRUE; - *lbegin = l; - return TRUE; - } - /* fall through ... */ - default: - return FALSE; - } -} - - -bool is_ivexpr(l,ivs,vars,lbegin_out,iv_out,sign_out) - line_p l, *lbegin_out; - lset ivs,vars; - iv_p *iv_out; - int *sign_out; -{ - line_p l2; - bool iv_seen; - - - loopvars = vars; - ivars = ivs; - if (match_expr(l,TRUE,&l2,&iv_seen,1)) { - if (iv_seen) { - /* recognized a correct expression */ - *lbegin_out = l2; - *iv_out = last_iv; - *sign_out = iv_sign; - return TRUE; - } - } - return FALSE; -} diff --git a/util/ego/sr/sr_expr.h b/util/ego/sr/sr_expr.h deleted file mode 100644 index dae187ccb..000000000 --- a/util/ego/sr/sr_expr.h +++ /dev/null @@ -1,13 +0,0 @@ -/* S T R E N G T H R E D U C T I O N - * - * S R _ E X P R . H - * - */ - -extern bool is_ivexpr();/* (line_p l; lset ivs,vars; line_p *lbegin; iv_p *iv; - * int *out_sign) - * Try to recognize an expression that is a linear - * function of presicely one induction variable. - * It may only use loop constants (besides the - * induc. var.). - */ diff --git a/util/ego/sr/sr_iv.c b/util/ego/sr/sr_iv.c deleted file mode 100644 index fe561d2b9..000000000 --- a/util/ego/sr/sr_iv.c +++ /dev/null @@ -1,183 +0,0 @@ -/* S T R E N G T H R E D U C T I O N - * - * S R _ I V . C - * - */ - - -#include "../share/types.h" -#include "sr.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/alloc.h" -#include "../share/aux.h" -#include "sr_aux.h" -#include "sr_cand.h" -#include "sr_iv.h" - - - -STATIC lset ivvars; /* set of induction variables */ - -STATIC short nature(lnp) - line_p lnp; -{ - /* Auxiliary routine used by inc_or_dec, is_add and plus_or_min. - * Determine if lnp had INCREMENT/DECREMENT-nature (1), - * ADD-nature (2), SUBTRACT-nature (3) - * or Buddha-nature (0). - */ - - bool size_ok; - - assert(lnp != (line_p) 0); - size_ok = (TYPE(lnp) == OPSHORT && SHORT(lnp) == ws); - switch(INSTR(lnp)) { - case op_inc: - case op_dec: - return 1; - case op_adi: - case op_adu: - return (size_ok? 2:0); - case op_sbi: - case op_sbu: - return (size_ok? 3:0); - } - return 0; -} - - - -#define is_add(l) (nature(l) == 2) -#define plus_or_min(l) (nature(l) > 1) -#define inc_or_dec(l) (nature(l) == 1) - - -STATIC bool is_same(l,lnp) - line_p l, lnp; -{ - /* lnp is a STL x , where x is a candidate - * induction variable. See if l is a LOL x - * (with the same x as the store-instruction) - */ - - assert(INSTR(lnp) == op_stl); - return l != (line_p) 0 && INSTR(l) == op_lol && - off_set(l) == off_set(lnp); -} - - -STATIC ivar(lnp,step) - line_p lnp; - int step; -{ - /* Record the fact that we've found a new induction variable. - * lnp points to the last instruction of the code that - * increments the induction variable, i.e. a STL, DEL or INL. - */ - - iv_p i; - - i = newiv(); - i->iv_off = (TYPE(lnp) == OPSHORT ? (offset) SHORT(lnp) : OFFSET(lnp)); - i->iv_incr = lnp; /* last instruction of increment code */ - i->iv_step = step; /* step value */ - Ladd(i,&ivvars); -} - - -STATIC int sign(lnp) - line_p lnp; -{ - switch(INSTR(lnp)) { - case op_inc: - case op_inl: - case op_adi: - case op_adu: - return 1; - case op_dec: - case op_del: - case op_sbi: - case op_sbu: - return (-1); - default: - assert(FALSE); - } - /* NOTREACHED */ -} - - -STATIC try_patterns(lnp) - line_p lnp; -{ - /* lnp is a STL x; try to recognize - * one of the patterns: - * 'LOAD const; LOAD x; ADD; STORE x' - * or 'LOAD x; LOAD const; ADD or SUBTRACT; - * STORE x' - * or 'LOAD x; INCREMENT/DECREMENT; STORE x' - */ - - line_p l, l2; - - l = PREV(lnp); /* instruction before lnp*/ - if (l == (line_p) 0) return; /* no match possible */ - l2 = PREV(l); - if (inc_or_dec(l)) { - if (is_same(l2,lnp)) { - /* e.g. LOL iv ; INC ; STL iv */ - ivar(lnp,sign(l)); - } - return; - } - if (is_add(lnp)) { - if(is_same(l2,lnp) && is_const(PREV(l2))) { - ivar(lnp,SHORT(PREV(l2))); - return; - } - } - if (plus_or_min(l)) { - if (is_const(l2) && is_same(PREV(l2),lnp)) { - ivar(lnp,sign(l) * SHORT(l2)); - } - } -} - - -induc_vars(loop,ivar_out, vars_out) - loop_p loop; - lset *ivar_out, *vars_out; -{ - /* Construct the set of induction variables. We use several - * global variables computed by 'candidates'. - */ - - Lindex i; - line_p lnp; - lset cand_iv, vars; - - ivvars = Lempty_set(); - candidates(loop, &cand_iv, &vars); - /* Find the set of all variables that are assigned precisely - * once within the loop, within a firm block. - * Also find all remaining local variables that are changed - * within the loop. - */ - if (Lnrelems(cand_iv) > 0) { - for (i = Lfirst(cand_iv); i != (Lindex) 0; i = Lnext(i,cand_iv)) { - lnp = (line_p) Lelem(i); - if (INSTR(lnp) == op_inl || INSTR(lnp) == op_del) { - ivar(lnp,sign(lnp)); - } else { - try_patterns(lnp); - } - } - } - Ljoin(cand_iv, &vars); - *ivar_out = ivvars; - *vars_out = vars; -} diff --git a/util/ego/sr/sr_iv.h b/util/ego/sr/sr_iv.h deleted file mode 100644 index a157e25fe..000000000 --- a/util/ego/sr/sr_iv.h +++ /dev/null @@ -1,7 +0,0 @@ -/* S R _ I V . H */ - -extern induc_vars(); /* (loop_p loop; lset *ivars, *vars) - * Find the set of induction variables - * of the loop. Also find the set of (local) - * variables that are changed. - */ diff --git a/util/ego/sr/sr_reduce.c b/util/ego/sr/sr_reduce.c deleted file mode 100644 index db9543d70..000000000 --- a/util/ego/sr/sr_reduce.c +++ /dev/null @@ -1,626 +0,0 @@ -/* S T R E N G T H R E D U C T I O N - * - * S R _ R E D U C E . C - * - */ - - -#include "../share/types.h" -#include "sr.h" -#include "../../../h/em_mnem.h" -#include "../share/debug.h" -#include "../share/alloc.h" -#include "../share/global.h" -#include "../share/aux.h" -#include "sr_aux.h" -#include "../share/lset.h" -#include "sr_xform.h" -#include "sr_reduce.h" -#include "sr_expr.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_reg.h" -#include "../../../h/em_mes.h" -#include "../../../h/em_mnem.h" - - - -STATIC lset avail; -/* If an expression such as "iv * const" or "A[iv]" is - * used more than once in a loop, we only use one temporary - * local for it and reuse this local each time. - * After the first occurrence, the expression is said to - * be available. - */ - -STATIC int regtyp(code) - code_p code; -{ - switch(code->co_instr) { - case op_mli: - case op_mlu: - return reg_any; - default: - return reg_pointer; - } - /* NOTREACHED */ -} - - -STATIC gen_regmes(tmp,score,code,p) - offset tmp; - int score; - code_p code; - proc_p p; -{ - /* generate a register message for the temporary variable and - * insert it at the start of the procedure. - */ - - line_p l,pro; - - l = reg_mes(tmp,code->co_tmpsize,regtyp(code),score); - pro = p->p_start->b_start; /* every proc. begins with a PRO pseudo */ - l->l_next = pro->l_next; - PREV(l->l_next) = l; - pro->l_next = l; - PREV(l) = pro; -} - - -STATIC line_p newcode(code,tmp) - code_p code; - offset tmp; -{ - /* Construct the EM code that will replace the reducible code, - * e.g. iv * c -> tmp - * a[iv] -> *tmp - */ - - line_p l; - - switch(code->co_instr) { - case op_mli: - case op_mlu: - /* new code is just a LOL tmp */ - l = int_line(tmp); - l->l_instr = op_lol; - break; - case op_aar: - /* New code is a LOAD tmp, where tmp is a - * pointer variable, so the actual EM code - * depends on the pointer size. - */ - l = move_pointer(tmp,LOAD); - break; - case op_lar: - /* New code is a load-indirect */ - l = int_line(tmp); - l->l_instr = op_lil; - break; - case op_sar: - /* New code is a store-indirect */ - l = int_line(tmp); - l->l_instr = op_sil; - break; - default: - assert(FALSE); - } - return l; -} - - - -STATIC replcode(code,text) - code_p code; - line_p text; -{ - /* Replace old code (extending from code->co_lfirst to - * code->co_llast) by new code (headed by 'text'). - */ - - line_p l, l1, l2; - - for (l = text; l->l_next != (line_p) 0; l = l->l_next); - /* 'l' now points to last instruction of text */ - l1 = PREV(code->co_lfirst); /* instruction just before old code */ - l2 = code->co_llast->l_next; /* instruction just behind old code */ - if (l1 == (line_p) 0) { - code->co_block->b_start = text; - PREV(text) = (line_p) 0; - } else { - l1->l_next = text; - PREV(text) = l1; - } - if (l2 != (line_p) 0) { - PREV(l2) = l; - } - l->l_next = l2; - code->co_llast->l_next = (line_p) 0; - /* Note that the old code is still accessible via code->co_lfirst */ -} - - - -STATIC init_code(code,tmp) - code_p code; - offset tmp; -{ - /* Generate code to set up the temporary local. - * For multiplication, its initial value is const*iv_expr, - * for array operations it is &a[iv_expr] (where iv_expr is - * an expression that is a linear function of the induc. var. - * This code is inserted immediately before the loop entry. - * As the initializing code looks very much like the - * reduced code, we reuse that (old) code. - */ - - line_p l, *p; - - l = code->co_llast; /* the mli, lar etc. instruction */ - switch(INSTR(l)) { - case op_mli: - case op_mlu: - /* reduced code is: iv_expr * lc (or lc * iv_expr) - * init_code is: tmp = iv_expr * lc (or lc*iv_expr) - * So we just insert a 'STL tmp'. - */ - l->l_next = int_line(tmp); - l->l_next->l_instr = op_stl; - break; - case op_lar: - case op_sar: - /* reduced code is: ...= A[iv_expr] resp. - * A[iv]_expr = .. - * init_code is: tmp = &A[iv_expr]. - * So just change the lar or sar into a aar ... - */ - l->l_instr = (byte) op_aar; - /* ... and fall through !! */ - case op_aar: - /* append code to store a pointer in temp. local */ - l->l_next = move_pointer(tmp,STORE); - break; - default: - assert(FALSE); /* non-reducible instruction */ - } - PREV(l->l_next) = l; - /* Now insert the code at the end of the header block */ - p = &code->co_loop->LP_INSTR; - if (*p == (line_p) 0) { - /* LP_INSTR points to last instruction of header block, - * so if it is 0, the header block is empty yet. - */ - code->co_loop->LP_HEADER->b_start = - code->co_lfirst; - } else { - (*p)->l_next = code->co_lfirst; - PREV(code->co_lfirst) = *p; - } - *p = l->l_next; /* new last instruction */ -} - - - -STATIC incr_code(code,tmp) - code_p code; - offset tmp; -{ - /* Generate code to increment the temporary local variable. - * The variable is incremented by - * 1) multiply --> step value of iv * loop constant - * 2) array --> step value of iv * element size - * This value can be determined statically. - * If the induction variable is used in a linear - * expression in which its sign is negative - * (such as in: "5-(6-(-iv))" ), this value is negated. - * The generated code looks like: - * LOL tmp ; LOC incr ; ADI ws ; STL tmp - * For pointer-increments we generate a "ADP c", rather than - * a "LOC c; ADS ws". - * This code is put just after the code that increments - * the induction variable. - */ - - line_p load_tmp, loc, add, store_tmp, l; - - add = newline(OPSHORT); - SHORT(add) = ws; /* the add instruction, can be ADI,ADU or ADS */ - switch(code->co_instr) { - case op_mli: - case op_mlu: - loc = int_line( - code->co_sign * - off_set(code->c_o.co_loadlc) * - code->co_iv->iv_step); - loc->l_instr = op_loc; - add->l_instr = op_adi; - load_tmp = int_line(tmp); - load_tmp->l_instr = op_lol; - store_tmp = int_line(tmp); - store_tmp->l_instr = op_stl; - break; - case op_lar: - case op_sar: - case op_aar: - loc = (line_p) 0; - add = int_line( - code->co_sign * - code->co_iv->iv_step * - elemsize(code->c_o.co_desc)); - add->l_instr = op_adp; - load_tmp = move_pointer(tmp,LOAD); - store_tmp = move_pointer(tmp,STORE); - break; - default: - assert(FALSE); - } - /* Now we've got pieces of code to load the temp. local, - * load the constant, add the two and store the result in - * the local. This code will be put just after the code that - * increments the induction variable. - */ - if (loc != (line_p) 0) concatenate(load_tmp,loc); - concatenate(load_tmp,add); - concatenate(load_tmp,store_tmp); - /* Now load_tmp points to a list of EM instructions */ - l = code->co_iv->iv_incr; - if (l->l_next != (line_p) 0) { - DLINK(store_tmp,l->l_next); - } - DLINK(l,load_tmp); /* doubly link them */ -} - - -STATIC remcode(c) - code_p c; -{ - line_p l, next; - - for (l = c->co_lfirst; l != (line_p) 0; l = next) { - next = l->l_next; - oldline(l); - } - oldcinfo(c); -} - - -STATIC bool same_address(l1,l2,vars) - line_p l1,l2; - lset vars; -{ - /* See if l1 and l2 load the same address */ - - if (INSTR(l1) != INSTR(l2)) return FALSE; - switch(INSTR(l1)) { - case op_lae: - return OBJ(l1) == OBJ(l2); - case op_lal: - return off_set(l1) == off_set(l2); - case op_lol: - return ps == ws && - off_set(l1) == off_set(l2) && - is_loopconst(l1,vars); - case op_ldl: - return ps == 2*ws && - off_set(l1) == off_set(l2) && - is_loopconst(l1,vars); - default: - return FALSE; - } -} - - -STATIC bool same_expr(lb1,le1,lb2,le2) - line_p lb1,le1,lb2,le2; -{ - /* See if the code from lb1 to le1 is the same - * expression as the code from lb2 to le2. - */ - - - register line_p l1,l2; - - l1 = lb1; - l2 = lb2; - for (;;) { - if (INSTR(l1) != INSTR(l2)) return FALSE; - switch(TYPE(l1)) { - case OPSHORT: - if (TYPE(l2) != OPSHORT || - SHORT(l1) != SHORT(l2)) return FALSE; - break; - case OPOFFSET: - if (TYPE(l2) != OPOFFSET || - OFFSET(l1) != OFFSET(l2)) return FALSE; - break; - case OPNO: - break; - default: - return FALSE; - } - if (l1 == le1 ) return l2 == le2; - if (l2 == le2) return FALSE; - l1 = l1->l_next; - l2 = l2->l_next; - } -} - -STATIC bool same_code(c1,c2,vars) - code_p c1,c2; - lset vars; -{ - /* See if c1 and c2 compute the same expression. Two array - * references can be the same even if one is e.g a fetch - * and the other a store. - */ - - switch(c1->co_instr) { - case op_mli: - return c1->co_instr == c2->co_instr && - off_set(c1->c_o.co_loadlc) == - off_set(c2->c_o.co_loadlc) && - same_expr(c1->co_ivexpr,c1->co_endexpr, - c2->co_ivexpr,c2->co_endexpr); - case op_aar: - case op_lar: - case op_sar: - return c2->co_instr != op_mli && - c2->co_instr != op_mlu && - same_expr(c1->co_ivexpr,c1->co_endexpr, - c2->co_ivexpr,c2->co_endexpr) && - same_address(c1->c_o.co_desc,c2->c_o.co_desc,vars) && - same_address(c1->co_lfirst,c2->co_lfirst,vars); - default: - assert(FALSE); - } - /* NOTREACHED */ -} - - -STATIC code_p available(c,vars) - code_p c; - lset vars; -{ - /* See if the code is already available. - * If so, return a pointer to the first occurrence - * of the code. - */ - - Lindex i; - code_p cp; - - for (i = Lfirst(avail); i != (Lindex) 0; i = Lnext(i,avail)) { - cp = (code_p) Lelem(i); - if (same_code(c,cp,vars)) { - return cp; - } - } - return (code_p) 0; -} - - - -STATIC reduce(code,vars) - code_p code; - lset vars; -{ - /* Perform the actual transformations. The code on the left - * gets transformed into the code on the right. Note that - * each piece of code is assigned a name, that will be - * used to describe the whole process. - * - * t = iv * 118; (init_code) - * do ---> do - * .. iv * 118 .. .. t .. (new_code) - * iv++; iv++; - * t += 118; (incr_code) - * od od - */ - - offset tmp; - code_p ac; - - OUTTRACE("succeeded!!",0); - if ((ac = available(code,vars)) != (code_p) 0) { - /* The expression is already available, so we - * don't have to generate a new temporary local for it. - */ - OUTTRACE("expression was already available",0); - replcode(code,newcode(code,ac->co_temp)); - remcode(code); - } else { - make_header(code->co_loop); - /* make sure there's a header block */ - tmp = tmplocal(curproc,(offset) code->co_tmpsize); - code->co_temp = tmp; - /* create a new local variable in the stack frame - * of current proc. - */ - gen_regmes(tmp,3,code,curproc); /* generate register message */ - /* score is set to 3, as TMP is used at least 3 times */ - replcode(code,newcode(code,tmp)); - OUTTRACE("replaced old code by new code",0); - /* Construct the EM-code that will replace the reducible code - * and replace the old code by the new code. - */ - init_code(code,tmp); - OUTTRACE("emitted initializing code",0); - /* Emit code to initialize the temporary local. This code is - * put in the loop header block. - */ - incr_code(code,tmp); /* emit code to increment temp. local */ - OUTTRACE("emitted increment code",0); - Ladd(code,&avail); - } -} - - - -STATIC try_multiply(lp,ivs,vars,b,mul) - loop_p lp; - lset ivs,vars; - bblock_p b; - line_p mul; -{ - /* See if we can reduce the strength of the multiply - * instruction. If so, then set up the global common - * data structure 'c' (containing information about the - * code to be reduced) and call 'reduce'. - */ - - line_p l2,lbegin; - iv_p iv; - code_p c; - int sign; - - VL(mul); - OUTTRACE("trying multiply instruction on line %d",linecount); - if (ovfl_harmful && !IS_STRONG(b)) return; - /* If b is not a strong block, optimization may - * introduce an overflow error in the initializing code. - */ - - l2 = PREV(mul); /* Instruction before the multiply */ - if ( (is_ivexpr(l2,ivs,vars,&lbegin,&iv,&sign)) && - is_const(PREV(lbegin)) ) { - /* recognized expression "const * iv_expr" */ - c = newcinfo(); - c->c_o.co_loadlc = PREV(l2); - c->co_endexpr = l2; - c->co_lfirst = PREV(lbegin); - } else { - if (is_const(l2) && - (is_ivexpr(PREV(l2),ivs,vars,&lbegin,&iv,&sign))) { - /* recognized "iv * const " */ - c = newcinfo(); - c->c_o.co_loadlc = l2; - c->co_endexpr = PREV(l2); - c->co_lfirst = lbegin; - } else { - OUTTRACE("failed",0); - return; - } - } - /* common part for both patterns */ - c->co_iv = iv; - c->co_loop = lp; - c->co_block = b; - c->co_llast = mul; - c->co_ivexpr = lbegin; - c->co_sign = sign; - c->co_tmpsize = ws; /* temp. local is a word */ - c->co_instr = INSTR(mul); - OUTVERBOSE("sr: multiply in proc %d loop %d", - curproc->p_id, lp->lp_id); - Ssr++; - reduce(c,vars); -} - - - -STATIC try_array(lp,ivs,vars,b,arr) - loop_p lp; - lset ivs,vars; - bblock_p b; - line_p arr; -{ - /* See if we can reduce the strength of the array reference - * instruction 'arr'. - */ - - line_p l2,l3,lbegin; - iv_p iv; - code_p c; - int sign; - - /* Try to recognize the pattern: - * LOAD ADDRES OF A - * LOAD IV - * LOAD ADDRESS OF DESCRIPTOR - */ - VL(arr); - OUTTRACE("trying array instruction on line %d",linecount); - if (arrbound_harmful && !IS_STRONG(b)) return; - /* If b is not a strong block, optimization may - * introduce an array bound error in the initializing code. - */ - l2 = PREV(arr); - if (is_caddress(l2,vars) && - (INSTR(arr) == op_aar || elemsize(l2) == ws) && - (is_ivexpr(PREV(l2),ivs,vars,&lbegin,&iv,&sign)) ) { - l3 = PREV(lbegin); - if (is_caddress(l3,vars)) { - c = newcinfo(); - c->co_iv = iv; - c->co_loop = lp; - c->co_block = b; - c->co_lfirst = l3; - c->co_llast = arr; - c->co_ivexpr = lbegin; - c->co_endexpr = PREV(l2); - c->co_sign = sign; - c->co_tmpsize = ps; /* temp. local is pointer */ - c->co_instr = INSTR(arr); - c->c_o.co_desc = l2; - OUTVERBOSE("sr: array in proc %d loop %d", - curproc->p_id,lp->lp_id); - Ssr++; - reduce(c,vars); - } - } -} - - - -STATIC clean_avail() -{ - Lindex i; - - for (i = Lfirst(avail); i != (Lindex) 0; i = Lnext(i,avail)) { - oldcinfo(Lelem(i)); - } - Ldeleteset(avail); -} - - - -strength_reduction(lp,ivs,vars) - loop_p lp; /* description of the loop */ - lset ivs; /* set of induction variables of the loop */ - lset vars; /* set of local variables changed in loop */ -{ - /* Find all expensive instructions (multiply, array) and see if - * they can be reduced. We branch to several instruction-specific - * routines (try_...) that check if reduction is possible, - * and that set up a common data structure (code_info). - * The actual transformations are done by 'reduce', that is - * essentially instruction-independend. - */ - - bblock_p b; - line_p l, next; - Lindex i; - - avail = Lempty_set(); - for (i = Lfirst(lp->LP_BLOCKS); i != (Lindex) 0; - i = Lnext(i,lp->LP_BLOCKS)) { - b = (bblock_p) Lelem(i); - for (l = b->b_start; l != (line_p) 0; l = next) { - next = l->l_next; - if (TYPE(l) == OPSHORT && SHORT(l) == ws) { - switch(INSTR(l)) { - case op_mlu: - case op_mli: - try_multiply(lp,ivs,vars,b,l); - break; - case op_lar: - case op_sar: - case op_aar: - try_array(lp,ivs,vars,b,l); - break; - } - } - } - } - clean_avail(); -} diff --git a/util/ego/sr/sr_reduce.h b/util/ego/sr/sr_reduce.h deleted file mode 100644 index 794f68f11..000000000 --- a/util/ego/sr/sr_reduce.h +++ /dev/null @@ -1,5 +0,0 @@ -/* S R _ R E D U C E . H */ - -extern strength_reduction(); /* (loop_p loop; lset ivs, vars) - * Perform streength reduction. - */ diff --git a/util/ego/sr/sr_xform.c b/util/ego/sr/sr_xform.c deleted file mode 100644 index e36f95ed2..000000000 --- a/util/ego/sr/sr_xform.c +++ /dev/null @@ -1,178 +0,0 @@ -/* S T R E N G T H R E D U C T I O N - * - * S R _ X F O R M . C - * - */ - - - -#include -#include "../share/types.h" -#include "sr.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/alloc.h" -#include "../share/def.h" -#include "../share/get.h" -#include "sr_aux.h" -#include "../share/lset.h" -#include "../share/aux.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" -#include "sr_xform.h" - -/* Transformations on EM texts */ - -line_p move_pointer(tmp,dir) - offset tmp; - int dir; -{ - /* Generate EM code to load/store a pointer variable - * onto/from the stack, depending on dir(ection). - * We accept all kinds of pointer sizes. - */ - - line_p l; - - l = int_line(tmp); - if (ps == ws) { - /* pointer fits in a word */ - l->l_instr = (dir == LOAD ? op_lol : op_stl); - } else { - if (ps == 2 * ws) { - /* pointer fits in a double word */ - l->l_instr = (dir == LOAD ? op_ldl : op_sdl); - } else { - /* very large pointer size, generate code: - * LAL tmp ; LOI/STI ps */ - l->l_instr = op_lal; - l->l_next = newline(OPSHORT); - SHORT(l->l_next) = ps; - l->l_next->l_instr = - (dir == LOAD ? op_loi : op_sti); - PREV(l->l_next) = l; - } - } - return l; -} - - - -/* make_header */ - -STATIC copy_loops(b1,b2,except) - bblock_p b1,b2; - loop_p except; -{ - /* Copy the loopset of b2 to b1, except for 'except' */ - - Lindex i; - loop_p lp; - for (i = Lfirst(b2->b_loops); i != (Lindex) 0; - i = Lnext(i,b2->b_loops)) { - lp = (loop_p) Lelem(i); - if (lp != except) { - Ladd(lp,&b1->b_loops); - } - } -} - - -STATIC lab_id label(b) - bblock_p b; -{ - /* Find the label at the head of block b. If there is - * no such label yet, create one. - */ - - line_p l; - - assert (b->b_start != (line_p) 0); - if (INSTR(b->b_start) == op_lab) return INSTRLAB(b->b_start); - /* The block has no label yet. */ - l = newline(OPINSTRLAB); - INSTRLAB(l) = freshlabel(); - DLINK(l,b->b_start); /* doubly link them */ - return INSTRLAB(l); -} - - -STATIC adjust_jump(newtarg,oldtarg,c) - bblock_p newtarg,oldtarg,c; -{ - /* If the last instruction of c is a jump to the - * old target, then change it into a jump to the - * start of the new target. - */ - - line_p l; - - if (INSTR(oldtarg->b_start) == op_lab) { - /* If old target has no label, it cannot be jumped to */ - l = last_instr(c); - assert(l != (line_p) 0); - if (TYPE(l) == OPINSTRLAB && - INSTRLAB(l) == INSTRLAB(oldtarg->b_start)) { - INSTRLAB(l) = label(newtarg); - } - } -} - - -make_header(lp) - loop_p lp; -{ - /* Make sure that the loop has a header block, i.e. a block - * has the loop entry block as its only successor and - * that dominates the loop entry block. - * If there is no header yet, create one. - */ - - bblock_p b,c,entry; - Lindex i,next; - - if (lp->LP_HEADER != (bblock_p) 0) return; - OUTTRACE("creating a new header block",0); - /* The loop has no header yet. The main problem is to - * keep all relations (SUCC, PRED, NEXT, IDOM, LOOPS) - * up to date. - */ - b = freshblock(); /* new block with new b_id */ - entry = lp->lp_entry; - - /* update succ/pred. Also take care that any jump from outside - * the loop to the entry block now goes to b. - */ - - for (i = Lfirst(entry->b_pred); i != (Lindex) 0; i = next ) { - next = Lnext(i,entry->b_pred); - c = (bblock_p) Lelem(i); - /* c is a predecessor of the entry block */ - if (!Lis_elem(c,lp->LP_BLOCKS)) { - /* c is outside the loop */ - Lremove(c,&entry->b_pred); - Lremove(entry,&c->b_succ); - Ladd(b,&c->b_succ); - adjust_jump(b,entry,c); - } - } - Ladd(b,&entry->b_pred); - b->b_succ = Lempty_set(); - b->b_pred = Lempty_set(); - Ladd(entry,&b->b_succ); - if (curproc->p_start == entry) { - /* entry was the first block of curproc */ - curproc->p_start = b; - } else { - /* find block before entry block */ - for (c = curproc->p_start; c->b_next != entry; c = c->b_next); - c->b_next = b; - Ladd(c,&b->b_pred); - } - b->b_next = entry; - copy_loops(b,entry,lp); - b->b_idom = entry->b_idom; - entry->b_idom = b; - lp->LP_HEADER = b; -} diff --git a/util/ego/sr/sr_xform.h b/util/ego/sr/sr_xform.h deleted file mode 100644 index 8ea103be8..000000000 --- a/util/ego/sr/sr_xform.h +++ /dev/null @@ -1,19 +0,0 @@ -/* S T R E N G T H R E D U C T I O N - * - * S R _ X F O R M . H - * - */ - - - -line_p move_pointer(); /* (offset tmp; int dir ) */ - /* Generate EM code to load/store a pointer variable - * onto/from the stack, depending on dir(ection). - * We accept all kinds of pointer sizes. - */ -make_header() ; /* (loop_p lp) */ - /* Make sure that the loop has a header block, i.e. a block - * has the loop entry block as its only successor and - * that dominates the loop entry block. - * If there is no header yet, create one. - */ diff --git a/util/ego/ud/Makefile b/util/ego/ud/Makefile deleted file mode 100644 index 54fdbf1d9..000000000 --- a/util/ego/ud/Makefile +++ /dev/null @@ -1,122 +0,0 @@ -EMH=../../../h -EMLIB=../../../lib -SHR=../share - -CFILES=\ -ud.c ud_defs.c ud_const.c ud_copy.c ud_aux.c - -OFILES=\ -ud.o ud_const.o ud_copy.o ud_aux.o ud_defs.o - -HFILES=\ -ud.h ud_defs.h ud_const.h ud_copy.h ud_aux.h - -PRFILES=\ -$(CFILES) $(HFILES) Makefile - -SHARE_OFILES=\ -$(SHR)/get.o $(SHR)/put.o $(SHR)/map.o $(SHR)/alloc.o $(SHR)/global.o \ -$(SHR)/debug.o $(SHR)/lset.o $(SHR)/cset.o $(SHR)/files.o $(SHR)/aux.o \ -$(SHR)/locals.o $(SHR)/init_glob.o $(SHR)/go.o - -SHARE_MFILES=\ -$(SHR)/get.m $(SHR)/put.m $(SHR)/map.m $(SHR)/alloc.m $(SHR)/global.m \ -$(SHR)/debug.m $(SHR)/lset.m $(SHR)/cset.m $(SHR)/files.m $(SHR)/aux.m \ -$(SHR)/locals.m $(SHR)/init_glob.m $(SHR)/go.m - -ud: $(OFILES) - $(CC) -o ud $(LDFLAGS) $(OFILES) $(SHARE_OFILES) $(EMLIB)/em_data.a - -ud_ack: $(CFILES) $(SHARE_MFILES) - $(CC) -c.o $(CFLAGS) $(CFILES) $(SHARE_MFILES) - $(CC) -o ud -.c $(LDFLAGS) ud.o $(EMLIB)/em_data.a - -lint: - lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) - -pr: $(PRFILES) - @pr $? - @touch pr - -depend: - $(SHR)/makedepend - -# the next lines are generated automatically -# AUTOAUTOAUTOAUTOAUTOAUTO - -ud.o: ../../../h/em_pseu.h -ud.o: ../../../h/em_spec.h -ud.o: ../share/alloc.h -ud.o: ../share/aux.h -ud.o: ../share/cset.h -ud.o: ../share/debug.h -ud.o: ../share/def.h -ud.o: ../share/files.h -ud.o: ../share/get.h -ud.o: ../share/global.h -ud.o: ../share/locals.h -ud.o: ../share/lset.h -ud.o: ../share/map.h -ud.o: ../share/put.h -ud.o: ../share/types.h -ud.o: ud.h -ud.o: ud_const.h -ud.o: ud_copy.h -ud.o: ud_defs.h -ud_aux.o: ../../../h/em_mnem.h -ud_aux.o: ../../../h/em_pseu.h -ud_aux.o: ../../../h/em_spec.h -ud_aux.o: ../share/alloc.h -ud_aux.o: ../share/cset.h -ud_aux.o: ../share/debug.h -ud_aux.o: ../share/def.h -ud_aux.o: ../share/global.h -ud_aux.o: ../share/locals.h -ud_aux.o: ../share/lset.h -ud_aux.o: ../share/types.h -ud_aux.o: ../ud/ud.h -ud_aux.o: ../ud/ud_defs.h -ud_const.o: ../../../h/em_mnem.h -ud_const.o: ../../../h/em_pseu.h -ud_const.o: ../../../h/em_spec.h -ud_const.o: ../share/alloc.h -ud_const.o: ../share/aux.h -ud_const.o: ../share/cset.h -ud_const.o: ../share/debug.h -ud_const.o: ../share/def.h -ud_const.o: ../share/global.h -ud_const.o: ../share/locals.h -ud_const.o: ../share/lset.h -ud_const.o: ../share/types.h -ud_const.o: ../ud/ud.h -ud_const.o: ../ud/ud_defs.h -ud_const.o: ud_aux.h -ud_const.o: ud_const.h -ud_copy.o: ../../../h/em_mnem.h -ud_copy.o: ../../../h/em_pseu.h -ud_copy.o: ../../../h/em_spec.h -ud_copy.o: ../share/alloc.h -ud_copy.o: ../share/aux.h -ud_copy.o: ../share/cset.h -ud_copy.o: ../share/debug.h -ud_copy.o: ../share/def.h -ud_copy.o: ../share/global.h -ud_copy.o: ../share/locals.h -ud_copy.o: ../share/lset.h -ud_copy.o: ../share/types.h -ud_copy.o: ../ud/ud.h -ud_copy.o: ../ud/ud_defs.h -ud_copy.o: ud_aux.h -ud_copy.o: ud_copy.h -ud_defs.o: ../../../h/em_mnem.h -ud_defs.o: ../share/alloc.h -ud_defs.o: ../share/aux.h -ud_defs.o: ../share/cset.h -ud_defs.o: ../share/debug.h -ud_defs.o: ../share/global.h -ud_defs.o: ../share/locals.h -ud_defs.o: ../share/lset.h -ud_defs.o: ../share/map.h -ud_defs.o: ../share/types.h -ud_defs.o: ud.h -ud_defs.o: ud_defs.h diff --git a/util/ego/ud/ud.c b/util/ego/ud/ud.c deleted file mode 100644 index 7616a5e68..000000000 --- a/util/ego/ud/ud.c +++ /dev/null @@ -1,557 +0,0 @@ -/* U S E - D E F I N I T I O N A N A L Y S I S */ - -#include -#include "../share/types.h" -#include "ud.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/def.h" -#include "../share/files.h" -#include "../share/map.h" -#include "../share/get.h" -#include "../share/put.h" -#include "../share/alloc.h" -#include "../share/aux.h" -#include "../share/init_glob.h" -#include "../share/locals.h" -#include "../share/go.h" -#include "../../../h/em_spec.h" -#include "ud_defs.h" -#include "ud_const.h" -#include "ud_copy.h" - -/* core allocation macros */ -#define newudbx() (bext_p) newstruct(bext_ud) -#define oldudbx(x) oldstruct(bext_ud,x) - -short nrglobals; -short nrvars; - -int Svalue,Svariable; - -cond_p globl_cond_tab,local_cond_tab; - -STATIC cond_p getcondtab(f) - FILE *f; -{ - int l,i; - cond_p tab; - - fscanf(f,"%d",&l); - tab = newcondtab(l); - for (i = 0; i < l; i++) { - fscanf(f,"%hd %hd %hd",&tab[i].mc_cond,&tab[i].mc_tval, - &tab[i].mc_sval); - } - assert(tab[l-1].mc_cond == DEFAULT); - return tab; -} - - -STATIC ud_machinit(f) - FILE *f; -{ - char s[100]; - - for (;;) { - while(getc(f) != '\n'); - fscanf(f,"%s",s); - if (strcmp(s,"%%UD") == 0)break; - } - globl_cond_tab = getcondtab(f); - local_cond_tab = getcondtab(f); -} - - - -STATIC bool test_cond(cond,val) - short cond; - offset val; -{ - switch(cond) { - case DEFAULT: - return TRUE; - case FITBYTE: - return val >= -128 && val < 128; - } - assert(FALSE); - /* NOTREACHED */ -} - - -STATIC short map_value(tab,val,time) - struct cond_tab tab[]; - offset val; - bool time; -{ - cond_p p; - - for (p = &tab[0]; ; p++) { - if (test_cond(p->mc_cond,val)) { - return (time ? p->mc_tval : p->mc_sval); - } - } -} - - -STATIC init_root(root) - bblock_p root; -{ - /* Initialise the IN OUT sets of the entry block of the - * current procedure. Global variables and parameters - * already have a value at this point, although we do - * not know which value. Therefor, implicit definitions - * to all global variables and parameters are - * put in IN. - */ - - short v; - - for (v = 1; v <= nrglobals; v++) { - Cadd(IMPLICIT_DEF(GLOB_TO_VARNR(v)), &IN(root)); - } - for (v = 1; v <= nrlocals; v++) { - if (locals[v]->lc_off >= 0) { - Cadd(IMPLICIT_DEF(LOC_TO_VARNR(v)),&IN(root)); - } - } - /* OUT(root) = IN(root) - KILL(root) + GEN(root) */ - Ccopy_set(IN(root),&OUT(root)); - Csubtract(KILL(root),&OUT(root)); - Cjoin(GEN(root),&OUT(root)); -} - - - - -STATIC unite_outs(bbset,setp) - lset bbset; - cset *setp; -{ - /* Take the union of OUT(b), for all b in bbset, - * and put the result in setp. - */ - - Lindex i; - - Cclear_set(setp); - for (i = Lfirst(bbset); i != (Lindex) 0; i = Lnext(i,bbset)) { - Cjoin(OUT((bblock_p) Lelem(i)), setp); - } -} - - - -STATIC solve_equations(p) - proc_p p; -{ - /* Solve the data flow equations for reaching - * definitions of procedure p. - * These equations are: - * (1) OUT(b) = IN(b) - KILL(b) + GEN(b) - * (2) IN(b) = OUT(p1) + .. + OUT(pn) ; - * where PRED(b) = {p1, .. , pn} - * We use the iterative algorithm of Aho&Ullman to - * solve the equations. - */ - - register bblock_p b; - bool change; - cset newin; - - /* initializations */ - newin = Cempty_set(nrdefs); - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - IN(b) = Cempty_set(nrdefs); - OUT(b) = Cempty_set(nrdefs); - Ccopy_set(GEN(b), &OUT(b)); - } - init_root(p->p_start); - /* Global variables and parameters have already a value - * at the procedure entry block. - */ - change = TRUE; - /* main loop */ - while (change) { - change = FALSE; - for (b = p->p_start->b_next; b != (bblock_p) 0; b = b->b_next) { - unite_outs(b->b_pred, &newin); - /* newin = OUT(p1) + .. + OUT(pn) */ - if (!Cequal(newin,IN(b))) { - change = TRUE; - Ccopy_set(newin, &IN(b)); - Ccopy_set(IN(b), &OUT(b)); - Csubtract(KILL(b), &OUT(b)); - Cjoin(GEN(b), &OUT(b)); - } - } - } - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - Cdeleteset(KILL(b)); - Cdeleteset(OUT(b)); - } - Cdeleteset(newin); -} - - - -short global_addr_cost() -{ - return add_timespace(map_value(globl_cond_tab,(offset) 0,TRUE), - map_value(globl_cond_tab,(offset) 0,FALSE)); -} - -short local_addr_cost(off) - offset off; -{ - return add_timespace(map_value(local_cond_tab,off,TRUE), - map_value(local_cond_tab,off,FALSE)); -} - - - -STATIC bool fold_is_desirable(old,new) - line_p old,new; -{ - /* See if it is desirable to replace the variable used by the - * EM instruction 'old' by the variable used by 'new'. - * We do not replace 'cheaply addressable variables' by 'expensively - * addressable variables'. E.g. if we're optimizing object code size, - * we do not replace a local variable by a global variable on a VAX, - * because the former occupies 1 or 2 bytes and the latter occupies - * 4 bytes. - * If 2 local variables are equally expensive to address, we replace - * the first one by the second only if the first one is used at - * least as many times as the second one. - */ - - local_p oldloc,newloc; - short old_cost,new_cost,nr; - bool ok; - - if (TYPE(old) == OPOBJECT) { - /* old variable is a global variable */ - return TYPE(new) != OPOBJECT && - global_addr_cost() >= - local_addr_cost(off_set(new)); - } - find_local(off_set(old),&nr,&ok); - assert(ok); - oldloc = locals[nr]; - old_cost = local_addr_cost(off_set(old)); - if (TYPE(new) == OPOBJECT) { - return oldloc->lc_score == 2 || /* old var. can be eliminated */ - old_cost > global_addr_cost(); - } - find_local(off_set(new),&nr,&ok); - assert(ok); - newloc = locals[nr]; - new_cost = local_addr_cost(off_set(new)); - return old_cost > new_cost || - (old_cost == new_cost && oldloc->lc_score < newloc->lc_score); -} - - - -#ifdef TRACE -/*********** TRACING ROUTINES ***********/ - -pr_localtab() { - short i; - local_p lc; - - printf("LOCAL-TABLE (%d)\n\n",nrlocals); - for (i = 1; i <= nrlocals; i++) { - lc = locals[i]; - printf("LOCAL %d\n",i); - printf(" offset= %D\n",lc->lc_off); - printf(" size= %d\n",lc->lc_size); - printf(" flags= %d\n",lc->lc_flags); - } -} - -pr_globals() -{ - dblock_p d; - obj_p obj; - - printf("GLOBALS (%d)\n\n",nrglobals); - printf("ID GLOBNR\n"); - for (d = fdblock; d != (dblock_p) 0; d = d->d_next) { - for (obj = d->d_objlist; obj != (obj_p) 0; obj = obj->o_next) { - if (obj->o_globnr != 0) { - printf("%d %d\n", obj->o_id,obj->o_globnr); - } - } - } -} - -extern char em_mnem[]; - -pr_defs() -{ - short i; - line_p l; - - printf("DEF TABLE\n\n"); - for (i = 1; i <= nrexpldefs; i++) { - l = defs[i]; - printf("%d %s ",EXPL_TO_DEFNR(i), - &em_mnem[(INSTR(l)-sp_fmnem)*4]); - switch(TYPE(l)) { - case OPSHORT: - printf("%d\n",SHORT(l)); - break; - case OPOFFSET: - printf("%D\n",OFFSET(l)); - break; - case OPOBJECT: - printf("%d\n",OBJ(l)->o_id); - break; - default: - assert(FALSE); - } - } -} - - -pr_set(name,k,s,n) - char *name; - cset s; - short k,n; -{ - short i; - - printf("%s(%d) = {",name,k); - for (i = 1; i <= n; i++) { - if (Cis_elem(i,s)) { - printf("%d ",i); - } - } - printf ("}\n"); -} - -pr_blocks(p) - proc_p p; -{ - bblock_p b; - short n; - - for (b = p->p_start; b != 0; b = b->b_next) { - printf ("\n"); - n = b->b_id; - pr_set("GEN",n,GEN(b),nrdefs); - pr_set("KILL",n,KILL(b),nrdefs); - pr_set("IN ",n,IN(b),nrdefs); - pr_set("OUT",n,OUT(b),nrdefs); - pr_set("CHGVARS",n,CHGVARS(b),nrvars); - } -} - -pr_copies() -{ - short i; - - printf("\nCOPY TABLE\n\n"); - for (i = 1; i <= nrdefs; i++) { - if (def_to_copynr[i] != 0) { - printf("%d %d\n",i,def_to_copynr[i]); - } - } -} - -pr_cblocks(p) - proc_p p; -{ - bblock_p b; - short n; - - for (b = p->p_start; b != 0; b = b->b_next) { - printf ("\n"); - n = b->b_id; - pr_set("CGEN",n,C_GEN(b),nrcopies); - pr_set("CKILL",n,C_KILL(b),nrcopies); - pr_set("CIN ",n,C_IN(b),nrcopies); - pr_set("COUT",n,C_OUT(b),nrcopies); - } -} - -/*********** END TRACING ********/ - -#endif - -STATIC ud_analysis(p) - proc_p p; -{ - /* Perform use-definition analysis on procedure p */ - - make_localtab(p); /* See for which local we'll keep ud-info */ -#ifdef TRACE - pr_localtab(); -#endif - nrvars = nrglobals + nrlocals; - make_defs(p); /* Make a table of all useful definitions in p */ -#ifdef TRACE - pr_defs(); -#endif - nrdefs = nrexpldefs + nrvars; /* number of definitions */ - gen_sets(p); /* compute GEN(b), for every basic block b */ - kill_sets(p); /* compute KILL(b), for every basic block b */ - solve_equations(p); /* solve data flow equations for p */ -#ifdef TRACE - pr_blocks(p); -#endif -} - - - -STATIC clean_maps() -{ - local_p *p; - cset *v; - - oldmap(defs,nrexpldefs); - for (p = &locals[1]; p <= &locals[nrlocals]; p++) { - oldlocal(*p); - } - oldmap(locals,nrlocals); - for (v = &vardefs[1]; v <= &vardefs[nrvars]; v++) { - Cdeleteset(*v); - } - oldmap(vardefs,nrvars); -} - - - -STATIC bool try_optim(l,b) - line_p l; - bblock_p b; -{ - /* Try copy propagation and constant propagation */ - - line_p def; - offset val; - short defnr; - - - if (is_use(l) && (def = unique_def(l,b,&defnr)) != (line_p) 0) { - if (is_copy(def)) { - if (value_retained(def,defnr,l,b) && - fold_is_desirable(l,PREV(def))) { - fold_var(l,PREV(def),b); - OUTVERBOSE("vp:variable folded in proc %d", - curproc->p_id,0); - Svariable++; - return TRUE; - } - } else { - if (value_known(def,&val)) { - fold_const(l,b,val); - OUTVERBOSE("vp:value folded in proc %d", - curproc->p_id,0); - Svalue++; - return TRUE; - } - } - } - return FALSE; -} - - - -value_propagation(p) - proc_p p; -{ - /* Apply value propagation to procedure p */ - - bool changes; - bblock_p b; - line_p l, next; - - changes = TRUE; - /* If a statement like A := B is folded to A := constant, - * new opportunities for constant folding may arise, - * e.g. the value of A might be statically known too now. - */ - - while (changes) { - changes = FALSE; - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (l = b->b_start; l != (line_p) 0; l = next) { - next = l->l_next; - if (try_optim(l,b)) { - changes = TRUE; - } - } - } - } - oldmap(copies,nrcopies); - oldtable(def_to_copynr,nrdefs); -} - - -STATIC ud_extend(p) - proc_p p; -{ - /* Allocate extended data structures for Use Definition analysis */ - - register bblock_p b; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - b->b_extend = newudbx(); - } -} - - -STATIC ud_cleanup(p) - proc_p p; -{ - /* Deallocate extended data structures for Use Definition analysis */ - - register bblock_p b; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - Cdeleteset(GEN(b)); - Cdeleteset(IN(b)); - Cdeleteset(C_GEN(b)); - Cdeleteset(C_KILL(b)); - Cdeleteset(C_IN(b)); - Cdeleteset(C_OUT(b)); - Cdeleteset(CHGVARS(b)); - oldudbx(b->b_extend); - } -} - - -ud_optimize(p) - proc_p p; -{ - ud_extend(p); - locals = (local_p *) 0; - vardefs = (cset *) 0; - defs = (line_p *) 0; - ud_analysis(p); - copy_analysis(p); -#ifdef TRACE - pr_copies(); - pr_cblocks(p); -#endif - value_propagation(p); - ud_cleanup(p); - clean_maps(); -} - -main(argc,argv) - int argc; - char *argv[]; -{ - go(argc,argv,init_globals,ud_optimize,ud_machinit,no_action); - report("values folded",Svalue); - report("variables folded",Svariable); - exit(0); -} - - - diff --git a/util/ego/ud/ud.h b/util/ego/ud/ud.h deleted file mode 100644 index 34368ca8c..000000000 --- a/util/ego/ud/ud.h +++ /dev/null @@ -1,21 +0,0 @@ -/* U S E - D E F I N I T I O N A N A L Y S I S - * - * U D . H - */ - -#define GEN(b) (b)->b_extend->bx_ud.bx_gen -#define KILL(b) (b)->b_extend->bx_ud.bx_kill -#define IN(b) (b)->b_extend->bx_ud.bx_in -#define OUT(b) (b)->b_extend->bx_ud.bx_out -#define C_GEN(b) (b)->b_extend->bx_ud.bx_cgen -#define C_KILL(b) (b)->b_extend->bx_ud.bx_ckill -#define C_IN(b) (b)->b_extend->bx_ud.bx_cin -#define C_OUT(b) (b)->b_extend->bx_ud.bx_cout -#define CHGVARS(b) (b)->b_extend->bx_ud.bx_chgvars - -extern short nrglobals; /* number of global variables for which - * ud-info is maintained. - */ -extern short nrvars; /* total number of variables (global + local) - * for which ud-info is maintained. - */ diff --git a/util/ego/ud/ud_aux.c b/util/ego/ud/ud_aux.c deleted file mode 100644 index 20e5a169b..000000000 --- a/util/ego/ud/ud_aux.c +++ /dev/null @@ -1,55 +0,0 @@ -/* C O P Y P R O P A G A T I O N - * - * A U X I L I A R Y R O U T I N E S - */ - - -#include "../share/types.h" -#include "../ud/ud.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/alloc.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/def.h" -#include "../share/locals.h" -#include "../share/aux.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" -#include "../ud/ud_defs.h" - -repl_line(old,new,b) - line_p old,new; - bblock_p b; -{ - /* Replace 'old' by 'new' */ - - if (PREV(old) == (line_p) 0) { - b->b_start = new; - } else { - PREV(old)->l_next = new; - } - PREV(new) = PREV(old); - if ((new->l_next = old->l_next) != (line_p) 0) { - PREV(new->l_next) = new; - } - oldline(old); -} - - - -bool same_var(use,def) - line_p use,def; -{ - /* 'use' is an instruction that uses a variable - * for which we maintain ud-info (e.g. a LOL). - * See if 'def' references the same variable. - */ - - if (TYPE(use) == OPOBJECT) { - return TYPE(def) == OPOBJECT && OBJ(use) == OBJ(def); - } else { - return TYPE(def) != OPOBJECT && off_set(use) == off_set(def); - } -} diff --git a/util/ego/ud/ud_aux.h b/util/ego/ud/ud_aux.h deleted file mode 100644 index 8c3a55455..000000000 --- a/util/ego/ud/ud_aux.h +++ /dev/null @@ -1,17 +0,0 @@ - -/* C O P Y P R O P A G A T I O N - * - * A U X I L I A R Y R O U T I N E S - */ - - -extern repl_line(); /* (line_p old,new; bblock_p b) - * Replace EM instruction 'old' by a - * copy of 'new'. Update doubly-linked - * list. - */ -extern bool same_var(); /* (line_p use,def) - * 'use' is an instruction that uses a variable - * for which we maintain ud-info (e.g. a LOL). - * See if 'def' references the same variable. - */ diff --git a/util/ego/ud/ud_const.c b/util/ego/ud/ud_const.c deleted file mode 100644 index 26420321c..000000000 --- a/util/ego/ud/ud_const.c +++ /dev/null @@ -1,246 +0,0 @@ -/* C O N S T A N T P R O P A G A T I O N */ - -#include "../share/types.h" -#include "../ud/ud.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/alloc.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/def.h" -#include "../share/aux.h" -#include "../share/locals.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" -#include "../ud/ud_defs.h" -#include "ud_const.h" -#include "ud_aux.h" - - -#define CHANGE_INDIR(p) (p->p_change->c_flags & CF_INDIR) -#define IS_REG(v) (locals[TO_LOCAL(v)]->lc_flags & LCF_REG) -#define BODY_KNOWN(p) (p->p_flags1 & (byte) PF_BODYSEEN) -#define CALLS_UNKNOWN(p) (p->p_flags1 & (byte) PF_CALUNKNOWN) - - -bool is_use(l) - line_p l; -{ - /* See if 'l' is a use of a variable */ - - switch(INSTR(l)) { - case op_lde: - case op_ldl: - case op_loe: - case op_lol: - return TRUE; - default: - return FALSE; - } - /* NOTREACHED */ -} - - - - -bool value_known(def,val_out) - line_p def; - offset *val_out; -{ - /* See if the value stored by definition 'def' - * is known statically (i.e. is a constant). - */ - - short sz1, sz2; - offset v; - line_p l; - - sz1 = ws; - switch(INSTR(def)) { - case op_inl: - case op_ine: - case op_del: - case op_dee: - return FALSE; - case op_zrl: - case op_zre: - v = (offset) 0; - break; - case op_sdl: - case op_sde: - sz1 += ws; - /* fall through ... */ - case op_stl: - case op_ste: - l = PREV(def); - if (l == (line_p) 0) return FALSE; - sz2 = ws; - switch(INSTR(l)) { - case op_zer: - if (SHORT(l) >= sz1) { - v = (offset) 0; - break; - } - return FALSE; - case op_ldc: - sz2 += ws; - /* fall through ...*/ - case op_loc: - if (sz1 == sz2) { - v = off_set(l); - break; - } - /* fall through ... */ - default: - return FALSE; - } - break; - default: - assert(FALSE); - } - *val_out = v; - return TRUE; -} - - - - -bool affected(use,v,l) - line_p use,l; - short v; -{ - /* See if the variable referenced by 'use' may be - * changed by instruction l, which is either a cal, cai or - * an indirect assignment. - */ - - if (INSTR(l) == op_cal && - TYPE(use) == OPOBJECT && - BODY_KNOWN(PROC(l)) && - !CALLS_UNKNOWN(PROC(l)) && - !CHANGE_INDIR(PROC(l))) { - return Cis_elem(OBJ(use)->o_id,PROC(l)->p_change->c_ext); - } - return TYPE(use) == OPOBJECT || !IS_REG(v); -} - - - - -STATIC search_backwards(use,v,found,def) - line_p use, *def; - short v; - bool *found; -{ - /* Search backwards in the current basic block, - * starting at 'use', trying to find a definition - * of the variable referenced by 'use', whose variable - * number is v. If the definition found is an - * implicit one, return 0 as def. - */ - - register line_p l; - - for (l = PREV(use); l != (line_p) 0; l = PREV(l)) { - if (does_expl_def(l) && same_var(use,l)) { - *found = TRUE; - *def = l; - return; - } - if (does_impl_def(l) && affected(use,v,l)) { - *found = TRUE; - *def = (line_p) 0; - return; - } - } - *found = FALSE; -} - - - - -STATIC short outer_def(vdefs,in) - cset vdefs, in; -{ - /* See if there is a unique definition of variable - * v reaching the beginning of block b. - * 'vdefs' is vardefs[v], 'in' is IN(b). - */ - - short n,defnr = 0; - Cindex i; - - for (i = Cfirst(vdefs); i != (Cindex) 0; i = Cnext(i,vdefs)) { - n = Celem(i); - if (Cis_elem(EXPL_TO_DEFNR(n),in)) { - if (defnr != 0) return 0; - /* If there was already a def., there's no unique one */ - defnr = n; - } - } - return defnr; -} - - - - -line_p unique_def(use,b,defnr_out) - line_p use; - bblock_p b; - short *defnr_out; -{ - /* See if there is one unique explicit definition - * of the variable used by 'use', that reaches 'use'. - */ - - short v; - bool found; - line_p def = (line_p) 0; - - *defnr_out = 0; - var_nr(use,&v,&found); - if (found) { - /* We do maintain ud-info for this variable. - * See if there is a previous explicit definition - * in the current basic block. - */ - search_backwards(use,v,&found,&def); - if (!found && !Cis_elem(IMPLICIT_DEF(v),IN(b))) { - /* See if there is a unique explicit definition - * outside the current block, reaching the - * beginning of the current block. - */ - *defnr_out = outer_def(vardefs[v],IN(b)); - def = (*defnr_out == 0 ? (line_p) 0 : defs[*defnr_out]); - } - } - return def; -} - - - -fold_const(l,b,val) - line_p l; - bblock_p b; - offset val; -{ - /* Perform the substitutions required for constant folding */ - - line_p n; - - n = int_line(val); - switch(INSTR(l)) { - case op_lol: - case op_loe: - n->l_instr = op_loc; - break; - case op_ldl: - case op_lde: - n->l_instr = op_ldc; - break; - default: - assert (FALSE); - } - repl_line(l,n,b); -} diff --git a/util/ego/ud/ud_const.h b/util/ego/ud/ud_const.h deleted file mode 100644 index 237e4a516..000000000 --- a/util/ego/ud/ud_const.h +++ /dev/null @@ -1,24 +0,0 @@ - -/* C O N S T A N T P R O P A G A T I O N */ - -extern line_p unique_def(); /* ( line_p use; bblock_p b; short *defnr_out;) - * See if there is a unique explicit definition - * of the variable used by 'use' that - * reaches 'use'. - */ -extern bool value_known(); /* (line_p def; offset *val_out) - * See if the value stored by definition 'def' - * is known statically (i.e. is a constant). - */ -extern fold_const(); /* (line_p l; bblock_p b; offset val) - * Perform the substitutions required for - * constant folding. - */ -extern bool is_use(); /* (line_p l) - * See if 'l' is a use of a variable. - */ -extern bool affected(); /* (line_p use,l; short v) - * See if the variable referenced by 'use' may - * be changed by instruction l, which is - * either a cal, cai or an indirect assignment. - */ diff --git a/util/ego/ud/ud_copy.c b/util/ego/ud/ud_copy.c deleted file mode 100644 index 3e351f6ef..000000000 --- a/util/ego/ud/ud_copy.c +++ /dev/null @@ -1,390 +0,0 @@ -/* C O P Y P R O P A G A T I O N */ - -#include "../share/types.h" -#include "../ud/ud.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/alloc.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/def.h" -#include "../share/aux.h" -#include "../share/locals.h" -#include "../../../h/em_mnem.h" -#include "../../../h/em_pseu.h" -#include "../../../h/em_spec.h" -#include "../ud/ud_defs.h" -#include "ud_copy.h" -#include "ud_const.h" -#include "ud_aux.h" - - - -line_p *copies; /* table of copies; every entry points to the - * store-instruction. - */ -short *def_to_copynr; /* table that maps a 'definition'-number to a - * 'copy' number. - */ -short nrcopies; /* number of copies in the current procedure - * (length of copies-table) - */ - -#define COPY_NR(c) def_to_copynr[c] -#define CHANGED(v,b) (Cis_elem(v,CHGVARS(b)) || Cis_elem(IMPLICIT_DEF(v),GEN(b))) - - -#define COUNT 0 -#define MAP 1 - -STATIC traverse_defs(p,action) - proc_p p; - int action; -{ - bblock_p b; - line_p l; - bool found; - short defcnt,v,cnt; - - defcnt = 1; - if (action == COUNT) { - nrcopies = 0; - } else { - copies = (line_p *) newmap(nrcopies); - def_to_copynr = newtable(nrdefs); - cnt = 1; - } - if (defcnt > nrdefs) return; - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - if (defs[defcnt] == l) { - if (is_copy(l)) { - var_nr(PREV(l),&v,&found); - if (found) { - if (action == COUNT) { - nrcopies++; - } else { - copies[cnt] = l; - def_to_copynr[defcnt] = - cnt++; - } - } - } - if (++defcnt > nrdefs) return; - } - } - } -} - - - -STATIC make_copytab(p) - proc_p p; -{ - /* Make a table of all copies appearing in procedure p. - * We first count how many there are, because we - * have to allocate a dynamic array of the correct size. - */ - - traverse_defs(p,COUNT); - traverse_defs(p,MAP); -} - - - -STATIC bool is_changed(varl,start,stop) - line_p varl, start, stop; -{ - /* See if the variable used by instruction varl - * is changed anywhere between 'start' and 'stop' - */ - - register line_p l; - short v; - bool found; - - var_nr(varl,&v,&found); - if (!found) { - return TRUE; /* We don't maintain ud-info for this variable */ - } - for (l = start; l != (line_p) 0 && l != stop; l = l->l_next) { - if (does_expl_def(l) && same_var(varl,l)) return TRUE; - if (does_impl_def(l) && affected(varl,v,l)) return TRUE; - } - return FALSE; -} - - - -STATIC gen_kill_copies(p) - proc_p p; -{ - /* Compute C_GEN and C_KILL for every basic block - * of p. - */ - - register line_p l; - register bblock_p b,n; - short v; - bool found; - short copycnt = 1, defcnt = 1; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - C_GEN(b) = Cempty_set(nrcopies); - C_KILL(b) = Cempty_set(nrcopies); - } - if (nrcopies == 0) return; - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - if (copies[copycnt] == l) { - var_nr(PREV(l),&v,&found); - assert(found); - for (n = p->p_start; n != (bblock_p) 0; - n = n->b_next) { - if (n != b && CHANGED(v,n) && - Cis_elem(EXPL_TO_DEFNR(defcnt),IN(n))) { - Cadd(copycnt,&C_KILL(n)); - } - } - if (is_changed(PREV(l),l,(line_p) 0)) { - Cadd(copycnt,&C_KILL(b)); - } else { - Cadd(copycnt,&C_GEN(b)); - } - if (++copycnt > nrcopies) return; - } - if (defs[defcnt] == l) defcnt++; - } - } -} - - - -STATIC intersect_outs(bbset,setp,full_set) - lset bbset; - cset *setp,full_set; -{ - /* Take the intersection of C_OUT(b), for all b in bbset, - * and put the result in setp. - */ - - Lindex i; - - Ccopy_set(full_set,setp); - for (i = Lfirst(bbset); i != (Lindex) 0; i = Lnext(i,bbset)) { - Cintersect(C_OUT((bblock_p) Lelem(i)), setp); - } -} - - - -STATIC init_cin(p,full_set) - proc_p p; - cset full_set; -{ - /* Initialize C_IN(b) and C_OUT(b), for every basic block b. - * C_IN of the root of the CFG (i.e. the procedure entry block) - * will contain every copy, as it trivially holds that for - * every copy "s: A := B" there is no assignment to B on any - * path from s to the beginning of the root (because PRED(root)=empty). - * C_IN and C_OUT of the root will never be changed. - * For all remaining blocks b, C_IN(b) is initialized to the set of - * all copies, and C_OUT is set to all copies but those killed in b. - */ - - bblock_p b; - bblock_p root = p->p_start; - - C_IN(root) = Cempty_set(nrcopies); - Ccopy_set(full_set,&C_IN(root)); /* full_set is the set of all copies */ - /* C_OUT(root) = {all copies} - C_KILL(root) + C_GEN(root) */ - C_OUT(root) = Cempty_set(nrcopies); - Ccopy_set(full_set,&C_OUT(root)); - Csubtract(C_KILL(root),&C_OUT(root)); - Cjoin(C_GEN(root),&C_OUT(root)); - for (b = root->b_next; b != (bblock_p) 0; b = b->b_next) { - C_IN(b) = Cempty_set(nrcopies); - Ccopy_set(full_set,&C_IN(b)); - C_OUT(b) = Cempty_set(nrcopies); - Ccopy_set(full_set,&C_OUT(b)); - Csubtract(C_KILL(b),&C_OUT(b)); - } -} - - - -STATIC solve_cin(p) - proc_p p; -{ - /* Solve the data flow equations for reaching - * definitions of procedure p. - * These equations are: - * (1) C_OUT(b) = C_IN(b) - C_KILL(b) + C_GEN(b) - * (2) C_IN(b) = C_OUT(p1) * .. * C_OUT(pn) - * (3) C_IN(root) = {all copies} ; - * where PRED(b) = {p1, .. , pn} - * and '*' denotes set intersection. - * We use the iterative algorithm of Aho&Ullman to - * solve the equations. - */ - - register bblock_p b; - bool change; - cset newin,full_set; - short n; - - /* initializations */ - full_set = Cempty_set(nrcopies); - for (n = 1; n <= nrcopies; n++) { - Cadd(n,&full_set); - } - newin = Cempty_set(nrcopies); - init_cin(p,full_set); - change = TRUE; - /* main loop */ - while (change) { - change = FALSE; - for (b = p->p_start->b_next; b != (bblock_p) 0; b = b->b_next) { - intersect_outs(b->b_pred, &newin,full_set); - /* newin = C_OUT(p1) * .. * C_OUT(pn) */ - if (!Cequal(newin,C_IN(b))) { - change = TRUE; - Ccopy_set(newin, &C_IN(b)); - Ccopy_set(C_IN(b), &C_OUT(b)); - Csubtract(C_KILL(b), &C_OUT(b)); - Cjoin(C_GEN(b), &C_OUT(b)); - } - } - } - Cdeleteset(newin); - Cdeleteset(full_set); -} - - - -copy_analysis(p) - proc_p p; -{ - /* Determine which copies procedure p has. Compute C_IN(b), - * for every basic block b. - */ - - make_copytab(p); /* Make a table of all copies */ - gen_kill_copies(p); /* Compute C_GEN(b) and C_KILL(b), for every b */ - solve_cin(p); /* Solve equations for C_IN(b) */ -} - - - -bool is_copy(def) - line_p def; -{ - /* See if the definition def is also a 'copy', i.e. an - * statement of the form 'A := B' (or, in EM terminology: - * a sequence 'Load Variable; Store Variable'). - */ - - - line_p lhs; - int instr; - - lhs = PREV(def); - if (lhs == (line_p) 0) return FALSE; - instr = INSTR(def); - switch(INSTR(lhs)) { - case op_lol: - case op_loe: - return instr == op_stl || instr == op_ste; - case op_ldl: - case op_lde: - return instr == op_sdl || instr == op_sde; - default: - return FALSE; - } - /* NOTREACHED */ -} - - - -fold_var(old,new,b) - line_p old, new; - bblock_p b; -{ - /* The variable referenced by the EM instruction 'old' - * must be replaced by the variable referenced by 'new'. - */ - - line_p l; - -/* DEBUGGING: - local_p loc; - short nr; - bool ok; - if (TYPE(old) == OPOBJECT) { - printf("global var."); - } else { - printf("local var. with off. %D",off_set(old)); - find_local(off_set(old),&nr,&ok); - assert(ok); - loc = locals[nr]; - printf(",score %D",loc->lc_score); - } - printf(" replaced by "); - if (TYPE(new) == OPOBJECT) { - printf("global var."); - } else { - printf("local var. with off. %D",off_set(new)); - find_local(off_set(new),&nr,&ok); - assert(ok); - loc = locals[nr]; - printf(",score %D",loc->lc_score); - } - printf("\n"); -END DEBUG */ - l = old; - if (TYPE(l) != TYPE(new)) { - l = newline(TYPE(new)); - l->l_instr = INSTR(new); - repl_line(old,l,b); - } - switch(TYPE(new)) { - case OPOBJECT: - OBJ(l) = OBJ(new); - break; - case OPSHORT: - SHORT(l) = SHORT(new); - break; - case OPOFFSET: - OFFSET(l) = OFFSET(new); - break; - default: - assert(FALSE); - } -} - - - -bool value_retained(copy,defnr,use,b) - line_p copy,use; - short defnr; - bblock_p b; -{ - /* See if the right hand side variable of the - * copy still has the same value at 'use'. - * If the copy and the use are in the same - * basic block (defnr = 0), search from the - * copy to the use, to see if the rhs variable - * is changed. If the copy is in another block, - * defnr is the definition-number of the copy. - * Search from the beginning of the block to - * the use, to see if the rhs is changed; if not, - * check that the copy is in C_IN(b). - */ - - line_p rhs, start; - - rhs = PREV(copy); - start = (defnr == 0 ? copy : b->b_start); - return !is_changed(rhs,start,use) && - (defnr == 0 || Cis_elem(COPY_NR(defnr), C_IN(b))); -} diff --git a/util/ego/ud/ud_copy.h b/util/ego/ud/ud_copy.h deleted file mode 100644 index f6b398117..000000000 --- a/util/ego/ud/ud_copy.h +++ /dev/null @@ -1,41 +0,0 @@ - -/* C O P Y P R O P A G A T I O N */ - -extern line_p *copies; /* table of copies; every entry points to the - * store-instruction. - */ -extern short *def_to_copynr; /* Table that maps a 'definition'-number to a - * 'copy' number. - */ -extern short nrcopies; /* number of copies in the current procedure - * (length of copies-table) - */ - -extern copy_analysis(); /* (proc_p p) - * Determine which copies procedure p has. - * Compute C_IN(b), for every basic block b. - */ -extern bool is_copy(); /* (line_p def) - * See if the definition def is also a 'copy', - * i.e. an statement of the form - * 'A := B' (or, in EM terminology: - * a sequence 'Load Variable; Store Variable'). - */ -extern fold_var(); /* (line_p old,new; bblock_p b) - * The variable referenced by the - * EM instruction 'old' must be replaced - * by the variable referenced by 'new'. - */ -extern bool value_retained(); /* (line_p copy; short defnr; line_p use; - * bblock_p b) - * See if the right hand side variable of the - * copy still has the same value at 'use'. - * If the copy and the use are in the same - * basic block (defnr = 0), search from the - * copy to the use, to see if the rhs variable - * is changed. If the copy is in another block, - * defnr is the definition-number of the copy. - * Search from the beginning of the block to - * the use, to see if the rhs is changed; - * if not, check that the copy is in C_IN(b). - */ diff --git a/util/ego/ud/ud_defs.c b/util/ego/ud/ud_defs.c deleted file mode 100644 index 5bca2cf7c..000000000 --- a/util/ego/ud/ud_defs.c +++ /dev/null @@ -1,378 +0,0 @@ - -/* U S E - D E F I N I T I O N A N A L Y S I S - * - * U D _ D E F S . C - */ - -#include "../share/types.h" -#include "ud.h" -#include "../share/debug.h" -#include "../share/global.h" -#include "../share/lset.h" -#include "../share/cset.h" -#include "../share/map.h" -#include "../share/locals.h" -#include "../../../h/em_mnem.h" -#include "ud_defs.h" -#include "../share/alloc.h" -#include "../share/aux.h" - -#define BODY_KNOWN(p) (p->p_flags1 & (byte) PF_BODYSEEN) -#define CHANGE_INDIR(p) (p->p_change->c_flags & CF_INDIR) - -short nrdefs; /* total number of definitions */ -short nrexpldefs; /* number of explicit definitions */ -line_p *defs; -cset *vardefs; - -STATIC cset all_globl_defs, all_indir_defs; -/* auxiliary sets, used by gen_sets */ - - -bool does_expl_def(l) - line_p l; -{ - /* See if instruction l does an explicit definition */ - - switch(INSTR(l)) { - case op_stl: - case op_sdl: - case op_ste: - case op_sde: - case op_inl: - case op_del: - case op_ine: - case op_dee: - case op_zrl: - case op_zre: - return TRUE; - default: - return FALSE; - } - /* NOTREACHED */ -} - - - -bool does_impl_def(l) - line_p l; -{ - /* See if instruction l does an implicit definition */ - - switch(INSTR(l)) { - case op_cal: - case op_cai: - case op_sil: - case op_stf: - case op_sti: - case op_sts: - case op_sdf: - case op_sar: - case op_blm: - case op_bls: - case op_zrf: - return TRUE; - default: - return FALSE; - } -} - - -make_defs(p) - proc_p p; -{ - /* Make a map of all explicit definitions - * occurring in p. - * Determine the set of explicit definitions - * of variable v (i.e. vardefs[v]), for all - * v from 1 to nrvars. - * For every basic block b, compute CHGVARS(b), - * i.e. the set of variables changed in b by an - * explicit definition. - */ - - register bblock_p b; - register line_p l; - short v, i, cnt = 0; - bool found; - - /* first count the number of definitions */ - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - for (l = b->b_start; l != (line_p) 0 ; l = l->l_next) { - if (does_expl_def(l)) { - var_nr(l,&v,&found); - if (!found) continue; /* no ud for this var */ - cnt++; - } - } - } - nrexpldefs = cnt; - /* now allocate the defs table and the vardefs table*/ - defs = (line_p *) newmap(nrexpldefs); - vardefs = (cset *) newmap(nrvars); - for (i = 1; i <= nrvars; i++) { - vardefs[i] = Cempty_set(nrexpldefs); - } - cnt = 1; - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - CHGVARS(b) =Cempty_set(nrvars); - for (l = b->b_start; l != (line_p) 0 ; l = l->l_next) { - if (does_expl_def(l)) { - var_nr(l,&v,&found); - if (!found) continue; - assert (v <= nrvars); - Cadd(v,&CHGVARS(b)); - defs[cnt] = l; - Cadd(cnt,&vardefs[v]); - cnt++; - } - } - } -} - - - -STATIC init_gen(nrdefs) - short nrdefs; -{ - /* Initializing routine of gen_sets. Compute the set - * of all implicit definitions to global variables - * (all_globl_defs) and the set of all implicit - * definition generated by an indirect assignment - * through a pointer (all_indir_defs). - */ - - short v; - - all_globl_defs = Cempty_set(nrdefs); - all_indir_defs = Cempty_set(nrdefs); - for (v = 1; v <= nrglobals; v++) { - Cadd(IMPLICIT_DEF(GLOB_TO_VARNR(v)), &all_globl_defs); - Cadd(IMPLICIT_DEF(GLOB_TO_VARNR(v)), &all_indir_defs); - } - for (v = 1; v <= nrlocals; v++) { - if (!IS_REGVAR(locals[v])) { - Cadd(IMPLICIT_DEF(LOC_TO_VARNR(v)), &all_indir_defs); - } - } -} - - - -STATIC clean_gen() -{ - Cdeleteset(all_globl_defs); - Cdeleteset(all_indir_defs); -} - - - -STATIC bool same_target(l,defnr) - line_p l; - short defnr; -{ - /* See if l defines the same variable as def */ - - line_p def; - short v; - - if (IS_IMPL_DEF(defnr)) { - /* An implicitly generated definition */ - v = IMPL_VAR(TO_IMPLICIT(defnr)); - if (IS_GLOBAL(v)) { - return TYPE(l) == OPOBJECT && - OBJ(l)->o_globnr == TO_GLOBAL(v); - } else { - return TYPE(l) != OPOBJECT && - locals[TO_LOCAL(v)]->lc_off == off_set(l); - } - } - /* explicit definition */ - def = defs[TO_EXPLICIT(defnr)]; - if (TYPE(l) == OPOBJECT) { - return TYPE(def) == OPOBJECT && OBJ(def) == OBJ(l); - } else { - return TYPE(def) != OPOBJECT && off_set(def) == off_set(l); - } -} - - - -STATIC rem_prev_defs(l,gen_p) - line_p l; - cset *gen_p; -{ - /* Remove all definitions in gen that define the - * same variable as l. - */ - - cset gen; - Cindex i,next; - - gen = *gen_p; - for (i = Cfirst(gen); i != (Cindex) 0; i = next) { - next = Cnext(i,gen); - if (same_target(l,Celem(i))) { - Cremove(Celem(i),gen_p); - } - } -} - - - - -STATIC impl_globl_defs(p,gen_p) - proc_p p; - cset *gen_p; -{ - /* Add all definitions of global variables - * that are generated implicitly by a call - * to p to the set gen_p. - */ - - Cindex i; - short v; - cset ext = p->p_change->c_ext; - - for (i = Cfirst(ext); i != (Cindex) 0; i = Cnext(i,ext)) { - if (( v = omap[Celem(i)]->o_globnr) != (short) 0) { - /* the global variable v, for which we do - * maintain ud-info is changed by p, so a - * definition of v is generated implicitly. - */ - Cadd(IMPLICIT_DEF(GLOB_TO_VARNR(v)),gen_p); - } - } -} - - - -STATIC impl_gen_defs(l,gen_p) - line_p l; - cset *gen_p; -{ - /* Add all definitions generated implicitly by instruction l - * to gen_p. l may be a call or some kind of indirect - * assignment. - */ - - proc_p p; - - switch(INSTR(l)) { - case op_cal: - p = PROC(l); - if (BODY_KNOWN(p)) { - impl_globl_defs(p,gen_p); - if (!CHANGE_INDIR(p)) return; - break; - } - /* else fall through ... */ - case op_cai: - /* Indirect subroutine call or call to - * a subroutine whose body is not available. - * Assume worst case; all global - * variables are changed and - * the called proc. does a store- - * indirect. - */ - Cjoin(all_globl_defs,gen_p); - break; - /* default: indir. assignment */ - } - Cjoin(all_indir_defs,gen_p); -} - - - - -gen_sets(p) - proc_p p; -{ - /* Compute for every basic block b of p the - * set GEN(b) of definitions in b (explicit as - * well as implicit) that reach the end of b. - */ - - register bblock_p b; - register line_p l; - short defnr = 1; - - init_gen(nrdefs); /* compute all_globl_defs and all_indir_defs */ - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - GEN(b) = Cempty_set(nrdefs); - for (l = b->b_start; l != (line_p) 0; l = l->l_next) { - if (does_impl_def(l)) { - impl_gen_defs(l,&GEN(b)); - /* add definitions implicitly - * generated by subroutine call - * or indir. pointer assignment. - */ - } else { - if (does_expl_def(l)) { - if (defnr <= nrdefs && defs[defnr] == l) { - rem_prev_defs(l,&GEN(b)); - /* previous defs. of same var - * don't reach the end of b. - */ - Cadd(EXPL_TO_DEFNR(defnr),&GEN(b)); - defnr++; - } - } - } - } - } - clean_gen(); /* clean up */ -} - - - - -STATIC killed_defs(v,b) - short v; - bblock_p b; -{ - /* Put all definitions of v occurring outside b - * in KILL(b). In fact, we also put explicit - * definitions occurring in b, but not reaching the - * end of b, in KILL(b). This causes no harm. - */ - - Cindex i; - short d; - - for (i = Cfirst(vardefs[v]); i != (Cindex) 0; i = Cnext(i,vardefs[v])) { - d = Celem(i); /* d is an explicit definition of v */ - if (!Cis_elem(EXPL_TO_DEFNR(d),GEN(b))) { - Cadd(EXPL_TO_DEFNR(d),&KILL(b)); - } - } - /* Also add implicit definition of v to KILL(b) */ - Cadd(IMPLICIT_DEF(v),&KILL(b)); -} - - - - -kill_sets(p) - proc_p p; -{ - /* For every basic block b of p compute the set - * KILL(b) of definitions outside b that define - * variables redefined by b. - * KILL(b) contains explicit as well as implicit - * definitions. - */ - - register bblock_p b; - Cindex i; - short v; - - for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { - KILL(b) = Cempty_set(nrdefs); - for (i = Cfirst(CHGVARS(b)); i != (Cindex) 0; - i = Cnext(i,CHGVARS(b))) { - v = Celem(i); /* v is a variable changed in b */ - killed_defs(v,b); - } - } -} diff --git a/util/ego/ud/ud_defs.h b/util/ego/ud/ud_defs.h deleted file mode 100644 index 08c68db7a..000000000 --- a/util/ego/ud/ud_defs.h +++ /dev/null @@ -1,51 +0,0 @@ -/* U S E - D E F I N I T I O N A N A L Y S I S - * - * U D _ D E F S . H - */ - -extern short nrdefs; /* total number of definitions */ -extern short nrexpldefs; /* number of explicit definitions */ -extern line_p *defs; /* map of explicit definitions */ -extern cset *vardefs; /* set of explicit defs. of all variables */ - -extern make_defs(); /* (proc_p p) - * Compute defs[], vardefs[] - * and CHGVARS(b) (for every b). - */ -extern gen_sets(); /* (proc_p p) - * Compute GEN(b) (for every b). - */ -extern kill_sets(); /* (proc_p p) - *Compute KILL(b) (for every b). - */ -extern bool does_expl_def(); /* (line_p l) - * See if instruction l does an explicit - * definition (e.g. a STL). - */ -extern bool does_impl_def(); /* (line_p l) - * See if instruction l does an implicit - * definition (e.g. a CAL). - */ - - -/* Two kinds of definitions exist: - * - an explicit definition is an assignment to a single - * variable (e.g. a STL, STE, INE). - * - an implicit definition is an assignment to a variable - * performed via a subroutine call or an - * indirect assignment (through a pointer). - * Every explicit definition has an 'explicit definition number', - * which is its index in the 'defs' table. - * Every implicit definition has an 'implicit definition number', - * which is the 'variable number' of the changed variable. - * Every such definition also has a 'definition number'. - * Conversions exist between these numbers. - */ - -#define TO_EXPLICIT(defnr) (defnr - nrvars) -#define TO_IMPLICIT(defnr) (defnr) -#define EXPL_TO_DEFNR(explnr) (explnr + nrvars) -#define IMPL_TO_DEFNR(implnr) (implnr) -#define IMPLICIT_DEF(v) (v) -#define IMPL_VAR(defnr) (defnr) -#define IS_IMPL_DEF(defnr) (defnr <= nrvars) diff --git a/util/ego/ud/ud_locals.h b/util/ego/ud/ud_locals.h deleted file mode 100644 index b3d3a53f9..000000000 --- a/util/ego/ud/ud_locals.h +++ /dev/null @@ -1,18 +0,0 @@ -/* U S E - D E F I N I T I O N A N A L Y S I S - * - * U D _ L O C A L S . H - */ - -extern local_p *locals; /* table of locals, index is local-number */ -extern short nrlocals; /* number of locals for which we keep ud-info */ - -extern make_localtab(); /* (proc_p p) - * Analyse the text of procedure p to determine - * which local variable p has. Make a table of - * these variables ('locals') and count them - * ('nrlocals'). Also collect register messages. - */ -extern var_nr(); /* (line_p l; short *nr_out;bool *found_out) - * Compute the 'variable number' of the - * variable referenced by EM instruction l. - */ diff --git a/util/led/Makefile b/util/led/Makefile deleted file mode 100644 index 2589cc20d..000000000 --- a/util/led/Makefile +++ /dev/null @@ -1,142 +0,0 @@ -# -# Author: L.J. Bekema @ VU Informatica, Amsterdam -# - -.SUFFIXES: .c,v .h .h,v - -.c,v.o: - co -q $*.c - $(CC) $(CFLAGS) -c $*.c - rm -f $*.c - -.h,v.h: - co -q $*.h - -# Definitions for the making programs. - -PREFLAGS= -DNDEBUG -DNASSERT -CFLAGS = -O $(PREFLAGS) -LDFLAGS = -LINTFLAGS=-phbxac $(PREFLAGS) -PR = pr -PRFLAGS = - -# Some convenient macro definitions. - -CFILES = archive.c byte_order.c error.c extract.c finish.c main.c memory.c\ - output.c read.c relocate.c save.c scan.c sym.c write.c -CVFILES = archive.c,v byte_order.c,v error.c,v extract.c,v finish.c,v main.c,v\ - memory.c,v output.c,v read.c,v relocate.c,v save.c,v scan.c,v\ - sym.c,v write.c,v -HFILES = arch.h assert.h const.h debug.h defs.h memory.h orig.h out.h\ - ranlib.h scan.h -HVFILES = arch.h,v assert.h,v const.h,v debug.h,v defs.h,v memory.h,v orig.h,v\ - out.h,v ranlib.h,v scan.h,v -OFILES = archive.o byte_order.o error.o extract.o finish.o main.o memory.o\ - output.o read.o relocate.o save.o scan.o sym.o write.o - -# Things that can be made. - -led: $(OFILES) - $(CC) $(LDFLAGS) $(OFILES) $(LDLIBS) -o led - -mach.c: mach.c,v - co -q mach.c - -lint: - -for i in $(CFILES) $(HFILES) mach.c; do\ - if test ! -f $$i; then\ - echo $$i >> checked.out;\ - co -q $$i;\ - fi;\ - done - lint $(LINTFLAGS) $(CFILES) - rm -f `cat checked.out` checked.out - -pr: $(CVFILES) $(HVFILES) mach.c - @-for i in $?; do\ - co -q -p $$i | $(PR) $(PRFLAGS) -h `basename $$i ,v`;\ - done - @touch pr - -depend: - -for i in $(CFILES); do\ - if test ! -f $$i; then\ - echo $$i >> checked.out;\ - co -q $$i;\ - fi;\ - done - makedepend $(CFILES) - rm -f `cat checked.out` checked.out - -# The next lines are generated automatically. -# AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO -archive.o: arch.h -archive.o: const.h -archive.o: debug.h -archive.o: defs.h -archive.o: memory.h -archive.o: out.h -archive.o: ranlib.h -byte_order.o: assert.h -byte_order.o: const.h -error.o: const.h -error.o: out.h -extract.o: const.h -extract.o: debug.h -extract.o: defs.h -extract.o: memory.h -extract.o: orig.h -extract.o: out.h -extract.o: scan.h -finish.o: const.h -finish.o: defs.h -finish.o: memory.h -finish.o: orig.h -finish.o: out.h -finish.o: scan.h -main.o: const.h -main.o: debug.h -main.o: defs.h -main.o: memory.h -main.o: orig.h -main.o: out.h -memory.o: assert.h -memory.o: const.h -memory.o: debug.h -memory.o: mach.c -memory.o: memory.h -memory.o: out.h -output.o: const.h -output.o: memory.h -output.o: out.h -read.o: arch.h -read.o: assert.h -read.o: const.h -read.o: out.h -read.o: ranlib.h -relocate.o: const.h -relocate.o: debug.h -relocate.o: defs.h -relocate.o: orig.h -relocate.o: out.h -save.o: arch.h -save.o: assert.h -save.o: const.h -save.o: memory.h -save.o: out.h -scan.o: arch.h -scan.o: assert.h -scan.o: const.h -scan.o: memory.h -scan.o: out.h -scan.o: ranlib.h -scan.o: scan.h -sym.o: const.h -sym.o: memory.h -sym.o: out.h -write.o: assert.h -write.o: const.h -write.o: memory.h -write.o: orig.h -write.o: out.h diff --git a/util/led/archive.c b/util/led/archive.c deleted file mode 100644 index f453256e6..000000000 --- a/util/led/archive.c +++ /dev/null @@ -1,178 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -#include "arch.h" -#include "out.h" -#include "ranlib.h" -#include "const.h" -#include "debug.h" -#include "defs.h" -#include "memory.h" - -#define ENDLIB ((long)0) - -extern ind_t hard_alloc(); - -static struct ar_hdr arhdr; - -/* - * First read a long telling how many ranlib structs there are, then - * the structs themselves. Second read a long telling how many chars there are - * in the string table, then the string table itself. - * We keep only one ranlib table in core, so this table always starts at offset - * (ind_t)0 from its base. - */ -static long -getsymdeftable() -{ - register ind_t off; - register struct ranlib *ran; - register long count; - register long nran, nchar; - extern long getlong(); - - count = nran = getlong(); - debug("%ld ranlib structs, ", nran, 0, 0, 0); - off = hard_alloc(ALLORANL, nran * sizeof(struct ranlib)); - if (off == BADOFF) - fatal("no space for ranlib structs"); - ran = (struct ranlib *)address(ALLORANL, off); - read_table(ran, count); - nchar = getlong(); - debug("%ld ranlib chars\n", nchar, 0, 0, 0); - if ((off = hard_alloc(ALLORANL, nchar)) == BADOFF) - fatal("no space for ranlib strings"); - read_char(address(ALLORANL, off), nchar); - ran = (struct ranlib *)address(ALLORANL, (ind_t)0); - while (count--) { - /* - * Adjust because names are now in core, not on file. - * Note that `ran_off' is measured from the beginning of the - * string area, NOT from the beginning of the file. - */ - if (ran->ran_off >= nchar) - fatal("bad ranlib string offset"); - ran->ran_off += off; - ran++; - } - return nran; -} - -extern char *modulname; -extern long position; - -/* - * Process archive with table of contents. The table of contents tells - * of symbols in which module they are defined. We scan the table for - * symbols that are known but not yet defined. Then we extract all necessary - * information from the corresponding module. This module may need symbols that - * were defined in modules located before this one in the archive, so we - * scan the table again. We perform these actions as long as new symbols - * are defined. - */ -arch() -{ - long nran; - bool resolved; - - nran = getsymdeftable(); - - savemagic(); - do { - register ind_t ranindex; - register long count; - - debug("(re)scan ranlib table\n", 0, 0, 0, 0); - ranindex = (ind_t)0; - count = nran; - resolved = FALSE; - while (count > 0) { - register struct ranlib *ran; - register char *string; - register struct outname *name; - register long pos; - extern int hash(); - extern struct outname *searchname(); - - ran = (struct ranlib *)address(ALLORANL, ranindex); - string = address(ALLORANL, (ind_t)ran->ran_off); - name = searchname(string, hash(string)); - if (name == (struct outname *)0 || !ISUNDEFINED(name)) { - ranindex += sizeof(struct ranlib); - count--; - continue; - } - seek(ran->ran_pos); - get_archive_header(&arhdr); - modulname = arhdr.ar_name; - debug("%s defines %s\n", modulname, string, 0, 0); - position = ran->ran_pos + SZ_ARCH; - resolved = TRUE; - /* - * This archive member is going to be linked, - * so we don't need to know what else it defines. - * Note that we assume that all ranlib information of - * one archive member is contiguous. - */ - pos = ran->ran_pos; - do { - count--; ran++; - ranindex += sizeof(struct ranlib); - } while (count > 0 && ran->ran_pos == pos); - notelib(pos); - savehdr(&arhdr); - extract(); - } - } while (resolved); - - dealloc(ALLORANL); - notelib(ENDLIB); -} - -/* - * An archive member that will be loaded is remembered by storing its position - * in the archive into the table of positions. - */ -notelib(pos) - long pos; -{ - register ind_t off; - - if ((off = hard_alloc(ALLOARCH, (long)sizeof(long))) == BADOFF) - fatal("no space for archive position"); - *(long *)address(ALLOARCH, off) = pos; -} - -/* - * Index of position of first archive member of next archive. - */ -static ind_t posindex = (ind_t)0; - -/* - * Process the archive in pass 2. - * We walk through the table of positions telling at what byte offset the - * archive header + module is located, until this position is ENDLIB, meaning - * that we've processed all needed modules in this archive. Each group of - * positions of an archive is terminated with ENDLIB. - */ -arch2() -{ - register long *pos; - register ind_t localpos; - - localpos = posindex; - for ( pos = (long *)address(ALLOARCH, localpos); - *pos != ENDLIB; - pos++, localpos += sizeof(long) - ) { - seek(*pos); - get_archive_header(&arhdr); - modulname = arhdr.ar_name; - debug("%s: archive member\n", modulname, 0, 0, 0); - position = *pos + SZ_ARCH; - finish(); - } - localpos += sizeof(long); /* Skip ENDLIB. */ - posindex = localpos; /* Remember for next call. */ -} diff --git a/util/led/assert.h b/util/led/assert.h deleted file mode 100644 index 9ff3ae982..000000000 --- a/util/led/assert.h +++ /dev/null @@ -1,18 +0,0 @@ -/* $Header$ */ - -#ifndef lint -#ifdef NASSERT - -#define assert(ex) - -#else NASSERT - -#define assert(ex) \ -{if (!(ex)) fatal("Assertion failed: file %s, line %d", __FILE__, __LINE__);} - -#endif NASSERT -#else lint - -#define assert(ex) - -#endif lint diff --git a/util/led/byte_order.c b/util/led/byte_order.c deleted file mode 100644 index 0172ec3de..000000000 --- a/util/led/byte_order.c +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif lint - -#include "const.h" -#include "assert.h" - -bool bytes_reversed = FALSE; -bool words_reversed = FALSE; - -/* - * Determine the byte/word order in shorts/longs, assuming the size of a short - * is 2 chars, and the size of a long is 4 chars. Not all theoretical - * possibilities are tested; only bytes reversed and/or words reversed. - */ -determine_ordering() -{ - short s; - long l; - register char *cp; - register short *sp; - - cp = (char *)&s; - cp[0] = 0x01; cp[1] = 0x02; - if (s != 0x01 + (0x02 << 8)) - bytes_reversed = TRUE; - sp = (short *)&l; - sp[0] = 0x0001; sp[1] = 0x0002; - if (l != 0x0001 + (0x0002 << 16)) - words_reversed = TRUE; -} - -/* - * `Format' is a string of digits indicating how many bytes must be taken - * from `buf' to form an integer of some type. E.g. if the digit is '2', two - * bytes are taken to form a short. - */ -swap(buf, format) - register char *buf; - register char *format; -{ - register char savebyte; - - while (*format) { - switch (*format++) { - case '1': - buf += 1; - break; - case '2': - if (bytes_reversed) { - savebyte = buf[0]; - buf[0] = buf[1]; - buf[1] = savebyte; - } - buf += 2; - break; - case '4': - /* - * Written out to save recursive calls. - */ - if (bytes_reversed && words_reversed) { - savebyte = buf[0]; - buf[0] = buf[3]; - buf[3] = savebyte; - savebyte = buf[1]; - buf[1] = buf[2]; - buf[2] = savebyte; - } else if (bytes_reversed) { - savebyte = buf[0]; - buf[0] = buf[1]; - buf[1] = savebyte; - savebyte = buf[2]; - buf[2] = buf[3]; - buf[3] = savebyte; - } else if (words_reversed) { - savebyte = buf[0]; - buf[0] = buf[2]; - buf[2] = savebyte; - savebyte = buf[1]; - buf[1] = buf[3]; - buf[3] = savebyte; - } - buf += 4; - break; - default: - assert(FALSE); - break; - } - } -} diff --git a/util/led/const.h b/util/led/const.h deleted file mode 100644 index 6c70358d2..000000000 --- a/util/led/const.h +++ /dev/null @@ -1,26 +0,0 @@ -/* $Header$ */ - -typedef int bool; - -#define FALSE 0 -#define TRUE 1 - -#define S_ZER 0x2000 /* Internal use only. */ - -#define WIDTH 8 /* Number of bits in a byte. */ -#define BYTEMASK 0xFF /* Mask to get low order byte. */ -#define MININT (1 << (sizeof(int) * WIDTH - 1)) -#define MAXCHUNK (-(MININT + 1)) /* Highest count we write(2). */ - -#define RFLAG 0x01 /* -r flag given. */ -#define SFLAG 0x02 /* -s flag given. */ - -#define MAXSECT 64 /* Maximum number of sections. */ - -#define PLAIN 0 /* Input file is a normal file. */ -#define ARCHIVE 1 /* Input file is an archive. */ - -#define FIRST 1 /* Pass number. */ -#define SECOND 2 /* Idem. */ - -#define BADOFF ((ind_t)-1) diff --git a/util/led/debug.h b/util/led/debug.h deleted file mode 100644 index 16fff039a..000000000 --- a/util/led/debug.h +++ /dev/null @@ -1,11 +0,0 @@ -/* $Header$ */ - -#ifdef NDEBUG - -#define debug(s, a1, a2, a3, a4) - -#else - -#define debug(s, a1, a2, a3, a4) printf(s, a1, a2, a3, a4) - -#endif diff --git a/util/led/defs.h b/util/led/defs.h deleted file mode 100644 index 721986a04..000000000 --- a/util/led/defs.h +++ /dev/null @@ -1,10 +0,0 @@ -/* $Header$ */ - -/* - * We need the S_EXT because we leave locals alone. - */ -#define ISUNDEFINED(n) (((n)->on_type & (S_TYP | S_EXT)) == (S_UND | S_EXT)) -#define ISABSOLUTE(n) (((n)->on_type & (S_TYP | S_EXT)) == (S_ABS | S_EXT)) -#define ISCOMMON(n) (((n)->on_type & (S_COM | S_EXT)) == (S_COM | S_EXT)) - -#define mustsavelocal(name) (!((name)->on_type & S_SCT)) diff --git a/util/led/error.c b/util/led/error.c deleted file mode 100644 index 59c011e27..000000000 --- a/util/led/error.c +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -#include -#include -#include "out.h" -#include "const.h" - -static short nerrors = 0; - -static -stop() -{ - extern char *outputname; - - if (nerrors) - unlink(outputname); - - exit(nerrors); -} - -trap_signals() -{ - static int trap_them[] = { SIGHUP, SIGINT, SIGQUIT, SIGTERM, 0 }; - register int *ip; - - for (ip = trap_them; *ip; ip++) - if (signal(*ip, stop) == SIG_IGN) - signal(*ip, SIG_IGN); /* Oops, reset. */ -} - -/* VARARGS1 */ -fatal(format, a1, a2, a3, a4) - char *format; -{ - nerrors++; - diag("fatal", format, a1, a2, a3, a4); - stop(); -} - -/* VARARGS1 */ -warning(format, a1, a2, a3, a4) - char *format; -{ - diag("warning", format, a1, a2, a3, a4); -} - -/* VARARGS1 */ -error(format, a1, a2, a3, a4) - char *format; -{ - nerrors++; - diag("error", format, a1, a2, a3, a4); -} - -static -diag(tail, format, a1, a2, a3, a4) - char *tail; - char *format; -{ - extern char *progname, *archname, *modulname; - - fprintf(stderr, "%s: ", progname); - if (archname) - fprintf(stderr, "%s: ", archname); - if (modulname) - fprintf(stderr, "%s: ", modulname); - fprintf(stderr, format, a1, a2, a3, a4); - fprintf(stderr, " (%s)\n", tail); -} diff --git a/util/led/extract.c b/util/led/extract.c deleted file mode 100644 index 1b186f3ae..000000000 --- a/util/led/extract.c +++ /dev/null @@ -1,234 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -#include "out.h" -#include "const.h" -#include "debug.h" -#include "defs.h" -#include "memory.h" -#include "orig.h" -#include "scan.h" - -/* - * Get section sizes and symboltable information from present module. - */ -extract() -{ - struct outhead head; - - get_modul(); - /* - * Copy head because we need it so often but it can change place, - * so we can't trust a pointer to it. - */ - head = *(struct outhead *)modulptr(IND_HEAD); - get_names(&head); - process(&head); - skip_modul(&head); -} - -ushort NLocals = 0; /* Number of local names to be saved. */ -ushort NGlobals = 0; /* Number of global names. */ - -/* - * Walk through the nametable of this module, counting the locals that must - * appear in the final output file if this module is linked. - * That number will be returned. - */ -static -get_names(head) - register struct outhead *head; -{ - register int nnames; - register ind_t sectindex, nameindex, charindex; - register ind_t charoff; - extern int flagword; - - nnames = head->oh_nname; - sectindex = IND_SECT(*head); - nameindex = IND_NAME(*head); - charindex = IND_CHAR(*head); - charoff = OFF_CHAR(*head); - while (nnames--) { - register struct outsect *sects; - struct outname name; /* A local copy. */ - /* - * Because savelocal/getexternal might relocate the modules - * we have to compute the core addresses again. - */ - sects = (struct outsect *)modulptr(sectindex); - name = *(struct outname *)modulptr(nameindex); - /* - * Change the offset in file into an offset in the memory area. - * There will always be at least a header before the string - * area, so we don't have to be afraid to confuse "no name" - * with "the first name". - */ - if (name.on_foff) - name.on_foff += charindex - charoff; - namerelocate(&name, sects); - if (name.on_type & S_EXT) { - getexternal(&name); - } else { - /* - * The only thing we want to know about locals is - * whether they must appear in the output file. - */ - if (!(flagword & SFLAG) && mustsavelocal(&name)) { - NLocals++; - savelocal(&name); - } - } - nameindex += sizeof(struct outname); - } -} - -extern struct orig relorig[]; - -static -process(head) - register struct outhead *head; -{ - register struct outsect *sects; - register struct outsect *outsp; - register int nsect; - register struct orig *orig = relorig; - extern struct outhead outhead; - extern struct outsect outsect[]; - - outhead.oh_nrelo += head->oh_nrelo; - outhead.oh_nemit += head->oh_nemit; - if (head->oh_nsect > outhead.oh_nsect) - outhead.oh_nsect = head->oh_nsect; - sects = (struct outsect *)modulptr(IND_SECT(*head)); - nsect = head->oh_nsect; - outsp = outsect; - while (nsect--) { - outsp->os_size += sects->os_size; - outsp->os_flen += sects->os_flen; - /* - * Add all flen's and all (size - flen == zero)'s of - * preceding sections with the same number. - */ - orig->org_flen += sects->os_flen; - orig->org_zero += sects->os_size - sects->os_flen; - orig++; outsp++; sects++; - } -} - -/* - * Add relocation constant for names in user defined sections. - * The value of a common name indicates a size instead of an offset, - * and hence shouldn't be relocated. - * The value of a name in the zero part of a section is relative from the - * beginning of the section, not from the beginning of the zero part; but - * all zero parts will be put after the normal section contents, so we - * must subtract the flen of its section from the value (and later on add - * the total flen of its section) and add the accumulated size of all - * zero parts in preceding sections with the same number. - * Otherwise we just add the accumulated size of all normal parts in preceding - * sections with the same size. - */ -namerelocate(name, sects) - register struct outname *name; - struct outsect *sects; -{ - register int type = name->on_type; - register int sectindex; - - if ((type & S_TYP) == S_UND || (type & S_TYP) == S_ABS) - return; - if (type & S_COM) - return; - - sectindex = (type & S_TYP) - S_MIN; - if (name->on_valu >= sects[sectindex].os_flen) { - name->on_type |= S_ZER; - name->on_valu -= sects[sectindex].os_flen; - name->on_valu += relorig[sectindex].org_zero; - } else { - name->on_valu += relorig[sectindex].org_flen; - } -} - -/* - * If we see this name for the first time, we must remember it for - * we might need it later on. Otherwise it must confirm to what we already - * know about it, and eventually add to that knowledge. - */ -static -getexternal(name) - register struct outname *name; -{ - register char *string; - register int h; - register struct outname *old; - extern int hash(); - extern struct outname *searchname(); - - string = modulptr((ind_t)name->on_foff); - h = hash(string); - old = searchname(string, h); - if (old == (struct outname *)0) { - NGlobals++; - entername(name, h); - } else if (!ISUNDEFINED(name)) { - if (ISUNDEFINED(old)) { - transfer(name, old); - } else { - name->on_mptr = string; /* Just for convenience. */ - redefine(name, old); - } - } -} - -/* - * Handle the redefinition of `new' in the current module. - * A name can be defined in three ways, in increasing priority: - * undefined, - * common, - * defined in a section. - * A name may become "higher" when defined, but not "lower". - * A redefinition as common is allowed. It is ignored, but a warning is given - * when the desired section of `new' doesn't correspond with the section of - * `old'. If a common definition is given again for a name, we take the - * greatest value so that the common declared name always has enough space. - * If a common is defined as a not-common, the old definition is ignored. - */ -static -redefine(new, old) - register struct outname *new, *old; -{ - if (!ISCOMMON(old)) { - if (!ISCOMMON(new)) - error("%s: multiply defined", new->on_mptr); - - if ((new->on_type & S_TYP) != (old->on_type & S_TYP)) - warning("%s: sections differ", new->on_mptr); - } else { - /* `Old' is common. */ - if ((new->on_type & S_TYP) != (old->on_type & S_TYP)) - warning("%s: sections differ", new->on_mptr); - - if (ISCOMMON(new)) { - if (new->on_valu > old->on_valu) - old->on_valu = new->on_valu; - } else { - transfer(new, old); - } - } -} - -/* - * Transfer things we want to know from `src' to `dst'. - */ -static -transfer(src, dst) - register struct outname *src, *dst; -{ - debug("%s defined here\n", src->on_mptr, 0, 0, 0); - dst->on_valu = src->on_valu; - dst->on_type = src->on_type; - dst->on_desc = src->on_desc; -} diff --git a/util/led/finish.c b/util/led/finish.c deleted file mode 100644 index 00125f679..000000000 --- a/util/led/finish.c +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -#include "out.h" -#include "const.h" -#include "defs.h" -#include "memory.h" -#include "orig.h" -#include "scan.h" - -extern bool incore; -extern int flagword; - -/* - * We know all there is to know about the current module. - * Now we relocate the values in the emitted bytes and write - * those to the final output file. Then we compute the relative origins - * for the next module. - */ -finish() -{ - struct outhead *head; - struct outsect *sects; - struct outname *names; - char *chars; - - get_modul(); - head = (struct outhead *)modulptr(IND_HEAD); - sects = (struct outsect *)modulptr(IND_SECT(*head)); - names = (struct outname *)modulptr(IND_NAME(*head)); - chars = (char *)modulptr(IND_CHAR(*head)); - adjust_names(names, head, chars); - handle_relos(head, sects, names); - if (!incore && !(flagword & SFLAG)) { - put_locals(names, head->oh_nname, sects); -#ifdef SYMDBUG - put_dbug(OFF_DBUG(*head)); -#endif SYMDBUG - } - compute_origins(sects, head->oh_nsect); - skip_modul(head); -} - -/* - * Adjust all local names for the move into core. - */ -static -adjust_names(name, head, chars) - register struct outname *name; - struct outhead *head; - register char *chars; -{ - register int cnt; - register ind_t charoff; - - cnt = head->oh_nname; - charoff = OFF_CHAR(*head); - while (cnt--) { - if (name->on_foff != (long)0) - name->on_mptr = chars + name->on_foff - charoff; - name++; - } -} - -/* - * If all sections are in core, we can access them randomly, so we need only - * scan the relocation table once. Otherwise we must for each section scan - * the relocation table again, because the relocation entries of one section - * need not be consecutive. - */ -static -handle_relos(head, sects, names) - struct outhead *head; - struct outsect *sects; - struct outname *names; -{ - register struct outrelo *relo; - register int sectindex; - register int nrelo; - register char *emit; - extern char *getemit(); - extern struct outrelo *nextrelo(); - - if (incore) { - nrelo = head->oh_nrelo; sectindex = -1; - startrelo(head); relo = nextrelo(); - while (nrelo--) { - if (sectindex != relo->or_sect - S_MIN) { - sectindex = relo->or_sect - S_MIN; - emit = getemit(head, sects, sectindex); - } - relocate(head, emit, names, relo, sects); - relo++; - } - } else { - for (sectindex = 0; sectindex < head->oh_nsect; sectindex++) { - emit = getemit(head, sects, sectindex); - nrelo = head->oh_nrelo; startrelo(head); - while (nrelo--) { - relo = nextrelo(); - if (relo->or_sect - S_MIN == sectindex) { - relocate(head,emit,names,relo,sects); - /* - * Write out the (probably changed) - * relocation information. - */ - if (flagword & RFLAG) - wrt_relo(relo); - } - } - wrt_emit(emit, sectindex, sects[sectindex].os_flen); - /* - * XXX We should be able to free the emitted bytes. - */ - } - } -} - -/* - * Write out the local names that must be saved. - */ -static -put_locals(name, nnames, sects) - register struct outname *name; - register ushort nnames; - register struct outsect *sects; -{ - while (nnames--) { - if ((name->on_type & S_EXT) == 0 && mustsavelocal(name)) { - namerelocate(name, sects); - addbase(name); - wrt_name(name); - } - name++; - } -} - -/* - * Add all flen's and all (size - flen == zero)'s of preceding sections - * with the same number. - */ -static -compute_origins(sect, nsect) - register struct outsect *sect; - register ushort nsect; -{ - extern struct orig relorig[]; - register struct orig *orig = relorig; - - while (nsect--) { - orig->org_flen += sect->os_flen; - orig->org_zero += sect->os_size - sect->os_flen; - orig++; sect++; - } -} -#ifdef SYMDBUG - -/* - * Write out what is after the string area. This is likely to be - * debugging information. - */ -static -put_dbug(offdbug) - long offdbug; -{ - char buf[512]; - register int nbytes; - register long dbugsize; - extern long objectsize; - extern long position; - - dbugsize = objectsize - offdbug; - seek(position + offdbug); - while (dbugsize) { - nbytes = dbugsize > 512 ? 512 : dbugsize; - read_char(buf, (long)nbytes); - wrt_dbug(buf, nbytes); - dbugsize -= nbytes; - } -} -#endif SYMDBUG diff --git a/util/led/mach.c b/util/led/mach.c deleted file mode 100644 index e17bf1217..000000000 --- a/util/led/mach.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * $Header$ - */ -/* - * Values depend on the machine on which this program should run. - * Now for Vax 11/750. - */ - -#define K 1024 - - mems[ALLOEMIT + 0].mem_left = 64 * K; - mems[ALLOEMIT + 1].mem_left = 64 * K; - mems[ALLORELO].mem_left = 64 * K; - mems[ALLOLOCL].mem_left = 64 * K; - mems[ALLOGLOB].mem_left = 64 * K; - mems[ALLOLCHR].mem_left = 64 * K; - mems[ALLOGCHR].mem_left = 64 * K; -#ifdef SYMDBUG - mems[ALLODBUG].mem_left = 64 * K; -#endif SYMDBUG - mems[ALLOSYMB].mem_left = 4 * K; - mems[ALLOARCH].mem_left = 1 * K; - mems[ALLOMODL].mem_left = 3 * 64 * K; - mems[ALLORANL].mem_left = 4 * K; diff --git a/util/led/main.c b/util/led/main.c deleted file mode 100644 index 9f47cd167..000000000 --- a/util/led/main.c +++ /dev/null @@ -1,554 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -/* - * led - linkage editor for ACK assemblers output format - */ - -#include -#include "out.h" -#include "const.h" -#include "debug.h" -#include "defs.h" -#include "memory.h" -#include "orig.h" - -extern bool incore; - -main(argc, argv) - int argc; - char **argv; -{ - initializations(argc, argv); - first_pass(argv); - freeze_core(); - evaluate(); - beginoutput(); - second_pass(argv); - endoutput(); - exit(0); -} - -char *progname; /* Name this program was invoked with. */ -int passnumber; /* Pass we are in. */ -struct outhead outhead; /* Header of final output file. */ -struct outsect outsect[MAXSECT];/* Its section table. */ - -/* ARGSUSED */ -static -initializations(argc, argv) - int argc; - char *argv[]; -{ - /* - * Avoid malloc()s. - */ - setbuf(stdin, (char *)NULL); - setbuf(stdout, (char *)NULL); - setbuf(stderr, (char *)NULL); - - progname = argv[0]; - passnumber = FIRST; - determine_ordering(); - init_core(); - init_symboltable(); - outhead.oh_magic = O_MAGIC; - outhead.oh_stamp = O_STAMP; -} - -/* ------------------------ ROUTINES OF FIRST PASS ------------------------- */ - -int flagword = 0; /* To store command-line options. */ -char *outputname = "a.out"; /* Name of the resulting object file. */ - -/* - * Scan the arguments. - * If the argument starts with a '-', it's a flag, else it is either - * a plain file to be loaded, or an archive. - */ -static -first_pass(argv) - register char **argv; -{ - register char *argp; - int sectno; - int h; - extern int atoi(); - extern long number(); - extern char *index(); - extern int hash(); - extern struct outname *searchname(); - extern struct outname *makename(); - - while (*++argv) { - argp = *argv; - if (*argp != '-') { - pass1(argp); - continue; - } - /* It's a flag. */ - switch (*++argp) { - case 'a': - /* - * The rest of the argument must be of the form - * `
:', where - *
and are numbers. - * will be the alignment in the machine of - * section
. - */ - sectno = atoi(++argp); - if ((argp = index(argp, ':')) == (char *)0) - fatal("usage: -a
:"); - setlign(sectno, number(++argp)); - break; - case 'b': - /* - * The rest of the argument must be of the form - * `
:', where
- * and base are decimal numbers. will be - * the base address in the machine of section - *
. - */ - sectno = atoi(++argp); - if ((argp = index(argp, ':')) == (char *)0) - fatal("usage: -b
:"); - setbase(sectno, number(++argp)); - break; - case 'o': - /* - * The `name' argument after -o is used as name - * of the led output file, instead of "a.out". - */ - if ((outputname = *++argv) == (char *)0) - fatal("-o needs filename"); - break; - case 'r': - /* - * Generate relocation information in the output file - * so that it can be the subject of another led run. - * This flag also prevents final definitions from being - * given to common symbols, and suppresses the - * `Undefined:' diagnostic. - */ - if (flagword & SFLAG) - warning("-r contradicts -s: -s ignored"); - flagword |= RFLAG; - break; - case 's': - /* - * `Strip' the output, that is, remove the symbol table - * and relocation table to save space (but impair the - * usefullness of the debuggers). This information can - * also be removed by astrip(1). - */ - if (flagword & RFLAG) - warning("-s contradicts -r: -s ignored"); - else - flagword |= SFLAG; - break; - case 'u': - /* - * Take the following argument as a symbol and enter it - * as undefined in the symbol table. This is useful for - * loading wholly from a library, since initially the - * symbol table is empty and an unresolved reference is - * needed to force the loading of the first routine. - */ - if (*++argv == (char *)0) - fatal("-u needs symbol name"); - h = hash(*argv); - if (searchname(*argv, h) == (struct outname *)0) - entername(makename(*argv), h); - break; - default: - fatal("bad flag letter %c", *argp); - break; - } - } -} - -/* - * If `s' starts with 0x/0X, it's hexadecimal, - * else if it starts with 0b/0B, it's binary, - * else if it starts with 0, it's octal, - * else it's decimal. - */ -static long -number(s) - register char *s; -{ - register int digit; - register long value = 0; - register int radix = 10; - - if (*s == '0') { - radix = 8; - s++; - if (*s == 'x' || *s == 'X') { - radix = 16; - s++; - } else if (*s == 'b' || *s == 'B') { - radix = 2; - s++; - } - } - while (digit = *s++) { - if (digit >= 'A' && digit <= 'F') - digit -= 'A' + 10; - else if (digit >= 'a' && digit <= 'f') - digit -= 'a' + 10; - else if (digit >= '0' && digit <= '9') - digit -= '0'; - else - fatal("wrong digit %c", digit); - if (digit >= radix) - fatal("digit %c exceeds radix %d", digit, radix); - value = radix * value + digit; - } - return value; -} - -/* - * We use one bit per section to indicate whether a base was already given or - * not. Only one base may be given. The same applies for alignments. - */ -static char basemap[MAXSECT / WIDTH]; -static long sect_base[MAXSECT]; -static char lignmap[MAXSECT / WIDTH]; -static long sect_lign[MAXSECT]; - -/* -/* - * Set the alignment of section `sectno' to `lign', if this doesn't - * conflict with earlier alignment. - */ -static -setlign(sectno, lign) - register int sectno; - register long lign; -{ - extern bool setbit(); - - if (setbit(sectno, lignmap) && sect_lign[sectno] != lign) - fatal("section has different alignments"); - if (lign == (long)0) - fatal("alignment cannot be zero"); - sect_lign[sectno] = lign; -} - -/* - * Set the base of section `sectno' to `base', if no other base has been - * given yet. - */ -static -setbase(sectno, base) - register int sectno; - register long base; -{ - extern bool setbit(); - - if (setbit(sectno, basemap) && sect_base[sectno] != base) - fatal("section has different bases"); - sect_base[sectno] = base; -} - -static struct outname * -makename(string) - char *string; -{ - static struct outname namebuf; - - namebuf.on_mptr = string; - namebuf.on_type = S_UND + S_EXT; - namebuf.on_valu = (long)0; - - return &namebuf; -} - -/* - * If `file' is a plain file, symboltable information and section sizes are - * extracted. If it is an archive it is examined to see if it defines any - * undefined symbols. - */ -static -pass1(file) - char *file; -{ - if (getfile(file) == PLAIN) { - debug("%s: plain file\n", file, 0, 0, 0); - extract(); - } else { - /* It must be an archive. */ - debug("%s: archive\n", file, 0, 0, 0); - arch(); - } - closefile(file); -} - -/* ---------------- ROUTINES BETWEEN FIRST AND SECOND PASS ----------------- */ - -/* - * After pass 1 we know the sizes of all commons so we can give each common - * name an address within its section and we can compute the sizes of all - * sections in the machine. After this we can compute the bases of all - * sections. We then add the section bases to the values of names in - * corresponding sections. - */ -static -evaluate() -{ - if (!(flagword & RFLAG)) - norm_commons(); - complete_sections(); - if (!(flagword & RFLAG)) - change_names(); -} - -extern ushort NGlobals, NLocals; - -/* - * Sect_comm[N] is the number of common bytes in section N. - * It is computed after pass 1. - */ -static long sect_comm[MAXSECT]; - -/* - * If there are undefined names, we print them and we set a flag so that - * the output can be subject to another led run and we return. - * We now know how much space each common name needs. We change the value - * of the common name from the size to the address within its section, - * just like "normal" names. We also count the total size of common names - * within each section to be able to compute the final size in the machine. - */ -static -norm_commons() -{ - register struct outname *name; - register int cnt; - register int und = FALSE; - - name = (struct outname *)address(ALLOGLOB, (ind_t)0); - cnt = NGlobals; - while (cnt-- > 0) { - if (ISUNDEFINED(name)) { - if (!und) { - und = TRUE; - outhead.oh_flags |= HF_LINK; - flagword = (flagword & ~SFLAG) | RFLAG; - fprintf(stderr, "Undefined:\n"); - } - fprintf(stderr, "\t%s\n", - address(ALLOGCHR, (ind_t)name->on_foff) - ); - } - name++; - } - if (flagword & RFLAG) return; - - /* - * RFLAG is off, so we need not produce relocatable output. - * We can now assign an address to common names. - * It also means that there are no undefined names. - */ - name = (struct outname *)address(ALLOGLOB, (ind_t)0); - cnt = NGlobals; - while (cnt-- > 0) { - if (!ISABSOLUTE(name) && ISCOMMON(name)) { - register long size; - register int sectindex; - - size = name->on_valu; /* XXX rounding? */ - sectindex = (name->on_type & S_TYP) - S_MIN; - name->on_valu = - outsect[sectindex].os_size + - sect_comm[sectindex]; - sect_comm[sectindex] += size; - name->on_type &= ~S_COM; - } - name++; - } -} - -struct orig relorig[MAXSECT]; - -/* - * Compute the offsets in file and machine that the sections will have. - * Also set the origins to 0. - */ -static -complete_sections() -{ - register long base = 0; - register long foff; - register int sectindex; - extern bool tstbit(); - - foff = SZ_HEAD + outhead.oh_nsect * SZ_SECT; - for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++) { - relorig[sectindex].org_flen = (long)0; - relorig[sectindex].org_zero = (long)0; - outsect[sectindex].os_foff = foff; - foff += outsect[sectindex].os_flen; - - if (flagword & RFLAG) - continue; - - outsect[sectindex].os_size += sect_comm[sectindex]; - outsect[sectindex].os_lign = - tstbit(sectindex, lignmap) ? sect_lign[sectindex] : 1; - if (tstbit(sectindex, basemap)) { - base = sect_base[sectindex]; - if (base % outsect[sectindex].os_lign) - fatal("base not aligned"); - } else { - base += outsect[sectindex].os_lign - 1; - base -= base % outsect[sectindex].os_lign; - } - outsect[sectindex].os_base = base; - base += outsect[sectindex].os_size; - } -} - -/* - * For each name we add the base of its section to its value, unless - * the output has to be able to be linked again, as indicated by RFLAG. - */ -static -change_names() -{ - register int cnt; - register struct outname *name; - - name = (struct outname *)address(ALLOGLOB, (ind_t)0); - cnt = NGlobals; - while (cnt-- > 0) { - addbase(name); - name++; - } - if (!incore) - return; - /* - * Do the same with the local names. - */ - name = (struct outname *)address(ALLOLOCL, (ind_t)0); - cnt = NLocals; - while (cnt-- > 0) { - addbase(name); - name++; - } -} - -#define BIT 0x01 - -/* - * This function sets a bit with index `indx' in string. - * It returns whether it was already set. - */ -bool -setbit(indx, string) - int indx; - char string[]; -{ - register int byte_index, bit_index; - register int byte; - - byte_index = indx / WIDTH; /* Index of byte with bit we need. */ - bit_index = indx % WIDTH; /* Index of bit we need. */ - byte = string[byte_index]; - byte >>= bit_index; - if (byte & BIT) return TRUE; - - byte = BIT; - byte <<= bit_index; - string[byte_index] |= byte; - return FALSE; -} - -/* - * This function returns whether the bit given by `indx' is set in `string'. - */ -static bool -tstbit(indx, string) - int indx; - char string[]; -{ - register int byte_index, bit_index; - register int byte; - - byte_index = indx / WIDTH; /* Index of byte with bit we need. */ - bit_index = indx % WIDTH; /* Index of bit we need. */ - byte = string[byte_index]; - byte >>= bit_index; - - return byte & BIT; -} - -/* - * Add the base of the section of a name to its value. For a name in the zero - * part, the size of the normal part is also a "base". - */ -addbase(name) - struct outname *name; -{ - register int type = name->on_type & S_TYP; - register int sectindex = type - S_MIN; - - if (type == S_UND || type == S_ABS) - return; - if (name->on_type & S_COM) - return; - - if (name->on_type & S_ZER) { - name->on_valu += outsect[sectindex].os_flen; - name->on_type &= ~S_ZER; - } - name->on_valu += outsect[sectindex].os_base; - debug( "%s: type 0x%x, value %ld\n", - address((name->on_type & S_EXT) ? ALLOGCHR : ALLOLCHR, - (ind_t)name->on_foff - ), - name->on_type, name->on_valu, 0 - ); -} - -/* ------------------------ ROUTINES OF SECOND PASS ------------------------ */ - -/* - * Flags have already been processed, so we ignore them here. - */ -static -second_pass(argv) - char **argv; -{ - passnumber = SECOND; - while (*++argv) { - if ((*argv)[0] != '-') { - pass2(*argv); - continue; - } - switch ((*argv)[1]) { - case 'o': - case 'u': - ++argv; - break; - default: - break; - } - } -} - -static -pass2(file) - char *file; -{ - if (getfile(file) == PLAIN) { - debug("%s: plain file\n", file, 0, 0, 0); - finish(); - } else { - /* It must be an archive. */ - debug("%s: archive\n", file, 0, 0, 0); - arch2(); - } - closefile(file); -} diff --git a/util/led/memory.c b/util/led/memory.c deleted file mode 100644 index 8069af18c..000000000 --- a/util/led/memory.c +++ /dev/null @@ -1,459 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -/* - * Memory manager. Memory is divided into NMEMS pieces. There is a struct - * for each piece telling where it is, how many bytes are used, and how may - * are left. If a request for core doesn't fit in the left bytes, an sbrk() - * is done and pieces after the one that requested the growth are moved up. - */ - -#include "out.h" -#include "const.h" -#include "assert.h" -#include "debug.h" -#include "memory.h" - -struct memory mems[NMEMS]; - -bool incore = TRUE; /* TRUE while everything can be kept in core. */ -ind_t core_position = (ind_t)0; /* Index of current module. */ - -#define AT_LEAST 2 /* See comment about string areas. */ - -/* - * Initialize some pieces of core. We hope that this will be our last - * real allocation, meaning we've made the right choices. - */ -init_core() -{ - register char *base; - register ind_t total_size; - register struct memory *mem; - extern char *sbrk(); - -#include "mach.c" - - total_size = (ind_t)0; /* Will accumulate the sizes. */ - base = sbrk(0); /* First free. */ - for (mem = mems; mem < &mems[NMEMS]; mem++) { - mem->mem_base = base; - mem->mem_full = (ind_t)0; - base += mem->mem_left; /* Each piece will start after prev. */ - total_size += mem->mem_left; - } - /* - * String areas are special-cased. The first byte is unused as a way to - * distinguish a name without string from a name which has the first - * string in the string area. - */ - if (mems[ALLOLCHR].mem_left == 0) - total_size += 1; - else - mems[ALLOLCHR].mem_left -= 1; - if (mems[ALLOGCHR].mem_left == 0) - total_size += 1; - else - mems[ALLOGCHR].mem_left -= 1; - mems[ALLOLCHR].mem_full = 1; - mems[ALLOGCHR].mem_full = 1; - - if (total_size != (int)total_size || (int)sbrk((int)total_size) == -1) { - incore = FALSE; /* In core strategy failed. */ - if ((int)sbrk(AT_LEAST) == -1) - fatal("no core at all"); - } -} - -/* - * Allocate an extra block of `incr' bytes and move all pieces with index - * higher than `piece' up with the size of the block. Return whether the - * allocate succeeded. - */ -static bool -move_up(piece, incr) - register int piece; - register ind_t incr; -{ - register struct memory *mem; - extern char *sbrk(); - - debug("move_up(%d, %d)\n", piece, (int)incr, 0, 0); - if (incr != (int)incr || (int)sbrk((int)incr) == -1) - return FALSE; - - for (mem = &mems[NMEMS - 1]; mem > &mems[piece]; mem--) - copy_up(mem, incr); - - mems[piece].mem_left += incr; - return TRUE; -} - -extern int passnumber; - -/* - * This routine is called if `piece' needs `incr' bytes and the system won't - * give them. We first steal the free bytes of all lower pieces and move them - * and `piece' down. If that doesn't give us enough bytes, we steal the free - * bytes of all higher pieces and move them up. We return whether we have - * enough bytes, the first or the second time. - */ -static bool -compact(piece, incr) - register int piece; - register ind_t incr; -{ - register ind_t gain; - register struct memory *mem; - - debug("compact(%d, %d)\n", piece, (int)incr, 0, 0); - gain = mems[0].mem_left; - mems[0].mem_left = (ind_t)0; - for (mem = &mems[1]; mem <= &mems[piece]; mem++) { - /* Here memory is inserted before a piece. */ - assert(passnumber == FIRST || gain == (ind_t)0); - copy_down(mem, gain); - gain += mem->mem_left; - mem->mem_left = (ind_t)0; - } - /* - * Note that we already added the left bytes of the piece we want to - * enlarge to `gain'. - */ - if (gain < incr) { - register ind_t up = (ind_t)0; - - for (mem = &mems[NMEMS - 1]; mem > &mems[piece]; mem--) { - /* Here memory is appended after a piece. */ - up += mem->mem_left; - copy_up(mem, up); - mem->mem_left = (ind_t)0; - } - gain += up; - } - mems[piece].mem_left = gain; - return gain >= incr; -} - -/* - * The bytes of `mem' must be moved `dist' down in the address space. - * We copy the bytes from low to high, because the tail of the new area may - * overlap with the old area, but we do not want to overwrite them before they - * are copied. - */ -static -copy_down(mem, dist) - register struct memory *mem; - ind_t dist; -{ - register char *old; - register char *new; - register ind_t size; - - size = mem->mem_full; - old = mem->mem_base; - new = old - dist; - mem->mem_base = new; - while (size--) - *new++ = *old++; -} - -/* - * The bytes of `mem' must be moved `dist' up in the address space. - * We copy the bytes from high to low, because the tail of the new area may - * overlap with the old area, but we do not want to overwrite them before they - * are copied. - */ -static -copy_up(mem, dist) - register struct memory *mem; - ind_t dist; -{ - register char *old; - register char *new; - register ind_t size; - - size = mem->mem_full; - old = mem->mem_base + size; - new = old + dist; - while (size--) - *--new = *--old; - mem->mem_base = new; -} - -/* - * Add `size' bytes to the bytes already allocated for `piece'. If it has no - * free bytes left, ask them from memory or, if that fails, from the free - * bytes of other pieces. The offset of the new area is returned. No matter - * how many times the area is moved, because of another allocate, this offset - * remains valid. - */ -ind_t -alloc(piece, size) - register int piece; - register long size; -{ - register ind_t incr = 0; - register ind_t left = mems[piece].mem_left; - register ind_t full = mems[piece].mem_full; - - assert(passnumber == FIRST || (!incore && piece == ALLOMODL)); - if (size == (long)0) - return full; - if (size != (ind_t)size) - return BADOFF; - - while (left + incr < size) - incr += INCRSIZE; - - if (incr == 0 || move_up(piece, incr) || compact(piece, incr)) { - mems[piece].mem_full += size; - mems[piece].mem_left -= size; - return full; - } else { - incore = FALSE; - return BADOFF; - } -} - -/* - * Same as alloc() but for a piece which really needs it. If the first - * attempt fails, release the space occupied by other pieces and try again. - */ -ind_t -hard_alloc(piece, size) - register int piece; - register long size; -{ - register ind_t ret; - register int i; - - if (size != (ind_t)size) - return BADOFF; - if ((ret = alloc(piece, size)) != BADOFF) - return ret; - - /* - * Deallocate what we don't need. - */ - for (i = 0; i < NMEMS; i++) { - switch (i) { - case ALLOGLOB: - case ALLOGCHR: - case ALLOSYMB: - case ALLOARCH: - case ALLOMODL: - break; /* Do not try to deallocate this. */ - default: - dealloc(i); - break; - } - } - free_saved_moduls(); - - return alloc(piece, size); -} - -/* - * We don't need the previous modules, so we put the current module - * at the start of the piece allocated for module contents, thereby - * overwriting the saved modules, and release its space. - */ -static -free_saved_moduls() -{ - register ind_t size; - register char *old, *new; - register struct memory *mem = &mems[ALLOMODL]; - - size = mem->mem_full - core_position; - new = mem->mem_base; - old = new + core_position; - while (size--) - *new++ = *old++; - mem->mem_full -= core_position; - mem->mem_left += core_position; - core_position = (ind_t)0; -} - -/* - * The piece of memory with index `piece' is no longer needed. - * We take care that it can be used by compact() later, if needed. - */ -dealloc(piece) - register int piece; -{ - /* - * Some pieces need their memory throughout the program. - */ - assert(piece != ALLOGLOB); - assert(piece != ALLOGCHR); - assert(piece != ALLOSYMB); - assert(piece != ALLOARCH); - mems[piece].mem_left += mems[piece].mem_full; - mems[piece].mem_full = (ind_t)0; -} - -char * -core_alloc(piece, size) - register int piece; - register long size; -{ - register ind_t off; - - if ((off = alloc(piece, size)) == BADOFF) - return (char *)0; - return address(piece, off); -} - -/* - * Reset index into piece of memory for modules and - * take care that the allocated pieces will not be moved. - */ -freeze_core() -{ - register int i; - - core_position = (ind_t)0; - - if (incore) - return; - - for (i = 0; i < NMEMS; i++) { - switch (i) { - case ALLOGLOB: - case ALLOGCHR: - case ALLOSYMB: - case ALLOARCH: - break; /* Do not try to deallocate this. */ - default: - dealloc(i); - break; - } - } - compact(NMEMS - 1, (ind_t)0); -} - -/* ------------------------------------------------------------------------- */ - -extern bool bytes_reversed; -extern bool words_reversed; - -/* - * To transform the various pieces of the output in core to the file format, - * we must order the bytes in the ushorts and longs as ACK prescribes. - */ -write_bytes() -{ - ushort nsect, nrelo; - long offchar; - int fd; - register struct memory *mem; - extern ushort NLocals, NGlobals; - extern long NLChars, NGChars; - extern int flagword; - extern struct outhead outhead; - extern struct outsect outsect[]; - extern char *outputname; - - nsect = outhead.oh_nsect; - nrelo = outhead.oh_nrelo; - offchar = OFF_CHAR(outhead); - - if (bytes_reversed || words_reversed) { - swap((char *)&outhead, SF_HEAD); - sectswap(outsect, nsect); - reloswap(nrelo); - } - /* - * We allocated two areas: one for local and one for global names. - * Also, we used another kind of on_foff than on file. - * At the end of the global area we have put the section names. - */ - if (!(flagword & SFLAG)) { - namecpy((struct outname *)mems[ALLOLOCL].mem_base, - NLocals, - offchar - ); - namecpy((struct outname *)mems[ALLOGLOB].mem_base, - NGlobals + nsect, - offchar + NLChars - ); - } - if ((fd = creat(outputname, 0666)) < 0) - fatal("can't create %s", outputname); - /* - * These pieces must always be written. - */ - writelong(fd, (char *)&outhead, (ind_t)SZ_HEAD); - writelong(fd, (char *)outsect, (ind_t)nsect * SZ_SECT); - for (mem = &mems[ALLOEMIT]; mem < &mems[ALLORELO]; mem++) - writelong(fd, mem->mem_base, mem->mem_full); - /* - * The rest depends on the flags. - */ - if (flagword & RFLAG) - writelong(fd, mems[ALLORELO].mem_base, mems[ALLORELO].mem_full); - if (!(flagword & SFLAG)) { - writelong(fd, mems[ALLOLOCL].mem_base, mems[ALLOLOCL].mem_full); - writelong(fd, mems[ALLOGLOB].mem_base, mems[ALLOGLOB].mem_full); - writelong(fd, mems[ALLOLCHR].mem_base + 1, (ind_t)NLChars); - writelong(fd, mems[ALLOGCHR].mem_base + 1, (ind_t)NGChars); -#ifdef SYMDBUG - writelong(fd, mems[ALLODBUG].mem_base, mems[ALLODBUG].mem_full); -#endif SYMDBUG - } - close(fd); -} - -static -writelong(fd, base, size) - register int fd; - register char *base; - register ind_t size; -{ - register int chunk; - - while (size) { - chunk = size > (ind_t)MAXCHUNK ? MAXCHUNK : size; - write(fd, base, chunk); - size -= chunk; - base += chunk; - } -} - -static -sectswap(sect, nsect) - register struct outsect *sect; - register ushort nsect; -{ - while (nsect--) - swap((char *)sect++, SF_SECT); -} - -static -reloswap(nrelo) - register ushort nrelo; -{ - register struct outrelo *relo; - - relo = (struct outrelo *)mems[ALLORELO].mem_base; - while (nrelo--) - swap((char *)relo++, SF_RELO); -} - -static -namecpy(name, nname, offchar) - register struct outname *name; - register ushort nname; - register long offchar; -{ - while (nname--) { - if (name->on_foff) - name->on_foff += offchar - 1; - if (bytes_reversed || words_reversed) - swap((char *)name, SF_NAME); - name++; - } -} diff --git a/util/led/memory.h b/util/led/memory.h deleted file mode 100644 index e78b065d3..000000000 --- a/util/led/memory.h +++ /dev/null @@ -1,35 +0,0 @@ -/* $Header$ */ - -#define ALLOEMIT 0 /* Section contents. */ -#define ALLORELO (ALLOEMIT + MAXSECT) /* Relocation table. */ -#define ALLOLOCL (ALLORELO + 1) /* Saved local names. */ -#define ALLOGLOB (ALLOLOCL + 1) /* Saved global names. */ -#define ALLOLCHR (ALLOGLOB + 1) /* Strings of local names. */ -#define ALLOGCHR (ALLOLCHR + 1) /* Strings of global names. */ -#ifdef SYMDEBUG -#define ALLODBUG (ALLOGCHR + 1) /* Symbolic debugging info. */ -#else SYMDEBUG -#define ALLODBUG ALLOGCHR -#endif SYMDEBUG -#define ALLOSYMB (ALLODBUG + 1) /* Symbol table. */ -#define ALLOARCH (ALLOSYMB + 1) /* Archive positions. */ -#define ALLOMODL (ALLOARCH + 1) /* Modules. */ -#define ALLORANL (ALLOMODL + 1) /* Ranlib information. */ -#define NMEMS (ALLORANL + 1) - -#define INCRSIZE 1024 - -typedef unsigned int ind_t; -#define BADOFF ((ind_t)-1) - -struct memory { - char *mem_base; - ind_t mem_full; - ind_t mem_left; -}; -extern struct memory mems[]; - -#define address(piece,offset) (mems[(piece)].mem_base+(offset)) -#define modulptr(offset) (mems[ALLOMODL].mem_base+core_position+(offset)) - -extern ind_t core_position; diff --git a/util/led/orig.h b/util/led/orig.h deleted file mode 100644 index 0fed9e974..000000000 --- a/util/led/orig.h +++ /dev/null @@ -1,6 +0,0 @@ -/* $Header$ */ - -struct orig { - long org_flen; /* Accumulated length of preceding sections. */ - long org_zero; /* " " " zeroparts. */ -}; diff --git a/util/led/output.c b/util/led/output.c deleted file mode 100644 index 9547e9eb7..000000000 --- a/util/led/output.c +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -#include "out.h" -#include "const.h" -#include "memory.h" - -extern struct outhead outhead; -extern bool incore; -extern int flagword; - -/* - * We have counted all relocation structs but we know only now if - * these must be emitted.We add all names here,unless the -s(trip) - * flag was given. - * If this flag is given we don't need the string table either. - */ -beginoutput() -{ - extern ushort NLocals, NGlobals; - extern long NLChars, NGChars; - - if (incore) - generate_section_names(); - - if (!(flagword & RFLAG)) - outhead.oh_nrelo = (ushort)0; - if (flagword & SFLAG) { - outhead.oh_nname = (ushort)0; - outhead.oh_nchar = (long)0; - } else { - outhead.oh_nname = NLocals + NGlobals + outhead.oh_nsect; - outhead.oh_nchar = NLChars + NGChars; - } - trap_signals(); - if (!incore) - begin_write(); -} - -/* - * Generate names for all sections and put them after the global names. - * Section names are used for relocation. - */ -static -generate_section_names() -{ - register struct outname *name; - register int sectindex; - register long size; - extern struct outsect outsect[]; - extern char *core_alloc(); - - size = (long)outhead.oh_nsect * sizeof(struct outname); - name = (struct outname *)core_alloc(ALLOGLOB, size); - if (name == (struct outname *)0) - return; - - for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++, name++) { - name->on_foff = (long)0; /* No string name. */ - name->on_type = (S_MIN + sectindex) | S_SCT; - name->on_desc = (ushort)0; - name->on_valu = outsect[sectindex].os_base; - } -} - -/* - * If we didn't keep the whole output file in core, most of it has been - * written out, and we just finish that. - * If we did, we write out our pieces of core. - */ -endoutput() -{ - if (!incore) { - if (!(flagword & SFLAG)) - end_write(); - } else { - write_bytes(); - } -} diff --git a/util/led/read.c b/util/led/read.c deleted file mode 100644 index f888a71a1..000000000 --- a/util/led/read.c +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -/* - * Routines to read in the various parts of the object file. - */ - -#include "arch.h" -#include "out.h" -#include "ranlib.h" -#include "const.h" -#include "assert.h" - -int infile; /* The current input file. */ - -extern bool bytes_reversed; -extern bool words_reversed; - -ushort -getushort() -{ - ushort ubuf; - - if (read(infile, (char *)&ubuf, 2) != 2) - fatal("premature EOF"); - if (bytes_reversed) - swap((char *)&ubuf, "2"); - return ubuf; -} - -long -getlong() -{ - long lbuf; - - if (read(infile, (char *)&lbuf, 4) != 4) - fatal("premature EOF"); - if (bytes_reversed || words_reversed) - swap((char *)&lbuf, "4"); - return lbuf; -} - -read_head(head) - register struct outhead *head; -{ - if (read(infile, (char *)head, SZ_HEAD) != SZ_HEAD) - fatal("premature EOF"); - if (bytes_reversed || words_reversed) - swap((char *)head, SF_HEAD); - if (BADMAGIC(*head)) - fatal("bad magic number"); -} - -/* - * Someone inadvertently misaligned a long, thereby creating a hole. - * Therefore we can't read the header in one chunk. - */ -read_arhdr(arhdr) - register struct ar_hdr *arhdr; -{ - if (read(infile, (char *)arhdr, 14) != 14) - fatal("premature EOF"); - if (read(infile, (char *)&arhdr->ar_date, SZ_ARCH - 14) != SZ_ARCH - 14) - fatal("premature EOF"); - if (bytes_reversed || words_reversed) - swap((char *)&arhdr->ar_date, SF_ARCH); -} - -read_table(ran, cnt) - register struct ranlib *ran; - register long cnt; -{ - read_char((char *)ran, cnt * SZ_RAN); - if (bytes_reversed || words_reversed) - while (cnt--) - swap((char *)ran++, SF_RAN); -} - -read_sect(sect, cnt) - register struct outsect *sect; - register ushort cnt; -{ - if (read(infile, (char *)sect, cnt * SZ_SECT) != cnt * SZ_SECT) - fatal("premature EOF"); - if (bytes_reversed || words_reversed) - while (cnt--) - swap((char *)sect++, SF_SECT); -} - -read_emit(emit, cnt) - register char *emit; - register long cnt; -{ - read_char(emit, cnt); -} - -read_relo(relo, cnt) - register struct outrelo *relo; - register ushort cnt; -{ - read_char((char *)relo, (long)cnt * SZ_RELO); - if (bytes_reversed || words_reversed) - while (cnt--) - swap((char *)relo++, SF_RELO); -} - -read_name(name, cnt) - register struct outname *name; - register ushort cnt; -{ - read_char((char *)name, (long)cnt * SZ_NAME); - if (bytes_reversed || words_reversed) - while (cnt--) - swap((char *)name++, SF_NAME); -} - -/* - * We don't have to worry about byte order here. - */ -read_char(string, cnt) - register char *string; - register long cnt; -{ - register int n; - - while (cnt) { - n = cnt >= MAXCHUNK ? MAXCHUNK : cnt; - if (read(infile, string, n) != n) - fatal("premature EOF"); - string += n; - cnt -= n; - } -} diff --git a/util/led/relocate.c b/util/led/relocate.c deleted file mode 100644 index 05d604822..000000000 --- a/util/led/relocate.c +++ /dev/null @@ -1,256 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -#include "out.h" -#include "const.h" -#include "debug.h" -#include "defs.h" -#include "orig.h" - -#define UBYTE(x) ((x) & BYTEMASK) - -/* - * The bits in type indicate how many bytes the value occupies and what - * significance should be attributed to each byte. - */ -static long -getvalu(addr, type) - char addr[]; - char type; -{ - ushort word0, word1; - - switch (type & RELSZ) { - case RELO1: - return UBYTE(addr[0]); - case RELO2: - if (type & RELBR) - return (UBYTE(addr[0]) << WIDTH) + UBYTE(addr[1]); - else - return (UBYTE(addr[1]) << WIDTH) + UBYTE(addr[0]); - case RELO4: - if (type & RELBR) { - word0 = (UBYTE(addr[0]) << WIDTH) + UBYTE(addr[1]); - word1 = (UBYTE(addr[2]) << WIDTH) + UBYTE(addr[3]); - } else { - word0 = (UBYTE(addr[1]) << WIDTH) + UBYTE(addr[0]); - word1 = (UBYTE(addr[3]) << WIDTH) + UBYTE(addr[2]); - } - if (type & RELWR) - return ((long)word0 << (2 * WIDTH)) + word1; - else - return ((long)word1 << (2 * WIDTH)) + word0; - default: - fatal("bad relocation size"); - } - /* NOTREACHED */ -} - -/* - * The bits in type indicate how many bytes the value occupies and what - * significance should be attributed to each byte. - * We do not check for overflow. - */ -static -putvalu(valu, addr, type) - long valu; - char addr[]; - char type; -{ - ushort word0, word1; - - switch (type & RELSZ) { - case RELO1: - addr[0] = valu; - break; - case RELO2: - if (type & RELBR) { - addr[0] = valu >> WIDTH; - addr[1] = valu; - } else { - addr[0] = valu; - addr[1] = valu >> WIDTH; - } - break; - case RELO4: - if (type & RELWR) { - word0 = valu >> (2 * WIDTH); - word1 = valu; - } else { - word0 = valu; - word1 = valu >> (2 * WIDTH); - } - if (type & RELBR) { - addr[0] = word0 >> WIDTH; - addr[1] = word0; - addr[2] = word1 >> WIDTH; - addr[3] = word1; - } else { - addr[0] = word0; - addr[1] = word0 >> WIDTH; - addr[2] = word1; - addr[3] = word1 >> WIDTH; - } - break; - default: - fatal("bad relocation size"); - } -} - -/* - * Returns whether `valu' refers to the zero part of its section. - * The address of its zero part (relative to the beginning of the section) - * is in `zero_addr'. If `valu' is used in a pc-relative address computation, - * we have to do that computation ourselves. A pc-relative address is the - * difference between the address of the byte after the value and the "real" - * address: - * referencing address + its size + pc-relative address == "real" address. - */ -static bool -refers_zero(valu, relo, zero_addr) - register long valu; - struct outrelo *relo; - long zero_addr; -{ - if (relo->or_type & RELPC) { - valu += relo->or_addr; - /* - * Below is a dirty switch-statement. But an even dirtier - * statement would be: valu += (relo->or_type & RELSZ), - * because in that case you would have to know the values - * of the RELO[124] symbols. - */ - switch (relo->or_type & RELSZ) { - case RELO4: valu += 1; - valu += 1; - case RELO2: valu += 1; - case RELO1: valu += 1; - } - } - return valu >= zero_addr; -} - -extern ushort NLocals, NGlobals; -extern struct outsect outsect[]; -extern struct orig relorig[]; - -/* - * There are two cases: `local' is an undefined external or common name, - * or `local' is a section name. - * First case: if the name has been defined in another module, - * its value is known and can be added. Or_nami will be the - * index of the name of the section in which this name was - * defined. Otherwise we must change or_nami to the index of - * this name in the name table of the output file and leave - * its value unchanged. - * Second case: we must update the value by the change - * in position of the section of local. - */ -static ushort -addrelo(relo, names, sects, valu_out) - struct outrelo *relo; - struct outname *names; - struct outsect *sects; - long *valu_out; /* Out variable. */ -{ - register struct outname *local = &names[relo->or_nami]; - register ushort index = NLocals; - register long valu = *valu_out; - - if (ISUNDEFINED(local) || ISCOMMON(local)) { - register struct outname *name; - extern int hash(); - extern struct outname *searchname(); - extern ushort indexof(); - - name = searchname(local->on_mptr, hash(local->on_mptr)); - if (name == (struct outname *)0) - fatal("name %s not found in pass 2", local->on_mptr); - if (ISCOMMON(name) || ISUNDEFINED(name)) { - debug("can't relocate from %s\n",local->on_mptr,0,0,0); - index += indexof(name); - } else { - valu += name->on_valu; - index += NGlobals + (name->on_type & S_TYP) - S_MIN; - } - } else { - register int sectindex = (local->on_type & S_TYP) - S_MIN; - - if (!(local->on_type & S_SCT)) - fatal("bad relocation index"); - if (refers_zero(valu, relo, sects[sectindex].os_flen)) { - valu -= sects[sectindex].os_flen; - valu += outsect[sectindex].os_flen; - valu += relorig[sectindex].org_zero; - } else { - valu += relorig[sectindex].org_flen; - } - valu += outsect[sectindex].os_base; - index += NGlobals + sectindex; - } - *valu_out = valu; - return index; -} - -/* - * This routine relocates a value in a section pointed to by `emit', of - * which the header is pointed to by `head'. Relocation is relative to the - * names in `names'; `relo' tells how to relocate. - */ -relocate(head, emit, names, relo, sects) - struct outhead *head; - char *emit; - struct outname names[]; - struct outrelo *relo; - struct outsect *sects; -{ - long valu; - int sectindex = relo->or_sect - S_MIN; - extern struct outhead outhead; - - /* - * Pick up previous value at location to be relocated. - */ - valu = getvalu(emit + relo->or_addr, relo->or_type); - /* - * Or_nami is an index in the name table of the considered module. - * The name of which it is an index can be: - * - an undefined external or a common name - * - a section name - * - the first name outside! the name table (argh) - */ - if (relo->or_nami < head->oh_nname) { - /* First two cases. */ - relo->or_nami = addrelo(relo, names, sects, &valu); - } else { - /* - * Third case: it is absolute. The relocation of absolute - * names is always 0. We only need to change the index. - */ - relo->or_nami = NLocals + NGlobals + outhead.oh_nsect; - } - - /* - * If relocation is pc-relative, we had to update the value by - * the change in distance between the referencING and referencED - * section. We already added the origin of the referencED section; - * now we subtract the origin of the referencING section. - * Note that the the value to be relocated cannot lie within the - * zero part. - */ - if (relo->or_type & RELPC) - valu -= relorig[sectindex].org_flen+outsect[sectindex].os_base; - - /* - * Now put the value back. - */ - putvalu(valu, emit + relo->or_addr, relo->or_type); - - /* - * We must change the offset within the section of the value to be - * relocated to its offset in the new section. `Or_addr' must again be - * in the normal part, of course. - */ - relo->or_addr += relorig[sectindex].org_flen; -} diff --git a/util/led/save.c b/util/led/save.c deleted file mode 100644 index 807c79e69..000000000 --- a/util/led/save.c +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -/* - * If everything is kept in core, we must save some things for the second pass. - */ - -#include "arch.h" -#include "out.h" -#include "const.h" -#include "assert.h" -#include "memory.h" - -extern bool incore; -extern char *core_alloc(); - -savemagic() -{ - register char *p; - - if (!incore) - return; - - if ((p = core_alloc(ALLOMODL, (long)sizeof(ushort))) != (char *)0) { - *(ushort *)p = ARMAG; - core_position += sizeof(ushort); - } -} - -savehdr(hdr) - struct ar_hdr *hdr; -{ - register char *p; - - if (!incore) - return; - - if ((p=core_alloc(ALLOMODL,(long)sizeof(struct ar_hdr)))!=(char *)0) { - *(struct ar_hdr *)p = *hdr; - core_position += sizeof(struct ar_hdr); - } -} - -long NLChars = 0; /* Size of string area for local names. */ -long NGChars = 0; /* Idem for global names. */ - -/* - * Put the string in cp into the block allocated for the string area. - * Return its offset in this area. We don't use the first char of the string - * area, so that empty strings can be distinguished from the first string. - */ -ind_t -savechar(piece, off) - register int piece; - register ind_t off; -{ - register long len; - register ind_t newoff; - extern int strlen(); - extern ind_t alloc(); - extern ind_t hard_alloc(); - extern char *strcpy(); - - if (off == (ind_t)0) - return 0; - - len = strlen(modulptr(off)) + 1; - if (piece == ALLOLCHR) { - NLChars += len; - if (!incore || (newoff = alloc(piece, len)) == BADOFF) - return BADOFF; - } else { - assert(piece == ALLOGCHR); - NGChars += len; - if ((newoff = hard_alloc(piece, len)) == BADOFF) - return BADOFF; - } - strcpy(address(piece, newoff), modulptr(off)); - return newoff; -} - -/* - * Put the local in `name' in the piece allocated for local names that must - * be saved. `Name' points to a private copy, so will not become invalid after - * allocation, but the string of which name->on_foff is the offset may be - * destroyed, so we save that first. - */ -savelocal(name) - struct outname *name; -{ - ind_t savindex; - struct outname *new; - - if ((savindex = savechar(ALLOLCHR, (ind_t)name->on_foff)) == BADOFF) - return; - - new = (struct outname *) - core_alloc(ALLOLOCL, (long)sizeof(struct outname)); - if (new != (struct outname *)0) { - *new = *name; - new->on_foff = savindex; - } -} diff --git a/util/led/scan.c b/util/led/scan.c deleted file mode 100644 index 32ed1efde..000000000 --- a/util/led/scan.c +++ /dev/null @@ -1,524 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -#ifdef SYMDBUG -#include -#include -#endif SYMDBUG -#include "arch.h" -#include "out.h" -#include "ranlib.h" -#include "const.h" -#include "assert.h" -#include "memory.h" -#include "scan.h" - -#define READ 0 - -#define IND_EMIT(x) (IND_CHAR(x) + (ind_t)align((x).oh_nchar)) -#define IND_RELO(x) (IND_EMIT(x) + (x).oh_nsect * sizeof(ind_t)) -#ifdef SYMDBUG -#define IND_DBUG(x) (IND_RELO(x) + sizeof(ind_t)) -#endif SYMDBUG - -extern long lseek(); -extern bool incore; -extern int infile; -extern int passnumber; - -char *archname; /* Name of archive, if reading from archive. */ -char *modulname; /* Name of object module. */ -long position; /* Byte offset within cuurent input file. */ -#ifdef SYMDBUG -long objectsize; -#endif SYMDBUG - -static long align(); -static char *modulbase; -static long modulsize(); - -/* - * Open the file with name `filename' (if necessary) and examine the first - * few bytes to see if it's a plain file or an archive. - * In case of a plain file, the file pointer is repositioned after the - * examination. Otherwise it is at the beginning of the table of contents. - */ -int -getfile(filename) - char *filename; -{ - struct ar_hdr archive_header; - ushort magic_number; -#ifdef SYMDBUG - struct stat statbuf; - extern int fstat(); -#endif SYMDBUG - extern ushort getushort(); - - archname = (char *)0; - modulname = (char *)0; - - if (passnumber == FIRST || !incore) { - if ((infile = open(filename, READ)) < 0) - fatal("can't read %s", filename); - magic_number = getushort(); - } else { - modulbase = modulptr((ind_t)0); - magic_number = *(ushort *)modulbase; - } - - switch (magic_number) { - case O_MAGIC: -#ifdef SYMDBUG - if (passnumber == FIRST || !incore) { - if (fstat(infile, &statbuf) < 0) - fatal("cannot stat"); - objectsize = statbuf.st_size; - } -#endif SYMDBUG - position = (long)0; - seek((long)0); - modulname = filename; - return PLAIN; - case ARMAG: - archname = filename; - if (passnumber == FIRST) { - read_arhdr(&archive_header); - if (strcmp(archive_header.ar_name, SYMDEF)) - fatal("no table of contents"); - } else if (incore) { - modulbase += sizeof(ushort); - core_position += sizeof(ushort); - } - return ARCHIVE; - default: - fatal("wrong magic number"); - } - /* NOTREACHED */ -} - -/* ARGSUSED */ -closefile(filename) - char *filename; -{ - if (passnumber == FIRST || !incore) - close(infile); -} - -get_archive_header(archive_header) - register struct ar_hdr *archive_header; -{ - if (passnumber == FIRST || !incore) { - read_arhdr(archive_header); - } else { - /* Copy structs. */ - *archive_header = *(struct ar_hdr *)modulbase; - modulbase += sizeof(struct ar_hdr); - core_position += sizeof(struct ar_hdr); - } -#ifdef SYMDBUG - objectsize = archive_header.ar_size; -#endif SYMDBUG -} - -get_modul() -{ - if (passnumber == FIRST) { - scan_modul(); - } else if (!incore) { - read_modul(); - } -} - -/* - * Read module from the current file. If it doesn't fit into core, the strategy - * to keep everything in core is abandoned, but we will always put the header, - * the section table, and the name and string table into core. - */ -static -scan_modul() -{ - bool space; - struct outhead *head; - struct outsect *sect; - - space = all_alloc(); - head = (struct outhead *)modulptr(IND_HEAD); - if (space) { - sect = (struct outsect *)modulptr(IND_SECT(*head)); - get_indirect(head, sect); - } else { - lseek(infile, OFF_NAME(*head) - OFF_EMIT(*head), 1); - } - read_name((struct outname *)modulptr(IND_NAME(*head)), head->oh_nname); - read_char((char *)modulptr(IND_CHAR(*head)), head->oh_nchar); -#ifdef SYMDBUG - if (space) { - get_dbug(*(ind_t *)modulptr(IND_DBUG(*head)), - ojectsize - OFF_DBUG(*head) - ); - } -#endif SYMDBUG -} - -/* - * Allocate space for and read in the header and section table. - * First get the header. With this we can determine what to allocate - * for the rest of the module, and with the rest we can determine what - * to allocate for the section contents. - * If possible, allocate space for the rest of the module. Return whether - * this was possible. - */ -static bool -all_alloc() -{ - struct outhead head; - extern ind_t hard_alloc(); - - if (hard_alloc(ALLOMODL, (long)sizeof(struct outhead)) == BADOFF) - fatal("no space for module header"); - read_head((struct outhead *)modulptr(IND_HEAD)); - /* - * Copy the header because we need it so often. - */ - head = *(struct outhead *)modulptr(IND_HEAD); - return direct_alloc(&head) && indirect_alloc(&head); -} - -/* - * Allocate space for the rest of the direct bytes. - * First allocate the section table and read it in, then allocate the rest - * and return whether this succeeded. - */ -static bool -direct_alloc(head) - struct outhead *head; -{ - ind_t sectindex = IND_SECT(*head); - ushort nsect = head->oh_nsect; - long size, rest; - extern ind_t hard_alloc(); - extern ind_t alloc(); - -#ifdef SYMDBUG - rest = nsect * sizeof(ind_t) + sizeof(ind_t) + sizeof(ind_t); -#else SYMDBUG - rest = nsect * sizeof(ind_t) + sizeof(ind_t); -#endif SYMDBUG - /* - * We already allocated space for the header, we now need - * the section, name an string table. - */ - size = modulsize(head) - sizeof(struct outhead) - rest; - if (hard_alloc(ALLOMODL, size) == BADOFF) - fatal("no space for module"); - read_sect((struct outsect *)modulptr(sectindex), nsect); - - return incore && alloc(ALLOMODL, rest) != BADOFF; -} - -/* - * Allocate space for the indirectly accessed pieces: the section contents and - * the relocation table, and put their indices in the right place. - */ -static bool -indirect_alloc(head) - struct outhead *head; -{ - register int allopiece; - ushort nsect = head->oh_nsect; - ushort nrelo = head->oh_nrelo; - ind_t sectindex = IND_SECT(*head); - ind_t emitoff = IND_EMIT(*head); - ind_t relooff = IND_RELO(*head); -#ifdef SYMDBUG - ind_t dbugoff = IND_DBUG(*head); - extern long objectsize; - long dbugsize = objectsize - OFF_DBUG(*head); -#endif SYMDBUG - - assert(incore); - for (allopiece = ALLOEMIT; allopiece < ALLOEMIT + nsect; allopiece++) { - if (!putemitindex(sectindex, emitoff, allopiece)) - return FALSE; - sectindex += sizeof(struct outsect); - emitoff += sizeof(ind_t); - } -#ifdef SYMDBUG - return putreloindex(relooff, (long)nrelo * sizeof(struct outrelo)) - && - putdbugindex(dbugoff, dbugsize); -#else SYMDBUG - return putreloindex(relooff, (long)nrelo * sizeof(struct outrelo)); -#endif SYMDBUG -} - -/* - * Allocate space for the contents of the section of which the table entry is - * at offset `sectindex'. Put the offset of the allocated piece at offset - * `emitoff'. - */ -static bool -putemitindex(sectindex, emitoff, allopiece) - ind_t sectindex; - ind_t emitoff; - int allopiece; -{ - long flen; - ind_t emitindex; - extern ind_t alloc(); - - flen = ((struct outsect *)modulptr(sectindex))->os_flen; - if ((emitindex = alloc(allopiece, flen)) != BADOFF) { - *(ind_t *)modulptr(emitoff) = emitindex; - return TRUE; - } - return FALSE; -} - -/* - * Allocate space for a relocation table with `nrelobytes' bytes, and put the - * offset at `relooff'. - */ -static bool -putreloindex(relooff, nrelobytes) - ind_t relooff; - long nrelobytes; -{ - ind_t reloindex; - extern ind_t alloc(); - - if ((reloindex = alloc(ALLORELO, nrelobytes)) != BADOFF) { - *(ind_t *)modulptr(relooff) = reloindex; - return TRUE; - } - return FALSE; -} -#ifdef SYMDBUG -/* - * Allocate space for debugging information and put the offset at `dbugoff'. - */ -static bool -putdbugindex(dbugoff, ndbugbytes) - ind_t relooff; - long ndbugbytes; -{ - ind_t dbugindex; - extern ind_t alloc(); - - if ((dbugindex = alloc(ALLORELO, ndbugbytes)) != BADOFF) { - *(ind_t *)modulptr(dbugoff) = dbugindex; - return TRUE; - } - return FALSE; -} -#endif SYMDBUG - -/* - * Compute addresses and read in. Remember that the contents of the sections - * and also the relocation table are accessed indirectly. - */ -static -get_indirect(head, sect) - register struct outhead *head; - register struct outsect *sect; -{ - register ind_t *emitindex; - register int nsect; - register int piece; - ind_t *reloindex; - - emitindex = (ind_t *)modulptr(IND_EMIT(*head)); - nsect = head->oh_nsect; piece = ALLOEMIT; - while (nsect--) { - read_emit(address(piece, *emitindex), sect->os_flen); - piece++; emitindex++; sect++; - } - reloindex = (ind_t *)modulptr(IND_RELO(*head)); - read_relo((struct outrelo *)address(ALLORELO, *reloindex), - head->oh_nrelo - ); -} - -/* - * Set the file pointer at `pos'. - */ -seek(pos) - long pos; -{ - if (passnumber == FIRST || !incore) - lseek(infile, pos, 0); -} - -/* - * A file pointer is advanced automatically when reading, a char pointer - * is not. That's why we do it here. If we don't keep everything in core, - * we give the space allocated for a module back. - */ -skip_modul(head) - struct outhead *head; -{ - register ind_t skip = modulsize(head); - - if (incore) { - core_position += skip; - if (passnumber == SECOND) - modulbase += skip; - } else { - dealloc(ALLOMODL); - core_position = (ind_t)0; - } -} - -/* - * Read in what we need in pass 2, because we couldn't keep it in core. - */ -static -read_modul() -{ - struct outhead *head; - struct outsect *sects; - struct outname *names; - char *chars; - ind_t sectindex, nameindex, charindex; - ushort nsect, nname; - long size; - long nchar; - long skip; - extern ind_t hard_alloc(); - - assert(passnumber == SECOND); - assert(!incore); - if (hard_alloc(ALLOMODL, (long)sizeof(struct outhead)) == BADOFF) - fatal("no space for module header"); - head = (struct outhead *)modulptr(IND_HEAD); - read_head(head); - nsect = head->oh_nsect; sectindex = IND_SECT(*head); - nname = head->oh_nname; nameindex = IND_NAME(*head); - nchar = head->oh_nchar; charindex = IND_CHAR(*head); - skip = OFF_NAME(*head) - OFF_EMIT(*head); -#ifdef SYMDBUG - size = modulsize(head) - (nsect * sizeof(ind_t) + 2 * sizeof(ind_t)); -#else SYMDBUG - size = modulsize(head) - (nsect * sizeof(ind_t) + sizeof(ind_t)); -#endif SYMDBUG - if (hard_alloc(ALLOMODL, size) == BADOFF) - fatal("no space for module"); - - sects = (struct outsect *)modulptr(sectindex); - names = (struct outname *)modulptr(nameindex); - chars = modulptr(charindex); - - read_sect(sects, nsect); - lseek(infile, skip, 1); - read_name(names, nname); - read_char(chars, nchar); -} - -/* - * Align `size' to a multiple of the size of a double. - * This is assumed to be a power of 2. - */ -static long -align(size) - register long size; -{ - size += sizeof(double) - 1; - return size - (size & (sizeof(double) - 1)); -} - -/* - * Compute how many DIRECT bytes must be allocated for a module of which the - * header is pointed to by `head': - * 0. the header, - * 1. the section table, - * 2. the name table, - * 3. the string table, - * 4. for each section the offset of its contents, - * 5. the offset of the relocation table. -#ifdef SYMDBUG - * 6. the offset of the debugging information. -#endif SYMDBUG - */ -static long -modulsize(head) - register struct outhead *head; -{ - return sizeof(struct outhead) + /* 0 */ - head->oh_nsect * sizeof(struct outsect) + /* 1 */ - head->oh_nname * sizeof(struct outname) + /* 2 */ - align(head->oh_nchar) + /* 3 */ - head->oh_nsect * sizeof(ind_t) + /* 4 */ -#ifdef SYMDBUG - sizeof(ind_t) + /* 5 */ - sizeof(ind_t); /* 6 */ -#else SYMDBUG - sizeof(ind_t); /* 5 */ -#endif SYMDBUG -} - -/* ------------------------------------------------------------------------- */ - -/* - * Walk through the relocation table of the current module. We must either walk - * through core or through file. Startrelo() should be called first. - */ - -static struct outrelo *walkrelo; - -startrelo(head) - struct outhead *head; -{ - ind_t reloindex; - - if (incore) { - reloindex = *(ind_t *)(modulbase + IND_RELO(*head)); - walkrelo = (struct outrelo *)address(ALLORELO, reloindex); - } else - lseek(infile, position + OFF_RELO(*head), 0); -} - -struct outrelo * -nextrelo() -{ - static struct outrelo relobuf; - - if (incore) - return walkrelo++; - - read_relo(&relobuf, (ushort)1); - return &relobuf; -} - -/* ------------------------------------------------------------------------- */ - -/* - * Get the section contents in core of which the describing struct has index - * `sectindex'. `Head' points to the header of the module. - */ -char * -getemit(head, sects, sectindex) - struct outhead *head; - struct outsect *sects; - int sectindex; -{ - char *ret; - ind_t off; - extern char *core_alloc(); - - if (!incore) { - ret = core_alloc(ALLOMODL, sects[sectindex].os_flen); - if (ret == (char *)0) - fatal("no space for section contents"); - lseek(infile, position + sects[sectindex].os_foff, 0); - read_emit(ret, sects[sectindex].os_flen); - return ret; - } - /* - * We have an offset in the contents of the final output - * "file" where normally the contents would be. - */ - off = *((ind_t *)(modulbase + IND_EMIT(*head)) + sectindex); - return address(ALLOEMIT + sectindex, off); -} diff --git a/util/led/scan.h b/util/led/scan.h deleted file mode 100644 index a35b015b4..000000000 --- a/util/led/scan.h +++ /dev/null @@ -1,13 +0,0 @@ -/* $Header$ */ - -/* - * Offsets of the pieces of the input module in core. - */ - -#define IND_HEAD ((ind_t)0) -#define IND_SECT(x) (IND_HEAD + sizeof(struct outhead)) -#define IND_NAME(x) (IND_SECT(x) + (x).oh_nsect * sizeof(struct outsect)) -#define IND_CHAR(x) (IND_NAME(x) + (x).oh_nname * sizeof(struct outname)) -#ifdef SYMDBUG -#define OFF_DBUG(x) (OFF_CHAR(x) + (x).oh_nchar) -#endif SYMDBUG diff --git a/util/led/sym.c b/util/led/sym.c deleted file mode 100644 index b257fba6b..000000000 --- a/util/led/sym.c +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -/* - * Symbol table management. - */ - -#include "out.h" -#include "const.h" -#include "memory.h" - -/* - * Symbol table types. Each hash table entry contains the offset of a symbol - * struct. `Sy_name' contains the offset the name in the piece of global - * names. `Sy_next' contains the offset of the next symbol of which the - * corresponding name has the same hash value. - */ -struct symbol { - ind_t sy_name; - ind_t sy_next; -}; - -#define NHASH 256 /* Size of hash table. Should be even. */ - -static ind_t hashtable[NHASH]; - -/* - * Initialize the symbol table. All indices should be noticeably invalid. - */ -init_symboltable() -{ - register ind_t *rap; - - for (rap = hashtable; rap < &hashtable[NHASH]; rap++) - *rap = BADOFF; -} - -/* - * Search for `string' in the symboltable. The hash value of `string' is in - * `hashval'. The linked list belonging to the entry of hashval - * in the hash table is followed. If the names match, a pointer to the outname - * in this element of the list is returned. When a match cannot be found, - * NIL is returned. - */ -struct outname * -searchname(string, hashval) - char *string; - int hashval; -{ - register char *rcp; - register char *namestring; - register ind_t symindex; - register struct outname *name; - register struct symbol *sym; - - symindex = hashtable[hashval]; - while (symindex != BADOFF) { - sym = (struct symbol *)address(ALLOSYMB, symindex); - name = (struct outname *)address(ALLOGLOB, sym->sy_name); - namestring = address(ALLOGCHR, (ind_t)name->on_foff); - rcp = string; - while (*rcp == *namestring++) - if (*rcp++ == '\0') - return name; - symindex = sym->sy_next; - } - /* Not found. */ - return (struct outname *)0; -} - -/* - * Enter a new name in the symbol table. We must copy everything to a - * new entry. `Name' is a private copy, i.e. the pointer to it will not be - * destroyed by allocation. However, the string of which name->on_foff is the - * offset can be destroyed, so we save it first. - */ -entername(name, hashval) - struct outname *name; - int hashval; -{ - ind_t savindex; - ind_t symindex; - ind_t namindex; - struct symbol *sym; - struct outname *newname; - extern ind_t savechar(); - extern ind_t hard_alloc(); - - savindex = savechar(ALLOGCHR, (ind_t)name->on_foff); - symindex = hard_alloc(ALLOSYMB, (long)sizeof(struct symbol)); - namindex = hard_alloc(ALLOGLOB, (long)sizeof(struct outname)); - if (savindex == BADOFF || symindex == BADOFF || namindex == BADOFF) - fatal("symbol table overflow"); - sym = (struct symbol *)address(ALLOSYMB, symindex); - sym->sy_name = namindex; - newname = (struct outname *)address(ALLOGLOB, namindex); - *newname = *name; - newname->on_foff = savindex; - sym->sy_next = hashtable[hashval]; - hashtable[hashval] = symindex; -} - -/* - * Return the index of `name' in the symbol table in the order in which - * it was entered. We need a REAL index, not a byte offset. - */ -ushort -indexof(name) - struct outname *name; -{ - return name - (struct outname *)address(ALLOGLOB, (ind_t)0); -} - -/* - * Assign an integer to the string in p. - * 0 <= hash(p) < NHASH, so it can - and will - be used - * as index in a hash table. - */ -int -hash(p) - register char *p; -{ - register unsigned int h = 0; - register int c; - - while (c = *p++) { - h <<= 2; - h += c; - } - return h & (NHASH - 1); -} diff --git a/util/led/write.c b/util/led/write.c deleted file mode 100644 index bb4014dcc..000000000 --- a/util/led/write.c +++ /dev/null @@ -1,297 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Header$"; -#endif - -/* - * You can choose between two strategies: - * - Open the output file several times, once for each logical part, and - * write to it in multiple places. - * - Open the output file once and seek back and forth to each logical - * part. In this case #define OUTSEEK. - */ - -#include -#include "out.h" -#include "const.h" -#include "assert.h" -#include "memory.h" -#include "orig.h" - -extern long lseek(); - -#define WRITE 1 /* Argument to open(). */ - -/* - * Parts of the output file. - */ -#define PARTEMIT 0 -#define PARTRELO 1 -#define PARTNAME 2 -#define PARTCHAR 3 -#ifdef SYMDBUG -#define PARTDBUG 4 -#else SYMDBUG -#define PARTDBUG PARTCHAR -#endif SYMDBUG -#define NPARTS (PARTDBUG + 1) - -/* - * Call OUTPART() with the part you want to write on as argument, before - * you call OUTWRITE(). - */ -static int outpart = NPARTS; - -#ifdef OUTSEEK - -static int outfile; -static long outseek[NPARTS]; - -#define OUTPART(p) \ - { if (outpart != (p)) {\ - outpart = (p);\ - lseek(outfile, outseek[(p)], 0);\ - }\ - } -#define OUTSECT(i) \ - { outpart = NPARTS;\ - outseek[PARTEMIT] =\ - outsect[(i)].os_foff + relorig[(i)].org_flen;\ - } -#define OUTWRITE(b, n) \ - { if (write(outfile, (b), (n)) != (n))\ - fatal("write error");\ - outseek[outpart] += (n);\ - } -#define BEGINSEEK(p, o) \ - { outseek[(p)] = (o);\ - } - -#else OUTSEEK - -static int outfile[NPARTS]; - -#define OUTPART(p) \ - { outpart = (p);\ - } -#define OUTSECT(i) \ - { lseek( outfile[PARTEMIT],\ - outsect[(i)].os_foff + relorig[(i)].org_flen,\ - 0\ - );\ - } -#define OUTWRITE(b, n) \ - { if (write(outfile[outpart], (b), (n)) != (n))\ - fatal("write error");\ - } -#define BEGINSEEK(p, o) \ - { lseek(outfile[(p)], (o), 0);\ - } - -#endif OUTSEEK - -extern struct outhead outhead; -extern struct outsect outsect[]; -extern int flagword; -extern struct orig relorig[]; -extern bool bytes_reversed, words_reversed; -extern bool incore; - - -static long offchar; - -/* - * Open the output file according to the chosen strategy. - * Write away the header and section table: they will not change anymore. - */ -begin_write() -{ - register long off; - - openoutput(); - BEGINSEEK(PARTEMIT, (long)0); - wrt_head(&outhead); - wrt_sect(outsect, outhead.oh_nsect); - - off = SZ_HEAD + (long)outhead.oh_nsect * SZ_SECT + outhead.oh_nemit; - - if (flagword & RFLAG) { - /* A relocation table will be produced. */ - BEGINSEEK(PARTRELO, off); - off += (long)outhead.oh_nrelo * SZ_RELO; - } - - if (flagword & SFLAG) - return; - - /* A name table will be produced. */ - BEGINSEEK(PARTNAME, off); - off += (long)outhead.oh_nname * SZ_NAME; - BEGINSEEK(PARTCHAR, off); - offchar = off; /* See wrt_name(). */ -#ifdef SYMDBUG - off += outhead.oh_nchar; - BEGINSEEK(PARTDBUG, off); -#endif SYMDBUG -} - -static -openoutput() -{ -#ifndef OUTSEEK - register int *fdp; -#endif OUTSEEK - extern char *outputname; - - close(creat(outputname, 0666)); -#ifdef OUTSEEK - if ((outfile = open(outputname, WRITE)) < 0) - fatal("can't write %s", outputname); -#else OUTSEEK - for (fdp = &outfile[PARTEMIT]; fdp < &outfile[NPARTS]; fdp++) - if ((*fdp = open(outputname, WRITE)) < 0) - fatal("can't write %s", outputname); -#endif OUTSEEK -} - -static struct outname * -sectname(sectindex) - int sectindex; -{ - static struct outname namebuf; - - namebuf.on_foff = (long)0; /* No string name. */ - namebuf.on_type = (S_MIN + sectindex) | S_SCT; - namebuf.on_desc = 0; - namebuf.on_valu = outsect[sectindex].os_base; - - return &namebuf; -} - -/* - * Write out the symbol table and the section names. - */ -end_write() -{ - register ushort cnt; - register struct outname *name; - register int sectindex; - extern ushort NGlobals; - - assert(!incore); - assert(!(flagword & SFLAG)); - cnt = NGlobals; - name = (struct outname *)address(ALLOGLOB, (ind_t)0); - while (cnt--) { - if (name->on_foff != (long)0) { - name->on_mptr = address(ALLOGCHR, (ind_t)name->on_foff); - } else { - name->on_mptr = (char *)0; - } - wrt_name(name); - name++; - } - - for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++) - wrt_name(sectname(sectindex)); -} - -static -wrt_head(head) - register struct outhead *head; -{ - assert(!incore); - OUTPART(PARTEMIT); - if (bytes_reversed || words_reversed) - swap((char *)head, SF_HEAD); - OUTWRITE((char *)head, SZ_HEAD); - /* - * Swap back because we will need it again. - */ - if (bytes_reversed || words_reversed) - swap((char *)head, SF_HEAD); -} - -static -wrt_sect(sect, cnt) - register struct outsect *sect; - register ushort cnt; -{ - assert(!incore); - OUTPART(PARTEMIT); - while (cnt--) { - if (bytes_reversed || words_reversed) - swap((char *)sect, SF_SECT); - OUTWRITE((char *)sect, SZ_SECT); - /* - * Swap back because we will need it again. - */ - if (bytes_reversed || words_reversed) - swap((char *)sect, SF_SECT); - sect++; - } -} - -/* - * We don't have to worry about byte order here. - */ -wrt_emit(emit, sectindex, cnt) - register char *emit; - int sectindex; - register long cnt; -{ - register int n; - - assert(!incore); - OUTPART(PARTEMIT); - OUTSECT(sectindex); - while (cnt) { - n = cnt >= BUFSIZ ? BUFSIZ : cnt; - OUTWRITE(emit, n); - emit += n; - cnt -= n; - } -} - -wrt_relo(relo) - register struct outrelo *relo; -{ - assert(!incore); - assert(flagword & RFLAG); - OUTPART(PARTRELO); - if (bytes_reversed || words_reversed) - swap((char *)relo, SF_RELO); - OUTWRITE((char *)relo, SZ_RELO); -} - -wrt_name(name) - register struct outname *name; -{ - assert(!incore); - assert(!(flagword & SFLAG)); - if (name->on_mptr != (char *)0) { - register int len = strlen(name->on_mptr) + 1; - - OUTPART(PARTCHAR); - OUTWRITE(name->on_mptr, len); - name->on_foff = offchar; - offchar += len; - } else { - name->on_foff = (long)0; - } - OUTPART(PARTNAME); - if (bytes_reversed || words_reversed) - swap((char *)name, SF_NAME); - OUTWRITE((char *)name, SZ_NAME); -} -#ifdef SYMDBUG - -wrt_dbug(buf, size) - char *buf; - int size; -{ - assert(!incore); - assert(!(flagword & SFLAG)); - OUTPART(PARTDBUG); - OUTWRITE((char *)buf, size); -} -#endif SYMDBUG -- 2.34.1