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
/**********************************************************************
62
$Author: pwe $
63
$Date: 1998/03/17 16:34:54 $
64
$Revision: 1.6 $
65
$Log: dw2_extra.c,v $
66
 * Revision 1.6  1998/03/17  16:34:54  pwe
67
 * correction for non-NEWDIAGS
68
 *
69
 * Revision 1.5  1998/03/15  16:00:15  pwe
70
 * regtrack dwarf dagnostics added
71
 *
72
 * Revision 1.4  1998/03/11  11:03:04  pwe
73
 * DWARF optimisation info
74
 *
75
 * Revision 1.3  1998/02/18  11:22:01  pwe
76
 * test corrections
77
 *
78
 * Revision 1.2  1998/01/21  10:29:59  pwe
79
 * labdiff change
80
 *
81
 * Revision 1.1.1.1  1998/01/17  15:55:51  release
82
 * First version to be checked into rolling release.
83
 *
84
 * Revision 1.1  1998/01/09  14:47:37  pwe
85
 * prep restructure
86
 *
87
 * Revision 1.10  1997/12/04  20:01:36  pwe
88
 * ANDF-DE V1.9
89
 *
90
 * Revision 1.9  1997/10/28  10:26:55  pwe
91
 * correct extra diags / locations
92
 *
93
 * Revision 1.8  1997/10/23  09:37:36  pwe
94
 * extra_diags
95
 *
96
 * Revision 1.7  1997/10/10  18:26:09  pwe
97
 * prep ANDF-DE revision
98
 *
99
 * Revision 1.6  1997/08/23  13:46:10  pwe
100
 * initial ANDF-DE
101
 *
102
 * Revision 1.5  1997/05/02  11:05:04  pwe
103
 * minor dwarf2 corrections
104
 *
105
 * Revision 1.4  1997/04/17  11:56:12  pwe
106
 * dwarf2 improvements
107
 *
108
 * Revision 1.3  1997/04/02  10:33:49  pwe
109
 * diagnose pl_tests
110
 *
111
 * Revision 1.2  1997/03/24  11:15:53  pwe
112
 * dwarf2 option/default
113
 *
114
 * Revision 1.1  1997/03/20  16:24:44  pwe
115
 * dwarf2
116
 *
117
**********************************************************************/
118
 
119
#include "config.h"
120
#include "common_types.h"
121
 
122
#ifdef NEWDWARF
123
 
124
#include "localtypes.h"
125
#include "dg_aux.h"
126
#include "dg_types.h"
127
#include "dw2_config.h"
128
#include "dw2_codes.h"
129
#include "dw2_entries.h"
130
#include "dw2_basic.h"
131
#include "dw2_info.h"
132
#include "codermacs.h"
133
#include "flags.h"
134
#include "operand.h"
135
#include "machine.h"
136
#include "instr386.h"
137
#include "expmacs.h"
138
#include "shapemacs.h"
139
#include "instr.h"
140
#include "basicread.h"
141
#include "szs_als.h"
142
#include "coder.h"
143
#include "tags.h"
144
#include "const.h"
145
#include "label_ops.h"
146
#include "flpttypes.h"
147
#include "f64.h"
148
#include "dw2_extra.h"
149
#include "operand.h"
150
#include "reg_record.h"
151
#include "dw2_locdata.h"
152
 
153
 
154
extern int locals_offset; /* declared in cproc.c */
155
 
156
 
7 7u83 157
static long dwarfreg[8] = {0, 2, 1, 3, 7, 6, 5, 4};
2 7u83 158
#define dw_sp 4
159
#define dw_fp 5
160
#define retaddr 8
161
 
162
static long cie_pointer;
163
static long fde_end;
164
static long proc_end;
165
 
166
static char * sp50 = "                                                  ";
167
 
168
enum loctype { L_INREG = 1, L_REGOFF, L_GLOB, L_INDIRECT };
169
 
170
typedef struct {
171
  enum loctype key;
172
  int reg;
173
  char* s;
174
  long off;
175
} loc_s;
176
 
177
static int extra_deref;
178
static int locate_param;
179
static int has_fp;
180
static int no_location;
181
 
182
 
183
 
184
 
185
static void outsep
7 7u83 186
(void)
2 7u83 187
{
7 7u83 188
  outs(", ");
2 7u83 189
}
190
 
191
 
192
int dw_is_const
7 7u83 193
(exp e)
2 7u83 194
{
195
  switch (name(e)) {
196
    case val_tag:
197
    case null_tag:
198
    case real_tag:
199
      return 1;
200
    case name_tag:
7 7u83 201
      return(!isdiscarded(e) && isvar(son(e)));
2 7u83 202
#if 0
203
    case cont_tag:
7 7u83 204
      return(name(son(e)) == name_tag && !isdiscarded(son(e)) &&
205
		!isvar(son(son(e))) && !isparam(son(son(e))));
2 7u83 206
#endif
207
    case reff_tag:
208
      return 1;
209
    default:
210
      return 0;
211
  }
212
}
213
 
214
exp dw_has_location
7 7u83 215
(exp e)
2 7u83 216
{
217
  switch (name(e)) {
218
    case name_tag: {
219
      if (isdiscarded(e) || isvar(son(e)))
220
	return nilexp;
7 7u83 221
      return(son(e));
2 7u83 222
    }
223
    case cont_tag: {
224
      do {
225
	e = son(e);
226
	if (name(e) == name_tag && isdiscarded(e))
227
	  return nilexp;
228
      }
7 7u83 229
      while (name(e)!= ident_tag);
2 7u83 230
      return e;
231
    }
232
    default:
233
      return nilexp;
234
  }
235
}
236
 
237
 
7 7u83 238
static loc_s name_to_loc(exp e);
2 7u83 239
 
240
static loc_s find_param
7 7u83 241
(exp e)
2 7u83 242
{
243
  switch (name(e)) {
244
    case name_tag:
245
      if (isvar(son(e)))
246
	extra_deref--;
247
      if (isparam(son(e)))
7 7u83 248
        return name_to_loc(e);
249
      return find_param(son(son(e)));
2 7u83 250
    case cont_tag:
251
      extra_deref++;	/* drop through */
252
    case chvar_tag:
253
    case chfl_tag:
7 7u83 254
      return find_param(son(e));
2 7u83 255
    default:
256
      break;
257
  }
7 7u83 258
  failer("parameter inconsistency");
259
  return find_param(e);
2 7u83 260
}
261
 
