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

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

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
$Author: release $
33
$Date: 1998/01/17 15:56:05 $
34
$Revision: 1.1.1.1 $
35
$Log: inst_fmt.c,v $
36
 * Revision 1.1.1.1  1998/01/17  15:56:05  release
37
 * First version to be checked into rolling release.
38
 *
39
 * Revision 1.5  1995/09/12  10:59:26  currie
40
 * gcc pedanttry
41
 *
42
 * Revision 1.4  1995/08/16  16:06:47  currie
43
 * Shortened some .h names
44
 *
45
 * Revision 1.3  1995/08/15  09:19:21  currie
46
 * Dynamic callees + trap_tag
47
 *
48
 * Revision 1.2  1995/08/09  10:53:38  currie
49
 * apply_general bug
50
 *
51
 * Revision 1.1  1995/04/13  09:08:06  currie
52
 * Initial revision
53
 *
54
***********************************************************************/
55
/******************************************************************
56
		inst_fmt.c
57
 
58
	Procs for outputting various MIPS instruction formats to the
59
files as_file and ba_file. Each procedure produces assembler for a family of
60
MIPS operations, the actual member is passed as the string understood
61
by the assembler. The string contains as its first element the binasm coding for
62
the instruction +1; see mips_ins.c. Each instruction which alters a register clears
63
any memory of its contents - see regexps.c
64
 
65
******************************************************************/
66
 
67
#include "config.h"
68
#include "addrtypes.h"
69
#include "psu_ops.h"
70
#include "regexps.h"
71
#include "mips_ins.h"
72
#include "ibinasm.h"
73
#include "out_ba.h"
74
#include "syms.h"
75
#include "common_types.h"
76
#include "main.h"
77
#include "basicread.h"
78
#include "inst_fmt.h"
79
 
80
 
81
/*******************************************************************
82
ls_ins
83
This procedure outputs asembler for load and store instructions.
84
These necessarily take a reg and a baseoff as parameters, the latter argument allowing
85
the address to be constructed formrom its base and offset field, see addressingtypes.h.
86
********************************************************************/
87
 
88
 
89
int   andpeep = 0;		/* used to do trivial peepholing of and
90
				   instructions */
91
long  andop = 0;
92
 
93
 
94
 
95
 
96
void ls_ins
97
    PROTO_N ( (ins, reg, a) )
98
    PROTO_T ( char *ins X int reg X baseoff a )
99
{
100
				/* load and store instructions */
101
 
102
 
103
  if (reg <0) {reg = 0; /* pathological load of clear_tag */ }
104
 
105
  clear_reg (reg);
106
  if (ins == i_lbu) {		/* for peepholing later ands */
107
    andpeep = reg;
108
    andop = 255;
109
  }
110
  else
111
    if (ins == i_lhu) {
112
      andpeep = reg;
113
      andop = 0xffff;
114
    }
115
    else {
116
      andpeep = 0;
117
    }
118
 
119
  if (a.base == 0 && ins[1]!='s') {		/* literal */
120
    if (as_file)
121
      fprintf (as_file, "\t%s\t$%d, %ld\n", ins + 1, reg, a.offset);
122
    out_iinst (0, ins[0] - 1, reg, xnoreg, formri, a.offset);
123
  }
124
  else
125
    if (a.base >= 0 && a.base <= 31) {/* base - offset */
126
      if (as_file)
127
	fprintf (as_file, "\t%s\t$%d, %ld($%d)\n", ins + 1, reg, a.offset, a.base);
128
      out_iinst (0, ins[0] - 1, reg, a.base, formrob, a.offset);
129
    }
130
    else
131
      if (a.base < 0) {		/* global named */
132
	char *extname = main_globals[-a.base - 1] -> dec_u.dec_val.dec_id;
133
 
134
	if (as_file) {
135
	  if (a.offset == 0) {
136
	    fprintf (as_file, "\t%s\t$%d, %s\n", ins + 1, reg, extname);
137
	  }
138
	  else
139
	    if (a.offset < 0) {
140
	      fprintf (as_file, "\t%s\t$%d, %s-%ld\n",
141
		  ins + 1, reg, extname, -a.offset);
142
	    }
143
	    else {
144
	      fprintf (as_file, "\t%s\t$%d, %s+%ld\n",
145
		  ins + 1, reg, extname, a.offset);
146
	    }
147
	}
148
	out_iinst (symnos[-a.base - 1], ins[0] - 1, reg, xnoreg, formra, a.offset);
149
      }
150
      else {
151
	if (as_file) {		/* global anonymous */
152
	  if (a.offset == 0) {
153
	    fprintf (as_file, "\t%s\t$%d, $$%d\n", ins + 1, reg, a.base);
154
	  }
155
	  else
156
	    if (a.offset < 0) {
157
	      fprintf (as_file, "\t%s\t$%d, $$%d- %ld\n", ins + 1, reg,
158
		  a.base, -a.offset);
159
	    }
160
	    else {
161
	      fprintf (as_file, "\t%s\t$%d, $$%d+ %ld\n", ins + 1, reg,
162
		  a.base, a.offset);
163
	    }
164
	}
165
	out_iinst (tempsnos[a.base - 32], ins[0] - 1, reg, xnoreg, formra, a.offset);
166
      }
167
 
168
 
169
}
170
 
