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) 1996
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
			    VERSION INFORMATION
31
			    ===================
32
 
33
--------------------------------------------------------------------------
34
$Header: /u/g/release/CVSROOT/Source/src/installers/680x0/common/mach_ins.c,v 1.1.1.1 1998/01/17 15:55:49 release Exp $
35
--------------------------------------------------------------------------
36
$Log: mach_ins.c,v $
37
 * Revision 1.1.1.1  1998/01/17  15:55:49  release
38
 * First version to be checked into rolling release.
39
 *
40
Revision 1.4  1997/11/13 08:27:13  ma
41
All avs test passed (except add_to_ptr).
42
 
43
Revision 1.3  1997/11/10 15:38:06  ma
44
.
45
 
46
Revision 1.2  1997/11/09 14:13:58  ma
47
comment.
48
 
49
Revision 1.1.1.1  1997/10/13 12:42:55  ma
50
First version.
51
 
52
Revision 1.5  1997/10/13 08:49:35  ma
53
Made all pl_tests for general proc & exception handling pass.
54
 
55
Revision 1.4  1997/06/18 10:09:36  ma
56
Checking in before merging with Input Baseline changes.
57
 
58
Revision 1.3  1997/05/13 11:30:34  ma
59
Introduced make_comment for debug.
60
 
61
Revision 1.2  1997/04/20 11:30:31  ma
62
Introduced gcproc.c & general_proc.[ch].
63
Added cases for apply_general_proc next to apply_proc in all files.
64
 
65
Revision 1.1.1.1  1997/03/14 07:50:14  ma
66
Imported from DRA
67
 
68
 * Revision 1.1.1.1  1996/09/20  10:56:55  john
69
 *
70
 * Revision 1.2  1996/07/05  14:22:21  john
71
 * Changes for spec 3.1
72
 *
73
 * Revision 1.1.1.1  1996/03/26  15:45:14  john
74
 *
75
 * Revision 1.2  94/02/21  15:59:49  15:59:49  ra (Robert Andrews)
76
 * Add a couple of explicit casts.  Some flags which used to be bool are
77
 * now int.
78
 *
79
 * Revision 1.1  93/02/22  17:16:02  17:16:02  ra (Robert Andrews)
80
 * Initial revision
81
 *
82
--------------------------------------------------------------------------
83
*/
84
 
85
 
86
#include "config.h"
87
#include "common_types.h"
88
#include "instrs.h"
89
#include "mach.h"
90
#include "mach_ins.h"
91
#include "mach_op.h"
92
#include "codex.h"
93
#include "output.h"
94
#include "utility.h"
95
extern bool have_cond ;
96
 
97
#ifdef EBUG
98
extern bool seek_label ;
99
extern bool seek_extern ;
100
extern int seek_label_no ;
101
extern char *seek_extern_id ;
102
#endif
103
 
104
 
105
/*
106
    OUTPUT FLAG
107
 
108
    If this is true, all instructions are output immediately.  This
109
    effectively switches off all peephole optimizations.
110
*/
111
 
112
int output_immediately = 0 ;
113
 
114
/*
115
    LIST OF ALL INSTRUCTIONS
116
 
117
    A list of all instructions in maintained.  The current instruction is
118
    given by current_ins.
119
*/
120
 
121
mach_ins *all_mach_ins = null ;
122
mach_ins *current_ins = null ;
123
 
124
 
125
/*
126
    RECORD OF LAST JUMP AND REGISTERS CHANGED SINCE
127
 
128
    This is used to help get a more accurate idea of which registers
129
    are known during the peephole optimizations.
130
*/
131
 
132
long last_jump = -1 ;
133
bitpattern last_jump_regs = 0 ;
134
 
135
 
136
/*
137
    LIST OF FREE INSTRUCTIONS
138
 
139
    A list of free mach_ins's, linked by their next field, is maintained.
140
*/
141
 
142
static mach_ins *mach_ins_list = null ;
143
 
144
 