262
static loc_s name_to_loc
7 7u83 263
(exp e)
2 7u83 264
{
265
  loc_s l;
266
  exp id = son(e);
7 7u83 267
  long n_off = no(e) /8;
2 7u83 268
  if (locate_param && !isparam(id)) {
7 7u83 269
    return find_param(son(id));
2 7u83 270
#if 0
271
    if (name(son(id)) == name_tag && isloadparam(son(id)) && isparam(son(son(id))))
7 7u83 272
      return name_to_loc(son(id));
2 7u83 273
    if (name(son(id)) == cont_tag && name(son(son(id))) == name_tag &&
274
		isparam(son(son(son(id)))))
7 7u83 275
      return name_to_loc(son(son(id)));
276
    failer("parameter inconsistency");
2 7u83 277
#endif
278
  }
7 7u83 279
  if (isglob(id)) {
2 7u83 280
    l.key = L_GLOB;
281
    l.s = brog(id) -> dec_u.dec_val.dec_id;
282
    l.off = n_off;
283
  }
284
  else {
7 7u83 285
    switch (ptno(id)) {
2 7u83 286
      case local_pl: {
287
	l.key = L_REGOFF;
288
	l.reg = -1;
7 7u83 289
	l.off = (no(id) /8) + n_off;
2 7u83 290
	if (name(id))
291
	  l.off -= locals_offset;
292
	else {			/* env_off modification */
293
	  if (locate_param) {
294
	    l.reg = dw_sp;
295
	  }
296
	}
297
	if (has_fp && l.reg < 0)
298
	  l.off += 4;
299
	break;
300
      };
301
      case callstack_pl: {
7 7u83 302
	failer("callstack arg - location list needed");
2 7u83 303
	break;
304
      };
305
      case par_pl: {
306
	l.key = L_REGOFF;
307
	l.reg = (locate_param ? dw_sp : -1);
7 7u83 308
	l.off = (no(id) /8) +4 + n_off;
2 7u83 309
	break;
310
      };
311
      case reg_pl: {
7 7u83 312
	int z = get_reg_no(no(id));
2 7u83 313
	l.key = L_INREG;
7 7u83 314
	l.reg = (z >= first_fl_reg ? 100 + z - first_fl_reg :
2 7u83 315
					(int)dwarfreg[z]);
316
	break;
317
      };
318
      default:
7 7u83 319
	failer("no location for id");
320
	SET(l);
2 7u83 321
    }
322
    if (has_fp && l.reg < 0)
323
      l.off += 4;
324
  }
325
  return l;
326
}
327
 
328
static loc_s find_loc
7 7u83 329
(exp e)
2 7u83 330
{
331
  loc_s l;
7 7u83 332
  switch (name(e)) {
2 7u83 333
 
7 7u83 334
    case name_tag: {
2 7u83 335
      if (isdiscarded(e) || (isglob(son(e)) && no(son(e)) == 0 &&
7 7u83 336
				!(brog(son(e)) ->dec_u.dec_val.extnamed))) {
2 7u83 337
	l.key = L_INREG;
338
	l.reg = 0;
339
	no_location = 1;
340
	return l;
341
      }
7 7u83 342
      if (isvar(son(e)))
2 7u83 343
	extra_deref--;
7 7u83 344
      return name_to_loc(e);
2 7u83 345
    }
346
 
7 7u83 347
    case cont_tag:
348
    case contvol_tag: {
2 7u83 349
      if (name(son(e)) == name_tag) {
350
	if (isdiscarded(son(e)) ||
351
			(isglob(son(son(e))) && no(son(son(e))) == 0 &&
7 7u83 352
			 !(brog(son(son(e))) ->dec_u.dec_val.extnamed))) {
2 7u83 353
	  l.key = L_INREG;
354
	  l.reg = 0;
355
	  no_location = 1;
356
	  return l;
357
	}
7 7u83 358
	if (isvar(son(son(e))))
359
	  return name_to_loc(son(e));
2 7u83 360
      }
7 7u83 361
      l = find_loc(son(e));
2 7u83 362
      if (l.key == L_INREG) {
363
	l.key = L_REGOFF;
364
	l.off = 0;
365
      }
366
      else
367
	l.key = L_INDIRECT;
368
      break;
369
    }
370
 
7 7u83 371
    case reff_tag: {
372
      l = find_loc(son(e));
2 7u83 373
      if (l.key == L_GLOB || l.key == L_REGOFF)
7 7u83 374
	l.off += (no(e) /8);
2 7u83 375
      else
376
      if (l.key == L_INREG) {
377
	l.key = L_REGOFF;
7 7u83 378
	l.off = (no(e) /8);
2 7u83 379
	extra_deref--;
380
      }
381
      else
382
	l.key = L_INDIRECT;
383
      break;
384
    }
385
 
7 7u83 386
    case chvar_tag: {
387
      l = find_loc(son(e));
2 7u83 388
      break;
389
    }
390
 
391
    default:
7 7u83 392
      failer("unimplemented location condition");
393
      SET(l);
2 7u83 394
  }
395
  return l;
396
}
397
 
398
static int inreg_length
7 7u83 399
(int r, int more)
2 7u83 400
{
401
  int ans = 1 + more;
402
  if (r >= 32)
403
    ans += uleb128_length((unsigned long)r);
404
  return ans;
405
}
406
 
407
static void out_inreg
7 7u83 408
(int r, int more)
2 7u83 409
{
410
  if (!more) {
411
    if (r < 32)
7 7u83 412
      outn((long)(DW_OP_reg0 + r));
2 7u83 413
    else {
7 7u83 414
      outn((long)DW_OP_regx); outsep(); uleb128((unsigned long)r);
2 7u83 415
    }
416
  }
417
  else {
418
    if (r < 32)
7 7u83 419
      outn((long)(DW_OP_breg0 + r));
2 7u83 420
    else {
7 7u83 421
      outn((long)DW_OP_bregx); outsep(); uleb128((unsigned long)r);
2 7u83 422
    }
7 7u83 423
    outsep(); outn((long)0);
2 7u83 424
  }
425
  return;
426
}
427
 
428
static int regoff_length
7 7u83 429
(loc_s l)
2 7u83 430
{
7 7u83 431
  return(1 + sleb128_length(l.off));
2 7u83 432
}
433
 
434
static void out_regoff
7 7u83 435
(loc_s l)
2 7u83 436
{
7 7u83 437
  outn((long)(l.reg < 0 ? DW_OP_fbreg : DW_OP_breg0 + l.reg)); outsep();
438
  sleb128(l.off);
2 7u83 439
  return;
440
}
441
 
442
static int glob_length
7 7u83 443
(loc_s l)
2 7u83 444
{
7 7u83 445
  UNUSED(l);
2 7u83 446
  return 5;
447
}
448
 
449
static void out_glob
7 7u83 450
(loc_s l)
2 7u83 451
{
7 7u83 452
  outn((long)DW_OP_addr); d_outnl();
453
  out32(); outs(l.s);
2 7u83 454
  if (l.off) {
7 7u83 455
    outs(" + ");
456
    outn((long)l.off);
2 7u83 457
  }
458
  return;
459
}
460
 
