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
/*
7 7u83 2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    Copyright (c) 1993 Open Software Foundation, Inc.
33
 
34
 
35
    All Rights Reserved
36
 
37
 
38
    Permission to use, copy, modify, and distribute this software
39
    and its documentation for any purpose and without fee is hereby
40
    granted, provided that the above copyright notice appears in all
41
    copies and that both the copyright notice and this permission
42
    notice appear in supporting documentation.
43
 
44
 
45
    OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
46
    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47
    PARTICULAR PURPOSE.
48
 
49
 
50
    IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
51
    CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
52
    LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
53
    NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
54
    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
55
*/
56
 
57
/*
58
    		 Crown Copyright (c) 1997
7 7u83 59
 
2 7u83 60
    This TenDRA(r) Computer Program is subject to Copyright
61
    owned by the United Kingdom Secretary of State for Defence
62
    acting through the Defence Evaluation and Research Agency
63
    (DERA).  It is made available to Recipients with a
64
    royalty-free licence for its use, reproduction, transfer
65
    to other parties and amendment for any purpose not excluding
66
    product development provided that any such use et cetera
67
    shall be deemed to be acceptance of the following conditions:-
7 7u83 68
 
2 7u83 69
        (1) Its Recipients shall ensure that this Notice is
70
        reproduced upon any copies or amended versions of it;
7 7u83 71
 
2 7u83 72
        (2) Any amended version of it shall be clearly marked to
73
        show both the nature of and the organisation responsible
74
        for the relevant amendment or amendments;
7 7u83 75
 
2 7u83 76
        (3) Its onward transfer from a recipient to another
77
        party shall be deemed to be that party's acceptance of
78
        these conditions;
7 7u83 79
 
2 7u83 80
        (4) DERA gives no warranty or assurance as to its
81
        quality or suitability for any purpose and DERA accepts
82
        no liability whatsoever in relation to any use to which
83
        it may be put.
84
*/
85
 
86
 
87
 
88
/**********************************************************************
89
$Author: release $
90
$Date: 1998/02/04 15:49:02 $
91
$Revision: 1.2 $
92
$Log: parameter.c,v $
93
 * Revision 1.2  1998/02/04  15:49:02  release
94
 * Added OSF copyright message.
95
 *
96
 * Revision 1.1.1.1  1998/01/17  15:55:57  release
97
 * First version to be checked into rolling release.
98
 *
99
 * Revision 1.2  1996/10/04  16:03:18  pwe
100
 * add banners and mod for PWE ownership
101
 *
102
**********************************************************************/
103
 
104
 
105
#include "config.h"
106
#include "memtdf.h"
107
#include "codegen.h"
108
#include "geninst.h"
109
#include "translat.h"
110
#include "makecode.h"
111
#include "machine.h"
112
#include "flags.h"
113
#include "myassert.h"
114
#include "comment.h"
115
#include "proc.h"
116
#include "stack.h"
117
#include "mem_copy.h"
118
#include "xalloc.h"
119
#include "parameter.h"
120
bool suspected_varargs = 0;
121
int saved_varargs_register=0;
122
int saved_varargs_offset = 0;
123
 
124
typedef struct
125
{
126
  exp par;
127
  int dest;
128
  int copied;
129
} TREG;
130
 
131
static int spare_fixed;/* The spare t-reg used in case of looping copy i.e if 3-->4 and 4-->3
132
			  replace with 3-->spare_fixed 4-->3 spare_fixed-->4  */
133
static int spare_float;
134
 
135
static int copying_fixed;
136
static int copying_float;
137
bool remember;
138
long fixedfree;
139
long floatfree;
140
 
141
 
142
TREG fixed_array[13];
143
TREG float_array[14];
144
 
7 7u83 145
static void do_fixed_params(void);
146
static void do_float_params(void);
147
static void copy_fixed(int);
148
static void copy_float(int);
149
static void clear_fixed(void);
150
static void clear_float(void);
151
static void set_fixed(exp,int,int);
152
static void set_float(exp,int,int);
153
static int getspare(long);
154
void track_fixed(int,exp);
155
void track_float(int,exp);
2 7u83 156
static int end_param;
157
 
