Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5-amd64/src/installers/sparc/common/dw2_extra.c – Rev 5

Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/*
32
			    VERSION INFORMATION
33
			    ===================
34
 
35
--------------------------------------------------------------------------
36
$Header: /u/g/release/CVSROOT/Source/src/installers/sparc/common/dw2_extra.c,v 1.5 1998/03/15 16:00:41 pwe Exp $
37
--------------------------------------------------------------------------
38
$Log: dw2_extra.c,v $
39
 * Revision 1.5  1998/03/15  16:00:41  pwe
40
 * regtrack dwarf dagnostics added
41
 *
42
 * Revision 1.4  1998/03/11  11:03:53  pwe
43
 * DWARF optimisation info
44
 *
45
 * Revision 1.3  1998/02/18  11:22:25  pwe
46
 * test corrections
47
 *
48
 * Revision 1.2  1998/01/21  10:30:11  pwe
49
 * labdiff change
50
 *
51
 * Revision 1.1.1.1  1998/01/17  15:55:53  release
52
 * First version to be checked into rolling release.
53
 *
54
 * Revision 1.1  1998/01/09  14:59:26  pwe
55
 * prep restructure
56
 *
57
 * Revision 1.9  1997/12/08  19:25:26  pwe
58
 * chfl param
59
 *
60
 * Revision 1.8  1997/12/04  19:54:52  pwe
61
 * ANDF-DE V1.9
62
 *
63
 * Revision 1.7  1997/11/06  09:29:29  pwe
64
 * ANDF-DE V1.8
65
 *
66
 * Revision 1.6  1997/10/28  10:19:28  pwe
67
 * extra diags
68
 *
69
 * Revision 1.5  1997/10/23  09:33:43  pwe
70
 * prep extra_diags
71
 *
72
 * Revision 1.4  1997/10/10  18:33:35  pwe
73
 * prep ANDF-DE revision
74
 *
75
 * Revision 1.3  1997/08/23  13:55:18  pwe
76
 * initial ANDF-DE
77
 *
78
 * Revision 1.2  1997/05/02  11:09:32  pwe
79
 * dwarf2 re return address offset
80
 *
81
 * Revision 1.1  1997/04/17  12:00:30  pwe
82
 * dwarf2 support
83
 *
84
--------------------------------------------------------------------------
85
*/
86
 
87
#include "config.h"
88
#include "common_types.h"
89
 
90
#ifdef NEWDWARF
91
 
92
#include "myassert.h"
93
#include "dg_aux.h"
94
#include "dw2_config.h"
95
#include "dw2_codes.h"
96
#include "dw2_basic.h"
97
#include "szs_als.h"
98
#include "addrtypes.h"
99
#include "expmacs.h"
100
#include "shapemacs.h"
101
#include "bitsmacs.h"
102
#include "tags.h"
103
#include "regmacs.h"
104
#include "locate.h"
105
#include "translat.h"
106
#include "basicread.h"
107
#include "codehere.h"
108
#include "eval.h"
109
#include "proc.h"
110
#include "procrec.h"
111
#include "dw2_entries.h"
112
#include "regable.h"
113
#include "const.h"
114
#include "flpttypes.h"
115
#include "f64.h"
116
#include "regexps.h"
117
#include "dw2_extra.h"
118
#include "dw2_locdata.h"
119
 
120
extern int call_base_reg;	/* declared in locate.c */
121
 
122
 
123
 
124
#define retaddr_column 64
125
#define DIAG_FREG 32
126
 
127
long instr_count = -1;
128
long fde_count = -1;
129
 
130
 
131
static long cie_pointer;
132
static long fde_end;
133
static long proc_end;
134
 
135
#ifdef NEEDS_DEBUG_ALIGN
136
static int calc_length;
137
#endif
138
 
139
static int extra_deref;
140
static int locate_param;
141
static int last_param_reg;
142
static int no_location;
143
 
144
static exp this_proc;
145
 
146
enum loctype { L_INREG = 1, L_REGOFF, L_GLOB, L_INDIRECT, L_SPLIT };
147
 
148
typedef struct {
149
  int key;
150
  int reg;
151
  long off;
152
} loc_s;
153
 
154
 
155
 
156
static void outsep
157
    PROTO_Z ()
158
{
159
  outs (", ");
160
}
161
 
162
 
163
int dw_is_const
164
    PROTO_N ( (e) )
165
    PROTO_T ( exp e )
166
{
167
  switch (name(e)) {
168
    case val_tag:
169
    case null_tag:
170
    case real_tag:
171
      return 1;
172
    case name_tag:
173
      if (isdiscarded(e))
174
	return 0;
175
      if (isvar(son(e)))
176
	return 1;
177
      if ( props (son(e)) & defer_bit )
178
	return dw_is_const (son(son(e)));
179
      return 0;
180
#if 0
181
    case cont_tag:
182
      return (name(son(e)) == name_tag && !isdiscarded(son(e)) &&
183
		!isvar(son(son(e))) && !isparam(son(son(e))) );
184
#endif
185
    case reff_tag:
186
      return 1;
187
    default:
188
      return 0;
189
  }
190
}
191
 
192
exp dw_has_location
193
    PROTO_N ( (e) )
194
    PROTO_T ( exp e )
