Subversion Repositories tendra.SVN

Rev

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: inst_fmt.c,v $
33
 * Revision 1.1.1.1  1998/01/17  15:56:02  release
34
 * First version to be checked into rolling release.
35
 *
36
 * Revision 1.8  1997/01/29  10:19:10  wfs
37
 *    Fixed a minor bug in "move.c" and "oprators.c" due to immediates of  >
38
 * 14 bits appearing in the field of ldo instrcutions.
39
 *
40
 * Revision 1.7  1996/12/09  12:52:43  wfs
41
 *    Prevented the superfluous "loading" to GR0.
42
 *
43
 * Revision 1.6  1996/11/20  17:26:47  wfs
44
 *    Fixed bug in makecode.c's case_tag involving unsigned control variable.
45
 *
46
 * Revision 1.5  1996/11/14  15:22:17  wfs
47
 *    Fixed a bug in regexps.c which was common to most of the installers and
48
 * has only just come to light due to PWE's work on powertrans. (There was
49
 * previously only a patch.) Cosmetic changes to other files.
50
 *
51
 * Revision 1.4  1996/11/07  14:48:16  wfs
52
 * A bug fix to "round_tag" - was clearing wrong freg. Cosmetic changes to
53
 * "inst_fmt.c".
54
 *
55
 * Revision 1.3  1996/08/06  10:50:09  wfs
56
 * bug fixes to pic code, enum diagnostics enabled.
57
 *
58
 * Revision 1.2  1995/12/18  13:11:38  wfs
59
 * Put hppatrans uder cvs control. Major Changes made since last release
60
 * include:
61
 * (i) PIC code generation.
62
 * (ii) Profiling.
63
 * (iii) Dynamic Initialization.
64
 * (iv) Debugging of Exception Handling and Diagnostics.
65
 *
66
 * Revision 5.5  1995/10/30  14:26:53  wfs
67
 * Refined the limit on the number of exp's which determines the type of
68
 * branches used.
69
 *
70
 * Revision 5.4  1995/10/20  13:57:25  wfs
71
 * Changes for gcc compilation.
72
 *
73
 * Revision 5.3  1995/10/12  17:20:44  wfs
74
 * *** empty log message ***
75
 *
76
 * Revision 5.2  1995/10/09  12:57:46  wfs
77
 * Cosmetic changes.
78
 *
79
 * Revision 5.1  1995/09/15  12:34:24  wfs
80
 * Made what, I hope, is a temporary fix to "set_ins()" + changes to
81
 * stop gcc compiler from complaining.
82
 *
83
 * Revision 5.0  1995/08/25  13:42:58  wfs
84
 * Preperation for August 25 Glue release
85
 *
86
 * Revision 3.3  1995/08/25  09:42:29  wfs
87
 * internal register synonyms changed. much superfluous code was
88
 * removed after changes were made to register allocation
89
 *
90
 * Revision 3.3  1995/08/25  09:42:29  wfs
91
 * internal register synonyms changed. much superfluous code was
92
 * removed after changes were made to register allocation
93
 *
94
 * Revision 3.1  95/04/10  16:26:55  16:26:55  wfs (William Simmonds)
95
 * Apr95 tape version.
96
 *
97
 * Revision 3.0  95/03/30  11:17:29  11:17:29  wfs (William Simmonds)
98
 * Mar95 tape version with CRCR95_178 bug fix.
99
 *
100
 * Revision 2.0  95/03/15  15:27:40  15:27:40  wfs (William Simmonds)
101
 * spec 3.1 changes implemented, tests outstanding.
102
 *
103
 * Revision 1.2  95/01/17  17:23:19  17:23:19  wfs (William Simmonds)
104
 * Changes to outp made whilst debugging bootstrap
105
 *
106
 * Revision 1.1  95/01/11  13:09:32  13:09:32  wfs (William Simmonds)
107
 * Initial revision
108
 *
109
*/
110
 
111
 
112
#define HPPATRANS_CODE
113
/******************************************************************
114
		inst_formats.c
115
 
116
	Procs for outputting various HPPA RISC instruction formats to the
117
external file - outf. Each procedure produces assembler code for a family
118
of HPPA RISC operations, the actual member is passed as the string
119
understood by the assembler.
120
******************************************************************/
121
 
122
#include "config.h"
123
#include "myassert.h"
124
#include "xalloc.h"
125
#include "addrtypes.h"
126
#include "regexps.h"
127
#include "regmacs.h"
128
#include "hppains.h"
129
#include "maxminmacs.h"
130
#include "comment.h"
131
#include "translat.h"
132
#include "inst_fmt.h"
133
#include "out.h"
134
#include "misc.h"
135
#include "frames.h"
136
#include "new_tags.h"
137
#include "tags.h"
138
#include "expmacs.h"
139
#include "flags.h"
140
#include "eval.h"
141
 
142
#define name( x ) ( ( x )->namef )
143
#define sh( x ) ( ( x )->shf )
144
#define son( x ) ( ( x )->sonf.e )
145
 
146
#define GAP "                                                                "
147
#define prokhd 24
148
 
149
#define plabel( X ) ( (X)<0 ?\
150
    ( son(main_globals[((-X))-1]->dec_u.dec_val.dec_exp)==nilexp ?\
151
    name(sh(main_globals[((-X))-1]->dec_u.dec_val.dec_exp))==prokhd :\
152
    ( IS_A_PROC(son(main_globals[((-X))-1]->dec_u.dec_val.dec_exp)) ) ) : 0 )
153
 
154
#define globaldata(X) ( (X)<0 ?\
155
    ( (name(sh(main_globals[((-X))-1]->dec_u.dec_val.dec_exp))==proc_tag ||\
156
    name(sh(main_globals[((-X))-1]->dec_u.dec_val.dec_exp))==general_proc_tag)\
157
    ? 0 : 1 ) : 0 )
158
 
159
 
160
extern int firstlab, labno;
161
extern int nexps;
162
char last_ins[96];
163
 
164
int zops[]={0,0,0,0};
165
int last_line;
166
char last_symb[128];
167
int last_o;
168
 
169
static CONST char reg_name_tab[32][6] =
170
{ "%r0"  ,
171
  "%r1"  ,
172
  "%r2"  ,
173
  "%r19" ,
174
  "%r20" ,
175
  "%r21" ,
176
  "%r22" ,
177
  "%r26" ,
178
  "%r25" ,
179
  "%r24" ,
180
  "%r23" ,
181
  "%dp"  , /* %dp=%r27 */
182
  "%r28" ,
183
  "%r29" ,
184
  "%sp"  , /* %sp=%r30 */
185
  "%r31" ,
186
  "%r3"  ,
187
  "%r4"  ,
188
  "%r5"  ,
189
  "%r6"  ,
190
  "%r7"  ,
191
  "%r8"  ,
192
  "%r9"  ,
193
  "%r10" ,
194
  "%r11" ,
195
  "%r12" ,
196
  "%r13" ,
197
  "%r14" ,
198
  "%r15" ,
199
  "%r16" ,
200
  "%r17" ,
201
  "%r18"    };
