Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | 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:49:01 $
61
$Revision: 1.2 $
62
$Log: oprators.c,v $
63
 * Revision 1.2  1998/02/04  15:49:01  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.3  1996/11/18  15:50:25  pwe
70
 * correct alias with bitfields, and case odds
71
 *
72
 * Revision 1.2  1996/10/04  16:03:10  pwe
73
 * add banners and mod for PWE ownership
74
 *
75
**********************************************************************/
76
 
77
 
78
#include "config.h"
79
#include "myassert.h"
80
#include "memtdf.h"
81
#include "codegen.h"
82
#include "geninst.h"
83
#include "maxminmacs.h"		/* for absval() */
84
#include "flags.h"
85
#include "instruct.h"
86
#include "proc.h"
87
#include "oprators.h"
88
#include "comment.h"
89
#include "makecode.h"
90
#include "error.h"
91
 
92
void tidyshort PROTO_N ((r,e)) PROTO_T (int r X exp e)
93
{
94
  shape s = sh(e);
95
  switch(name(e))
96
  {
97
   case and_tag:
98
    {
99
      exp r = bro(son(e));/* could be a val_tag */
100
      if(name(s)==ucharhd && name(r)==val_tag && ( (no(r) & 0xff) == no(r) ))
101
      {
102
	return;
103
      }
104
      if(name(s)==uwordhd && name(r)==val_tag && ( (no(r) & 0xffff) == no(r) ))
105
      {
106
	return;
107
      }
108
    }
109
  }
110
 
111
  if (name(s) == ucharhd)
112
  {
113
    rir_ins(i_and, r, 255, r);
114
  }
115
  else if (name(s) == uwordhd)
116
  {
117
    rir_ins(i_and, r, 0xffff, r);
118
  }
119
}
120
 
121
 
122
 /*
123
  * given a list of expressions seq which contains one whose value is in
124
  * register reg, removes that exp from seq and delivers 1; otherwise delivers 0
125
  */
126
bool regremoved PROTO_N ((seq,reg)) PROTO_T (exp * seq X int reg)
127
{
128
  exp s = *seq;
129
  exp t = bro(s);
130
 
131
  if (absval(regofval(s)) == reg)
132
  {
133
    (*seq) = t;
134
    return 1;
135
  }
136
  for (;;)
137
  {
138
    if (absval(regofval(t)) == reg)
139
    {
140
      bro(s) = bro(t);
141
      if (last(t))
142
	setlast(s);
143
      return 1;
144
    }
145
    if (last(t))
146
    {
147
      return 0;
148
    }
149
    s = t;
150
    t = bro(t);
151
  }
152
}
153
 
154
 
155
 /*
156
  * evaluates the fixed operation seq1 rins seq 2 rins...., into reg final,
157
  * using sp as free t-regs
158
  */
159
void do_comm PROTO_N ((seq,sp,final,rins)) PROTO_T (exp seq X space sp X int final X Instruction_P rins)
160
{
161
  int r = 0;
162
  space nsp;
163
  int a1;
164
  int a2;
165
 
166
  /* should have been optimised in scan... */
167
  ASSERT(!(rins == i_a && name(seq) == neg_tag && name(bro(seq)) != val_tag));
168
 
169
  /* evaluate 1st operand into a1 */
170
  a1 = reg_operand(seq, sp);
171
 
172
  for (;;)
173
  {
174
    nsp = guardreg(a1, sp);
175
    seq = bro(seq);
176
    if (name(seq) == val_tag)	/* next operand is a constant */
177
    {
178
      if (last(seq))
179
      {
180
	rir_ins(rins, a1, no(seq), final);
181
	return;
182
      }
183
      else
184
      {
185
	if (r == 0)
186
	  r = getreg(sp.fixed);
187
	rir_ins(rins, a1, no(seq), r);
188
      }
189
    }
190
    else
191
    {
192
      exp sq = seq;
193
      Instruction_P ins = rins;
194
 
195
      a2 = reg_operand(sq, nsp);
196
      /* evaluate next operand */
197
      if (last(seq))
198
      {
199
	rrr_ins(ins, a1, a2, final);
200
	return;
201
      }
202
      else
203
      {
204
	if (r == 0)
205
	  r = getreg(sp.fixed);
206
	rrr_ins(ins, a1, a2, r);
207
      }
208
    }
209
    a1 = r;
210
  }
211
}
212
 
