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
    Copyright (c) 1993 Open Software Foundation, Inc.
3
 
4
 
5
    All Rights Reserved
6
 
7
 
8
    Permission to use, copy, modify, and distribute this software
9
    and its documentation for any purpose and without fee is hereby
10
    granted, provided that the above copyright notice appears in all
11
    copies and that both the copyright notice and this permission
12
    notice appear in supporting documentation.
13
 
14
 
15
    OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
16
    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17
    PARTICULAR PURPOSE.
18
 
19
 
20
    IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
21
    CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22
    LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
23
    NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
24
    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
*/
26
 
27
/*
28
    		 Crown Copyright (c) 1997
29
 
30
    This TenDRA(r) Computer Program is subject to Copyright
31
    owned by the United Kingdom Secretary of State for Defence
32
    acting through the Defence Evaluation and Research Agency
33
    (DERA).  It is made available to Recipients with a
34
    royalty-free licence for its use, reproduction, transfer
35
    to other parties and amendment for any purpose not excluding
36
    product development provided that any such use et cetera
37
    shall be deemed to be acceptance of the following conditions:-
38
 
39
        (1) Its Recipients shall ensure that this Notice is
40
        reproduced upon any copies or amended versions of it;
41
 
42
        (2) Any amended version of it shall be clearly marked to
43
        show both the nature of and the organisation responsible
44
        for the relevant amendment or amendments;
45
 
46
        (3) Its onward transfer from a recipient to another
47
        party shall be deemed to be that party's acceptance of
48
        these conditions;
49
 
50
        (4) DERA gives no warranty or assurance as to its
51
        quality or suitability for any purpose and DERA accepts
52
        no liability whatsoever in relation to any use to which
53
        it may be put.
54
*/
55
 
56
 
57
 
58
/**********************************************************************
59
$Author: release $
60
$Date: 1998/02/04 15:48:50 $
61
$Revision: 1.2 $
62
$Log: inst_fmt.c,v $
63
 * Revision 1.2  1998/02/04  15:48:50  release
64
 * Added OSF copyright message.
65
 *
66
 * Revision 1.1.1.1  1998/01/17  15:55:57  release
67
 * First version to be checked into rolling release.
68
 *
69
 * Revision 1.2  1996/10/04  16:01:25  pwe
70
 * add banners and mod for PWE ownership
71
 *
72
**********************************************************************/
73
 
74
 
75
/******************************************************************
76
		inst_formats.c
77
 
78
	Procs for outputting various POWER instruction formats to the
79
external file - as_file. Each procedure produces assembler for a family
80
of POWER operations, the actual member is passed as the string
81
understood by the assembler.
82
 
83
******************************************************************/
84
 
85
#include "config.h"
86
#include "geninst.h"
87
 
88
#include "proc.h"		
89
#include "myassert.h"
90
#include "flags.h"
91
#include "comment.h"
92
#include "translat.h"
93
#include "maxminmacs.h"		/* for absval() */
94
#include "stack.h"
95
#include "inst_fmt.h"
96
#include "macro.h"
97
#include "mask.h"
98
#define IS_POW2(c)		((c) != 0 && ((c) & ((c)-1)) == 0)
99
 
100
#define CHECKREG(r)		ASSERT(IS_FIXREG(r) && (!IS_SREG(r) || (r) >= p_sreg_first_save || (r == R_FP)) );
101
#define CHECKFREG(r)		ASSERT((!IS_FLT_SREG(r) || (r) >= p_sfreg_first_save));
102
 
103
extern FILE *as_file;
104
char * get_instruction PROTO_S ((Instruction_P));
105
 
106
char *ext_name PROTO_N ((id)) PROTO_T (long id)
107
{
108
  if (id < 0)
109
  {
110
    char *ext = main_globals[(-id) - 1]->dec_u.dec_val.dec_id;
111
 
112
    return ext;
113
  }
114
  else
115
  {
116
    static char sp[16];
117
 
118
    ASSERT(id > R_LAST);	/* not a confused register */
119
 
120
    sprintf(sp, "L.D%ld", id);
121
    return sp;
122
  }
123
}
124
 
125
/* +++ do better for offset to R_SP too big, trace reg or load extra base reg */
126
 
127
void ld_ro_ins PROTO_N ((ins,a,dest)) PROTO_T (Instruction_P ins X baseoff a X int dest)
128
{
129
  CHECKREG(dest); CHECKREG(a.base);
130
 
131
  clear_reg(dest);
132
 
133
  if (a.base == R_0)
134
  {
135
    /* base reg of R_0 is not normally allowed, special case 0 offset */
136
    if (a.offset != 0)
137
      fail("ld_ro_ins: non zero offset to R_0");
138
    /* with XXXx (indexed instructions) RA of R_0 is taken as constant 0 */
139
#ifdef DO_ASSEMBLER_MACROS
140
    fprintf(as_file, "\t%sx\t%s,%s,%s",get_instruction(ins),reg_macro(dest),reg_macro(R_0),reg_macro(R_0));
141
#else
142
    fprintf(as_file, "\t%sx\t%d,%d,%d", get_instruction(ins), dest, R_0, R_0);
143
#endif
144
  }
145
  else if (IMM_SIZE(a.offset))
146
  {
147
#ifdef DO_ASSEMBLER_MACROS
148
    fprintf(as_file, "\t%s\t%s,%d(%s)", get_instruction(ins), reg_macro(dest), (int)a.offset, reg_macro(a.base));
149
#else
150
    fprintf(as_file, "\t%s\t%d,%d(%d)", get_instruction(ins), dest, (int)a.offset, a.base);
151
#endif
152
  }
153
  else
154
  {
155
    /* offset too big, put in temp reg and used ld_rr_ins */
156
    /* +++ arrange stack variable to minimise this */
157
    ASSERT(a.base!=R_TMP0);
158
    ld_const_ins(a.offset, R_TMP0);
159
    ld_rr_ins(ins, a.base, R_TMP0, dest);
160
  }
161
}
162
 
163
 