461
static int indirect_length
7 7u83 462
(exp e)
2 7u83 463
{
464
  int length;
465
  loc_s l;
466
  switch (name(e)) {
467
    case cont_tag: {
468
      length = 1;
469
      break;
470
    }
471
    case reff_tag: {
472
      if (no(e) >= 0)
7 7u83 473
	length = 1 + uleb128_length((unsigned long)(no(e) /8));
2 7u83 474
      else
7 7u83 475
	length = 2 + uleb128_length((unsigned long)(-no(e) /8));
2 7u83 476
      break;
477
    }
478
    default: {
7 7u83 479
      failer("unimplemented dwarf locate");
2 7u83 480
      return 0;
481
    }
482
  }
7 7u83 483
  l = find_loc(son(e));
2 7u83 484
  switch (l.key) {
485
    case L_INREG: {
7 7u83 486
      length += inreg_length(l.reg, 1);
2 7u83 487
      break;
488
    }
489
    case L_REGOFF: {
490
      length += regoff_length(l);
491
      break;
492
    }
493
    case L_GLOB: {
494
      length += glob_length(l);
495
      break;
496
    }
497
    case L_INDIRECT: {
498
      length += indirect_length(son(e));
499
      break;
500
    }
501
  }
502
  return length;
503
}
504
 
505
static void out_indirect
7 7u83 506
(exp e)
2 7u83 507
{
508
  loc_s l;
7 7u83 509
  l = find_loc(e);
2 7u83 510
  switch (l.key) {
511
    case L_INREG: {
7 7u83 512
      out_inreg(l.reg, 1);
2 7u83 513
      outsep();
514
      break;
515
    }
516
    case L_REGOFF: {
7 7u83 517
      out_regoff(l);
2 7u83 518
      outsep();
519
      break;
520
    }
521
    case L_GLOB: {
7 7u83 522
      out_glob(l);
2 7u83 523
      d_outnl(); out8();
524
      break;
525
    }
526
    case L_INDIRECT: {
527
      out_indirect(son(e));
528
      outsep();
529
      break;
530
    }
531
  }
532
  switch (name(e)) {
533
    case cont_tag: {
7 7u83 534
      outn((long)DW_OP_deref);
2 7u83 535
      break;
536
    }
537
    case reff_tag: {
538
      if (no(e) >= 0) {
7 7u83 539
	outn((long)DW_OP_plus_uconst); outsep();
540
	uleb128((unsigned long)(no(e) /8));
2 7u83 541
      }
542
      else {
7 7u83 543
	outn((long)DW_OP_constu); outsep();
544
	uleb128((unsigned long)(-no(e) /8)); outsep();
545
	outn((long)DW_OP_minus);
2 7u83 546
      }
547
      break;
548
    }
549
  }
550
  return;
551
}
552
 
553
 
554
void dw2_locate_exp
7 7u83 555
(exp e, int locate_const, int cx)
2 7u83 556
{
557
  loc_s l;
558
  int length;
559
  int within_loclist = (cx & 1);
560
  locate_param = (cx & 2);
561
  extra_deref = locate_const;
562
  no_location = 0;
563
  l = find_loc (e);	/* may reduce extra_deref */
564
  length = extra_deref;
565
  switch (l.key) {
566
    case L_INREG: {
7 7u83 567
      length += inreg_length(l.reg, extra_deref);
2 7u83 568
      break;
569
    }
570
    case L_REGOFF: {
571
      length += regoff_length(l);
572
      break;
573
    }
574
    case L_GLOB: {
575
      length += glob_length(l);
576
      break;
577
    }
578
    case L_INDIRECT: {
579
      length += indirect_length(e);
580
      break;
581
    }
582
  }
583
  if (no_location)
584
    length = 0;
585
 
586
  if (within_loclist) {
7 7u83 587
    out16();
588
    outn((long)length); outnl();
2 7u83 589
    if (no_location)
590
      return;
7 7u83 591
    out8();
2 7u83 592
  }
593
  else {
7 7u83 594
    out8();
595
    outn((long)length);
2 7u83 596
    if (no_location) {
597
      outnl();
598
      return;
599
    }
600
    outsep();
601
  }
602
  switch (l.key) {
603
    case L_INREG: {
7 7u83 604
      out_inreg(l.reg, extra_deref);
2 7u83 605
      break;
606
    }
607
    case L_REGOFF: {
7 7u83 608
      out_regoff(l);
2 7u83 609
      break;
610
    }
611
    case L_GLOB: {
7 7u83 612
      out_glob(l);
2 7u83 613
      break;
614
    }
615
    case L_INDIRECT: {
7 7u83 616
      out_indirect(e);
2 7u83 617
      break;
618
    }
619
  }
620
  while (extra_deref) {
621
    if (extra_deref < 0) {
7 7u83 622
      failer("miscalculated location");
2 7u83 623
      break;
624
    }
625
#if 0
626
    if (locate_const)
7 7u83 627
      failer("constant location???");
2 7u83 628
#endif
629
    outsep();
7 7u83 630
    outn((long)DW_OP_deref);
2 7u83 631
    extra_deref--;
632
  }
7 7u83 633
  d_outnl();
2 7u83 634
  return;
635
}
636
 
637
 
638
void dw2_prepare_locate
7 7u83 639
(exp id)
2 7u83 640
{
641
			/* set local proc conditions for local locations */
642
  exp p = son(id);	/* proc or general proc */
643
  locals_offset = no(p);
644
  has_fp = proc_has_fp(p);
645
  return;
646
}
647
 
648
void dw_at_procdetails
7 7u83 649
(void)
2 7u83 650
{
651
			/* return address and frame base */
652
  out8(); outn((long)2); outsep(); outn((long)DW_OP_fbreg); outsep();
653
  if (has_fp) {
654
    outn((long)4); d_outnl();
655
    out8(); outn((long)1); outsep();
656
    outn((long)DW_OP_reg0+dw_fp); d_outnl();
657
  }
658
  else {
659
    outn((long)0); d_outnl();
660
    out8(); outn((long)0); d_outnl();
661
  }
662
  return;
663
}
664
 
665
 
666
void dw2_locate_result
7 7u83 667
(shape sha)
2 7u83 668
{
669
  long length = 1;
670
  int reg = 0;
671
  int indirect = 0;
672
  int multi = 0;
673
  if (is_floating(name(sha))) {
674
    reg = 100;
7 7u83 675
    length = inreg_length(reg, 0);
2 7u83 676
  }
677
  else
678
  if (!reg_result(sha)) {
679
    indirect = 1;
680
    length = 2;
681
  }
682
  else
7 7u83 683
  if (shape_size(sha) > 32) {
2 7u83 684
    multi = 1;
685
    length = 6;
686
  }
7 7u83 687
  out8(); outn(length); outsep();
2 7u83 688
  if (multi) {
7 7u83 689
    outn((long)DW_OP_reg0); outsep();
690
    outn((long)DW_OP_piece); outsep(); outn((long)4);
2 7u83 691
    outsep();
7 7u83 692
    outn((long)DW_OP_reg0+2); outsep();
693
    outn((long)DW_OP_piece); outsep(); outn((long)4);
2 7u83 694
  }
695
  else
696
  if (indirect) {
7 7u83 697
    outn((long)DW_OP_breg0); outsep(); outn((long)0);
2 7u83 698
  }
699
  else {
7 7u83 700
    out_inreg(reg, 0);
2 7u83 701
  }
7 7u83 702
  d_outnl();
2 7u83 703
  return;
704
}
705
 
