Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2006 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
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1996
32
    		 Crown Copyright (c) 1996
3
 
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
Line 86... Line 116...
86
    LIST OF FREE OPERANDS
116
    LIST OF FREE OPERANDS
87
 
117
 
88
    A list of free mach_op's, linked by the plus field.
118
    A list of free mach_op's, linked by the plus field.
89
*/
119
*/
90
 
120
 
91
static mach_op *mach_op_list = null ;
121
static mach_op *mach_op_list = null;
92
 
122
 
93
 
123
 
94
/*
124
/*
95
    ALLOCATE A NEW OPERAND
125
    ALLOCATE A NEW OPERAND
96
 
126
 
97
    This routine returns a pointer to a mach_op.  This is taken from the
127
    This routine returns a pointer to a mach_op.  This is taken from the
98
    list of free mach_op's.
128
    list of free mach_op's.
99
*/
129
*/
100
#ifndef tdf3
130
#ifndef tdf3
101
#ifdef EBUG
131
#ifdef EBUG
102
static int next_id = 0 ;
132
static int next_id = 0;
103
#endif
133
#endif
104
#endif
134
#endif
105
 
135
 
106
mach_op *new_mach_op
136
mach_op *
107
    PROTO_Z ()
137
new_mach_op(void)
108
{
138
{
109
    mach_op *p ;
139
	mach_op *p;
110
    if ( mach_op_list == null ) {
140
	if (mach_op_list == null) {
111
	int i, n = 1000 ;
141
		int i, n = 1000;
112
	p = alloc_nof ( mach_op, n ) ;
142
		p = alloc_nof(mach_op, n);
113
	for ( i = 0 ; i < n - 1 ; i++ ) {
143
		for (i = 0; i < n - 1; i++) {
114
	    ( p + i )->plus = p + ( i + 1 ) ;
144
			(p + i)->plus = p + (i + 1);
115
	    ( p + i )->of = null ;
145
			(p + i)->of = null;
-
 
146
		}
-
 
147
		(p + (n - 1))->plus = null;
-
 
148
		(p + (n - 1))->of = null;
-
 
149
		mach_op_list = p;
116
	}
150
	}
117
	( p + ( n - 1 ) )->plus = null ;
-
 
118
	( p + ( n - 1 ) )->of = null ;
-
 
119
	mach_op_list = p ;
-
 
120
    }
-
 
121
    p = mach_op_list ;
151
	p = mach_op_list;
122
    if ( p->of ) {
152
	if (p->of) {
123
	mach_op *q = p->of ;
153
		mach_op *q = p->of;
124
	mach_op_list = q ;
154
		mach_op_list = q;
125
	while ( q->plus ) q = q->plus ;
155
		while (q->plus) {
-
 
156
			q = q->plus;
-
 
157
		}
126
	q->plus = p->plus ;
158
		q->plus = p->plus;
127
    } else {
159
	} else {
128
	mach_op_list = p->plus ;
160
		mach_op_list = p->plus;
129
    }
161
	}
130
    p->def.num = 0 ;
162
	p->def.num = 0;
131
    p->plus = null ;
163
	p->plus = null;
132
    p->of = null ;
164
	p->of = null;
133
#ifndef tdf3
165
#ifndef tdf3
134
#ifdef EBUG
166
#ifdef EBUG
135
    if (next_id == 70) {
167
	if (next_id == 70) {
136
       int dummy = next_id ;
168
		int dummy = next_id;
137
    }
169
	}
138
 
170
 
139
    p->id = next_id ++ ;
171
	p->id = next_id++;
140
#endif
172
#endif
141
#endif
173
#endif
142
    return ( p ) ;
174
	return (p);
143
}
175
}
144
 
176
 
145
 
177
 
146
/*
178
/*
147
    FREE AN OPERAND
179
    FREE AN OPERAND
148
 
180
 
149
    A mach_op is freed by adding it to the list of free mach_op's.
181
    A mach_op is freed by adding it to the list of free mach_op's.
150
*/
182
*/
151
 
183
 
152
void free_mach_op
184
void
153
    PROTO_N ( ( ptr ) )
-
 
154
    PROTO_T ( mach_op *ptr )
185
free_mach_op(mach_op *ptr)
155
{
186
{
156
    mach_op *p = ptr ;
187
	mach_op *p = ptr;
157
    if ( p == null ) return ;
188
	if (p == null) {
-
 
189
		return;
-
 
190
	}
158
    while ( p->plus ) p = p->plus ;
191
	while (p->plus) {
-
 
192
		p = p->plus;
-
 
193
	}
159
    p->plus = mach_op_list ;
194
	p->plus = mach_op_list;
160
    mach_op_list = ptr ;
195
	mach_op_list = ptr;
161
    return ;
196
	return;
162
}
197
}
163
 
198
 
164
 
199
 
165
/*
200
/*
166
    SPECIAL LABELS INFORMATION
201
    SPECIAL LABELS INFORMATION
167
 
202
 
168
    A special label consists of the label prefix, "L", followed by the
203
    A special label consists of the label prefix, "L", followed by the
169
    special label identifier, followed by the value of special_no for
204
    special label identifier, followed by the value of special_no for
170
    the current procedure.  A particular special label is that with
205
    the current procedure.  A particular special label is that with
171
    identifier special_str.
206
    identifier special_str.
172
*/
207
*/
173
 
208
 
174
long special_no = 0 ;
209
long special_no = 0;
175
char *special_str = "S" ;
210
char *special_str = "S";
176
 
211
 
177
 
212
 
178
/*
213
/*
179
    TEMPORARY REGISTER STATUS
214
    TEMPORARY REGISTER STATUS
180
 
215
 
181
    This records the number of temporary registers which have been allocated
216
    This records the number of temporary registers which have been allocated
182
    at any given moment, any temporary register preferences and the last
217
    at any given moment, any temporary register preferences and the last
183
    temporary register used.
218
    temporary register used.
184
*/
219
*/
185
 
220
 
186
int tmp_reg_status = 0 ;
221
int tmp_reg_status = 0;
187
int tmp_reg_prefer = 0 ;
222
int tmp_reg_prefer = 0;
188
static int last_reg = 0 ;
223
static int last_reg = 0;
189
 
224
 
190
 
225
 
191
/*
226
/*
192
    FIND THE NUMBER OF THE NEXT TEMPORARY REGISTER
227
    FIND THE NUMBER OF THE NEXT TEMPORARY REGISTER
193
 
228
 
Line 201... Line 236...
201
    this equals X, if which case A0 is used.
236
    this equals X, if which case A0 is used.
202
 
237
 
203
    If X is not specified, the first temporary register will be Y,
238
    If X is not specified, the first temporary register will be Y,
204
    if that exists, or A1.  The second will be A1 if Y exists, or
239
    if that exists, or A1.  The second will be A1 if Y exists, or
205
    A0 otherwise.
240
    A0 otherwise.
206
 
241
 
207
    Under very rare conditions a third temporary register is required.
242
    Under very rare conditions a third temporary register is required.
208
    In these cases D0 always suffices.
243
    In these cases D0 always suffices.
209
*/
244
*/
210
 
245
 
211
int next_tmp_reg
246
int
212
    PROTO_Z ()