195
{			/* return ident or nilexp */
196
  switch (name(e)) {
197
    case name_tag: {
198
      if (isdiscarded(e) || isvar(son(e)))
199
	return nilexp;
200
      if ( props (son(e)) & defer_bit )
201
	return dw_has_location (son(son(e)));
202
      return (son(e));
203
    }
204
    case cont_tag: {
205
      do {
206
	e = son(e);
207
	if (name(e) == name_tag && isdiscarded(e))
208
	  return nilexp;
209
      }
210
      while (name(e) != ident_tag || (props(e) & defer_bit));
211
      return e;
212
    }
213
    default:
214
      return nilexp;
215
  }
216
}
217
 
218
 
219
static loc_s find_in_store
220
    PROTO_N ( (dc, off) )
221
    PROTO_T ( exp dc X long off )
222
{
223
  loc_s l;
224
  baseoff b;
225
  assert (! ( props ( dc ) & defer_bit ));
226
  b = boff (dc);
227
  l.reg = b.base;
228
  l.off = off + b.offset;
229
  l.key = (isglob(dc) ? L_GLOB : L_REGOFF);
230
  return l;
231
}
232
 
233
 
234
static loc_s find_loc
235
    PROTO_N ( (e) )
236
    PROTO_T ( exp e )
237
{
238
  loc_s l;
239
  switch ( name ( e ) ) {
240
 
241
    case name_tag : {
242
      if (isdiscarded(e) || (isglob(son(e)) && no(son(e)) == 0 &&
243
				!(brog(son(e))->dec_u.dec_val.extnamed) )) {
244
	l.key = L_INREG;
245
	l.reg = 0;
246
	no_location = 1;
247
	return l;
248
      }
249
      if ( isvar(son(e)) )
250
	extra_deref--;
251
      if ( props (son(e)) & defer_bit ) {
252
	l = find_loc (son(son(e)));
253
	l.off += (no(e)/8);
254
      }
255
      else
256
      if (locate_param) {
257
	int r = no(son(son(e)))/32;
258
	if (!isparam(son(e))) {
259
	  if (name(son(son(e))) == chvar_tag ||
260
		name(son(son(e))) == chfl_tag)
261
	    return find_loc (son(son(son(e))));
262
	  failer ("param inconsistency");
263
	}
264
	if (r > last_param_reg) {
265
	  l.key = L_REGOFF;
266
	  l.reg = R_SP;
267
	  l.off = (no(son(son(e))) + no(e))/8 + 68;
268
	}
269
	else
270
	if (shape_size(sh(son(son(e)))) > 32) {
271
	  l.key = L_SPLIT;
272
	  l.reg = r;
273
	}
274
	else {
275
	  l.key = L_INREG;
276
	  l.reg = r + R_O0;
277
	}
278
      }
279
      else
280
      if ( l.reg = regofval(e), l.reg >= 0 && l.reg < R_NO_REG ) {
281
	l.key = L_INREG;
282
      }
283
      else
284
      if ( l.reg = fregofval(e), l.reg >= 0 && l.reg < R_NO_REG ) {
285
	l.reg = ((l.reg << 1) + DIAG_FREG);
286
	l.key = L_INREG;
287
      }
288
      else
289
	l = find_in_store (son(e), (long)no(e)/8);
290
      break;
291
    }
292
 
293
    case cont_tag :
294
    case contvol_tag : {
295
      if (name(son(e)) == name_tag && (isdiscarded(son(e)) ||
296
			(isglob(son(son(e))) && no(son(son(e))) == 0 &&
297
			 !(brog(son(son(e)))->dec_u.dec_val.extnamed) ))) {
298
	l.key = L_INREG;
299
	l.reg = 0;
300
	no_location = 1;
301
	return l;
302
      }
303
      if ( name(son(e)) != name_tag || !isvar(son(son(e))) ) {
304
	l = find_loc (son(e));
305
	if (l.key == L_INREG) {
306
	  l.key = L_REGOFF;
307
	  l.off = 0;
308
	}
309
	else
310
	  l.key = L_INDIRECT;
311
      }
312
      else
313
      if ( props (son(son(e))) & defer_bit ) {
314
	l = find_loc (son(son(son(e))));
315
	l.off += (no(son(e))/8);
316
      }
317
      else
318
      if (locate_param) {
319
	int r = no(son(son(son(e))))/32;
320
	if (!isparam(son(son(e)))) {
321
	  if (name(son(son(son(e)))) == chvar_tag ||
322
		name(son(son(son(e)))) == chfl_tag)
323
	    return find_loc (son(son(son(son(e)))));
324
	  failer ("param inconsistency");
325
	}
326
	if (r > last_param_reg) {
327
	  l.key = L_REGOFF;
328
	  l.reg = R_SP;
329
	  l.off = (no(son(son(son(e)))) + no(son(e)))/8 + 68;
330
	}
331
	else
332
	if (shape_size(sh(son(son(son(e))))) > 32) {
333
	  l.key = L_SPLIT;
334
	  l.reg = r;
335
	}
336
	else {
337
	  l.key = L_INREG;
338
	  l.reg = r + R_O0;
339
	}
340
      }
341
      else
342
      if ( l.reg = - regofval(son(e)), l.reg >= 0 ) {
343
	l.key = L_INREG;
344
      }
345
      else
346
      if ( l.reg = fregofval(son(e)), l.reg < R_NO_REG ) {
347
	l.reg = ((l.reg << 1) + DIAG_FREG);
348
	l.key = L_INREG;
349
      }
350
      else
351
	l = find_in_store (son(son(e)), (long)no(son(e))/8);
352
      break;
353
    }
354
 
355
    case reff_tag : {
356
      l = find_loc (son(e));
357
      if (l.key == L_GLOB || l.key == L_REGOFF)
358
	l.off += (no(e)/8);
359
      else
360
      if (l.key == L_INREG) {
361
	l.key = L_REGOFF;
362
	l.off = (no(e)/8);
363
	extra_deref--;
364
      }
365
      else
366
	l.key = L_INDIRECT;
367
      break;
368
    }
369
 
370
    default:
371
      failer ("unimplemented location condition");
372
  }
373
  return l;
374
}
375
 