164
void ld_rr_ins PROTO_N ((ins,reg1,reg2,dest)) PROTO_T (Instruction_P ins X int reg1 X int reg2 X int dest)
165
{
166
  CHECKREG(dest); CHECKREG(reg1); CHECKREG(reg2);
167
  ASSERT(reg1!=R_0);
168
 
169
  clear_reg(dest);
170
#ifdef DO_ASSEMBLER_MACROS
171
  fprintf(as_file, "\t%sx\t%s,%s,%s\n", get_instruction(ins), reg_macro(dest), reg_macro(reg1), reg_macro(reg2));
172
#else
173
  fprintf(as_file, "\t%sx\t%d,%d,%d\n", get_instruction(ins), dest, reg1, reg2);
174
#endif
175
}
176
 
177
 
178
void set_ins PROTO_N ((a,dest)) PROTO_T (baseoff a X int dest)
179
{
180
  char *extname = ext_name(a.base);
181
 
182
  CHECKREG(dest);
183
 
184
  clear_reg(dest);
185
#ifdef DO_ASSEMBLER_MACROS
186
  fprintf(as_file, "\t%s\t%s,T.%s(%s)\n", get_instruction(i_l), reg_macro(dest), extname, reg_macro(R_TOC));
187
#else
188
  fprintf(as_file, "\t%s\t%d,T.%s(%d)\n", get_instruction(i_l), dest, extname, R_TOC);
189
#endif
190
  /* +++ offsets in TOC */
191
  if (a.offset != 0)
192
    rir_ins(i_a, dest, a.offset, dest);
193
}
194
 
195
 
196
void ld_ins PROTO_N ((ins,a,dest)) PROTO_T (Instruction_P ins X baseoff a X int dest)
197
{
198
  /*
199
   * Not a single instruction. Load from baseoff, which may be a global
200
   * requiring a temporary reg.
201
   */
202
 
203
  CHECKREG(dest);
204
 
205
  if (!IS_FIXREG(a.base))
206
  {
207
    /* global */
208
    baseoff tmp_off;
209
 
210
    FULLCOMMENT2("ld_ins ext: off=%#x -> r%d", a.offset, dest);
211
    ASSERT(a.offset==0 || dest!=R_TMP0);
212
 
213
    /* load base into dest reg, then let ld_ro_ins do offset (which may need R_TMP0) */
214
    tmp_off.base = a.base;
215
    tmp_off.offset = 0;
216
 
217
    set_ins(tmp_off, dest);
218
 
219
    tmp_off.base = dest;
220
    tmp_off.offset = a.offset;
221
 
222
    ld_ro_ins(ins, tmp_off, dest);comment(NIL);
223
  }
224
  else
225
  {
226
    ld_ro_ins(ins, a, dest);comment(NIL);
227
  }
228
}
229
 
230
 
231
void st_ro_ins PROTO_N ((ins,src,a)) PROTO_T (Instruction_P ins X int src X baseoff a)
232
{
233
  CHECKREG(src); CHECKREG(a.base);
234
 
235
 
236
  /* in general we cannot cope with store using temp reg, catch it always */
237
  if ((src == R_TMP0 || a.base == R_TMP0) && absval(a.offset) > (16 + 1 + 6) * 4)	/* leeway for mem_temp() */
238
    fail("st_ro_ins: store of temp reg to offset not allowed");	/* should not happen */
239
 
240
  if (a.base == R_0)
241
  {
242
    if (a.offset != 0)
243
      fail("st_ro_ins: non zero offset to R_0");
244
    /* with XXXx (indexed instructions) RA of R_0 is taken as constant 0 */
245
#ifdef DO_ASSEMBLER_MACROS
246
    fprintf(as_file, "\t%sx\t%s,%s,%s", get_instruction(ins), reg_macro(src), reg_macro(R_0), reg_macro(R_0));
247
#else
248
    fprintf(as_file, "\t%sx\t%d,%d,%d", get_instruction(ins), src, R_0, R_0);
249
#endif
250
  }
251
  else if (IMM_SIZE(a.offset))
252
  {
253
#ifdef DO_ASSEMBLER_MACROS
254
    fprintf(as_file, "\t%s\t%s,%d(%s)", get_instruction(ins), reg_macro(src), (int)a.offset, reg_macro(a.base));
255
#else
256
    fprintf(as_file, "\t%s\t%d,%d(%d)", get_instruction(ins), src, (int)a.offset, a.base);
257
#endif
258
  }
259
  else
260
  {
261
    /* offset too big, put in temp reg and used st_rr_ins */
262
    /* +++ arrange stack variable to minimise this */
263
    COMMENT("st_ro_ins: big offset, use temp reg and st_rr_ins");
264
    ASSERT(a.base!=R_TMP0);		/* otherwise we corrupt it */
265
    ld_const_ins(a.offset, R_TMP0);
266
    st_rr_ins(ins, src, a.base, R_TMP0);
267
  }
268
}
269
 
270
 
271
void st_rr_ins PROTO_N ((ins,src,reg1,reg2)) PROTO_T (Instruction_P ins X int src X int reg1 X int reg2)
272
{
273
  CHECKREG(src); CHECKREG(reg1); CHECKREG(reg2);
274
  ASSERT(reg1!=R_0);
275
#ifdef DO_ASSEMBLER_MACROS
276
  fprintf(as_file, "\t%sx\t%s,%s,%s\n", get_instruction(ins), reg_macro(src), reg_macro(reg1), reg_macro(reg2));
277
#else
278
  fprintf(as_file, "\t%sx\t%d,%d,%d\n", get_instruction(ins), src, reg1, reg2);
279
#endif
280
}
281
 
282
 
283
void st_ins PROTO_N ((ins,src,a)) PROTO_T (Instruction_P ins X int src X baseoff a)
284
{
285
  /*
286
   * Not a single instruction. Store into baseoff, which may be a global
287
   * requiring a temporary reg.
288
   */
289
 
290
  CHECKREG(src);
291
 
292
  if (!IS_FIXREG(a.base))
293
  {
294
    /* global */
295
    baseoff tmp_off;
296
 
297
    if (src == R_TMP0)
298
      fail("st_ins: store of temp reg to global not allowed");	/* should not happen */
299
 
300
    tmp_off.base = R_TMP0;
301
    tmp_off.offset = 0;
302
 
303
    set_ins(a, R_TMP0);
304
    st_ro_ins(ins, src, tmp_off);comment(NIL);
305
  }
306
  else
307
  {
308
    st_ro_ins(ins, src, a);comment(NIL);
309
  }
310
}
311
 
312
 
