Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1996
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
/*
30
			    VERSION INFORMATION
31
			    ===================
32
 
33
--------------------------------------------------------------------------
34
$Header: /u/g/release/CVSROOT/Source/src/installers/680x0/common/weights.c,v 1.1.1.1 1998/01/17 15:55:50 release Exp $
35
--------------------------------------------------------------------------
36
$Log: weights.c,v $
37
 * Revision 1.1.1.1  1998/01/17  15:55:50  release
38
 * First version to be checked into rolling release.
39
 *
40
Revision 1.1.1.1  1997/10/13 12:43:00  ma
41
First version.
42
 
43
Revision 1.3  1997/09/25 06:45:40  ma
44
All general_proc tests passed
45
 
46
Revision 1.2  1997/04/20 11:30:41  ma
47
Introduced gcproc.c & general_proc.[ch].
48
Added cases for apply_general_proc next to apply_proc in all files.
49
 
50
Revision 1.1.1.1  1997/03/14 07:50:20  ma
51
Imported from DRA
52
 
53
 * Revision 1.1.1.1  1996/09/20  10:57:00  john
54
 *
55
 * Revision 1.2  1996/07/05  14:29:51  john
56
 * Changes for spec 3.1
57
 *
58
 * Revision 1.1.1.1  1996/03/26  15:45:19  john
59
 *
60
 * Revision 1.2  94/02/21  16:06:14  16:06:14  ra (Robert Andrews)
61
 * Put in an explicit cast.
62
 *
63
 * Revision 1.1  93/02/22  17:16:59  17:16:59  ra (Robert Andrews)
64
 * Initial revision
65
 *
66
--------------------------------------------------------------------------
67
*/
68
 
69
 
70
#include "config.h"
71
#include "common_types.h"
72
#include "exp.h"
73
#include "expmacs.h"
74
#include "externs.h"
75
#include "shapemacs.h"
76
#include "tags.h"
77
#include "tests.h"
78
#include "utility.h"
79
#include "mach.h"
80
#include "where.h"
81
#include "translate.h"
82
#include "weights.h"
83
 
84
 
85
/*
86
    CONTROL MACROS
87
*/
88
 
89
#define  AVERAGE_LOOP_LENGTH	10
90
 
91
 
92
/*
93
    MAXIMUM AND MINIMUM WEIGHTS
94
*/
95
 
96
#define  cant_use		( ( float ) -1.0e10 )
97
 
98
 
99
/*
100
    NUMBERS OF AVAILABLE REGISTERS
101
*/
102
 
103
#define  wdno		16
104
#define  wano		16
105
#define  wfno		6
106
#define  wno		( wdno + wano + wfno )
107
 
108
 
109
/*
110
    STRUCTURE DEFINITIONS OF weights, wp, explist
111
*/
112
 
113
typedef struct {
114
    float wts [ wno ] ;
115
    long d_used ;
116
    long a_used ;
117
    long f_used ;
118
} weights ;
119
 
120
typedef struct {
121
    weights wt ;
122
    long bkpt ;
123
} wp ;
124
 
125
typedef struct elt {
126
    exp member ;
127
    struct elt *next ;
128
} explist  ;
129
 
130
 
131
/*
132
    BASIC WEIGHTS
133
*/
134
 
135
static weights zeros ;
136
static weights weightsv PROTO_S ( ( exp, explist * ) ) ;
137
 
138
 
139
/*
140
    CURRENT WEIGHTS SCALE FACTOR
141
*/
142
 
143
static float scale ;
144
 
145
 
146
/*
147
    ADD TWO WEIGHT VECTORS
148
*/
149
 
150
static weights add_weights
151
    PROTO_N ( ( w1, w2 ) )
152
    PROTO_T ( weights w1 X weights w2 )
153
{
154
    long i ;
155
    weights r ;
156
    float wa, wb ;
157
    for ( i = 0 ; i < wno ; i++ ) {
158
	wa = ( w1.wts )[i] ;
159
	wb = ( w2.wts )[i] ;
160
	if ( wa == cant_use || wb == cant_use ) {
161
	    ( r.wts )[i] = cant_use ;
162
	} else {
163
	    ( r.wts )[i] = wa + wb ;
164
	}
165
    }
166
    r.d_used = maximum ( w1.d_used, w2.d_used ) ;
167
    r.a_used = maximum ( w1.a_used, w2.a_used ) ;
168
    r.f_used = maximum ( w1.f_used, w2.f_used ) ;
169
    return ( r ) ;
170
}
171
 