247
next_tmp_reg(void)
213
{
248
{
214
    int r ;
249
	int r;
215
    int t = tmp_reg_status ;
250
	int t = tmp_reg_status;
216
    if ( t > 1 ) {
251
	if (t > 1) {
217
	debug_warning ( "Temporary D-register used" ) ;
252
		debug_warning("Temporary D-register used");
218
	r = REG_D0 ;
253
		r = REG_D0;
219
    } else if ( tmp_reg_prefer ) {
254
	} else if (tmp_reg_prefer) {
220
	if ( t == 0 ) {
255
		if (t == 0) {
221
	    r = tmp_reg_prefer ;
256
			r = tmp_reg_prefer;
222
	    last_reg = r ;
257
			last_reg = r;
223
	} else {
258
		} else {
224
	    bitpattern na = ( regsinuse | reuseables | regsindec ) ;
259
			bitpattern na = (regsinuse | reuseables | regsindec);
225
	    bitpattern a = regsinproc & ~na & 0x3c00 ;
260
			bitpattern a = regsinproc & ~na & 0x3c00;
226
	    r = ( a ? reg ( a ) : REG_A1 ) ;
261
			r = (a ? reg(a): REG_A1);
227
	    if ( r == last_reg ) r = REG_A0 ;
262
			if (r == last_reg) {
-
 
263
				r = REG_A0;
228
	}
264
			}
229
    } else {
265
		}
230
	bitpattern na = ( regsinuse | reuseables | regsindec ) ;
-
 
231
	bitpattern a = regsinproc & ~na & 0x3c00 ;
-
 
232
	if ( t == 0 ) {
-
 
233
	    r = ( a ? reg ( a ) : REG_A1 ) ;
-
 
234
	    last_reg = r ;
-
 
235
	} else {
266
	} else {
-
 
267
		bitpattern na = (regsinuse | reuseables | regsindec);
-
 
268
		bitpattern a = regsinproc & ~na & 0x3c00;
-
 
269
		if (t == 0) {
-
 
270
			r = (a ? reg(a): REG_A1);
-
 
271
			last_reg = r;
-
 
272
		} else {
236
	    r = ( a ? REG_A1 : REG_A0 ) ;
273
			r = (a ? REG_A1 : REG_A0);
-
 
274
			if (r == last_reg) {
237
	    if ( r == last_reg ) r = ( r == REG_A0 ? REG_A1 : REG_A0 ) ;
275
				r = (r == REG_A0 ? REG_A1 : REG_A0);
-
 
276
			}
-
 
277
		}
238
	}
278
	}
239
    }
-
 
240
    return ( r ) ;
279
	return (r);
241
}
280
}
242
 
281
 
243
 
282
 
244
/*
283
/*
245
    AVOID A GIVEN TEMPORARY REGISTER
284
    AVOID A GIVEN TEMPORARY REGISTER
246
 
285
 
247
    This marks the given register number as to be avoided by pretending
286
    This marks the given register number as to be avoided by pretending
248
    that it was the previous temporary register.
287
    that it was the previous temporary register.
249
*/
288
*/
250
 
289
 
251
void avoid_tmp_reg
290
void
252
    PROTO_N ( ( r ) )
-
 
253
    PROTO_T ( int r )
291
avoid_tmp_reg(int r)
254
{
292
{
255
    last_reg = r ;
293
	last_reg = r;
256
    tmp_reg_status++ ;
294
	tmp_reg_status++;
257
    return ;
295
	return;
258
}
296
}
259
 
297
 
260
 
298
 
261
/*
299
/*
262
    MOVE AN OPERAND INTO A TEMPORARY REGISTER
300
    MOVE AN OPERAND INTO A TEMPORARY REGISTER
Line 264... Line 302...
264
    It is sometimes necessary to move an operand into a temporary address
302
    It is sometimes necessary to move an operand into a temporary address
265
    register.  A move instruction (given by instr) is output, and the
303
    register.  A move instruction (given by instr) is output, and the
266
    number of the temporary register is returned.
304
    number of the temporary register is returned.
267
*/
305
*/
268
 
306
 
269
int tmp_reg
307
int
270
    PROTO_N ( ( instr, ptr ) )
-
 
271
    PROTO_T ( int instr X mach_op *ptr )
308
tmp_reg(int instr, mach_op *ptr)
272
{
309
{
273
    int t = tmp_reg_status ;
310
	int t = tmp_reg_status;
274
    int r = next_tmp_reg () ;
311
	int r = next_tmp_reg();
275
    mach_op *p = new_mach_op () ;
312
	mach_op *p = new_mach_op();
276
    p->type = MACH_REG ;
313
	p->type = MACH_REG;
277
    p->def.num = ( long ) r ;
314
	p->def.num = (long)r;
278
    make_instr_aux ( instr, ptr, p, regmsk ( r ), 1 ) ;
315
	make_instr_aux(instr, ptr, p, regmsk(r), 1);
279
    regsinproc |= regmsk ( r ) ;
316
	regsinproc |= regmsk(r);
280
    tmp_reg_status = t + 1 ;
317
	tmp_reg_status = t + 1;
281
    return ( r ) ;
318
	return (r);
282
}
319
}
283
 
320
 
284
 
321
 
285
/*
322
/*
286
    TEST IF A REGISTER IS USED IN AN OPERAND
323
    TEST IF A REGISTER IS USED IN AN OPERAND
287
 
324
 
288
    This routine returns 1 if register r is used in the operand op.
325
    This routine returns 1 if register r is used in the operand op.
289
*/
326
*/
290
 
327
 
291
bool check_op
328
bool
292
    PROTO_N ( ( op, r ) )
-
 
293
    PROTO_T ( mach_op *op X int r )
329
check_op(mach_op *op, int r)
294
{
330
{
295
    if ( op == null ) return ( 0 ) ;
331
	if (op == null) {
-
 
332
		return (0);
-
 
333
	}
296
    switch ( op->type ) {
334
	switch (op->type) {
-
 
335
	case MACH_CONT:
-
 
336
		return ((op->def.num) & regmsk(r)? 1 : 0);
-
 
337
	case MACH_REG:
-
 
338
	case MACH_DEC:
-
 
339
	case MACH_INC:
-
 
340
		return (op->def.num == r ? 1 : 0);
-
 
341
	case MACH_BF:
-
 
342
		return (check_op(op->of, r));
-
 
343
	case MACH_RPAIR:
-
 
344
		if (op->def.num == r) {
-
 
345
			return (1);
297
 
346
		}
298
	case MACH_CONT : return ( ( op->def.num ) & regmsk ( r ) ? 1 : 0 ) ;
347
		return (op->plus->def.num == r ? 1 : 0);
-
 
348
	}
-
 
349
	return (0);
-
 
350
}
299
 
351
 
300
	case MACH_REG :
-
 
301
	case MACH_DEC :
-
 
302
	case MACH_INC : return ( op->def.num == r ? 1 : 0 ) ;
-
 
303
 
352
 
304
	case MACH_BF : return ( check_op ( op->of, r ) ) ;
-
 
305
 
-
 
306
	case MACH_RPAIR : {
-
 
307
	    if ( op->def.num == r ) return ( 1 ) ;
-
 
308
	    return ( op->plus->def.num == r ? 1 : 0 ) ;
-
 
309
	}
-
 
310
    }
-
 
311
    return ( 0 ) ;
-
 
312
}
-
 
313
 
-
 
314
 
-
 
315
/*
353
/*
316
    TEST IF TWO OPERANDS ARE EQUAL
354
    TEST IF TWO OPERANDS ARE EQUAL
317
 
355
 
318
    This returns 1 if the two operands have equal effect.  Note that,
356
    This returns 1 if the two operands have equal effect.  Note that,
319
    for example, consecutive uses of the same pre-decremented register,
357
    for example, consecutive uses of the same pre-decremented register,
320
    although having the same representation, are not equal in this
358
    although having the same representation, are not equal in this
321
    context.
359
    context.
322
*/
360
*/
323
 
361
 
324
bool equal_op
362
bool
325
    PROTO_N ( ( op1, op2 ) )
-
 
326
    PROTO_T ( mach_op *op1 X mach_op *op2 )