706
 
707
void dw2_locate_val
7 7u83 708
(dg_where v)
2 7u83 709
{
7 7u83 710
  out8();
2 7u83 711
  switch (v.k) {
712
    case NO_WH: {
7 7u83 713
      outn((long)0);
2 7u83 714
      break;
715
    }
716
    case WH_STR: {
717
      loc_s l;
718
      l.key = L_GLOB;
719
      l.s = v.u.s;
720
      l.off = v.o;
7 7u83 721
      outn((long)glob_length(l)); outsep();
722
      out_glob(l);
2 7u83 723
      break;
724
    }
725
    case WH_REG: {
726
      int r = (int)dwarfreg[v.u.l];
7 7u83 727
      outn((long)inreg_length(r, 0)); outsep();
728
      out_inreg(r, 0);
2 7u83 729
      break;
730
    }
731
    case WH_REGOFF: {
732
      loc_s l;
733
      l.key = L_REGOFF;
734
      l.reg = (int)v.u.l;
735
      l.off = v.o;
736
      if (l.reg == -2) {
737
	l.reg = -1;
738
	l.off -= locals_offset;
739
      }
7 7u83 740
      outn((long)regoff_length(l)); outsep();
741
      out_regoff(l);
2 7u83 742
      break;
743
    }
744
    default:
7 7u83 745
      failer("unexpected locate val");
2 7u83 746
  }
7 7u83 747
  d_outnl();
2 7u83 748
  return;
749
}
750
 
751
 
752
static int dw_eval_exp
7 7u83 753
(exp e, int line_started)
2 7u83 754
{
755
  if (line_started)
756
    outsep();
757
  else {
7 7u83 758
    out8();
2 7u83 759
    line_started = 1;
760
  }
761
  switch (name(e)) {
762
    case name_tag:
763
    case cont_tag:
764
    case contvol_tag:
765
    case reff_tag: {
766
      loc_s l;
767
      locate_param = extra_deref = no_location = 0;
7 7u83 768
      l = find_loc(e);
2 7u83 769
      if (no_location || extra_deref)
7 7u83 770
	failer("value unobtainable by DWARF expression");
2 7u83 771
      switch (l.key) {
772
	case L_INREG: {
7 7u83 773
	  out_inreg(l.reg, extra_deref);
2 7u83 774
	  break;
775
	}
776
	case L_REGOFF: {
7 7u83 777
	  out_regoff(l);
2 7u83 778
	  break;
779
	}
780
	case L_GLOB: {
7 7u83 781
	  out_glob(l);
782
	  d_outnl();
2 7u83 783
	  line_started = 0;
784
	  break;
785
	}
786
	case L_INDIRECT: {
7 7u83 787
	  out_indirect(e);
2 7u83 788
	  break;
789
	}
790
      }
791
      break;
792
    }
793
    case val_tag:
7 7u83 794
    case null_tag: {
2 7u83 795
      if (isbigval(e)) {
796
	flt64 x;
797
	int ov;
798
	x = flt_to_f64(no(e), is_signed(sh(e)), &ov);
7 7u83 799
	outn((long)(is_signed(sh(e))? DW_OP_const8s : DW_OP_const8u)); d_outnl();
2 7u83 800
	out32(); outn((long)(x.small)); outsep(); outn((long)(x.big)); d_outnl();
801
	line_started = 0;
802
      }
803
      else
804
      if (no(e) >= 0 && no(e) < 32)
805
	outn((long)(DW_OP_lit0 + no(e)));
806
      else
807
      if (is_signed(sh(e))) {
808
	outn((long)DW_OP_consts); outsep();
7 7u83 809
	sleb128((long)no(e));
2 7u83 810
      }
811
      else {
812
	outn((long)DW_OP_constu); outsep();
7 7u83 813
	uleb128((unsigned long)no(e));
2 7u83 814
      }
815
      break;
816
    }
817
    case plus_tag:
7 7u83 818
    case offset_add_tag: {
819
      line_started = dw_eval_exp(son(e), line_started);
2 7u83 820
      if (name(bro(son(e))) == val_tag && !is_signed(sh(e)) && !isbigval(bro(son(e)))) {
821
	if (line_started)
822
	  outsep();
823
	else {
7 7u83 824
	  out8();
2 7u83 825
	  line_started = 1;
826
	}
827
	outn((long)DW_OP_plus_uconst); outsep();
7 7u83 828
	uleb128((unsigned long)no(e));
2 7u83 829
      }
830
      else {
7 7u83 831
	line_started = dw_eval_exp(bro(son(e)), line_started);
2 7u83 832
	if (line_started)
833
	  outsep();
834
	else {
7 7u83 835
	  out8();
2 7u83 836
	  line_started = 1;
837
	}
838
	outn((long)DW_OP_plus);
839
      }
840
      break;
841
    }
842
    case minus_tag:
7 7u83 843
    case offset_subtract_tag: {
844
      line_started = dw_eval_exp(son(e), line_started);
845
      line_started = dw_eval_exp(bro(son(e)), line_started);
2 7u83 846
      if (line_started)
847
	outsep();
848
      else {
7 7u83 849
	out8();
2 7u83 850
	line_started = 1;
851
      }
852
      outn((long)DW_OP_minus);
853
      break;
854
    }
855
    case neg_tag:
7 7u83 856
    case offset_negate_tag: {
857
      line_started = dw_eval_exp(son(e), line_started);
2 7u83 858
      if (line_started)
859
	outsep();
860
      else {
7 7u83 861
	out8();
2 7u83 862
	line_started = 1;
863
      }
864
      outn((long)DW_OP_neg);
865
      break;
866
    }
867
    case mult_tag:
7 7u83 868
    case offset_mult_tag: {
869
      line_started = dw_eval_exp(son(e), line_started);
870
      line_started = dw_eval_exp(bro(son(e)), line_started);
2 7u83 871
      if (line_started)
872
	outsep();
873
      else {
7 7u83 874
	out8();
2 7u83 875
	line_started = 1;
876
      }
877
      outn((long)DW_OP_mul);
878
      break;
879
    }
7 7u83 880
    case div0_tag:
881
    case div1_tag:
882
    case div2_tag:
883
    case offset_div_by_int_tag:
884
    case offset_div_tag: {
885
      line_started = dw_eval_exp(son(e), line_started);
886
      line_started = dw_eval_exp(bro(son(e)), line_started);
2 7u83 887
      if (line_started)
888
	outsep();
889
      else {
7 7u83 890
	out8();
2 7u83 891
	line_started = 1;
892
      }
893
      outn((long)DW_OP_div);
894
      break;
895
    }
896
    default:
7 7u83 897
      failer("unsupported operation for DWARF expression");
2 7u83 898
  }
899
  return line_started;
900
}
901
 
