Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
 
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
Line 100... Line 130...
100
#include "translate.h"
130
#include "translate.h"
101
#include "evaluate.h"
131
#include "evaluate.h"
102
#define REGISTER_SIZES
132
#define REGISTER_SIZES
103
#include "instr_aux.h"
133
#include "instr_aux.h"
104
#include "special_exps.h"
134
#include "special_exps.h"
105
static int find_where PROTO_S ( ( exp ) ) ;
135
static int find_where(exp);
106
 
136
 
107
/*
137
/*
108
    MACROS
138
    MACROS
109
 
139
 
110
    These are used as convenient shorthands.
140
    These are used as convenient shorthands.
111
*/
141
*/
112
 
142
 
113
#define  new_exp( A, B, C, D )	getexp ( A, nilexp, 0, B, nilexp, L0, C, D )
143
#define  new_exp(A, B, C, D)	getexp(A, nilexp, 0, B, nilexp, L0, C, D)
114
#define  ptrsh		 	ptr_shape ( slongsh )
144
#define  ptrsh		 	ptr_shape(slongsh)
115
 
145
 
116
 
146
 
117
/*
147
/*
118
    WHAT SORT OF REGISTER SHOULD WE PUT SOMETHING OF A GIVEN SHAPE IN?
148
    WHAT SORT OF REGISTER SHOULD WE PUT SOMETHING OF A GIVEN SHAPE IN?
119
 
149
 
120
    The shape sha is examined and the appropriate register type -
150
    The shape sha is examined and the appropriate register type -
121
    Dreg, Areg or Freg is returned.
151
    Dreg, Areg or Freg is returned.
122
*/
152
*/
123
 
153
 
124
int shtype
154
int shtype
125
    PROTO_N ( ( sha ) )
-
 
126
    PROTO_T ( shape sha )
155
(shape sha)
127
{
156
{
128
    char n = name ( sha ) ;
157
    char n = name(sha);
129
    if ( n >= scharhd && n <= ulonghd ) return ( Dreg ) ;
158
    if (n >= scharhd && n <= ulonghd) return(Dreg);
130
    if ( n >= shrealhd && n <= doublehd ) return ( Freg ) ;
159
    if (n >= shrealhd && n <= doublehd) return(Freg);
131
    if ( n != bitfhd && n != nofhd && n != cpdhd ) return ( Areg ) ;
160
    if (n != bitfhd && n != nofhd && n != cpdhd) return(Areg);
132
    return ( shape_size ( sha ) <= 32 ? Dreg : Areg ) ;
161
    return(shape_size(sha) <= 32 ? Dreg : Areg);
133
}
162
}
134
 
163
 
135
 
164
 
136
/*
165
/*
137
    REGISTERS USED IN OPERAND
166
    REGISTERS USED IN OPERAND
138
 
167
 
139
    This is a bitmask of all the registers used in an operand.  It is
168
    This is a bitmask of all the registers used in an operand.  It is
140
    built up by find_where.
169
    built up by find_where.
141
*/
170
*/
142
 
171
 
143
static bitpattern where_regmsk ;
172
static bitpattern where_regmsk;
144
 
173
 
145
 
174
 
146
/*
175
/*
147
    FIND ADDRESSING TYPE OF A REGISTER INDIRECT WITH DISPLACEMENT
176
    FIND ADDRESSING TYPE OF A REGISTER INDIRECT WITH DISPLACEMENT
148
 
177
 
Line 150... Line 179...
150
    mask rgs is returned.  This is RegInd if rgs corresponds to an
179
    mask rgs is returned.  This is RegInd if rgs corresponds to an
151
    A-register, and Other otherwise.
180
    A-register, and Other otherwise.
152
*/
181
*/
153
 
182
 
154
static int find_reg_ind
183
static int find_reg_ind
155
    PROTO_N ( ( r ) )
-
 
156
    PROTO_T ( int r )
184
(int r)
157
{
185
{
158
    bitpattern rgs = ( bitpattern ) r ;
186
    bitpattern rgs = (bitpattern)r;
159
    where_regmsk |= rgs ;
187
    where_regmsk |= rgs;
160
    /* If rgs corresponds to an A register, we have an effective address */
188
    /* If rgs corresponds to an A register, we have an effective address */
161
    if ( rgs & areg_msk ) return ( RegInd ) ;
189
    if (rgs & areg_msk) return(RegInd);
162
    return ( Other ) ;
190
    return(Other);
163
}
191
}
164
 
192
 
165
 
193
 
166
/*
194
/*
167
    FIND ADDRESSING TYPE OF AN INDEX OPERAND
195
    FIND ADDRESSING TYPE OF AN INDEX OPERAND
Line 169... Line 197...
169
    The addressing type of the operand given by e1 indexed by e2 times
197
    The addressing type of the operand given by e1 indexed by e2 times
170
    some constant is returned.
198
    some constant is returned.
171
*/
199
*/
172
 
200
 
173
static int find_ind
201
static int find_ind
174
    PROTO_N ( ( e1, e2 ) )
-
 
175
    PROTO_T ( exp e1 X exp e2 )
202
(exp e1, exp e2)
176
{
203
{
177
    int f1 = find_where ( e1 ) ;
204
    int f1 = find_where(e1);
178
    int f2 = find_where ( e2 ) ;
205
    int f2 = find_where(e2);
179
    if ( f1 == Other ) return ( Other ) ;
206
    if (f1 == Other) return(Other);
180
    if ( f2 == Dreg || f2 == Areg ) return ( EffAddr ) ;
207
    if (f2 == Dreg || f2 == Areg) return(EffAddr);
181
    return ( Other ) ;
208
    return(Other);
182
}
209
}
183
 
