Subversion Repositories tendra.SVN

Rev

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

Rev 5 Rev 6
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 89... Line 119...
89
 
119
 
90
/*
120
/*
91
    OUTPUT FILE
121
    OUTPUT FILE
92
*/
122
*/
93
 
123
 
94
FILE *fpout ;
124
FILE *fpout;
95
 
125
 
96
 
126
 
97
/*
127
/*
98
    OPEN OUTPUT FILE
128
    OPEN OUTPUT FILE
99
 
129
 
100
    This routine opens the file with the given name for output.  If the
130
    This routine opens the file with the given name for output.  If the
101
    name is null, the standard output is used.
131
    name is null, the standard output is used.
102
*/
132
*/
103
 
133
 
104
void open_output
134
void
105
    PROTO_N ( ( nm ) )
-
 
106
    PROTO_T ( char *nm )
135
open_output(char *nm)
107
{
136
{
108
    if ( nm == null ) {
137
	if (nm == null) {
109
	fpout = stdout ;
138
		fpout = stdout;
110
    } else {
139
	} else {
111
	fpout = fopen ( nm, "w" ) ;
140
		fpout = fopen(nm, "w");
112
	if ( fpout == null ) {
141
		if (fpout == null) {
113
	    error ( "Can't open output file, %s", nm ) ;
142
			error("Can't open output file, %s", nm);
114
	    exit ( EXIT_FAILURE ) ;
143
			exit(EXIT_FAILURE);
-
 
144
		}
115
	}
145
	}
116
    }
-
 
117
    return ;
146
	return;
118
}
147
}
119
 
148
 
120
 
149
 
121
/*
150
/*
122
    ARRAY OF INSTRUCTION NAMES
151
    ARRAY OF INSTRUCTION NAMES
123
 
152
 
124
    This table gives the mapping between instruction numbers and the
153
    This table gives the mapping between instruction numbers and the
125
    corresponding names.
154
    corresponding names.
126
*/
155
*/
127
 
156
 
128
#ifdef asm_dotty_instrs
157
#ifdef asm_dotty_instrs
129
#define INSTR_SET_0
158
#define INSTR_SET_0
130
#endif /* asm_dotty_instrs */
159
#endif /* asm_dotty_instrs */
131
 
160
 
132
#ifdef asm_simple_instrs
161
#ifdef asm_simple_instrs
133
#define INSTR_SET_1
162
#define INSTR_SET_1
134
#endif /* asm_simple_instrs */
163
#endif /* asm_simple_instrs */
135
 
164
 
136
char *instr_names [] = {
165
char *instr_names[] = {
137
#include "instr_aux.h"
166
#include "instr_aux.h"
138
} ;
167
};
139
 
168
 
140
 
169
 
141
/*
170
/*
142
    ARRAY OF GLOBAL REGISTER NAMES
171
    ARRAY OF GLOBAL REGISTER NAMES
143
 
172
 
144
    This table gives the mapping between register numbers and register
173
    This table gives the mapping between register numbers and register
145
    names.
174
    names.
146
*/
175
*/
147
 
176
 
148
#ifdef asm_percent_regs
177
#ifdef asm_percent_regs
Line 151... Line 180...
151
 
180
 
152
#ifdef asm_simple_regs
181
#ifdef asm_simple_regs
153
#define REGISTER_SET_1
182
#define REGISTER_SET_1
154
#endif /* asm_simple_regs */
183
#endif /* asm_simple_regs */
155
 
184
 
156
static char *glob_reg_names [] = {
185
static char *glob_reg_names[] = {
157
#include "instr_aux.h"
186
#include "instr_aux.h"
158
} ;
187
};
159
 
188
 
160
 
189
 
161
/*
190
/*
162
    ARRAY OF LOCAL REGISTER NAMES
191
    ARRAY OF LOCAL REGISTER NAMES
163
 
192
 
164
    This table gives the local mapping between register numbers and
193
    This table gives the local mapping between register numbers and
165
    register names.  It is initialized from the table of global register
194
    register names.  It is initialized from the table of global register
166
    names, but may be changed thereafter.
195
    names, but may be changed thereafter.
167
*/
196
*/
168
 
197
 
169
char *reg_names [ NO_OF_REGS ] ;
198
char *reg_names[NO_OF_REGS];
170
 
199
 
171
 
200
 
172
/*
201
/*
173
    OUTPUT A REGISTER NAME
202
    OUTPUT A REGISTER NAME
174
 
203
 
175
    This routine outputs the register name corresponding to a given
204
    This routine outputs the register name corresponding to a given
176
    register number.
205
    register number.
177
*/
206
*/
178
 
207
 
179
#define  out_reg_name( X )	outs ( reg_names [ ( X ) ] )
208
#define  out_reg_name(X)	outs(reg_names[(X)])
180
 
209
 
181
 
210
 
182
/*
211
/*
183
    OUTPUT A SUM OF DATA, EXTERNALS AND LABELS
212
    OUTPUT A SUM OF DATA, EXTERNALS AND LABELS
184
 
213
 
185
    This routine prints the sum of all data, external and labels, starting
214
    This routine prints the sum of all data, external and labels, starting
186
    with ptr, and moving down the plus-chain.
215
    with ptr, and moving down the plus-chain.
187
*/
216
*/
188
 