145
/*
146
    FREE A SINGLE INSTRUCTION AND ITS OPERANDS
147
 
148
    The operands of the instruction are freed and the instruction
149
    itself is added to the list of all free instructions.
150
*/
151
 
152
void reclaim_ins
153
    PROTO_N ( ( p ) )
154
    PROTO_T ( mach_ins *p )
155
{
156
    if ( p->op1 ) free_mach_op ( p->op1 ) ;
157
    if ( p->op2 ) free_mach_op ( p->op2 ) ;
158
    p->next = mach_ins_list ;
159
    mach_ins_list = p ;
160
    return ;
161
}
162
 
163
 
164
/*
165
    FREE ALL INSTRUCTIONS AND THEIR OPERANDS
166
 
167
    All the instructions in the list of all instructions are freed and
168
    the list is reset to zero length.
169
*/
170
 
171
void free_all_ins
172
    PROTO_Z ()
173
{
174
    mach_ins *p = all_mach_ins, *q = null ;
175
    if ( p == null ) return ;
176
    while ( p != null ) {
177
	if ( p->op1 ) free_mach_op ( p->op1 ) ;
178
	if ( p->op2 ) free_mach_op ( p->op2 ) ;
179
	q = p ;
180
	p = p->next ;
181
    }
182
    q->next = mach_ins_list ;
183
    mach_ins_list = all_mach_ins ;
184
    all_mach_ins = null ;
185
    current_ins = null ;
186
    last_jump = -1 ;
187
    last_jump_regs = 0 ;
188
    return ;
189
}
190
 
191
 
192
/*
193
    CREATE A NEW INSTRUCTION
194
 
195
    A new instruction, with instruction number insno and operands op1 and
196
    op2 is added to the list of all instructions.  ch gives the mask of
197
    all registers changed by the instruction.  If susp is true then
198
    this instruction is never output immediately.  This only occurs in
199
    tmp_reg.
200
 
201
    This routine is usual called via the macro make_instr which has the
202
    same first four arguments, but has susp always false.
203
*/
204
 
205
#ifdef EBUG
206
static int next_id = 0 ;
207
#endif
208
 
209
void make_instr_aux
210
    PROTO_N ( ( insno, op1, op2, ch, susp ) )
211
    PROTO_T ( int insno X mach_op *op1 X mach_op *op2 X bitpattern ch X int susp )
212
{
213
    mach_ins *p ;
214
    if (insno != m_comment) {
215
      if ( stack_change ) update_stack () ;
216
    }
217
    if ( mach_ins_list == null ) {
218
	int i, n = 1000 ;
219
	mach_ins_list = alloc_nof ( mach_ins, n ) ;
220
	for ( i = 0 ; i < n - 1 ; i++ ) {
221
	    ( mach_ins_list + i )->next = mach_ins_list + ( i + 1 ) ;
222
	}
223
	( mach_ins_list + ( n - 1 ) )->next = null ;
224
    }
225
    p = mach_ins_list ;
226
    mach_ins_list = p->next ;
227
#ifdef EBUG
228
    p->id = ++ next_id ;
229
#if 1
230
    if(p->id == 4803) {
231
       int found = 1 ;
232
    }
233
#endif
234
#endif
235
    p->ins_no = insno ;
236
    p->op1 = op1 ;
237
    p->op2 = op2 ;
238
    p->changed = ch ;
239
    last_jump_regs |= ch ;
240
    if ( current_ins == null ) {
241
	p->next = all_mach_ins ;
242
	all_mach_ins = p ;
243
    } else {
244
	p->next = current_ins->next ;
245
	current_ins->next = p ;
246
    }
247
    current_ins = p ;
248
 
249
    if ( insno != m_comment ) {
250
      /* Clear the temporary register status */
251
      tmp_reg_status = 0 ;
252
      tmp_reg_prefer = 0 ;
253
    }
254
 
255
    if ( output_immediately && !susp ) {
256
	output_all () ;
257
	free_all_ins () ;
258
    }
259
    return ;
260
}
261
 
262
 
