!! 28-JAN-81
! **************************************************************
! * *
! * PERKIN-ELMER 32-BIT SERIES IMP COMPILER *
! * INTERMEDIATE CODE ASSEMBLER *
! * *
! * (GENERAL SERVICE VERSION) *
! * *
! * C.H. WHITFIELD *
! * 19, REDFORD TERRACE *
! * COLINTON, *
! * EDINBURGH EH13-0BT *
! * *
! * COPYRIGHT (c) MAY 1ST. 1980 *
! * ALL RIGHTS RESERVED *
! * *
! **************************************************************
! Pass 3 for 7/32 Imp
! ===========
! N.B. All loader-visible addresses generated by pass2 are in units
! of halfwords.
! ===========
! ****Compatibility header: to disappear with old-format EXE files
constinteger h8 = 8
!
begin
include "Sysinc:Com.inc"
constinteger direct=1, object=2
constinteger report=0
! N.B. <0 for diagnostic tracing, >0 for extra details of dumped code
constinteger diagnostic = 0
constinteger register template = x'7DEF'; ! wsp, code, gla, link
constinteger max tag=2050
constinteger max ref=2900
constinteger max proc=255
constinteger bmax = 8; ! no. of DA buffers available to phase 2
constinteger safe pc rel = 6500; ! 'SAFE' limit in stretch routines q.v.
! Parameters related to diagnostic table generation
constinteger indirect = x'4000'
constinteger line diag limit = 31
constinteger proc header=1, diag entry=0, linkage name=-1; ! 'descriptions'
constinteger none = 0, partial = 1, full = 2
owninteger diags = full, hide = 0
constinteger main prog = x'4000'; ! main program marker in event chain
conststring (3) main ep = "%GO"; ! must match pass 2
conststring (6) trace ep = "$TRACE"; ! likewise
constinteger init lit = 4; ! halfwords: must not exceed pass 2 value
!********
constshortinteger max prim = 52
constshortintegerarray prim(1:1018) = c
x'026F',x'0215',x'0224',x'0035',x'0064',x'0087',x'00D7',x'015A',x'00C1',
x'0232',x'029A',x'0160',x'02B3',x'02C7',x'02E7',x'030A',x'01C5',x'01F5',
x'01AB',x'0335',x'02AA',x'0294',x'028E',x'0278',x'0288',x'0315',x'0188',
x'0194',x'02A2',x'0051',x'0251',x'0265',x'0244',x'019E',x'03AF',x'03CD',
x'03DC',x'03EC',x'0000',x'0000',x'0000',x'0000',x'0000',x'0000',x'0000',
x'0000',x'0000',x'0000',x'039C',x'03A3',x'0338',x'033F',x'001B',x'480F',
x'0000',x'2133',x'3402',x'9400',x'9300',x'D331',x'0000',x'C530',x'0080',
x'2138',x'D431',x'0001',x'2135',x'2408',x'2411',x'8883',x'0034',x'0503',
x'2385',x'2401',x'2417',x'8883',x'0034',x'26F2',x'8888',x'001E',x'0012',
x'0512',x'033F',x'D331',x'0000',x'9433',x'3443',x'F830',x'FF00',x'0001',
x'D301',x'4400',x'0000',x'D202',x'4400',x'0000',x'0A43',x'2087',x'030F',
x'0022',x'480F',x'0000',x'2133',x'3402',x'9400',x'9300',x'D331',x'0000',
x'C530',x'0080',x'2138',x'D431',x'0001',x'2135',x'2408',x'2411',x'8883',
x'0034',x'2440',x'0503',x'2383',x'0830',x'2304',x'D301',x'4400',x'0000',
x'D202',x'4400',x'0000',x'2641',x'2731',x'2218',x'430F',x'0002',x'0039',
x'480F',x'0000',x'2133',x'3402',x'9400',x'9300',x'D331',x'0000',x'C530',
x'0080',x'2138',x'D431',x'0001',x'2135',x'2408',x'2411',x'8883',x'0034',
x'D342',x'0000',x'C540',x'0080',x'2134',x'D442',x'0001',x'223B',x'0A43',
x'C540',x'0100',x'2185',x'2401',x'2413',x'8883',x'0034',x'0B04',x'2315',
x'2401',x'2417',x'8883',x'0034',x'D242',x'0000',x'0B43',x'0A42',x'2450',
x'2308',x'D301',x'4500',x'0001',x'D204',x'4500',x'0001',x'2651',x'2731',
x'2218',x'430F',x'0002',x'0015',x'2441',x'D331',x'0000',x'D302',x'0000',
x'0B30',x'231B',x'0A03',x'2309',x'D351',x'4400',x'0000',x'D452',x'4400',
x'0000',x'023F',x'2641',x'2701',x'2219',x'0833',x'030F',x'0082',x'735F',
x'0000',x'9465',x'1058',x'2133',x'3452',x'9455',x'9355',x'1068',x'2133',
x'3464',x'9466',x'9366',x'D0B7',x'0000',x'D3B3',x'0000',x'C5B0',x'0080',
x'2134',x'D4B3',x'0001',x'2339',x'D301',x'0000',x'C500',x'0080',x'2138',
x'D401',x'0001',x'2135',x'2408',x'2411',x'8883',x'0034',x'0BB0',x'4210',
x'80A8',x'24C0',x'0800',x'4330',x'8038',x'D301',x'0001',x'D403',x'4C00',
x'0001',x'2339',x'26C1',x'05BC',x'2286',x'4300',x'808A',x'D301',x'0001',
x'2207',x'08E3',x'0AEC',x'D3D1',x'0000',x'27D1',x'D30E',x'4D00',x'0001',
x'D401',x'4D00',x'0001',x'203E',x'27D1',x'2028',x'0822',x'2334',x'055C',
x'4280',x'8062',x'08DC',x'0844',x'233A',x'D301',x'0000',x'0AC0',x'D3E3',
x'0000',x'0BEC',x'056E',x'4280',x'804A',x'0822',x'233C',x'D2D2',x'0000',
x'2307',x'D303',x'4D00',x'0001',x'D202',x'4D00',x'0001',x'27D1',x'2217',
x'0844',x'4330',x'801C',x'D2E4',x'0000',x'0AC3',x'24D0',x'2308',x'D30C',
x'4D00',x'0001',x'D204',x'4D00',x'0001',x'26D1',x'27E1',x'2218',x'2501',
x'D1B7',x'0000',x'430F',x'0002',x'2400',x'2205',x'D1B7',x'0000',x'2401',
x'2417',x'8883',x'0034',x'0005',x'023F',x'2407',x'2410',x'8883',x'0034',
x'0027',x'D301',x'0000',x'C500',x'0080',x'2138',x'D401',x'0001',x'2135',
x'2408',x'2411',x'8883',x'0034',x'0822',x'2326',x'0503',x'2184',x'CB32',
x'FFFF',x'2316',x'0843',x'2405',x'2414',x'8883',x'0034',x'0A21',x'C817',
x'0000',x'D231',x'0000',x'2307',x'D302',x'4300',x'0000',x'D201',x'4300',
x'0001',x'2731',x'2217',x'030F',x'000B',x'1132',x'2307',x'5801',x'4300',
x'0000',x'5002',x'4300',x'0000',x'2734',x'2217',x'030F',x'0009',x'1132',
x'2400',x'2304',x'5002',x'4300',x'0000',x'2734',x'2214',x'030F',x'000C',
x'0B44',x'D301',x'4400',x'0000',x'D402',x'4400',x'0000',x'023F',x'2641',
x'0543',x'2039',x'030F',x'0019',x'0831',x'4932',x'0002',x'212C',x'4B32',
x'0000',x'2119',x'0A33',x'7333',x'4200',x'0004',x'2339',x'0A33',x'0A3E',
x'0303',x'0821',x'2406',x'2413',x'8883',x'0034',x'0821',x'2408',x'2412',
x'8883',x'0034',x'002F',x'D097',x'0000',x'2431',x'2410',x'489F',x'0000',
x'08B4',x'48AF',x'0002',x'58CB',x'0008',x'5BCB',x'0004',x'26C1',x'4210',
x'8030',x'50CB',x'0000',x'1C0C',x'5B1B',x'0004',x'1C2C',x'26BC',x'2791',
x'203F',x'50AB',x'0000',x'1C0A',x'1C2A',x'2633',x'C430',x'FFFC',x'48CF',
x'0000',x'50C4',x'0000',x'D197',x'0000',x'430F',x'0004',x'084B',x'D197',
x'0000',x'2405',x'2413',x'8883',x'0034',x'001F',x'0807',x'0A03',x'590D',
x'0000',x'2325',x'2402',x'2411',x'8883',x'0034',x'0A71',x'5072',x'0000',
x'5042',x'0004',x'2628',x'0870',x'580E',x'000C',x'F500',x'8080',x'8080',
x'023F',x'2450',x'0B53',x'033F',x'5007',x'4500',x'0000',x'2654',x'2034',
x'030F',x'000E',x'0822',x'2315',x'2405',x'2412',x'8883',x'0034',x'2401',
x'2411',x'2302',x'1C03',x'2721',x'2212',x'8888',x'0015',x'000D',x'2401',
x'2F00',x'0801',x'2316',x'2D02',x'2820',x'2400',x'CB01',x'0001',x'033F',
x'2C02',x'2701',x'2203',x'8010',x'2802',x'2114',x'6A00',x'8010',x'2305',
x'6B00',x'800A',x'6A20',x'800A',x'2800',x'2B20',x'030F',x'4600',x'0000',
x'4110',x'0000',x'0000',x'800C',x'2822',x'2114',x'6A20',x'800C',x'2303',
x'6B20',x'8006',x'2E12',x'030F',x'0000',x'4080',x'0000',x'0013',x'480F',
x'0000',x'2133',x'3401',x'9400',x'9300',x'0822',x'2328',x'0502',x'2186',
x'E611',x'4200',x'0000',x'430F',x'0002',x'2406',x'2415',x'8883',x'0034',
x'0009',x'581D',x'0000',x'CB17',x'0200',x'031F',x'2402',x'2411',x'8883',
x'0034',x'0008',x'023F',x'2408',x'2411',x'8883',x'0034',x'0000',x'8080',
x'8080',x'000F',x'0822',x'233A',x'0B10',x'0801',x'EE00',x'001F',x'1D02',
x'0811',x'2113',x'0800',x'033F',x'2405',x'2411',x'8883',x'0034',x'0005',
x'033F',x'2404',x'2412',x'8883',x'0034',x'0005',x'033F',x'2401',x'2415',
x'8883',x'0034',x'0005',x'034F',x'2401',x'2415',x'8883',x'0034',x'0007',
x'D401',x'0000',x'038F',x'2401',x'2417',x'8883',x'0034',x'0007',x'C320',
x'FFE0',x'033F',x'2405',x'2416',x'8883',x'0034',x'0008',x'0800',x'033F',
x'2601',x'033F',x'2401',x'2411',x'8883',x'0034',x'0013',x'5823',x'0004',
x'5912',x'0004',x'2119',x'5912',x'0008',x'2126',x'5C02',x'000C',x'5A13',
x'0000',x'030F',x'0842',x'0821',x'2406',x'2412',x'8883',x'0034',x'001F',
x'5843',x'0004',x'5914',x'0004',x'4210',x'8028',x'5914',x'0008',x'4220',
x'8020',x'5C04',x'000C',x'5924',x'0010',x'211A',x'5924',x'0014',x'2127',
x'0A12',x'5C04',x'0018',x'5A13',x'0000',x'030F',x'0812',x'264C',x'0821',
x'2406',x'2412',x'8883',x'0034',x'0022',x'5853',x'0004',x'5845',x'0000',
x'2741',x'1142',x'0A42',x'0801',x'2410',x'2744',x'5905',x'0004',x'4210',
x'801C',x'5905',x'0008',x'212C',x'0A10',x'5C05',x'000C',x'265C',x'5804',
x'0000',x'0542',x'228F',x'5A13',x'0000',x'030F',x'0845',x'0820',x'2406',
x'2412',x'8883',x'0034',x'000A',x'5843',x'0004',x'5C04',x'000C',x'0A12',
x'5C04',x'0018',x'5A13',x'0000',x'030F',x'001F',x'0847',x'484F',x'0000',
x'732F',x'0002',x'1122',x'0B42',x'0A27',x'583D',x'0000',x'C532',x'0200',
x'2385',x'2402',x'2411',x'8883',x'0034',x'26F4',x'0872',x'F830',x'8080',
x'8080',x'553E',x'000C',x'023F',x'5037',x'4400',x'0000',x'2644',x'2224',
x'030F',x'0002',x'8883',x'0034',x'0006',x'D007',x'002C',x'0867',x'CA70',
x'006C',x'8102',x'005C',x'D007',x'002C',x'584D',x'0008',x'2337',x'5004',
x'0000',x'5014',x'0004',x'5024',x'0008',x'C8A7',x'0040',x'0810',x'2441',
x'ED41',x'0000',x'0813',x'4120',x'805C',x'0855',x'2315',x'083F',x'0813',
x'4120',x'8050',x'4826',x'0002',x'9352',x'1152',x'585A',x'45FF',x'FFEC',
x'0822',x'4210',x'8022',x'7316',x'0008',x'0A11',x'0A1E',x'0931',x'232C',
x'4816',x'0004',x'0414',x'2338',x'D17A',x'0008',x'7316',x'0006',x'0A11',
x'0A1E',x'0301',x'C320',x'4000',x'2138',x'5835',x'0028',x'58E5',x'0024',
x'08A5',x'4300',x'FFB0',x'D107',x'002C',x'8101',x'736E',x'40FF',x'FFFE',
x'0A66',x'0B1E',x'7306',x'4E00',x'0000',x'0A00',x'0856',x'0B50',x'0916',
x'2123',x'0915',x'2128',x'0865',x'221B',x'D107',x'002C',x'2400',x'241F',
x'8101',x'0855',x'0212',x'0A6E',x'0302',x'0006',x'583D',x'0004',x'08C8',
x'0183',x'088C',x'030F',x'000B',x'486F',x'0000',x'26F2',x'085F',x'D057',
x'0000',x'D1DD',x'8887',x'082F',x'08F5',x'0302',x'001D',x'2400',x'C830',
x'001C',x'5841',x'4300',x'0000',x'5852',x'4300',x'0000',x'0865',x'0464',
x'0964',x'2333',x'C600',x'0001',x'0965',x'2333',x'C600',x'0002',x'2734',
x'4310',x'FFDA',x'2460',x'450F',x'0000',x'2132',x'2461',x'430F',x'0002',
x'000E',x'C830',x'001C',x'5801',x'4300',x'0000',x'5602',x'4300',x'0000',
x'5001',x'4300',x'0000',x'2734',x'221A',x'030F',x'000F',x'C830',x'001C',
x'2501',x'5702',x'4300',x'0000',x'5401',x'4300',x'0000',x'5001',x'4300',
x'0000',x'2734',x'221B',x'030F',x'000E',x'C830',x'001C',x'5801',x'4300',
x'0000',x'5402',x'4300',x'0000',x'5001',x'4300',x'0000',x'2734',x'221A',
x'030F'
!********
! ==== control codes ====
constinteger tag defn = 1
constinteger r ref = 2
constinteger p ref = 3
constinteger sw ref = 4
constinteger j ref = 5
constinteger c ref = 6
constinteger code item = 7
constinteger gla item = 8
constinteger line diag = 9
constinteger line reset = 10
constinteger var diag = 11
constinteger code area = 12
constinteger lit area = 13
constinteger lit org = 14
constinteger frame patch = 15
constinteger proc head = 16
constinteger proc end = 17
constinteger prog end = 18
constinteger code rel = 19
constinteger gla rel = 20
constinteger extern = 21
! external reference sub-types
constinteger data spec = 4, data defn = 5
constinteger ep spec = 6, ep defn = 7
! ======== constants associated with code generation ========
constinteger align=3; ! single word alignment (literal area)
constinteger emark = x'8880', tmark = x'8887'
constinteger backwards = X'0100'; ! short jump modifier
constinteger code base = 14; ! code base register
constinteger BZ = X'433E', BZS = X'2330'
constinteger BNZ = X'423E', BNZS = X'2130'
constinteger BM = X'421E', BMS = X'2110'
constinteger BP = X'422E', BPS = X'2120'
constinteger BNP = X'432E', BNPS = X'2320'
constinteger BNM = X'431E', BNMS = X'2310'
constinteger JMP = X'430E', JMPS = X'2300'
constinteger BAL = X'410E'
constshortintegerarray short jump(0:12) =
BZS, BNZS, BMS, BPS, BNPS, BNMS,
BNZS, BZS, BPS, BMS, BNMS, BNPS, JMPS
constshortintegerarray long jump(0:12) =
BZ, BNZ, BM, BP, BNP, BNM,
BNZ, BZ, BP, BM, BNM, BNP, JMP
! == flag bits used in 'REF' table ==
constinteger short=1
constinteger long=2
constinteger pc rel=4
constinteger very=8
constinteger invert=16
constinteger remove=32
constinteger rcall=64
constinteger safe=128
constinteger conditional=256
! == values used in code generation phase ( reftype(k)=0 -> 'REMOVE' ) ==
constinteger sf=1
constinteger rx1=2
constinteger rx2=3
constinteger rx3=4
constinteger sign bit = x'80000000'
constinteger halfword sign = x'FFFF8000'
! ** Purely for accumulating jump instruction statistics
owninteger sfjump=0, rx1jump=0, rx2jump=0, rx13jump=0
! ** For accumulating counts in various bits of program
owninteger localtot=0,localnonsafe=0, globaltot=0,globalnonsafe=0
owninteger buff miss1=0, buff miss2=0, buff miss3=0
! ** for recording timings
integer t0,t1,t2; ! phase 1, phase 2 timing
integer t10, t11, t12; ! local, global stretch timing (inside phase 1)
recordformat reffm(shortinteger tag, link, flags, ca)
recordformat deffm(record (deffm)name link, shortinteger proc,ca)
recordformat procfm(record (procfm)name link,
record (reffm)name ref list,
record (deffm)name def list,
shortinteger base, ca,
static frame, event mask,
display reg, event start,
event finish, ld base,
ld size, vd base,
vd size, Me)
record (procfm)array proc(1:max proc)
record (deffm)array tagdef(1:max tag)
byteintegerarray reftype(1:max ref)
owninteger refs = 0
constrecord (*)name null == (0)
record (procfm)name proc1, last proc; ! ** N.B. proc1 ultimately is prim **
shortintegerarray prim entry(1:max prim)
integer header size, gla size, code size, literal size
integer var diags, line diags
owninteger defns = 0, specs = 0, relocations = 0
integer current line, line incr, ca incr
integer j,k,l
tagdef(j) = 0 for j = 1,1,max tag
prim entry(j) = -1 for j = 1,1,max prim
proc1 == proc(1); proc1 = 0
last proc == proc1
routine phex(shortinteger n)
integer j,k
for j = 12,-4,0 cycle
k = (n>>j)&15
if k < 10 then k = k+'0' else k = k-10+'A'
print symbol(k)
repeat
end
routine error(integer n,p)
select output(report)
print string("*ERROR"); write(n,1)
print symbol(':'); write(p,4)
newline
signal 15,15
end
routine get(integername n)
integer j,k
read symbol(j); read symbol(K)
n = j<<8 ! k
end
routine phase one; ! Input directives and expand jumps
record (reffm)array ref(1:max ref)
record (procfm)name pp, qq
integer procs; procs = 0
integer ca total; ca total = 0
integer extra, n
integer j
routine input directives
owninteger depth = 0
owninteger code = 0, n = 0, ca = 0
record (reffm)name r
record (deffm)name d, dd
record (procfm)name p
integer last ref, this proc, last line
switch dir(1:extern)
depth = depth+1
procs = procs+1
this proc = procs; p == proc(procs); p = 0
P_Me = This proc
p_ld size = diags; ! FRIG: 0 = none, 1 = partial, 2 full
! 0 + ( ( line org + ( link )? )?
p_vd size = 0
if diags > none start ; ! p_vd size set = zero above
p_vd size = 4; ! procedure identifier
p_vd size = 5 if diags = full; ! link required as well
finish
last line = current line; ! ???????
last ref = 0; r == null
cycle
read symbol(code)
-> dir(code) if 0 < code <= extern
!!dir(*):
error(0,code)
dir(proc head): ! <proc index>
read symbol(n); error(1,n) unless n = procs
input directives
continue
dir(proc end): ! <code size> <no. var diags> <static frame size>
! <local display register> <event mask> <event start> <event finish>
get(ca)
get(n)
p_vd size = p_vd size + n if diags = full; ! header+local idents
get(n); p_static frame <- n
p_display reg = next symbol; skip symbol; ! avoid any limited 'read symbol'
get(n); p_event mask <- n
get(n); p_event start = n; ! tag no
get(n); p_event finish = n; ! tag no
depth = depth-1; return if depth = 0
p_ca = ca+2; ! size + basic event header
p_ca = p_ca+3 if p_event mask # 0; ! full form required
ca total = ca total + ca
! *** reverse reference list - should grow it forwards ***
if not r == null start
n = last ref; last ref = 0
while n # 0 cycle
r == ref(n)
k = r_link; r_link = last ref
last ref = n
n = k
repeat
finish
p_ref list == r
last proc_link == p; last proc == p
return
dir(tag defn): ! <tag no> <ca> *N.B. switch defns. have x'8000' bit set*
get(j); get(ca)
n = j&x'7FFF'; ! mask out 'switch' bit
error(3,n) unless 0 < n <= max tag
d == tag def(n)
if not d_link == null start ; ! already defined
error(4,n) if j&x'8000' = 0; ! not a switch tag so it's an error
! remove existing entry so it can be redefined
if not p_def list == d start
dd == p_def list
dd == dd_link while not dd_link == d
dd_link == d_link
else
p_def list == d_link
finish
finish
d_proc = this proc; d_ca = ca
d_link == p_def list
p_def list == d
continue
dir(r ref): ! <n> <ca>
code = r call + long; -> ref ref
dir(j ref):
code = short; -> ref ref
dir(c ref):
code = short + conditional
ref ref:
get(n); get(ca)
error(5,n) unless 0 < n <= max tag
error(6,n) if refs = max ref
refs = refs+1
r == ref(refs)
r_link = last ref; last ref = refs
r_tag = n
r_ca = ca
r_flags = code
continue
dir(sw ref): ! <n> <ca> * * * IGNORED * * *
get(n); get(ca)
continue
dir(p ref): ! <n> <ca>
get(n); get(ca)
prim entry(n) = -2
continue
dir(line reset):
get(n); current line = n-1
dir(line diag):
current line = current line+1
if diags = full start
p_ld size = p_ld size + 1
p_ld size = p_ld size + 1 unless c
0 <= current line-last line <= line diag limit
finish
last line = current line
continue
repeat
end ; ! input directives
routine set prim(integer n)
integer a,j,k,base,to
error(9,n) unless 0 < n <= max prim
return if prim entry(n) >= 0
base = proc1_ca; ! current size of prim package
j = prim(n); ! entry to pointer table
k = prim(j); ! size of this prim routine
if k&x'8000' # 0 start ; ! routine to be full-word aligned
base = (base+1)&(¬1)
finish
k = k & x'7FFF'; ! strip 'align' bit
prim entry(n) = base
proc1_ca = base + k*(2//2); ! halfwords
to = j+k; ! N.B. j+1:to inclusive
while j # to cycle
j = j+1; a = prim(j)&x'FFFF'
if a&x'FFF0' = emark and a # tmark start
j = j+1; a = prim(j)
set prim(a) if prim entry(a) < 0
finish
repeat
end ; ! set prim
routine local stretch(record (procfm)name p)
record (deffm)name d,dd
record (reffm)name r
integer j,n,mod
return if p_ref list == null; ! no references !!
cycle
n = 0; mod = 0
r == p_ref list
cycle
local tot = local tot+1; ! *** monitoring only ***
r_ca = r_ca + mod
if r_flags&(long!rcall!safe) = 0 start
local nonsafe = local nonsafe+1; ! *** monitoring only ***
d == tagdef(r_tag)
j = r_ca
unless j-30//2 <= d_ca <= j+30//2 start
n = 1; mod = mod + (2//2)
p_ca = p_ca + (2//2)
r_flags = r_flags ! long
if j+2-16384//2 <= d_ca <= j+2+16384//2-1 start
r_flags = r_flags ! pc rel
r_flags = r_flags ! safe if |(j-d_ca)| <= safe pc rel
finish
dd == p_def list
cycle
exit if dd == null or dd_ca <= r_ca
dd_ca = dd_ca+(2//2)
dd == dd_link
repeat
finish
finish
exit if r_link = 0
r == ref(r_link)
repeat
exit if n = 0
repeat
end ; ! local stretch
routine global stretch(record (procfm)name p, integername extra)
record (procfm)name pp
record (deffm)name d,dd
record (reffm)name r
integer j,k,x,n,mod,me
extra = 0 and return if p_ref list == null
x = 0
cycle
n = 0; mod = 0
r == p_ref list; Me = P_Me
cycle
global tot = global tot+1; ! *** monitoring only ***
r_ca = r_ca + mod
if r_flags&(safe!very) = 0 start
global nonsafe = global nonsafe+1; ! *** monitoring only ***
d == tagdef(r_tag)
j = p_base + r_ca
! ****** This wants cleaning up ******
if D_Proc # Me or R_Flags&rcall # 0 start
k = proc(d_proc)_base + d_ca
if j+2-16384//2 <= k <= j+2+16384//2-1 start
r_flags = r_flags ! pc rel
r_flags = r_flags ! safe if |(j-k)| <= safe pc rel
-> NEXT if R_Flags&Long # 0
finish
else
k = p_base + d_ca
finish
-> NEXT if j-30//2 <= k <= j+30//2; ! short form adequate
if r_flags&long = 0 start
r_flags = r_flags ! long
if j+2-16384//2 <= k <= j+2+16384//2-1 start
r_flags = r_flags ! pc rel
r_flags = r_flags ! safe if |(j-k)| <= safe pc rel
finish
else if (r_flags & pc rel = 0 and not 0 <= k <= 16383//2) c
or (r_flags & pc rel # 0 c
and not j+2-16384//2 <= k <= j+2+16384//2-1)
if 0 <= k <= 16383//2 start
r_flags = r_flags & (¬pc rel)
-> NEXT
finish
r_flags = r_flags ! very
else
-> NEXT
finish
!************************************
n = 1; x = x+(2//2); mod = mod+(2//2)
p_ca = p_ca + (2//2)
dd == p_def list
cycle
exit if dd_ca <= r_ca
dd_ca = dd_ca + (2//2)
dd == dd_link
repeat
pp == p
cycle
pp == pp_link; exit if pp == null
pp_base = pp_base+(2//2)
repeat
finish
NEXT:
exit if r_link = 0
r == ref(r_link)
repeat
exit if n = 0
repeat
extra = x
end ; ! global stretch
routine condense
constbyteintegerarray m(0:15) =
SF, SF,
! 0 1
RX1, RX1,
! 2 3
RX2, RX2, RX2, RX2,
! 4 5 6 7
RX3, RX3, RX3, RX3, RX3, RX3, RX3, RX3
! 8 9 10 11 12 13 14 15
integer j,f
for j = 1,1,refs cycle
f = ref(j)_flags
if f&remove # 0 start
reftype(j) = 0
else
reftype(j) = m(f&15) ! ( f & (invert+rcall) )
finish
repeat
if diagnostic < 0 start
for j = 1,1,refs cycle
if (j-1)&15 = 0 start
newline; write(j,-4); print string(": ")
finish
write(reftype(j),2)
repeat
newlines(2)
finish
end ; ! condense
! === for diagnostics only ===
routine dump tags
integer k
integerfn tagno(record (deffm)name d)
integer k
for k = 1,1,max tag cycle
result = k if tagdef(k) == d
repeat
signal 15,15
end
routine dump proc(integer n)
record (procfm)name p
record (deffm)Name d
integer k; k = 0
p == proc(n)
print string(" base"); write(p_base,1)
print string(" size"); write(p_ca,1)
newline
d == p_deflist
while not d == null cycle
write(tagno(d),3); print symbol(':')
write(d_ca,0)
k = k+1
newline if k&7 = 0
d == d_link
repeat
newline if k&7 # 0
end
for k = 1,1,procs cycle
newline; print string("proc"); write(k,1)
dump proc(k)
repeat
end ; ! dump tags
select input(direct)
current line = 0
input directives
last proc_link == null
readsymbol(j)
error(-1, j) unless j = prog end
! read next six halfwords defining various sizes for last block:
! <code size> <literal size> <gla size> <defns> <specs> <relocations>
!===== size in halfwords
get(code size); get(literal size); get(gla size)
!===== no. of items
get(defns); get(specs); get(relocations)
error(8,ca total) if code size # ca total
for j = 1,1,max prim cycle
set prim(j) if prim entry(j) = -2
repeat
proc1_ca = proc1_ca+2; !event marker+link
dump tags if diagnostic < 0
t10 = cpu time; ! *** monitoring only ***
! Initial stretching and block allocation
! no diags in perm == proc1
!!! proc1_ld size = 0
!!! proc1_vd size = 0
pp == proc1
cycle
qq == pp_link; exit if qq == null
local stretch(qq)
qq_base = qq_base + pp_base + pp_ca
qq_ld base = pp_ld base + pp_ld size
qq_vd base = pp_vd base + pp_vd size
pp == qq
repeat
dump tags if diagnostic < 0
t11 = cpu time; ! *** monitoring only ***
! Routine calls and final stretch
cycle
n = 0
pp == proc1
cycle
pp == pp_link; exit if pp == null
global stretch(pp,extra)
if extra # 0 start
n = n+1
pp_ca = pp_ca + extra
qq == pp
cycle
qq == qq_link; exit if qq == null
qq_base = qq_base + extra
repeat
finish
repeat
exit if n = 0
repeat
dump tags if diagnostic < 0
t12 = cputime; ! *** monitoring only ***
condense; ! from ref(k)_flags -> reftype(k)
line diags = last proc_ld base + last proc_ld size
var diags = last proc_vd base + last proc_vd size
code size = last proc_base + last proc_ca
end ; ! phase one
routine phase two
! generate final object file using 'tag defn' and 'ref type' tables
recordformat bfm(record (bfm)name link, integer block, c
shortintegerarray b(0:255))
recordformat sfm(integer zero addr, lower, upper, ca)
record (sfm) code, gla, ldiag, vdiag, reloc, defn, spec
constinteger bmax = 8; ! no. of da buffers (at least 2 !!)
record (bfm)array buffpool(1:bmax)
record (bfm)name buff list, bp
recordformat hdfm(shortinteger p1,p2)
recordformat headerfm(shortinteger pure size,gla size, code disp, c
lit disp, registers, main ep, c
record (hdfm) reloc, defn, spec, ldiag, vdiag)
record (headerfm) header; constinteger basic header=18; ! ** halfwords **
! formats associated with external linkage
recordformat namefm(shortinteger n1a,n1b,n2a,n2b)
recordformat xdeffm(record (namefm) n, integer ep)
recordformat specfm(integer code, gla, link)
recordformat descriptionfm(integer base,disp,type,size,form,otype, c
data size, shortinteger ident len, string (12) sym)
record (descriptionfm) xd
integer this proc; this proc = 0
integer total blocks
integer op, cond, tag, extra
integer ref; ref = 0
integer event link, ldiag link, vdiag link, defn link, spec link, asynch link
integer trace patch = 0; ! point in perm to patch in jump to $TRACE
integer j,k,l
! =================== SYSTEM DEPENDENT =====================
recordformat parmfm(shortinteger dsno,dact,ssno,sact, c
integer p1,p2,p3,p4,p5,p6)
owninteger da key = 0
constinteger da read = 9, da write = 10
routine open da(string (31)name fd, integer blocks)
record (parmfm) p,q
string(addr(p_sact)) = fd; svc(17,p); ! pack
if p_p2 < 0 start
print string(fd."?"); newline
stop
finish
q = p
p_dact = 14; svc(20,p); ! delete
p = q; p_p5 = blocks
p_dact = 2; svc(20,p); ! create
if p_p6 >= 0 start
p = q
p_p5 = 1; !permit write
p_dact = 6; svc(20,p); ! open da
da key = p_p5 and return if p_p6 >= 0
finish
print string("open da: ".string(addr(p_p1))); newline
stop
end
routine close da
record (parmfm) p
p_p5 = da key
p_dact = 11; svc(20,p)
da key = 0
return if p_p6 >= 0
print string("close da: ".string(addr(p_p1))); newline
stop
end
routine block io(record (bfm)name block, integer iofn)
record (parmfm) p
p_p4 = addr(block_b(0))
p_p5 = da key
p_p6 = block_block; ! block number req'd
p_dact = iofn; svc(20,p)
return if p_p6 >= 0
print string("block io: ".string(addr(p_p1))); write(block_block,1)
newline
signal 15,15
end
! ==========================================================
! Initialise buffer pool
buff list == null
for j = 1,1,bmax cycle
bp == buff list
buff list == buffpool(j)
buff list_block = -1; buff list_link == bp
repeat
! Initialise control records
routine set section(record (sfm)name sect, integer sect size, c
record (hdfm)name hd)
sect_zero addr = header size; header size = header size + sect size
sect_lower = 0
sect_upper = sect size
sect_ca = 0
hd_p1 = sect_zero addr; hd_p2 = 0
end ; ! set section
header size = basic header
defns = defns*(3*2); ! 3 fullwords each
specs = specs*(2*2); ! 2 fullwords each
relocations = relocations*((2//2)); ! 1 halfword each
literal size = (literal size + 3)&(¬3); ! double word align
code size = code size + proc1_ca; ! allow for prim
! N.B. == defn and spec are fullword aligned in output file ==
set section(defn,defns,header_defn)
set section(spec,specs,header_spec)
set section(reloc,relocations,header_reloc)
set section(ldiag,line diags,header_ldiag)
set section(vdiag,var diags,header_vdiag)
header size = (header size+3)&(¬3); ! align literals + code
code_zero addr = header size + literal size
code_lower = -literal size
code_upper = code size
code_ca = 0
gla_zero addr = (code_zero addr + code size + h8 + 255)&(¬255); ! block align
gla_lower = 0
gla_upper = gla size
gla_ca = 0
header_registers = register template
header_main ep = -1; ! default: reset if a main program
header_code disp = code_zero addr; ! within-file disp.
header_lit disp = header size; ! within-file disp.
header_pure size = code_zero addr + code size
header_gla size = gla size
total blocks = (gla_zero addr + gla size + 255) >> 8
header_reloc_p2 = relocations; ! no. of halfwords
header_defn_p2 = defns
record (bfm)map buff(integer addr)
record (bfm)name this,last
integer block
block = addr>>8; ! ** N.B. halfword addressing units, 512 byte block **
result == buff list if block = buff list_block
buff miss1 = buff miss1+1; ! *** monitoring only ***
if diagnostic < 0 start
printstring("block"); write(block,1); newline
finish
last == buff list
cycle
buff miss3 = buff miss3+1; ! *** monitoring only ***
this == last_link
-> promote if this_block = block
exit if this_link == null
last == this
repeat
if this_block < 0 start ; ! buffer still free
this_block = block
else
block io(this,da write)
this_block = block
block io(this,da read)
buff miss2 = buff miss2+1; ! *** monitoring only ***
finish
promote:
last_link == this_link
this_link == buff list
buff list == this
result == buff list
end ; ! of 'buff'
routine flush buffers
record (bfm)name this
integer k
this == buff(0)
if h8 # 0 start
this_b(0) = (header_pure size + h8 + 255)//256
this_b(1) = (header_gla size + 255)//256
this_b(2) = x'4321'; ! new format identifier
this_b(3) = 0; this_b(4) = 0; this_b(5) = 0
this_b(6) = 0; ! flags
this_b(7) = 0; ! stack
finish
for k = 0,1,basic header-1 cycle
this_b(k+h8) = short integer(addr(header)+k*2)
repeat
this == buff list
cycle
block io(this,da write) if this_block >= 0
this == this_link
exit if this == null
repeat
end ; ! flush buffers
routine origin(record (sfm)name section, integer org)
if diagnostic < 0 start
if diagnostic <= -2 start
print string("ORG:"); write(org,1)
write(section_lower,6); write(section_upper,1)
newline
finish
finish
section_ca = org and return if section_lower <= org <= section_upper
error(25,org)
end
routine put(record (sfm)name section, shortinteger item)
record (bfm)name bp
integer addr
owninteger last = -1
addr = section_zero addr + section_ca
addr = addr + h8 unless section == gla
if diagnostic < 0 start
if diagnostic < -2 start ; ! two-stage test for speed
newline if addr # last+1
last = addr
write(addr,4); print string(": "); phex(item)
newline
finish
finish
bp == buff(addr)
bp_b(addr&255) = item
section_ca = section_ca + 1
end ; ! of 'put'
routine put name(record (sfm)name sect)
integer j; shortinteger half
integerfn ch(integer sym)
result = sym-'A'+1 if 'A' <= sym <= 'Z'
result = sym-'a'+1 if 'a' <= sym <= 'z'; ! ** lower case alphabet **
result = sym-'0'+27 if '0' <= sym <= '9'
result = sym-'#'+37 if '#' <= sym <= '%'; ! 37='#', 38='$', 39='%'
result = 0 if sym = ' '
result = -1
end ; ! ch
routine pack3(integer k, shortintegername n)
integer p,q,r
p = charno(xd_sym,k); q = charno(xd_sym,k+1); r = charno(xd_sym,k+2)
n <- ( (ch(p)*40 + ch(q))*40 + ch(r) ); ! ugh!!!
end ; ! pack3
charno(xd_sym,j) = ' ' for j = length(xd_sym)+1,1,xd_ident len
for j = 1,3,xd_identlen-2 cycle
pack3(j,half); put(sect,half)
repeat
end ; ! put name
routine set description(integer desc type)
integer sym,j,k,l, char
read symbol(k)
l = k; l = 12 if l > 12
length(xd_sym) = l
for j = 1,1,l cycle
readsymbol(char)
char = char - 'a' + 'A' if c
'a' <= char <= 'z'
charno(xd_sym,j) = char
repeat
k = k-l
skip symbol and k = k-1 while k > 0
xd_ident len = 12; ! assume full 12-character ident.
return if desc type = proc header; ! only ident. present
xd_identlen = 6 if l <= 6 and desc type = diag entry
read symbol(xd_otype)
read symbol(k)
xd_type = k>>4; xd_form = k&15
read symbol(j); get(k)
xd_base = j>>4
xd_disp = (j&15)<<16 + (k&x'FFFF')
if diagnostic < 0 start
print string(xd_sym.": "); write(xd_identlen,1)
write(xd_base,1); write(xd_disp,4)
write(xd_type,3); write(xd_form,1); write(xd_otype,1)
newline
finish
end ; ! set description
routine insert prims
integer j,k,l,m,to
for j = 1,1,max prim cycle
k = prim entry(j)
if k >= 0 start
if diagnostic < 0 start
print string("prim"); write(j,1); print symbol(' '); phex(k)
newline
finish
origin(code,proc1_base + prim entry(j))
k = prim(j)
to = k + prim(k) & x'7FFF'; ! strip 'align' bit
while k # to cycle
k = k+1; m = prim(k)&x'FFFF'
if m&x'FFF0' # emark start
put(code,m)
else if m = tmark; ! trace routine external call
trace patch = code_ca
put(code,m)
else
if m&15 = 8 start
put(code, jmp)
else
put(code, bal + (m&15)<<4)
finish
k = k+1; m = prim(k)
l = prim entry(m); ! pointer to referenced routine
error(15,j) if l < 0
put(code,(proc1_base+l)*2); ! byte displacement
finish
repeat
finish
repeat
asynch link = prim entry(max prim); ! *** must be last entry in perms ***
end ; ! 'insert prims'
routine plant code ref
integer j,k,l,t,there
record (deffm)name d
switch format(SF:RX3)
ref = ref+1; t = reftype(ref)
d == tagdef(tag)
there = proc(d_proc)_base + d_ca + extra
cond = cond+6 if t&invert # 0
op = long jump(cond) if t&rcall = 0
-> format(t&7)
format(SF): ! short format
sfjump = sfjump+1
l = 0; k = there-code_ca; ! halfword disp. req'd here
if k < 0 start
l = backwards; k = -k
finish
error(200,code_ca) if k > 15; ! error in reference table
put(code,(short jump(cond) !! l) + k)
return
format(RX1):
rx1jump = rx1jump+1
format(RX3):
rx13jump = rx13jump+1
k = (there - proc1_base)*2; ! byte disp. from code base
put(code, op)
if t&7 = RX3 start
put(code, x'4000'!((k>>16)&15))
else
error(201,code_ca) unless 0 <= k <= 16383
finish
put(code,k&x'FFFF')
return
format(RX2):
rx2jump = rx2jump+1
k = (there - (code_ca+4//2))*2
error(202,code_ca) unless -16384 <= k <= 16383
put(code, op&(¬15))
put(code,halfword sign ! k)
end ; ! 'plant code ref'
routine dump code
owninteger depth = 0
integer last line, last ca
integer code reset
owninteger lit reset; ! no recursion!! - literals are not exbedded
owninteger last spec = 0, gla skip = 0
record (procfm)name p
integer cca, lca, vca
integer k,c,half
switch dir(1:extern)
depth = depth+1
this proc = this proc+1
p == proc(this proc)
origin(code,p_base); origin(ldiag,p_ldbase); origin(vdiag,p_vdbase)
last ca = code_ca; last line = 0
if this proc # 1 start ; ! its a recursive call
! DIAGS: dump procedure line origin and identifier
get(last line); set description(proc header)
if diags # none start
k = last line
k = 0 if hide # 0
put(ldiag,k); put name(vdiag)
finish
else ; ! initial (non-recursive) call
if diags # none start
xd_sym = "PERM"; xd_identlen = 12
put(ldiag,0); put name(vdiag)
finish
insert prims
origin(code,proc1_base+proc1_ca-2)
put(code,code_ca - event link); ! link round perm
event link = code_ca - 1
put(code,x'8000'); ! dummy event mask
finish
cycle
read symbol(c)
-> dir(c) if 0 < c <= extern
!!dir(*):
error(12,c)
dir(proc head):
read symbol(k); error(13,k) unless k = this proc
cca = code_ca; lca = ldiag_ca; vca = vdiag_ca
dump code
origin(code,cca); origin(ldiag,lca); origin(vdiag,vca)
continue
dir(proc end):
depth = depth-1
if depth # 0 start ; !not in perm
! dump event chain
put(code,code_ca-event link); ! here relative link to preceding block
event link = code_ca-1
if p_event mask = 0 start
put(code,p_display reg ! halfword sign)
else
put(code,p_display reg)
put(code,p_event mask)
put(code,tagdef(p_event start)_ca + p_base)
put(code,tagdef(p_event finish)_ca + p_base)
finish
finish
! dump line diag. table link
!!!!!!!!!! last line = -line diag limit-1
if diagnostic < 0 start
write(ldiag_ca,1)
write(p_ldbase,1); write(p_ldsize,1); newline
finish
if diags = full start
if depth = 0 start ; !special for perm
put(ldiag, proc1_ldsize)
put(vdiag, proc1_vdsize)
else
put(ldiag, ldiag_ca-ldiag link); ! relative to here
ldiag link = ldiag_ca - 1
put(vdiag, vdiag_ca-vdiag link); ! ... ditto ...
vdiag link = vdiag_ca - 1
finish
k = p_ld base + p_ld size; put(ldiag,0) while ldiag_ca # k; ! zero
finish
return
dir(code area):
lit reset = code_ca
code_ca = code reset
continue
dir(lit area):
code reset = code_ca
code_ca = lit reset
continue
dir(lit org):
get(half)
lit reset = -half
continue
dir(code item):
get(half)
put(code,half)
continue
dir(gla item):
get(half)
gla skip = gla skip-1 and continue if gla skip # 0
put(gla,half)
continue
dir(gla rel):
! Assumed to immediately follow the dumping of the GLA full-word to
! which it refers.
put(reloc,gla_ca-2); ! N.B. -2 halfwords = -4 bytes
continue
dir(code rel):
! As for GLA REL but modifies a word in gla according to the value of
! code base at load time
put(reloc,(gla_ca-2)+1); ! N.B ** odd-numbered halfword => code seg **
continue
dir(frame patch):
origin(code,code_ca-1)
put(code,p_static frame); ! bytes if TRUSTED else fullwords
continue
dir(c ref):
dir(j ref): ! jumps
skip symbol; ! 'code item'
get(half)
cond = half&15; tag = half>>4
extra = 0; ! to match r ref path!!
plant code ref
continue
dir(r ref): ! procedure calls (including %begin-%end blocks)
get(tag)
skip symbol; ! 'code item'
get(op)
skip symbol; ! 'code item'
get(extra)
cond = 0
plant code ref
continue
dir(p ref): ! prim call
skip symbol; ! 'code item'
get(op)
skip symbol; ! 'code item'
get(k)
error(15,k) unless 0 < k <= max prim
put(code,op)
put(code,prim entry(k)*2 ); ! byte disp.
continue
dir(sw ref):
skip symbol; ! 'code item'
get(tag)
k = tag def(tag)_ca; k = k + p_base if k # 0
put(code,k); ! N.B. halfwords relative to code base
continue
dir(line reset):
get(half)
current line = half-1; ! * see below *
dir(line diag):
current line = current line + 1
if diagnostic < 0 start
print string("line"); write(current line,1); write(code_ca,1)
newline
finish
ca incr = code_ca - last ca
continue if ca incr = 0
line incr = current line - last line
unless 0 <= line incr <= line diag limit start
put(ldiag, (current line-1) ! halfword sign ) if diags = full
line incr = 1
finish
put(ldiag, ca incr*(line diag limit+1) + line incr) if diags = full
last line = current line
last ca = code_ca
continue
dir(var diag):
set description(diag entry)
if diags = full start
k = ((xd_type&7)<<4 + xd_base&15)<<4 + (xd_disp>>16)
k = k!halfword sign if xd_identlen # 12; ! ...%if a short ident
k = k!indirect if xd_form = 2; ! %name variable
k = k!x'2000' if xd_type&8 # 0
put(vdiag,k); put(vdiag,xd_disp&x'FFFF')
put name(vdiag)
finish
continue
dir(extern):
! <=== word 1 =====> <======== word 2 ======> <== word 3 =>
! ------------------ ------------ ----------- -------------
! Proc spec: | link to previous | identifier : self-link | x'00000000' |
! ------------------ ------------ ----------- -------------
! ------------------ ------------ ----------- -------------
! Data spec | link to previous | identifier : ????????? | x'80000000' |
! ------------------ ------------ ----------- -------------
read symbol(c); ! type of cross reference
get(xd_data size)
set description(linkage name)
gla skip = 0
if c = ep defn or c = data defn start
k = xd_disp
if c = ep defn start
k = code_ca
if xd_sym = main ep start
p_display reg = p_display reg ! main prog
header_main ep = k
finish
finish
put(defn, defn link); defn link = header_defn_p1 + defn_ca-1; ! file relative
put(defn, k)
put name(defn)
else if c = ep spec or c = data spec
if trace patch # 0 and xd_sym = trace ep start
c = code_ca
origin(code,trace patch)
put(code,gla_ca*2); !halfwords note.
origin(code,c)
finish
k = header_spec_p1 + spec_ca; ! file relative
put name(spec)
put(gla,spec link>>16); put(gla,spec link); ! gla relative back link
spec link = gla_ca - 2
put(gla,k)
put(gla,gla_ca-3); ! halfword disp. of this block into GLA
if c = data spec start
put(gla, -1); put(gla, -1)
else
put(gla, 0); put(gla, 0)
finish
gla skip = 6; ! half words
else
error(170,c)
finish
continue
repeat
end ; ! of 'dump code'
select input(object)
open da(IMPCOM_file,total blocks)
!!!! read symbol(j); put(gla,x'7FFF') %for j = 1,1,j; ! init gla
! Dual standard meantime for first words in gla
read symbol(j); put(gla,x'7FFF') for j = 1,1,j-2
put(gla,0); put(gla,0)
read symbol(j); error(17,j) if j < init lit; ! pass2 INIT LIT value
current line = 0
event link = -1
ldiag link = proc1_ldsize-1
vdiag link = proc1_vdsize-1
defn link = 0
spec link = 0
dump code
readsymbol(j)
error(-2,j) unless j = prog end
origin(code,-init lit); ! = -4: must always dump the exact number
put(code,0); ! *** padding ***
put(code,asynch link); ! signal relative to code base
put(code,header_code disp); ! code base addr - file start addr
put(code,event link)
if diags # full start ; ! no links embedded in tables!!!
if diags = partial start
header_ldiag_p1 = header_ldiag_p1 ! halfword sign
ldiag link = this proc*(2//2); ! halfword size: for use below
vdiag link = this proc*8//2; ! ditto
else ; ! 'none'
header_ldiag_p1 = 0; ! no diag tables present
finish
finish
header_ldiag_p2 = ldiag link; ! ldiag_p1+ldiag_p2 => start of chain
header_vdiag_p2 = vdiag link
header_spec_p2 = spec link; ! GLA relative
header_defn_p2 = defn link; ! N.B. FILE relative
flush buffers
close da
end ; ! phase two
!========================================================================
diags = (IMPCOM_flags >> 8)&7; ! * * * * SYSTEM DEPENDENT * * * *
hide = IMPCOM_flags&x'0800'
!========================================================================
select output(report)
t0 = cpu time; ! *** monitoring only ***
diags = full if diags > full
phase one
t1 = cpu time; ! *** monitoring only ***
phase two
t2 = cpu time; ! *** monitoring only ***
IMPCOM_code = (code size+literal size-proc1_ca)*2
IMPCOM_perm = proc1_ca*2
IMPCOM_gla = gla size*2
IMPCOM_diags = (line diags+var diags)*2
! print string("Jumps:")
! write(sfjump,1); print string(" SF +")
! write(rx1jump,1); print string(" RX1 +")
! write(rx2jump,1); print string(" RX2 +")
! write(rx13jump-rx1jump,1); print string(" RX3 =")
! write(sfjump+rx2jump+rx13jump,1)
! newline; print string("Diagnostic Tables (bytes):")
! print string(" line"); write(line diags*2,1)
! print string(", ident"); write(var diags*2,1)
! newlines(2)
! print string("Millisec s: phase1 "); write(t1-t0,1)
! print string(" phase2"); write(t2-t1,1)
! newline
! %if local tot # 0 %and global tot # 0 %start
! print string("Stretching - safe/total (%) local:")
! write( (local tot-local nonsafe)*100//local tot, 4)
! print string(" global:")
! write( (global tot-global nonsafe)*100//global tot,4)
! newline
! %finish
! spaces(15)
! print string("millisecs:"); write(t11-t10,14); write(t12-t11,13)
! newline
! print string("Total output (halfwords):")
! write(code size+literal size+gla size+var diags+line diags, 1)
! newline
! print string("Disc buffer: searches"); write(buff miss1,1)
! print string(" cache misses"); write(buff miss2,1)
! newline
! print string("Mean search length="); print(buff miss3/buff miss1,1,2)
! newline
endofprogram