217
 
189
static void out_data
218
static void
190
    PROTO_N ( ( ptr ) )
-
 
191
    PROTO_T ( mach_op *ptr )
219
out_data(mach_op *ptr)
192
{
220
{
193
    mach_op *p ;
221
	mach_op *p;
194
    bool neg_next = 0 ;
222
	bool neg_next = 0;
195
    bool need_plus = 0 ;
223
	bool need_plus = 0;
196
    for ( p = ptr ; p ; p = p->plus ) {
224
	for (p = ptr; p; p = p->plus) {
197
	switch ( p->type ) {
225
		switch (p->type) {
198
 
-
 
199
	    case MACH_EXT :
226
		case MACH_EXT:
200
	    case MACH_EXTQ : {
227
		case MACH_EXTQ:
-
 
228
			if (need_plus || neg_next) {
201
		if ( need_plus || neg_next ) outc ( neg_next ? '-' : '+' ) ;
229
				outc(neg_next ? '-' : '+');
-
 
230
			}
202
		outs ( p->def.str ) ;
231
			outs(p->def.str);
203
		need_plus = 1 ;
232
			need_plus = 1;
204
		neg_next = 0 ;
233
			neg_next = 0;
205
		break ;
234
			break;
206
	    }
-
 
207
 
-
 
208
	    case MACH_LAB :
235
		case MACH_LAB:
209
	    case MACH_LABQ : {
236
		case MACH_LABQ:
-
 
237
			if (need_plus || neg_next) {
210
		if ( need_plus || neg_next ) outc ( neg_next ? '-' : '+' ) ;
238
				outc(neg_next ? '-' : '+');
-
 
239
			}
211
		outc ( LPREFIX ) ;
240
			outc(LPREFIX);
212
		outn ( p->def.num ) ;
241
			outn(p->def.num);
213
		need_plus = 1 ;
242
			need_plus = 1;
214
		neg_next = 0 ;
243
			neg_next = 0;
215
		break ;
244
			break;
216
	    }
-
 
217
 
-
 
218
	    case MACH_SPEC :
245
		case MACH_SPEC:
219
	    case MACH_SPECQ : {
246
		case MACH_SPECQ:
220
		if ( !output_immediately && p->def.str == special_str ) {
247
			if (!output_immediately && p->def.str == special_str) {
221
		    /* The value of LSx is known, so use it */
248
				/* The value of LSx is known, so use it */
222
		    long n = ldisp ;
249
				long n = ldisp;
223
		    if ( neg_next ) n = ( -n ) ;
250
				if (neg_next) {
-
 
251
					n = (-n);
-
 
252
				}
224
		    if ( p->plus && p->plus->type == MACH_VAL ) {
253
				if (p->plus && p->plus->type == MACH_VAL) {
225
			p->plus->def.num += n ;
254
					p->plus->def.num += n;
226
		    } else {
255
				} else {
227
			if ( need_plus && n >= 0 ) outc ( '+' ) ;
256
					if (need_plus && n >= 0) {
-
 
257
						outc('+');
-
 
258
					}
228
			outn ( n ) ;
259
					outn(n);
229
			need_plus = 1 ;
260
					need_plus = 1;
230
		    }
261
				}
231
		} else {
262
			} else {
-
 
263
				if (need_plus || neg_next) {
232
		    if ( need_plus || neg_next ) outc ( neg_next ? '-' : '+' ) ;
264
					outc(neg_next ? '-' : '+');
-
 
265
				}
233
		    outc ( LPREFIX ) ;
266
				outc(LPREFIX);
234
		    outs ( p->def.str ) ;
267
				outs(p->def.str);
235
		    outn ( ( long ) special_no ) ;
268
				outn((long)special_no);
236
		    need_plus = 1 ;
269
				need_plus = 1;
237
		}
270
			}
238
		neg_next = 0 ;
271
			neg_next = 0;
239
		break ;
272
			break;
240
	    }
-
 
241
 
-
 
242
	    case MACH_VAL :
273
		case MACH_VAL:
243
	    case MACH_VALQ : {
274
		case MACH_VALQ: {
244
		long n = p->def.num ;
275
			long n = p->def.num;
245
		if ( neg_next ) n = ( -n ) ;
276
			if (neg_next) {
-
 
277
				n = (-n);
-
 
278
			}
246
		if ( need_plus && n >= 0 ) outc ( '+' ) ;
279
			if (need_plus && n >= 0) {
-
 
280
				outc('+');
-
 
281
			}
247
		outn ( n ) ;
282
			outn(n);
248
		need_plus = 1 ;
283
			need_plus = 1;
249
		neg_next = 0 ;
284
			neg_next = 0;
250
		break ;
285
			break;
251
	    }
286
		}
252
 
-
 
253
	    case MACH_HEX :
287
		case MACH_HEX:
254
	    case MACH_HEXQ : {
288
		case MACH_HEXQ: {
255
		long n = p->def.num ;
289
			long n = p->def.num;
256
		if ( neg_next ) n = ( -n ) ;
290
			if (neg_next) {
-
 
291
				n = (-n);
-
 
292
			}
257
		if ( need_plus && n >= 0 ) outc ( '+' ) ;
293
			if (need_plus && n >= 0) {
-
 
294
				outc('+');
-
 
295
			}
258
		outh ( n ) ;
296
			outh(n);
259
		need_plus = 1 ;
297
			need_plus = 1;
260
		neg_next = 0 ;
298
			neg_next = 0;
261
		break ;
299
			break;
262
	    }
300
		}
263
 
-
 
264
	    case MACH_NEG : {
301
		case MACH_NEG:
265
		neg_next = 1 ;
302
			neg_next = 1;
266
		break ;
303
			break;
267
	    }
304
		default:
268
 
-
 
269
	    default : return ;
305
			return;
270
	}
306
		}
271
    }
307
	}
272
    return ;
308
	return;
273
}
309
}
274
 