7 7u83 158
void output_parameters(exp e)
2 7u83 159
{
160
  exp par;
161
 
7 7u83 162
  if (name(e) ==general_proc_tag)
2 7u83 163
  {
164
    end_param = GENERAL_PROC_PARAM_REGS + R_FIRST_PARAM - 1;
165
  }
166
  else
167
  {
168
    end_param = PROC_PARAM_REGS + R_FIRST_PARAM - 1;
169
  }
7 7u83 170
 
2 7u83 171
  /* Outputs the code for the parameters */
172
  fixedfree = PROC_TREGS;
173
  floatfree = PROC_FLT_TREGS;
174
  clear_fixed();
175
  clear_float();
7 7u83 176
 
2 7u83 177
  par = son(e);
7 7u83 178
 
179
  for (;;)
2 7u83 180
  {
181
    int param_reg;
182
    exp init_exp;
183
    int param_size;
184
    int param_align;
185
    int param_offset;
7 7u83 186
    bool is_float;
2 7u83 187
    bool src_in_reg;
188
    bool dest_in_reg;
189
    baseoff stackpos;
190
    where dest;
7 7u83 191
 
2 7u83 192
    if ((!isparam(par)) ||
193
	(name(par)!=ident_tag) ||
7 7u83 194
	(name(son(par)) ==formal_callee_tag))
2 7u83 195
      break;
196
 
197
    init_exp = son(par);
198
    is_float = is_floating(name(sh(init_exp)));
199
    param_reg = props(init_exp);
200
    param_size = shape_size(sh(init_exp));
201
    param_align = shape_align(sh(init_exp));
7 7u83 202
    param_offset = no(init_exp) >>3;
2 7u83 203
    src_in_reg = param_reg !=0;
204
    dest_in_reg = (props(par) & inanyreg)!=0;
205
 
7 7u83 206
 
2 7u83 207
    if (src_in_reg==1)
208
    {
7 7u83 209
      if (is_float)
2 7u83 210
      {
211
	p_float_params++;
212
      }
213
      else
214
      {
215
	p_fixed_params++;
216
      }
217
    }
218
 
7 7u83 219
    stackpos=boff_location(ENCODE_FOR_BOFF(param_offset,INPUT_CALLER_PARAMETER));
2 7u83 220
 
7 7u83 221
 
2 7u83 222
    clearvarargparam(par);
7 7u83 223
 
224
    if (dest_in_reg==0
225
	&& !p_has_no_vcallers
2 7u83 226
	&& isvis(par)
7 7u83 227
	&& props(init_exp)!=0
2 7u83 228
	&& last_caller_param(par))
229
    {
230
      /* VARARGS */
231
      int last_size;
232
      int pr;
233
      baseoff v;
234
      v = stackpos;
235
 
236
      setvarargparam(par);
7 7u83 237
 
2 7u83 238
      if (param_size == 0)
239
      {
240
	/* void from <varargs.h> */
241
	param_size = 32;
242
	param_align = 32;
243
      }
7 7u83 244
 
2 7u83 245
      last_size = param_size;
246
      pr = R_FIRST_PARAM + ALIGNNEXT(no(init_exp) + last_size, 32) / 32;
7 7u83 247
 
2 7u83 248
      v.offset += ALIGNNEXT(last_size, 32) / 8;
249
      /* now word align to allow for non word aligned last param */
250
      v.offset &= ~3;
251
      suspected_varargs = 1;
252
      saved_varargs_offset = v.offset;
253
      saved_varargs_register = pr;
254
      while (pr <= end_param)
255
      {
256
	st_ro_ins(i_st, pr, v);comment("varargs save all param regs");
257
	pr++;
258
	v.offset += 4;
259
      }
7 7u83 260
    }
2 7u83 261
    /* Set up dest */
262
    if (dest_in_reg==1)
263
    {
264
      setregalt(dest.answhere,no(par));
265
    }
266
    else
267
    {
268
      instore is;
269
      is.b = stackpos;
270
      is.adval = 1;
271
      setinsalt(dest.answhere,is);
272
    }
273
    dest.ashwhere.ashsize  = param_size;
274
    dest.ashwhere.ashalign = param_align;
275
 
7 7u83 276
 
2 7u83 277
    /* Work out how the parameter is passed and where it will live */
7 7u83 278
    if (src_in_reg==0 && dest_in_reg==1)
2 7u83 279
    {
280
      /* STACK  --->  REGISTER */
281
      /* Use move for consistency */
282
      ans a;
283
      instore is;
284
      is.b = stackpos;
285
      is.adval = 0;
286
      setinsalt(a,is);
287
      move(a, dest, PROC_TREGS | PARAM_TREGS, is_signed(sh(init_exp)));
288
    }
289
    else if (src_in_reg==1 && dest_in_reg ==0)
290
    {
291
      /* REGISTER  --->  STACK */
292
      bool is_aggregate =IS_AGGREGATE(sh(init_exp));
293
      if (is_aggregate)
294
      {
295
	/* Whole or part of struct passed in param t-regs */
296
	int last_st_reg;
297
	int r;
298
 
7 7u83 299
	last_st_reg = param_reg + (ALIGNNEXT(param_size, 32) /32) - 1;
2 7u83 300
	if (last_st_reg > end_param)
301
	{
302
	  last_st_reg = end_param;
303
	}
304
	for (r = param_reg; r <= last_st_reg; r++)
305
	{
306
	  st_ro_ins(i_st, r, stackpos);comment("copy param struct onto stack");
307
	  stackpos.offset += 4;
308
	}
7 7u83 309
	p_fixed_params += (last_st_reg - param_reg);
2 7u83 310
      }
311
      else
312
      {
313
	ans a;
314
	freg fr;
7 7u83 315
 
316
	if (is_float)
2 7u83 317
	{
318
	  fr.dble = is_double_precision((sh(init_exp)));
319
	  fr.fr = param_reg;
320
	  setfregalt(a,fr);
321
	}
322
	else
323
	{
7 7u83 324
	  setregalt(a, param_reg);
2 7u83 325
	}
326
	move(a,dest,PROC_TREGS|PARAM_TREGS,0);
327
      }
328
    }
7 7u83 329
    else if (src_in_reg==1 && dest_in_reg==1)
2 7u83 330
    {
331
      /* REGISTER  --->  REGISTER */
332
      int dest_reg = no(par);
333
      ASSERT(dest_reg!=0);/* This is now set up in needscan*/
334
      if ((props(par) & inreg_bits)!=0)
335
      {
336
	if (IS_SREG(dest_reg))
337
	{
338
	  /* FIXED REGISTER --> FIXED S-REG */
339
	  mov_rr_ins(param_reg , dest_reg);comment("copy param into an s-reg");
340
	  track_fixed(param_reg,par);
341
	}
342
	else
343
	{
344
	  /* FIXED REGISTER --> FIXED T-REG */
345
	  set_fixed(par,param_reg ,  dest_reg);
346
	}
347
      }
348
      else
349
      {
350
	if (IS_FLT_SREG(dest_reg))
351
	{
352
	  /* FLOAT REGISTER --> FLOAT S-REG */
7 7u83 353
	  rrf_ins(i_fmr,param_reg , dest_reg);
2 7u83 354
	  track_float(param_reg,par);
355
	}
356
	else
357
	{
358
	  /* FLOAT REGISTER --> FLOAT T-REG */
359
	  set_float(par,param_reg , dest_reg);
360
	}
361
      }
362
    }
363
    else
364
    {
365
      /* LIVES IN PLACE ON STACK */
366
    }
367
 
368
    par = bro(son(par));
369
  }
370
  do_fixed_params();
371
  do_float_params();
372
  return;
373
}
374
 