210
 
184
 
211
 
185
/*
212
/*
186
    FIND ADDRESSING TYPE OF AN OPERAND
213
    FIND ADDRESSING TYPE OF AN OPERAND
Line 189... Line 216...
189
    bitmask of all the registers used in e is built up in where_regmsk.
216
    bitmask of all the registers used in e is built up in where_regmsk.
190
    This routine should be compared with operand.
217
    This routine should be compared with operand.
191
*/
218
*/
192
 
219
 
193
static int find_where
220
static int find_where
194
    PROTO_N ( ( e ) )
-
 
195
    PROTO_T ( exp e )
221
(exp e)
196
{
222
{
197
    bitpattern rm ;
223
    bitpattern rm;
198
    switch ( name ( e ) ) {
224
    switch (name(e)) {
199
 
225
 
200
	case val_tag :
226
	case val_tag:
201
	case null_tag :
227
	case null_tag:
202
	    return ( Value ) ;
228
	    return(Value);
203
 
229
 
204
	case real_tag :
230
	case real_tag:
205
	case string_tag :
231
	case string_tag:
206
	case res_tag :
232
	case res_tag:
207
	    return ( External ) ;
233
	    return(External);
208
 
234
 
209
	case regpair_tag :
235
	case regpair_tag:
210
	    return ( RegPair ) ;
236
	    return(RegPair);
211
 
237
 
212
	case apply_general_tag :
238
	case apply_general_tag:
213
	case tail_call_tag :
239
	case tail_call_tag:
214
	case apply_tag :
240
	case apply_tag:
215
	    return ( EffAddr ) ;
241
	    return(EffAddr);
216
 
242
 
217
	case field_tag :
243
	case field_tag:
218
	    return ( find_where ( son ( e ) ) ) ;
244
	    return(find_where(son(e)));
219
 
245
 
220
	case ident_tag :
246
	case ident_tag:
221
	case labst_tag : {
247
	case labst_tag: {
222
	    switch ( ptno ( e ) ) {
248
	    switch (ptno(e)) {
223
#ifndef tdf3
249
#ifndef tdf3
224
                case par2_pl :
250
                case par2_pl:
225
                case par3_pl :
251
                case par3_pl:
226
#endif
252
#endif
227
 
253
 
228
		case par_pl : return ( Parameter ) ;
254
		case par_pl: return(Parameter);
229
		case var_pl : return ( Variable ) ;
255
		case var_pl: return(Variable);
230
		case reg_pl : {
256
		case reg_pl: {
231
		    rm = ( bitpattern ) no ( e ) ;
257
		    rm = (bitpattern)no(e);
232
		    where_regmsk |= rm ;
258
		    where_regmsk |= rm;
233
		    /* A register, but what type? */
259
		    /* A register, but what type? */
234
		    if ( rm & dreg_msk ) return ( Dreg ) ;
260
		    if (rm & dreg_msk) return(Dreg);
235
		    if ( rm & areg_msk ) return ( Areg ) ;
261
		    if (rm & areg_msk) return(Areg);
236
		    return ( Freg ) ;
262
		    return(Freg);
237
		}
263
		}
238
	    }
264
	    }
239
	    break ;
265
	    break;
240
	}
266
	}
241
 
267
 
242
	case name_tag : {
268
	case name_tag: {
243
	    exp id = son ( e ) ;
269
	    exp id = son(e);
244
#if 0
270
#if 0
245
	    if((name(sh(e)) == prokhd) &&
271
	    if ((name(sh(e)) == prokhd) &&
246
	       ((son(id) == nilexp) || (name(son(id)) == proc_tag) ||
272
	      ((son(id) == nilexp) || (name(son(id)) == proc_tag) ||
247
		(name(son(id)) == general_proc_tag))){
273
		(name(son(id)) == general_proc_tag))) {
248
	      exp proc_cont = getexp(sh(e),nilexp,0,e,nilexp,0,
274
	      exp proc_cont = getexp(sh(e),nilexp,0,e,nilexp,0,
249
				     0,cont_tag);
275
				     0,cont_tag);
250
	      /*return find_where(proc_cont);*/
276
	      /*return find_where(proc_cont);*/
251
	      e = proc_cont;
277
	      e = proc_cont;
252
	      /*return EffAddr;*/
278
	      /*return EffAddr;*/
253
	      id = son(e);
279
	      id = son(e);
254
/*	      return find_where(e);*/
280
/*	      return find_where(e);*/
255
	    }
281
	    }
256
#endif
282
#endif
257
 
283
 
258
	    if ( isglob ( id ) ) return ( External ) ;
284
	    if (isglob(id)) return(External);
259
	    switch ( ptno ( id ) ) {
285
	    switch (ptno(id)) {
260
#ifndef tdf3
286
#ifndef tdf3
261
		case par2_pl :
287
		case par2_pl:
262
		case par3_pl :
288
		case par3_pl:
263
#endif
289
#endif
264
 
290
 
265
		case par_pl :
291
		case par_pl:
266
		case var_pl : return ( EffAddr ) ;
292
		case var_pl: return(EffAddr);
267
		case reg_pl : {
293
		case reg_pl: {
268
		    rm = ( bitpattern ) no ( id ) ;
294
		    rm = (bitpattern)no(id);
269
		    where_regmsk |= rm ;
295
		    where_regmsk |= rm;
270
		    /* A register, but what type? */
296
		    /* A register, but what type? */
271
		    if ( rm & dreg_msk ) return ( Dreg ) ;
297
		    if (rm & dreg_msk) return(Dreg);
272
		    if ( rm & areg_msk ) return ( Areg ) ;
298
		    if (rm & areg_msk) return(Areg);
273
		    return ( Freg ) ;
299
		    return(Freg);
274
		}
300
		}
275
	    }
301
	    }
276
	    break ;
302
	    break;
277
	}
303
	}
278
 
304
 
279
	case cont_tag :
305
	case cont_tag:
280
	case ass_tag : {
306
	case ass_tag: {
281
	    exp r = son ( e ) ;
307
	    exp r = son(e);
282
	    switch ( name ( r ) ) {
308
	    switch (name(r)) {
283
 
309
 
284
		case name_tag : {
310
		case name_tag: {
285
		    exp id = son ( r ) ;
311
		    exp id = son(r);
286
		    long pt_id = ptno ( id ) ;
312
		    long pt_id = ptno(id);
287
		    if ( isvar ( id ) ) return ( find_where ( r ) ) ;
313
		    if (isvar(id)) return(find_where(r));
288
		    if ( isglob ( id ) ) {
314
		    if (isglob(id)) {
289
			if ( name ( sh ( e ) ) == prokhd ) return ( External ) ;
315
			if (name(sh(e)) == prokhd) return(External);
290
			return ( Other ) ;
316
			return(Other);
291
		    }
317
		    }
292
		    switch ( pt_id ) {
318
		    switch (pt_id) {
293
#ifndef tdf3
319
#ifndef tdf3
294
                        case par2_pl :
320
                        case par2_pl:
295
                        case par3_pl :
321
                        case par3_pl:
296
#endif
322
#endif
297
 
323
 
298
			case par_pl :
324
			case par_pl:
299
			case var_pl : return ( EffAddr ) ;
325
			case var_pl: return(EffAddr);
300
			case reg_pl : return ( find_reg_ind ( no ( id ) ) ) ;
326
			case reg_pl: return(find_reg_ind(no(id)));
301
		    }
327
		    }
302
		    break ;
328
		    break;
303
		}
329
		}
304
 
330
 
305
		case cont_tag : {
331
		case cont_tag: {
306
		    exp rr = son ( r ) ;
332
		    exp rr = son(r);
307
		    if ( name ( rr ) == name_tag ) {
333
		    if (name(rr) == name_tag) {
308
			exp id = son ( rr ) ;
334
			exp id = son(rr);
309
			if ( !isvar ( id ) ) break ;
335
			if (!isvar(id))break;
310
			if ( isglob ( id ) ) return ( Other ) ;
336
			if (isglob(id)) return(Other);
311
			switch ( ptno ( id ) ) {
337
			switch (ptno(id)) {
312
#ifndef tdf3
338
#ifndef tdf3
313
                            case par2_pl :
339
                            case par2_pl:
314
                            case par3_pl :
340
                            case par3_pl:
315
#endif
341
#endif
316
 
342
 
317
			    case par_pl :
343
			    case par_pl:
318
			    case var_pl : return ( EffAddr ) ;
344
			    case var_pl: return(EffAddr);
319
			    case reg_pl : {
345
			    case reg_pl: {
320
				return ( find_reg_ind ( no ( id ) ) ) ;
346
				return(find_reg_ind(no(id)));
321
			    }
347
			    }
322
			}
348
			}
323
		    }
349
		    }
324
		    break ;
350
		    break;
325
		}
351
		}
326
 
352
 
327
		case reff_tag : {
353
		case reff_tag: {
328
		    exp rr = son ( r ) ;
354
		    exp rr = son(r);
329
		    switch ( name ( rr ) ) {
355
		    switch (name(rr)) {
330
 
356
 
331
			case name_tag : {
357
			case name_tag: {
332
			    exp id = son ( rr ) ;
358
			    exp id = son(rr);
333
			    if ( ptno ( id ) == reg_pl ) {
359
			    if (ptno(id) == reg_pl) {
334
				return ( find_reg_ind ( no ( id ) ) ) ;
360
				return(find_reg_ind(no(id)));
335
			    }
361
			    }
336
			    return ( Other ) ;
362
			    return(Other);
337
			}
363
			}
338
 
364
 
339
			case cont_tag : {
365
			case cont_tag: {
340
			    exp id = son ( son ( rr ) ) ;
366
			    exp id = son(son(rr));
341
			    if ( ptno ( id ) == reg_pl ) {
367
			    if (ptno(id) == reg_pl) {
342
				return ( find_reg_ind ( no ( id ) ) ) ;
368
				return(find_reg_ind(no(id)));
343
			    }
369
			    }
344
			    return ( Other ) ;
370
			    return(Other);
345
			}
371
			}
346
 
372
 
347
			case addptr_tag : return ( find_where ( rr ) ) ;
373
			case addptr_tag: return(find_where(rr));
348
		    }
374
		    }
349
		    break ;
375
		    break;
350
		}
376
		}
351
 
377
 
352
		case addptr_tag : {
378
		case addptr_tag: {
353
		    exp rr = son ( r ) ;
379
		    exp rr = son(r);
354
		    exp eb = bro ( rr ) ;
380
		    exp eb = bro(rr);
355
		    exp ec = simple_exp ( cont_tag ) ;
381
		    exp ec = simple_exp(cont_tag);
356
		    son ( ec ) = rr ;
382
		    son(ec) = rr;
357
		    switch ( name ( eb ) ) {
383
		    switch (name(eb)) {
358
			case name_tag :
384
			case name_tag:
359
			case cont_tag : return ( find_ind ( eb, ec ) ) ;
385
			case cont_tag: return(find_ind(eb, ec));
360
			case offset_mult_tag : {
386
			case offset_mult_tag: {
361
			    return ( find_ind ( son ( eb ), ec ) ) ;
387
			    return(find_ind(son(eb), ec));
362
			}
388
			}
363
		    }
389
		    }
364
		    break ;
390
		    break;
365
		}
391
		}
366
	    }
392
	    }
367
	    break ;
393
	    break;
368
	}
394
	}
369
 
395
 
370
	case reff_tag :
396
	case reff_tag:
371
	case dummy_tag : {
397
	case dummy_tag: {
372
	    exp r = son ( e ) ;
398
	    exp r = son(e);
373
	    switch ( name ( r ) ) {
399
	    switch (name(r)) {
374
 
400
 
375
		case ident_tag : {
401
		case ident_tag: {
376
		    if ( ptno ( r ) == reg_pl ) {
402
		    if (ptno(r) == reg_pl) {
377
			return ( find_reg_ind ( no ( r ) ) ) ;
403
			return(find_reg_ind(no(r)));
378
		    }
404
		    }
379
		    break ;
405
		    break;
380
		}
406
		}
381
 
407
 
382
		case name_tag : {
408
		case name_tag: {
383
		    exp id = son ( r ) ;
409
		    exp id = son(r);
384
		    if ( isglob ( id ) ) return ( External ) ;
410
		    if (isglob(id)) return(External);
385
		    if ( ptno ( r ) == reg_pl ) {
411
		    if (ptno(r) == reg_pl) {
386
			return ( find_reg_ind ( no ( id ) ) ) ;
412
			return(find_reg_ind(no(id)));
387
		    }
413
		    }
388
		    break ;
414
		    break;
389
		}
415
		}
390
 
416
 
391
		case cont_tag :
417
		case cont_tag:
392
		case ass_tag : {
418
		case ass_tag: {
393
		    exp id = son ( son ( r ) ) ;
419
		    exp id = son(son(r));
394
		    if ( isglob ( id ) ) return ( External ) ;
420
		    if (isglob(id)) return(External);
395
		    if ( ptno ( r ) == reg_pl ) {
421
		    if (ptno(r) == reg_pl) {
396
			return ( find_reg_ind ( no ( id ) ) ) ;
422
			return(find_reg_ind(no(id)));
397
		    }
423
		    }
398
		    break ;
424
		    break;
399
		}
425
		}
400
 
426
 
401
		case addptr_tag : return ( find_where ( r ) ) ;
427
		case addptr_tag: return(find_where(r));
402
	    }
428
	    }
403
	    break ;
429
	    break;
404
	}
430
	}
405
 
431
 
406
	case addptr_tag : {
432
	case addptr_tag: {
407
	    exp r = son ( e ) ;
433
	    exp r = son(e);
408
	    exp eb = bro ( r ) ;
434
	    exp eb = bro(r);
409
	    exp ec = simple_exp ( cont_tag ) ;
435
	    exp ec = simple_exp(cont_tag);
410
	    son ( ec ) = r ;
436
	    son(ec) = r;
411
	    switch ( name ( eb ) ) {
437
	    switch (name(eb)) {
412
		case name_tag :
438
		case name_tag:
413
		case cont_tag : return ( find_ind ( eb, ec ) ) ;
439
		case cont_tag: return(find_ind(eb, ec));
414
		case offset_mult_tag : {
440
		case offset_mult_tag: {
415
		    return ( find_ind ( son ( eb ), ec ) ) ;
441
		    return(find_ind(son(eb), ec));
416
		}
442
		}
417
	    }
443
	    }
418
	    break ;
444
	    break;
419
	}
445
	}
420
 
446
 
421
	case diagnose_tag : {
447
	case diagnose_tag: {
422
	    exp r = son ( e ) ;
448
	    exp r = son(e);
423
	    return ( find_where ( r ) ) ;
449
	    return(find_where(r));
424
	}
450
	}
425
    }
451
    }
426
    /* Allow all other operands through */
452
    /* Allow all other operands through */
427
    return ( Other ) ;
453
    return(Other);
428
}
454
}
429
 