313
/* 3 register operand instructions, source1, source2, destination */
314
void rrr_ins PROTO_N ((ins,src1,src2,dest)) PROTO_T (Instruction_P ins X int src1 X int src2 X int dest)
315
{
316
  CHECKREG(dest); CHECKREG(src1); CHECKREG(src2);
317
 
318
  clear_reg(dest);
319
 
320
  /* i_s is a pseudo instruction, use i_sf with reversed ops */
321
  if (ins == i_s)
322
  {
323
#ifdef DO_ASSEMBLER_MACROS
324
    fprintf(as_file, "\t%s\t%s,%s,%s\n", get_instruction(i_sf), reg_macro(dest), reg_macro(src2), reg_macro(src1));
325
#else
326
    fprintf(as_file, "\t%s\t%d,%d,%d\n", get_instruction(i_sf), dest, src2, src1);
327
#endif
328
  }
329
  else
330
  {
331
#ifdef DO_ASSEMBLER_MACROS
332
    fprintf(as_file, "\t%s\t%s,%s,%s\n", get_instruction(ins), reg_macro(dest), reg_macro(src1), reg_macro(src2));
333
#else
334
    fprintf(as_file, "\t%s\t%d,%d,%d\n", get_instruction(ins), dest, src1, src2);
335
#endif
336
  }
337
 
338
}
339
 
340
 
341
/* source register, immediate, destination register instructions */
342
 
343
void rir_ins PROTO_N ((ins,src,imm,dest)) PROTO_T (Instruction_P ins X int src X long imm X int dest)
344
{
345
  bool logical = ins == i_and || ins == i_or || ins == i_xor|| 
346
    ins ==i_and_cr|| ins==i_or_cr || ins==i_xor_cr;
347
 
348
  CHECKREG(dest); CHECKREG(src);
349
  ASSERT(ins!=i_divs&&ins!=i_div);	/* no divi, so we should not be called for div */
350
 
351
  /*
352
   * Check agaonst IBM assembler bug which we should avoid at higher levels:
353
   * IX25505 bosadt : SRI 30,29,0 DOES NOT ASSEMBLE CORRECTLY
354
   */
355
  ASSERT(!(ins==i_sr && imm==0));
356
 
357
  clear_reg(dest);
358
 
359
  if (!logical && IMM_SIZE(imm))
360
  {
361
    Instruction_P imins;
362
    if      (ins==i_a)       imins=i_ai;
363
    else if (ins==i_a_cr)    imins=i_ai_cr;
364
    else if (ins==i_sf)      imins=i_sfi;
365
    else if (ins==i_sl)      imins=i_sli;
366
    else if (ins==i_sl_cr)   imins=i_sli_cr;
367
    else if (ins==i_sr)      imins=i_sri;
368
    else if (ins==i_sr_cr)   imins=i_sri_cr;
369
    else if (ins==i_sra)     imins=i_srai;
370
    else if (ins==i_sra_cr)  imins=i_srai_cr;
371
    else if (ins==i_muls)    imins=i_muli;
372
    else
373
    {
374
      printf("Unknown immediate instruction for %s\n",get_instruction(ins));
375
      imins=ins;    
376
    }
377
 
378
#ifdef DO_ASSEMBLER_MACROS 
379
    fprintf(as_file,"\t%s\t%s,%s,%ld\n",get_instruction(imins), reg_macro(dest), reg_macro(src), imm);
380
#else
381
    fprintf(as_file,"\t%s\t%d,%d,%ld\n",get_instruction(imins), dest, src, imm);
382
#endif
383
 
384
    return;
385
  }
386
 
387
  if (ins == i_a && IMMLOGU_SIZE(imm))
388
  {
389
    unsigned long uimm = imm;
390
#ifdef DO_ASSEMBLER_MACROS
391
    fprintf(as_file, "\t%s\t%s,%s,%ld\n", get_instruction(i_cau), reg_macro(dest), reg_macro(src), uimm >> 16);
392
#else
393
    fprintf(as_file, "\t%s\t%d,%d,%ld\n", get_instruction(i_cau), dest, src, uimm >> 16);
394
#endif
395
    return;
396
  }
397
 
398
  if ((ins == i_a || ins == i_s) && IMM_SIZE((imm/2)+1) && dest != R_SP)
399
  {
400
    COMMENT1("rir_ins: special casing add/sub of constant %ld", imm);
401
    if (ins == i_s && imm == 0x8000)
402
    {
403
      /* use -0x8000 as imm, which is immediate */
404
      rir_ins(i_a, src, -imm, dest);
405
    }
406
    else
407
    {
408
      /* use 2 adds or subs */
409
      long half = imm / 2;
410
 
411
      rir_ins(ins, src, half, dest);
412
      rir_ins(ins, dest, imm - half, dest);
413
    }
414
    return;
415
  }
416
 
417
  if (ins == i_and)
418
  {
419
    /*
420
     * See if we can use rlinm instruction, ie a single series of one bits.
421
     * This is prefered to generating an andiX. below, which may cause
422
     * a CR delay.
423
     */
424
    unsigned long x = imm;
425
 
426
    ASSERT(x != 0);		/* should be handled above */
427
    if (is_a_mask(x) || is_a_mask(~x))
428
    {
429
      COMMENT1("rir_ins: special casing and of constant %#lx", imm);
430
#ifdef DO_ASSEMBLER_MACROS
431
      fprintf(as_file, "\t%s\t%s,%s,0,0x%lx\n", get_instruction(i_rlinm), reg_macro(dest), reg_macro(src), imm);
432
#else
433
      fprintf(as_file, "\t%s\t%d,%d,0,0x%lx\n", get_instruction(i_rlinm), dest, src, imm);
434
#endif
435
      return;
436
    }
437
  }
438
  if (ins == i_and_cr)
439
  {
440
    /*
441
     * See if we can use rlinm instruction, ie a single series of one bits.
442
     * This is prefered to generating an andiX. below, which may cause
443
     * a CR delay.
444
     */
445
    unsigned long x = imm;
446
 
447
    ASSERT(x != 0);		/* should be handled above */
448
    if (is_a_mask(x) || is_a_mask(~x))
449
    {
450
      COMMENT1("rir_ins: special casing and of constant %#lx", imm);
451
#ifdef DO_ASSEMBLER_MACROS
452
      fprintf(as_file, "\t%s\t%s,%s,0,0x%lx\n", get_instruction(i_rlinm_cr), reg_macro(dest), reg_macro(src), imm);
453
#else
454
      fprintf(as_file, "\t%s\t%d,%d,0,0x%lx\n", get_instruction(i_rlinm_cr), dest, src, imm);
455
#endif
456
      return;
457
    }
458
  }
459
 
460
 
461
  if (logical && IMMLOGL_SIZE(imm))  /* Lower 16 bit load */
462
  {
463
    Instruction_P ilins;
464
    if      (ins==i_and)  ilins = i_andil_cr;
465
    else if (ins==i_or)   ilins = i_oril;
466
    else if (ins==i_xor)  ilins = i_xoril;
467
    else if (ins==i_and_cr) ilins = i_andil_cr;
468
    else fail("Should never reach here");
469
#ifdef DO_ASSEMBLER_MACROS
470
    fprintf(as_file, "\t%s\t%s,%s,%ld\n", get_instruction(ilins), reg_macro(dest), reg_macro(src), imm);
471
#else
472
    fprintf(as_file, "\t%s\t%d,%d,%ld\n", get_instruction(ilins), dest, src, imm);
473
#endif
474
    return;
475
  }
476
 
477
  if (logical && IMMLOGU_SIZE(imm))  /* Upper 16 bit load */ 
478
  {
479
    unsigned long uimm = imm;
480
    Instruction_P iuins;
481
    if      (ins==i_and)  iuins = i_andiu_cr;
482
    else if (ins==i_or)   iuins = i_oriu;
483
    else if (ins==i_xor)  iuins = i_xoriu;
484
    else if (ins==i_and_cr) iuins = i_andiu_cr;
485
    else fail("Should never reach here");
486
#ifdef DO_ASSEMBLER_MACROS
487
    fprintf(as_file, "\t%s\t%s,%s,%ld\n",get_instruction(iuins), reg_macro(dest), reg_macro(src), uimm >> 16);
488
#else
489
    fprintf(as_file, "\t%s\t%d,%d,%ld\n",get_instruction(iuins), dest, src, uimm >> 16);
490
#endif
491
    return;
492
  }
493
 
494
  if (ins == i_or)
495
  {
496
    /* or lower and then upper end */
497
    unsigned long uimm = imm;
498
#ifdef DO_ASSEMBLER_MACROS
499
    fprintf(as_file, "\t%s\t%s,%s,0x%lx\n", get_instruction(i_oril), reg_macro(dest), reg_macro(src), uimm & 0xffff);
500
    fprintf(as_file, "\t%s\t%s,%s,0x%lx\n", get_instruction(i_oriu), reg_macro(dest), reg_macro(dest), uimm >> 16);
501
#else
502
    fprintf(as_file, "\t%s\t%d,%d,0x%lx\n", get_instruction(i_oril), dest, src, uimm & 0xffff);
503
    fprintf(as_file, "\t%s\t%d,%d,0x%lx\n", get_instruction(i_oriu), dest, dest, uimm >> 16);
504
#endif
505
 
506
    return;
507
  }
508
 
509
  /* default: use temp reg for large constant */
510
  COMMENT("rir_ins: large constant in R_TMP0");
511
  if (src == R_TMP0)
512
    fail("rir_ins: temp reg in use when needed for large constant");	/* should not happen */
513
  ld_const_ins(imm, R_TMP0);
514
  rrr_ins(ins, src, R_TMP0, dest);
515
}
516
 