213
 
214
/*
215
 * Evaluate commutative operation rrins given by e into d,
216
 * using sp to get t-regs 
217
 */
218
int comm_op PROTO_N ((e,sp,d,rrins)) PROTO_T (exp e X space sp X where d X Instruction_P rrins)
219
{
220
  Instruction_P rins = rrins;
221
 
222
  switch (d.answhere.discrim)
223
  {
224
  case inreg:
225
    {
226
      int dest = regalt(d.answhere);
227
      bool usesdest = regremoved(&son(e), dest);
228
      exp seq = son(e);
229
 
230
      /*
231
       * the destination is in a register; take care that we don't alter it
232
       * before possible use as an operand ....
233
       */
234
      if (usesdest && last(seq))
235
      {
236
	/* used, but there is only one other operand */
237
	if (name(seq) == val_tag)
238
	{
239
	  rir_ins(rins, dest, no(seq), dest);
240
	}
241
	else
242
	{
243
	  rrr_ins(rins, dest, reg_operand(seq, sp), dest);
244
	}
245
	tidyshort(dest, e);
246
	return dest;
247
      }
248
      else if (usesdest)
249
      {
250
	/* dest used, use temp */
251
	int r = getreg(sp.fixed);
252
 
253
	do_comm(seq, sp, r, rins);
254
	rrr_ins(rins, dest, r, dest);
255
	tidyshort(dest, e);
256
	return dest;
257
      }
258
      else
259
      {
260
	/* dest not used, evaluate into dest */
261
	do_comm(seq, sp, dest, rins);
262
	tidyshort(dest, e);
263
	return dest;
264
      }
265
    }				/* end inreg */
266
  default:
267
    {
268
      ans a;
269
      int r = getreg(sp.fixed);
270
      space nsp;
271
      bool rok =1;
272
      setregalt(a, r);
273
      do_comm(son(e), sp, r, rins);
274
      /* evaluate the expression into r ... */
275
      if(d.answhere.discrim != notinreg) { 
276
	tidyshort (r, e);
277
      } 
278
      else 
279
	rok = shape_size(sh(e))==32;
280
      nsp = guardreg(r, sp);
281
      move(a, d, nsp.fixed, 1);
282
      /* ... and move into a */
283
      return ((rok)?r:NOREG);
284
    }				/* notinreg */
285
  }				/* end switch */
286
}
287
 
288
/* evalate binary operation e with ins into dest */
289
int non_comm_op PROTO_N ((e,sp,dest,ins)) PROTO_T (exp e X space sp X where dest X Instruction_P ins)
290
{
291
  exp l = son(e);
292
  exp r = bro(l);
293
  bool sf_imm = name(l) == val_tag && ins == i_s && IMM_SIZE(no(l));
294
		/* we can use sfi instruction */
295
  int a1;
296
  int a2;
297
  space nsp;
298
 
299
  switch (dest.answhere.discrim)
300
  {
301
  case inreg:
302
    {
303
      int d = regalt(dest.answhere);
304
 
305
      if (sf_imm)
306
      {
307
	rir_ins(i_sf, reg_operand(r, sp), no(l), d);
308
      }
309
      else
310
      {
311
	a1 = reg_operand(l, sp);
312
	nsp = guardreg(a1, sp);
313
	a2 = reg_operand(r, nsp);
314
	rrr_ins(ins, a1, a2, d);
315
      }
316
 
317
      tidyshort(d, e);
318
      return d;
319
    }
320
 
321
  default:			/* destination elsewhere */
322
    {
323
      ans a;
324
      int r1 = getreg(sp.fixed);
325
 
326
      setregalt(a, r1);
327
 
328
      if (sf_imm)
329
      {
330
	rir_ins(i_sf, reg_operand(r, sp), no(l), r1);
331
      }
332
      else
333
      {
334
	a1 = reg_operand(l, sp);
335
	nsp = guardreg(a1, sp);
336
	a2 = reg_operand(r, nsp);
337
	rrr_ins(ins, a1, a2, r1);
338
      }
339
 
340
      tidyshort(r1, e);
341
      nsp = guardreg(r1, sp);
342
      move(a, dest, nsp.fixed, 1);
343
      return r1;
344
    }
345
  }
346
}
347
 
