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) 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
7 7u83 129
(regcell * s)
2 7u83 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) {
7 7u83 136
      dw_close_regassn(i, 0);
137
      dw_close_regassn(i, 1);
2 7u83 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
7 7u83 147
(regcell * s)
2 7u83 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) {
7 7u83 154
      dw_close_regassn(i, 0);
155
      dw_close_regassn(i, 1);
2 7u83 156
    }
157
#endif
158
  }
159
  return;
160
}
161
 
162
 
163
/* true if changing d invalidates r */
164
static  int inval
7 7u83 165
(exp d, exp r)
2 7u83 166
{
7 7u83 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)));
2 7u83 173
 
7 7u83 174
  if (name(r) == reff_tag)
175
    return(inval(d, son(r)));
2 7u83 176
 
7 7u83 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))));
2 7u83 181
  };
182
 
7 7u83 183
  if (name(r) == ident_tag)
184
    return(inval(d, son(r)) || inval(d, bro(son(r))));
2 7u83 185
 
7 7u83 186
  return(0);
2 7u83 187
}
188
 
189
/* true if changing d invalidates r */
190
int invalidates
7 7u83 191
(exp d, exp r)
2 7u83 192
{
7 7u83 193
  if (name(r) == cont_tag || name(r) == ass_tag)
194
    return(inval(d, son(r)));
195
  return(0);
2 7u83 196
}
197
 
198
/* convert register mask to register number */
199
static int  get_regno
7 7u83 200
(int mask)
2 7u83 201
{
202
  int   m = 1;
203
  int   res;
204
  for (res = 0; res < no_fixed_regs && (mask & m) == 0; res++)
205
    m = m + m;
7 7u83 206
  return(res);
2 7u83 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
7 7u83 214
(where w, int sz)
2 7u83 215
{
216
  int   i;
217
  where res;
218
  res.where_exp = nilexp;
219
 
220
  if (w.where_off != 0)
7 7u83 221
    return(res);
2 7u83 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) &&
7 7u83 226
	eq_where_exp(p -> first_dest, w.where_exp, 1,(sz==0))) {
2 7u83 227
#ifdef NEWDWARF
228
      if (dwarf2)
7 7u83 229
	dw_used_regassn(i, 0);
2 7u83 230
#endif
7 7u83 231
      return(reg_wheres[i]);
2 7u83 232
    }
233
    if ((p -> regcell_key & 2) &&
234
	(sz == 0 || sz == p -> second_size) &&
7 7u83 235
	eq_where_exp(p -> second_dest, w.where_exp, 1,(sz==0))) {
2 7u83 236
#ifdef NEWDWARF
237
      if (dwarf2)
7 7u83 238
	dw_used_regassn(i, 1);
2 7u83 239
#endif
7 7u83 240
      return(reg_wheres[i]);
2 7u83 241
    }
242
  };
243
  res.where_exp = nilexp;
7 7u83 244
  return(res);
2 7u83 245
}
246
 
247
static int is_aliased
7 7u83 248
(exp dest)
2 7u83 249
{
250
  if (dest == nilexp)
251
    return 0;
7 7u83 252
  if (name(dest)!= cont_tag &&
253
      name(dest)!= ass_tag)
254
    return(0);
2 7u83 255
 
7 7u83 256
  if (name(son(dest)) == name_tag &&
257
      isvar(son(son(dest))) &&
258
      iscaonly(son(son(dest))))
259
    return(0);
260
  return(1);
2 7u83 261
}
262
 
263
static  int shape_overlap
7 7u83 264
(exp e1, exp e2)
2 7u83 265
{
7 7u83 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);
2 7u83 273
}
274
 
275
 
276
/* make changes to the register record
277
   needed when dest receives an unknown
278
   value */
279
void invalidate_dest
7 7u83 280
(where dest)
2 7u83 281
{
282
  exp d = dest.where_exp;
7 7u83 283
  int  regmask = (d == nilexp)? 0 :(in_reg(d) & 0x7fffffff);
2 7u83 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
 
7 7u83 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)))) {
2 7u83 297
    cond1_set = 0;
298
    cond2_set = 0;
299
  };
300
 