517
/* register to register pseudo instruction */
518
void rr_ins PROTO_N ((ins,src,dest)) PROTO_T (Instruction_P ins X int src X int dest)
519
{
520
  CHECKREG(dest); CHECKREG(src);
521
 
522
  clear_reg(dest);
523
  if (ins == i_not)
524
    rir_ins(i_sf, src, -1, dest);		/* implements monadic not */
525
  else
526
#ifdef DO_ASSEMBLER_MACROS
527
    fprintf(as_file, "\t%s\t%s,%s\n", get_instruction(ins), reg_macro(dest), reg_macro(src));
528
#else
529
    fprintf(as_file, "\t%s\t%d,%d\n", get_instruction(ins), dest, src);
530
#endif
531
}
532
 
533
 
534
 
535
/* mov fixed point reg to another */
536
void mov_rr_ins PROTO_N ((src,dest)) PROTO_T (int src X int dest)
537
{
538
  CHECKREG(dest); CHECKREG(src);
539
 
540
  if (src != dest)
541
  {
542
    clear_reg(dest);
543
    /* move by i_oril of src with 0 to dest */
544
#ifdef DO_ASSEMBLER_MACROS
545
    fprintf(as_file, "\t%s\t%s,%s,%d", get_instruction(i_oril), reg_macro(dest), reg_macro(src), 0);
546
#else
547
    fprintf(as_file, "\t%s\t%d,%d,%d", get_instruction(i_oril), dest, src, 0);
548
#endif
549
  }
550
}
551
 
552
 
553
/* load const into fixed point reg */
554
void ld_const_ins PROTO_N ((imm,dest)) PROTO_T (long imm X int dest)
555
{
556
  CHECKREG(dest);
557
 
558
  clear_reg(dest);
559
 
560
  if (IMM_SIZE(imm))
561
  {
562
#ifdef DO_ASSEMBLER_MACROS
563
    fprintf(as_file, "\t%s\t%s,%ld\n", get_instruction(i_lil), reg_macro(dest), imm);
564
#else
565
    fprintf(as_file, "\t%s\t%d,%ld\n", get_instruction(i_lil), dest, imm);
566
#endif
567
  }
568
  else
569
  {
570
    unsigned long uimm = imm;
571
    unsigned long uimml = uimm & 0xffff;
572
 
573
    /* load upper 16 bits */
574
#ifdef DO_ASSEMBLER_MACROS
575
    fprintf(as_file, "\t%s\t%s,0x%lx\n",get_instruction(i_liu), reg_macro(dest), uimm >> 16);
576
#else
577
    fprintf(as_file, "\t%s\t%d,0x%lx\n",get_instruction(i_liu), dest, uimm >> 16);
578
#endif
579
    /* or in lower 16 bits if needed */
580
    if (uimml != 0)
581
    {
582
#ifdef DO_ASSEMBLER_MACROS
583
      fprintf(as_file, "\t%s\t%s,%s,0x%lx\n", get_instruction(i_oril), reg_macro(dest), reg_macro(dest), uimml);
584
#else
585
      fprintf(as_file, "\t%s\t%d,%d,0x%lx\n", get_instruction(i_oril), dest, dest, uimml);
586
#endif
587
    }
588
  }
589
}
590
 