363
equal_op(mach_op *op1, mach_op *op2)
327
{
364
{
328
    mach_op *p1 = op1, *p2 = op2 ;
365
	mach_op *p1 = op1, *p2 = op2;
329
    while ( p1 && p2 ) {
366
	while (p1 && p2) {
330
	if ( p1->type != p2->type ) return ( 0 ) ;
367
		if (p1->type != p2->type) {
-
 
368
			return (0);
-
 
369
		}
331
	if ( p1->type == MACH_DEC || p1->type == MACH_INC ) return ( 0 ) ;
370
		if (p1->type == MACH_DEC || p1->type == MACH_INC) {
-
 
371
			return (0);
-
 
372
		}
332
	if ( p1->def.num != p2->def.num ) return ( 0 ) ;
373
		if (p1->def.num != p2->def.num) {
-
 
374
			return (0);
-
 
375
		}
333
	if ( p1->plus ) {
376
		if (p1->plus) {
334
	    if ( p2->plus == null ) return ( 0 ) ;
377
			if (p2->plus == null) {
-
 
378
				return (0);
-
 
379
			}
335
	    if ( !equal_op ( p1->plus, p2->plus ) ) return ( 0 ) ;
380
			if (!equal_op(p1->plus, p2->plus)) {
-
 
381
				return (0);
-
 
382
			}
336
	} else {
383
		} else {
337
	    if ( p2->plus ) return ( 0 ) ;
384
			if (p2->plus) {
-
 
385
				return (0);
-
 
386
			}
-
 
387
		}
-
 
388
		p1 = p1->of;
-
 
389
		p2 = p2->of;
338
	}
390
	}
339
	p1 = p1->of ;
-
 
340
	p2 = p2->of ;
-
 
341
    }
-
 
342
    return ( p1 == p2 ? 1 : 0 ) ;
391
	return (p1 == p2 ? 1 : 0);
343
}
392
}
344
 
393
 
345
 
394
 
346
/*
395
/*
347
    MAKE AN INTEGER CONSTANT OPERAND
396
    MAKE AN INTEGER CONSTANT OPERAND
348
 
397
 
349
    This and the subsequent routines are used to allocate machine operands.
398
    This and the subsequent routines are used to allocate machine operands.
350
    The constructions are simple applications of the descriptions given
399
    The constructions are simple applications of the descriptions given
351
    in mach.h.  They need very little other comment.
400
    in mach.h.  They need very little other comment.
352
*/
401
*/
353
 
-
 
354
mach_op *make_value
-
 
355
    PROTO_N ( ( n ) )
-
 
356
    PROTO_T ( long n )
-
 
357
{
-
 
358
    mach_op *p = new_mach_op () ;
-
 
359
    p->type = MACH_VAL ;
-
 
360
    p->def.num = n ;
-
 
361
    return ( p ) ;
-
 
362
}
-
 
363
 
-
 
364
 
-
 
365
/*
-
 
366
    MAKE AN INTEGER DATA OPERAND
-
 
367
*/
-
 
368
 
402
 
369
mach_op *make_int_data
403
mach_op *
370
    PROTO_N ( ( n ) )
-
 
371
    PROTO_T ( long n )
404
make_value(long n)
372
{
405
{
373
    mach_op *p = new_mach_op () ;
406
	mach_op *p = new_mach_op();
374
    p->type = MACH_VALQ ;
407
	p->type = MACH_VAL;
375
    p->def.num = n ;
408
	p->def.num = n;
376
    return ( p ) ;
409
	return (p);
377
}
410
}
378
 
411
 
379
 
412
 
380
/*
413
/*
381
    MAKE A HEXADECIMAL INTEGER CONSTANT OPERAND
414
    MAKE AN INTEGER DATA OPERAND
382
*/
415
*/
383
 
416
 
384
mach_op *make_hex_value
417
mach_op *
385
    PROTO_N ( ( n ) )
-
 
386
    PROTO_T ( long n )
418
make_int_data(long n)
387
{
419
{
388
    mach_op *p = new_mach_op () ;
420
	mach_op *p = new_mach_op();
389
    p->type = MACH_HEX ;
421
	p->type = MACH_VALQ;
390
    p->def.num = n ;
422
	p->def.num = n;
391
    return ( p ) ;
423
	return (p);
392
}
424
}
393
 
425
 
394
 
426
 
395
/*
427
/*
396
    MAKE A HEXADECIMAL INTEGER CONSTANT DATA OPERAND
428
    MAKE A HEXADECIMAL INTEGER CONSTANT OPERAND
397
*/
429
*/
398
 
430
 
399
mach_op *make_hex_data
431
mach_op *
400
    PROTO_N ( ( n ) )
-
 
401
    PROTO_T ( long n )
432
make_hex_value(long n)
402
{
433
{
403
    mach_op *p = new_mach_op () ;
434
	mach_op *p = new_mach_op();
404
    p->type = MACH_HEXQ ;
435
	p->type = MACH_HEX;
405
    p->def.num = n ;
436
	p->def.num = n;
406
    return ( p ) ;
437
	return (p);
407
}
438
}
408
 
439
 
409
 
440
 
410
/*
441
/*
411
    MAKE A FLOATING POINT DATA OPERAND
442
    MAKE A HEXADECIMAL INTEGER CONSTANT DATA OPERAND
412
*/
443
*/
413
 
444
 
414
mach_op *make_float_data
445
mach_op *
415
    PROTO_N ( ( f ) )
446
make_hex_data(long n)
416
    PROTO_T ( flt *f )
-
 
417
{
447
{
418
    mach_op *p = new_mach_op () ;
448
	mach_op *p = new_mach_op();
419
    p->type = MACH_FLOATQ ;
449
	p->type = MACH_HEXQ;
420
    p->def.fp = f ;
450
	p->def.num = n;
421
    return ( p ) ;
451
	return (p);
422
}
452
}
423
 
453
 
424
 
454
 
425
/*
455
/*
426
    MAKE A LABEL OPERAND
456
    MAKE A FLOATING POINT DATA OPERAND
427
*/
457
*/
428
 
458
 
429
mach_op *make_lab
459
mach_op *
430
    PROTO_N ( ( n, d ) )
460
make_float_data(flt *f)
431
    PROTO_T ( long n X long d )
-
 
432
{
461
{
-
 
462
	mach_op *p = new_mach_op();
-
 
463
	p->type = MACH_FLOATQ;
-
 
464
	p->def.fp = f;
-
 
465
	return (p);
-
 
466
}
-
 
467
 
-
 
468
 
-
 
469
/*
-
 
470
    MAKE A LABEL OPERAND
-
 
471
*/
-
 
472
 
-
 
473
mach_op *
-
 
474
make_lab(long n, long d)
-
 
475
{
433
    mach_op *p1 = new_mach_op () ;
476
	mach_op *p1 = new_mach_op();
434
    p1->type = MACH_LAB ;
477
	p1->type = MACH_LAB;
435
    p1->def.num = n ;
478
	p1->def.num = n;
436
    if ( d ) {
479
	if (d) {
437
	mach_op *p2 = new_mach_op () ;
480
		mach_op *p2 = new_mach_op();
438
	p2->type = MACH_VAL ;
481
		p2->type = MACH_VAL;
439
	p2->def.num = d ;
482
		p2->def.num = d;
440
	p1->plus = p2 ;
483
		p1->plus = p2;
441
    }
484
	}
442
    return ( p1 ) ;
485
	return (p1);
443
}
486
}
444
 
487
 
445
 
488
 
446
/*
489
/*
447
    MAKE A LABEL DATA OPERAND
490
    MAKE A LABEL DATA OPERAND
448
*/
491
*/
449
 
492
 
450
mach_op *make_lab_data
493
mach_op *
451
    PROTO_N ( ( n, d ) )
-
 
452
    PROTO_T ( long n X long d )
494
make_lab_data(long n, long d)
453
{
495
{
454
    mach_op *p1 = new_mach_op () ;
496
	mach_op *p1 = new_mach_op();
455
    p1->type = MACH_LABQ ;
497
	p1->type = MACH_LABQ;
456
    p1->def.num = n ;
498
	p1->def.num = n;
457
    if ( d ) {
499
	if (d) {
458
	mach_op *p2 = new_mach_op () ;
500
		mach_op *p2 = new_mach_op();
459
	p2->type = MACH_VAL ;
501
		p2->type = MACH_VAL;
460
	p2->def.num = d ;
502
		p2->def.num = d;
461
	p1->plus = p2 ;
503
		p1->plus = p2;
462
    }
504
	}
463
    return ( p1 ) ;
505
	return (p1);
464
}
506
}
465
 