376
static int inreg_length
377
    PROTO_N ( (r, more) )
378
    PROTO_T ( int r X int more )
379
{
380
  int ans = 1 + more;
381
  if (r >= 32)
382
    ans += uleb128_length((unsigned long)r);
383
  return ans;
384
}
385
 
386
static void out_inreg
387
    PROTO_N ( (r, more) )
388
    PROTO_T ( int r X int more )
389
{
390
  if (!more) {
391
    if (r < 32)
392
      outn ((long)(DW_OP_reg0 + r));
393
    else {
394
      outn ((long)DW_OP_regx); outsep(); uleb128((unsigned long)r);
395
    }
396
  }
397
  else {
398
    if (r < 32)
399
      outn ((long)(DW_OP_breg0 + r));
400
    else {
401
      outn ((long)DW_OP_bregx); outsep(); uleb128((unsigned long)r);
402
    }
403
    outsep(); outn ((long)0);
404
  }
405
  return;
406
}
407
 
408
static int regoff_length
409
    PROTO_N ( (l) )
410
    PROTO_T ( loc_s l )
411
{
412
  assert (l.reg >= 0 && l.reg < 32);
413
  return (1 + sleb128_length (l.off));
414
}
415
 
416
static void out_regoff
417
    PROTO_N ( (l) )
418
    PROTO_T ( loc_s l )
419
{
420
  outn ((long)(l.reg == R_FP ? DW_OP_fbreg : DW_OP_breg0 + l.reg)); outsep();
421
  sleb128 (l.off);
422
  return;
423
}
424
 
425
static int split_length
426
    PROTO_N ( (l) )
427
    PROTO_T ( loc_s l )
428
{
429
  int ans = inreg_length (l.reg + R_O0, 0) +4;
430
  if (l.reg == last_param_reg) {
431
    l.key = L_REGOFF;
432
    l.off = (l.reg * 4) + 72;
433
    l.reg = R_SP;
434
    ans += regoff_length (l);
435
  }
436
  else
437
    ans += inreg_length (l.reg + R_O1, 0);
438
  return ans;
439
}
440
 
441
static void out_split
442
    PROTO_N ( (l) )
443
    PROTO_T ( loc_s l )
444
{
445
  out_inreg (l.reg + R_O0, 0);
446
  outsep(); outn ((long)DW_OP_piece);
447
  outsep(); outn ((long)4); outsep();
448
  if (l.reg == last_param_reg) {
449
    l.key = L_REGOFF;
450
    l.off = (l.reg * 4) + 72;
451
    l.reg = R_SP;
452
    out_regoff (l);
453
  }
454
  else
455
    out_inreg (l.reg + R_O1, 0);
456
  outsep(); outn ((long)DW_OP_piece);
457
  outsep(); outn ((long)4);
458
  return;
459
}
460
 
461
static int glob_length
462
    PROTO_N ( (l) )
463
    PROTO_T ( loc_s l )
464
{
465
#ifdef NEEDS_DEBUG_ALIGN
466
  calc_length = 0;
467
#endif
468
  return 5;
469
}
470
 
471
static void out_glob
472
    PROTO_N ( (l) )
473
    PROTO_T ( loc_s l )
474
{
475
  outn ((long)DW_OP_addr); d_outnl ();
476
  out32 (); outlab (l.reg);
477
  if (l.off) {
478
    outs (" + ");
479
    outn ((long)l.off);
480
  }
481
  return;
482
}
483
 
484
static int indirect_length
485
    PROTO_N ( (e) )
486
    PROTO_T ( exp e )
487
{
488
  int length;
489
  loc_s l;
490
#ifdef NEEDS_DEBUG_ALIGN
491
  if (!calc_length)
492
    return 0;
493
#endif
494
  switch (name(e)) {
495
    case cont_tag: {
496
      length = 1;
497
      break;
498
    }
499
    case reff_tag: {
500
      if (no(e) >= 0)
501
	length = 1 + uleb128_length ((unsigned long)(no(e)/8));
502
      else
503
	length = 2 + uleb128_length ((unsigned long)(-no(e)/8));
504
      break;
505
    }
506
    case name_tag: {
507
      if (props(son(e)) & defer_bit) {
508
	return indirect_length (son(son(e)));
509
      }	/* else drop through to failure */
510
    }
511
    default: {
512
      failer ("unimplemented dwarf locate");
513
      return 0;
514
    }
515
  }
516
  l = find_loc (son(e));
517
  switch (l.key) {
518
    case L_INREG: {
519
      length += inreg_length (l.reg, 1);
520
      break;
521
    }
522
    case L_REGOFF: {
523
      length += regoff_length(l);
524
      break;
525
    }
526
    case L_SPLIT: {
527
      length += split_length(l);
528
      break;
529
    }
530
    case L_GLOB: {
531
      length += glob_length(l);
532
      break;
533
    }
534
    case L_INDIRECT: {
535
      length += indirect_length(son(e));
536
      break;
537
    }
538
  }
539
  return length;
540
}
541
 
542
static void out_indirect
543
    PROTO_N ( (e) )