172
 
173
/*
174
    INITIALIZE BASIC WEIGHTS
175
*/
176
 
177
void init_weights
178
    PROTO_Z ()
179
{
180
    long i ;
181
    for ( i = 0 ; i < wno ; i++ ) ( zeros.wts )[i] = ( float ) 0.0 ;
182
    zeros.d_used = -1 ;
183
    zeros.a_used = -1 ;
184
    zeros.f_used = -1 ;
185
    return ;
186
}
187
 
188
 
189
/*
190
    MARK A LIST OF EXPS
191
*/
192
 
193
static void markcall
194
    PROTO_N ( ( el, b ) )
195
    PROTO_T ( explist *el X bitpattern b )
196
{
197
    explist *t ;
198
    for ( t = el ; t != null ; t = t->next ) props ( t->member ) |= b ;
199
    return ;
200
}
201
 
202
 
203
/*
204
    WORK OUT WEIGHTS FOR A DECLARATION
205
*/
206
 
207
static wp max_weights
208
    PROTO_N ( ( s, locp, ws, rtype ) )
209
    PROTO_T ( long s X float locp X weights ws X int rtype )
210
{
211
    wp res ;
212
    bool bkset = 0 ;
213
    long i, n ;
214
    long sz = ( s + 31 ) / 32, bk = 1 ;
215
    long q = 0 ;
216
    float *w, *pw ;
217
    long used, total, offset ;
218
 
219
    /* Find values for this register type */
220
    switch ( rtype ) {
221
 
222
	case Dreg : {
223
	    offset = 0 ;
224
	    total = wdno ;
225
	    used = ws.d_used ;
226
	    break ;
227
	}
228
 
229
	case Areg : {
230
	    offset = wdno ;
231
	    total = wano ;
232
	    used = ws.a_used ;
233
	    break ;
234
	}
235
 
236
	case Freg : {
237
	    offset = wdno + wano ;
238
	    total = wfno ;
239
	    used = ws.f_used ;
240
	    break ;
241
	}
242
 
243
	default : {
244
	    error ( "Illegal register type" ) ;
245
	    exit ( EXIT_FAILURE ) ;
246
	}
247
    }
248
    w = &( ws.wts )[ offset ] ;
249
    pw = &( ( res.wt ).wts )[ offset ] ;
250
    n = used + sz + 1 ;
251
    if ( n > total ) n = total ;
252
 
253
    /* Copy ws to res.wt */
254
    for ( i = 0 ; i < wno ; i++ ) ( ( res.wt ).wts )[i] = ( ws.wts )[i] ;
255
    res.wt.d_used = ws.d_used ;
256
    res.wt.a_used = ws.a_used ;
257
    res.wt.f_used = ws.f_used ;
258
 
259
    if ( locp == cant_use ) {
260
	for ( i = 0 ; i < n ; i++ ) pw [i] = cant_use ;
261
	for ( i = n ; i < total ; i++ ) pw [i] = w [i] ;
262
	switch ( rtype ) {
263
	    case Dreg : res.wt.d_used = ws.d_used + sz ; break ;
264
	    case Areg : res.wt.a_used = ws.a_used + sz ; break ;
265
	    case Freg : res.wt.f_used = ws.f_used + sz ; break ;
266
	}
267
	bk = 0 ;
268
    } else {
269
	float loc = locp * ( ( float ) sz ) ;
270
	q = -1 ;
271
	for ( i = 0 ; i < total ; i++ ) {
272
	    if ( w [i] == cant_use ) {
273
		pw [i] = cant_use ;
274
		q = i ;
275
	    } else {
276
		if ( i < ( sz + q ) ) {
277
		    pw [i] = w [i] ;
278
		} else {
279
		    if ( i == ( sz + q ) ) {
280
			if ( loc >= w [i] && used <= q ) {
281
			    pw [i] = loc ;
282
			    bk = i + 1 ;
283
			    bkset = 1 ;
284
			} else {
285
			    pw [i] = w [i] ;
286
			}
287
		    } else {
288
			float z = loc + w [ i - sz ] ;
289
			if ( z >= w [i] ) {
290
			    pw [i] = z ;
291
			    if ( !bkset ) { bk = i + 1 ; bkset = 1 ; }
292
			} else {
293
			    pw [i] = w [i] ;
294
			}
295
		    }
296
		}
297
	    }
298
	}
299
    }
300
    /* Set the breakpoint */
301
    res.bkpt = bk ;
302
    return ( res ) ;
303
}
304
 