902
 
903
void dw2_offset_exp
7 7u83 904
(exp e)
2 7u83 905
{
7 7u83 906
  long block_end = next_dwarf_label();
907
  if (name(sh(e))!= offsethd)
908
    failer("wrong shape for offset expression");
909
  dw_at_form(DW_FORM_block2); d_outnl();
910
  out16(); out_dwf_dist_to_label(block_end); d_outnl();
911
  if (dw_eval_exp(e, 0))
2 7u83 912
    d_outnl();
7 7u83 913
  if (name(sh(e)) == offsethd && al2(sh(e)) < 8) {
914
    out8(); outn((long)(DW_OP_lit0 + 8)); outsep();
2 7u83 915
    outn((long)DW_OP_mul); d_outnl();
916
  }
7 7u83 917
  out_dwf_label(block_end, 1);
2 7u83 918
  return;
919
}
920
 
921
 
922
void dw2_cie
7 7u83 923
(void)
2 7u83 924
{
925
  long cie_end;
926
  cie_pointer = next_dwarf_label();
927
  cie_end = next_dwarf_label();
7 7u83 928
  enter_section("debug_frame");
929
  outnl_comment("Common Information Entry");
930
  out_dwf_label(cie_pointer, 1);
931
  out32(); out_dwf_dist_to_label(cie_end); d_outnl();
932
  out32(); outn((long)DW_CIE_id); d_outnl();
933
  out8(); outn((long)DW_CIE_MOD_VERSION); d_outnl();
934
  out_string("DERA/DDC-I");
935
  out8(); uleb128((unsigned long)framecode_factor); d_outnl();
936
  out8(); sleb128((long)framedata_factor); d_outnl();
2 7u83 937
  out8 (); outn ((long)retaddr); d_outnl ();	/* return address column */
7 7u83 938
  out8(); outn((long)DW_CFA_def_cfa);
939
	outsep(); uleb128((unsigned long)dw_sp);
2 7u83 940
	outsep (); uleb128 ((unsigned long)0);	/* CFA is sp at entry point */
7 7u83 941
	d_outnl();
942
  out8(); outn((long)DW_CFA_undefined);
2 7u83 943
	outsep (); uleb128 ((unsigned long)dwarfreg [0]);	/* eax */
7 7u83 944
	d_outnl();
945
  out8(); outn((long)DW_CFA_undefined);
2 7u83 946
	outsep (); uleb128 ((unsigned long)dwarfreg [1]);	/* edx */
7 7u83 947
	d_outnl();
948
  out8(); outn((long)DW_CFA_undefined);
2 7u83 949
	outsep (); uleb128 ((unsigned long)dwarfreg [2]);	/* ecx */
7 7u83 950
	d_outnl();
951
  out8(); outn((long)DW_CFA_same_value);
2 7u83 952
	outsep (); uleb128 ((unsigned long)dwarfreg [3]);	/* ebx */
7 7u83 953
	d_outnl();
954
  out8(); outn((long)DW_CFA_same_value);
2 7u83 955
	outsep (); uleb128 ((unsigned long)dwarfreg [4]);	/* edi */
7 7u83 956
	d_outnl();
957
  out8(); outn((long)DW_CFA_same_value);
2 7u83 958
	outsep (); uleb128 ((unsigned long)dwarfreg [5]);	/* esi */
7 7u83 959
	d_outnl();
960
  out8(); outn((long)DW_CFA_same_value);
2 7u83 961
	outsep (); uleb128 ((unsigned long)dwarfreg [6]);	/* ebp */
7 7u83 962
	d_outnl();
963
  out8(); outn((long)DW_CFA_DD_location);
2 7u83 964
	outsep (); uleb128 ((unsigned long)dw_sp);		/* esp */
965
	outsep (); outn ((long)2);	/* location block */
7 7u83 966
	outsep(); outn((long)DW_OP_plus_uconst);
2 7u83 967
	outsep (); uleb128 ((unsigned long)4);	/* virtual pop return address */
7 7u83 968
	d_outnl();
969
  out8(); outn((long)DW_CFA_offset + retaddr);
2 7u83 970
	outsep (); uleb128 ((unsigned long)0);	/* return address */
7 7u83 971
	d_outnl();
972
  dot_align(PTR_SZ/8);
973
  out_dwf_label(cie_end, 1);
974
  exit_section();
2 7u83 975
  return;
976
}
977
 
978
static void short_advance
7 7u83 979
(long lo, long hi)
2 7u83 980
{
981
  if (lo) {
7 7u83 982
    out8(); out_dwf_label(hi, 0);  outs(" - "); out_dwf_label(lo, 0);
983
    outs(" + "); outn((long)DW_CFA_advance_loc); d_outnl();
2 7u83 984
  }
985
  else {
7 7u83 986
    out8(); outn((long)DW_CFA_set_loc); d_outnl();
987
    out32(); out_dwf_label(hi, 0); d_outnl();
2 7u83 988
  }
989
  return;
990
}
991
 
992
long dw2_start_fde
7 7u83 993
(long proc_start, long fblab)
2 7u83 994
{
995
  long hold_pos;
996
  fde_end = next_dwarf_label();
997
  proc_end = next_dwarf_label();
7 7u83 998
  enter_section("debug_frame");
999
  outnl_comment("Frame Descriptor Entry");
1000
  out32(); out_dwf_dist_to_label(fde_end); d_outnl();
1001
  out32(); out_dwf_label(cie_pointer, 0); d_outnl();
1002
  out32(); out_dwf_label(proc_start, 0); d_outnl();
1003
  out32(); out_dwf_labdiff(proc_start, proc_end); d_outnl();
2 7u83 1004
 
1005
  if (callee_size >= 0) {
1006
    unsigned long pop_bytes = 4;
7 7u83 1007
    int n = (remove_struct_ref && has_struct_res(crt_proc_exp))? 32 : 0;
1008
    if ((n += callee_size)!= 0) {
2 7u83 1009
      pop_bytes += (unsigned long)(n/8);
7 7u83 1010
      out8(); outn((long)DW_CFA_DD_location);
1011
	outsep(); uleb128((unsigned long)dw_sp);
1012
	outsep(); outn((long)1 + (long)uleb128_length(pop_bytes));
1013
	outsep(); outn((long)DW_OP_plus_uconst);
2 7u83 1014
	outsep (); uleb128 (pop_bytes);	/* adjust virtual pops */
7 7u83 1015
	d_outnl();
2 7u83 1016
    }
1017
  }
1018
  else {	/* var_callees */
7 7u83 1019
    int extra = (remove_struct_ref && has_struct_res(crt_proc_exp))? 2 : 0;
1020
    out8(); outn((long)DW_CFA_DD_location);
1021
	outsep(); uleb128((unsigned long)dw_sp);
2 7u83 1022
	outsep (); outn ((long)(3 + extra));	/* location block length */
7 7u83 1023
	outsep(); outn((long)DW_OP_plus_uconst);
2 7u83 1024
	outsep (); uleb128 ((unsigned long)4);	/* virtual pop return address */
1025
	outsep (); outn ((long)DW_OP_deref);	/* over callees */
1026
	if (extra) {
7 7u83 1027
	  outsep(); outn((long)DW_OP_plus_uconst);
2 7u83 1028
	  outsep (); uleb128 ((unsigned long)4);	/* pop struct_res */
1029
	}
7 7u83 1030
	d_outnl();
2 7u83 1031
  }
1032
 
1033
  if (!no_frame) {
7 7u83 1034
    short_advance(proc_start, fblab);
1035
    out8(); outn((long)DW_CFA_def_cfa);
1036
	outsep(); uleb128((unsigned long)dwarfreg[6]);
2 7u83 1037
	outsep (); uleb128 ((unsigned long)4);	/* CFA now relative to %ebp */
7 7u83 1038
	d_outnl();
2 7u83 1039
    out8 (); outn ((long)DW_CFA_offset + dwarfreg[6]); /* %ebp */
7 7u83 1040
	outsep(); uleb128((unsigned long)1); d_outnl();
2 7u83 1041
  }
1042
 
1043
  if (flush_before_tell)
1044
    IGNORE fflush(fpout);
7 7u83 1045
  hold_pos = ftell(fpout);
1046
  outs(sp50); outs(sp50); outs(sp50); outs(sp50); outs(sp50); outs(sp50); outs(sp50);
1047
  d_outnl();
2 7u83 1048
 
7 7u83 1049
  exit_section();
2 7u83 1050
  return hold_pos;
1051
}
1052
 