507
 
466
 
508
 
467
/*
509
/*
468
    MAKE AN OPERAND CORRESPONDING TO THE DIFFERENCE OF TWO LABELS
510
    MAKE AN OPERAND CORRESPONDING TO THE DIFFERENCE OF TWO LABELS
469
*/
511
*/
470
 
512
 
471
mach_op *make_lab_diff
513
mach_op *
472
    PROTO_N ( ( a, b ) )
-
 
473
    PROTO_T ( long a X long b )
514
make_lab_diff(long a, long b)
474
{
515
{
475
    mach_op *p1 = new_mach_op () ;
516
	mach_op *p1 = new_mach_op();
476
    mach_op *p2 = new_mach_op () ;
517
	mach_op *p2 = new_mach_op();
477
    mach_op *p3 = new_mach_op () ;
518
	mach_op *p3 = new_mach_op();
478
    p1->type = MACH_LABQ ;
519
	p1->type = MACH_LABQ;
479
    p1->def.num = a ;
520
	p1->def.num = a;
480
    p1->plus = p2 ;
521
	p1->plus = p2;
481
    p2->type = MACH_NEG ;
522
	p2->type = MACH_NEG;
482
    p2->plus = p3 ;
523
	p2->plus = p3;
483
    p3->type = MACH_LABQ ;
524
	p3->type = MACH_LABQ;
484
    p3->def.num = b ;
525
	p3->def.num = b;
485
    return ( p1 ) ;
526
	return (p1);
486
}
527
}
487
 
528
 
488
 
529
 
489
/*
530
/*
490
    MAKE AN EXTERNAL OPERAND
531
    MAKE AN EXTERNAL OPERAND
491
*/
532
*/
492
 
533
 
493
mach_op *make_extern
534
mach_op *
494
    PROTO_N ( ( nm, d ) )
-
 
495
    PROTO_T ( char *nm X long d )
535
make_extern(char *nm, long d)
496
{
536
{
497
    mach_op *p1 = new_mach_op () ;
537
	mach_op *p1 = new_mach_op();
498
    p1->type = MACH_EXT ;
538
	p1->type = MACH_EXT;
499
    p1->def.str = nm ;
539
	p1->def.str = nm;
500
    if ( d ) {
540
	if (d) {
501
	mach_op *p2 = new_mach_op () ;
541
		mach_op *p2 = new_mach_op();
502
	p2->type = MACH_VAL ;
542
		p2->type = MACH_VAL;
503
	p2->def.num = d ;
543
		p2->def.num = d;
504
	p1->plus = p2 ;
544
		p1->plus = p2;
505
    }
545
	}
506
    return ( p1 ) ;
546
	return (p1);
507
}
547
}
508
 
548
 
509
 
549
 
510
/*
550
/*
511
    MAKE AN EXTERNAL DATA OPERAND
551
    MAKE AN EXTERNAL DATA OPERAND
512
*/
552
*/
513
 
553
 
514
mach_op *make_extern_data
554
mach_op *
515
    PROTO_N ( ( nm, d ) )
-
 
516
    PROTO_T ( char *nm X long d )
555
make_extern_data(char *nm, long d)
517
{
556
{
518
    mach_op *p1 = new_mach_op () ;
557
	mach_op *p1 = new_mach_op();
519
    p1->type = MACH_EXTQ ;
558
	p1->type = MACH_EXTQ;
520
    p1->def.str = nm ;
559
	p1->def.str = nm;
521
    if ( d ) {
560
	if (d) {
522
	mach_op *p2 = new_mach_op () ;
561
		mach_op *p2 = new_mach_op();
523
	p2->type = MACH_VAL ;
562
		p2->type = MACH_VAL;
524
	p2->def.num = d ;
563
		p2->def.num = d;
525
	p1->plus = p2 ;
564
		p1->plus = p2;
526
    }
565
	}
527
    return ( p1 ) ;
566
	return (p1);
528
}
567
}
529
 
568
 
530
 
569
 
531
/*
570
/*
532
    MAKE A SPECIAL LABEL OPERAND
571
    MAKE A SPECIAL LABEL OPERAND
533
*/
572
*/
534
 
573
 
535
mach_op *make_special
574
mach_op *
536
    PROTO_N ( ( nm ) )
-
 
537
    PROTO_T ( char *nm )
575
make_special(char *nm)
538
{
576
{
539
    mach_op *p = new_mach_op () ;
577
	mach_op *p = new_mach_op();
540
    p->type = MACH_SPEC ;
578
	p->type = MACH_SPEC;
541
    p->def.str = nm ;
579
	p->def.str = nm;
542
    return ( p ) ;
580
	return (p);
543
}
581
}
544
 
582
 
545
 
583
 
546
/*
584
/*
547
    MAKE A SPECIAL LABEL DATA OPERAND
585
    MAKE A SPECIAL LABEL DATA OPERAND
548
*/
586
*/
549
 
587
 
550
mach_op *make_special_data
588
mach_op *
551
    PROTO_N ( ( nm ) )
-
 
552
    PROTO_T ( char *nm )
589
make_special_data(char *nm)
553
{
590
{
554
    mach_op *p = new_mach_op () ;
591
	mach_op *p = new_mach_op();
555
    p->type = MACH_SPECQ ;
592
	p->type = MACH_SPECQ;
556
    p->def.str = nm ;
593
	p->def.str = nm;
557
    return ( p ) ;
594
	return (p);
558
}
595
}
559
 
596
 
560
 
597
 
561
/*
598
/*
562
    MAKE A LABEL INDIRECT OPERAND
599
    MAKE A LABEL INDIRECT OPERAND
563
*/
600
*/
564
 
601
 
565
mach_op *make_lab_ind
602
mach_op *
566
    PROTO_N ( ( n, d ) )
-
 
567
    PROTO_T ( long n X long d )
603
make_lab_ind(long n, long d)
568
{
-
 
569
    mach_op *p1 = new_mach_op () ;
-
 
570
    mach_op *p2 = new_mach_op () ;
-
 
571
    p1->type = MACH_CONT ;
-
 
572
    p1->def.num = 0 ;
-
 
573
    p1->of = p2 ;
-
 
574
    p2->type = MACH_LAB ;
-
 
575
    p2->def.num = n ;
-
 
576
    if ( d ) {
-
 
577
	mach_op *p3 = new_mach_op () ;
-
 
578
	p3->type = MACH_VAL ;
-
 
579
	p3->def.num = d ;
-
 
580
	p2->plus = p3 ;
-
 
581
    }
-
 
582
    return ( p1 ) ;
-
 
583
}
-
 
584
 
-
 
585
 
-
 
586
/*
-
 
587
    MAKE AN EXTERNAL INDIRECT OPERAND
-
 
588
*/
-
 
589
 
-
 
590
mach_op *make_extern_ind
-
 
591
    PROTO_N ( ( nm, d ) )
-
 
592
    PROTO_T ( char *nm X long d )
-
 
593
{
604
{
594
    mach_op *p1 = new_mach_op () ;
605
	mach_op *p1 = new_mach_op();
595
    mach_op *p2 = new_mach_op () ;
606
	mach_op *p2 = new_mach_op();
596
    p1->type = MACH_CONT ;
607
	p1->type = MACH_CONT;
597
    p1->def.num = 0 ;
608
	p1->def.num = 0;
598
    p1->of = p2 ;
609
	p1->of = p2;
599
    p2->type = MACH_EXT ;
610
	p2->type = MACH_LAB;
600
    p2->def.str = nm ;
611
	p2->def.num = n;
601
    if ( d ) {
612
	if (d) {
602
	mach_op *p3 = new_mach_op () ;
613
		mach_op *p3 = new_mach_op();
603
	p3->type = MACH_VAL ;
614
		p3->type = MACH_VAL;
604
	p3->def.num = d ;
615
		p3->def.num = d;
605
	p2->plus = p3 ;
616
		p2->plus = p3;
606
    }
617
	}
607
    return ( p1 ) ;
618
	return (p1);
608
}
619
}
609
 