591
 
592
/* move from branch unit to fixed point reg */
593
void mf_ins PROTO_N ((ins,dest)) PROTO_T (Instruction_P ins X int dest)
594
{
595
  if (ins !=i_mffs)
596
  {
597
    CHECKREG(dest);
598
    clear_reg(dest);
599
  }
600
  else 
601
  {
602
    CHECKFREG(dest);
603
    clear_freg(dest);
604
  }
605
#ifdef DO_ASSEMBLER_MACROS
606
  fprintf(as_file, "\t%s\t%s\n", get_instruction(ins), reg_macro(dest));
607
#else
608
  fprintf(as_file, "\t%s\t%d\n", get_instruction(ins), dest);
609
#endif
610
}
611
 
612
/* move to branch unit from fixed point reg */
613
void mt_ins PROTO_N ((ins,src)) PROTO_T (Instruction_P ins X int src)
614
{
615
  CHECKREG(src);
616
#ifdef DO_ASSEMBLER_MACROS
617
  fprintf(as_file, "\t%s\t%s\n", get_instruction(ins), reg_macro(src));
618
#else
619
  fprintf(as_file, "\t%s\t%d\n", get_instruction(ins), src);
620
#endif
621
}
622
 
623
 
624
 
625
/* zeroadic pseudo instruction */
626
void z_ins PROTO_N ((ins)) PROTO_T (Instruction_P ins)
627
{
628
  fprintf(as_file, "\t%s\n", get_instruction(ins));
629
}
630
 
631
 
632
/******************************************************************************
633
Branch instructions. These have labels as destination.
634
******************************************************************************/
635
 
636
/* unconditional branch */
637
void uncond_ins PROTO_N ((ins,lab)) PROTO_T (Instruction_P ins X int lab)
638
{
639
  fprintf(as_file, "\t%s\tL.%d\n", get_instruction(ins), lab);
640
}
641
 
642
 
643
 
644
 
645
/*
646
 * Call, and external jump instructions.
647
 */
648
 
649
/* jump/call to external identifier */
650
void extj_ins PROTO_N ((ins,b)) PROTO_T (Instruction_P ins X baseoff b)
651
{
652
  char *ext;
653
 
654
  FULLCOMMENT1("extj_ins: global proc no=%d", (-b.base) - 1);
655
  ASSERT(((-b.base)-1)>=0);
656
 
657
  ext = main_globals[(-b.base) - 1]->dec_u.dec_val.dec_id;
658
 
659
  fprintf(as_file, "\t%s\t.%s\n", get_instruction(ins), ext);
660
 
661
  /*
662
   * By convention a special no-op is generated after a call,
663
   * which the linker changes to reload our TOC reg (2) if the
664
   * call is inter-module.
665
   *
666
   * We optimise by omitting the no-op where we know the call is intra-module.
667
   */
668
  if (diagnose || !main_globals[(-b.base)-1]->dec_u.dec_val.have_def)
669
  {
670
    fprintf(as_file, "\t%s\t%d,%d,%d\n", get_instruction(i_cror), 15, 15, 15);	/* conventional nop */
671
  }
672
 
673
}
674
 
675
/* jump/call to compiler generated external identifier, eg .mul */
676
void extj_special_ins PROTO_N ((ins,nm)) PROTO_T (Instruction_P ins X char *nm)
677
{
678
  fprintf(as_file, "\t%s\t%s\n", get_instruction(ins), nm);
679
  fprintf(as_file, "\t%s\t%d,%d,%d\n", get_instruction(i_cror), 15, 15, 15);	/* conventional nop */
680
}
681
 
682
 
683
/*
684
 * Conditional instructions.
685
 */
686
 
687
/* branch conditional instruction */
688
void bc_ins PROTO_N ((ins,creg,lab,prediction)) PROTO_T (Instruction_P ins X int creg X int lab X int prediction)
689
{
690
  if(architecture == POWERPC_CODE)
691
  {
692
 
693
    int BI;
694
    int BO;
695
    BI=creg*4;
696
 
697
    if (ins==i_ble)
698
    {
699
      BO  = 4;
700
      BI += 1;
701
    }
702
    else if (ins ==i_blt)
703
    {
704
      BO  = 12;
705
      BI += 0;
706
    }
707
    else if (ins == i_bge)
708
    {
709
      BO  = 4 ;
710
      BI += 0;
711
    } 
712
    else if (ins == i_bgt)
713
    {
714
      BO  = 12;
715
      BI += 1;
716
    }
717
    else if(ins == i_bne)
718
    {
719
      BO  = 4;
720
      BI += 2;
721
    }
722
    else if (ins == i_beq)
723
    {
724
      BO  = 12;
725
      BI += 2;
726
    }
727
    else 
728
    {
729
      fprintf(as_file,"\t%s\t%d,L.%d\n",get_instruction(ins),creg,lab);
730
      return;
731
    }
732
    if(prediction)
733
    {
734
      BO+=1;
735
    }
736
    fprintf(as_file,"\t%s\t%d,%d,L.%d\n",get_instruction(i_bc),BO,BI,lab);
737
  }
738
  else
739
  {
740
#ifdef DO_ASSEMBLER_MACROS
741
    fprintf(as_file,"\t%s\t%s,L.%d\n",get_instruction(ins),cr_macro(creg),lab);
742
#else
743
    fprintf(as_file,"\t%s\t%d,L.%d\n",get_instruction(ins),creg,lab);
744
#endif
745
  }
746
}
747
/* branch conditional instruction */
748
void long_bc_ins PROTO_N ((ins,creg,lab,prediction)) PROTO_T (Instruction_P ins X int creg X int lab X int prediction)
749
{
750
  /* same as bc_ins only the test is reversed so that the lab is called directly so that there is no chance of the branch being out of range */
751
 
752
  long new_lab = lab;
753
  lab = new_label();
754
  if      (ins==i_blt){ins = i_bge;}
755
  else if (ins==i_ble){ins = i_bgt;}
756
  else if (ins==i_bne){ins = i_beq;}
757
  else if (ins==i_beq){ins = i_bne;}
758
  else if (ins==i_bgt){ins = i_ble;}
759
  else if (ins==i_bge){ins = i_blt;}
760
  else if (ins==i_bso){ins = i_bns;}
761
  else if (ins==i_bns){ins = i_bso;}
762
  else
763
  {
764
    fail("Don't know how to reverse this test");
765
  }
766
 
767
  if(architecture == POWERPC_CODE)
768
  {
769
 
770
    int BI;
771
    int BO;
772
    BI=creg*4;
773
 
774
    if (ins==i_ble)
775
    {
776
      BO  = 4;
777
      BI += 1;
778
    }
779
    else if (ins ==i_blt)
780
    {
781
      BO  = 12;
782
      BI += 0;
783
    }
784
    else if (ins == i_bge)
785
    {
786
      BO  = 4 ;
787
      BI += 0;
788
    } 
789
    else if (ins == i_bgt)
790
    {
791
      BO  = 12;
792
      BI += 1;
793
    }
794
    else if(ins == i_bne)
795
    {
796
      BO  = 4;
797
      BI += 2;
798
    }
799
    else if (ins == i_beq)
800
    {
801
      BO  = 12;
802
      BI += 2;
803
    }
804
    else 
805
    {
806
      fprintf(as_file,"\t%s\t%d,L.%d\n",get_instruction(ins),creg,lab);
807
      uncond_ins(i_b,new_lab);
808
      set_label(lab);
809
      return;
810
    }
811
    if(prediction)
812
    {
813
      BO+=1;
814
    }
815
    fprintf(as_file,"\t%s\t%d,%d,L.%d\n",get_instruction(i_bc),BO,BI,lab);
816
    uncond_ins(i_b,new_lab);
817
    set_label(lab);
818
    return;
819
  }
820
  else
821
  {
822
#ifdef DO_ASSEMBLER_MACROS
823
    fprintf(as_file,"\t%s\t%s,L.%d\n",get_instruction(ins),cr_macro(creg),lab);
824
#else
825
    fprintf(as_file,"\t%s\t%d,L.%d\n",get_instruction(ins),creg,lab);
826
 
827
#endif
828
    uncond_ins(i_b,new_lab);
829
    set_label(lab);
830
    return;
831
  }
832
}
833
 