1053
void dw2_fde_entry
7 7u83 1054
(long dwl0, long dwl1, long dwl2, long dwl3, long dwl4, long dwl8, int space)
2 7u83 1055
{
1056
  long here = dwl0;
1057
  unsigned long up = 0;
1058
  if (!no_frame) {
1059
    here = dwl1;
1060
    ++up;
1061
  }
1062
  if (min_rfree & 0x8) {
7 7u83 1063
    short_advance(here, dwl2);
2 7u83 1064
    here = dwl2;
7 7u83 1065
    out8();
2 7u83 1066
    if (no_frame) {
7 7u83 1067
	outn((long)DW_CFA_DD_def_cfa_inc_offset); outsep();
2 7u83 1068
    }
1069
	outn ((long)DW_CFA_offset + dwarfreg[3]); /* %ebx */
7 7u83 1070
	outsep(); uleb128(++up); d_outnl();
2 7u83 1071
  }
1072
  if (min_rfree & 0x10) {
7 7u83 1073
    short_advance(here, dwl3);
2 7u83 1074
    here = dwl3;
7 7u83 1075
    out8();
2 7u83 1076
    if (no_frame) {
7 7u83 1077
	outn((long)DW_CFA_DD_def_cfa_inc_offset); outsep();
2 7u83 1078
    }
1079
	outn ((long)DW_CFA_offset + dwarfreg[4]); /* %edi */
7 7u83 1080
	outsep(); uleb128(++up); d_outnl();
2 7u83 1081
  }
1082
  if (min_rfree & 0x20) {
7 7u83 1083
    short_advance(here, dwl4);
2 7u83 1084
    here = dwl4;
7 7u83 1085
    out8();
2 7u83 1086
    if (no_frame) {
7 7u83 1087
	outn((long)DW_CFA_DD_def_cfa_inc_offset); outsep();
2 7u83 1088
    }
1089
	outn ((long)DW_CFA_offset + dwarfreg[5]); /* %esi */
7 7u83 1090
	outsep(); uleb128(++up); d_outnl();
2 7u83 1091
  }
1092
  if (no_frame && (min_rfree & 0x40)) {
7 7u83 1093
    short_advance(here, dwl1);
2 7u83 1094
    here = dwl1;
7 7u83 1095
    out8(); outn((long)DW_CFA_DD_def_cfa_inc_offset); outsep();
2 7u83 1096
	outn ((long)DW_CFA_offset + dwarfreg[6]); /* %ebp */
7 7u83 1097
	outsep(); uleb128(++up); d_outnl();
2 7u83 1098
  }
1099
  if (space && no_frame) {
7 7u83 1100
    short_advance(here, dwl8);
1101
    out8(); outn((long)DW_CFA_def_cfa_offset); outsep();
1102
	uleb128((unsigned long)space); d_outnl();
2 7u83 1103
  }
1104
  return;
1105
}
1106
 
1107
void dw2_untidy_return
7 7u83 1108
(void)
2 7u83 1109
{
1110
	/* we have pushed the return address */
7 7u83 1111
  long here = set_dw_text_label();
1112
  enter_section("debug_frame");
1113
  out8(); outn((long)DW_CFA_set_loc); d_outnl();
1114
  out32(); out_dwf_label(here, 0); d_outnl();
1115
  out8(); outn((long)DW_CFA_remember_state); outsep();
2 7u83 1116
  if (no_frame) {
7 7u83 1117
    outn((long)DW_CFA_DD_def_cfa_inc_offset); d_outnl();
2 7u83 1118
  }
7 7u83 1119
  exit_section();
2 7u83 1120
  return;
1121
}
1122
 
1123
long dw2_prep_fde_restore_args
7 7u83 1124
(int untidy)
2 7u83 1125
{
1126
  long here;
1127
  if (!untidy) {
1128
    long pos;
7 7u83 1129
    enter_section("debug_frame");
1130
    out8(); outn((long)DW_CFA_remember_state); d_outnl();
2 7u83 1131
    pos = ftell(fpout);
7 7u83 1132
    outs(sp50); outs(sp50); outs(sp50); outs(sp50); outs(sp50); outs(sp50);
2 7u83 1133
    d_outnl();
7 7u83 1134
    d_outnl();
1135
    exit_section();
2 7u83 1136
    return pos;
1137
  }
1138
	/* otherwise */
7 7u83 1139
  here = set_dw_text_label();
1140
  enter_section("debug_frame");
1141
  short_advance((long)0, here);
1142
  out8(); outn((long)DW_CFA_restore + dwarfreg[3]); d_outnl();
1143
  out8(); outn((long)DW_CFA_restore + dwarfreg[4]); d_outnl();
1144
  out8(); outn((long)DW_CFA_restore + dwarfreg[5]); d_outnl();
1145
  out8(); outn((long)DW_CFA_restore + dwarfreg[6]); d_outnl();
2 7u83 1146
 
1147
  if (!no_frame) {	/* %ebp restored, return address pushed */
7 7u83 1148
    out8(); outn((long)DW_CFA_def_cfa);
1149
	outsep(); uleb128((unsigned long)dw_sp);
2 7u83 1150
	outsep (); uleb128 ((unsigned long)0);	/* temp CFA */
7 7u83 1151
	d_outnl();
1152
    out8(); outn((long)DW_CFA_undefined);
1153
	outsep(); uleb128((unsigned long)dw_sp);
1154
	d_outnl();
2 7u83 1155
  }
7 7u83 1156
  exit_section();
2 7u83 1157
  return 0;
1158
}
1159
 