620
 
610
 
621
 
611
/*
622
/*
612
    MAKE A REGISTER DIRECT OPERAND
623
    MAKE AN EXTERNAL INDIRECT OPERAND
613
*/
624
*/
614
 
625
 
615
mach_op *make_register
626
mach_op *
616
    PROTO_N ( ( r ) )
-
 
617
    PROTO_T ( int r )
627
make_extern_ind(char *nm, long d)
618
{
628
{
-
 
629
	mach_op *p1 = new_mach_op();
-
 
630
	mach_op *p2 = new_mach_op();
-
 
631
	p1->type = MACH_CONT;
-
 
632
	p1->def.num = 0;
-
 
633
	p1->of = p2;
-
 
634
	p2->type = MACH_EXT;
-
 
635
	p2->def.str = nm;
-
 
636
	if (d) {
-
 
637
		mach_op *p3 = new_mach_op();
-
 
638
		p3->type = MACH_VAL;
-
 
639
		p3->def.num = d;
-
 
640
		p2->plus = p3;
-
 
641
	}
-
 
642
	return (p1);
-
 
643
}
-
 
644
 
-
 
645
 
-
 
646
/*
-
 
647
    MAKE A REGISTER DIRECT OPERAND
-
 
648
*/
-
 
649
 
-
 
650
mach_op *
-
 
651
make_register(int r)
-
 
652
{
619
    mach_op *p = new_mach_op () ;
653
	mach_op *p = new_mach_op();
620
    p->type = MACH_REG ;
654
	p->type = MACH_REG;
621
    p->def.num = ( long ) r ;
655
	p->def.num = (long)r;
622
    return ( p ) ;
656
	return (p);
623
}
657
}
624
 
658
 
625
/*
659
/*
626
    MAKE PSEUDO OPERAND REPRESENTING LDISP
660
    MAKE PSEUDO OPERAND REPRESENTING LDISP
627
    (the space between sp and the parameters at procedure entry)
661
    (the space between sp and the parameters at procedure entry)
628
*/
662
*/
629
 
663
 
630
mach_op *make_ldisp
664
mach_op *
631
    PROTO_N ( ( offset ) )
-
 
632
    PROTO_T ( long offset )
665
make_ldisp(long offset)
633
{
666
{
634
    mach_op *p1 = new_mach_op () ;
667
	mach_op *p1 = new_mach_op();
635
    p1->type = MACH_SPEC ;
668
	p1->type = MACH_SPEC;
636
    p1->def.str = special_str ;
669
	p1->def.str = special_str;
637
    if (offset) {
670
	if (offset) {
638
       p1->plus = new_mach_op () ;
671
		p1->plus = new_mach_op();
639
       p1->plus->type = MACH_VAL ;
672
		p1->plus->type = MACH_VAL;
640
       p1->plus->def.num = offset ;
673
		p1->plus->def.num = offset;
641
    }
674
	}
642
    return ( p1 ) ;
675
	return (p1);
643
}
676
}
644
 
677
 
645
 
678
 
646
/*
679
/*
647
    MAKE A REGISTER INDIRECT WITH DISPLACEMENT OPERAND
680
    MAKE A REGISTER INDIRECT WITH DISPLACEMENT OPERAND
Line 650... Line 683...
650
    Under very rare circumstances, we may be trying to address relative
683
    Under very rare circumstances, we may be trying to address relative
651
    to a D-register, if which case we need to use a temporary A-register
684
    to a D-register, if which case we need to use a temporary A-register
652
    instead.
685
    instead.
653
*/
686
*/
654
 
687
 
655
mach_op *make_indirect
688
mach_op *
656
    PROTO_N ( ( r, d ) )
-
 
657
    PROTO_T ( int r X long d )
689
make_indirect(int r, long d)
658
{
690
{
659
    mach_op *p1 = new_mach_op () ;
691
	mach_op *p1 = new_mach_op();
660
    mach_op *p2 = new_mach_op () ;
692
	mach_op *p2 = new_mach_op();
661
    p1->type = MACH_CONT ;
693
	p1->type = MACH_CONT;
662
    p1->def.num = regmsk ( r ) ;
694
	p1->def.num = regmsk(r);
663
    p2->type = MACH_REG ;
695
	p2->type = MACH_REG;
664
    p2->def.num = ( long ) r ;
696
	p2->def.num = (long)r;
665
    if ( is_dreg ( r ) ) {
697
	if (is_dreg(r)) {
666
	int t = tmp_reg ( m_movl, p2 ) ;
698
		int t = tmp_reg(m_movl, p2);
667
	p2 = new_mach_op () ;
699
		p2 = new_mach_op();
668
	p2->type = MACH_REG ;
700
		p2->type = MACH_REG;
669
	p2->def.num = ( long ) t ;
701
		p2->def.num = (long)t;
670
	p1->def.num = regmsk ( t ) ;
702
		p1->def.num = regmsk(t);
671
    }
703
	}
672
    p1->of = p2 ;
704
	p1->of = p2;
673
    if ( d ) {
705
	if (d) {
674
	mach_op *p3 = new_mach_op () ;
706
		mach_op *p3 = new_mach_op();
675
	p3->type = MACH_VAL ;
707
		p3->type = MACH_VAL;
676
	p3->def.num = d ;
708
		p3->def.num = d;
677
	p2->plus = p3 ;
709
		p2->plus = p3;
678
    }
710
	}
679
    return ( p1 ) ;
711
	return (p1);
680
}
712
}
681
 
713
 
682
 
714
 
683
/*
715
/*
684
    MAKE A APPLICATION POINTER INDIRECT WITH DISPLACEMENT OPERAND
716
    MAKE A APPLICATION POINTER INDIRECT WITH DISPLACEMENT OPERAND
Line 686... Line 718...
686
    Since we don't want to use an applications pointer unless absolutely
718
    Since we don't want to use an applications pointer unless absolutely
687
    necessary, this is often changed into a stack pointer indirect
719
    necessary, this is often changed into a stack pointer indirect
688
    with displacement operand.
720
    with displacement operand.
689
*/
721
*/
690
 
722
 
691
mach_op *make_rel_ap
723
mach_op *
692
    PROTO_N ( ( d ) )
-
 
693
    PROTO_T ( long d )
724
make_rel_ap(long d)
694
{
725
{
695
    mach_op *p1 = new_mach_op () ;
726
	mach_op *p1 = new_mach_op();
696
    mach_op *p2 = new_mach_op () ;
727
	mach_op *p2 = new_mach_op();
697
    p1->type = MACH_CONT ;
728
	p1->type = MACH_CONT;
698
    p1->def.num = 0 ;
729
	p1->def.num = 0;
699
    p2->type = MACH_REG ;
730
	p2->type = MACH_REG;
700
    p1->of = p2 ;
731
	p1->of = p2;
701
    if ( d > 0 ) {
732
	if (d > 0) {
702
	if ( !used_stack ) {
733
		if (!used_stack) {
703
	    /* Use stack pointer instead of application pointer */
734
			/* Use stack pointer instead of application pointer */
704
	    long s = stack_size + stack_change ;
735
			long s = stack_size + stack_change;
705
	    mach_op *p3 = new_mach_op () ;
736
			mach_op *p3 = new_mach_op();
706
	    mach_op *p4 = new_mach_op () ;
737
			mach_op *p4 = new_mach_op();
707
	    p2->def.num = ( long ) REG_SP ;
738
			p2->def.num = (long)REG_SP;
708
	    p3->type = MACH_SPEC ;
739
			p3->type = MACH_SPEC;
709
	    p3->def.str = special_str ;
740
			p3->def.str = special_str;
710
	    p2->plus = p3 ;
741
			p2->plus = p3;
711
	    p4->type = MACH_VAL ;
742
			p4->type = MACH_VAL;
712
	    p4->def.num = d - s / 8 ;
743
			p4->def.num = d - s / 8;
713
	    p3->plus = p4 ;
744
			p3->plus = p4;
714
	    used_ldisp = 1 ;
745
			used_ldisp = 1;
715
	    return ( p1 ) ;
746
			return (p1);
-
 
747
		}
-
 
748
		d += 4;
716
	}
749
	}
717
	d += 4 ;
-
 
718
    }
-
 
719
    p2->def.num = ( long ) REG_AP ;
750
	p2->def.num = (long)REG_AP;
720
    if ( d ) {
751
	if (d) {
721
	mach_op *p3 = new_mach_op () ;
752
		mach_op *p3 = new_mach_op();
722
	p3->type = MACH_VAL ;
753
		p3->type = MACH_VAL;
723
	p3->def.num = d ;
754
		p3->def.num = d;
724
	p2->plus = p3 ;
755
		p2->plus = p3;
725
    }
756
	}
726
    used_stack = 1 ;
757
	used_stack = 1;
727
    return ( p1 ) ;
758
	return (p1);
728
}
759
}
729
 