455
 
430
 
456
 
431
/*
457
/*
432
    CREATE A WHERE
458
    CREATE A WHERE
Line 434... Line 460...
434
    A where is created from an expression e and an offset d.  The routine
460
    A where is created from an expression e and an offset d.  The routine
435
    find_where is used to calculate the wh_is and wh_regs fields.
461
    find_where is used to calculate the wh_is and wh_regs fields.
436
*/
462
*/
437
 
463
 
438
where mw
464
where mw
439
    PROTO_N ( ( e, d ) )
-
 
440
    PROTO_T ( exp e X long d )
465
(exp e, long d)
441
{
466
{
442
  where w ;
467
  where w;
443
#if 0
468
#if 0
444
 
469
 
445
  if ((name(e)==name_tag && name(sh(e)) == prokhd) &&
470
  if ((name(e) ==name_tag && name(sh(e)) == prokhd) &&
446
      !(((son (son(e)) == nilexp || name (son (son(e))) == proc_tag ||
471
      !(((son(son(e)) == nilexp || name(son(son(e))) == proc_tag ||
447
	  name(son(son(e))) == apply_tag ||
472
	  name(son(son(e))) == apply_tag ||
448
	  name(son(son(e))) == apply_general_tag)))) {
473
	  name(son(son(e))) == apply_general_tag)))) {
449
    exp proc_cont = getexp(sh(e),nilexp,0,e,nilexp,0,0,cont_tag);
474
    exp proc_cont = getexp(sh(e),nilexp,0,e,nilexp,0,0,cont_tag);
450
    e = proc_cont;
475
    e = proc_cont;
451
  }
476
  }
452
#endif
477
#endif
453
  w.wh_exp = e ;
478
  w.wh_exp = e;
454
  w.wh_off = d ;
479
  w.wh_off = d;
455
  where_regmsk = 0 ;
480
  where_regmsk = 0;
456
  w.wh_is = find_where ( e ) ;
481
  w.wh_is = find_where(e);
457
  w.wh_regs = where_regmsk ;
482
  w.wh_regs = where_regmsk;
458
  return ( w ) ;
483
  return(w);
459
}
484
}
460
 