834
 
835
/* cmp or cmpl instruction */
836
void cmp_rr_ins PROTO_N ((ins,reg1,reg2,cr_dest)) PROTO_T (Instruction_P ins X int reg1 X int reg2 X int cr_dest)
837
{
838
  CHECKREG(reg1); CHECKREG(reg2);
839
#ifdef DO_ASSEMBLER_MACROS
840
  fprintf(as_file, "\t%s\t%s,%s,%s\n", get_instruction(ins), cr_macro(cr_dest), reg_macro(reg1), reg_macro(reg2));
841
#else
842
  fprintf(as_file, "\t%s\t%d,%d,%d\n", get_instruction(ins), cr_dest, reg1, reg2);
843
#endif
844
}
845
 
846
 
847
/* for cmpi or cmpli instruction */
848
void cmp_ri_ins PROTO_N ((ins,reg,imm,cr_dest)) PROTO_T (Instruction_P ins X int reg X long imm X int cr_dest)
849
{
850
  CHECKREG(reg);
851
 
852
  /* +++ for equality can use cmpi or cmpli for larger constant range */
853
  if (ins == i_cmp && IMM_SIZE(imm))
854
  {
855
#ifdef DO_ASSEMBLER_MACROS
856
    fprintf(as_file, "\t%si\t%s,%s,%ld\n", get_instruction(ins), cr_macro(cr_dest), reg_macro(reg), imm);
857
#else
858
    fprintf(as_file, "\t%si\t%d,%d,%ld\n", get_instruction(ins), cr_dest, reg, imm);
859
#endif
860
  }
861
  else if (ins == i_cmpl && IMMLOGL_SIZE(imm))
862
  {
863
#ifdef DO_ASSEMBLER_MACROS
864
    fprintf(as_file, "\t%si\t%s,%s,%ld\n", get_instruction(ins), cr_macro(cr_dest), reg_macro(reg), imm);
865
#else
866
    fprintf(as_file, "\t%si\t%d,%d,%ld\n", get_instruction(ins), cr_dest, reg, imm);
867
#endif
868
  }
869
  else
870
  {
871
    /* use temp reg for large constant */
872
    COMMENT("condri_ins: large constant in R_TMP0");
873
    if (reg == R_TMP0)
874
      fail("cmp_ri_ins: temp reg in use when needed for large constant");	/* should not happen */
875
    ld_const_ins(imm, R_TMP0);
876
    cmp_rr_ins(ins, reg, R_TMP0, cr_dest);
877
  }
878
}
879
 
880
 
881
 
882
 
883
/*
884
 * Floating point instructions.
885
 */
886
 
887
void ldf_ro_ins PROTO_N ((ins,a,dest)) PROTO_T (Instruction_P ins X baseoff a X int dest)
888
{
889
  CHECKREG(a.base); CHECKFREG(dest);
890
 
891
  clear_freg(dest);
892
 
893
  if (a.base == R_0)
894
  {
895
    if (a.offset != 0)
896
      fail("ldf_ro_ins: non zero offset to R_0");
897
    /* with XXXx (indexed instructions) RA of R_0 is taken as constant 0 */
898
#ifdef DO_ASSEMBLER_MACROS
899
    fprintf(as_file, "\t%sx\t%s,%s,%s\n", get_instruction(ins), freg_macro(dest), reg_macro(R_0), reg_macro(R_0));
900
#else
901
    fprintf(as_file, "\t%sx\t%d,%d,%d\n", get_instruction(ins), dest, R_0, R_0);
902
#endif
903
  }
904
  else
905
  if (IMM_SIZE(a.offset))
906
  {
907
#ifdef DO_ASSEMBLER_MACROS
908
    fprintf(as_file, "\t%s\t%s,%d(%s)\n", get_instruction(ins), freg_macro(dest), (int)a.offset, reg_macro(a.base));
909
#else
910
    fprintf(as_file, "\t%s\t%d,%d(%d)\n", get_instruction(ins), dest, (int)a.offset, a.base);
911
#endif
912
  }
913
  else
914
  {
915
    /* offset too big, put in temp reg and used ld_rr_ins */
916
    /* +++ arrange stack variable to minimise this */
917
    COMMENT("ldf_ro_ins: big offset, use R_TMP0 and ldf_rr_ins");
918
    ASSERT(a.base!=R_TMP0);		/* otherwise we corrupt it */
919
    ld_const_ins(a.offset, R_TMP0);
920
    ldf_rr_ins(ins, a.base, R_TMP0, dest);
921
  }
922
}
923
 