310
 
275
 
311
 
276
/*
312
/*
277
    OUTPUT A SCALED OPERAND
313
    OUTPUT A SCALED OPERAND
278
 
314
 
279
    This routine outputs a scaled register operand.
315
    This routine outputs a scaled register operand.
280
*/
316
*/
281
 
317
 
282
static void out_scaled
318
static void
283
    PROTO_N ( ( ptr ) )
-
 
284
    PROTO_T ( mach_op *ptr )
319
out_scaled(mach_op *ptr)
285
{
320
{
286
    long sf = ptr->def.num ;
321
	long sf = ptr->def.num;
287
    asm_scale_before ;
322
	asm_scale_before;
288
    out_reg_name ( ptr->of->def.num ) ;
323
	out_reg_name(ptr->of->def.num);
289
    if ( sf == 1 ) {
324
	if (sf == 1) {
290
	asm_scale_1 ;
325
		asm_scale_1;
291
    } else {
326
	} else {
292
	asm_scale ;
327
		asm_scale;
293
	outn ( sf ) ;
328
		outn(sf);
294
    }
329
	}
295
    return ;
330
	return;
296
}
331
}
297
 
332
 
298
 
333
 
299
/*
334
/*
300
    OUTPUT A FLOATING POINT NUMBER
335
    OUTPUT A FLOATING POINT NUMBER
301
 
336
 
302
    This routine outputs a floating point number.
337
    This routine outputs a floating point number.
303
*/
338
*/
304
 
339
 
305
static void out_float
340
static void
306
    PROTO_N ( ( f ) )
-
 
307
    PROTO_T ( flt *f )
341
out_float(flt *f)
308
{
342
{
309
#if ( FBASE == 10 )
343
#if (FBASE == 10)
310
    int i ;
344
	int i;
311
    asm_fprefix ;
345
	asm_fprefix;
312
    if ( f->sign < 0 ) outc ( '-' ) ;
346
	if (f->sign < 0) {
-
 
347
		outc('-');
-
 
348
	}
313
    outc ( '0' + f->mant [0] ) ;
349
	outc('0' + f->mant[0]);
314
    outc ( '.' ) ;
350
	outc('.');
315
    for ( i = 1 ; i < MANT_SIZE ; i++ ) outc ( '0' + f->mant [i] ) ;
351
	for (i = 1; i < MANT_SIZE; i++) {
-
 
352
		outc('0' + f->mant[i]);
-
 
353
	}
316
    outc ( 'e' ) ;
354
	outc('e');
317
    if ( f->exp >= 0 ) outc ( '+' ) ;
355
	if (f->exp >= 0) {
-
 
356
		outc('+');
-
 
357
	}
318
    outn ( f->exp ) ;
358
	outn(f->exp);
319
#else
359
#else
320
    error ( "Illegal floating point constant" ) ;
360
	error("Illegal floating point constant");
321
#endif
361
#endif
322
    return ;
362
	return;
323
}
363
}
324
 
364
 
325
 
365
 
326
/*
366
/*
327
    MACROS FOR CONSTRUCTS DEPENDING ON asm_data_first
367
    MACROS FOR CONSTRUCTS DEPENDING ON asm_data_first
328
*/
368
*/
329
 
369
 
330
#ifdef asm_data_first
370
#ifdef asm_data_first
331
 
371
 
332
#define  out_data_1( X )	if ( X ) out_data ( X )
372
#define  out_data_1(X)		if (X)out_data(X)
333
#define  out_data_1a( X )	if ( X ) { out_data ( X ) ; outc ( ',' ) ; }
373
#define  out_data_1a(X)		if (X) { out_data(X); outc(','); }
334
#define  out_data_1b( X )	if ( X ) { outc ( ',' ) ; out_data ( X ) ; }
374
#define  out_data_1b(X)		if (X) { outc(','); out_data(X); }
335
#define  out_sf_data( X, Y )	if ( Y ) out_scaled ( Y )
375
#define  out_sf_data(X, Y)	if (Y)out_scaled(Y)
336
 
376
 
337
#else /* asm_data_first */
377
#else /* asm_data_first */
338
 
378
 
