Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
6 7u83 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
 */
31
/*
32
    		 Crown Copyright (c) 1997
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
 
61
/* 80x86/reg_record.c */
62
 
63
/**********************************************************************
64
$Author: pwe $
65
$Date: 1998/03/15 16:00:22 $
66
$Revision: 1.3 $
67
 
68
$Log: reg_record.c,v $
69
 * Revision 1.3  1998/03/15  16:00:22  pwe
70
 * regtrack dwarf dagnostics added
71
 *
72
 * Revision 1.2  1998/02/02  11:18:25  pwe
73
 * 80x86 shape_overlap correction
74
 *
75
 * Revision 1.1.1.1  1998/01/17  15:55:52  release
76
 * First version to be checked into rolling release.
77
 *
78
 * Revision 1.4  1996/12/10  15:41:17  pwe
79
 * check condition at invalidate_dest
80
 *
81
 * Revision 1.3  1995/04/03  08:30:28  pwe
82
 * invalidate regs if overlap, eg if bitfield on byte boundaries
83
 *
84
 * Revision 1.2  1995/01/30  12:56:44  pwe
85
 * Ownership -> PWE, tidy banners
86
 *
87
 * Revision 1.1  1994/10/27  14:15:22  jmf
88
 * Initial revision
89
 *
90
 * Revision 1.1  1994/07/12  14:39:53  jmf
91
 * Initial revision
92
 *
93
**********************************************************************/
94
 
95
 
96
 
97
#include "config.h"
98
#include "common_types.h"
99
#include "operand.h"
100
#include "tags.h"
101
#include "exp.h"
102
#include "expmacs.h"
103
#include "instr386.h"
104
#include "shapemacs.h"
105
#include "codermacs.h"
106
#include "flags.h"
107
 
108
#ifdef NEWDWARF
109
#include "dw2_extra.h"
110
#endif
111
 
112
#include "reg_record.h"
113
 
114
 
115
/* This collection of routines maintains a record of what is known to
116
   to be in each register during code production
117
*/
118
 
119
/* VARIABLES */
120
/* All variables initialised */
121
 
122
reg_record crt_reg_record;
123
				/* init by cproc */
124
 
125
/* PROCEDURES */
126
 
127
/* clear out all the register records */
128
void clear_reg_record
129
(regcell * s)
130
{
131
  int   i;
132
  for (i = 0; i < no_fixed_regs; ++i) {
133
    s[i].regcell_key = 4;
134
#ifdef NEWDWARF
135
    if (dwarf2) {
136
      dw_close_regassn(i, 0);
137
      dw_close_regassn(i, 1);
138
    }
139
#endif
140
  }
141
  return;
142
}
143
 
144
/* clear out the registers not preserved
145
   over procedure calls */
146
void clear_low_reg_record
147
(regcell * s)
148
{
149
  int   i;
150
  for (i = 0; i < no_fixed_regs; ++i) {
151
    s[i].regcell_key = 4;
152
#ifdef NEWDWARF
153
    if (dwarf2) {
154
      dw_close_regassn(i, 0);
155
      dw_close_regassn(i, 1);
156
    }
157
#endif
158
  }
159
  return;
160
}
161
 
162
 
163
/* true if changing d invalidates r */
164
static  int inval
165
(exp d, exp r)
166
{
167
  if ((d == nilexp || name(d) == cont_tag) &&
168
     (name(r) == cont_tag || (name(r) == name_tag && isglob(son(r)))))
169
    return(1);
170
  if ((name(r) == name_tag && !isvar(son(r))) ||
171
	name(r) == cont_tag)
172
    return(eq_where(mw(d, 0), mw(r, 0)));
173
 
174
  if (name(r) == reff_tag)
175
    return(inval(d, son(r)));
176
 
177
  if (name(r) == addptr_tag) {
178
    if (name(bro(son(r))) == offset_mult_tag)
179
      return(inval(d, son(r)) || inval(d, son(bro(son(r)))));
180
    return(inval(d, son(r)) || inval(d, bro(son(r))));
181
  };
182
 
183
  if (name(r) == ident_tag)
184
    return(inval(d, son(r)) || inval(d, bro(son(r))));
185
 
186
  return(0);
187
}
188
 
189
/* true if changing d invalidates r */
190
int invalidates
191
(exp d, exp r)
192
{
193
  if (name(r) == cont_tag || name(r) == ass_tag)
194
    return(inval(d, son(r)));
195
  return(0);
196
}
197
 
198
/* convert register mask to register number */
199
static int  get_regno
200
(int mask)
201
{
202
  int   m = 1;
203
  int   res;
204
  for (res = 0; res < no_fixed_regs && (mask & m) == 0; res++)
205
    m = m + m;
206
  return(res);
207
}
208
 
209
/* if there is a register holding the same
210
   value as is in w, return this register
211
   (as a where), otherwise the where_exp
212
   field of the result will be nilexp */
