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
$Log: proc.c,v $
33
 * Revision 1.1.1.1  1998/01/17  15:56:03  release
34
 * First version to be checked into rolling release.
35
 *
36
 * Revision 1.15  1996/12/09  12:52:46  wfs
37
 *    Prevented the superfluous "loading" to GR0.
38
 *
39
 * Revision 1.14  1996/11/14  15:22:24  wfs
40
 *    Fixed a bug in regexps.c which was common to most of the installers and
41
 * has only just come to light due to PWE's work on powertrans. (There was
42
 * previously only a patch.) Cosmetic changes to other files.
43
 *
44
 * Revision 1.13  1996/09/05  11:05:11  wfs
45
 * "dynamic_init" boolean variable removed - must always be considered true.
46
 *
47
 * Revision 1.12  1996/08/30  09:02:32  wfs
48
 * Various fixes of bugs arising from avs and pl_tdf tests.
49
 *
50
 * Revision 1.11  1996/03/28  10:53:19  wfs
51
 * Bug fixes to scan(), peephole optimisations in proc.c, and enum diagnostics.
52
 *
53
 * Revision 1.10  1996/03/08  11:52:27  wfs
54
 * Another typo in "proc.c".
55
 *
56
 * Revision 1.9  1996/03/08  11:31:14  wfs
57
 * typo in "proc.c" dynamic initialization code.
58
 *
59
 * Revision 1.8  1996/03/06  17:40:27  wfs
60
 * Corrected typo in last bug fix.
61
 *
62
 * Revision 1.7  1996/03/06  17:26:30  wfs
63
 * Fixed a bug in the profiling option.
64
 *
65
 * Revision 1.6  1996/01/30  15:36:31  wfs
66
 * Added the dynamic initialization files "dyn_begin.s" and "dyn_end.s" to
67
 * the hppatrans repository. The bl_install and bl_update scripts were
68
 * expanded to deal with these new "initcode" files.
69
 *
70
 * Revision 1.5  1996/01/19  14:13:20  wfs
71
 * Added "bool" type to an extern declaration in "frames.h".
72
 *
73
 * Revision 1.4  1996/01/11  14:46:33  wfs
74
 * Fixed bug in "ass_tag" case of scan(). Removed superfluous macro and comment.
75
 *
76
 * Revision 1.3  1995/12/19  16:52:51  wfs
77
 * Reinstated the "__main" call and a ".CODE" directive when producing gdb
78
 * diagnostic code.
79
 *
80
 * Revision 1.2  1995/12/18  13:12:18  wfs
81
 * Put hppatrans uder cvs control. Major Changes made since last release
82
 * include:
83
 * (i) PIC code generation.
84
 * (ii) Profiling.
85
 * (iii) Dynamic Initialization.
86
 * (iv) Debugging of Exception Handling and Diagnostics.
87
 *
88
 * Revision 5.5  1995/10/20  14:10:06  wfs
89
 * gcc compilation changes.
90
 *
91
 * Revision 5.4  1995/10/11  16:00:23  wfs
92
 * Moved all of the "apply_tag" stuff to "makecode.c".
93
 *
94
 * Revision 5.3  1995/10/09  10:41:02  wfs
95
 * Only one return from a procedure when producing diagnostics. White space
96
 * changes.
97
 *
98
 * Revision 5.2  1995/09/25  10:50:50  wfs
99
 * A "ghostscript" bug fix.
100
 *
101
 * Revision 5.1  1995/09/15  13:09:18  wfs
102
 * Finished the implementation of the exception token and stack limit
103
 * stuff + minor cosmetic changes.
104
 *
105
 * Revision 5.0  1995/08/25  13:42:58  wfs
106
 * Preperation for August 25 Glue release
107
 *
108
 * Revision 3.3  1995/08/25  10:21:17  wfs
109
 * A fairly major revision. A lot of the code which set up the frame
110
 * specific variables has been moved to "frames.c". 3.1 and 4.0 stuff
111
 * such as "return_to_label" and "untidy_return" have been incorporated.
112
 * Register synonyms changed. A lot of superfluous code was removed
113
 * after the register allocation stuff was changed.
114
 *
115
 * Revision 3.3  1995/08/25  10:21:17  wfs
116
 * A fairly major revision. A lot of the code which set up the frame
117
 * specific variables has been moved to "frames.c". 3.1 and 4.0 stuff