544
    PROTO_T ( exp e )
545
{
546
  loc_s l;
547
  if (name(e) == name_tag) {
548
    assert (props(son(e)) & defer_bit);
549
    out_indirect (son(son(e)));
550
    return;
551
  }
552
  l = find_loc (son(e));
553
  switch (l.key) {
554
    case L_INREG: {
555
      out_inreg (l.reg, 1);
556
      outsep();
557
      break;
558
    }
559
    case L_REGOFF: {
560
      out_regoff (l);
561
      outsep();
562
      break;
563
    }
564
    case L_SPLIT: {
565
      out_split (l);
566
      outsep();
567
      break;
568
    }
569
    case L_GLOB: {
570
      out_glob (l);
571
      d_outnl(); out8();
572
      break;
573
    }
574
    case L_INDIRECT: {
575
      out_indirect(son(e));
576
      outsep();
577
      break;
578
    }
579
  }
580
  switch (name(e)) {
581
    case cont_tag: {
582
      outn ((long)DW_OP_deref);
583
      break;
584
    }
585
    case reff_tag: {
586
      if (no(e) >= 0) {
587
	outn ((long)DW_OP_plus_uconst); outsep();
588
	uleb128 ((unsigned long)(no(e)/8));
589
      }
590
      else {
591
	outn ((long)DW_OP_constu); outsep();
592
	uleb128 ((unsigned long)(-no(e)/8)); outsep();
593
	outn ((long)DW_OP_minus);
594
      }
595
      break;
596
    }
597
  }
598
  return;
599
}
600
 
601
 
602
void dw2_locate_exp
603
    PROTO_N ( (e, locate_const, cx) )
604
    PROTO_T ( exp e X int locate_const X int cx )
605
{
606
  loc_s l;
607
  int length;
608
  int within_loclist = (cx & 1);
609
#ifdef NEEDS_DEBUG_ALIGN
610
  long over_lab;
611
  calc_length = 1;
612
#endif
613
  locate_param = (cx & 2);
614
  extra_deref = locate_const;
615
  no_location = 0;
616
  l = find_loc (e);	/* may reduce extra_deref */
617
  length = extra_deref;
618
  switch (l.key) {
619
    case L_INREG: {
620
      length += inreg_length (l.reg, extra_deref);
621
      break;
622
    }
623
    case L_REGOFF: {
624
      length += regoff_length(l);
625
      break;
626
    }
627
    case L_SPLIT: {
628
      length += split_length(l);
629
      break;
630
    }
631
    case L_GLOB: {
632
      length += glob_length(l);
633
      break;
634
    }
635
    case L_INDIRECT: {
636
      length += indirect_length(e);
637
      break;
638
    }
639
  }
640
  if (no_location)
641
    length = 0;
642
 
643
  if (within_loclist)
644
    out16 ();
645
  else
646
    out8 ();
647
#ifdef NEEDS_DEBUG_ALIGN
648
  if (!calc_length) {
649
    over_lab = next_dwarf_label();
650
    out_dwf_label (over_lab, 0);
651
    if (within_loclist)
652
      outs (" - . - 2");
653
    else
654
      outs (" - . - 1");
655
  }
656
  else
657
#endif
658
  outn ((long)length);
659
  d_outnl();
660
  if (no_location)
661
    return;
662
  out8 ();
663
  switch (l.key) {
664
    case L_INREG: {
665
      out_inreg (l.reg, extra_deref);
666
      break;
667
    }
668
    case L_REGOFF: {
669
      out_regoff (l);
670
      break;
671
    }
672
    case L_SPLIT: {
673
      out_split (l);
674
      break;
675
    }
676
    case L_GLOB: {
677
      out_glob (l);
678
      break;
679
    }
680
    case L_INDIRECT: {
681
      out_indirect (e);
682
      break;
683
    }
684
  }
685
  while (extra_deref) {
686
    if (extra_deref < 0) {
687
      failer ("miscalculated location");
688
      break;
689
    }
690
#if 0
691
    if (locate_const)
692
      failer ("constant location???");
693
#endif
694
    outsep();
695
    outn ((long)DW_OP_deref);
696
    extra_deref--;
697
  }
698
  d_outnl ();
699
#ifdef NEEDS_DEBUG_ALIGN
700
  if (!calc_length)
701
    out_dwf_label (over_lab, 1);
702
#endif
703
  return;
704
}
705
 
706
static long current_pprops;
707
 
708
void dw2_prepare_locate
709
    PROTO_N ( (id) )
710
    PROTO_T ( exp id )
711
{
712
			/* set local proc conditions for local locations */
713
  exp e = son(id);	/* proc or general proc */
714
  procrec *pr = &procrecs [ no ( e ) ] ;
715
  needs *ndpr = &pr->needsproc ;
716
  spacereq *sppr = &pr->spacereqproc ;
717
  long pprops = ( long ) ( ndpr->prps ) ;
718
  /* bool leaf = ( bool ) ( ( pprops & anyproccall ) == 0 ) ;	*/
719
  long maxargs = ndpr->maxargs ;/* maxargs of proc body in bits */
720
  long st = sppr->stack ;		/* space for locals in bits */
721
 
722
  Has_vcallees = (name(e) == general_proc_tag) && (proc_has_vcallees(e));
723
	/* callee_start_reg as initialisation */
724
  call_base_reg = R_NO_REG;	/* needs reset at apply_general */
725
  proc_state.params_offset = PARAMS_OFFSET;
726
  st = ( st + 63 ) & ~63 ;
727
  proc_state.callee_size = ndpr->callee_size;
728
  proc_state.locals_space = st ;
729
  proc_state.locals_offset = 0 ;
730
  proc_state.frame_size = maxargs + st ;
731
  proc_state.maxargs = maxargs ;
732
  last_param_reg = 5;
733
  if (proc_may_have_callees(e))
734
    last_param_reg = (Has_vcallees ? 3 : 4);
735
  this_proc = e;
736
  current_pprops = pprops;
737
  return;
738
}
739
 
