Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 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
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1996
33
 
34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
42
 
43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
45
 
46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
49
 
50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
53
 
54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
/*
60
			    VERSION INFORMATION
61
			    ===================
62
 
63
--------------------------------------------------------------------------
64
$Header: /u/g/release/CVSROOT/Source/src/installers/680x0/common/trans.c,v 1.1.1.1 1998/01/17 15:55:49 release Exp $
65
--------------------------------------------------------------------------
66
$Log: trans.c,v $
67
 * Revision 1.1.1.1  1998/01/17  15:55:49  release
68
 * First version to be checked into rolling release.
69
 *
70
Revision 1.2  1997/10/29 10:22:31  ma
71
Replaced use_alloca with has_alloca.
72
 
73
Revision 1.1.1.1  1997/10/13 12:43:00  ma
74
First version.
75
 
76
Revision 1.6  1997/10/13 08:50:13  ma
77
Made all pl_tests for general proc & exception handling pass.
78
 
79
Revision 1.5  1997/09/25 06:45:36  ma
80
All general_proc tests passed
81
 
82
Revision 1.4  1997/06/18 12:04:59  ma
83
Merged with Input Baseline changes.
84
 
85
Revision 1.3  1997/06/18 10:09:45  ma
86
Checking in before merging with Input Baseline changes.
87
 
88
Revision 1.2  1997/04/20 11:30:40  ma
89
Introduced gcproc.c & general_proc.[ch].
90
Added cases for apply_general_proc next to apply_proc in all files.
91
 
92
Revision 1.1.1.1  1997/03/14 07:50:19  ma
93
Imported from DRA
94
 
95
 * Revision 1.1.1.1  1996/09/20  10:56:59  john
96
 *
97
 * Revision 1.2  1996/07/05  14:28:02  john
98
 * Changes for spec 3.1
99
 *
100
 * Revision 1.1.1.1  1996/03/26  15:45:18  john
101
 *
102
 * Revision 1.3  94/02/21  16:05:07  16:05:07  ra (Robert Andrews)
103
 * Just declare scan2 traditionally.
104
 *
105
 * Revision 1.2  93/11/19  16:23:34  16:23:34  ra (Robert Andrews)
106
 * Reformatted mark_unaliased.
107
 *
108
 * Revision 1.1  93/02/22  17:16:50  17:16:50  ra (Robert Andrews)
109
 * Initial revision
110
 *
111
--------------------------------------------------------------------------
112
*/
113
 
114
 
115
#include "config.h"
116
#include "common_types.h"
117
#include "expmacs.h"
118
#include "exp.h"
119
#include "flags.h"
120
#include "instrs.h"
121
#include "installglob.h"
122
#include "shapemacs.h"
123
#include "evaluate.h"
124
#include "mach.h"
125
#include "mach_ins.h"
126
#include "mach_op.h"
127
#include "weights.h"
128
#include "mach.h"
129
#include "where.h"
130
#include "coder.h"
131
#include "codex.h"
132
#include "optimise.h"
133
#include "output.h"
134
#include "tests.h"
135
#include "tags.h"
136
#include "utility.h"
137
#if have_diagnostics
138
#include "xdb_basics.h"
139
#endif
7 7u83 140
extern dec *sort_decs(dec *);
141
static void output_all_exps(void);
2 7u83 142
 
143
/*
144
    INCLUDE DEBUGGING ROUTINES
145
 
146
    These are used to aid in debugging.
147
 
148
*/
149
#ifdef EBUG
150
/*
151
#include <misc/debug>
152
*/
7 7u83 153
void breakpoint(void) {}
2 7u83 154
#endif
155
 
156
#ifndef tdf3
157
#include "general_proc.h"
158
#include "68k_globals.h"
7 7u83 159
int need_dummy_double = 0;
2 7u83 160
#endif
161
 
162
/*
163
    LOCAL AND GLOBAL NAME PREFIXES
164
*/
165
 
7 7u83 166
char *local_prefix = "L";
167
char *name_prefix = "_";
2 7u83 168
 
169
 
170
/*
171
    EXTERNAL POSITIONS
172
*/
173
 
7 7u83 174
static long crt_ext_off = 64;
175
static long crt_ext_pt = 10;
2 7u83 176
 
177
 
178
/*
179
    MARK AN EXPRESSION AS BEING STATIC AND UNALIASED
180
*/
181
 