202
 
203
static CONST char float_reg_name_tab[32][3][7] =
204
{
205
  { "%fr0L", "%fr0", "%fr0R" },
206
  { "%fr1L", "%fr1", "%fr1R" },
207
  { "%fr2L", "%fr2", "%fr2R" },
208
  { "%fr3L", "%fr3", "%fr3R" },
209
  { "%fr4L", "%fr4", "%fr4R" },
210
  { "%fr5L", "%fr5", "%fr5R" },
211
  { "%fr6L", "%fr6", "%fr6R" },
212
  { "%fr7L", "%fr7", "%fr7R" },
213
  { "%fr8L", "%fr8", "%fr8R" },
214
  { "%fr9L", "%fr9", "%fr9R" },
215
  { "%fr10L", "%fr10", "%fr10R" },
216
  { "%fr11L", "%fr11", "%fr11R" },
217
  { "%fr12L", "%fr12", "%fr12R" },
218
  { "%fr13L", "%fr13", "%fr13R" },
219
  { "%fr14L", "%fr14", "%fr14R" },
220
  { "%fr15L", "%fr15", "%fr15R" },
221
  { "%fr16L", "%fr16", "%fr16R" },
222
  { "%fr17L", "%fr17", "%fr17R" },
223
  { "%fr18L", "%fr18", "%fr18R" },
224
  { "%fr19L", "%fr19", "%fr19R" },
225
  { "%fr20L", "%fr20", "%fr20R" },
226
  { "%fr21L", "%fr21", "%fr21R" },
227
  { "%fr22L", "%fr22", "%fr22R" },
228
  { "%fr23L", "%fr23", "%fr23R" },
229
  { "%fr24L", "%fr24", "%fr24R" },
230
  { "%fr25L", "%fr25", "%fr25R" },
231
  { "%fr26L", "%fr26", "%fr26R" },
232
  { "%fr27L", "%fr27", "%fr27R" },
233
  { "%fr28L", "%fr28", "%fr28R" },
234
  { "%fr29L", "%fr29", "%fr29R" },
235
  { "%fr30L", "%fr30", "%fr30R" },
236
  { "%fr31L", "%fr31", "%fr31R" }
237
};
238
 
239
static CONST char space_reg_name_tab[8][5] =
240
{ "%sr0" ,
241
  "%sr1" ,
242
  "%sr2" ,
243
  "%sr3" ,
244
  "%sr4" ,
245
  "%sr5" ,
246
  "%sr6" ,
247
  "%sr7"    };
248
 
249
 
250
#define	RN(reg)	reg_name( reg )
251
#define	FN(reg)	float_reg_name(reg)
252
#define	SN(reg)	space_reg_name_tab[ reg ]
253
 
254
#define NA -1
255
 
256
ins_p NOCOND=0;
257
 
258
 
259
CONST char *reg_name
260
    PROTO_N ( (r) )
261
    PROTO_T ( int r )
262
{
263
  assert(IS_FIXREG(r));
264
  return reg_name_tab[r];
265
}
266
 
267
static CONST char *float_reg_name
268
    PROTO_N ( (reg) )
269
    PROTO_T ( int reg )
270
{
271
   return float_reg_name_tab[0][0]+(7*reg);
272
}
273
 
274
 
275
int outp
276
    PROTO_N ( (ins,cc,ops,lab) )
277
    PROTO_T ( ins_p ins X ins_p cc X int *ops X int lab )
278
{
279
   if (!OPTIM)
280
   {
281
      return 1;
282
   }
283
   if ( line>(lines-16) )
284
   {
285
      /* Increment number of assembler instructions allowed for by INCR */
286
      int i;
287
      pIn *temp=pCode;
288
      pCode = (pIn*) malloc( (lines+INCR)*sizeof(pIn) );
289
      for(i=0;i<lines;i++)
290
	 pCode[i]=temp[i];
291
      free(temp);
292
      lines+=INCR;
293
   }
294
   if (ins==i_add && line>0)
295
   {
296
      pIn lst=pCode[line-1];
297
      ins_p lI=lst->ins;
298
      if (lst->op[1]==0 && (lI==i_sh1add || lI==i_sh2add || lI==i_sh3add))
299
      {
300
	 int r=lst->op[2];
301
	 int r0=ops[0];
302
	 int r1=ops[1];
303
	 if ( r==ops[2] && (r==r0 || r==r1) )
304
	 {
305
	    if (r==r1)
306
	       r1=r0;
307
	    r0=lst->op[0];
308
	    SET_FILE_POSN(outf,(lst->fpos));
309
	    fprintf(outf,"\t%s\t%s,%s,%s\n",lI,RN(r0),RN(r1),RN(r));
310
	    lst->op[1]=r1;
311
	    line--;
312
	    return 0;
313
	 }
314
      }
315
   }
316
   else if (ins==i_ub && line>0)
317
   {
318
      if (pCode[line-1]->ins==i_ub)
319
      {
320
	 if (line==1)
321
	    return 0;
322
	 else if (pCode[line-2]->ins!=i_ftest && pCode[line-2]->cc==c_)
323
	    return 0;
324
      }
325
   }
326
   else if (ins==i_lab && line>0)
327
   {
328
      int l=line-1;
329
      pIn j=pCode[l];
330
      while ( (j->ins==i_ub || j->ins==i_cj || j->ins==i_cij || j->ins==i_bb)                 && j->lab==lab && l>=0 )
331
      {
332
	 SET_FILE_POSN(outf,(j->fpos));
333
	 free(j);
334
	 l--;
335
	 if (l>=0)
336
	 {
337
	    j=pCode[l];
338
	    if (j->ins==i_ftest)
339
	    {
340
	      free(j);
341
	      j=pCode[l-1];
342
	      SET_FILE_POSN(outf,(j->fpos));
343
	      free(j);
344
	      l-=2;
345
	      if (l>=0)
346
		 j=pCode[l];
347
	    }
348
	 }
349
      }
350
      line=l+1;
351
      if ( line>1 && j->ins==i_lab )
352
      {
353
	 ins_p jIns;
354
	 j=pCode[line-2];
355
	 jIns=j->ins;
356
	 if ( (jIns==i_cj || jIns==i_cij || jIns==i_ub) && j->lab==lab )
357
	 {
358
	    SET_FILE_POSN(outf,(j->fpos));
359
	    fprintf(outf,"L$$%d\n",pCode[l]->lab);
360
	    labIntro[pCode[l]->lab-firstlab]=line-2;
361
	    pCode[l-1]=pCode[l];
362
	    free(j);
363
	    line--;
364
	 }
365
      }
366
      else
367
      if ( line>1 && j->ins!=i_ub && j->ins!=i_cj && j->ins!=i_cij
368
	   && j->ins!=i_bb && j->ins!=i_lab )
369
      {
370
	 ins_p jIns;
371
	 j=pCode[line-2];
372
	 jIns=j->ins;
373
	 if ( (jIns==i_cj || jIns==i_cij) && j->lab==lab )
374
	 {
375
	     FILE_POSN pos;
376
	     char s[64];
377
	     int a,b,i;
378
	     a=j->op[0];
379
	     b=j->op[1];
380
	     GET_FILE_POSN(outf,pos);
381
	     SET_FILE_POSN(outf,(j->fpos));
382
	     if (jIns==i_cj)
383
	     {
384
		IGNORE sprintf(s,"\tcomclr%s\t%s,%s,0",j->cc,RN(a),RN(b));
385
		i=(int)strlen(s);
386
		j->ins=i_comclr;
387
	     }
388
	     else
389
	     {
390
		IGNORE sprintf(s,"\tcomiclr%s\t%d,%s,0",j->cc,a,RN(b));
391
		i=(int)strlen(s);
392
		j->ins=i_comiclr;
393
	     }
394
	     for(;i<63;i++)
395
		s[i]=' ';
396
	     s[63]=0;
397
	     fprintf(outf,"%s\n",s);
398
	     j->op[2]=0;
399
	     j->lab=NA;
400
	     SET_FILE_POSN(outf,pos);
401
	 }
402
      }
403
      else
404
      if (j->ins==i_ub && line>1 && ((pCode[line-2]->ins==i_cij ||
405
				        pCode[line-2]->ins==i_cj) &&
406
				       pCode[line-2]->lab==lab))
407
      {
408
	 pCode[line-2]->lab=j->lab;
409
	 pCode[line-2]->cc=opp(pCode[line-2]->cc);
410
	 SET_FILE_POSN(outf,(j->fpos));
411
	 free(j);
412
	 line--;
413
      }
414
   }
415
 
416
   {
417
      pIn pI;
418
      pI = (pIn) malloc( sizeof(psuedoIn) );
419
      GET_FILE_POSN(outf,(pI->fpos));
420
      pI->ins=ins;
421
      pI->cc=cc;
422
      pI->lab=lab;
423
      pI->op[0]=ops[0];
424
      pI->op[1]=ops[1];
425
      pI->op[2]=ops[2];
426
      pI->op[3]=ops[3];
427
      pCode[line]=pI;
428
      if (ins==i_lab)
429
      {
430
	 if ( (lab-firstlab)>(nLabels-16) )
431
	 {
432
	    /* Increment number of labels allowed for by INCR */
433
	    int i;
434
	    int *temp=labIntro;
435
	    labIntro = (int*) malloc( (nLabels+INCR)*sizeof(int) );
436
	    for(i=0;i<nLabels;i++)
437
	       labIntro[i]=temp[i];
438
	    for(i=nLabels;i<nLabels+INCR;i++)
439
	       labIntro[i]=-1;
440
	    free(temp);
441
	    nLabels+=INCR;
442
	 }
443
	 labIntro[lab-firstlab]=line;
444
      }
445
      line++;
446
      fflush(outf);
447
      return 1;
448
   }
449
}
450
 