485
 
461
 
486
 
462
/*
487
/*
463
    CREATE A WHERE REPRESENTING A NUMBER
488
    CREATE A WHERE REPRESENTING A NUMBER
464
 
489
 
465
    A where is created corresponding to the integer constant d.
490
    A where is created corresponding to the integer constant d.
466
*/
491
*/
467
 
492
 
468
where mnw
493
where mnw
469
    PROTO_N ( ( d ) )
-
 
470
    PROTO_T ( long d )
494
(long d)
471
{
495
{
472
    where w ;
496
    where w;
473
    w.wh_exp = zeroe ;
497
    w.wh_exp = zeroe;
474
    w.wh_off = d ;
498
    w.wh_off = d;
475
    w.wh_is = Value ;
499
    w.wh_is = Value;
476
    w.wh_regs = 0 ;
500
    w.wh_regs = 0;
477
    return ( w ) ;
501
    return(w);
478
}
502
}
479
 
503
 
480
 
504
 
481
/*
505
/*
482
    CREATE A WHERE REPRESENTING A FLOATING POINT NUMBER
506
    CREATE A WHERE REPRESENTING A FLOATING POINT NUMBER
Line 484... Line 508...
484
    A where is created corresponding to the floating point number with
508
    A where is created corresponding to the floating point number with
485
    sign sg (+1, 0 or -1), digits v and exponent e.
509
    sign sg (+1, 0 or -1), digits v and exponent e.
486
*/
510
*/
487
 