348
/* evaluate floating dyadic operation e using ins into dest */
349
int fop PROTO_N ((e,sp,dest,ins)) PROTO_T (exp e X space sp X where dest X Instruction_P ins)
350
{
351
  exp l = son(e);
352
  exp r = bro(l);
353
  int a1;
354
  int a2;
355
  space nsp;
356
 
357
  if (IsRev(e))
358
  {
359
    a2 = freg_operand(r, sp, getfreg(sp.flt));
360
    nsp = guardfreg(a2, sp);
361
    a1 = freg_operand(l, nsp, getfreg(nsp.flt));
362
  }
363
  else
364
  {
365
    a1 = freg_operand(l, sp, getfreg(sp.flt));
366
    nsp = guardfreg(a1, sp);
367
    a2 = freg_operand(r, nsp, getfreg(nsp.flt));
368
  }
369
 
370
  switch (dest.answhere.discrim)
371
  {
372
  case infreg:			/* dest in register */
373
    {
374
      freg fr;
375
 
376
      fr = fregalt(dest.answhere);
377
      if (ERROR_TREATMENT(e))
378
      {
379
	do_fop_error_jump(e,a1,a2,fr.fr);/* Floating point error jump */
380
      }
381
      else
382
      {
383
	rrrf_ins(ins, a1, a2, fr.fr);
384
      }
385
      if (fr.dble==0 && round_after_flop)
386
      {
387
	rrf_ins(i_frsp,fr.fr,fr.fr);
388
      }   
389
      return ((fr.dble) ? -(fr.fr + 32) : (fr.fr + 32));
390
    }
391
  default:			/* destination elsewhere */
392
    {
393
      ans a;
394
      freg fr;
395
      int r1 = getfreg(nsp.flt);
396
 
397
      fr.fr = r1;
398
      fr.dble = (dest.ashwhere.ashsize == 64) ? 1 : 0;
399
      setfregalt(a, fr);
400
      if (ERROR_TREATMENT(e))
401
      {
402
	do_fop_error_jump(e,a1,a2,fr.fr);/* Floating point error jump */
403
      }
404
      else
405
      {
406
	rrrf_ins(ins, a1, a2, r1);
407
      }
408
      if (fr.dble==0 && round_after_flop)
409
      {
410
	rrf_ins(i_frsp,r1,r1);
411
      }   
412
      move(a, dest, sp.fixed, 1);
413
      return ((fr.dble) ? -(fr.fr + 32) : (fr.fr + 32));
414
    }
415
  }
416
}
417
 
418
/* evaluate floating monadic operation e using ins into dest */
419
int fmop PROTO_N ((e,sp,dest,ins)) PROTO_T (exp e X space sp X where dest X Instruction_P ins)
420
{
421
  int a1 = freg_operand(son(e), sp, getfreg(sp.flt));
422
 
423
  switch (dest.answhere.discrim)
424
  {
425
  case infreg:
426
    {
427
      freg fr;
428
 
429
      fr = fregalt(dest.answhere);
430
      if (ERROR_TREATMENT(e))
431
      {
432
	do_fmop_error_jump(e,a1,fr.fr);
433
      }
434
      else
435
      {
436
	rrf_ins(ins, a1, fr.fr);
437
      }
438
      if (fr.dble==0 && round_after_flop)
439
      {
440
	rrf_ins(i_frsp,fr.fr,fr.fr);
441
      }
442
      return ((fr.dble) ? -(fr.fr + 32) : (fr.fr + 32));
443
    }
444
 
445
  default:
446
    {
447
      ans a;
448
      freg fr;
449
 
450
      fr.fr = getfreg(sp.flt);
451
      fr.dble = (dest.ashwhere.ashsize == 64) ? 1 : 0;
452
      setfregalt(a, fr);
453
      if (ERROR_TREATMENT(e))
454
      {
455
	do_fmop_error_jump(e,a1,fr.fr);
456
      }
457
      else
458
      {
459
	rrf_ins(ins, a1, fr.fr);      
460
      }
461
      if (fr.dble==0 && round_after_flop)
462
      {
463
	rrf_ins(i_frsp,fr.fr,fr.fr);
464
      }      
465
      move(a, dest, sp.fixed, 1);
466
      return ((fr.dble) ? -(fr.fr + 32) : (fr.fr + 32));
467
    }
468
  }
469
}