118
 * such as "return_to_label" and "untidy_return" have been incorporated.
119
 * Register synonyms changed. A lot of superfluous code was removed
120
 * after the register allocation stuff was changed.
121
 *
122
 * Revision 3.1  95/04/10  16:27:45  16:27:45  wfs (William Simmonds)
123
 * Apr95 tape version.
124
 *
125
 * Revision 3.0  95/03/30  11:18:36  11:18:36  wfs (William Simmonds)
126
 * Mar95 tape version with CRCR95_178 bug fix.
127
 *
128
 * Revision 2.0  95/03/15  15:28:27  15:28:27  wfs (William Simmonds)
129
 * spec 3.1 changes implemented, tests outstanding.
130
 *
131
 * Revision 1.3  95/02/22  11:28:47  11:28:47  wfs (William Simmonds)
132
 * Added Has_ll, changed the base register of mem_temp0 to R_FP.
133
 *
134
 * Revision 1.2  95/01/17  17:30:24  17:30:24  wfs (William Simmonds)
135
 * Changed name of an included header file.
136
 *
137
 * Revision 1.1  95/01/11  13:14:46  13:14:46  wfs (William Simmonds)
138
 * Initial revision
139
 *
140
*/
141
 
142
 
143
#define HPPATRANS_CODE
144
#include "config.h"
145
#include "myassert.h"
146
#include "addrtypes.h"
147
#include "tags.h"
148
#include "expmacs.h"
149
#include "installtypes.h"
150
#include "exp.h"
151
#include "exptypes.h"
152
#include "frames.h"
153
#include "maxminmacs.h"
154
#include "shapemacs.h"
155
#include "basicread.h"
156
#include "proctypes.h"
157
#include "eval.h"
158
#include "move.h"
159
#include "comment.h"
160
#include "getregs.h"
161
#include "guard.h"
162
#include "locate.h"
163
#include "codehere.h"
164
#include "inst_fmt.h"
165
#include "hppains.h"
166
#include "bitsmacs.h"
167
#include "labels.h"
168
#include "regexps.h"
169
#include "regmacs.h"
170
#include "regable.h"
171
#include "flags.h"
172
#include "special.h"
173
#include "translat.h"
174
#include "makecode.h"
175
#include "out.h"
176
#include "proc.h"
177
#include "misc.h"
178
#include "hppadiags.h"
179
#include "loc_signal.h"
180
 
181
#define RES    1
182
#define TO_LAB 2
183
#define UNTIDY 3
184
 
185
#define	RN(r)  reg_name(r)  /* short hand */
186
#define NA    -1
187
 
188
 
189
extern outofline *odd_bits;
190
extern int repeat_level;
191
extern regpeep regexps[64];
192
extern char *proc_name;
193
extern int line;
194
extern char export[128];
195
extern int firstlab,labno;
196
int leaf;
197
extern baseoff find_tg PROTO_S ((char* s));
198
extern exp find_named_tg PROTO_S ((char *,shape));
199
extern shape f_pointer PROTO_S ((alignment));
200
extern alignment f_alignment PROTO_S ((shape));
201
extern shape f_proc;
202
extern void do_exception PROTO_S ((int));
203
 
204
int res_label;
205
static int untidy_return_label,return_to_label_label;
206
static bool simpleans;
207
static ans procans;
208
int RSCOPE_LEVEL,RSCOPE_LABEL;
209
 
210
/*
211
*   Temporary space on stack which can be referenced by short instruction
212
*   sequences, the space is initialised by each procedure prelude.
213
 */
214
baseoff mem_temp
215
    PROTO_N ( (byte_offset) )
216
    PROTO_T ( int byte_offset )
217
{
218
   baseoff b;
219
   b = MEM_TEMP_BOFF;
220
 
221
   /* Only 2 words of temporary memory allocated */
222
   assert(byte_offset >= 0 && byte_offset < 8);
223
 
224
   b.offset+=byte_offset;
225
   return b;
226
}
227
 
228
 
229
 
230
/* Save callee-saves ("s") registers on the stack. */
231
void save_sregs
232
    PROTO_Z ()
233
{
234
   if (fixdump==0)
235
      return;
236
   else
237
   {
238
      int o=0,r;
239
      for(r=16;r<32;r++)
240
      {
241
	 if (fixdump&(1<<r))
242
	 {
243
	    st_ir_ins(i_stw,cmplt_,r,fs_,empty_ltrl,o,SP);
244
	    o+=4;
245
	 }
246
      }
247
   }
248
}
249
 