451
 
452
char *ext_name
453
    PROTO_N ( (id) )
454
    PROTO_T ( long id )
455
{
456
  static char *sp;
457
  static int sizeof_space = 0;
458
 
459
  if (sizeof_space == 0)
460
  {
461
    /* init sp */
462
    sizeof_space = 64;		/* generous first guess */
463
    sp = (char *) malloc(sizeof_space);
464
  }
465
 
466
  if (id < 0)
467
  {
468
    char *ext = main_globals[(-id) - 1]->dec_u.dec_val.dec_id;
469
 
470
    int len_needed = 1 + strlen(ext) + 1;	/* _NAME\0 */
471
 
472
    if (len_needed > sizeof_space)
473
    {
474
      sizeof_space = len_needed;
475
      sp = (char *) xrealloc(sp, sizeof_space);
476
    }
477
 
478
    sprintf(sp, "%s", ext);
479
 
480
    return sp;
481
  }
482
  else
483
  {
484
    assert(id > R_LAST);	/* not a confused register */
485
 
486
    sprintf(sp, "LD$%ld", id);
487
    return sp;
488
  }
489
}
490
 
491
 
492
/*
493
*   3 register instructions
494
 */
495
void rrr_ins
496
    PROTO_N ( (ins,cond,a,b,c) )
497
    PROTO_T ( ins_p ins X ins_p cond X int a X int b X int c )
498
{
499
  int p;
500
  int ops[4];
501
  clear_reg(c);
502
 
503
   if (ins==i_add && a==b)
504
   {
505
      ops[0]=a;
506
      ops[1]=0;
507
      ops[2]=c;
508
      p=outp(i_sh1add,cond,ops,NA);
509
      if (p)
510
	 fprintf(outf,"\tsh1add%s\t%s,0,%s\n",cond,RN(a),RN(c));
511
   }
512
   else
513
   {
514
      ops[0]=a;
515
      ops[1]=b;
516
      ops[2]=c;
517
      p=outp(ins,cond,ops,NA);
518
      if (p)
519
	 fprintf(outf,"\t%s%s\t%s,%s,%s\n",ins,cond,RN(a),RN(b),RN(c));
520
   }
521
}
522
 
523
 
524
 
525
/*
526
*   1 register pseudo instructions
527
 */
528
void r_ins
529
    PROTO_N ( (ins,a) )
530
    PROTO_T ( ins_p ins X int a )
531
{
532
   outp(ins,NOCOND,zops,NA);
533
   fprintf(outf,"\t%s\t%s\n",ins,RN(a));
534
}
535
 
536
 
537
 
538
 /*
539
*    non-store register, immediate, destination register instructions
540
 */
541
void rir_ins
542
    PROTO_N ( (ins,cc,a,imm,d) )
543
    PROTO_T ( ins_p ins X ins_p cc X int a X long imm X int d )
544
{
545
   clear_reg(d);
546
   outp(ins,cc,zops,NA);
547
   fprintf(outf,"\t%s%s\t%s,%ld,%s\n",ins,cc,RN(a),imm,RN(d));
548
}
549
 
550
 
551
 
552
 
553
/*
554
*   register to register pseudo instructions
555
 */
556
void rr_ins
557
    PROTO_N ( (ins,s,d) )
558
    PROTO_T ( ins_p ins X int s X int d )
559
{
560
  clear_reg(d);
561
  outp(ins,NOCOND,zops,NA);
562
  fprintf(outf,"\t%s\t%s,%s\n",ins,RN(s),RN(d));
563
}
564
 
565
 
566
/*
567
*   non-load immediate, register, register instructions
568
 */
569
void irr_ins
570
    PROTO_N ( (ins,cc,fs,i,a,d) )
571
    PROTO_T ( ins_p ins X ins_p cc X ins_p fs X long i X int a X int d )