171
 
172
/*************** monadic operations ***************************
173
e.g move, neg, abs
174
************************************************************/
175
 
176
void mon_ins
177
    PROTO_N ( (ins, dest, src) )
178
    PROTO_T ( char *ins X int dest X int src )
179
{
180
  clear_reg (dest);
181
  andpeep = 0;
182
  if (ins == i_neg) { setnoreorder();}
183
  if (as_file)
184
    fprintf (as_file, "\t%s\t$%d, $%d\n", ins + 1, dest, src);
185
  out_rinst (0, ins[0] - 1, dest, src, formrr, xnoreg);
186
  if (ins == i_neg) { setreorder(); }
187
  return;
188
}
189
 
190
 
191
/* 3 register operand instructions:- destination, source1, source2 */
192
 
193
void rrr_ins
194
    PROTO_N ( (ins,dest,src1,src2) )
195
    PROTO_T ( char *ins X int dest X int src1 X int src2 )
196
{
197
  int ex = (ins == i_add || ins == i_sub);
198
	/* scheduling wrong for exceptional instructions */
199
  clear_reg (dest);
200
  andpeep = 0;
201
  if (ex) { setnoreorder();}
202
  if (as_file)
203
    fprintf (as_file, "\t%s\t$%d, $%d, $%d\n", ins + 1, dest, src1, src2);
204
  out_rinst (0, ins[0] - 1, dest, src1, formrrr, src2);
205
  if (ex) { setreorder(); }
206
  return;
207
}
208
 
209
 
210
 
211
/* register, register, immediate instructions */
212
 
213
void rri_ins
214
    PROTO_N ( (ins, dest, src1, imm) )
215
    PROTO_T ( char *ins X int dest X int src1 X long imm )
216
{
217
  int ex = (ins == i_add || ins == i_sub);
218
	/* scheduling wrong for exceptional instructions */
219
  if (ins == i_and && dest == andpeep && (imm & andop) == andop) {
220
    return;
221
  }
222
  clear_reg (dest);
223
  if (ins == i_and) {
224
    andpeep = dest;
225
    andop = imm;
226
  }
227
  else {
228
    andpeep = 0;
229
  }
230
  if (ex) { setnoreorder();}
231
  if (as_file)
232
    fprintf (as_file, "\t%s\t$%d, $%d, %ld\n", ins + 1,
233
	dest, src1, imm);
234
  out_iinst (0, ins[0] - 1, dest, src1, formrri, imm);
235
  if (ex) { setreorder(); }
236
  return;
237
}
238
 
239
/* register, immediate instructions */
240
 
241
void ri_ins
242
    PROTO_N ( (ins, dest, imm) )
243
    PROTO_T ( char *ins X int dest X long imm )
244
{
245
  clear_reg (dest);
246
  andpeep = 0;
247
  if (as_file)
248
    fprintf (as_file, "\t%s\t$%d,%ld\n", ins + 1, dest, imm);
249
  out_iinst (0, ins[0] - 1, dest, xnoreg, formri, imm);
250
}
251
 
252
 
253
/******************************************************************************
254
Branch instructions. These have labels as destination.
255
******************************************************************************/
256
 
257
/* unconditional */
258
 
259
void uncond_ins
260
    PROTO_N ( (ins, lab) )
261
    PROTO_T ( char *ins X int lab )
262
{
263
  clear_all ();
264
  andpeep = 0;
265
  if (as_file)
266
    fprintf (as_file, "\t%s\t$%d\n", ins + 1, lab);
267
  if (lab >= 32)
268
    out_iinst (-lab, ins[0] - 1, xnoreg, xnoreg, forml, 0);
269
  else
270
    out_iinst (0, ins[0] - 1, lab, xnoreg, formr, 0);
271
}
272
 
273
/*conditional */
274
 
275
/* register comparisons */
276
void condrr_ins
277
    PROTO_N ( (ins, src1, src2, lab) )
278
    PROTO_T ( char *ins X int src1 X int src2 X int lab )