1160
void dw2_fde_restore_args
7 7u83 1161
(long dwl0, long dwl1, long dwl2, long dwl3, long dwl4, int space)
2 7u83 1162
{
1163
  long here = 0;
1164
  if (no_frame && dwl0) {
7 7u83 1165
    short_advance(here, dwl0);
2 7u83 1166
    here = dwl0;
7 7u83 1167
    out8(); outn((long)DW_CFA_def_cfa_offset); outsep();
1168
	uleb128((unsigned long)space); d_outnl();
2 7u83 1169
  }
1170
  if (no_frame && (min_rfree & 0x40)) {
7 7u83 1171
    short_advance(here, dwl1);
2 7u83 1172
    here = dwl1;
7 7u83 1173
    out8(); outn((long)DW_CFA_DD_def_cfa_dec_offset); outsep();
2 7u83 1174
	outn ((long)DW_CFA_restore + dwarfreg[6]); /* %ebp */
7 7u83 1175
	d_outnl();
2 7u83 1176
  }
1177
  if (min_rfree & 0x20) {
7 7u83 1178
    short_advance(here, dwl2);
2 7u83 1179
    here = dwl2;
7 7u83 1180
    out8();
2 7u83 1181
    if (no_frame) {
7 7u83 1182
	outn((long)DW_CFA_DD_def_cfa_dec_offset); outsep();
2 7u83 1183
    }
1184
	outn ((long)DW_CFA_restore + dwarfreg[5]); /* %esi */
7 7u83 1185
	d_outnl();
2 7u83 1186
  }
1187
  if (min_rfree & 0x10) {
7 7u83 1188
    short_advance(here, dwl3);
2 7u83 1189
    here = dwl3;
7 7u83 1190
    out8();
2 7u83 1191
    if (no_frame) {
7 7u83 1192
	outn((long)DW_CFA_DD_def_cfa_dec_offset); outsep();
2 7u83 1193
    }
1194
	outn ((long)DW_CFA_restore + dwarfreg[4]); /* %edi */
7 7u83 1195
	d_outnl();
2 7u83 1196
  }
1197
  if (min_rfree & 0x8) {
7 7u83 1198
    short_advance(here, dwl4);
2 7u83 1199
    here = dwl4;
7 7u83 1200
    out8();
2 7u83 1201
    if (no_frame) {
7 7u83 1202
	outn((long)DW_CFA_DD_def_cfa_dec_offset); outsep();
2 7u83 1203
    }
1204
	outn ((long)DW_CFA_restore + dwarfreg[3]); /* %ebx */
7 7u83 1205
	d_outnl();
2 7u83 1206
  }
7 7u83 1207
  if (!no_frame) {
1208
    short_advance(here, dwl1);
2 7u83 1209
    here = dwl1;
1210
    out8 (); outn ((long)DW_CFA_restore + dwarfreg[6]); /* %ebp */
7 7u83 1211
	outsep(); outn((long)DW_CFA_def_cfa);
1212
	outsep(); uleb128((unsigned long)dw_sp);
2 7u83 1213
	outsep (); uleb128 ((unsigned long)0);	/* CFA is sp at entry point */
7 7u83 1214
	d_outnl();
2 7u83 1215
  }
7 7u83 1216
  UNUSED(here);
2 7u83 1217
}
1218
 
1219
void dw2_after_fde_exit
7 7u83 1220
(long here)
2 7u83 1221
{
7 7u83 1222
  out_dwf_label(here, 1);
1223
  enter_section("debug_frame");
1224
  short_advance((long)0, here);
1225
  out8(); outn((long)DW_CFA_restore_state); d_outnl();
1226
  exit_section();
2 7u83 1227
  return;
1228
}
1229
 
1230
void dw2_track_push
7 7u83 1231
(void)
2 7u83 1232
{
7 7u83 1233
  long here = set_dw_text_label();
1234
  enter_section("debug_frame");
1235
  short_advance((long)0, here);
1236
  out8(); outn((long)DW_CFA_DD_def_cfa_inc_offset); d_outnl();
1237
  exit_section();
2 7u83 1238
  return;
1239
}
1240
 
1241
void dw2_track_pop
7 7u83 1242
(void)
2 7u83 1243
{
7 7u83 1244
  long here = set_dw_text_label();
1245
  enter_section("debug_frame");
1246
  short_advance((long)0, here);
1247
  out8(); outn((long)DW_CFA_DD_def_cfa_dec_offset); d_outnl();
1248
  exit_section();
2 7u83 1249
  return;
1250
}
1251
 
1252
void dw2_track_sp
7 7u83 1253
(void)
2 7u83 1254
{
7 7u83 1255
  long here = set_dw_text_label();
1256
  enter_section("debug_frame");
1257
  short_advance((long)0, here);
1258
  out8(); outn((long)DW_CFA_DD_def_cfa_fixed_offset); d_outnl();
1259
  out32(); outn((long)((extra_stack - stack_dec) / 8));
2 7u83 1260
    outs("+");
1261
    outs(local_prefix);
7 7u83 1262
    outs("disp");
1263
    outn((long)crt_proc_id);
1264
  d_outnl();
1265
  exit_section();
2 7u83 1266
  return;
1267
}
1268
 
1269
 
1270
void dw2_complete_fde
7 7u83 1271
(void)
2 7u83 1272
{
7 7u83 1273
  out_dwf_label(proc_end, 1);
1274
  enter_section("debug_frame");
1275
  dot_align(PTR_SZ/8);
1276
  out_dwf_label(fde_end, 1);
1277
  exit_section();
2 7u83 1278
  return;
1279
}
1280
 
1281
 
1282
void dw2_start_extra_bit
7 7u83 1283
(exp body)
2 7u83 1284
{
7 7u83 1285
  dg_info di = new_dg_info(DGA_EXTRA);
2 7u83 1286
  di->data.i_scope.start = next_dwarf_label();
1287
  di->data.i_scope.end = next_dwarf_label();
1288
  di->more = dgf(body);
1289
  dgf(body) = di;
1290
  return;
1291
}
1292
 
1293
void dw2_end_extra_bit
7 7u83 1294
(exp body)
2 7u83 1295
{
7 7u83 1296
  UNUSED(body);
2 7u83 1297
  return;
1298
}
1299
 
1300
 
1301
static exp lab_mark_list;
1302
 
1303
static void mark_lab
7 7u83 1304
(exp labst)
2 7u83 1305
{
7 7u83 1306
  if (!dg_labmark(labst)) {
1307
    set_dg_labmark(labst);
1308
    if (son(son(labst))!= nilexp)
1309
      failer("strange labst");
2 7u83 1310
    son(son(labst)) = lab_mark_list;
1311
    lab_mark_list = labst;
1312
  }
1313
  return;
1314
}
1315
 