924
 
925
void ldf_rr_ins PROTO_N ((ins,reg1,reg2,dest)) PROTO_T (Instruction_P ins X int reg1 X int reg2 X int dest)
926
{
927
  CHECKREG(reg1); CHECKREG(reg2); CHECKFREG(dest);
928
 
929
  clear_freg(dest);
930
#ifdef DO_ASSEMBLER_MACROS
931
  fprintf(as_file, "\t%sx\t%s,%s,%s\n", get_instruction(ins), freg_macro(dest), reg_macro(reg1), reg_macro(reg2));
932
#else
933
  fprintf(as_file, "\t%sx\t%d,%d,%d\n", get_instruction(ins), dest, reg1, reg2);
934
#endif
935
}
936
 
937
 
938
void ldf_ins PROTO_N ((ins,a,dest)) PROTO_T (Instruction_P ins X baseoff a X int dest)
939
{
940
  /*
941
   * Not a single instruction. Load from baseoff, which may be a global
942
   * requiring a temporary reg.
943
   */
944
 
945
  CHECKFREG(dest);
946
 
947
  if (!IS_FIXREG(a.base))
948
  {
949
    /* global */
950
    baseoff tmp_off;
951
 
952
    tmp_off.base = R_TMP0;
953
    tmp_off.offset = 0;
954
 
955
    set_ins(a, R_TMP0);
956
    ldf_ro_ins(ins, tmp_off, dest);
957
  }
958
  else
959
  {
960
    ldf_ro_ins(ins, a, dest);
961
  }
962
}
963
 
964
 
965
void stf_ro_ins PROTO_N (( ins,src,a)) PROTO_T (Instruction_P ins X int src X baseoff a)
966
{
967
  CHECKREG(a.base); CHECKFREG(src);
968
 
969
  /* in general we cannot cope with store using temp reg, catch it always */
970
  if (a.base == R_TMP0 && absval(a.offset) > (16 + 1 + 6) * 4)	/* leeway for mem_temp() */
971
    fail("stf_ro_ins: store of temp reg to offset not allowed");	/* should not happen */
972
 
973
  if (a.base == R_0)
974
  {
975
    if (a.offset != 0)
976
      fail("stf_ro_ins: non zero offset to R_0");
977
    /* with XXXx (indexed instructions) RA of R_0 is taken as constant 0 */
978
#ifdef DO_ASSEMBLER_MACROS
979
    fprintf(as_file, "\t%sx\t%s,%s,%s\n", get_instruction(ins), freg_macro(src), reg_macro(R_0), reg_macro(R_0));
980
#else
981
    fprintf(as_file, "\t%sx\t%d,%d,%d\n", get_instruction(ins), src, R_0, R_0);
982
#endif
983
  }
984
  else
985
  if (IMM_SIZE(a.offset))
986
  {
987
#ifdef DO_ASSEMBLER_MACROS
988
    fprintf(as_file, "\t%s\t%s,%d(%s)\n", get_instruction(ins), freg_macro(src), (int)a.offset, reg_macro(a.base));
989
#else
990
    fprintf(as_file, "\t%s\t%d,%d(%d)\n", get_instruction(ins), src, (int)a.offset, a.base);
991
#endif
992
  }
993
  else
994
  {
995
    /* offset too big, put in temp reg and used stf_rr_ins */
996
    /* +++ arrange stack variable to minimise this */
997
    COMMENT("stf_ro_ins: big offset, use temp reg and stf_rr_ins");
998
    ASSERT(a.base!=R_TMP0);		/* otherwise we corrupt it */
999
    ld_const_ins(a.offset, R_TMP0);
1000
    stf_rr_ins(ins, src, a.base, R_TMP0);
1001
  }
1002
}
1003
 
1004
 
1005
void stf_rr_ins PROTO_N ((ins,src,reg1,reg2)) PROTO_T (Instruction_P ins X int src X int reg1 X int reg2)
1006
{
1007
  CHECKREG(reg1); CHECKREG(reg2);
1008
#ifdef DO_ASSEMBLER_MACROS
1009
  fprintf(as_file, "\t%sx\t%s,%s,%s\n", get_instruction(ins), freg_macro(src), reg_macro(reg1), reg_macro(reg2));
1010
#else
1011
  fprintf(as_file, "\t%sx\t%d,%d,%d\n", get_instruction(ins), src, reg1, reg2);
1012
#endif
1013
}
1014
 
1015
 
1016
void stf_ins PROTO_N ((ins,src,a)) PROTO_T (Instruction_P ins X int src X baseoff a)
1017
{
1018
  /*
1019
   * Not a single instruction. Store into baseoff, which may be a global
1020
   * requiring a temporary reg.
1021
   */
1022
 
1023
  CHECKFREG(src);
1024
 
1025
  if (!IS_FIXREG(a.base))
1026
  {
1027
    /* global */
1028
    baseoff tmp_off;
1029
 
1030
    tmp_off.base = R_TMP0;
1031
    tmp_off.offset = 0;
1032
 
1033
    set_ins(a, R_TMP0);
1034
    stf_ro_ins(ins, src, tmp_off);
1035
  }
1036
  else
1037
  {
1038
    stf_ro_ins(ins, src, a);
1039
  }
1040
}
1041
 
1042
 
1043
void rrf_cmp_ins PROTO_N ((ins,reg1,reg2,cr_dest)) PROTO_T (Instruction_P ins X int reg1 X int reg2 X int cr_dest)
1044
{
1045
  CHECKFREG(reg1); CHECKFREG(reg2);
1046
#ifdef DO_ASSEMBLER_MACROS
1047
  fprintf(as_file, "\t%s\t%s,%s,%s\n", get_instruction(ins), cr_macro(cr_dest), freg_macro(reg1), freg_macro(reg2));
1048
#else
1049
  fprintf(as_file, "\t%s\t%d,%d,%d\n", get_instruction(ins), cr_dest, reg1, reg2);
1050
#endif
1051
}
1052
 
1053
 