511
 
488
where mfw
512
where mfw
489
    PROTO_N ( ( sg, v, e ) )
-
 
490
#if ( FBASE == 10 )
513
#if (FBASE == 10)
491
    PROTO_T ( int sg X char *v X int e )
514
(int sg, char *v, int e)
492
#else
515
#else
493
    PROTO_T ( int sg X long *v X int e )
516
(int sg, long *v, int e)
494
#endif
517
#endif
495
{
518
{
496
    where w ;
519
    where w;
497
    int i, lv ;
520
    int i, lv;
498
    long lab = next_lab () ;
521
    long lab = next_lab();
499
    exp fe, ft = simple_exp ( internal_tag ) ;
522
    exp fe, ft = simple_exp(internal_tag);
500
    long fm = new_flpt () ;
523
    long fm = new_flpt();
501
    flt *f = &flptnos [ fm ] ;
524
    flt *f = &flptnos[fm];
502
    f->sign = sg ;
525
    f->sign = sg;
503
    f->exp = e ;
526
    f->exp = e;
504
#if ( FBASE == 10 )
527
#if (FBASE == 10)
505
    lv = strlen ( v ) ;
528
    lv = strlen(v);
506
    for ( i = 0 ; i < lv ; i++ ) f->mant [i] = v [i] - '0' ;
529
    for (i = 0; i < lv; i++)f->mant[i] = v[i] - '0';
507
#else
530
#else
508
    i = 0 ;
531
    i = 0;
509
    while ( v [i] != -1 ) {
532
    while (v[i]!= -1) {
510
	f->mant [i] = v [i] ;
533
	f->mant[i] = v[i];
511
	i++ ;
534
	i++;
512
    }
535
    }
513
    lv = i ;
536
    lv = i;
514
#endif
537
#endif
515
    for ( i = lv ; i < MANT_SIZE ; i++ ) f->mant [i] = 0 ;
538
    for (i = lv; i < MANT_SIZE; i++)f->mant[i] = 0;
516
    fe = new_exp ( realsh, nilexp, fm, real_tag ) ;
539
    fe = new_exp(realsh, nilexp, fm, real_tag);
517
    make_constant ( lab, fe ) ;
540
    make_constant(lab, fe);
518
    no ( ft ) = lab ;
541
    no(ft) = lab;
519
    w.wh_exp = ft ;
542
    w.wh_exp = ft;
520
    w.wh_off = 0 ;
543
    w.wh_off = 0;
521
    w.wh_is = Value ;
544
    w.wh_is = Value;
522
    w.wh_regs = 0 ;
545
    w.wh_regs = 0;
523
    return ( w ) ;
546
    return(w);
524
}
547
}
525
 
548
 
526
 
549
 
527
/*
550
/*
528
    CONSTRUCT A REGISTER PAIR
551
    CONSTRUCT A REGISTER PAIR
Line 530... Line 553...
530
    A where is created corresponding to the register pair a:b.  Both
553
    A where is created corresponding to the register pair a:b.  Both
531
    a and b must represent registers.
554
    a and b must represent registers.
532
*/
555
*/
533
 
556
 
534
where regpair
557
where regpair
535
    PROTO_N ( ( a, b ) )
-
 
536
    PROTO_T ( where a X where b )