250
 
251
/* Restore the callee-saves ("s") registers saved on the stack. */
252
void restore_sregs
253
    PROTO_Z ()
254
{
255
   if (fixdump==0)
256
      return;
257
   else
258
   {
259
      int o=0,r;
260
      for(r=16;r<32;r++)
261
      {
262
	 if (fixdump&(1<<r))
263
	 {
264
	    ld_ir_ins(i_ldw,cmplt_,fs_,empty_ltrl,o,SP,r);
265
	    o+=4;
266
	 }
267
      }
268
   }
269
}
270
 
271
 
272
/*
273
*   Some (more or less) common code for res_tag, return_to_label and
274
*   untidy_return.
275
 */
276
static void code_for_ret
277
    PROTO_N ( (which_ret) )
278
    PROTO_T ( int which_ret )
279
{
280
   if (which_ret==UNTIDY)
281
      rr_ins(i_copy,SP,T2);
282
   if (Has_fp)
283
      rr_ins(i_copy,FP,SP);
284
   else
285
   {
286
      baseoff b;
287
      b.base=(Has_vsp ? EP : SP); b.offset=-(frame_sz>>3);
288
      ld_ins(i_lo,0,b,SP);
289
   }
290
   restore_sregs();
291
   if (which_ret!=TO_LAB)
292
      ld_ir_ins(i_ldw,cmplt_,fs_,empty_ltrl,-20,SP,RP);
293
   extj_reg_ins(i_bv,RP);
294
   if (which_ret==UNTIDY)
295
      rr_ins(i_copy,T2,SP);
296
   else
297
      z_ins(i_nop);
298
}
299
 
300
 
301
static void add_odd_bits
302
    PROTO_N ( (r) )
303
    PROTO_T ( outofline *r )
304
{
305
   space sp;
306
   if (r!=(outofline*)nilexp)
307
   {
308
      add_odd_bits(r->next);
309
      if (r->next==(outofline*)nilexp)
310
	 last_odd_bit=1;
311
   }
312
   else
313
      return;
314
   outlab("L$$",r->labno);
315
   sp=r->sp;
316
   clear_all();
317
   make_code(r->body,sp,r->dest, name(sh(r->body))!=bothd ? ptno(r->jr) : res_label);
318
   if (name(sh(r->body))!=bothd)
319
      ub_ins(cmplt_,ptno(r->jr));
320
}
321
 
322
 
323
/*
324
 * The following functions generate code for various procedure related
325
 * constructs.  They put the result in dest using t-regs given by sp.
326
 * If non-zero, exitlab is the label of where the code is to continue.
327
 * These functions are called by make_code(), the code selection switch.
328
 */
329
 
330
 
331
/*
332
*    Procedure definition
333
 */
334
makeans make_proc_tag_code
335
    PROTO_N ( (e,sp,dest,exitlab) )
336
    PROTO_T ( exp e X space sp X where dest X int exitlab )