1316
static void trace_branch_aux
7 7u83 1317
(exp whole, exp e)
2 7u83 1318
{
1319
  exp t;
1320
  switch (name(e)) {
1321
    case test_tag:
1322
    case goto_tag: {
7 7u83 1323
      if (!intnl_to(whole, pt(e)))
1324
	mark_lab(pt(e));
2 7u83 1325
      break;
1326
    }
1327
    case case_tag: {
1328
      t = bro(son(e));
1329
      for (;;) {
7 7u83 1330
	if (!intnl_to(whole, pt(t)))
1331
	  mark_lab(pt(t));
1332
	if (last(t))break;
2 7u83 1333
	t = bro(t);
1334
      }
1335
      break;
1336
    }
1337
    case labst_tag: {
1338
      t = final_dest(e);
7 7u83 1339
      if (!intnl_to(whole, t))
1340
	mark_lab(t);
2 7u83 1341
      break;
1342
    }
1343
    case name_tag:
1344
    case env_offset_tag:
1345
    case general_env_offset_tag:
1346
      return;
1347
  }
1348
  t = son(e);
1349
  if (t) {
1350
    for (;;) {
7 7u83 1351
      trace_branch_aux(whole, t);
1352
      if (last(t) || name(e) == case_tag)break;
2 7u83 1353
      t = bro(t);
1354
    }
1355
  }
1356
  return;
1357
}
1358
 
1359
void trace_dw_branch_exits
7 7u83 1360
(exp e)
2 7u83 1361
{
1362
  lab_mark_list = nilexp;
7 7u83 1363
  trace_branch_aux(e, e);
2 7u83 1364
  while (lab_mark_list) {
1365
    exp labst = lab_mark_list;
1366
    exp dest = final_dest(labst);
7 7u83 1367
    clear_dg_labmark(labst);
2 7u83 1368
    lab_mark_list = son(son(labst));
1369
    son(son(labst)) = nilexp;
7 7u83 1370
    IGNORE dw_entry(dwe_break,(long)0);
1371
    out32(); out_code_label((long)ptno(pt(son(dest)))); d_outnl();
2 7u83 1372
  }
1373
  return;
1374
}
1375
 
1376
 
1377
 
1378
int dw_loc_equivalence
7 7u83 1379
(exp a, exp b)
2 7u83 1380
{
7 7u83 1381
  return eq_where_exp(a, b, 1, 0);
2 7u83 1382
}
1383
 
1384
typedef struct
1385
{
1386
  dg_name	nm;
1387
  long		start;
1388
  long		end;
1389
} dw_regassn;
1390
 
1391
typedef struct
1392
{
1393
  dg_name	alloc;
1394
  void *	share_set;
7 7u83 1395
  dw_regassn	assn[2];
2 7u83 1396
} dw_regdata;
1397
 
1398
#define TRACKREGS no_fixed_regs
1399
 
7 7u83 1400
static dw_regdata regassns[TRACKREGS];
2 7u83 1401
 
1402
 
1403
void dw_allocated
7 7u83 1404
(dg_name nm, exp id)
2 7u83 1405
{
1406
  int reg = no(id);
1407
  if (!isglob(id) && ptno(id) == reg_pl && reg < TRACKREGS) {
7 7u83 1408
    dw_close_regassn(reg, 0);
1409
    dw_close_regassn(reg, 1);
2 7u83 1410
    regassns[reg].alloc = nm;
1411
    regassns[reg].share_set = (void *)0;
1412
  }
1413
  return;
1414
}
1415
 
1416
void dw_deallocated
7 7u83 1417
(dg_name nm)
2 7u83 1418
{
1419
  int i;
1420
  for (i=0; i<TRACKREGS; i++) {
1421
    if (regassns[i].alloc == nm) {
7 7u83 1422
      dw_close_regassn(i, 0);
1423
      dw_close_regassn(i, 1);
2 7u83 1424
      regassns[i].alloc = (dg_name)0;
1425
      regassns[i].share_set = (void *)0;
1426
    }
1427
  }
1428
  return;
1429
}
1430
 
1431
void dw_all_deallocated		/* initialisation */
7 7u83 1432
(void)
2 7u83 1433
{
1434
  int i;
1435
  for (i=0; i<TRACKREGS; i++) {
7 7u83 1436
    dw_regassn * a = & (regassns[i].assn[0]);
1437
    dw_regassn * b = & (regassns[i].assn[1]);
2 7u83 1438
    regassns[i].alloc = (dg_name)0;
1439
    regassns[i].share_set = (void *)0;
1440
    a->start = a->end = b->start = b->end = (long)0;
1441
  }
1442
  return;
1443
}
1444
 
1445
 
1446
int dw_ignore_used_regassn = 0;
1447
 
1448
void dw_init_regassn
7 7u83 1449
(int reg, int x)
2 7u83 1450
{
1451
  if (reg < TRACKREGS) {
7 7u83 1452
    dg_name nm = find_equiv_object((!x ? crt_reg_record[reg].first_dest
2 7u83 1453
				: crt_reg_record[reg].second_dest), 0);
1454
    if (nm) {
7 7u83 1455
      dw_regassn * a = & (regassns[reg].assn[x]);
2 7u83 1456
      a->nm = nm;
7 7u83 1457
      a->start = set_dw_text_label();
2 7u83 1458
      a->end = (long)0;
1459
    }
1460
  }
1461
  return;
1462
}
1463
 
1464
void dw_used_regassn
7 7u83 1465
(int reg, int x)
2 7u83 1466
{
1467
  if (reg < TRACKREGS && regassns[reg].assn[x].start)
7 7u83 1468
    regassns[reg].assn[x].end = set_dw_text_label();
2 7u83 1469
  return;
1470
}
1471
 
1472
void dw_close_regassn
7 7u83 1473
(int reg, int x)
2 7u83 1474
{
1475
  dw_regassn * a;
1476
  if (dw_ignore_used_regassn || reg >= TRACKREGS)
1477
    return;
7 7u83 1478
  a = & (regassns[reg].assn[x]);
2 7u83 1479
  if (a->end) {
1480
    if (!regassns[reg].share_set) {
1481
      regassns[reg].share_set = (void *)
7 7u83 1482
		dw_new_regshare(regassns[reg].alloc, dwarfreg[reg]);
2 7u83 1483
    }
7 7u83 1484
    dw_add_regshare(regassns[reg].share_set, a->nm,
2 7u83 1485
		a->start, a->end);
1486
    a->end = (long)0;
1487
    if (!regassns[reg].alloc && !regassns[reg].assn[1-x].start)
1488
      regassns[reg].share_set = (void *)0;
1489
  }
1490
  a->start = (long)0;
1491
  return;
1492
}
1493
 
1494
#endif