213
where equiv_reg
214
(where w, int sz)
215
{
216
  int   i;
217
  where res;
218
  res.where_exp = nilexp;
219
 
220
  if (w.where_off != 0)
221
    return(res);
222
  for (i = 0; i < no_fixed_regs; i++) {
223
    regcell * p = &crt_reg_record[i];
224
    if ((p -> regcell_key & 1) &&
225
	(sz == 0 || sz == p -> first_size) &&
226
	eq_where_exp(p -> first_dest, w.where_exp, 1,(sz==0))) {
227
#ifdef NEWDWARF
228
      if (dwarf2)
229
	dw_used_regassn(i, 0);
230
#endif
231
      return(reg_wheres[i]);
232
    }
233
    if ((p -> regcell_key & 2) &&
234
	(sz == 0 || sz == p -> second_size) &&
235
	eq_where_exp(p -> second_dest, w.where_exp, 1,(sz==0))) {
236
#ifdef NEWDWARF
237
      if (dwarf2)
238
	dw_used_regassn(i, 1);
239
#endif
240
      return(reg_wheres[i]);
241
    }
242
  };
243
  res.where_exp = nilexp;
244
  return(res);
245
}
246
 
247
static int is_aliased
248
(exp dest)
249
{
250
  if (dest == nilexp)
251
    return 0;
252
  if (name(dest)!= cont_tag &&
253
      name(dest)!= ass_tag)
254
    return(0);
255
 
256
  if (name(son(dest)) == name_tag &&
257
      isvar(son(son(dest))) &&
258
      iscaonly(son(son(dest))))
259
    return(0);
260
  return(1);
261
}
262
 
263
static  int shape_overlap
264
(exp e1, exp e2)
265
{
266
  shape s1 = sh(e1);
267
  shape s2 = sh(e2);
268
  if (name(s1) <= doublehd && name(s1) > tophd && name(s2) == ptrhd)
269
    return(0);
270
  if (name(s2) <= doublehd && name(s2) > tophd && name(s1) == ptrhd)
271
    return(0);
272
  return(1);
273
}
274
 
275
 
276
/* make changes to the register record
277
   needed when dest receives an unknown
278
   value */
279
void invalidate_dest
280
(where dest)
281
{
282
  exp d = dest.where_exp;
283
  int  regmask = (d == nilexp)? 0 :(in_reg(d) & 0x7fffffff);
284
  int  regno;
285
  where weq;
286
  int   i;
287
 
288
	/* this repeats the condition state check at start of move,
289
	   in case contop has reset it */
290
 
291
  if ((cond1_set && (eq_where(dest, cond1) ||
292
	  invalidates(dest.where_exp, cond1.where_exp))) ||
293
     (cond2_set &&
294
	(eq_where(dest, cond2a) || eq_where(dest, cond2b) ||
295
	  invalidates(dest.where_exp, cond2a.where_exp) ||
296
	  invalidates(dest.where_exp, cond2b.where_exp)))) {
297
    cond1_set = 0;
298
    cond2_set = 0;
299
  };
300
 
301
  if (is_aliased(dest.where_exp)) {
302
    for (i = 0; i < no_fixed_regs; ++i) {
303
      regcell * pr = &crt_reg_record[i];
304
      switch (pr -> regcell_key) {
305
	case 1:
306
	  if (is_aliased(pr -> first_dest) &&
307
	      shape_overlap(dest.where_exp, pr -> first_dest)) {
308
	    pr -> regcell_key = 4;
309
#ifdef NEWDWARF
310
	    if (dwarf2)
311
	      dw_close_regassn(i, 0);
312
#endif
313
	  }
314
	  break;
315
	case 2:
316
	  if (is_aliased(pr -> second_dest) &&
317
	      shape_overlap(dest.where_exp, pr -> second_dest)) {
318
	    pr -> regcell_key = 4;
319
#ifdef NEWDWARF
320
	    if (dwarf2)
321
	      dw_close_regassn(i, 1);
322
#endif
323
	  }
324
	  break;
325
	case 3:
326
	  if (is_aliased(pr -> first_dest) &&
327
	      shape_overlap(dest.where_exp, pr -> first_dest)) {
328
	    pr -> regcell_key &= 2;
329
#ifdef NEWDWARF
330
	    if (dwarf2)
331
	      dw_close_regassn(i, 0);
332
#endif
333
	  }
334
	  if (is_aliased(pr -> second_dest) &&
335
	      shape_overlap(dest.where_exp, pr -> second_dest)) {
336
	    pr -> regcell_key &= 1;
337
#ifdef NEWDWARF
338
	    if (dwarf2)
339
	      dw_close_regassn(i, 1);
340
#endif
341
	  }
342
	  if (pr -> regcell_key == 0)
343
	    pr -> regcell_key = 4;
344
	default:;
345
      };
346
    };
347
  };
348
 
349
  if (regmask) {
350
    regno = get_regno(regmask);
351
    if (regno < no_fixed_regs)
352
      crt_reg_record[regno].regcell_key = 4;
353
  };
354
 
355
  if (regmask || d == nilexp) {
356
    for (i = 0; i < no_fixed_regs; ++i) {
357
      regcell * pr = &crt_reg_record[i];
358
      switch (pr -> regcell_key) {
359
	case 1:
360
	  if (invalidates(d, pr -> first_dest)) {
361
	    pr -> regcell_key = 4;
362
#ifdef NEWDWARF
363
	    if (dwarf2)
364
	      dw_close_regassn(i, 0);
365
#endif
366
	  }
367
	  break;
368
	case 2:
369
	  if (invalidates(d, pr -> second_dest)) {
370
	    pr -> regcell_key = 4;
371
#ifdef NEWDWARF
372
	    if (dwarf2)
373
	      dw_close_regassn(i, 1);
374
#endif
375
	  }
376
	  break;
377
	case 3:
378
	  if (invalidates(d, pr -> first_dest)) {
379
	    pr -> regcell_key &= 2;
380
#ifdef NEWDWARF
381
	    if (dwarf2)
382
	      dw_close_regassn(i, 0);
383
#endif
384
	  }
385
	  if (invalidates(d, pr -> second_dest)) {
386
	    pr -> regcell_key &= 1;
387
#ifdef NEWDWARF
388
	    if (dwarf2)
389
	      dw_close_regassn(i, 1);
390
#endif
391
	  }
392
	  if (pr -> regcell_key == 0)
393
	    pr -> regcell_key = 4;
394
	default:;
395
      };
396
    };
397
    return;
398
  };
399
#ifdef NEWDWARF
400
  dw_ignore_used_regassn = 1;
401
#endif
402
  while (1) {
403
    weq = equiv_reg(dest, 0);
404
    if (weq.where_exp == nilexp)
405
      break;
406
    regmask = (in_reg(weq.where_exp) & 0x7fffffff);
407
    regno = get_regno(regmask);
408
    if (regno < no_fixed_regs)
409
      crt_reg_record[regno].regcell_key = 4;
410
  };
411
#ifdef NEWDWARF
412
  dw_ignore_used_regassn = 0;
413
#endif
414
  return;
415
}
416
 