572
{
573
   clear_reg(d);
574
   outp(ins,cc,zops,NA);
575
   fprintf(outf,"\t%s%s\t%s%ld,%s,%s\n",ins,cc,fs,i,RN(a),RN(d));
576
}
577
 
578
 
579
/*
580
*   immediate, immediate, register instructions
581
 */
582
void iir_ins
583
    PROTO_N ( (ins,cc,a,b,d) )
584
    PROTO_T ( ins_p ins X ins_p cc X int a X int b X int d )
585
{
586
   clear_reg(d);
587
   outp(ins,cc,zops,NA);
588
   fprintf(outf,"\t%s%s\t%d,%d,%s\n",ins,cc,a,b,RN(d));
589
}
590
 
591
 
592
/*
593
*   immediate, immediate, immediate, register instructions
594
 */
595
void iiir_ins
596
    PROTO_N ( (ins,cond,a,b,c,d) )
597
    PROTO_T ( ins_p ins X ins_p cond X int a X int b X int c X int d )
598
{
599
   clear_reg(d);
600
   outp(ins,cond,zops,NA);
601
   fprintf(outf,"\t%s%s\t%d,%d,%d,%s\n",ins,cond,a,b,c,RN(d));
602
}
603
 
604
 
605
/*
606
*   immediate (i.e. field selector literal+long) to register instructions
607
 */
608
void ir_ins
609
    PROTO_N ( (ins,fs,ltrl,l,d) )
610
    PROTO_T ( ins_p ins X ins_p fs X CONST char *ltrl X long l X int d )
611
{
612
    char I[128];
613
 
614
    /* build immediate, i.e. field selector applied to literal+long */
615
    if (!(*ltrl))
616
       sprintf(I,"%s%ld",fs,l);
617
    else
618
    if (l>0)
619
       sprintf(I,"%s%s+%ld",fs,ltrl,l);
620
    else
621
    if (l<0)
622
       sprintf(I,"%s%s-%ld",fs,ltrl,-l);
623
    else
624
       sprintf(I,"%s%s",fs,ltrl);
625
 
626
    clear_reg(d);
627
 
628
    outp(ins,NOCOND,zops,NA);
629
    fprintf(outf,"\t%s\t%s,%s\n",ins,I,RN(d));
630
 
631
}
632
 
633
 
634
/*
635
*   register, register, immediate, register instructions
636
 */
637
void rrir_ins
638
    PROTO_N ( (ins,cc,a,b,i,d) )
639
    PROTO_T ( ins_p ins X ins_p cc X int a X int b X long i X int d )
640
{
641
   int ops[4];
642
   if (ins==i_shd && b==0 && i>28)
643
   {
644
      ins_p ins=(i==29 ? i_sh3add : (i==30 ? i_sh2add : i_sh1add));
645
      rrr_ins(ins,c_,a,0,d);
646
      return;
647
   }
648
   clear_reg(d);
649
   ops[0]=a;
650
   ops[1]=b;
651
   ops[2]=i;
652
   ops[3]=d;
653
   outp(ins,cc,ops,NA);
654
   fprintf(outf,"\t%s%s\t%s,%s,%ld,%s\n",ins,cc,RN(a),RN(b),i,RN(d));
655
}
656
 
657
 
658
 
659
/*
660
*   zeroadic pseudo instruction, not a branch
661
 */
662
void z_ins
663
    PROTO_N ( (ins) )
664
    PROTO_T ( ins_p ins )
665
{
666
   int b;
667
   b=outp(ins,NOCOND,zops,NA);
668
   if (b)
669
      fprintf(outf, "\t%s\n", ins);
670
}
671
 
672
 
673
 
674
/*
675
*   register, immediate, immediate, register instructions
676
 */
677
void riir_ins
678
    PROTO_N ( (ins,cc,s,a,b,d) )
679
    PROTO_T ( ins_p ins X ins_p cc X int s X long a X long b X int d )
680
{
681
   clear_reg(d);
682
   outp(ins,cc,zops,NA);
683
   fprintf(outf,"\t%s%s\t%s,%ld,%ld,%s\n",ins,cc,RN(s),a,b,RN(d));
684
}
685
 
686
 
687
/*
688
*   fixed point load instructions
689
 */
690
 
691
void ld_ir_ins
692
    PROTO_N ( (ins,cmplt,fs,ltrl,l,b,d) )
693
    PROTO_T ( ins_p ins X ins_p cmplt X ins_p fs X CONST char *ltrl X long l X int b X int d )
694
{
695
    char O[128];
696
    if (d==GR0)
697
       return;
698
    /* build offset, i.e. field selector applied to literal+long */
699
    if (!(*ltrl))
700
       sprintf(O,"%s%ld",fs,l);
701
    else
702
    if (l>0)
703
       sprintf(O,"%s%s+%ld",fs,ltrl,l);
704
    else
705
    if (l<0)
706
       sprintf(O,"%s%s-%ld",fs,ltrl,-l);
707
    else
708
       sprintf(O,"%s%s",fs,ltrl);
709
   clear_reg(d);
710
   outp(ins,NOCOND,zops,NA);
711
   fprintf(outf,"\t%s%s\t%s(%s),%s\n",ins,cmplt,O,RN(b),RN(d));
712
}
713
 
714
 
715
/*
716
*   loads a long, l, into a register, d, in at most two instructions
717
 */
718
void imm_to_r
719
    PROTO_N ( (l,d) )
720
    PROTO_T ( long l X int d )
721
{
722
   if (d==GR0)
723
      return;
724
   if (SIMM14(l))
725
      ir_ins(i_ldi,fs_,empty_ltrl,l,d);
726
   else
727
   {
728
      int p=0,n,j;
729
      while ( (l & (1<<p))==0 ) p++;
730
      n=p;
731
      while ( l & (1<<n) ) n++;
732
      j=n;
733
      while ( j<32 && (l & (1<<j))==0 ) j++;
734
      if (j==32)
735
	 iiir_ins(i_zdepi,c_,-1,31-p,n-p,d);
736
      else
737
      {
738
	 long sll;
739
	 sll=l>>p;
740
	 if (sll>0 && SIMM5(sll))
741
	    iiir_ins(i_zdepi,c_,sll,31-p,5,d);
742
	 else
743
	 {
744
	    ir_ins(i_ldil,fs_L,empty_ltrl,l,d);
745
	    ld_ir_ins(i_ldo,cmplt_,fs_R,empty_ltrl,l,d,d);
746
	 }
747
      }
748
   }
749
}
750
 
751
 
752
void set_ins
753
    PROTO_N ( (e, a, d) )
754
    PROTO_T ( char *e X baseoff a X int d )