7 7u83 301
  if (is_aliased(dest.where_exp)) {
2 7u83 302
    for (i = 0; i < no_fixed_regs; ++i) {
303
      regcell * pr = &crt_reg_record[i];
304
      switch (pr -> regcell_key) {
305
	case 1:
7 7u83 306
	  if (is_aliased(pr -> first_dest) &&
307
	      shape_overlap(dest.where_exp, pr -> first_dest)) {
2 7u83 308
	    pr -> regcell_key = 4;
309
#ifdef NEWDWARF
310
	    if (dwarf2)
7 7u83 311
	      dw_close_regassn(i, 0);
2 7u83 312
#endif
313
	  }
314
	  break;
315
	case 2:
7 7u83 316
	  if (is_aliased(pr -> second_dest) &&
317
	      shape_overlap(dest.where_exp, pr -> second_dest)) {
2 7u83 318
	    pr -> regcell_key = 4;
319
#ifdef NEWDWARF
320
	    if (dwarf2)
7 7u83 321
	      dw_close_regassn(i, 1);
2 7u83 322
#endif
323
	  }
324
	  break;
325
	case 3:
7 7u83 326
	  if (is_aliased(pr -> first_dest) &&
327
	      shape_overlap(dest.where_exp, pr -> first_dest)) {
2 7u83 328
	    pr -> regcell_key &= 2;
329
#ifdef NEWDWARF
330
	    if (dwarf2)
7 7u83 331
	      dw_close_regassn(i, 0);
2 7u83 332
#endif
333
	  }
7 7u83 334
	  if (is_aliased(pr -> second_dest) &&
335
	      shape_overlap(dest.where_exp, pr -> second_dest)) {
2 7u83 336
	    pr -> regcell_key &= 1;
337
#ifdef NEWDWARF
338
	    if (dwarf2)
7 7u83 339
	      dw_close_regassn(i, 1);
2 7u83 340
#endif
341
	  }
342
	  if (pr -> regcell_key == 0)
343
	    pr -> regcell_key = 4;
7 7u83 344
	default:;
2 7u83 345
      };
346
    };
347
  };
348
 
349
  if (regmask) {
7 7u83 350
    regno = get_regno(regmask);
2 7u83 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:
7 7u83 360
	  if (invalidates(d, pr -> first_dest)) {
2 7u83 361
	    pr -> regcell_key = 4;
362
#ifdef NEWDWARF
363
	    if (dwarf2)
7 7u83 364
	      dw_close_regassn(i, 0);
2 7u83 365
#endif
366
	  }
367
	  break;
368
	case 2:
7 7u83 369
	  if (invalidates(d, pr -> second_dest)) {
2 7u83 370
	    pr -> regcell_key = 4;
371
#ifdef NEWDWARF
372
	    if (dwarf2)
7 7u83 373
	      dw_close_regassn(i, 1);
2 7u83 374
#endif
375
	  }
376
	  break;
377
	case 3:
7 7u83 378
	  if (invalidates(d, pr -> first_dest)) {
2 7u83 379
	    pr -> regcell_key &= 2;
380
#ifdef NEWDWARF
381
	    if (dwarf2)
7 7u83 382
	      dw_close_regassn(i, 0);
2 7u83 383
#endif
384
	  }
7 7u83 385
	  if (invalidates(d, pr -> second_dest)) {
2 7u83 386
	    pr -> regcell_key &= 1;
387
#ifdef NEWDWARF
388
	    if (dwarf2)
7 7u83 389
	      dw_close_regassn(i, 1);
2 7u83 390
#endif
391
	  }
392
	  if (pr -> regcell_key == 0)
393
	    pr -> regcell_key = 4;
7 7u83 394
	default:;
2 7u83 395
      };
396
    };
397
    return;
398
  };
399
#ifdef NEWDWARF
400
  dw_ignore_used_regassn = 1;
401
#endif
402
  while (1) {
7 7u83 403
    weq = equiv_reg(dest, 0);
2 7u83 404
    if (weq.where_exp == nilexp)
405
      break;
7 7u83 406
    regmask = (in_reg(weq.where_exp) & 0x7fffffff);
407
    regno = get_regno(regmask);
2 7u83 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
7 7u83 420
(where from, where to, shape sha)
2 7u83 421
{
7 7u83 422
  int  regmask_to = in_reg(to.where_exp);
423
  int  regmask_from = in_reg(from.where_exp);
2 7u83 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;
7 7u83 433
  if (regmask_to && invalidates(to.where_exp, from.where_exp))
2 7u83 434
    return;
435
  if (regmask_to && regmask_to < 64) {
7 7u83 436
    int   regno_to = get_regno(regmask_to);
2 7u83 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)
7 7u83 446
	    dw_init_regassn(regno_to, 1);
2 7u83 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)
7 7u83 457
	    dw_init_regassn(regno_to, 0);
2 7u83 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)
7 7u83 470
	    dw_init_regassn(regno_to, 0);
2 7u83 471
#endif
472
	  break;
473
	};
474
    };
475
  };
476
  if (regmask_from && regmask_from < 64) {
7 7u83 477
    int   regno_from = get_regno(regmask_from);
2 7u83 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)
7 7u83 487
	    dw_init_regassn(regno_from, 1);
2 7u83 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)
7 7u83 498
	    dw_init_regassn(regno_from, 0);
2 7u83 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)
7 7u83 511
	    dw_init_regassn(regno_from, 0);
2 7u83 512
#endif
513
	  break;
514
	};
515
    };
516
  };
517
}