760
 
730
#ifndef tdf3
761
#ifndef tdf3
731
/*
762
/*
732
    MAKE A 2. APPLICATION POINTER INDIRECT WITH DISPLACEMENT OPERAND
763
    MAKE A 2. APPLICATION POINTER INDIRECT WITH DISPLACEMENT OPERAND
733
 
764
 
734
    This application pointer A5 is used by general proc. to access
765
    This application pointer A5 is used by general proc. to access
735
    the caller parameters, when there are a dynamic number of callees.
766
    the caller parameters, when there are a dynamic number of callees.
736
*/
767
*/
737
 
768
 
738
mach_op *make_rel_ap2
769
mach_op *
739
    PROTO_N ( ( d ) )
-
 
740
    PROTO_T ( long d )
770
make_rel_ap2(long d)
741
{
771
{
742
    mach_op *p1 = new_mach_op () ;
772
	mach_op *p1 = new_mach_op();
743
    mach_op *p2 = new_mach_op () ;
773
	mach_op *p2 = new_mach_op();
744
    mach_op *p3 = new_mach_op () ;
774
	mach_op *p3 = new_mach_op();
745
 
775
 
746
    p1->type = MACH_CONT ;
776
	p1->type = MACH_CONT;
747
    p1->def.num = 0 ;
777
	p1->def.num = 0;
748
    p2->type = MACH_REG ;
778
	p2->type = MACH_REG;
749
    p1->of = p2 ;
779
	p1->of = p2;
750
    p2->def.num = ( long ) REG_A5 ;
780
	p2->def.num = (long)REG_A5;
751
 
781
 
752
    p3->type = MACH_VAL ;
782
	p3->type = MACH_VAL;
753
    p3->def.num = d ;
783
	p3->def.num = d;
754
    p2->plus = p3 ;
784
	p2->plus = p3;
755
 
785
 
756
    used_stack = 1 ;
786
	used_stack = 1;
757
    return ( p1 ) ;
787
	return (p1);
758
}
788
}
759
/*
789
/*
760
   Used to access caller parrameters in the postlude.
790
   Used to access caller parrameters in the postlude.
761
 */
791
 */
762
 
792
 
763
mach_op *make_rel_sp
793
mach_op *
764
    PROTO_N ( ( d ) )
-
 
765
    PROTO_T ( long d )
794
make_rel_sp(long d)
766
{
795
{
767
    mach_op *p1 = new_mach_op () ;
796
	mach_op *p1 = new_mach_op();
768
    mach_op *p2 = new_mach_op () ;
797
	mach_op *p2 = new_mach_op();
769
    mach_op *p3 = new_mach_op () ;
798
	mach_op *p3 = new_mach_op();
770
    long s = stack_size + stack_change ;
799
	long s = stack_size + stack_change;
771
 
800
 
772
    p1->type = MACH_CONT ;
801
	p1->type = MACH_CONT;
773
    p1->def.num = 0 ;
802
	p1->def.num = 0;
774
    p1->of = p2 ;
803
	p1->of = p2;
775
 
804
 
776
    p2->type = MACH_REG ;
805
	p2->type = MACH_REG;
777
    p2->def.num = ( long ) REG_SP ;
806
	p2->def.num = (long)REG_SP;
778
    p2->plus = p3 ;
807
	p2->plus = p3;
779
 
808
 
780
    p3->type = MACH_VAL ;
809
	p3->type = MACH_VAL;
781
    p3->def.num = d - s / 8 ;
810
	p3->def.num = d - s / 8;
782
 
811
 
783
    return ( p1 ) ;
812
	return (p1);
784
}
813
}
785
 
814
 
786
#endif
815
#endif
787
 
816
 
788
/*
817
/*
789
    MAKE A REGISTER INDIRECT WITH INDEX OPERAND
818
    MAKE A REGISTER INDIRECT WITH INDEX OPERAND
790
 
819
 
791
    Again we have to be careful, in case r1 is a D-register.
820
    Again we have to be careful, in case r1 is a D-register.
792
*/
821
*/
793
 
822
 
794
mach_op *make_reg_index
823
mach_op *
795
    PROTO_N ( ( r1, r2, d, sf ) )
-
 
796
    PROTO_T ( int r1 X int r2 X long d X int sf )
824
make_reg_index(int r1, int r2, long d, int sf)
797
{
825
{
798
    mach_op *p1 = new_mach_op () ;
826
	mach_op *p1 = new_mach_op();
799
    mach_op *p2 = new_mach_op () ;
827
	mach_op *p2 = new_mach_op();
800
    mach_op *p3 = new_mach_op () ;
828
	mach_op *p3 = new_mach_op();
801
    mach_op *p4 = new_mach_op () ;
829
	mach_op *p4 = new_mach_op();
802
    p1->type = MACH_CONT ;
830
	p1->type = MACH_CONT;
803
    p2->type = MACH_REG ;
831
	p2->type = MACH_REG;
804
    p2->def.num = ( long ) r1 ;
832
	p2->def.num = (long)r1;
805
    if ( is_dreg ( r1 ) ) {
833
	if (is_dreg(r1)) {
806
	int t = tmp_reg ( m_movl, p2 ) ;
834
		int t = tmp_reg(m_movl, p2);
807
	p2 = new_mach_op () ;
835
		p2 = new_mach_op();
808
	p2->type = MACH_REG ;
836
		p2->type = MACH_REG;
809
	p2->def.num = ( long ) t ;
837
		p2->def.num = (long)t;
810
	p1->def.num = ( regmsk ( t ) | regmsk ( r2 ) ) ;
838
		p1->def.num = (regmsk(t) | regmsk(r2));
811
    } else {
839
	} else {
812
	p1->def.num = ( regmsk ( r1 ) | regmsk ( r2 ) ) ;
840
		p1->def.num = (regmsk(r1) | regmsk(r2));
813
    }
841
	}
814
    p1->of = p2 ;
842
	p1->of = p2;
815
    p2->plus = p3 ;
843
	p2->plus = p3;
816
    p3->type = MACH_SCALE ;
844
	p3->type = MACH_SCALE;
817
    p3->def.num = ( long ) sf ;
845
	p3->def.num = (long)sf;
818
    p3->of = p4 ;
846
	p3->of = p4;
819
    p4->type = MACH_REG ;
847
	p4->type = MACH_REG;
820
    p4->def.num = ( long ) r2 ;
848
	p4->def.num = (long)r2;
821
    if ( d ) {
849
	if (d) {
822
	mach_op *p5 = new_mach_op () ;
850
		mach_op *p5 = new_mach_op();
823
	p5->type = MACH_VAL ;
851
		p5->type = MACH_VAL;
824
	p5->def.num = d ;
852
		p5->def.num = d;
825
	p3->plus = p5 ;
853
		p3->plus = p5;
826
    }
854
	}
827
    return ( p1 ) ;
855
	return (p1);
828
}
856
}
829
 
857
 
830
 
858
 