339
#define  out_data_1( X )	/* empty */
379
#define  out_data_1( X )	/* empty */
340
#define  out_data_1a( X )	/* empty */
380
#define  out_data_1a( X )	/* empty */
341
#define  out_data_1b( X )	/* empty */
381
#define  out_data_1b( X )	/* empty */
342
#define  out_sf_data( X, Y )	\
382
#define  out_sf_data(X, Y)		\
343
    if ( X ) {			\
383
    if (X) {				\
344
	outc ( '(' ) ;		\
384
	    outc('(');			\
345
	out_data ( X ) ;	\
385
	    out_data(X);		\
346
	if ( Y ) {		\
386
	    if (Y) {			\
347
	    outc ( ',' ) ;	\
387
		    outc(',');		\
348
	    out_scaled ( Y ) ;	\
388
		    out_scaled(Y);	\
349
	}			\
389
	    }				\
350
	outc ( ')' ) ;		\
390
	    outc(')');			\
351
    } else {			\
391
    } else {				\
352
	if ( Y ) {		\
392
	    if (Y) {			\
353
	    outc ( '(' ) ;	\
393
		    outc('(');		\
354
	    out_scaled ( Y ) ;	\
394
		    out_scaled(Y);	\
355
	    outc ( ')' ) ;	\
395
		    outc(')');		\
356
	}			\
396
	    }				\
357
    }
397
    }
358
 
398
 
359
#endif /* asm_data_first */
399
#endif /* asm_data_first */
360
 
400
 
361
 
401
 
362
/*
402
/*
363
    OUTPUT A MACHINE OPERAND
403
   OUTPUT A MACHINE OPERAND
364
 
404
 
365
    This routine prints a machine operand.
405
   This routine prints a machine operand.
366
*/
406
 */
367
 
407
 
368
static void out_mach_op
408
static void
369
    PROTO_N ( ( ptr ) )
-
 
370
    PROTO_T ( mach_op *ptr )