755
{
756
   char *extname;
757
   long o;
758
   int p = 0;
759
   if (d==GR0)
760
      return;
761
   clear_reg(d);
762
   if (e[0])
763
      extname = e;
764
   else
765
      extname = ext_name(a.base);
766
   o = a.offset;
767
 
768
   if (a.base<0 )
769
   {
770
      p = plabel(a.base);
771
   }
772
   if (p)
773
   {
774
      if (PIC_code)
775
      {
776
	 ir_ins(i_ldil,fs_LP,extname,o,d);
777
	 ld_ir_ins(i_ldo,cmplt_,fs_RP,extname,o,d,d);
778
      }
779
      else
780
      {
781
	 ir_ins(i_ldil,fs_LP,extname,o,d);
782
	 ld_ir_ins(i_ldo,cmplt_,fs_RP,extname,o,d,d);
783
	 riir_ins(i_extru,c_eq,d,31,1,GR1);
784
	 ld_ir_ins(i_ldw,cmplt_,fs_,empty_ltrl,-4,GR27,GR1);
785
	 rrr_ins(i_add,c_,GR1,d,d);
786
      }
787
   }
788
   else
789
   {
790
      if (PIC_code)
791
      {
792
	 if (plusZ)
793
	 {
794
	    ir_ins(i_addil,fs_LT,extname,0,GR19);
795
	    ld_ir_ins(i_ldw,cmplt_,fs_RT,extname,0,GR1,o==0 ? d : GR1);
796
	 }
797
	 else
798
	 {
799
	    ld_ir_ins(i_ldw,cmplt_,fs_T,extname,0,GR19,o==0 ? d : GR1);
800
	 }
801
	 if (o)
802
	 {
803
	    if (SIMM14(o))
804
	       ld_ir_ins(i_ldo,cmplt_,fs_,empty_ltrl,o,GR1,d);
805
	    else
806
	    {
807
	       ir_ins(i_addil,fs_L,empty_ltrl,o,GR1);
808
	       ld_ir_ins(i_ldo,cmplt_,fs_R,empty_ltrl,o,GR1,d);
809
	    }
810
	 }
811
      }
812
      else
813
      {
814
	 char s[128];
815
	 sprintf(s,"%s-$global$",extname);
816
	 ir_ins(i_addil,fs_LR,s,o,GR27);
817
	 ld_ir_ins(i_ldo,cmplt_,fs_RR,s,o,GR1,d);
818
      }
819
   }
820
}
821
 
822
 
823
void ld_rr_ins
824
    PROTO_N ( (ins,cmplt,a,b,d) )
825
    PROTO_T ( ins_p ins X ins_p cmplt X int a X int b X int d )
826
{
827
   if (d==GR0)
828
      return;
829
   clear_reg(d);
830
   outp(ins,NOCOND,zops,NA);
831
   fprintf(outf,"\t%s%s\t%s(0,%s),%s\n",ins,cmplt,RN(a),RN(b),RN(d));
832
}
833
 
834
void ld_ins
835
    PROTO_N ( (ins,sgnd,a,d) )
836
    PROTO_T ( ins_p ins X int sgnd X baseoff a X int d )
837
{
838
   /* ins must be one of i_lb, i_lh, i_lo, i_lwm or i_lw */
839
   long o=a.offset;
840
   CONST char *i_ld;
841
   if (d==GR0)
842
      return;
843
   clear_reg(d);
844
   if (IS_FIXREG(a.base))
845
   {
846
      int b=a.base;
847
      i_ld=( ins==i_lb ? i_ldb : ( ins==i_lh ? i_ldh : ( ins==i_lo ? i_ldo : ( ins==i_lwm ? i_ldwm : i_ldw ) ) ) ) ;
848
      if (SIMM14(o))
849
	 ld_ir_ins(i_ld,cmplt_,fs_,empty_ltrl,o,b,d);
850
      else
851
      {
852
	 ir_ins(i_addil,fs_L,empty_ltrl,o,b);
853
	 ld_ir_ins(i_ld,cmplt_,fs_R,empty_ltrl,o,GR1,d);
854
      }
855
   }
856
   else
857
   {
858
      char *symb = ext_name(a.base);
859
      i_ld=( ins==i_lb ? i_ldb : ( ins==i_lh ? i_ldh : ( ins==i_lo ? i_ldo :  i_ldw ) ) ) ;
860
      if (globaldata((long)a.base))
861
      {
862
	 if (PIC_code)
863
	 {
864
	    if (plusZ)
865
	    {
866
	       ir_ins(i_addil,fs_LT,symb,0,GR19);
867
	       ld_ir_ins(i_ldw,cmplt_,fs_RT,symb,0,GR1,GR1);
868
	    }
869
	    else
870
	    {
871
	       ld_ir_ins(i_ldw,cmplt_,fs_T,symb,0,GR19,GR1);
872
	    }
873
	    if (SIMM14(o))
874
	       ld_ir_ins(i_ld,cmplt_,fs_,empty_ltrl,o,GR1,d);
875
	    else
876
	    {
877
	       ir_ins(i_addil,fs_L,empty_ltrl,o,GR1);
878
	       ld_ir_ins(i_ld,cmplt_,fs_R,empty_ltrl,o,GR1,d);
879
	    }
880
	 }
881
	 else
882
	 {
883
	    char s[128];
884
	    sprintf(s,"%s-$global$",symb);
885
	    ir_ins(i_addil,fs_LR,s,o,GR27);
886
	    ld_ir_ins(i_ld,cmplt_,fs_RR,s,o,GR1,d);
887
	    last_line=line;
888
	    strcpy(last_symb,symb);
889
	    last_o=o;
890
	 }
891
      }
892
      else
893
      {
894
	 ir_ins(i_ldil,fs_L,symb,o,GR1);
895
	 ld_ir_ins(i_ld,cmplt_,fs_R,symb,o,GR1,d);
896
      }
897
   }
898
   if (sgnd)
899
   {
900
      if (ins==i_lb)
901
	 riir_ins(i_extrs,c_,d,31,8,d);
902
      else if (ins==i_lh) /* would have to be, but just checking */
903
	 riir_ins(i_extrs,c_,d,31,16,d);
904
   }
905
}
906
 
907
 
908
 
909
/*
910
*   fixed point store instructions
911
 */
912
 
913
void st_ir_ins
914
    PROTO_N ( (ins,cmplt,s,fs,ltrl,l,b) )
915
    PROTO_T ( ins_p ins X ins_p cmplt X int s X ins_p fs X CONST char *ltrl X long l X int b )
916
{
917
    char O[128];
918
 
919
    /* build offset, i.e. field selector applied to literal+long */
920
    if (!(*ltrl))
921
       sprintf(O,"%s%ld",fs,l);
922
    else
923
    if (l>0)
924
       sprintf(O,"%s%s+%ld",fs,ltrl,l);
925
    else
926
    if (l<0)
927
       sprintf(O,"%s%s-%ld",fs,ltrl,-l);
928
    else
929
       sprintf(O,"%s%s",fs,ltrl);
930
 
931
    outp(ins,NOCOND,zops,NA);
932
    fprintf(outf,"\t%s%s\t%s,%s(%s)\n",ins,cmplt,RN(s),O,RN(b));
933
}
934
 