337
{
338
   static int p_lab = 0;
339
   procrec *pr=&procrecs[no(e)];
340
   needs *ndpr=&pr->needsproc;
341
   long pprops=(long) (ndpr->propsneeds);
342
   makeans mka;
343
   bool is_main=STRCMP(proc_name,"main");
344
   bool save_sp;
345
 
346
   set_up_frame(e);
347
 
348
   /*
349
   *   Grab the frame size, offsets, etc. of this procedure's frame
350
    */
351
   leaf = pr->leaf;
352
   locals_space = pr->locals_space;
353
   max_args = pr->max_args;
354
   frame_sz = pr->frame_sz;
355
   callees_offset = pr->callees_offset;
356
   params_offset = pr->params_offset;
357
   locals_offset = pr->locals_offset;
358
   callee_sz = pr->callee_sz;
359
   simpleans = (pprops & long_result_bit) == 0;
360
 
361
   save_sp = ( ((Has_fp && (No_S || (Uses_crt_env && Has_vcallees)))) ||
362
	       (Uses_crt_env && (!leaf || proc_has_checkstack(e)
363
				       || Has_checkalloc)));
364
 
365
   if (OPTIM)
366
   {
367
      lines=BLOCK;
368
      pCode = (pIn*) malloc(BLOCK*sizeof(pIn));
369
      nLabels=4096;
370
      labIntro = (int*) malloc(nLabels*sizeof(int));
371
      for(line=0;line<4096;line++)
372
	 labIntro[line]=-1;
373
      line=0;
374
   }
375
   odd_bits = (outofline*)0;
376
   repeat_level=0;
377
 
378
   mka.lab = exitlab;
379
   mka.regmove = NOREG;
380
 
381
   assert(name(e) == proc_tag);	/* procedure definition */
382
 
383
   export[0]=0;
384
   outnl();
385
   if (is_main)
386
   {
387
      if (gcc_assembler)
388
      {
389
	 outs("\t.IMPORT\t__CTOR_LIST__,DATA\n");
390
	 outs("\t.IMPORT\t__main,CODE\n");
391
      }
392
      else
393
	 outs("\t.IMPORT\t__TDF_CTOR_LIST__,DATA\n");
394
   }
395
   if (do_profile)
396
   {
397
      outs("\t.BSS\n");
398
      outs("\t.ALIGN\t4\n");
399
      outs("G$");
400
      outn(p_lab);
401
      outs("\t.BLOCKZ\t4\n");
402
   }
403
   outs("\t.CODE\n");
404
   outs(proc_name);
405
   outnl();
406
   outs("\t.PROC\n");
407
   /*
408
   *   Output `CALLINFO' directive (c.f. pp 3-10 - 3-13 of assembly language
409
   *   reference manual)
410
    */
411
   outs("\t.CALLINFO FRAME=");
412
		  /* FRAME=frame size - frame marker bytes (if allocated) */
413
   if (gcc_assembler)
414
   {
415
      outn(frame_sz>>3);
416
   }
417
   else
418
   {
419
      outn((frame_sz>>3) - (leaf ? 0 : 8<<2));
420
   }
421
   if (save_sp)
422
      outs(",SAVE_SP");
423
   outs(",SAVE_RP,ENTRY_GR=3");
424
   if (leaf)
425
   {
426
      outc('\n');
427
   }
428
   else
429
   {
430
      outs(",CALLS\n");
431
   }
432
   outs("\t.ENTRY\n");
433
 
434
   /* store return pointer */
435
   st_ir_ins(i_stw,cmplt_,RP,fs_,empty_ltrl,-20,SP);
436
 
437
   if (fixdump != 0)
438
   {
439
      save_sregs();  /* Save the s-regs on stack. */
440
   }
441
 
442
   if (do_profile)
443
   {
444
      char g[128];
445
      baseoff b;
446
      b.base=SP;
447
      b.offset=-36;
448
      st_ins(i_sw,ARG0,b);
449
      b.offset-=4;
450
      st_ins(i_sw,ARG1,b);
451
      b.offset-=4;
452
      st_ins(i_sw,ARG2,b);
453
      b.offset-=4;
454
      st_ins(i_sw,ARG3,b);
455
      b.base=0; b.offset=0;
456
      sprintf(g,"G$%d",p_lab);
457
      set_ins(g,b,ARG2);
458
      rr_ins(i_blr,GR0,ARG1);
459
      rr_ins(i_copy,RP,ARG0);
460
      call_ins(cmplt_,"_mcount",RP,"ARGW0=GR,ARGW1=GR,ARGW2=GR");
461
      p_lab++;
462
      b.base=SP;
463
      b.offset=-36;
464
      ld_ins(i_lw,0,b,ARG0);
465
      b.offset-=4;
466
      ld_ins(i_lw,0,b,ARG1);
467
      b.offset-=4;
468
      ld_ins(i_lw,0,b,ARG2);
469
      b.offset-=4;
470
      ld_ins(i_lw,0,b,ARG3);
471
   }
472
 
473
   {
474
      /*
475
      *   Increment the Stack Pointer
476
       */
477
      int R = SP;
478
      if (proc_has_checkstack(e))
479
      {
480
	 R = T1;
481
      }
482
      else if (Has_fp)
483
      {
484
	 rr_ins(i_copy,SP,FP);
485
      }
486
      else
487
      if (save_sp)
488
      {
489
	 rr_ins(i_copy,SP,T1);
490
      }
491
      if (Has_vcallees)
492
      {
493
	 /* Add on callee_sz passed on stack by caller... */
494
	 ld_ir_ins(i_ldw,cmplt_,fs_,empty_ltrl,(16<<2),SP,GR1);
495
	 rrr_ins(i_add,c_,SP,GR1,R);
496
	 /* ...and ensure the stack pointer stays 16 word (64 byte) aligned */
497
	 if (SIMM14((frame_sz>>3)+63))
498
	 {
499
	    ld_ir_ins(i_ldo,cmplt_,fs_,empty_ltrl,(frame_sz>>3)+63,R,R);
500
	 }
501
	 else
502
	 {
503
	    ir_ins(i_addil,fs_L,empty_ltrl,(frame_sz>>3)+63,R);
504
	    ld_ir_ins(i_ldo,cmplt_,fs_R,empty_ltrl,(frame_sz>>3)+63,GR1,R);
505
	 }
506
	 riir_ins(i_dep,c_,0,31,6,R);
507
      }
508
      else
509
      {
510
	 if (SIMM14(frame_sz>>3))
511
	 {
512
	    ld_ir_ins(i_ldo,cmplt_,fs_,empty_ltrl,frame_sz>>3,SP,R);
513
	 }
514
	 else
515
	 {
516
	    ir_ins(i_addil,fs_L,empty_ltrl,frame_sz>>3,SP);
517
	    ld_ir_ins(i_ldo,cmplt_,fs_R,empty_ltrl,frame_sz>>3,GR1,R);
518
	 }
519
      }
520
   }
521
 
522
   if (save_sp && !Has_fp)
523
   {
524
      if (proc_has_checkstack(e))
525
	 st_ir_ins(i_stw,cmplt_,SP,fs_,empty_ltrl,FP_BOFF.offset,T1);
526
      else
527
	 st_ir_ins(i_stw,cmplt_,T1,fs_,empty_ltrl,FP_BOFF.offset,SP);
528
   }
529
 
530
   if (proc_has_checkstack(e))
531
   {
532
      baseoff b;
533
      exp stl = find_named_tg("__TDFstacklim",
534
			      f_pointer(f_alignment(f_proc)));
535
      setvar(stl);
536
      b = boff(stl);
537
      stackerr_lab = new_label();
538
      ld_ins(i_lw,1,b,GR1);
539
      cj_ins(c_g,T1,GR1,stackerr_lab);
540
      if (Has_fp)
541
	 rr_ins(i_copy,SP,FP);
542
      rr_ins(i_copy,T1,SP);
543
   }
544
 
545
   if (PIC_code)
546
   {
547
      st_ir_ins(i_stw,cmplt_,GR19,fs_,empty_ltrl,-32,SP);
548
      if (!leaf && !is_main)
549
      {
550
	 rr_ins(i_copy,GR19,GR5);
551
      }
552
   }
553
 
554
   if (is_main)
555
   {
556
      int n = new_label();
557
      int end = new_label();
558
      baseoff b;
559
      b.base = 0; b.offset = (gcc_assembler ? 0 : 4 );
560
      set_ins((gcc_assembler ? "__CTOR_LIST__" : "__TDF_CTOR_LIST__"),b,GR4);
561
      b.base = GR4;
562
      b.offset = 4;
563
      if (gcc_assembler)
564
      {
565
	 ld_ins(i_lwm,1,b,GR5);
566
	 cj_ins(c_eq,GR0,GR5,end);
567
	 rrr_ins(i_sh2add,c_,GR5,GR4,GR5);
568
	 outlab("L$$",n);
569
	 ld_ins(i_lwm,1,b,GR22);
570
	 call_millicode( MILLI_DYNCALL, RP, "",0 );
571
	 cj_ins(c_l,GR4,GR5,n);
572
	 outlab("L$$",end);
573
	 if (is_PIC_and_calls)
574
	    ld_ir_ins(i_ldw,cmplt_,fs_,empty_ltrl,-32,SP,GR5);
575
	 call_ins(cmplt_,"__main",RP,"");
576
      }
577
      else
578
      {
579
	 ld_ins(i_lwm,1,b,GR22);
580
	 cj_ins(c_eq,GR0,GR22,end);
581
	 outlab("L$$",n);
582
	 call_millicode( MILLI_DYNCALL, RP, "",0 );
583
	 ld_ins(i_lwm,1,b,GR22);
584
	 cj_ins(c_neq,GR0,GR22,n);
585
	 outlab("L$$",end);
586
      }
587
   }
588
 
589
   if (Has_vsp)
590
      rr_ins(i_copy,SP,EP);
591
   if (Has_tos)
592
      st_ins(i_sw,SP,SP_BOFF);
593
   if ( (Has_fp && (No_S || (Uses_crt_env && Has_vcallees))) )
594
      st_ins(i_sw,FP,FP_BOFF);
595
 
596
   if (!simpleans)
597
   {
598
      /* structure or union result */
599
      instore is;
600
      /* where to find address of result */
601
      is.adval = 0;
602
      is.b = LONG_RESULT_BOFF;
603
      setinsalt(procans,is);
604
      st_ins(i_sw,RET0,is.b);
605
   }
606
   else if ((pprops & realresult_bit) != 0)
607
   {
608
      /* real result */
609
      freg frg;
610
      frg.fr = R_FR4;
611
      frg.dble = (pprops & longrealresult_bit) ? 1 : 0;
612
      setfregalt(procans,frg);
613
   }
614
   else if ((pprops & has_result_bit) != 0)
615
   {
616
      /* fixed register result */
617
      setregalt(procans,RET0);
618
   }
619
   else
620
   {
621
      /* no result */
622
      setregalt(procans,GR0);
623
   }
624
 
625
  clear_all();
626
  RSCOPE_LEVEL = 0;
627
  res_label = 0;
628
  untidy_return_label = 0;
629
  return_to_label_label = 0;
630
  last_odd_bit = 0;
631
  doing_odd_bits = 0;
632
 
633
  code_here(son(e),sp,nowhere);	/* Code body of procedure. */
634
 
635
  if (stackerr_lab!=0)
636
  {
637
     outlab("L$$",stackerr_lab);
638
     do_exception(SIGUSR1);
639
  }
640
  if (aritherr_lab!=0)
641
  {
642
     outlab("L$$",aritherr_lab);
643
     do_exception(SIGFPE);
644
  }
645
 
646
  doing_odd_bits = 1;
647
  while (odd_bits != (outofline*)0)
648
  {
649
     outofline *ol = odd_bits;
650
     odd_bits = (outofline*)0;
651
     last_odd_bit=0;
652
     add_odd_bits(ol);
653
  }
654
 
655
  if (xdb)
656
  {
657
     outlab("L$$",res_label);
658
     code_for_ret(RES);
659
  }
660
 
661
 
662
  if (OPTIM)
663
  {
664
     /*
665
     *   Jump and "peephole" optimisations
666
      */
667
     int i,j;
668
     char *hit;
669
     FILE_POSN Pos;
670
     GET_FILE_POSN(outf,Pos);
671
     hit = (char*) malloc( (nLabels+8)*sizeof(char) );
672
     for(i=0;i<line;i++)
673
     {
674
	char s[65];
675
	int lab,to=0,jump;
676
	lab=pCode[i]->lab;
677
	if (lab==res_label && lab>0)
678
	   to=labIntro[lab-firstlab];
679
	else
680
	if (lab>NA && lab != res_label && pCode[i]->ins != i_lab)
681
	{
682
	   for (j=0;j<nLabels+8;j++)
683
	       hit[j]=0;
684
	   to=labIntro[lab-firstlab];
685
	   while(to+1<line && lab!=res_label && pCode[to+1]->lab>NA
686
			   && pCode[to+1]->ins==i_ub && hit[lab-firstlab]==0)
687
	   {
688
	      hit[lab-firstlab]=1;
689
	      lab=pCode[to+1]->lab;
690
	      to=labIntro[lab-firstlab];
691
	   }
692
	}
693
	if (pCode[i]->ins==i_bb)
694
	{
695
	   jump = i-to ;
696
	   if (SIMM11(jump*4))
697
	   {
698
	      ins_p cc;
699
	      int a,b;
700
	      cc=pCode[i]->cc;
701
	      SET_FILE_POSN(outf,(pCode[i]->fpos));
702
	      a=pCode[i]->op[0];
703
	      b=pCode[i]->op[1];
704
	      IGNORE sprintf(s,"\tbb%s,N\t%s,%d,L$$%d\n\tnop",cc,RN(a),b,lab);
705
	      j=(int)strlen(s);
706
	      for(;j<63;j++)
707
		 s[j]=' ';
708
	      s[63]=0;
709
	      fprintf(outf,"%s\n",s);
710
	   }
711
	   else
712
	   {
713
	      ins_p cc;
714
	      int a,b;
715
	      if (pCode[i]->cc==bit_is_0)
716
		 cc=c_OD;
717
	      else
718
		 cc=c_EV;
719
	      SET_FILE_POSN(outf,(pCode[i]->fpos));
720
	      a=pCode[i]->op[0];
721
	      b=pCode[i]->op[1];
722
	      IGNORE sprintf(s,"\textru%s\t%s,%d,1,0\n\tb\tL$$%d\n\tnop",cc,RN(a),b,lab);
723
	      j=(int)strlen(s);
724
	      for(;j<63;j++)
725
		 s[j]=' ';
726
	      s[63]=0;
727
	      fprintf(outf,"%s\n",s);
728
	   }
729
	}
730
	else
731
	if (pCode[i]->ins==i_ub)
732
	{
733
	   jump = i-to ;
734
	   SET_FILE_POSN(outf,(pCode[i]->fpos));
735
#if 0
736
	   if (SIMM19(jump*4))
737
	   {
738
#endif
739
	      IGNORE sprintf(s,"\tb\tL$$%d\n\tnop",lab);
740
	      j=(int)strlen(s);
741
	      for(;j<63;j++)
742
		 s[j]=' ';
743
	      s[63]='\n';
744
	      s[64]=0;
745
	      fprintf(outf,"%s",s);
746
#if 0
747
	   }
748
	   else
749
	   {
750
	   }
751
#endif
752
	}
753
	else
754
	if (pCode[i]->ins==i_cj || pCode[i]->ins==i_cij)
755
	{
756
	   jump = i-to ;
757
	   if (SIMM11(jump*4))
758
	   {
759
	      ins_p cc;
760
	      int a,b;
761
	      cc=pCode[i]->cc;
762
	      SET_FILE_POSN(outf,(pCode[i]->fpos));
763
	      a=pCode[i]->op[0];
764
	      b=pCode[i]->op[1];
765
	      if (jump<0 && line>i)
766
	      {
767
	      if (pCode[i]->ins==i_cj)
768
		 IGNORE sprintf(s,"\tcomb%s,N\t%s,%s,L$$%d\n",cc,RN(a),RN(b),lab);
769
	      else
770
		 IGNORE sprintf(s,"\tcomib%s,N\t%d,%s,L$$%d\n",cc,a,RN(b),lab);
771
	      }
772
	      else
773
	      {
774
	      if (pCode[i]->ins==i_cj)
775
		 IGNORE sprintf(s,"\tcomb%s,N\t%s,%s,L$$%d\n\tnop",cc,RN(a),RN(b),lab);
776
	      else
777
		 IGNORE sprintf(s,"\tcomib%s,N\t%d,%s,L$$%d\n\tnop",cc,a,RN(b),lab);
778
	      }
779
	      j=(int)strlen(s);
780
	      for(;j<63;j++)
781
		 s[j]=' ';
782
	      s[63]=0;
783
	      fprintf(outf,"%s\n",s);
784
	   }
785
	   else
786
#if 0
787
	   if (SIMM19(jump*4))
788
#endif
789
	   {
790
	      ins_p cc;
791
	      int a,b;
792
	      cc=opp(pCode[i]->cc);
793
	      SET_FILE_POSN(outf,(pCode[i]->fpos));
794
	      a=pCode[i]->op[0];
795
	      b=pCode[i]->op[1];
796
	      if (pCode[i]->ins==i_cj)
797
		 IGNORE sprintf(s,"\tcomclr%s\t%s,%s,0\n\tb\tL$$%d\n\tnop",cc,RN(a),RN(b),lab);
798
	      else
799
		 IGNORE sprintf(s,"\tcomiclr%s\t%d,%s,0\n\tb\tL$$%d\n\tnop",cc,a,RN(b),lab);
800
	      j=(int)strlen(s);
801
	      for(;j<63;j++)
802
		 s[j]=' ';
803
	      s[63]=0;
804
	      fprintf(outf,"%s\n",s);
805
	   }
806
#if 0
807
	   else
808
	   {
809
	      ins_p cc;
810
	      int a,b;
811
	      cc=pCode[i]->cc;
812
	      SET_FILE_POSN(outf,(pCode[i]->fpos));
813
	      a=pCode[i]->op[0];
814
	      b=pCode[i]->op[1];
815
	      if (pCode[i]->ins==i_cj)
816
		 IGNORE sprintf(s,"\tcomb%s,N\t%s,%s,.+16\n\tnop\n\tLB\tL$$%d\n",cc,RN(a),RN(b),lab);
817
	      else
818
		 IGNORE sprintf(s,"\tcomib%s,N\t%d,%s,.+16\n\tnop\n\tLB\tL$$%d\n",cc,a,RN(b),lab);
819
	      j=(int)strlen(s);
820
	      for(;j<63;j++)
821
		 s[j]=' ';
822
	      s[63]=0;
823
	      fprintf(outf,"%s\n",s);
824
	   }
825
#endif
826
	}
827
     }
828
     SET_FILE_POSN(outf,Pos);
829
     free(hit);
830
  }
831
 
832
 
833
 
834
{
835
   int i;
836
   for(i=0;i<line;i++)
837
   {
838
      pIn j=pCode[line];
839
      free(j);
840
   }
841
   free(pCode);
842
   free(labIntro);
843
}
844
 
845
 
846
   outs("\t.EXIT\n");
847
   clear_all();  /* for next proc */
848
   return mka;
849
}
850
 