409
out_mach_op(mach_op *ptr)
371
{
410
{
372
    mach_op *p = ptr ;
411
	mach_op *p = ptr;
373
    switch ( p->type ) {
412
	switch (p->type) {
374
 
-
 
375
	case MACH_BF : {
413
	case MACH_BF: {
376
	    /* Bitfield operands */
414
		/* Bitfield operands */
377
	    long bf_off = p->def.num ;
415
		long bf_off = p->def.num;
378
	    long bf_bits = p->plus->def.num ;
416
		long bf_bits = p->plus->def.num;
379
	    out_mach_op ( p->of ) ;
417
		out_mach_op(p->of);
380
	    asm_bf_before ;
418
		asm_bf_before;
381
	    asm_nprefix ;
419
		asm_nprefix;
382
	    outn ( bf_off ) ;
420
		outn(bf_off);
383
	    asm_bf_middle ;
421
		asm_bf_middle;
384
	    asm_nprefix ;
422
		asm_nprefix;
385
	    outn ( bf_bits ) ;
423
		outn(bf_bits);
386
	    asm_bf_after ;
424
		asm_bf_after;
387
	    return ;
425
		return;
388
	}
426
	}
389
 
-
 
390
	case MACH_CONT : {
427
	case MACH_CONT:
391
	    p = p->of ;
428
		p = p->of;
392
	    switch ( p->type ) {
429
		switch (p->type) {
393
 
-
 
394
		case MACH_CONT : {
430
		case MACH_CONT: {
395
		    /* Memory indirect (post- or pre-indexed) */
431
			/* Memory indirect (post- or pre-indexed) */
396
		    mach_op *p1 = p->plus ;
432
			mach_op *p1 = p->plus;
397
		    mach_op *p2 = null ;
433
			mach_op *p2 = null;
398
		    mach_op *q = p->of ;
434
			mach_op *q = p->of;
399
		    mach_op *q1 = q->plus ;
435
			mach_op *q1 = q->plus;
400
		    mach_op *q2 = null ;
436
			mach_op *q2 = null;
401
		    if ( p1 && p1->type == MACH_SCALE ) {
437
			if (p1 && p1->type == MACH_SCALE) {
402
			p2 = p1 ;
438
				p2 = p1;
403
			p1 = p2->plus ;
439
				p1 = p2->plus;
404
		    }
440
			}
405
		    if ( q1 && q1->type == MACH_SCALE ) {
441
			if (q1 && q1->type == MACH_SCALE) {
406
			if ( p2 ) {
442
				if (p2) {
407
			    error ( "Illegal addressing mode" ) ;
443
					error("Illegal addressing mode");
408
			    outs ( "error" ) ;
444
					outs("error");
409
			    return ;
445
					return;
-
 
446
				}
-
 
447
				q2 = q1;
-
 
448
				q1 = q2->plus;
410
			}
449
			}
411
			q2 = q1 ;
-
 
412
			q1 = q2->plus ;
-
 
413
		    }
-
 
414
		    asm_mem_before ;
450
			asm_mem_before;
415
		    out_data_1a ( q1 ) ;
451
			out_data_1a(q1);
416
		    out_reg_name ( q->def.num ) ;
452
			out_reg_name(q->def.num);
417
		    asm_mem_second ;
453
			asm_mem_second;
418
		    out_sf_data ( q1, q2 ) ;
454
			out_sf_data(q1, q2);
419
		    asm_mem_third ;
455
			asm_mem_third;
420
		    out_sf_data ( p1, p2 ) ;
456
			out_sf_data(p1, p2);
421
		    if ( p2 ) out_scaled ( p2 ) ;
-
 
422
		    out_data_1b ( p1 ) ;
-
 
423
		    asm_mem_after ;
-
 
424
		    return ;
-
 
425
		}
-
 
426
 
-
 
427
		case MACH_REG : {
-
 
428
		    /* Register indirect (with displacement or index) */
-
 
429
		    mach_op *p1 = p->plus ;
-
 
430
		    mach_op *p2 = null ;
-
 
431
		    if ( p1 ) {
457
			if (p2) {
432
			if ( p1->type == MACH_SCALE ) {
-
 
433
			    p2 = p1 ;
-
 
434
			    p1 = p2->plus ;
-
 
435
			}
-
 
436
			out_data_1 ( p1 ) ;
458
				out_scaled(p2);
437
		    }
-
 
438
		    asm_ind_before ;
-
 
439
		    out_reg_name ( p->def.num ) ;
-
 
440
		    asm_ind_middle ;
-
 
441
		    out_sf_data ( p1, p2 ) ;
-
 
442
		    asm_ind_after ;
-
 
443
		    return ;
-
 
444
		}
-
 
445
 
-
 
446
		case MACH_EXTQ : {
-
 
447
		    /* External indirect (with displacement or index) */
-
 
448
		    mach_op *p1 = p->plus ;
-
 
449
		    mach_op *p2 = null ;
-
 
450
		    if ( p1 ) {
-
 
451
			if ( p1->type == MACH_SCALE ) {
-
 
452
			    p2 = p1 ;
-
 
453
			    p1 = p2->plus ;
-
 
454
			}
459
			}
455
			out_data_1 ( p1 ) ;
460
			out_data_1b(p1);
456
		    }
-
 
457
		    asm_ind_before ;
-
 
458
		    outs ( p->def.str ) ;
-
 
459
		    asm_ind_middle ;
-
 
460
		    out_sf_data ( p1, p2 ) ;
-
 
461
		    asm_ind_after ;
461
			asm_mem_after;
462
		    return ;
462
			return;
463
		}
463
		}
-
 
464
		case MACH_REG: {
-
 
465
			/* Register indirect (with displacement or index) */
-
 
466
			mach_op *p1 = p->plus;
-
 
467
			mach_op *p2 = null;
-
 
468
			if (p1) {
-
 
469
				if (p1->type == MACH_SCALE) {
-
 
470
					p2 = p1;
-
 
471
					p1 = p2->plus;
-
 
472
				}
-
 
473
				out_data_1(p1);
-
 
474
			}
-
 
475
			asm_ind_before;
-
 
476
			out_reg_name(p->def.num);
-
 
477
			asm_ind_middle;
-
 
478
			out_sf_data(p1, p2);
-
 
479
			asm_ind_after;
-
 
480
			return;
464
 
481
		}
-
 
482
		case MACH_EXTQ: {
-
 
483
			/* External indirect (with displacement or index) */
-
 
484
			mach_op *p1 = p->plus;
-
 
485
			mach_op *p2 = null;
-
 
486
			if (p1) {
-
 
487
				if (p1->type == MACH_SCALE) {
-
 
488
					p2 = p1;
-
 
489
					p1 = p2->plus;
-
 
490
				}
-
 
491
				out_data_1(p1);
-
 
492
			}
-
 
493
			asm_ind_before;
-
 
494
			outs(p->def.str);
-
 
495
			asm_ind_middle;
-
 
496
			out_sf_data(p1, p2);
-
 
497
			asm_ind_after;
-
 
498
			return;
-
 
499
		}
465
		case MACH_EXT :
500
		case MACH_EXT:
466
		case MACH_LAB :
501
		case MACH_LAB:
467
		case MACH_SPEC :
502
		case MACH_SPEC:
468
		case MACH_VAL :
503
		case MACH_VAL:
469
		case MACH_HEX :
504
		case MACH_HEX:
470
		case MACH_NEG : {
505
		case MACH_NEG:
471
		    /* Contents of immediate data, externals, labels */
506
			/* Contents of immediate data, externals, labels */
472
		    out_data ( p ) ;
507
			out_data(p);
473
		    return ;
508
			return;
474
		}
509
		}
475
	    }
-
 
476
	    error ( "Illegal addressing mode" ) ;
510
		error("Illegal addressing mode");
477
	    outs ( "error" ) ;
511
		outs("error");
478
	    return ;
512
		return;
479
	}
513
	}
480
 
-
 
481
	case MACH_DEC : {
514
	case MACH_DEC:
482
	    /* Register indirect with predecrement */
515
		/* Register indirect with predecrement */
483
	    asm_predec_before ;
516
		asm_predec_before;
484
	    out_reg_name ( p->def.num ) ;
517
		out_reg_name(p->def.num);
485
	    asm_predec_after ;
518
		asm_predec_after;
486
	    return ;
519
		return;
487
	}
-
 
488
 
-
 
489
	case MACH_INC : {
520
	case MACH_INC:
490
	    /* Register indirect with postincrement */
521
		/* Register indirect with postincrement */
491
	    asm_postinc_before ;
522
		asm_postinc_before;
492
	    out_reg_name ( p->def.num ) ;
523
		out_reg_name(p->def.num);
493
	    asm_postinc_after ;
524
		asm_postinc_after;
494
	    return ;
525
		return;
495
	}
-
 
496
 
-
 
497
	case MACH_REG : {
526
	case MACH_REG:
498
	    /* Register direct */
527
		/* Register direct */
499
	    out_reg_name ( p->def.num ) ;
528
		out_reg_name(p->def.num);
500
	    return ;
529
		return;
501
	}
-
 
502
 
-
 
503
	case MACH_RPAIR : {
530
	case MACH_RPAIR:
504
	    /* Register pair */
531
		/* Register pair */
505
	    out_reg_name ( p->def.num ) ;
532
		out_reg_name(p->def.num);
506
	    asm_rpair_sep ;
533
		asm_rpair_sep;
507
	    out_reg_name ( p->plus->def.num ) ;
534
		out_reg_name(p->plus->def.num);
508
	    return ;
535
		return;
509
	}
-
 
510
 
-
 
511
	case MACH_EXT :
536
	case MACH_EXT:
512
	case MACH_LAB :
537
	case MACH_LAB:
513
	case MACH_SPEC :
538
	case MACH_SPEC:
514
	case MACH_VAL :
539
	case MACH_VAL:
515
	case MACH_HEX : {
540
	case MACH_HEX:
516
	    /* Immediate data, externals, labels */
541
		/* Immediate data, externals, labels */
517
	    asm_nprefix ;
542
		asm_nprefix;
518
	    out_data ( p ) ;
543
		out_data(p);
519
	    return ;
544
		return;
520
	}
-
 
521
 
-
 
522
	case MACH_EXTQ :
545
	case MACH_EXTQ:
523
	case MACH_LABQ :
546
	case MACH_LABQ:
524
	case MACH_SPECQ : {
547
	case MACH_SPECQ:
525
	    /* Contents of externals, labels */
548
		/* Contents of externals, labels */
526
	    out_data ( p ) ;
549
		out_data(p);
527
	    return ;
550
		return;
528
	}
-
 
529
 
-
 
530
	case MACH_FLOATQ : {
551
	case MACH_FLOATQ:
531
	    /* Floating-point data */
552
		/* Floating-point data */
532
	    out_float ( p->def.fp ) ;
553
		out_float(p->def.fp);
533
	    return ;
554
		return;
534
	}
-
 
535
 
-
 
536
	case MACH_VALQ : {
555
	case MACH_VALQ:
537
	    /* Integer data */
556
		/* Integer data */
538
	    outn ( p->def.num ) ;
557
		outn(p->def.num);
539
	    return ;
558
		return;
540
	}
-
 
541
 
-
 
542
	case MACH_HEXQ : {
559
	case MACH_HEXQ:
543
	    /* Integer data */
560
		/* Integer data */
544
	    outh ( p->def.num ) ;
561
		outh(p->def.num);
545
	    return ;
562
		return;
546
	}
563
	}
547
    }
-
 
548
    error ( "Illegal addressing mode" ) ;
564
	error("Illegal addressing mode");
549
    outs ( "error" ) ;
565
	outs("error");
550
    return ;
566
	return;
551
}
567
}
552
 