375
 
7 7u83 376
static void do_fixed_params(void)
2 7u83 377
{
378
  int r;
379
 
7 7u83 380
  spare_fixed = getspare(fixedfree);
2 7u83 381
  copying_fixed = spare_fixed;
382
  copy_fixed(spare_fixed);
7 7u83 383
 
384
  for (r=R_FIRST_PARAM;r<=end_param;r++)
2 7u83 385
  {
386
    remember = 0;
387
    copying_fixed = r;
388
    copy_fixed(r);
389
    if (remember==1)
390
    {
7 7u83 391
      mov_rr_ins(spare_fixed , copying_fixed);comment("move param to its new reg");
392
      track_fixed(spare_fixed , fixed_array[copying_fixed].par);
2 7u83 393
    }
394
  }
395
  return;
7 7u83 396
}
397
static void do_float_params(void)
2 7u83 398
{
399
  int r;
7 7u83 400
 
2 7u83 401
  spare_float = getspare(floatfree);
402
  copying_float = spare_float;
403
  copy_float(spare_float);
7 7u83 404
 
405
  for (r=FR_FIRST_PARAM;r<=FR_LAST_PARAM;r++)
2 7u83 406
  {
407
    remember = 0;
408
    copying_float = r;
409
    copy_float(r);
410
    if (remember==1)
411
    {
412
      rrf_ins(i_fmr,spare_float,copying_float);
413
      track_float(spare_float,float_array[copying_float].par);
414
    }
415
  }
416
  return;
7 7u83 417
}
418
static void copy_fixed(int reg)
2 7u83 419
{
7 7u83 420
  if (fixed_array[reg].copied==1)
2 7u83 421
  {
422
    return;
423
  }
7 7u83 424
  if (fixed_array[reg].dest==reg)
2 7u83 425
  {
426
    fixed_array[reg].copied=1;
427
    return;
428
  }
7 7u83 429
  if (fixed_array[reg].dest==copying_fixed)
2 7u83 430
  {
431
    /* We have gone round in a loop */
432
    remember = 1;
433
    mov_rr_ins(reg,spare_fixed);comment("copy param reg to new location");
434
    fixed_array[reg].copied=1;
435
    return;
436
  }
437
  copy_fixed(fixed_array[reg].dest);
438
  mov_rr_ins(reg,fixed_array[reg].dest);comment("copy param reg to new reg");
439
  track_fixed(reg,fixed_array[reg].par);
440
  fixed_array[reg].copied=1;
441
  return;
442
}
7 7u83 443
static void copy_float(int reg)
2 7u83 444
{
7 7u83 445
  if (float_array[reg].copied==1)
2 7u83 446
  {
447
    return;
448
  }
7 7u83 449
  if (float_array[reg].dest==reg)
2 7u83 450
  {
451
    float_array[reg].copied=1;
452
    return;
453
  }
7 7u83 454
  if (float_array[reg].dest==copying_float)
2 7u83 455
  {
456
    /* We have gone round in a loop */
457
    remember = 1;
458
    rrf_ins(i_fmr,reg,spare_float);
459
    float_array[reg].copied=1;
460
    return;
461
  }
462
  copy_float(float_array[reg].dest);
463
  rrf_ins(i_fmr,reg,float_array[reg].dest);
464
  track_float(reg,float_array[reg].par);
465
  float_array[reg].copied=1;
466
  return;
7 7u83 467
}
2 7u83 468
 