740
 
741
void dw2_locate_result
742
    PROTO_N ( (sha) )
743
    PROTO_T ( shape sha )
744
{
745
  out8 ();
746
  if ( !valregable (sha) && name (sha) != tophd &&
747
	( !is_floating ( name (sha) ) || shape_size(sha) > 64 )) {
748
      /* structure or union result, address of space to [ %fp+64 ] */
749
    loc_s l;
750
    l.key = L_REGOFF;
751
    l.reg = R_FP;
752
    l.off = 64;
753
    outn ((long)regoff_length (l)); outsep();
754
    out_regoff (l);
755
  }
756
  else {
757
    int r;
758
    if ( is_floating ( name (sha) ) ) {
759
	/* proc has real result */
760
      r = R_F0 + DIAG_FREG;
761
    }
762
    else if ( name (sha) > tophd  ) {
763
      r = R_I0;
764
    }
765
    else {
766
	/* no result */
767
      failer ("inconsistent result");
768
      r = R_G0;
769
    }
770
    outn ((long)inreg_length (r, 0)); outsep();
771
    out_inreg (r, 0);
772
  }
773
  d_outnl ();
774
  return;
775
}
776
 
777
void dw_at_procdetails
778
    PROTO_Z ()
779
{			/* return address and frame base */
780
  out8(); outn((long)2); outsep();
781
  outn((long)DW_OP_breg0 + R_I7); outsep();
782
  outn ((long)(has_struct_res (this_proc) ? 12 : 8)); d_outnl();
783
  out8(); outn((long)1); outsep();
784
  outn((long)DW_OP_reg0 + R_SP); d_outnl();
785
  return;
786
}
787
 
788
 
789
void dw2_locate_val
790
    PROTO_N ( (v) )
791
    PROTO_T ( dg_where v )
792
{
793
#ifdef NEEDS_DEBUG_ALIGN
794
  long over_lab;
795
  calc_length = 1;
796
#endif
797
  out8 ();
798
  switch (v.k) {
799
    case WH_CODELAB: {
800
      int length;
801
      loc_s l;
802
      l.key = L_GLOB;
803
      l.reg = v.u.l;
804
      l.off = v.o;
805
      length = glob_length (l);
806
#ifdef NEEDS_DEBUG_ALIGN
807
      if (!calc_length) {
808
	over_lab = next_dwarf_label();
809
	out_dwf_label (over_lab, 0);
810
	outs (" - . - 1");
811
      }
812
      else
813
#endif
814
      outn ((long)length);
815
      d_outnl();
816
      out8 ();
817
      out_glob (l);
818
      break;
819
    }
820
    case WH_REG: {
821
      int r = v.u.l;
822
      outn ((long)inreg_length (r, 0)); outsep();
823
      out_inreg (r, 0);
824
      break;
825
    }
826
    case WH_REGOFF: {
827
      loc_s l;
828
      l.key = L_REGOFF;
829
      l.reg = v.u.l;
830
      l.off = v.o;
831
      outn ((long)regoff_length (l)); outsep();
832
      out_regoff (l);
833
      break;
834
    }
835
    default:
836
      failer ("unexpected locate val");
837
  }
838
  d_outnl ();
839
#ifdef NEEDS_DEBUG_ALIGN
840
  if (!calc_length)
841
    out_dwf_label (over_lab, 1);
842
#endif
843
  return;
844
}
845
 
846
 
847
static int dw_eval_exp
848
    PROTO_N ( (e, line_started) )
849
    PROTO_T ( exp e X int line_started )