851
 
852
/*
853
*   res_tag, return_to_label or untidy_return
854
 */
855
 
856
makeans make_res_tag_code
857
    PROTO_N ( (e,sp,dest,exitlab) )
858
    PROTO_T ( exp e X space sp X where dest X int exitlab )
859
{
860
   makeans mka;
861
   int nm,*ret_label;
862
   mka.lab = exitlab;
863
   mka.regmove = NOREG;
864
   if (name(e)==res_tag)
865
   {
866
      nm=RES;
867
      ret_label=&res_label;
868
   }
869
   else
870
   if (name(e)==return_to_label_tag)
871
   {
872
      nm=TO_LAB;
873
      ret_label=&return_to_label_label;
874
   }
875
   else
876
   {
877
      nm=UNTIDY;
878
      ret_label=&untidy_return_label;
879
   }
880
   if (nm!=TO_LAB)  /* don't evaluate result if returning to label */
881
   {
882
      where w;
883
      bool cmpd;
884
      w.answhere = procans;
885
      w.ashwhere = ashof(sh(son(e)));
886
      cmpd = (w.ashwhere.ashsize<65 && !simpleans);
887
      if (cmpd)
888
      {
889
	 /*
890
	 *   The HP_PA RISC convention states that compound results of 64
891
	*    bits are to be returned in the registers RET0 and RET1. We put
892
	*    the result into the stack space LONG_RESULT_BOFF and then load
893
	 *   into the registers.
894
	  */
895
	w.answhere.val.instoreans.adval=1;
896
      }
897
      code_here(son(e),sp,w); /*  Get the result  */
898
      if (cmpd)
899
      {
900
	 instore is;
901
	 baseoff b;
902
	 is=procans.val.instoreans;
903
	 b = is.b;
904
	 ld_ins(i_lw,SIGNED,b,RET0);
905
	 b.offset+=4;
906
	 ld_ins(i_lw,SIGNED,b,RET1);
907
      }
908
   }
909
   if (RSCOPE_LEVEL==0)
910
   {
911
      if (nm==TO_LAB)
912
	 reg_operand_here(son(e),sp,RP);
913
      if (*ret_label==0)
914
      {
915
	 /*
916
	 *    Must be the first res_tag, the first return_to_label, or the
917
	 *    first untidy_return encountered in this procedure - label
918
	  *   and output relevant code sequence
919
	   */
920
	 *ret_label = new_label();
921
	 if (xdb)
922
	 {
923
	    ub_ins(cmplt_,*ret_label);
924
	 }
925
	 else
926
	 {
927
	    outlab("L$$",*ret_label);
928
	    code_for_ret(nm);
929
	 }
930
      }
931
      else
932
      if (xdb || fixdump)
933
	 ub_ins(cmplt_,*ret_label);
934
      else
935
	 code_for_ret(nm);  /*
936
			    *   A very short return sequence - output code
937
			    *   each time thus avoiding a jump to *ret_label
938
			     */
939
   }
940
   else
941
   {
942
      /* inlined result */
943
      if (RSCOPE_LABEL == 0)
944
	 RSCOPE_LABEL = new_label();
945
      if (RSCOPE_LABEL != exitlab)
946
	 ub_ins(cmplt_,RSCOPE_LABEL);
947
   }
948
 
949
   clear_all();	  /* regs invalid after return. (Not needed for inlining?) */
950
 
951
   return mka;
952
}
953
 
954
 
955