182
static void mark_unaliased
7 7u83 183
(exp e)
2 7u83 184
{
7 7u83 185
    exp p = pt(e);
186
    bool ca = 1;
187
    while (p != nilexp && ca) {
188
	exp q = bro(p);
189
	if (q == nilexp) {
190
	    ca = 0;
191
	} else if (!(last(p) && name(q) == cont_tag) &&
192
		    !(!last(p) && last(q) &&
193
		       name(bro(q)) == ass_tag)) {
194
	    ca = 0;
2 7u83 195
	}
7 7u83 196
	p = pt(p);
2 7u83 197
    }
7 7u83 198
    if (ca)setcaonly(e);
199
    return;
2 7u83 200
}
201
 
202
 
203
/*
204
    PROCESS THE TDF
205
 
206
    This routine gets all the TDF read into the correct operand form
207
    and applies the dead variable and register allocation analysis.
208
*/
209
 
210
void translate_capsule
7 7u83 211
(void)
2 7u83 212
{
7 7u83 213
    dec *d;
2 7u83 214
 
215
    /* Fix procedure handling (copied from trans386) */
216
    d = top_def;
217
#if 0
7 7u83 218
    while (d != (dec *)0) {
2 7u83 219
    exp crt_exp = d -> dec_u.dec_val.dec_exp;
220
    exp idval;
7 7u83 221
      if (!(d -> dec_u.dec_val.dec_var) && (name(sh(crt_exp))!= prokhd ||
222
          (idval = son(crt_exp),
223
             idval != nilexp && name(idval)!= null_tag &&
224
               name(idval)!= proc_tag && name(idval)!= general_proc_tag))) {
2 7u83 225
	/* make variable, and change all uses to contents */
226
        exp p = pt(crt_exp);
227
        if (d -> dec_u.dec_val.extnamed)
228
          sh(crt_exp) = f_pointer(f_alignment(sh(crt_exp)));
229
	else
230
          setvar(crt_exp);
231
        while (p != nilexp) {
232
          exp np = pt(p);
7 7u83 233
          exp* ptr = refto(father(p), p);
234
          exp c = getexp(sh(p), bro(p), last(p), p, nilexp, 0, 0, cont_tag);
235
          setfather(c, p);
236
          if (no(p)!= 0) {
237
            exp r = getexp(sh(p), c, 1, p, nilexp, 0, no(p), reff_tag);
2 7u83 238
            no(p) = 0;
239
            son(c) = r;
7 7u83 240
            setfather(r, p);
2 7u83 241
          }
242
          *ptr = c;
243
          p = np;
244
        }
245
      }
246
      d = d->def_next;
247
    }
248
#endif
249
 
250
 
7 7u83 251
    make_transformations();
2 7u83 252
 
253
#ifndef EBUG
7 7u83 254
    opt_all_exps();
2 7u83 255
#endif
256
 
257
    /* Mark static unaliases declarations */
7 7u83 258
    if (!separate_units) {
259
	for (d = top_def; d; d = d->def_next) {
260
	    exp c = d->dec_u.dec_val.dec_exp;
261
	    if (son(c)!= nilexp &&
262
		 !(d->dec_u.dec_val.extnamed) && isvar(c)) {
263
		mark_unaliased(c);
2 7u83 264
	    }
265
	}
266
    }
267
 
268
    /* Mark locations for all globals */
7 7u83 269
    for (d = top_def; d; d = d->def_next) {
270
	if (d->dec_u.dec_val.processed) {
271
	    exp c = d->dec_u.dec_val.dec_exp;
272
	    ptno(c) = crt_ext_pt++;
273
	    no(c) = crt_ext_off;
274
	    crt_ext_off += shape_size(d->dec_u.dec_val.dec_shape);
2 7u83 275
	}
276
    }
277
 
278
    /* Output all code */
7 7u83 279
    output_all_exps();
2 7u83 280
 
7 7u83 281
    return;
2 7u83 282
}
283
 
284
 
285
/*
286
    TRANSLATE A SINGLE TAG DEFINITION
287
*/
288
 
289
void translate_tagdef
7 7u83 290
(void)
2 7u83 291
{
7 7u83 292
    return;
2 7u83 293
}
294
 
295
 
296
/*
297
    TRANSLATE A SINGLE UNIT
298
*/
299
 
300
void translate_unit
7 7u83 301
(void)
2 7u83 302
{
7 7u83 303
    if (separate_units) {
304
	dec *d;
305
	translate_capsule();
306
	d = top_def;
307
	while (d) {
308
	    exp c = d->dec_u.dec_val.dec_exp;
309
	    no(c) = 0;
310
	    pt(c) = nilexp;
311
	    d = d->def_next;
2 7u83 312
	}
7 7u83 313
	crt_repeat = nilexp;
314
	repeat_list = nilexp;
2 7u83 315
    }
7 7u83 316
    return;
2 7u83 317
}
318
 