279
{
280
  if (as_file)
281
    fprintf (as_file, "\t%s\t$%d, $%d, $%d\n", ins + 1, src1, src2, lab);
282
  out_iinst (-lab, ins[0] - 1, src1, src2, formrrl, 0);
283
 
284
}
285
 
286
/* register, immediate comparison */
287
void condri_ins
288
    PROTO_N ( (ins, src1, imm, lab) )
289
    PROTO_T ( char *ins X int src1 X long imm X int lab )
290
{
291
  if (imm == 0 && ins[4] == 0) {/* optimise branch on zero test */
292
    if (as_file)
293
      fprintf (as_file, "\t%sz\t$%d, $%d\n", ins + 1, src1, lab);
294
    out_iinst (-lab, ins[0] - 1, src1, 0, formrrl, 0);
295
  }
296
  else {
297
    if (as_file)
298
      fprintf (as_file, "\t%s\t$%d, %ld, $%d\n", ins + 1,
299
	  src1, imm, lab);
300
    out_iinst (-lab, ins[0] - 1, src1, xnoreg, formril, imm);
301
  }
302
}
303
 
304
/* register comparison with zero*/
305
void condr_ins
306
    PROTO_N ( (ins, src1, lab) )
307
    PROTO_T ( char *ins X int src1 X int lab )
308
{
309
  if (as_file)
310
    fprintf (as_file, "\t%s\t$%d, $%d\n", ins + 1, src1, lab);
311
  out_iinst (-lab, ins[0] - 1, src1, xnoreg, formrl, 0);
312
}
313
 
314
 
315
/*******************************************************************************
316
coprocessor instructions
317
*******************************************************************************/
318
 
319
void cop_ins
320
    PROTO_N ( (ins, gr, fr) )
321
    PROTO_T ( char *ins X int gr X int fr )
322
{
323
  clear_reg (gr);
324
  andpeep = 0;
325
  if (ins == i_ctc1 || ins== i_cfc1) {
326
    if (as_file)
327
      fprintf (as_file, "\t%s\t$%d, $%d\n", ins + 1, gr, fr);
328
    out_rinst (0, ins[0] - 1, gr, fr, formrr, xnoreg);
329
  }
330
  else {
331
    clear_reg ((fr >> 1) + 32);
332
    if (as_file)
333
      fprintf (as_file, "\t%s\t$%d, $f%d\n", ins + 1, gr, fr);
334
    out_rinst (0, ins[0] - 1, gr, fr + float_register, formrr, xnoreg);
335
  }
336
}
337
 
338
/* floating point instructions */
339
 
340
void lsfp_ins
341
    PROTO_N ( (ins, reg, a) )
342
    PROTO_T ( char *ins X int reg X baseoff a )
343
{
344
  clear_reg ((reg >> 1) + 32);
345
  if (a.base == 0) {
346
    failer ("ZERO BASE in fp op");/* can't have literal operand */
347
    if (as_file)
348
      fprintf (as_file, "\t%s\t$f%d, %ld\n", ins + 1, reg, a.offset);
349
  }
350
  else
351
    if (a.base >= 0 && a.base <= 31) {/* base offset */
352
      if (as_file)
353
	fprintf (as_file, "\t%s\t$f%d, %ld($%d)\n",
354
	    ins + 1, reg, a.offset, a.base);
355
      out_iinst (0, ins[0] - 1, reg + float_register, a.base, formrob, a.offset);
356
 
357
    }
358
    else
359
      if (a.base < 0) {		/* global named */
360
	char *extname = main_globals[-a.base - 1] -> dec_u.dec_val.dec_id;
361
	if (as_file) {
362
	  if (a.offset == 0) {
363
	    fprintf (as_file, "\t%s\t$f%d, %s\n", ins + 1, reg, extname);
364
	  }
365
	  else
366
	    if (a.offset < 0) {
367
	      fprintf (as_file, "\t%s\t$f%d, %s-%ld\n",
368
		  ins + 1, reg, extname, -a.offset);
369
	    }
370
	    else {
371
	      fprintf (as_file, "\t%s\t$f%d, %s+%ld\n",
372
		  ins + 1, reg, extname, a.offset);
373
	    }
374
	}
375
	out_iinst (symnos[-a.base - 1], ins[0] - 1, reg + float_register, xnoreg,
376
	    formra, a.offset);
377
 
378
      }
379
      else {			/* global anonymous */
380
	if (as_file) {
381
	  if (a.offset == 0) {
382
	    fprintf (as_file, "\t%s\t$f%d, $$%d\n", ins + 1, reg, a.base);
383
	  }
384
	  else
385
	    if (a.offset < 0) {
386
	      fprintf (as_file, "\t%s\t$f%d, $$%d- %ld\n", ins + 1, reg,
387
		  a.base, -a.offset);
388
	    }
389
	    else {
390
	      fprintf (as_file, "\t%s\t$f%d, $$%d+ %ld\n", ins + 1, reg,
391
		  a.base, a.offset);
392
	    }
393
	}
394
	out_iinst (tempsnos[a.base - 32], ins[0] - 1, reg + float_register, xnoreg,
395
	    formra, a.offset);
396
      }
397
}
398
 