558
(where a, where b)
537
{
559
{
538
    where w ;
560
    where w;
539
    exp ea = a.wh_exp ;
561
    exp ea = a.wh_exp;
540
    exp eb = b.wh_exp ;
562
    exp eb = b.wh_exp;
541
    w.wh_exp = getexp ( realsh, eb, 0, ea, nilexp, 0, 0, regpair_tag ) ;
563
    w.wh_exp = getexp(realsh, eb, 0, ea, nilexp, 0, 0, regpair_tag);
542
    w.wh_off = 0 ;
564
    w.wh_off = 0;
543
    w.wh_is = RegPair ;
565
    w.wh_is = RegPair;
544
    where_regmsk = 0 ;
566
    where_regmsk = 0;
545
    if ( find_where ( ea ) != Dreg || find_where ( eb ) != Dreg ) {
567
    if (find_where(ea)!= Dreg || find_where(eb)!= Dreg) {
546
	error ( "Illegal register pair" ) ;
568
	error("Illegal register pair");
547
    }
569
    }
548
    w.wh_regs = where_regmsk ;
570
    w.wh_regs = where_regmsk;
549
    return ( w ) ;
571
    return(w);
550
}
572
}
551
 
573
 
552
 
574
 
553
/*
575
/*
554
    CONSTANT WHERE'S
576
    CONSTANT WHERE'S
Line 557... Line 579...
557
    zero is the integer 0.  RW[] is the array of all registers.  A6_4
579
    zero is the integer 0.  RW[] is the array of all registers.  A6_4
558
    represents a position on the stack.  A0_p, A1_p, SP_p and A6_4_p
580
    represents a position on the stack.  A0_p, A1_p, SP_p and A6_4_p
559
    represent pointers.  D0_D1 is a register pair.
581
    represent pointers.  D0_D1 is a register pair.
560
*/
582
*/
561
 
583
 
562
where zero ;
584
where zero;
563
where fzero ;
585
where fzero;
564
where RW [ NO_OF_REGS ] ;
586
where RW[NO_OF_REGS];
565
where A6_4, A0_p, A1_p, SP_p, A6_4_p, D0_D1 ;
587
where A6_4, A0_p, A1_p, SP_p, A6_4_p, D0_D1;
566
where dummy_double_dest ;
588
where dummy_double_dest;
567
where firstlocal;
589
where firstlocal;
568
 
590
 
569
 
591
 
570
/*
592
/*
571
    CONSTANT EXP'S
593
    CONSTANT EXP'S
572
 
594
 
573
    These expressions are the wh_exp fields of the where's above.
595
    These expressions are the wh_exp fields of the where's above.
574
*/
596
*/
575
 
597
 
576
exp zeroe ;
598
exp zeroe;
577
static exp fzeroe ;
599
static exp fzeroe;
578
static exp RE [ NO_OF_REGS ] ;
600
static exp RE[NO_OF_REGS];
579
static exp E_long, E_float, E_ptr, E_A6_4 ;
601
static exp E_long, E_float, E_ptr, E_A6_4;
580
static exp firstlocalid;
602
static exp firstlocalid;
581
 
603
 
582
/*
604
/*
583
    SET UP CONSTANTS WHERE'S
605
    SET UP CONSTANTS WHERE'S
584
 
606
 
585
    The constant where's are initialized.
607
    The constant where's are initialized.
586
*/
608
*/
587
 
609
 
588
void init_wheres
610
void init_wheres
589
    PROTO_Z ()
611
(void)
590
{
612
{
591
    int i ;
613
    int i;
592
 
614
 
593
    /* Set up the exps corresponding to 0 */
615
    /* Set up the exps corresponding to 0 */
594
    zeroe = new_exp ( botsh, nilexp, 0, val_tag ) ;
616
    zeroe = new_exp(botsh, nilexp, 0, val_tag);
595
    fzeroe = new_exp ( realsh, nilexp, fzero_no, real_tag ) ;
617
    fzeroe = new_exp(realsh, nilexp, fzero_no, real_tag);
596
 
618
 
597
    /* Set up the corresponding wheres */
619
    /* Set up the corresponding wheres */
598
    zero = zw ( zeroe ) ;
620
    zero = zw(zeroe);
599
    fzero = zw ( fzeroe ) ;
621
    fzero = zw(fzeroe);
600
 
622
 
601
    /* Create some dummy exp's */
623
    /* Create some dummy exp's */
602
    E_long = new_exp ( slongsh, nilexp, 0, val_tag ) ;
624
    E_long = new_exp(slongsh, nilexp, 0, val_tag);
603
    E_float = new_exp ( realsh, nilexp, 0, real_tag ) ;
625
    E_float = new_exp(realsh, nilexp, 0, real_tag);
604
    E_ptr = new_exp ( ptrsh, E_long, 0, cont_tag ) ;
626
    E_ptr = new_exp(ptrsh, E_long, 0, cont_tag);
605
    E_A6_4 = new_exp ( botsh, E_ptr, 0, ident_tag ) ;
627
    E_A6_4 = new_exp(botsh, E_ptr, 0, ident_tag);
606
    ptno ( E_A6_4 ) = var_pl ;
628
    ptno(E_A6_4) = var_pl;
607
 
629
 
608
    /* Set up the exp's corresponding to the utility registers */
630
    /* Set up the exp's corresponding to the utility registers */
609
    for ( i = 0 ; i < NO_OF_REGS ; i++ ) {
631
    for (i = 0; i < NO_OF_REGS; i++) {
610
	exp t = E_float ;
632
	exp t = E_float;
611
	if ( is_dreg ( i ) ) t = E_long ;
633
	if (is_dreg(i))t = E_long;
612
	if ( is_areg ( i ) ) t = E_ptr ;
634
	if (is_areg(i))t = E_ptr;
613
	RE [i] = new_exp ( botsh, t, regmsk ( i ), ident_tag ) ;
635
	RE[i] = new_exp(botsh, t, regmsk(i), ident_tag);
614
	ptno ( RE [i] ) = reg_pl ;
636
	ptno(RE[i]) = reg_pl;
615
	RW [i] = zw ( new_exp ( slongsh, RE [i], 0, name_tag ) ) ;
637
	RW[i] = zw(new_exp(slongsh, RE[i], 0, name_tag));
616
    }
638
    }
617
 
639
 
618
    /* Set up some pointer where's */
640
    /* Set up some pointer where's */
619
    A0_p = zw ( new_exp ( ptrsh, A0.wh_exp, 0, cont_tag ) ) ;
641
    A0_p = zw(new_exp(ptrsh, A0.wh_exp, 0, cont_tag));
620
    A1_p = zw ( new_exp ( ptrsh, A1.wh_exp, 0, cont_tag ) ) ;
642
    A1_p = zw(new_exp(ptrsh, A1.wh_exp, 0, cont_tag));
621
    SP_p = zw ( new_exp ( ptrsh, SP.wh_exp, 0, cont_tag ) ) ;
643
    SP_p = zw(new_exp(ptrsh, SP.wh_exp, 0, cont_tag));
622
    A6_4 = zw ( new_exp ( slongsh, E_A6_4, -32, name_tag ) ) ;
644
    A6_4 = zw(new_exp(slongsh, E_A6_4, -32, name_tag));
623
    A6_4_p = zw ( new_exp ( ptrsh, A6_4.wh_exp, 0, cont_tag ) ) ;
645
    A6_4_p = zw(new_exp(ptrsh, A6_4.wh_exp, 0, cont_tag));
624
 
646
 
625
    /* Set up the register pair D0:D1 */
647
    /* Set up the register pair D0:D1 */
626
    D0_D1 = regpair ( D0, D1 ) ;
648
    D0_D1 = regpair(D0, D1);
627
 
649
 
628
    dummy_double_dest = zw(get_dummy_double_dest()) ;
650
    dummy_double_dest = zw(get_dummy_double_dest());
629
 
651
 
630
    firstlocalid = new_exp (f_bottom, E_long, 0, ident_tag);
652
    firstlocalid = new_exp(f_bottom, E_long, 0, ident_tag);
631
    ptno(firstlocalid) = var_pl;
653
    ptno(firstlocalid) = var_pl;
632
    firstlocal = zw (new_exp (slongsh, firstlocalid, -32, name_tag));
654
    firstlocal = zw(new_exp(slongsh, firstlocalid, -32, name_tag));
633
}
655
}
634
 