305
 
306
/*
307
    WORK OUT WEIGHTS FOR A LIST OF EXPS
308
*/
309
 
310
static weights add_wlist
311
    PROTO_N ( ( re, el ) )
312
    PROTO_T ( exp re X explist *el )
313
{
314
    weights wl1, wl2 ;
315
    if ( re == nilexp ) return ( zeros ) ;
316
 
317
    wl1 = weightsv ( re, el ) ;
318
 
319
    while ( !last ( re ) ) {
320
	re = bro ( re ) ;
321
	wl2 = weightsv ( re, el ) ;
322
	wl1 = add_weights ( wl1, wl2 ) ;
323
    }
324
    return ( wl1 ) ;
325
}
326
 
327
 
328
/*
329
    IS X AN ASSIGNMENT?
330
*/
331
 
332
#define  ass( X )	( name ( X ) == ass_tag || name ( X ) == assvol_tag )
333
 
334
 
335
/*
336
    WORK OUT WEIGHTS FOR e SCALED BY scale AND SET BREAK POINTS
337
*/
338
 
339
static weights weightsv
340
    PROTO_N ( ( e, el ) )
341
    PROTO_T ( exp e X explist *el )
342
{
343
    unsigned char n = name ( e ) ;
344
    switch ( n ) {
345
 
346
	case name_tag : {
347
	    if ( !isglob ( son ( e ) ) ) fno ( son ( e ) ) += scale ;
348
	    /* Add value to the no field of the declaration */
349
	    return ( zeros ) ;
350
	}
351
 
352
	case make_lv_tag : {
353
	    return ( zeros ) ;
354
	}
355
 
356
	case ident_tag : {
357
	    wp p ;
358
	    long sz ;
359
	    shape sha ;
360
 
361
	    /* Starting point for pt list */
362
	    exp t = pt ( e ) ;
363
	    exp d = son ( e ) ;
364
 
365
	    /* Add e to the list of exps */
366
	    explist nel ;
367
	    nel.member = e ;
368
	    nel.next = el ;
369
 
370
	    while ( isvar ( e ) && !isvis ( e ) && t != nilexp ) {
371
		/* Scan along pt list */
372
		if ( !( last ( t ) && name ( bro ( t ) ) == cont_tag ) &&
373
		     !( last ( bro ( t ) ) &&
374
		     ass ( bro ( bro ( t ) ) ) ) )
375
		    /* Make sure it will not go in register */
376
		    setvis ( e ) ;
377
		t = pt ( t ) ;
378
	    }
379
 
380
	    if ( d != nilexp ) {
381
		int sht ;
382
		weights wdef, wbody ;
383
		fno ( e ) = ( float ) 0.0 ;
384
 
385
		/* Work out weights for the body */
386
		wbody = weightsv ( bro ( d ), &nel ) ;
387
 
388
		/* Work out weights for the definition */
389
		if ( name ( d ) == clear_tag ) {
390
		    wdef = zeros ;
391
		} else {
392
		    float old_scale = scale ;
393
		    if ( name ( d ) == name_tag ) scale = fno ( e ) ;
394
		    wdef = weightsv ( d, el ) ;
395
		    scale = old_scale ;
396
		}
397
 
398
		/* Shape information */
399
		sha = sh ( d ) ;
400
		sz = shape_size ( sha ) ;
401
		sht = shtype ( sha ) ;
402
 
403
#if 0
404
		/* Correct producer bug */
405
		if ( name ( sha ) == slonghd && name ( d ) == val_tag &&
406
		     no ( d ) == 0 ) {
407
		    bool fix = 0 ;
408
		    t = pt ( e ) ;
409
		    while ( t != nilexp ) {
410
			exp f = father ( t ) ;
411
			if ( name ( f ) == cont_tag &&
412
			     name ( sh ( f ) ) == ptrhd ) fix = 1 ;
413
			t = ( last ( t ) ? nilexp : pt ( t ) ) ;
414
		    }
415
		    if ( fix ) {
416
			sh ( d ) = ptr_shape ( sha ) ;
417
			sht = Areg ;
418
		    }
419
		}
420
#endif
421
 
422
		if ( isusereg ( e ) ) {
423
		    /* Work out breakpoint */
424
		    p = max_weights ( sz, cant_use, wbody, sht ) ;
425
		    no ( e ) = p.bkpt ;
426
		    if ( no ( e ) == 13 ) error ( "Bad breakpoint" ) ;
427
		    return ( add_weights ( wdef, p.wt ) ) ;
428
		}
429
 
430
		if ( regable ( e ) ) {
431
		    /* Work out breakpoint */
432
		    float loc = fno ( e ) ;
433
		    if ( name ( d ) == name_tag && isusereg ( e ) ) {
434
			loc = ( float ) 1.0 ;
435
		    }
436
		    p = max_weights ( sz, loc, wbody, sht ) ;
437
		    no ( e ) = p.bkpt ;
438
		    return ( add_weights ( wdef, p.wt ) ) ;
439
		}
440
 
441
		no ( e ) = 16 ;
442
		return ( add_weights ( wdef, wbody ) ) ;
443
	    }
444
	    return ( zeros ) ;
445
	}
446
 
447
	case labst_tag : {
448
	    /* Add e to list of exps */
449
	    explist nel ;
450
	    nel.member = e ;
451
	    nel.next = el ;
452
	    if ( regable ( e ) ) {
453
		weights wbody ;
454
		float old_scale = scale ;
455
		scale = fno ( e ) ;
456
		wbody = weightsv ( bro ( son ( e ) ), &nel ) ;
457
		scale = old_scale ;
458
		return ( wbody ) ;
459
	    } else {
460
		return ( add_wlist ( bro ( son ( e ) ), &nel ) ) ;
461
	    }
462
	}
463
 
464
	case rep_tag : {
465
	    weights swl, bwl ;
466
	    swl = weightsv ( son ( e ), el ) ;
467
	    bwl = weightsv ( bro ( son ( e ) ), el ) ;
468
	    return ( add_weights ( swl, bwl ) ) ;
469
	}
470
 
471
	case compound_tag : {
472
	    return ( add_wlist ( son ( e ), el ) ) ;
473
	}
474
 
475
        case untidy_return_tag :
476
	case case_tag :
477
	case res_tag : {
478
	    return ( weightsv ( son ( e ), el ) ) ;
479
	}
480
	case apply_general_tag :
481
	case apply_tag :
482
	case round_tag :
483
	case float_tag : {
484
	    markcall ( el, ( bitpattern ) 0x80 ) ;
485
	    return ( add_wlist ( son ( e ), el ) ) ;
486
	}
487
 
488
	case ass_tag :
489
	case assvol_tag : {
490
	    weights swl, bwl ;
491
	    swl = weightsv ( son ( e ), el ) ;
492
	    bwl = weightsv ( bro ( son ( e ) ), el ) ;
493
	    return ( add_weights ( swl, bwl ) ) ;
494
	}
495
 
496
	case general_proc_tag :
497
	case proc_tag : {
498
	    weightsv ( son ( e ), null ) ;
499
	    return ( zeros ) ;
500
	}
501
 
502
	case env_offset_tag : {
503
	    return ( zeros ) ;
504
	}
505
 
506
	case val_tag :
507
	case real_tag : {
508
	    return ( zeros ) ;
509
	}
510
 
511
	case test_tag : {
512
	    weights twl ;
513
	    twl = add_wlist ( son ( e ), el ) ;
514
	    /* scale = scale * ( ( ( float ) 1.0 ) - fno ( e ) ) ; */
515
	    return ( twl ) ;
516
	}
517
 
518
	default : {
519
	    return ( add_wlist ( son ( e ), el ) ) ;
520
	}
521
    }
522
}
523
 
524
 
525
/*
526
    COMPUTE WEIGHTS
527
*/
528
 
529
void comp_weights
530
    PROTO_N ( ( e ) )
531
    PROTO_T ( exp e )
532
{
533
    scale = ( float ) 1.0 ;
534
    weightsv ( e, null ) ;
535
    return ;
536
}