319
 
320
/*
321
    ENCODE A PROCEDURE
322
 
323
    The procedure with declaration d, name id, definition c and body s
324
    is encoded.
325
*/
326
 
327
static void code_proc
7 7u83 328
(dec *d, char *id, exp c, exp s)
2 7u83 329
{
7 7u83 330
    diag_global *di = d->dec_u.dec_val.diag_info;
331
    int reg_res = (has_struct_res(s)? 0 : 1);
332
    int is_ext = (d->dec_u.dec_val.extnamed ? 1 : 0);
2 7u83 333
 
7 7u83 334
    area(ptext);
2 7u83 335
 
7 7u83 336
    cur_proc_dec = d;
337
    cur_proc_callees_size = 0;
338
    cur_proc_has_vcallees = 0;
2 7u83 339
 
340
    /* Code procedure body */
341
#if 0
7 7u83 342
    if (name(s) == proc_tag)
343
    cproc(s, id, -1, is_ext, reg_res, di);
2 7u83 344
    else
345
#endif
7 7u83 346
    gcproc(s, id, -1, is_ext, reg_res, di);
2 7u83 347
 
348
 
349
    d -> dec_u.dec_val.index = cur_proc_env_size ; /* for use in constant evaluation */
350
 
351
    output_env_size(d, cur_proc_env_size);
352
}
353
 
354
 
355
/*
356
    ENCODE A CONSTANT
357
 
358
    The constant with declaration d, name id, definition c and body s
359
    is encoded.
360
*/
361
 
362
static void code_const
7 7u83 363
(dec *d)
2 7u83 364
{
7 7u83 365
   exp c = d->dec_u.dec_val.dec_exp;
366
   exp s = son(c);
367
   char *id = d->dec_u.dec_val.dec_id;
2 7u83 368
 
7 7u83 369
   diag_global *di = d->dec_u.dec_val.diag_info;
370
   area(isvar(c)? pdata : ptext);
2 7u83 371
#ifndef no_align_directives
7 7u83 372
   make_instr(m_as_align4, null, null, 0);
2 7u83 373
#endif
7 7u83 374
   evaluate(s, L_1 , id, !isvar(c), 1, di);
2 7u83 375
}
376
 
377
 
378
/*
379
    ENCODE THE CONSTANTS IN const_list
380
 
381
    All auxiliary constants are formed into a list, const_list.  This
382
    routine applies evaluate to each element of this list.
383
*/
384
 
385
static void code_const_list
7 7u83 386
(void)
2 7u83 387
{
7 7u83 388
    while (const_list != nilexp) {
389
	exp t = const_list;
390
	exp s = son(t);
391
	bool b = (name(s)!= res_tag);
392
	const_list = bro(const_list);
393
	if (name(s) == proc_tag || name(s) == general_proc_tag) {
394
	    char *id = alloc_nof(char, 30);
395
	    sprintf(id, "%s%ld", local_prefix, no(t));
396
	    gcproc(s, null, no(t), 0, 1, null);
2 7u83 397
	} else {
7 7u83 398
	    area(b ? pdata : ptext);
399
	    evaluate(s, no(t), null, b, 0, null);
2 7u83 400
	}
401
    }
7 7u83 402
    return;
2 7u83 403
}
404
 
405
/*
406
   CONST_READY
407
 
408
   Returns TRUE if it is possible to evaluate the value of the constant now
409
*/
410
 
411
static int const_ready
7 7u83 412
(exp e)
2 7u83 413
{
7 7u83 414
  unsigned char  n = name(e);
2 7u83 415
  if (n == env_size_tag)
7 7u83 416
    return(brog(son(son(e))) -> dec_u.dec_val.processed);
2 7u83 417
  if (n == env_offset_tag)
7 7u83 418
    return(ismarked(son(e)));
2 7u83 419
  if (n == name_tag || son(e) == nilexp)
420
    return 1;
421
  e = son(e);
422
  while (!last(e)) {
423
    if (!const_ready(e))
424
      return 0;
425
    e = bro(e);
426
  }
7 7u83 427
  return(const_ready(e));
2 7u83 428
}
429
 
430
typedef struct delayedconst{
431
   dec* This;
432
   struct delayedconst* next;
7 7u83 433
} delayed_const;
2 7u83 434
 