656
 
635
 
657
 
636
/*
658
/*
637
    ARE TWO WHERE'S EQUAL?
659
    ARE TWO WHERE'S EQUAL?
Line 640... Line 662...
640
    defined to be eq_where_a ( a, b, 1 ).  It returns 1 if the where's
662
    defined to be eq_where_a ( a, b, 1 ).  It returns 1 if the where's
641
    a and b are equal, but 0 otherwise.
663
    a and b are equal, but 0 otherwise.
642
*/
664
*/
643
 
665
 
644
bool eq_where_a
666
bool eq_where_a
645
    PROTO_N ( ( wa, wb, first ) )
-
 
646
    PROTO_T ( where wa X where wb X int first )
667
(where wa, where wb, int first)
647
{
668
{
648
    where sa, sb ;
669
    where sa, sb;
649
    exp a = wa.wh_exp ;
670
    exp a = wa.wh_exp;
650
    exp b = wb.wh_exp ;
671
    exp b = wb.wh_exp;
651
    char na = name ( a ) ;
672
    char na = name(a);
652
    char nb = name ( b ) ;
673
    char nb = name(b);
653
 
674
 
654
    if ( wa.wh_off != wb.wh_off ) return ( 0 ) ;
675
    if (wa.wh_off != wb.wh_off) return(0);
655
    if ( a == b ) return ( 1 ) ;
676
    if (a == b) return(1);
656
 
677
 
657
    if ( na == nb ) {
678
    if (na == nb) {
658
 
679
 
659
	switch ( na ) {
680
	switch (na) {
660
 
681
 
661
	    case val_tag : {
682
	    case val_tag: {
662
		return ( no ( a ) == no ( b ) ? 1 : 0 ) ;
683
		return(no(a) == no(b)? 1 : 0);
663
	    }
684
	    }
664
 
685
 
665
	    case ident_tag : {
686
	    case ident_tag: {
666
		if ( no ( a ) != no ( b ) ) return ( 0 ) ;
687
		if (no(a)!= no(b)) return(0);
667
		return ( ptno ( a ) == ptno ( b ) ? 1 : 0 ) ;
688
		return(ptno(a) == ptno(b)? 1 : 0);
668
	    }
689
	    }
669
 
690
 
670
	    case name_tag :
691
	    case name_tag:
671
	    case field_tag :
692
	    case field_tag:
672
	    case reff_tag : {
693
	    case reff_tag: {
673
		if ( no ( a ) != no ( b ) ) return ( 0 ) ;
694
		if (no(a)!= no(b)) return(0);
674
		sa.wh_exp = son ( a ) ;
695
		sa.wh_exp = son(a);
675
		sa.wh_off = 0 ;
696
		sa.wh_off = 0;
676
		sb.wh_exp = son ( b ) ;
697
		sb.wh_exp = son(b);
677
		sb.wh_off = 0 ;
698
		sb.wh_off = 0;
678
		return ( eq_where_a ( sa, sb, 0 ) ) ;
699
		return(eq_where_a(sa, sb, 0));
679
	    }
700
	    }
680
 
701
 
681
	    case cont_tag : {
702
	    case cont_tag: {
682
		sa.wh_exp = son ( a ) ;
703
		sa.wh_exp = son(a);
683
		sa.wh_off = 0 ;
704
		sa.wh_off = 0;
684
		sb.wh_exp = son ( b ) ;
705
		sb.wh_exp = son(b);
685
		sb.wh_off = 0 ;
706
		sb.wh_off = 0;
686
		return ( eq_where_a ( sa, sb, 0 ) ) ;
707
		return(eq_where_a(sa, sb, 0));
687
	    }
708
	    }
688
 
709
 
689
	    case real_tag : {
710
	    case real_tag: {
690
		int i ;
711
		int i;
691
		bool z = 1 ;
712
		bool z = 1;
692
		flt fa, fb ;
713
		flt fa, fb;
693
		fa = flptnos [ no ( a ) ] ;
714
		fa = flptnos[no(a)];
694
		fb = flptnos [ no ( b ) ] ;
715
		fb = flptnos[no(b)];
695
 
716
 
696
		for ( i = 0 ; i < MANT_SIZE ; i++ ) {
717
		for (i = 0; i < MANT_SIZE; i++) {
697
		    if ( fa.mant [i] != fb.mant [i] ) return ( 0 ) ;
718
		    if (fa.mant[i]!= fb.mant[i]) return(0);
698
		    if ( fa.mant [i] ) z = 0 ;
719
		    if (fa.mant[i])z = 0;
699
		}
720
		}
700
 
721
 
701
		if ( z ) return ( 1 ) ;
722
		if (z) return(1);
702
		if ( fa.exp != fb.exp ) return ( 0 ) ;
723
		if (fa.exp != fb.exp) return(0);
703
		if ( fa.sign != fb.sign ) return ( 0 ) ;
724
		if (fa.sign != fb.sign) return(0);
704
		return ( 1 ) ;
725
		return(1);
705
	    }
726
	    }
706
	}
727
	}
707
	return ( 0 ) ;
728
	return(0);
708
    }
729
    }
709
 
730
 
710
    if ( first && na == name_tag && nb == ident_tag ) {
731
    if (first && na == name_tag && nb == ident_tag) {
711
	if ( no ( a ) ) return ( 0 ) ;
732
	if (no(a)) return(0);
712
	sa.wh_exp = son ( a ) ;
733
	sa.wh_exp = son(a);
713
	sa.wh_off = 0 ;
734
	sa.wh_off = 0;
714
	return ( eq_where_a ( sa, wb, 0 ) ) ;
735
	return(eq_where_a(sa, wb, 0));
715
    }
736
    }
716
 
737
 
717
    if ( first && nb == name_tag && na == ident_tag ) {
738
    if (first && nb == name_tag && na == ident_tag) {
718
	if ( no ( b ) ) return ( 0 ) ;
739
	if (no(b)) return(0);
719
	sb.wh_exp = son ( b ) ;
740
	sb.wh_exp = son(b);
720
	sb.wh_off = 0 ;
741
	sb.wh_off = 0;
721
	return ( eq_where_a ( wa, sb, 0 ) ) ;
742
	return(eq_where_a(wa, sb, 0));
722
    }
743
    }
723
 
744
 
724
    if ( ( na == cont_tag || na == ass_tag ) &&
745
    if ((na == cont_tag || na == ass_tag) &&
725
	 name ( son ( a ) ) == name_tag &&
746
	 name(son(a)) == name_tag &&
726
	 isvar ( son ( son ( a ) ) ) &&
747
	 isvar(son(son(a))) &&
727
	 ( nb == ident_tag || nb == name_tag ) ) {
748
	(nb == ident_tag || nb == name_tag)) {
728
	if ( no ( son ( a ) ) ) return ( 0 ) ;
749
	if (no(son(a))) return(0);
729
	sa.wh_exp = son ( son ( a ) ) ;
750
	sa.wh_exp = son(son(a));
730
	sa.wh_off = 0 ;
751
	sa.wh_off = 0;
731
	return ( eq_where_a ( sa, wb, 0 ) ) ;
752
	return(eq_where_a(sa, wb, 0));
732
    }
753
    }
733
 
754
 
734
    if ( ( nb == cont_tag || nb == ass_tag ) &&
755
    if ((nb == cont_tag || nb == ass_tag) &&
735
	 name ( son ( b ) ) == name_tag &&
756
	 name(son(b)) == name_tag &&
736
	 isvar ( son ( son ( b ) ) ) &&
757
	 isvar(son(son(b))) &&
737
	 ( na == ident_tag || na == name_tag ) ) {
758
	(na == ident_tag || na == name_tag)) {
738
	if ( no ( son ( b ) ) ) return ( 0 ) ;
759
	if (no(son(b))) return(0);
739
	sb.wh_exp = son ( son ( b ) ) ;
760
	sb.wh_exp = son(son(b));
740
	sb.wh_off = 0 ;
761
	sb.wh_off = 0;
741
	return ( eq_where_a ( wa, sb, 0 ) ) ;
762
	return(eq_where_a(wa, sb, 0));
742
    }
763
    }
743
 
764
 
744
 
765
 
745
    if ( ( na == ass_tag && nb == cont_tag ) ||
766
    if ((na == ass_tag && nb == cont_tag) ||
746
	 ( nb == ass_tag && na == cont_tag ) ) {
767
	(nb == ass_tag && na == cont_tag)) {
747
	sa.wh_exp = son ( a ) ;
768
	sa.wh_exp = son(a);
748
	sa.wh_off = 0 ;
769
	sa.wh_off = 0;
749
	sb.wh_exp = son ( b ) ;
770
	sb.wh_exp = son(b);
750
	sb.wh_off = 0 ;
771
	sb.wh_off = 0;
751
	return ( eq_where_a ( sa, sb, 0 ) ) ;
772
	return(eq_where_a(sa, sb, 0));
752
    }
773
    }
753
 
774
 
754
    return ( 0 ) ;
775
    return(0);
755
}
776
}