263
/*
264
    CREATE A LABEL
265
 
266
    A label is added to the list of all instructions.  This has the effect
267
    of marking all registers as changed.
268
*/
269
 
270
void make_label
271
    PROTO_N ( ( n ) )
272
    PROTO_T ( long n )
273
{
274
    mach_op *p = new_mach_op () ;
275
    p->type = MACH_LABQ ;
276
    p->def.num = n ;
277
    make_instr_aux ( m_label_ins, p, null, ( bitpattern ) 0xffff, 0 ) ;
278
    have_cond = 0 ;
279
#ifdef EBUG
280
    if ( seek_label && n == ( long ) seek_label_no ) {
281
	warning ( "Label %ld used", n ) ;
282
	breakpoint () ;
283
    }
284
#endif
285
    return ;
286
}
287
 
288
#ifdef EBUG
289
 
290
void make_comment
291
    PROTO_N ( ( comment ) )
292
    PROTO_T ( char* comment )
293
{
294
    mach_op *p;
295
 
296
    p = new_mach_op () ;
297
    p->type = MACH_COMMENT ;
298
    p->def.str = comment ;
299
    make_instr_aux ( m_comment, p, null, ( bitpattern ) 0x0000, 0 ) ;
300
 
301
    return ;
302
}
303
#endif
304
 
305
/*
306
    CREATE AN EXTERNAL LABEL
307
 
308
    An external label is added to the list of all instructions.  This has
309
    the effect of marking all registers as changed.
310
*/
311
 
312
void make_external_label
313
    PROTO_N ( ( nm ) )
314
    PROTO_T ( char *nm )
315
{
316
    mach_op *p = new_mach_op () ;
317
    p->type = MACH_EXTQ ;
318
    p->def.str = nm ;
319
    make_instr_aux ( m_extern_ins, p, null, ( bitpattern ) 0xffff, 0 ) ;
320
    have_cond = 0 ;
321
#ifdef EBUG
322
    if ( seek_extern && eq ( nm, seek_extern_id ) ) {
323
	warning ( "Label %s used", nm ) ;
324
	breakpoint () ;
325
    }
326
#endif
327
    return ;
328
}
329
 
330
 
331
/*
332
    CREATE A JUMP
333
 
334
    A jump, instruction number insno, to label n, is added to the list
335
    of all instructions.
336
*/
337
 
338
void make_jump
339
    PROTO_N ( ( insno, n ) )
340
    PROTO_T ( int insno X long n )
341
{
342
    mach_op *p = new_mach_op () ;
343
    p->type = MACH_LABQ ;
344
    p->def.num = n ;
345
    make_instr_aux ( insno, p, null, ( bitpattern ) 0, 0 ) ;
346
    if ( n != last_jump ) {
347
	last_jump = n ;
348
	last_jump_regs = 0 ;
349
    }
350
    return ;
351
}
352
 
353
 
354
/*
355
    SET A SPECIAL LABEL VALUE
356
 
357
    The special label with identifier nm is set equal to the given value.
358
*/
359
 
360
void set_special
361
    PROTO_N ( ( nm, op ) )
362
    PROTO_T ( char *nm X mach_op *op )
363
{
364
    mach_op *op1 = make_special_data ( nm ) ;
365
    make_instr_aux ( m_as_assign, op1, op, ( bitpattern ) 0, 0 ) ;
366
    return ;
367
}
368
 
369
 
370
/*
371
    OUTPUT AN IDENTIFICATION OF TWO NAMES
372
 
373
    This is not required, since all link information is known by the
374
    time I get round to code production.
375
*/
376
 
377
void out_rename
378
    PROTO_N ( ( old_nm, nm ) )
379
    PROTO_T ( char *old_nm X char *nm )
380
{
381
#if 0
382
    mach_op *op1 = make_extern_data ( old_nm, 0 ) ;
383
    mach_op *op2 = make_extern_data ( nm, 0 ) ;
384
    make_instr_aux ( m_as_assign, op1, op2, 0, 0 ) ;
385
#endif
386
    return ;
387
}