435
static delayed_const* delayed_const_list = 0;
436
 
437
static void eval_if_ready
7 7u83 438
(dec *d)
2 7u83 439
{
7 7u83 440
   exp c = d->dec_u.dec_val.dec_exp;
441
   if (const_ready(c)) {
442
      code_const(d);
2 7u83 443
   }
444
   else {
7 7u83 445
      delayed_const* p = (delayed_const*)xmalloc(sizeof(delayed_const));
2 7u83 446
      p->This = d;
447
      p->next = delayed_const_list;
448
      delayed_const_list = p;
449
   }
450
}
451
 
452
void eval_delayed_const_list
7 7u83 453
(void)
2 7u83 454
{
455
   delayed_const* p;
456
   bool done = 0;
457
   while (! done) {
458
      done = 1;
459
      for (p = delayed_const_list; p; p = p->next) {
460
         dec* d = p->This;
7 7u83 461
         if (!d->dec_u.dec_val.processed) {
462
            exp c = d->dec_u.dec_val.dec_exp;
463
            if (const_ready(c)) {
464
               code_const(d);
465
               d->dec_u.dec_val.processed = 1;
2 7u83 466
            }
467
            done = 0;
468
         }
469
      }
470
   }
471
}
472
 
473
 
474
/*
475
    OUTPUT ALL THE ENCODED EXPRESSIONS
476
 
477
    This routine scans through all the declarations encoding suitably.
478
*/
479
 
480
static void output_all_exps
7 7u83 481
(void)
2 7u83 482
{
7 7u83 483
    dec *d = top_def;
484
    if (diagnose)d = sort_decs(d);
2 7u83 485
 
7 7u83 486
    area(ptext);
2 7u83 487
 
488
    /* Clear any existing output */
7 7u83 489
    output_all();
490
    free_all_ins();
2 7u83 491
 
492
    /* Scan through the declarations */
7 7u83 493
    while (d) {
2 7u83 494
 
7 7u83 495
	if (!d->dec_u.dec_val.processed) {
496
	    exp c = d->dec_u.dec_val.dec_exp;
497
	    exp s = son(c);
498
	    char *id = d->dec_u.dec_val.dec_id;
2 7u83 499
 
7 7u83 500
	    init_output();
2 7u83 501
 
7 7u83 502
	    if (s != nilexp) {
503
		if (name(s) == proc_tag ||
504
                    name(s) == general_proc_tag) {
505
		    code_proc(d, id, c, s);
506
		    code_const_list();
507
                    d->dec_u.dec_val.processed = 1;
2 7u83 508
		} else {
7 7u83 509
		    eval_if_ready(d);
510
		    code_const_list();
2 7u83 511
		}
512
	    } else {
7 7u83 513
		shape sha = d->dec_u.dec_val.dec_shape;
514
		long sz = round(shape_size(sha) / 8, 4);
515
		area(ptext);
516
		if (!is_local(id) && isvar(c) &&
517
		     varsize(sha) && !reserved(id)) {
518
		    if (sz) {
519
			mach_op *op1 = make_extern_data(id, 0);
520
			mach_op *op2 = make_int_data(sz);
521
			make_instr(m_as_common, op1, op2, 0);
2 7u83 522
		    }
523
		} else {
7 7u83 524
		    if (is_local(id) && no(c)) {
525
			mach_op *op1 = make_extern_data(id, 0);
526
			mach_op *op2 = make_int_data(sz);
527
			make_instr(m_as_local, op1, op2, 0);
2 7u83 528
		    }
529
		}
7 7u83 530
                d->dec_u.dec_val.processed = 1;
2 7u83 531
	    }
532
 
7 7u83 533
	    output_all();
534
	    free_all_ins();
2 7u83 535
	}
7 7u83 536
	d = d->def_next;
2 7u83 537
    }
538
 
539
    eval_delayed_const_list();
7 7u83 540
    output_all();
541
    free_all_ins();
2 7u83 542
 
543
    /* Add final touches */
7 7u83 544
    init_output();
545
    if (need_dummy_double) {
546
       mach_op *op1 = make_extern_data("___m68k_dummy_double", 0);
547
       mach_op *op2 = make_int_data(8);
548
       make_instr(m_as_common, op1, op2, 0);
2 7u83 549
    }
550
 
7 7u83 551
    if (do_profile)profile_hack();
2 7u83 552
 
7 7u83 553
    area(pdata);
554
    output_all();
555
    free_all_ins();
556
    return;
2 7u83 557
}