935
void st_ins
936
    PROTO_N ( (ins,s,a) )
937
    PROTO_T ( ins_p ins X int s X baseoff a )
938
{
939
   /* ins must be one of i_sb, i_sh or i_sw */
940
   long o=a.offset;
941
   CONST char *i_st;
942
 
943
   if (IS_FIXREG(a.base))
944
   {
945
      int b=a.base;
946
      i_st = ( ins == i_sb ? i_stb : ( ins == i_sh ? i_sth : i_stw ) );
947
      if (SIMM14(o))
948
	 st_ir_ins(i_st,cmplt_,s,fs_,empty_ltrl,o,b);
949
      else
950
      {
951
	 ir_ins(i_addil,fs_L,empty_ltrl,o,b);
952
	 st_ir_ins(i_st,cmplt_,s,fs_R,empty_ltrl,o,GR1);
953
      }
954
   }
955
   else
956
   {
957
      char *symb = ext_name(a.base);
958
      i_st = ( ins == i_sb ? i_stb : ( ins == i_sh ? i_sth : i_stw ) );
959
      if (globaldata((long)a.base))
960
      {
961
	 if (PIC_code)
962
	 {
963
	    if (plusZ)
964
	    {
965
	       ir_ins(i_addil,fs_LT,symb,0,GR19);
966
	       ld_ir_ins(i_ldw,cmplt_,fs_RT,symb,0,GR1,GR1);
967
	    }
968
	    else
969
	    {
970
	       ld_ir_ins(i_ldw,cmplt_,fs_T,symb,0,GR19,GR1);
971
	    }
972
	    if (SIMM14(o))
973
	       st_ir_ins(i_st,cmplt_,s,fs_,empty_ltrl,o,GR1);
974
	    else
975
	    {
976
	       ir_ins(i_addil,fs_L,empty_ltrl,o,GR1);
977
	       st_ir_ins(i_st,cmplt_,s,fs_R,empty_ltrl,o,GR1);
978
	    }
979
	 }
980
	 else
981
	 {
982
	    char litrl[128];
983
	    sprintf(litrl,"%s-$global$",symb);
984
	    if (last_line==line-1 && pCode[line-1]->ins==i_ldo && !strcmp(symb,last_symb) && last_o==o)
985
	    {
986
	       st_ir_ins(i_st,cmplt_,s,fs_R,litrl,o,GR1);
987
	    }
988
	    else
989
	    {
990
	       ir_ins(i_addil,fs_L,litrl,o,GR27);
991
	       st_ir_ins(i_st,cmplt_,s,fs_R,litrl,o,GR1);
992
	    }
993
	 }
994
      }
995
      else
996
      {
997
	 ir_ins(i_ldil,fs_L,symb,o,1);
998
	 st_ir_ins(i_st,cmplt_,s,fs_R,symb,o,GR1);
999
      }
1000
   }
1001
}
1002
 
1003
 
1004
void ldsid_in
1005
    PROTO_N ( ( s, b, t ) )
1006
    PROTO_T ( int s X int b X int t )
1007
{
1008
   clear_reg(t);
1009
   outp(i_ldsid,NOCOND,zops,NA);
1010
   fprintf(outf,"\tldsid\t(%s,%s),%s\n",SN(s),RN(b),RN(t));
1011
}
1012
 
1013
 
1014
void mtsp_in
1015
    PROTO_N ( ( r, sr ) )
1016
    PROTO_T ( int r X int sr )
1017
{
1018
   outp(i_mtsp,NOCOND,zops,NA);
1019
   fprintf(outf,"\tmtsp\t%s,%s\n",RN(r),SN(sr));
1020
}
1021
 
1022
 
1023
/******************************************************************************
1024
Branch instructions. These have labels as destination.
1025
******************************************************************************/
1026
 
1027
/*
1028
*   Unconditional branch.
1029
 */
1030
void ub_ins
1031
    PROTO_N ( ( cmplt, lab ) )
1032
    PROTO_T ( CONST char *cmplt X int lab )
1033
{
1034
    if (OPTIM)
1035
    {
1036
       int b;
1037
       b=outp(i_ub,NOCOND,zops,lab);
1038
       if (b)
1039
	  fprintf(outf,"%s",GAP);
1040
    }
1041
    else
1042
    {
1043
       fprintf(outf,"\tb%s\tL$$%d\n",cmplt,lab);
1044
       z_ins(i_nop);
1045
    }
1046
}
1047
 
1048
 
1049
/*
1050
*   Call instructions
1051
 */
1052
void bl_in
1053
    PROTO_N ( (n,target,t) )
1054
    PROTO_T ( ins_p n X char *target X int t )
1055
{
1056
   outp(i_bl,NOCOND,zops,NA);
1057
   fprintf(outf,"\tbl%s\t%s,%s\n",n,target,(t==RP ? "%rp" : RN(t)) );
1058
}
1059
 
1060
void ble_in
1061
    PROTO_N ( (n,wd,sr,b) )
1062
    PROTO_T ( ins_p n X char* wd X int sr X int b )
1063
{
1064
   outp(i_ble,NOCOND,zops,NA);
1065
   fprintf(outf,"\tble%s\t%s(%s,%s)\n",n,wd,SN(sr),RN(b));
1066
}
1067
 
1068
void call_ins
1069
    PROTO_N ( (n,target,t,stub) )
1070
    PROTO_T ( ins_p n X char *target X int t X char stub[128] )
1071
{
1072
   if (nexps<40872 /*62327*/)
1073
   {
1074
      out_directive(".CALL",stub);
1075
      bl_in(n,target,t);
1076
      z_ins(i_nop);
1077
   }
1078
   else
1079
   {
1080
      /*
1081
       * Module so large that bl is not guarenteed to reach start of
1082
       * subspace - must generate a long call sequence.
1083
       */
1084
      if (PIC_code)
1085
      {
1086
	 int n = next_PIC_pcrel_lab();
1087
	 char s[16];
1088
	 bl_in(cmplt_,".+",RP);
1089
	 sprintf(s,"%s-$PIC_pcrel$%d",target,n);
1090
	 ir_ins(i_addil,fs_L,s,4,RP);
1091
	 sprintf(s,"%s-$PIC_pcrel$%d",target,n+1);
1092
	 ld_ir_ins(i_ldo,cmplt_,fs_R,s,8,GR1,GR1);
1093
	 outlab("$PIC_pcrel$",n);
1094
	 ldsid_in(SR0,GR1,GR31);
1095
	 outlab("$PIC_pcrel$",n+1);
1096
	 mtsp_in(GR31,SR0);
1097
	 out_directive(".CALL",stub);
1098
	 ble_in(cmplt_,"0",SR0,GR1);
1099
	 rr_ins(i_copy,GR31,t);
1100
	 next_PIC_pcrel_lab();
1101
      }
1102
      else
1103
      {
1104
	 char wd[128];
1105
	 sprintf(wd,"%s%s",fs_R,target);
1106
	 ir_ins(i_ldil,fs_L,target,0,GR31);
1107
	 out_directive(".CALL",stub);
1108
	 ble_in(cmplt_,wd,SR4,GR31);
1109
	 rr_ins(i_copy,GR31,t);
1110
      }
1111
   }
1112
   if (PIC_code)
1113
      rr_ins(i_copy,GR5,GR19);
1114
}
1115
 