568
 
553
 
569
 
554
/*
570
/*
555
    OUTPUT ALL MACHINE INSTRUCTIONS
571
    OUTPUT ALL MACHINE INSTRUCTIONS
556
 
572
 
557
    This routine outputs all the machine instructions, together with their
573
    This routine outputs all the machine instructions, together with their
558
    operands (if any).
574
    operands (if any).
559
*/
575
*/
560
 
576
 
561
void output_all
577
void
562
    PROTO_Z ()
578
output_all(void)
563
{
579
{
564
    int n ;
580
	int n;
565
    mach_ins *p ;
581
	mach_ins *p;
566
    for ( p = all_mach_ins ; p ; p = p->next ) {
582
	for (p = all_mach_ins; p; p = p->next) {
567
	n = p->ins_no ;
583
		n = p->ins_no;
568
#ifdef EBUG
584
#ifdef EBUG
569
#if 1
585
#if 1
570
        if ( n != m_comment ) {
586
		if (n != m_comment) {
571
           outs ( "#inst" ) ;
587
			outs("#inst");
572
           outn ( p->id ) ;
588
			outn(p->id);
573
           outnl () ;
589
			outnl();
574
        }
590
		}
575
        if ( p->id == 4921 ) {
591
		if (p->id == 4921) {
576
           int found = 1 ;
592
			int found = 1;
-
 
593
		}
577
        }
594
#endif
578
#endif
595
#endif
-
 
596
		switch (n) {
-
 
597
#ifdef EBUG
-
 
598
		case m_comment:
-
 
599
			outs("#");
-
 
600
			outs(p->op1->def.str);
-
 
601
			outnl();
-
 
602
			break;
579
#endif
603
#endif
580
	switch ( n ) {
-
 
581
#ifdef EBUG
-
 
582
            case m_comment : {
-
 
583
               outs ( "#" ) ;
-
 
584
               outs ( p->op1->def.str ) ;
-
 
585
               outnl () ;
-
 
586
               break ;
-
 
587
            }
-
 
588
#endif
-
 
589
 
604
 
590
#ifdef m_ignore_ins
605
#ifdef m_ignore_ins
591
	    case m_ignore_ins : {
606
		case m_ignore_ins:
592
		/* Ignore */
607
			/* Ignore */
593
		break ;
608
			break;
594
	    }
-
 
595
#endif /* m_ignore_ins */
609
#endif /* m_ignore_ins */
596
 
610
 
597
	    case m_label_ins : {
611
		case m_label_ins:
598
		/* Labels */
612
			/* Labels */
599
		outc ( LPREFIX ) ;
613
			outc(LPREFIX);
600
		outn ( p->op1->def.num ) ;
614
			outn(p->op1->def.num);
601
		outc ( ':' ) ;
615
			outc(':');
602
		outnl () ;
616
			outnl();
603
		break ;
617
			break;
604
	    }
-
 
605
 
-
 
606
	    case m_extern_ins : {
618
		case m_extern_ins:
607
		/* Externals */
619
			/* Externals */
608
		out_data ( p->op1 ) ;
620
			out_data(p->op1);
609
		outc ( ':' ) ;
621
			outc(':');
610
		outnl () ;
622
			outnl();
611
		break ;
623
			break;
612
	    }
-
 
613
 
-
 
614
#ifdef asm_uses_equals
624
#ifdef asm_uses_equals
615
	    case m_as_assign : {
625
		case m_as_assign:
616
		out_mach_op ( p->op1 ) ;
626
			out_mach_op(p->op1);
617
		outc ( '=' ) ;
627
			outc('=');
618
		out_mach_op ( p->op2 ) ;
628
			out_mach_op(p->op2);
619
		outnl () ;
629
			outnl();
620
		break ;
630
			break;
621
	    }
-
 
622
#endif /* asm_uses_equals */
631
#endif /* asm_uses_equals */
623
 
-
 
624
	    case m_as_byte :
632
		case m_as_byte:
625
	    case m_as_short :
633
		case m_as_short:
626
	    case m_as_long :
634
		case m_as_long:
627
	    case m_stabs :
635
		case m_stabs:
628
	    case m_stabd :
636
		case m_stabd:
629
	    case m_stabn :
637
		case m_stabn:
630
	    case m_dd_special : {
638
		case m_dd_special: {
631
		/* Data */
639
			/* Data */
632
		mach_op *q ;
640
			mach_op *q;
633
		bool started = 0 ;
641
			bool started = 0;
634
		int c = 0 ;
642
			int c = 0;
635
		for ( q = p->op1 ; q ; q = q->of ) {
643
			for (q = p->op1; q; q = q->of) {
636
		    if ( c == 0 ) {
644
				if (c == 0) {
637
			if ( started ) outnl () ;
645
					if (started) {
-
 
646
						outnl();
-
 
647
					}
638
			outs ( instr_names [n] ) ;
648
					outs(instr_names[n]);
639
		    } else {
649
				} else {
640
			outc ( ',' ) ;
650
					outc(',');
641
		    }
651
				}
642
		    out_data ( q ) ;
652
				out_data(q);
643
		    started = 1 ;
653
				started = 1;
644
		    if ( ++c == 8 ) c = 0 ;
654
				if (++c == 8) {
-
 
655
					c = 0;
-
 
656
				}
-
 
657
			}
-
 
658
			outnl();
-
 
659
			break;
645
		}
660
		}
646
		outnl () ;
-
 
647
		break ;
-
 
648
	    }
-
 
649
 
-
 
650
	    default : {
661
		default:
651
		if ( is_jump ( n ) ) {
662
			if (is_jump(n)) {
652
		    /* Jumps */
663
				/* Jumps */
653
#ifndef asm_does_jump_lens
664
#ifndef asm_does_jump_lens
654
		    if ( is_unsized ( n ) ) n += long_jump ;
665
				if (is_unsized(n)) {
-
 
666
					n += long_jump;
-
 
667
				}
655
#endif /* !asm_does_jump_lens */
668
#endif /* !asm_does_jump_lens */
656
		    outs ( instr_names [n] ) ;
669
				outs(instr_names[n]);
657
		    outc ( LPREFIX ) ;
670
				outc(LPREFIX);
658
		    outn ( p->op1->def.num ) ;
671
				outn(p->op1->def.num);
659
		    if ( n == m_bra || n == m_brab ||
672
				if (n == m_bra || n == m_brab ||
660
			 n == m_braw || n == m_bral ) {
673
				    n == m_braw || n == m_bral) {
661
			/* Align after unconditional jumps */
674
					/* Align after unconditional jumps */
662
			outnl () ;
675
					outnl();
663
#ifndef no_align_directives
676
#ifndef no_align_directives
664
                        outs ( instr_names [ m_as_align4 ] ) ;
677
					outs(instr_names[m_as_align4]);
665
#endif
678
#endif
666
		    }
679
				}
667
		} else {
680
			} else {
668
		    /* Simple instructions */
681
				/* Simple instructions */
669
		    outs ( instr_names [n] ) ;
682
				outs(instr_names[n]);
-
 
683
				if (p->op1) {
670
		    if ( p->op1 ) out_mach_op ( p->op1 ) ;
684
					out_mach_op(p->op1);
-
 
685
				}
671
		    if ( p->op2 ) {
686
				if (p->op2) {
672
			outc ( ',' ) ;
687
					outc(',');
673
#ifdef EBUG
688
#ifdef EBUG
674
			outc ( ' ' ) ;
689
					outc(' ');
675
#endif /* EBUG */
690
#endif /* EBUG */
676
			out_mach_op ( p->op2 ) ;
691
					out_mach_op(p->op2);
677
		    }
692
				}
-
 
693
			}
-
 
694
			outnl();
-
 
695
			break;
678
		}
696
		}
679
		outnl () ;
-
 
680
		break ;
-
 
681
	    }
-
 
682
	}
697
	}
683
    }
-
 
684
    return ;
698
	return;
685
}
699
}
686
 