469
 
470
 
7 7u83 471
static void clear_fixed(void)
2 7u83 472
{
473
  int r;
7 7u83 474
  for (r=0;r<=12;r++)
2 7u83 475
  {
476
    fixed_array[r].par = nilexp;
477
    fixed_array[r].dest = 0;
478
    fixed_array[r].copied = 1;
479
  }
480
  return;
481
}
7 7u83 482
static void clear_float(void)
2 7u83 483
{
484
  int r;
485
  for (r=0;r<=13;r++)
486
  {
487
    float_array[r].par = nilexp;
488
    float_array[r].dest = 0;
489
    float_array[r].copied = 1;
490
  }
491
  return;
492
}
493
 
7 7u83 494
static void set_fixed(exp p, int from, int to)
2 7u83 495
{
496
  ASSERT(IS_PARAM_REG(from));
497
  ASSERT(IS_TREG(to));
498
  ASSERT(to!=R_TMP0);
499
  fixed_array[from].par = p;
500
  fixed_array[from].dest = to;
501
  fixed_array[from].copied = 0;
502
  fixedfree |= RMASK(to);
503
}
7 7u83 504
static void set_float(exp p, int from, int to)
2 7u83 505
{
506
  ASSERT(IS_FLT_PARAM_REG(from));
507
  ASSERT(IS_FLT_TREG(to));
508
  float_array[from].par = p;
509
  float_array[from].dest = to;
510
  float_array[from].copied = 0;
511
  floatfree |= RMASK(to);
512
}
7 7u83 513
static int getspare(long s)
2 7u83 514
{
515
  int r;
7 7u83 516
  for (r=0;r<=31;r++)
2 7u83 517
  {
7 7u83 518
    if ((s & RMASK(r)) ==0)
2 7u83 519
    {
520
      return r;
521
    }
522
  }
523
  fail("getspare failed");
524
  return 100;
525
}
526
 
7 7u83 527
void track_fixed(int reg, exp id)
2 7u83 528
{
529
  exp def = son(id);
7 7u83 530
 
531
  if (pt(id)!=nilexp && keep_eq_size(sh(def),sh(pt(id))))
2 7u83 532
  {
7 7u83 533
    if (isvar(id))
2 7u83 534
    {
535
      keepcont(pt(id),reg);
7 7u83 536
    }
2 7u83 537
    else
538
    {
539
      keepreg(pt(id),reg);
540
    }
541
  }
542
  return;
543
}
544
 
7 7u83 545
void track_float(int reg, exp id)
2 7u83 546
{
547
  return;
548
}