831
/*
859
/*
832
    MAKE A APPLICATION POINTER INDEXED WITH DISPLACEMENT OPERAND
860
    MAKE A APPLICATION POINTER INDEXED WITH DISPLACEMENT OPERAND
833
 
861
 
834
    It is always quicker to do this using a temporary register rather
862
    It is always quicker to do this using a temporary register rather
835
    than using the complex addressing mode.  However we do use the
863
    than using the complex addressing mode.  However we do use the
836
    latter course when temporary registers are short.
864
    latter course when temporary registers are short.
837
 
865
 
838
    Typ determines the type of the application pointer.
866
    Typ determines the type of the application pointer.
839
*/
867
*/
840
 
868
 
841
mach_op *_make_ind_rel_ap
869
mach_op *
842
    PROTO_N ( ( d, e, typ ) )
-
 
843
    PROTO_T ( long d X long e X int typ )
870
_make_ind_rel_ap(long d, long e, int typ)
844
{
871
{
845
    mach_op *p1, *p2 ;
872
	mach_op *p1, *p2;
846
 
873
 
847
    switch (typ) {
874
	switch (typ) {
848
    case par2_pl :
875
	case par2_pl:
849
      p2 = make_rel_ap2 ( d ) ;
876
		p2 = make_rel_ap2(d);
850
      break ;
877
		break;
851
    case par3_pl :
878
	case par3_pl:
852
      p2 = make_rel_sp ( d ) ;
879
		p2 = make_rel_sp(d);
853
      break ;
880
		break;
854
    default :
881
	default:
855
      p2 = make_rel_ap ( d ) ;
882
		p2 = make_rel_ap(d);
856
    }
883
	}
857
 
884
 
858
    if ( tmp_reg_status < 2 ) {
885
	if (tmp_reg_status < 2) {
859
	int t = tmp_reg ( m_movl, p2 ) ;
886
		int t = tmp_reg(m_movl, p2);
860
	return ( make_indirect ( t, e ) ) ;
887
		return (make_indirect(t, e));
861
    }
888
	}
862
 
889
 
863
    debug_warning ( "Complex operand" ) ;
890
	debug_warning("Complex operand");
864
 
891
 
865
    p1 = new_mach_op () ;
892
	p1 = new_mach_op();
866
    p1->type = MACH_CONT ;
893
	p1->type = MACH_CONT;
867
    p1->def.num = 0 ;
894
	p1->def.num = 0;
868
    p1->of = p2 ;
895
	p1->of = p2;
869
    if ( e ) {
896
	if (e) {
870
	mach_op *p3 = new_mach_op () ;
897
		mach_op *p3 = new_mach_op();
871
	p3->type = MACH_VAL ;
898
		p3->type = MACH_VAL;
872
	p3->def.num = e ;
899
		p3->def.num = e;
873
	p2->plus = p3 ;
900
		p2->plus = p3;
874
    }
901
	}
875
    return ( p1 ) ;
902
	return (p1);
876
}
903
}
877
 
904
 
878
mach_op *make_ind_rel_ap
905
mach_op *
879
    PROTO_N ( ( d, e) )
-
 
880
    PROTO_T ( long d X long e )
906
make_ind_rel_ap(long d, long e)
881
{
907
{
882
   return _make_ind_rel_ap ( d, e, 0 ) ;
908
	return _make_ind_rel_ap(d, e, 0);
883
}
909
}
884
 
910
 
885
mach_op *make_ind_rel_ap2
911
mach_op *
886
    PROTO_N ( ( d, e) )
-
 
887
    PROTO_T ( long d X long e )
912
make_ind_rel_ap2(long d, long e)
888
{
913
{
889
   return _make_ind_rel_ap ( d, e, par2_pl ) ;
914
	return _make_ind_rel_ap(d, e, par2_pl);
890
}
-
 
891
mach_op *make_ind_rel_ap3
-
 
892
    PROTO_N ( ( d, e) )
-
 
893
    PROTO_T ( long d X long e )
-
 
894
{
-
 
895
   return _make_ind_rel_ap ( d, e, par3_pl ) ;
-
 
896
}
915
}
897
 
-
 
898
 
-
 
899
 
-
 
900
/*
-
 
901
    MAKE A PRE-DECREMENT STACK POINTER OPERAND
-
 
902
*/
-
 
903
 
916
 
904
mach_op *make_dec_sp
917
mach_op *
905
    PROTO_Z ()
918
make_ind_rel_ap3(long d, long e)
906
{
919
{
907
    mach_op *p = new_mach_op () ;
920
	return _make_ind_rel_ap(d, e, par3_pl);
908
    p->type = MACH_DEC ;
-
 
909
    p->def.num = ( long ) REG_SP ;
-
 
910
    return ( p ) ;
-
 
911
}
921
}
912
 
922
 
-
 
923
 
913
 
924
 
-
 
925
/*
-
 
926
    MAKE A PRE-DECREMENT STACK POINTER OPERAND
-
 
927
*/
-
 
928
 
-
 
929
mach_op *
-
 
930
make_dec_sp(void)
-
 
931
{
-
 
932
	mach_op *p = new_mach_op();
-
 
933
	p->type = MACH_DEC;
-
 
934
	p->def.num = (long)REG_SP;
-
 
935
	return (p);
-
 
936
}
-
 
937
 
-
 
938
 
914
/*
939
/*
915
    MAKE A POST-INCREMENT STACK POINTER OPERAND
940
    MAKE A POST-INCREMENT STACK POINTER OPERAND
916
*/
941
*/
917
 
942
 
918
mach_op *make_inc_sp
943
mach_op *
919
    PROTO_Z ()
944
make_inc_sp(void)
920
{
945
{
921
    mach_op *p = new_mach_op () ;
946
	mach_op *p = new_mach_op();
922
    p->type = MACH_INC ;
947
	p->type = MACH_INC;
923
    p->def.num = ( long ) REG_SP ;
948
	p->def.num = (long)REG_SP;
924
    return ( p ) ;
949
	return (p);
925
}
950
}
926
 
951
 
927
#ifndef tdf3
952
#ifndef tdf3
928
/*
953
/*
929
    MAKE A PRE-DECREMENT REGISTER OPERAND
954
    MAKE A PRE-DECREMENT REGISTER OPERAND
930
*/
955
*/
931
 
956
 
932
mach_op *make_predec
957
mach_op *
933
    PROTO_N ( ( r ) )
-
 
934
    PROTO_T ( int r )
958
make_predec(int r)
935
{
959
{
936
    mach_op *p = new_mach_op () ;
960
	mach_op *p = new_mach_op();
937
    p->type = MACH_DEC ;
961
	p->type = MACH_DEC;
938
    p->def.num = ( long ) r ;
962
	p->def.num = (long)r;
939
    return ( p ) ;
963
	return (p);
940
}
964
}
941
#endif
965
#endif
942
 
966
 
943
/*
967
/*
944
    MAKE A POSTINCREMENT REGISTER OPERAND
968
    MAKE A POSTINCREMENT REGISTER OPERAND
945
*/
969
*/
946
 
970
 
947
mach_op *make_postinc
971
mach_op *
948
    PROTO_N ( ( r ) )
-
 
949
    PROTO_T ( int r )
972
make_postinc(int r)
950
{
973
{
951
    mach_op *p = new_mach_op () ;
974
	mach_op *p = new_mach_op();
952
    p->type = MACH_INC ;
975
	p->type = MACH_INC;
953
    p->def.num = ( long ) r ;
976
	p->def.num = (long)r;
954
    return ( p ) ;
977
	return (p);
955
}
978
}
956
 
979
 
957
 
980
 
958
/*
981
/*
959
    MAKE A REGISTER PAIR
982
    MAKE A REGISTER PAIR
960
*/
983
*/
961
 
984
 
962
mach_op *make_reg_pair
985
mach_op *
963
    PROTO_N ( ( r1, r2 ) )
-
 
964
    PROTO_T ( int r1 X int r2 )