1054
void rrf_ins PROTO_N ((ins,src,dest)) PROTO_T (Instruction_P ins X int src X int dest)
1055
{
1056
  CHECKFREG(dest); CHECKFREG(src);
1057
 
1058
  clear_freg(dest);
1059
#ifdef DO_ASSEMBLER_MACROS
1060
  fprintf(as_file, "\t%s\t%s,%s\n", get_instruction(ins), freg_macro(dest), freg_macro(src));
1061
#else
1062
  fprintf(as_file, "\t%s\t%d,%d\n", get_instruction(ins), dest, src);
1063
#endif
1064
}
1065
 
1066
 
1067
void rrrf_ins PROTO_N ((ins,src1,src2,dest)) PROTO_T(Instruction_P ins X int src1 X int src2 X int dest)
1068
{
1069
  CHECKFREG(dest); CHECKFREG(src1); CHECKFREG(src2);
1070
 
1071
  clear_freg(dest);
1072
#ifdef DO_ASSEMBLER_MACROS
1073
  fprintf(as_file, "\t%s\t%s,%s,%s\n", get_instruction(ins), freg_macro(dest), freg_macro(src1), freg_macro(src2));
1074
#else
1075
  fprintf(as_file, "\t%s\t%d,%d,%d\n", get_instruction(ins), dest, src1, src2);
1076
#endif
1077
}
1078
 
1079
void rrrrf_ins PROTO_N ((ins,src1,src2,src3,dest)) PROTO_T (Instruction_P ins X int src1 X int src2 X int src3 X int dest )
1080
{
1081
  CHECKFREG(dest); CHECKFREG(src1); CHECKFREG(src2); CHECKFREG(src3);
1082
 
1083
  clear_freg(dest);
1084
#ifdef DO_ASSEMBLER_MACROS
1085
  fprintf(as_file,"\t%s\t%s,%s,%s,%s\n",get_instruction(ins),freg_macro(dest),freg_macro(src1),freg_macro(src2),freg_macro(src3));
1086
#else
1087
  fprintf(as_file,"\t%s\t%d,%d,%d,%d\n",get_instruction(ins),dest,src1,src2,src3);
1088
#endif
1089
}
1090
void rlinm_ins PROTO_N ((ins,src1,sl,mask,dest)) PROTO_T (Instruction_P ins X int src1 X int sl X unsigned int mask X int dest )
1091
{
1092
  CHECKREG(dest);CHECKREG(src1);
1093
  ASSERT(ins==i_rlinm||ins==i_rlinm_cr);
1094
  clear_reg(dest);
1095
#ifdef DO_ASSEMBLER_MACROS
1096
  fprintf(as_file,"\t%s\t%s,%s,%d,0x%x\n",get_instruction(ins),reg_macro(dest),reg_macro(src1),sl,mask);
1097
#else
1098
  fprintf(as_file,"\t%s\t%d,%d,%d,0x%x\n",get_instruction(ins),dest,src1,sl,mask);
1099
#endif
1100
}
1101
 
1102
void mfspr_ins PROTO_N ((spr,dest)) PROTO_T (int spr X int dest )
1103
{  
1104
  CHECKREG(dest);
1105
  clear_reg(dest);
1106
#ifdef DO_ASSEMBLER_MACROS
1107
  fprintf(as_file,"\t%s\t%s,%s\n",get_instruction(i_mfspr),reg_macro(dest),spr_macro(spr));
1108
#else
1109
  fprintf(as_file,"\t%s\t%d,%d\n",get_instruction(i_mfspr),dest,spr);
1110
#endif
1111
}
1112
void mtfsfi_ins PROTO_N ((fld,imm)) PROTO_T (int fld X int imm )
1113
{
1114
  fprintf(as_file,"\t%s\t%d,%d\n",get_instruction(i_mtfsfi),fld,imm);
1115
}
1116
void mtfsb0_ins PROTO_N ((bit)) PROTO_T (int bit)
1117
{
1118
  ASSERT(bit>=0 && bit<=31);
1119
  fprintf(as_file,"\t%s\t%d\n",get_instruction(i_mtfsb0),bit);
1120
}
1121
void mtfsb1_ins PROTO_N ((bit)) PROTO_T (int bit)
1122
{
1123
  ASSERT(bit>=0 && bit<=31);
1124
  fprintf(as_file,"\t%s\t%d\n",get_instruction(i_mtfsb1),bit);
1125
}
1126
void mcrfs_ins PROTO_N ((a,b)) PROTO_T (int a X int b)
1127
{
1128
  ASSERT(a>=0 && a<=7);
1129
  ASSERT(b>=0 && b<=7);
1130
#ifdef DO_ASSEMBLER_MACROS
1131
  fprintf(as_file,"\t%s\t%s,%d\n",get_instruction(i_mcrfs),cr_macro(a),b);
1132
#else
1133
  fprintf(as_file,"\t%s\t%d,%d\n",get_instruction(i_mcrfs),a,b);
1134
#endif
1135
}
1136
void lsi_ins PROTO_N ((src,dest,nb)) PROTO_T (int src X int dest X int nb)
1137
{
1138
  fprintf(as_file,"\t%s\t%d,%d,%d\n",get_instruction(i_lsi),dest,src,nb);
1139
}
1140
void stsi_ins PROTO_N ((src,dest,nb)) PROTO_T (int src X int dest X int nb)
1141
{
1142
  fprintf(as_file,"\t%s\t%d,%d,%d\n",get_instruction(i_stsi),src,dest,nb);
1143
}
1144
void comment PROTO_N ((p)) PROTO_T (char *p)
1145
{
1146
#ifdef DEBUG_POWERTRANS
1147
  if (p==NIL)
1148
  {
1149
    fprintf(as_file,"\n");
1150
  }
1151
  else
1152
  {
1153
    fprintf(as_file,"        # %s\n",p);
1154
  }
1155
#else
1156
  fprintf(as_file,"\n");
1157
#endif
1158
  return;
1159
}
1160
 
1161
char * get_instruction PROTO_N ((ins)) PROTO_T (Instruction_P ins)
1162
{
1163
  char *w;
1164
  switch(architecture)
1165
  {
1166
   case COMMON_CODE:
1167
    w=ins->com;
1168
    break;
1169
   case RS6000_CODE:
1170
    w=ins->pwr;
1171
    break;
1172
   case POWERPC_CODE:
1173
    w=ins->ppc;
1174
    break;
1175
  };
1176
  return w;
1177
}