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
    		 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
			    VERSION INFORMATION
33
			    ===================
34
 
35
--------------------------------------------------------------------------
36
$Header: /u/g/release/CVSROOT/Source/src/installers/sparc/common/codehere.c,v 1.2 1998/03/11 11:03:52 pwe Exp $
37
--------------------------------------------------------------------------
38
$Log: codehere.c,v $
39
 * Revision 1.2  1998/03/11  11:03:52  pwe
40
 * DWARF optimisation info
41
 *
42
 * Revision 1.1.1.1  1998/01/17  15:55:53  release
43
 * First version to be checked into rolling release.
44
 *
45
 * Revision 1.6  1997/08/23  13:53:36  pwe
46
 * initial ANDF-DE
47
 *
48
 * Revision 1.5  1997/04/17  11:59:31  pwe
49
 * dwarf2 support
50
 *
51
 * Revision 1.4  1995/09/29  09:42:04  john
52
 * Fix to apply
53
 *
54
 * Revision 1.3  1995/07/18  09:38:23  john
55
 * Implemented return_to_label
56
 *
57
 * Revision 1.2  1995/05/26  12:56:29  john
58
 * Reformatting
59
 *
60
 * Revision 1.1.1.1  1995/03/13  10:18:28  john
61
 * Entered into CVS
62
 *
63
 * Revision 1.3  1994/07/07  16:11:33  djch
64
 * Jul94 tape
65
 *
66
 * Revision 1.3  1994/07/07  16:11:33  djch
67
 * Jul94 tape
68
 *
69
 * Revision 1.2  1994/05/25  14:20:10  djch
70
 * added assert for extra sanity
71
 *
72
 * Revision 1.1  1994/05/03  14:49:29  djch
73
 * Initial revision
74
 *
75
 * Revision 1.4  93/08/27  11:22:06  11:22:06  ra (Robert Andrews)
76
 * Got rid of sp argument to is_reg_operand, a couple of lint-like
77
 * changes.
78
 * 
79
 * Revision 1.3  93/08/13  14:35:08  14:35:08  ra (Robert Andrews)
80
 * Reformatted.
81
 * 
82
 * Revision 1.2  93/06/29  14:22:26  14:22:26  ra (Robert Andrews)
83
 * Made an integer cast explicit.
84
 * 
85
 * Revision 1.1  93/06/24  14:57:59  14:57:59  ra (Robert Andrews)
86
 * Initial revision
87
 * 
88
--------------------------------------------------------------------------
89
*/
90
 
91
 
92
#define SPARCTRANS_CODE
93
#include "config.h"
94
#include "common_types.h"
95
#include "myassert.h"
96
#include "addrtypes.h"
97
#include "proctypes.h"
98
#include "labels.h"
99
#include "expmacs.h"
100
#include "tags.h"
101
#include "makecode.h"
102
#include "exp.h"
103
#include "bitsmacs.h"
104
#include "locate.h"
105
#include "regexps.h"
106
#include "regmacs.h"
107
#include "inst_fmt.h"
108
#include "sparcins.h"
109
#include "shapemacs.h"
110
#include "special.h"
111
#include "regable.h"
112
#include "guard.h"
113
#include "move.h"
114
#include "comment.h"
115
#include "codehere.h"
116
 
117
 
118
/*
119
  HAS A REGISTER BEEN ALLOCATED FOR A VALUE?
120
  The expression e is checked to see if it has been allocated into a
121
  fixed register.  If so the register number is returned, otherwise
122
  R_NO_REG is returned.
123
*/
124
 
125
int regofval 
126
    PROTO_N ( ( e ) )
127
    PROTO_T ( exp e )
128
{
129
  exp dc = son ( e ) ;
130
  if ( name ( e ) == name_tag && name ( dc ) == ident_tag ) {
131
    if ( ( props ( dc ) & defer_bit ) != 0 ) {
132
      return ( regofval ( son ( dc ) ) ) ;
133
    }
134
    if ( ( props ( dc ) & inreg_bits ) != 0 ) {
135
      return ( ( isvar ( dc ) ) ? ( -no ( dc ) ) : ( no ( dc ) ) ) ;
136
    }
137
    return ( R_NO_REG ) ;
138
  } 
139
  else if ( name ( e ) == val_tag && no ( e ) == 0 ) {
140
    return ( R_G0 ) ;
141
  }
142
  return ( R_NO_REG ) ;
143
}
144
 