700
 
687
 
701
 
688
/*
702
/*
689
    INITIALIZE INSTRUCTIONS
703
    INITIALIZE INSTRUCTIONS
690
 
704
 
691
    Apply a couple of patches for odd instruction quirks.
705
    Apply a couple of patches for odd instruction quirks.
692
*/
706
*/
693
 
707
 
-
 
708
void
694
void init_instructions
709
init_instructions(void)
695
    PROTO_Z ()
-
 
696
{
710
{
697
#ifdef asm_no_btst_suffix
711
#ifdef asm_no_btst_suffix
698
    instr_names [ m_btstb ] = instr_names [ m_btst ] ;
712
	instr_names[m_btstb] = instr_names[m_btst];
699
    instr_names [ m_btstl ] = instr_names [ m_btst ] ;
713
	instr_names[m_btstl] = instr_names[m_btst];
700
#endif /* asm_no_btst_suffix */
714
#endif /* asm_no_btst_suffix */
701
    return ;
715
	return;
702
}
716
}
703
 
717
 
704
 
718
 
705
/*
719
/*
706
    INITIALIZE OUTPUT ROUTINES
720
    INITIALIZE OUTPUT ROUTINES
707
 
721
 
708
    This routine copies the table of global register names into the
722
    This routine copies the table of global register names into the
709
    table of global register names and
723
    table of global register names and
710
*/
724
*/
711
 