1116
 
1117
/*
1118
*   jump/call to compiler generated external identifier, eg .mulI
1119
 */
1120
void extj_special_ins
1121
    PROTO_N ( (nm,r,stub,import) )
1122
    PROTO_T ( CONST char *nm X int r X char stub[128] X int import )
1123
{
1124
   if (import)
1125
   {
1126
      char s[128];
1127
      sprintf(s,"%s,MILLICODE",nm);
1128
      out_directive(".IMPORT",s);
1129
   }
1130
   out_directive(".CALL",stub);
1131
   bl_in(cmplt_,(char*)nm,MRP);
1132
   rr_ins(i_copy,MRP,r);
1133
}
1134
 
1135
 
1136
/*
1137
*   jump/call to value of reg
1138
 */
1139
void extj_reg_ins
1140
    PROTO_N ( (ins,reg) )
1141
    PROTO_T ( ins_p ins X int reg )
1142
{
1143
   outp(i_bv,NOCOND,zops,NA);
1144
   fprintf(outf,"\tbv\t%%r0(%s)\n",RN(reg));
1145
}
1146
 
1147
 
1148
/*
1149
*   Conditional pseudo instructions.
1150
 */
1151
 
1152
void addb_in
1153
    PROTO_N ( (cond,l,d,lab) )
1154
    PROTO_T ( char *cond X int l X int d X int lab )
1155
{
1156
   int ops[4];
1157
   ops[0]=l;
1158
   ops[1]=d;
1159
   outp(i_addb,cond,ops,lab);
1160
   fprintf(outf,"\taddb%s,N\t%s,%s,L$$%d\n",cond,RN(l),RN(d),lab);
1161
   z_ins(i_nop);
1162
}
1163
 
1164
 
1165
void addib_in
1166
    PROTO_N ( (cond,i,d,lab) )
1167
    PROTO_T ( char *cond X int i X int d X int lab )
1168
{
1169
   int ops[4];
1170
   ops[0]=i;
1171
   ops[1]=d;
1172
   outp(i_addib,cond,ops,lab);
1173
   fprintf(outf,"\taddib%s,N\t%d,%s,L$$%d\n",cond,i,RN(d),lab);
1174
   z_ins(i_nop);
1175
}
1176
 
1177
 
1178
/*
1179
*   register comparisons
1180
 */
1181
void comb_ins
1182
    PROTO_N ( (cond,l,r,lab) )
1183
    PROTO_T ( CONST char *cond X int l X int r X int lab )
1184
{
1185
   int ops[4];
1186
   ops[0]=l;
1187
   ops[1]=r;
1188
   outp(i_comb,cond,ops,lab);
1189
   if (lab<0)
1190
      fprintf(outf,"\tcomb%s\t%s,%s,.+%d\n",cond,RN(l),RN(r),-lab);
1191
   else
1192
      fprintf(outf,"\tcomb%s\t%s,%s,L$$%d\n",cond,RN(l),RN(r),lab);
1193
}
1194
 
1195
 
1196
/*
1197
*   constant/register comparison
1198
 */
1199
void comib_ins
1200
    PROTO_N ( (cond,l,r,lab) )
1201
    PROTO_T ( ins_p cond X int l X int r X int lab )
1202
{
1203
   int ops[4];
1204
   ops[0]=l;
1205
   ops[1]=r;
1206
   outp(i_comib,cond,ops,lab);
1207
   if (lab<0)
1208
      fprintf(outf,"\tcomib%s\t%d,%s,.+%d\n",cond,l,RN(r),-lab);
1209
   else
1210
      fprintf(outf,"\tcomib%s\t%d,%s,L$$%d\n",cond,l,RN(r),lab);
1211
}
1212
 
1213
 
1214
void cj_ins
1215
    PROTO_N ( (cond,l,r,lab) )
1216
    PROTO_T ( CONST char *cond X int l X int r X int lab )
1217
{
1218
   int ops[4];
1219
   ops[0]=l;
1220
   ops[1]=r;
1221
   if (OPTIM)
1222
   {
1223
      outp(i_cj,cond,ops,lab);
1224
      fprintf(outf,"%s",GAP);
1225
   }
1226
   else
1227
   {
1228
      rrr_ins(i_comclr,opp(cond),l,r,0);
1229
      ub_ins(cmplt_,lab);
1230
   }
1231
}
1232
 
1233
 
1234
/*
1235
*   register, immediate comparison
1236
 */
1237
void cij_ins
1238
    PROTO_N ( (cond,l,r,lab) )
1239
    PROTO_T ( CONST char *cond X long l X int r X int lab )
1240
{
1241
   int ops[4];
1242
   ops[0]=l;
1243
   ops[1]=r;
1244
   if (SIMM5(l))
1245
   {
1246
      if (OPTIM)
1247
      {
1248
	 outp(i_cij,cond,ops,lab);
1249
	 fprintf(outf,"%s",GAP);
1250
      }
1251
      else
1252
      {
1253
	 irr_ins(i_comiclr,opp(cond),fs_,l,r,0);
1254
	 ub_ins(cmplt_,lab);
1255
      }
1256
   }
1257
   else
1258
   {
1259
      /* use temp reg for large constant */
1260
      if (r == GR1)
1261
	 /* should not happen */
1262
	 fail("ins: temp reg in use when needed for large constant");
1263
      else
1264
      {
1265
	 imm_to_r(l,GR1);
1266
	 if (OPTIM)
1267
	 {
1268
	    cj_ins(cond,GR1,r,lab);
1269
	 }
1270
	 else
1271
	 {
1272
	    rrr_ins(i_comclr,opp(cond),GR1,r,0);
1273
	    ub_ins(cmplt_,lab);
1274
	 }
1275
      }
1276
   }
1277
}
1278
 
1279
 
1280
/*
1281
*   Branch on bit.
1282
 */
1283
void bb_in
1284
    PROTO_N ( (cond,r,b,lab) )
1285
    PROTO_T ( ins_p cond X int r X int b X int lab )
1286
{
1287
   int ops[4];
1288
   ops[0]=r;
1289
   ops[1]=b;
1290
   outp(i_bb,cond,ops,lab);
1291
   fprintf(outf,"%s",GAP);
1292
}
1293
 
1294
 
1295
/*
1296
*   Floating point instructions.
1297
 */
1298
 
1299
 
1300
void ldf_ir_ins
1301
    PROTO_N ( (ins, o, b, d) )
1302
    PROTO_T ( ins_p ins X int o X int b X int d )