145
 
146
/*
147
  HAS A FLOATING REGISTER BEEN ALLOCATED FOR A VALUE?
148
  The expression e is checked to see if it has been allocated into a
149
  floating register.  If so the register number is returned, 
150
  otherwise R_NO_REG is returned.
151
*/
152
 
153
int fregofval 
154
    PROTO_N ( ( e ) )
155
    PROTO_T ( exp e )
156
{
157
  exp dc = son ( e ) ;
158
  if ( name ( e ) == name_tag && name ( dc ) == ident_tag ) {
159
    if ( ( props ( dc ) & infreg_bits ) != 0 ) {
160
      return ( no ( dc ) ) ;
161
    }
162
    return ( R_NO_REG ) ;
163
  }
164
  return ( R_NO_REG ) ;
165
}
166
 
167
 
168
/*
169
  AUXILIARY MAKE_CODE ROUTINE
170
  This routine calls make_code and ties up any internal exit labels.
171
*/
172
static int make_code_here 
173
    PROTO_N ( ( e, sp, dest ) )
174
    PROTO_T ( exp e X space sp X where dest )
175
{
176
  makeans mka ;
177
  mka = make_code ( e, sp, dest, 0 ) ;
178
  if ( mka.lab != 0 ) {
179
    clear_all () ;
180
    set_label ( mka.lab ) ;
181
#ifdef NEWDWARF
182
    START_BB ();
183
#endif
184
  }
185
  return ( mka.regmove ) ;
186
}
187
 
188
 
189
/*
190
  DOES AN EXPRESSION FIT INTO A REGISTER?
191
  If e easily fits into a unique fixed register then this register 
192
  number is returned.  Otherwise R_NO_REG is returned.
193
*/
194
static int is_reg_operand 
195
    PROTO_N ( ( e ) )
196
    PROTO_T ( exp e )
197
{
198
  ans aa ;
199
  int x = regofval ( e ) ;
200
  if ( x >= 0 && x < R_NO_REG ) return ( x ) ;
201
  if ( name ( e ) == cont_tag ) {
202
    x = regofval ( son ( e ) ) ;
203
    if ( x < 0 ) return ( -x ) ;
204
  }
205
  aa = iskept ( e ) ;
206
  if ( discrim ( aa ) == inreg && regalt ( aa ) != 0 ) {
207
    return ( regalt ( aa ) ) ;
208
  }
209
  if ( discrim ( aa ) == notinreg ) {
210
    instore is ;
211
    is = insalt ( aa ) ;
212
    if ( is.adval && is.b.offset == 0 ) {
213
      int r = is.b.base ;
214
      return ( r ) ;
215
    }
216
  }
217
  return ( R_NO_REG ) ;
218
}
219
 
220
 
221
/*
222
  CODE AN EXPRESSION INTO A REGISTER
223
  The expression e is encoded into a fixed register and the register
224
  number is returned.
225
*/
226
 
227
int reg_operand 
228
    PROTO_N ( ( e, sp ) )
229
    PROTO_T ( exp e X space sp )
230
{
231
  int reg = is_reg_operand ( e ) ;
232
  if ( reg == R_NO_REG || reg == R_G0 ) {
233
    /* allow make_code_here to choose the register */
234
    ans aa ;
235
    where w ;
236
    reg = -1 ;
237
    setsomeregalt ( aa, &reg ) ;
238
    w.answhere = aa ;
239
    w.ashwhere = ashof ( sh ( e ) ) ;
240
    ( void ) make_code_here ( e, sp, w ) ;
241
    assert (reg != -1);
242
    keepreg ( e, reg ) ;
243
    return ( reg ) ;
244
  } 
245
  else {
246
    /* e was found easily in a register */
247
    assert ( IS_FIXREG ( reg ) ) ;
248
    return ( reg ) ;
249
  }
250
}
251
 
252
 