725
 
712
void init_output
726
void
713
    PROTO_Z ()
727
init_output(void)
714
{
728
{
715
    memcpy ( reg_names, glob_reg_names, sizeof ( glob_reg_names ) ) ;
729
	memcpy(reg_names, glob_reg_names, sizeof(glob_reg_names));
716
#ifdef SYSV_ABI
730
#ifdef SYSV_ABI
717
    {
731
	{
718
	char *r = reg_names [ REG_A0 ] ;
732
		char *r = reg_names[REG_A0];
719
	reg_names [ REG_A0 ] = reg_names [ REG_A1 ] ;
733
		reg_names[REG_A0] = reg_names[REG_A1];
720
	reg_names [ REG_A1 ] = r ;
734
		reg_names[REG_A1] = r;
721
    }
735
	}
722
#endif /* SYS_ABI */
736
#endif /* SYS_ABI */
723
    all_mach_ins = null ;
737
	all_mach_ins = null;
724
    current_ins = null ;
738
	current_ins = null;
725
    return ;
739
	return;
726
}
740
}
727
 
741
 
728
 
742
 
729
#ifdef EBUG
743
#ifdef EBUG
730
 
744
 
731
extern bool seek_line ;
745
extern bool seek_line;
732
extern int seek_line_no ;
746
extern int seek_line_no;
733
 
747
 
734
 
748
 
735
/*
749
/*
736
    OUTPUT NEW LINE (DEBUG MODE ONLY)
750
    OUTPUT NEW LINE (DEBUG MODE ONLY)
737
 
751
 
738
    In debug mode a count is keep of the current line number in the
752
    In debug mode a count is keep of the current line number in the
739
    output file to allow stopping the debugger at a given line.  Normally
753
    output file to allow stopping the debugger at a given line.  Normally
740
    outnl is a macro which just outputs a newline character.
754
    outnl is a macro which just outputs a newline character.
741
*/
755
*/
742
 
756
 
743
void outnl
757
void
744
    PROTO_Z ()
758
outnl(void)
745
{
759
{
746
    static int line_no = 0 ;
760
	static int line_no = 0;
747
    outc ( '\n' ) ;
761
	outc('\n');
748
    line_no++ ;
762
	line_no++;
749
    if ( seek_line && line_no == seek_line_no ) {
763
	if (seek_line && line_no == seek_line_no) {
750
	warning ( "Line %d reached", line_no ) ;
764
		warning("Line %d reached", line_no);
751
	breakpoint () ;
765
		breakpoint();
752
    }
766
	}
753
    return ;
767
	return;
754
}
768
}
755
 
769
 
756
#endif /* EBUG */
770
#endif /* EBUG */