1303
{
1304
   clear_freg(d);
1305
   outp(ins,NOCOND,zops,NA);
1306
   fprintf(outf,"\t%s\t%d(%s),%s\n",ins,o,RN(b),FN(d));
1307
}
1308
 
1309
 
1310
void ldf_rr_ins
1311
    PROTO_N ( (ins, cmplt, a, b, d) )
1312
    PROTO_T ( ins_p ins X ins_p cmplt X int a X int b X int d )
1313
{
1314
   clear_freg(d);
1315
   outp(ins,NOCOND,zops,NA);
1316
   fprintf(outf,"\t%s%s\t%s(%s),%s\n",ins,cmplt,RN(a),RN(b),FN(d));
1317
}
1318
 
1319
 
1320
void ldf_ins
1321
    PROTO_N ( (ins, a, d) )
1322
    PROTO_T ( ins_p ins X baseoff a X int d )
1323
{
1324
   /* ins must be either i_fldw or i_fldd */
1325
   CONST char *i_fld = ( ins==i_fldw ? i_fldws : i_fldds );
1326
   if (IS_FIXREG(a.base))
1327
   {
1328
      if (SIMM5(a.offset))
1329
	 ldf_ir_ins(i_fld, a.offset, a.base, d);
1330
      else
1331
      {
1332
	 /* offset too big, put in temp reg and use ldf_ir_ins */
1333
	 /* +++ arrange stack variable to minimise this */
1334
	 assert(a.base != GR1);	/* otherwise we corrupt it */
1335
	 if (SIMM14(a.offset))
1336
	    ld_ir_ins(i_ldo,cmplt_,fs_,empty_ltrl,a.offset,a.base,GR1);
1337
	 else
1338
	 {
1339
	    ir_ins(i_addil,fs_L,empty_ltrl,a.offset,a.base);
1340
	    ld_ir_ins(i_ldo,cmplt_,fs_R,empty_ltrl,a.offset,GR1,GR1);
1341
	 }
1342
	 ldf_ir_ins(i_fld, 0, GR1, d);
1343
      }
1344
   }
1345
   else
1346
   {
1347
      /* global */
1348
      set_ins("",a,GR1);
1349
      ldf_ir_ins(i_fld, 0, GR1, d);
1350
   }
1351
}
1352
 
1353
 
1354
void stf_ir_ins
1355
    PROTO_N ( (ins, s, o, b) )
1356
    PROTO_T ( ins_p ins X int s X int o X int b )
1357
{
1358
   outp(ins,NOCOND,zops,NA);
1359
   fprintf(outf,"\t%s\t%s,%d(%s)\n",ins,FN(s),o,RN(b));
1360
}
1361
 
1362
 
1363
void stf_rr_ins
1364
    PROTO_N ( (ins, s, a, b) )
1365
    PROTO_T ( ins_p ins X int s X int a X int b )
1366
{
1367
   outp(ins,NOCOND,zops,NA);
1368
   fprintf(outf,"\t%s\t%s,%s(%s)\n",ins,FN(s),RN(a),RN(b));
1369
}
1370
 
1371
 
1372
void stf_ins
1373
    PROTO_N ( (ins, s, a) )
1374
    PROTO_T ( ins_p ins X int s X baseoff a )
1375
{
1376
   /* ins must be either i_fstw or i_fstd */
1377
 
1378
 
1379
   CONST char *i_fst = ( ins==i_fstw ? i_fstws : i_fstds );
1380
   if (IS_FIXREG(a.base))
1381
   {
1382
      if (SIMM5(a.offset))
1383
	 stf_ir_ins(i_fst, s, a.offset, a.base);
1384
      else
1385
      {
1386
	 /* offset too big, put in temp reg and use stf_ir_ins */
1387
	 /* +++ arrange stack variable to minimise this */
1388
	 assert(a.base != GR1);	/* otherwise we corrupt it */
1389
	 if (SIMM14(a.offset))
1390
	    ld_ir_ins(i_ldo,cmplt_,fs_,empty_ltrl,a.offset,a.base,GR1);
1391
	 else
1392
	 {
1393
	    ir_ins(i_addil,fs_L,empty_ltrl,a.offset,a.base);
1394
	    ld_ir_ins(i_ldo,cmplt_,fs_R,empty_ltrl,a.offset,GR1,GR1);
1395
	 }
1396
	 stf_ir_ins(i_fst, s, 0, GR1);
1397
      }
1398
   }
1399
   else
1400
   {
1401
      /* global */
1402
      set_ins("",a,GR1);
1403
      stf_ir_ins(i_fst, s, 0, GR1);
1404
   }
1405
}
1406
 
1407
 
1408
void cmp_rrf_ins
1409
    PROTO_N ( (ins, fmt, cond, a, b) )
1410
    PROTO_T ( ins_p ins X ins_p fmt X ins_p cond X int a X int b )
1411
{
1412
   outp(ins,NOCOND,zops,NA);
1413
   fprintf(outf,"\t%s%s%s\t%s,%s\n",ins,fmt,cond,FN(a),FN(b));
1414
}
1415
 
1416
void rrf_ins
1417
    PROTO_N ( (ins, from_fmt, to_fmt, a, b) )
1418
    PROTO_T ( ins_p ins X ins_p from_fmt X ins_p to_fmt X int a X int b )
1419
{
1420
   outp(ins,NOCOND,zops,NA);
1421
   fprintf(outf,"\t%s%s%s\t%s,%s\n",ins,from_fmt,to_fmt,FN(a),FN(b));
1422
}
1423
 
1424
 
1425
void rrrf_ins
1426
    PROTO_N ( (ins, fmt, a, b, dest) )
1427
    PROTO_T ( ins_p ins X ins_p fmt X int a X int b X int dest )
1428
{
1429
   clear_freg(dest);
1430
   fprintf(outf, "\t%s%s\t%s,%s,%s\n",ins,fmt,FN(a),FN(b),FN(dest));
1431
   outp(ins,NOCOND,zops,NA);
1432
}
1433
 
1434
 
1435
 
1436
 
1437
/*
1438
*   Directives
1439
 */
1440
void out_directive
1441
    PROTO_N ( (d,params) )
1442
    PROTO_T ( CONST char *d X CONST char *params )
1443
{
1444
  /* directive, parameters */
1445
   outp(directive,NOCOND,zops,NA);
1446
   fprintf(outf,"\t%s\t%s\n",d,params);
1447
}
1448
 
1449
 
1450
 
1451
/*
1452
*   Print a label
1453
 */
1454
void outlab
1455
    PROTO_N ( ( prefix, n ) )
1456
    PROTO_T ( char *prefix X int n )
1457
{
1458
    if (prefix[0]=='L' && prefix[1]=='$')
1459
       outp(i_lab,NOCOND,zops,n);
1460
    else
1461
       outp(i_,NOCOND,zops,NA);
1462
    fprintf(outf,"%s%d\n",prefix,n);
1463
}