850
{
851
  if (line_started)
852
    outsep();
853
  else {
854
    out8 ();
855
    line_started = 1;
856
  }
857
  switch (name(e)) {
858
    case name_tag:
859
    case cont_tag:
860
    case contvol_tag:
861
    case reff_tag: {
862
      loc_s l;
863
      locate_param = extra_deref = no_location = 0;
864
      l = find_loc (e);
865
      if (no_location || extra_deref)
866
	failer ("value unobtainable by DWARF expression");
867
      switch (l.key) {
868
	case L_INREG: {
869
	  out_inreg (l.reg, extra_deref);
870
	  break;
871
	}
872
	case L_REGOFF: {
873
	  out_regoff (l);
874
	  break;
875
	}
876
	case L_GLOB: {
877
	  out_glob (l);
878
	  d_outnl ();
879
	  line_started = 0;
880
	  break;
881
	}
882
	case L_INDIRECT: {
883
	  out_indirect (e);
884
	  break;
885
	}
886
      }
887
      break;
888
    }
889
    case val_tag:
890
    case null_tag : {
891
      if (isbigval(e)) {
892
	flt64 x;
893
	int ov;
894
	x = flt_to_f64(no(e), is_signed(sh(e)), &ov);
895
	outn((long)(is_signed(sh(e)) ? DW_OP_const8s : DW_OP_const8u)); d_outnl();
896
	out32(); outn((long)(x.small)); outsep(); outn((long)(x.big)); d_outnl();
897
	line_started = 0;
898
      }
899
      else
900
      if (no(e) >= 0 && no(e) < 32)
901
	outn((long)(DW_OP_lit0 + no(e)));
902
      else
903
      if (is_signed(sh(e))) {
904
	outn((long)DW_OP_consts); outsep();
905
	sleb128 ((long)no(e));
906
      }
907
      else {
908
	outn((long)DW_OP_constu); outsep();
909
	uleb128 ((unsigned long)no(e));
910
      }
911
      break;
912
    }
913
    case plus_tag:
914
    case offset_add_tag : {
915
      line_started = dw_eval_exp (son(e), line_started);
916
      if (name(bro(son(e))) == val_tag && !is_signed(sh(e)) && !isbigval(bro(son(e)))) {
917
	if (line_started)
918
	  outsep();
919
	else {
920
	  out8 ();
921
	  line_started = 1;
922
	}
923
	outn((long)DW_OP_plus_uconst); outsep();
924
	uleb128 ((unsigned long)no(e));
925
      }
926
      else {
927
	line_started = dw_eval_exp (bro(son(e)), line_started);
928
	if (line_started)
929
	  outsep();
930
	else {
931
	  out8 ();
932
	  line_started = 1;
933
	}
934
	outn((long)DW_OP_plus);
935
      }
936
      break;
937
    }
938
    case minus_tag:
939
    case offset_subtract_tag : {
940
      line_started = dw_eval_exp (son(e), line_started);
941
      line_started = dw_eval_exp (bro(son(e)), line_started);
942
      if (line_started)
943
	outsep();
944
      else {
945
	out8 ();
946
	line_started = 1;
947
      }
948
      outn((long)DW_OP_minus);
949
      break;
950
    }
951
    case neg_tag:
952
    case offset_negate_tag : {
953
      line_started = dw_eval_exp (son(e), line_started);
954
      if (line_started)
955
	outsep();
956
      else {
957
	out8 ();
958
	line_started = 1;
959
      }
960
      outn((long)DW_OP_neg);
961
      break;
962
    }
963
    case mult_tag:
964
    case offset_mult_tag : {
965
      line_started = dw_eval_exp (son(e), line_started);
966
      line_started = dw_eval_exp (bro(son(e)), line_started);
967
      if (line_started)
968
	outsep();
969
      else {
970
	out8 ();
971
	line_started = 1;
972
      }
973
      outn((long)DW_OP_mul);
974
      break;
975
    }
976
    case div0_tag :
977
    case div1_tag :
978
    case div2_tag :
979
    case offset_div_by_int_tag :
980
    case offset_div_tag : {
981
      line_started = dw_eval_exp (son(e), line_started);
982
      line_started = dw_eval_exp (bro(son(e)), line_started);
983
      if (line_started)
984
	outsep();
985
      else {
986
	out8 ();
987
	line_started = 1;
988
      }
989
      outn((long)DW_OP_div);
990
      break;
991
    }
992
    default:
993
      failer ("unsupported operation for DWARF expression");
994
  }
995
  return line_started;
996
}
997
 
998
 
999
void dw2_offset_exp
1000
    PROTO_N ( (e) )
1001
    PROTO_T ( exp e )
1002
{
1003
  long block_end = next_dwarf_label ();
1004
  if (name(sh(e)) != offsethd)
1005
    failer ("wrong shape for offset expression");
1006
  dw_at_form (DW_FORM_block2); d_outnl();
1007
  out16 (); out_dwf_dist_to_label (block_end); d_outnl();
1008
  if (dw_eval_exp (e, 0))
1009
    d_outnl();
1010
  if (name(sh(e)) == offsethd && al2(sh(e)) < 8 ) {
1011
    out8 (); outn((long)(DW_OP_lit0 + 8)); outsep();
1012
    outn((long)DW_OP_mul); d_outnl();
1013
  }
1014
  out_dwf_label (block_end, 1);
1015
  return;
1016
}
1017
 
1018
 
1019
void dw2_cie
1020
    PROTO_Z ()
1021
{
1022
  long cie_end;
1023
  int i;
1024
  cie_pointer = next_dwarf_label();
1025
  cie_end = next_dwarf_label();
1026
  enter_section ("debug_frame");
1027
  outnl_comment ("Common Information Entry");
1028
  out_dwf_label (cie_pointer, 1);
1029
  out32 (); out_dwf_dist_to_label (cie_end); d_outnl ();
1030
  out32 (); outn ((long)DW_CIE_id); d_outnl ();
1031
  out8 (); outn ((long)DW_CIE_MOD_VERSION); d_outnl ();
1032
  out_string ("DERA/DDC-I");
1033
  out8 (); uleb128 ((unsigned long)framecode_factor); d_outnl ();
1034
  out8 (); sleb128 ((long)framedata_factor); d_outnl ();
1035
  out8 (); outn ((long)retaddr_column); d_outnl ();	/* return address column */
1036
 
1037
  out8 (); outn ((long)DW_CFA_DD_sparc_restore_regwindow); outsep();
1038
	sleb128 ((long) 8); d_outnl ();		/* sparc entry rules, ret offset 8 */
1039
 
1040
  for (i = R_FIRST; i <= R_LAST; i++) {
1041
    if ((i > R_G0 && i <= (R_G0 + g_reg_max)) ||
1042
		(i >= R_O0 && i <= R_O7 && i != R_SP)) {
1043
	out8 (); outn ((long)DW_CFA_undefined); outsep();
1044
	uleb128 ((unsigned long)i); d_outnl ();
1045
    }
1046
  }
1047
  dot_align (PTR_SZ/8);
1048
  out_dwf_label (cie_end, 1);
1049
  exit_section ();
1050
  return;
1051
}
1052
 