417
/* from is being moved to to. Make changes
418
   to the register records accordingly */
419
void move_reg
420
(where from, where to, shape sha)
421
{
422
  int  regmask_to = in_reg(to.where_exp);
423
  int  regmask_from = in_reg(from.where_exp);
424
  int sz = shape_size(sha);
425
  if (name(sha) == shrealhd)
426
    return;
427
  if (regmask_from != 0 && regmask_to != 0)
428
    return;
429
  if ((regmask_from & (int)0x80000000) || (regmask_to & (int)0x80000000))
430
    return;
431
  if (from.where_off != 0 || to.where_off != 0)
432
    return;
433
  if (regmask_to && invalidates(to.where_exp, from.where_exp))
434
    return;
435
  if (regmask_to && regmask_to < 64) {
436
    int   regno_to = get_regno(regmask_to);
437
    regcell * p = &crt_reg_record[regno_to];
438
    switch (p -> regcell_key) {
439
      case 1:
440
	{
441
	  p -> regcell_key = 3;
442
	  p -> second_dest = from.where_exp;
443
	  p -> second_size = sz;
444
#ifdef NEWDWARF
445
	  if (dwarf2)
446
	    dw_init_regassn(regno_to, 1);
447
#endif
448
	  break;
449
	};
450
      case 2:
451
	{
452
	  p -> regcell_key = 3;
453
	  p -> first_dest = from.where_exp;
454
	  p -> first_size = sz;
455
#ifdef NEWDWARF
456
	  if (dwarf2)
457
	    dw_init_regassn(regno_to, 0);
458
#endif
459
	  break;
460
	};
461
      case 3:
462
	break;
463
      default:
464
	{
465
	  p -> regcell_key = 1;
466
	  p -> first_dest = from.where_exp;
467
	  p -> first_size = sz;
468
#ifdef NEWDWARF
469
	  if (dwarf2)
470
	    dw_init_regassn(regno_to, 0);
471
#endif
472
	  break;
473
	};
474
    };
475
  };
476
  if (regmask_from && regmask_from < 64) {
477
    int   regno_from = get_regno(regmask_from);
478
    regcell * p = &crt_reg_record[regno_from];
479
    switch (p -> regcell_key) {
480
      case 1:
481
	{
482
	  p -> regcell_key = 3;
483
	  p -> second_dest = to.where_exp;
484
	  p -> second_size = sz;
485
#ifdef NEWDWARF
486
	  if (dwarf2)
487
	    dw_init_regassn(regno_from, 1);
488
#endif
489
	  break;
490
	};
491
      case 2:
492
	{
493
	  p -> regcell_key = 3;
494
	  p -> first_dest = to.where_exp;
495
	  p -> first_size = sz;
496
#ifdef NEWDWARF
497
	  if (dwarf2)
498
	    dw_init_regassn(regno_from, 0);
499
#endif
500
	  break;
501
	};
502
      case 3:
503
	break;
504
      default:
505
	{
506
	  p -> regcell_key = 1;
507
	  p -> first_dest = to.where_exp;
508
	  p -> first_size = sz;
509
#ifdef NEWDWARF
510
	  if (dwarf2)
511
	    dw_init_regassn(regno_from, 0);
512
#endif
513
	  break;
514
	};
515
    };
516
  };
517
}