253
/*
254
  CODE AN EXPRESSION INTO A GIVEN REGISTER
255
  The expression e is encoded into the given fixed register.
256
*/
257
void reg_operand_here 
258
    PROTO_N ( ( e, sp, this_reg ) )
259
    PROTO_T ( exp e X space sp X int this_reg )
260
{
261
  int reg = is_reg_operand ( e ) ;
262
  if ( reg == R_NO_REG || reg == R_G0 ) {
263
    /* evaluate e into this_reg directly */
264
    where w ;
265
    w.ashwhere = ashof ( sh ( e ) ) ;
266
    setregalt ( w.answhere, this_reg ) ;
267
    ( void ) make_code_here ( e, sp, w ) ;
268
  } 
269
  else {
270
    /* e was found easily in a register, so just do a move */
271
    assert ( IS_FIXREG ( reg ) ) ;
272
    if ( reg != this_reg ) rr_ins ( i_mov, reg, this_reg ) ;
273
  }
274
  if(name(e) != make_lv_tag) keepreg ( e, this_reg ) ;
275
  return ;
276
}
277
 
278
 
279
/*
280
  CODE AN EXPRESSION INTO A FLOATING REGISTER
281
  The expression e is encoded into a floating register and the 
282
  register number is returned.
283
*/
284
 
285
int freg_operand 
286
    PROTO_N ( ( e, sp, reg ) )
287
    PROTO_T ( exp e X space sp X int reg )
288
{
289
  ans aa ;
290
  where w ;
291
  freg fr ;
292
  int x = fregofval ( e ) ;
293
  if ( x >= 0 && x < R_NO_REG ) return ( x ) ;
294
  w.ashwhere = ashof ( sh ( e ) ) ;
295
  fr.dble = ( bool ) ( ( w.ashwhere.ashsize == 64 ) ? 1 : 0 ) ;
296
  if ( name ( e ) == cont_tag ) {
297
    x = fregofval ( son ( e ) ) ;
298
    if ( x < R_NO_REG ) return ( x ) ;
299
  } 
300
  else if ( name ( e ) == apply_tag || name(e) == apply_general_tag) {
301
    fr.fr = 0 ;
302
    setfregalt ( aa, fr ) ;
303
    w.answhere = aa ;
304
    /* w.ashwhere already correctly set up above */
305
    make_code ( e, sp, w, 0 ) ;
306
    /* floating point procedures give their result in %f0 */
307
    return ( 0 ) ;
308
  }
309
  aa = iskept ( e ) ;
310
  if ( discrim ( aa ) == infreg ) {
311
    /* e already evaluated in fl reg */
312
    return ( regalt ( aa ) ) /* cheat */ ;
313
  }
314
  fr.fr = reg ;
315
  setfregalt ( aa, fr ) ;
316
  w.answhere = aa ;
317
  ( void ) make_code_here ( e, sp, w ) ;
318
  keepexp ( e, aa ) ;
319
  return ( reg ) ;
320
}
321
 
322
 
323
/*
324
  ENCODE AN EXPRESSION
325
  The expression e is encoded into dest using make_code, and any
326
  internal exit labels are tied up.  However in the case when e is
327
  in a fixed register this is optimised to a move.
328
*/
329
 
330
int code_here 
331
    PROTO_N ( ( e, sp, dest ) )
332
    PROTO_T ( exp e X space sp X where dest )
333
{
334
  int reg = is_reg_operand ( e ) ;
335
  if ( reg == R_NO_REG || reg == R_G0 ) {
336
    return ( make_code_here ( e, sp, dest ) ) ;
337
  } 
338
  else {
339
    /* e was found easily in a register */
340
    ans aa ;
341
    assert ( IS_FIXREG ( reg ) ) ;
342
    assert ( ashof ( sh ( e ) ).ashsize <= 32 ) ;
343
    setregalt ( aa, reg ) ;
344
    ( void ) move ( aa, dest, guardreg ( reg, sp ).fixed, 1 ) ;
345
#ifdef NEWDIAGS
346
    if (dgf(e))
347
      diag_arg (e, sp, dest);
348
#endif
349
    return ( reg ) ;
350
  }
351
}