1053
 
1054
void dw2_start_fde
1055
    PROTO_N ( (e) )
1056
    PROTO_T ( exp e )
1057
{
1058
  long proc_start = next_dwarf_label();
1059
  fde_end = next_dwarf_label();
1060
  proc_end = next_dwarf_label();
1061
  out_dwf_label (proc_start, 1);
1062
  enter_section ("debug_frame");
1063
  outnl_comment ("Frame Descriptor Entry");
1064
  out32 (); out_dwf_dist_to_label (fde_end); d_outnl ();
1065
  out32 (); out_dwf_label (cie_pointer, 0); d_outnl ();
1066
  out32 (); out_dwf_label (proc_start, 0); d_outnl ();
1067
  out32 (); out_dwf_labdiff (proc_start, proc_end); d_outnl ();
1068
  this_proc = e;
1069
  if (has_struct_res (this_proc)) {
1070
    out8 (); outn ((long)DW_CFA_DD_location); outsep();
1071
	uleb128 ((unsigned long)retaddr_column);  outsep();
1072
	outn ((long)(2 + sleb128_length((long)12))); outsep();
1073
	outn ((long)DW_OP_drop); outsep();
1074
	outn ((long)(DW_OP_breg0 + R_O7)); outsep();
1075
	sleb128 ((long) 12); d_outnl ();	/* return R_O7 offset 12 */
1076
  }
1077
  exit_section ();
1078
  instr_count = -1;
1079
  fde_count = 0;
1080
  return;
1081
}
1082
 
1083
static void fde_advance
1084
    PROTO_N ( (here) )
1085
    PROTO_T ( long here )
1086
{
1087
  if (fde_count < 0) {
1088
    out8 (); outn ((long)DW_CFA_set_loc); d_outnl ();
1089
    out32 (); out_dwf_label (here, 0);
1090
  }
1091
  else
1092
  if (fde_count < 0x40) {
1093
    out8 (); outn ((long)DW_CFA_advance_loc + fde_count);
1094
  }
1095
  else
1096
  if (fde_count < 0x100) {
1097
    out8 (); outn ((long)DW_CFA_advance_loc1); outsep();
1098
    outn (fde_count);
1099
  }
1100
  else
1101
  if (fde_count < 0x10000) {
1102
    out8 (); outn ((long)DW_CFA_advance_loc2); d_outnl ();
1103
    out16 (); outn (fde_count);
1104
  }
1105
  else {
1106
    out8 (); outn ((long)DW_CFA_advance_loc4); d_outnl ();
1107
    out32 (); outn (fde_count);
1108
  }
1109
  d_outnl ();
1110
  fde_count = 0;
1111
  return;
1112
}
1113
 
1114
void dw2_fde_save
1115
    PROTO_Z ()
1116
{
1117
  long here = 0;
1118
  if (fde_count < 0)
1119
    here = set_dw_text_label();
1120
  enter_section ("debug_frame");
1121
  fde_advance (here);
1122
  out8 (); outn ((long)DW_CFA_DD_sparc_save_regwindow); outsep();
1123
	sleb128 ((long) (has_struct_res (this_proc) ? 12 : 8));
1124
	d_outnl ();
1125
  exit_section ();
1126
  return;
1127
}
1128
 
1129
void dw2_fde_restore
1130
    PROTO_Z ()
1131
{
1132
  long here = 0;
1133
  if (fde_count < 0)
1134
    here = set_dw_text_label();
1135
  enter_section ("debug_frame");
1136
  fde_advance (here);
1137
  out8 (); outn ((long)DW_CFA_DD_sparc_restore_regwindow); outsep();
1138
	sleb128 ((long) (has_struct_res (this_proc) ? 12 : 8));
1139
	d_outnl ();
1140
  exit_section ();
1141
  return;
1142
}
1143
 
1144
void dw2_complete_fde
1145
    PROTO_Z ()
1146
{
1147
  out_dwf_label (proc_end, 1);
1148
  enter_section ("debug_frame");
1149
  dot_align (PTR_SZ/8);
1150
  out_dwf_label (fde_end, 1);
1151
  exit_section ();
1152
  return;
1153
}
1154
 
1155
 
1156
static exp lab_mark_list;
1157
 
1158
static void mark_lab
1159
    PROTO_N ( (labst) )
1160
    PROTO_T ( exp labst )
1161
{
1162
  if (!dg_labmark (labst)) {
1163
    set_dg_labmark (labst);
1164
    if (son(son(labst)) != nilexp)
1165
      failer ("strange labst");
1166
    son(son(labst)) = lab_mark_list;
1167
    lab_mark_list = labst;
1168
  }
1169
  return;
1170
}
1171
 
1172
static void trace_branch_aux
1173
    PROTO_N ( (whole, e) )
1174
    PROTO_T ( exp whole X exp e )