399
 
400
void rrfp_ins
401
    PROTO_N ( (ins, dest, src) )
402
    PROTO_T ( char *ins X int dest X int src )
403
{
404
  clear_reg ((dest >> 1) + 32);
405
  if (as_file)
406
    fprintf (as_file, "\t%s\t$f%d, $f%d\n", ins + 1, dest, src);
407
  out_rinst (0, ins[0] - 1, dest + float_register, src + float_register, formrr,
408
      xnoreg);
409
}
410
 
411
void rrfpcond_ins
412
    PROTO_N ( (ins, dest, src) )
413
    PROTO_T ( char *ins X int dest X int src )
414
{
415
 
416
  if (as_file)
417
    fprintf (as_file, "\t%s\t$f%d, $f%d\n", ins + 1, dest, src);
418
  out_rinst (0, ins[0] - 1, dest + float_register, src + float_register, formrr,
419
      xnoreg);
420
}
421
 
422
void rrrfp_ins
423
    PROTO_N ( (ins, dest, src1, src2) )
424
    PROTO_T ( char *ins X int dest X int src1 X int src2 )
425
{
426
  clear_reg ((dest >> 1) + 32);
427
  if (as_file)
428
    fprintf (as_file, "\t%s\t$f%d, $f%d, $f%d\n", ins + 1, dest, src1, src2);
429
  out_rinst (0, ins[0] - 1, dest + float_register, src1 + float_register, formrrr,
430
      src2 + float_register);
431
}
432
 
433
 
434
/******************************************************************************
435
jump to address given by register parameter dest
436
*******************************************************************************/
437
 
438
void br_ins
439
    PROTO_N ( (ins, dest) )
440
    PROTO_T ( char *ins X int dest )
441
{
442
   /* clear_all (); shouldnt be necessary*/
443
  andpeep = 0;
444
  if (as_file)
445
    fprintf (as_file, "\t%s\t$%d\n", ins + 1, dest);
446
  if (dest >= 32)
447
    out_iinst (-dest, ins[0] - 1, xnoreg, xnoreg, forml, 0);
448
  else
449
    out_iinst (0, ins[0] - 1, dest, xnoreg, formr, 0);
450
}
451
 
452
 
453
/* jump to external identifier */
454
void extj_ins
455
    PROTO_N ( (ins, b) )
456
    PROTO_T ( char *ins X baseoff b )
457
{
458
  char *extname = main_globals[-b.base - 1] -> dec_u.dec_val.dec_id;
459
  clear_all ();
460
  andpeep = 0;
461
  if (as_file)
462
    fprintf (as_file, "\t%s\t%s\n", ins + 1, extname);
463
  out_iinst (symnos[-b.base - 1], ins[0] - 1, xnoreg, xnoreg, forma, 0);
464
}
465
 
466
void tround_ins
467
    PROTO_N ( (ins, dfr, sfr, gpr) )
468
    PROTO_T ( char *ins X int dfr X int sfr X int gpr )
469
{
470
				/* round and truncate */
471
  clear_reg (gpr);
472
  clear_reg ((dfr >> 1) + 32);
473
  andpeep = 0;
474
  if (as_file)
475
    fprintf (as_file, "\t%s\t$f%d,$f%d,$%d\n", ins + 1, dfr, sfr, gpr);
476
  out_rinst (0, ins[0] - 1, dfr + float_register, sfr + float_register,
477
      formrrr, gpr);
478
}
479
 
480
/* hi lo register manipulation */
481
void hilo_ins
482
    PROTO_N ( (ins, dest) )
483
    PROTO_T ( char * ins X int dest )
484
{
485
  clear_reg(dest);
486
  andpeep = 0;
487
  if (as_file)
488
    fprintf (as_file, "\t%s\t$%d\n", ins + 1,dest);
489
 
490
  out_rinst(0, ins[0]-1, dest, 0, formr, 0);
491
}
492
 
493
/* mult & div instructions operating on hilo */
494
void multdiv_ins
495
    PROTO_N ( (ins, r1, r2) )
496
    PROTO_T ( char *ins X int r1 X int r2 )
497
{
498
	andpeep=0;
499
	if (as_file)
500
		fprintf(as_file, "\t%s\t$%d,$%d\n", ins+1, r1, r2);
501
 
502
	out_rinst (0, ins[0] - 1, r1, r2, formrr, xnoreg);
503
}