986
make_reg_pair(int r1, int r2)
965
{
987
{
966
    mach_op *p1 = new_mach_op () ;
988
	mach_op *p1 = new_mach_op();
967
    mach_op *p2 = new_mach_op () ;
989
	mach_op *p2 = new_mach_op();
968
    p1->type = MACH_RPAIR ;
990
	p1->type = MACH_RPAIR;
969
    p1->def.num = ( long ) r1 ;
991
	p1->def.num = (long)r1;
970
    p1->plus = p2 ;
992
	p1->plus = p2;
971
    p2->type = MACH_REG ;
993
	p2->type = MACH_REG;
972
    p2->def.num = ( long ) r2 ;
994
	p2->def.num = (long)r2;
973
    return ( p1 ) ;
995
	return (p1);
974
}
996
}
975
 
997
 
976
 
998
 
977
/*
999
/*
978
    MAKE AN INDEX OPERAND
1000
    MAKE AN INDEX OPERAND
979
 
1001
 
980
    The machine operands op1 and op2 are turned into an index operand
1002
    The machine operands op1 and op2 are turned into an index operand
981
    with scale factor sf.  Unless op1 is very simple or temporary
1003
    with scale factor sf.  Unless op1 is very simple or temporary
982
    registers are short, it is always quicker to move the contents of
1004
    registers are short, it is always quicker to move the contents of
983
    op1 into a temporary register.  A temporary register may also be
1005
    op1 into a temporary register.  A temporary register may also be
984
    required for op2, but hopefully not too often.
1006
    required for op2, but hopefully not too often.
985
*/
1007
*/
986
 
1008
 
987
mach_op *make_index_op
1009
mach_op *
988
    PROTO_N ( ( op1, op2, sf ) )
-
 
989
    PROTO_T ( mach_op *op1 X mach_op *op2 X int sf )
1010
make_index_op(mach_op *op1, mach_op *op2, int sf)
990
{
1011
{
991
    bitpattern u ;
1012
	bitpattern u;
992
    bool use_tmp = 1 ;
1013
	bool use_tmp = 1;
993
    mach_op *p1, *p2 = new_mach_op () ;
1014
	mach_op *p1, *p2 = new_mach_op();
994
 
1015
 
995
    if ( op1->type != MACH_CONT ) {
1016
	if (op1->type != MACH_CONT) {
996
	error ( "Illegal indexing operand" ) ;
1017
		error("Illegal indexing operand");
997
	return ( null ) ;
1018
		return (null);
-
 
1019
	}
-
 
1020
 
-
 
1021
	p1 = op1->of;
-
 
1022
	u = op1->def.num;
-
 
1023
	if (p1->type == MACH_REG) {
-
 
1024
		use_tmp = is_dreg(p1->def.num);
-
 
1025
	} else if (tmp_reg_status && op2->type != MACH_REG) {
-
 
1026
		if (p1->type == MACH_EXT && p1->plus == null) {
-
 
1027
			p1->type = MACH_EXTQ;
-
 
1028
			use_tmp = 0;
-
 
1029
		} else if (p1->type == MACH_CONT) {
-
 
1030
			mach_op *q = p1->of;
-
 
1031
			if (q->type == MACH_REG) {
-
 
1032
				q = q->plus;
-
 
1033
				if (q == null || q->type != MACH_SCALE) {
-
 
1034
					use_tmp = 0;
998
    }
1035
				}
-
 
1036
			}
-
 
1037
		}
-
 
1038
	}
999
 
1039
 
1000
    p1 = op1->of ;
1040
	if (use_tmp) {
1001
    u = op1->def.num ;
1041
		int t = tmp_reg(m_movl, p1);
1002
    if ( p1->type == MACH_REG ) {
-
 
1003
	use_tmp = is_dreg ( p1->def.num ) ;
1042
		p1 = new_mach_op();
1004
    } else if ( tmp_reg_status && op2->type != MACH_REG ) {
-
 
1005
	if ( p1->type == MACH_EXT && p1->plus == null ) {
-
 
1006
	    p1->type = MACH_EXTQ ;
1043
		p1->type = MACH_REG;
1007
	    use_tmp = 0 ;
-
 
1008
	} else if ( p1->type == MACH_CONT ) {
-
 
1009
	    mach_op *q = p1->of ;
1044
		p1->def.num = (long)t;
1010
	    if ( q->type == MACH_REG ) {
-
 
1011
		q = q->plus ;
1045
		u = regmsk(t);
1012
		if ( q == null || q->type != MACH_SCALE ) use_tmp = 0 ;
-
 
1013
	    }
-
 
1014
	}
1046
	}
1015
    }
-
 
1016
 
-
 
1017
    if ( use_tmp ) {
-
 
1018
	int t = tmp_reg ( m_movl, p1 ) ;
-
 
1019
	p1 = new_mach_op () ;
-
 
1020
	p1->type = MACH_REG ;
-
 
1021
	p1->def.num = ( long ) t ;
-
 
1022
	u = regmsk ( t ) ;
-
 
1023
    }
-
 
1024
    op1->of = p1 ;
1047
	op1->of = p1;
1025
    p2->type = MACH_SCALE ;
1048
	p2->type = MACH_SCALE;
1026
    p2->def.num = ( long ) sf ;
1049
	p2->def.num = (long)sf;
1027
    p2->plus = p1->plus ;
1050
	p2->plus = p1->plus;
1028
    p1->plus = p2 ;
1051
	p1->plus = p2;
1029
    if ( op2->type == MACH_REG ) {
1052
	if (op2->type == MACH_REG) {
1030
	u |= regmsk ( op2->def.num ) ;
1053
		u |= regmsk(op2->def.num);
1031
    } else {
1054
	} else {
1032
	int t = tmp_reg ( m_movl, op2 ) ;
1055
		int t = tmp_reg(m_movl, op2);
1033
	op2 = new_mach_op () ;
1056
		op2 = new_mach_op();
1034
	op2->type = MACH_REG ;
1057
		op2->type = MACH_REG;
1035
	op2->def.num = ( long ) t ;
1058
		op2->def.num = (long)t;
1036
	u |= regmsk ( t ) ;
1059
		u |= regmsk(t);
1037
    }
1060
	}
1038
    p2->of = op2 ;
1061
	p2->of = op2;
1039
    op1->def.num = u ;
1062
	op1->def.num = u;
1040
    return ( op1 ) ;
1063
	return (op1);
1041
}
1064
}
1042
 
1065
 
1043
 
1066
 
1044
/*
1067
/*
1045
    MAKE A BITFIELD OPERAND
1068
    MAKE A BITFIELD OPERAND
1046
 
1069
 
1047
    The machine operand op is turned into the corresponding bitfield
1070
    The machine operand op is turned into the corresponding bitfield
1048
    operand.
1071
    operand.
1049
*/
1072
*/
1050
 
1073
 
1051
mach_op *make_bitfield_op
1074
mach_op *
1052
    PROTO_N ( ( op, bf_off, bf_bits ) )
-
 
1053
    PROTO_T ( mach_op *op X int bf_off X int bf_bits )
1075
make_bitfield_op(mach_op *op, int bf_off, int bf_bits)
1054
{
1076
{
1055
    mach_op *p1 = new_mach_op () ;
1077
	mach_op *p1 = new_mach_op();
1056
    mach_op *p2 = new_mach_op () ;
1078
	mach_op *p2 = new_mach_op();
1057
    p1->type = MACH_BF ;
1079
	p1->type = MACH_BF;
1058
    p1->def.num = ( long ) bf_off ;
1080
	p1->def.num = (long)bf_off;
1059
    p1->plus = p2 ;
1081
	p1->plus = p2;
1060
    p1->of = op ;
1082
	p1->of = op;
1061
    p2->type = MACH_VAL ;
1083
	p2->type = MACH_VAL;
1062
    p2->def.num = ( long ) bf_bits ;
1084
	p2->def.num = (long)bf_bits;
1063
    return ( p1 ) ;
1085
	return (p1);
1064
}
1086
}