1175
{
1176
  exp t;
1177
  switch (name(e)) {
1178
    case test_tag:
1179
    case goto_tag: {
1180
      if (!intnl_to (whole, pt(e)))
1181
	mark_lab (pt(e));
1182
      break;
1183
    }
1184
    case case_tag: {
1185
      t = bro(son(e));
1186
      for (;;) {
1187
	if (!intnl_to (whole, pt(t)))
1188
	  mark_lab (pt(t));
1189
	if (last(t)) break;
1190
	t = bro(t);
1191
      }
1192
      break;
1193
    }
1194
    case name_tag:
1195
    case env_offset_tag:
1196
    case general_env_offset_tag:
1197
      return;
1198
  }
1199
  t = son(e);
1200
  if (t) {
1201
    for (;;) {
1202
      trace_branch_aux (whole, t);
1203
      if (last(t) || name(e) == case_tag) break;
1204
      t = bro(t);
1205
    }
1206
  }
1207
  return;
1208
}
1209
 
1210
void trace_dw_branch_exits
1211
    PROTO_N ( (e) )
1212
    PROTO_T ( exp e )
1213
{
1214
  lab_mark_list = nilexp;
1215
  trace_branch_aux (e, e);
1216
  while (lab_mark_list) {
1217
    exp holder = son(lab_mark_list);
1218
    clear_dg_labmark (lab_mark_list);
1219
    lab_mark_list = son(holder);
1220
    son(holder) = nilexp;
1221
    dw_entry (dwe_break, (long)0);
1222
    out32 (); out_code_label ((long)no(holder)); d_outnl ();
1223
  }
1224
  return;
1225
}
1226
 
1227
 
1228
int dw_loc_equivalence
1229
    PROTO_N ( (a, b) )
1230
    PROTO_T ( exp a X exp b )
1231
{
1232
  return (int)sim_exp (a, b);
1233
}
1234
 
1235
typedef struct
1236
{
1237
  dg_name	alloc;
1238
  void *	share_set;
1239
  dg_name	nm;
1240
  long		start;
1241
  long		end;
1242
} dw_regdata;
1243
 
1244
#define TRACKREGS 32
1245
 
1246
static dw_regdata regassns [TRACKREGS];
1247
 
1248
 
1249
void dw_allocated
1250
    PROTO_N ( (nm, id) )
1251
    PROTO_T ( dg_name nm X exp id )
1252
{
1253
  int reg = no(id), i;
1254
  exp x = son(nm->data.n_obj.obtain_val);
1255
  if (!isglob(id) && (props(id) & inreg_bits) && reg < TRACKREGS) {
1256
    dw_close_regassn (reg);
1257
    regassns[reg].alloc = nm;
1258
    regassns[reg].share_set = (void *)0;
1259
  }
1260
  for (i=0; i<TRACKREGS; i++) {
1261
    if (regexps[i].keptexp && 
1262
	(regexps[i].iscont ? (name(x) == cont_tag &&
1263
			sim_exp (son(x), regexps[i].keptexp))
1264
		      : sim_exp (x, regexps[i].keptexp) )) {
1265
      regassns[i].nm = nm;
1266
      regassns[i].start = set_dw_text_label ();
1267
      regassns[i].end = (long)0;
1268
      break;
1269
    }
1270
  }
1271
  return;
1272
}
1273
 
1274
void dw_deallocated
1275
    PROTO_N ( (nm) )
1276
    PROTO_T ( dg_name nm )
1277
{
1278
  int i;
1279
  for (i=0; i<TRACKREGS; i++) {
1280
    if (regassns[i].alloc == nm) {
1281
      dw_close_regassn (i);
1282
      regassns[i].alloc = (dg_name)0;
1283
      regassns[i].share_set = (void *)0;
1284
    }
1285
  }
1286
  return;
1287
}
1288
 
1289
void dw_all_deallocated		/* initialisation */
1290
    PROTO_Z ()
1291
{
1292
  int i;
1293
  for (i=0; i<TRACKREGS; i++) {
1294
    regassns[i].alloc = (dg_name)0;
1295
    regassns[i].share_set = (void *)0;
1296
    regassns[i].start = regassns[i].end = (long)0;
1297
  }
1298
  return;
1299
}
1300
 
1301
 
1302
void dw_init_regassn
1303
    PROTO_N ( (reg) )
1304
    PROTO_T ( int reg )
1305
{
1306
  if (reg < TRACKREGS) {
1307
    dg_name nm = find_equiv_object (regexps[reg].keptexp,
1308
					regexps[reg].iscont);
1309
    if (nm) {
1310
      regassns[reg].nm = nm;
1311
      regassns[reg].start = set_dw_text_label ();
1312
      regassns[reg].end = (long)0;
1313
    }
1314
  }
1315
  return;
1316
}
1317
 
1318
void dw_used_regassn
1319
    PROTO_N ( (reg) )
1320
    PROTO_T ( int reg )
1321
{
1322
  if (reg < TRACKREGS && regassns[reg].start)
1323
    regassns[reg].end = set_dw_text_label ();
1324
  return;
1325
}
1326
 
1327
void dw_close_regassn
1328
    PROTO_N ( (reg) )
1329
    PROTO_T ( int reg )
1330
{
1331
  if (reg >= TRACKREGS)
1332
    return;
1333
  if (regassns[reg].end) {
1334
    if (!regassns[reg].share_set) {
1335
      regassns[reg].share_set = (void *)
1336
		dw_new_regshare (regassns[reg].alloc, reg);
1337
    }
1338
    dw_add_regshare (regassns[reg].share_set, regassns[reg].nm,
1339
			regassns[reg].start, regassns[reg].end);
1340
    regassns[reg].end = (long)0;
1341
    if (!regassns[reg].alloc)
1342
      regassns[reg].share_set = (void *)0;
1343
  }
1344
  regassns[reg].start = (long)0;
1345
  return;
1346
}
1347
 
1348
 
1349
#endif