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 68... Line 98...
68
#include "mach.h"
98
#include "mach.h"
69
#include "mach_ins.h"
99
#include "mach_ins.h"
70
#include "mach_op.h"
100
#include "mach_op.h"
71
#include "peephole.h"
101
#include "peephole.h"
72
#include "utility.h"
102
#include "utility.h"
73
extern bool have_cond ;
103
extern bool have_cond;
74
extern bool just_ret ;
104
extern bool just_ret;
75
extern long crt_ret_lab ;
105
extern long crt_ret_lab;
76
 
106
 
77
 
107
 
78
/*
108
/*
79
    SET UP TABLE OF OPPOSITE JUMPS
109
    SET UP TABLE OF OPPOSITE JUMPS
80
 
110
 
Line 82... Line 112...
82
    "if condition goto ..." and the opposite conditional jump
112
    "if condition goto ..." and the opposite conditional jump
83
    "if not condition goto ...".
113
    "if not condition goto ...".
84
*/
114
*/
85
 
115
 
86
#define OPPOSITE_JUMPS
116
#define OPPOSITE_JUMPS
87
#include "instr_aux.h"
117
#include "instr_aux.h"
88
 
118
 
89
 
119
 
90
/*
120
/*
91
    FIND A LABEL
121
    FIND A LABEL
92
 
122
 
93
    This routine searches the list of all instructions for label n.
123
    This routine searches the list of all instructions for label n.
94
    It returns null if it cannot be found.
124
    It returns null if it cannot be found.
95
*/
125
*/
96
 
126
 
97
static mach_ins *find_label
127
static mach_ins *
98
    PROTO_N ( ( n ) )
-
 
99
    PROTO_T ( long n )
128
find_label(long n)
100
{
129
{
101
    mach_ins *p ;
130
	mach_ins *p;
102
    for ( p = all_mach_ins ; p ; p = p->next ) {
131
	for (p = all_mach_ins; p; p = p->next) {
103
	if ( p->ins_no == m_label_ins && p->op1->def.num == n ) return ( p ) ;
132
		if (p->ins_no == m_label_ins && p->op1->def.num == n) {
-
 
133
			return (p);
104
    }
134
		}
-
 
135
	}
105
    return ( null ) ;
136
	return (null);
106
}
137
}
107
 
138
 
108
 
139
 
109
/*
140
/*
110
    CHECK A JUMP ALIAS FOR CYCLES
141
    CHECK A JUMP ALIAS FOR CYCLES
111
 
142
 
112
    A jump alias is a label followed immediately by an unconditional
143
    A jump alias is a label followed immediately by an unconditional
113
    jump to another label.  It is possible to get cycles of mutually
144
    jump to another label.  It is possible to get cycles of mutually
114
    dependent jump aliases.  This routine checks whether the alias a=>b
145
    dependent jump aliases.  This routine checks whether the alias a=>b
115
    is part of a cycle, and if so returns null.  Otherwise it returns
146
    is part of a cycle, and if so returns null.  Otherwise it returns
116
    the position of label b.
147
    the position of label b.
117
*/
148
*/
118
 
149
 
119
#define  alias_max	20
150
#define  alias_max	20
120
 
151
 
121
static mach_ins *check_jump_alias
152
static mach_ins *
122
    PROTO_N ( ( a, b ) )
-
 
123
    PROTO_T ( long a X long b )
153
check_jump_alias(long a, long b)
124
{
154
{
125
    int i, n ;
155
	int i, n;
126
    mach_ins *p, *q ;
156
	mach_ins *p, *q;
127
    long alias [ alias_max ] ;
157
	long alias[alias_max];
128
 
-
 
129
    if ( a == b ) return ( null ) ;
-
 
130
 
158
 
-
 
159
	if (a == b) {
-
 
160
		return (null);
-
 
161
	}
-
 
162
 
131
    alias [0] = a ;
163
	alias[0] = a;
132
    alias [1] = b ;
164
	alias[1] = b;
133
    p = find_label ( b ) ;
165
	p = find_label(b);
134
    if ( p == null ) return ( null ) ;
166
	if (p == null) {
-
 
167
		return (null);
-
 
168
	}
135
 
169
 
136
    for ( n = 2, q = p ; n < alias_max ; n++ ) {
170
	for (n = 2, q = p; n < alias_max; n++) {
137
	while ( q && q->ins_no == m_label_ins ) q = q->next ;
171
		while (q && q->ins_no == m_label_ins)q = q->next;
138
	if ( q && q->ins_no == m_bra ) {
172
		if (q && q->ins_no == m_bra) {
139
	    long c = q->op1->def.num ;
173
			long c = q->op1->def.num;
140
	    for ( i = 0 ; i < n ; i++ ) {
174
			for (i = 0; i < n; i++) {
141
		if ( c == alias [i] ) return ( null ) ;
175
				if (c == alias[i]) {
-
 
176
					return (null);
142
	    }
177
				}
-
 
178
			}
143
	    alias [n] = c ;
179
			alias[n] = c;
144
	    q = find_label ( c ) ;
180
			q = find_label(c);
145
	} else {
181
		} else {
146
	    return ( p ) ;
182
			return (p);
-
 
183
		}
147
	}
184
	}
148
    }
-
 
149
    return ( null ) ;
185
	return (null);
150
}
186
}
151
 
187
 
152
 
188
 
153
/*
189
/*
154
    CALCULATE ALL JUMP LENGTHS
190
    CALCULATE ALL JUMP LENGTHS
155
 
191
 
156
    This routine finds the length of all jumps and marks each as long,
192
    This routine finds the length of all jumps and marks each as long,
157
    word or byte.  The length is based on the number of instructions
193
    word or byte.  The length is based on the number of instructions
158
    jumped over.  It would be better if the assembler could do this.
194
    jumped over.  It would be better if the assembler could do this.
159
*/
195
*/
160
 
196
 
161
#define  byte_len_min	-16
197
#define  byte_len_min	-16
162
#define  byte_len_max	16
198
#define  byte_len_max	16
163
#define  word_len_min	-2000
199
#define  word_len_min	-2000
164
#define  word_len_max	2000
200
#define  word_len_max	2000
165
 
201
 
166
#ifndef asm_does_jump_lens
202
#ifndef asm_does_jump_lens
167
 
203
 
168
static void find_jump_sizes
204
static void
169
    PROTO_N ( ( lmin, lmax ) )
-
 
170
    PROTO_T ( long lmin X long lmax )
205
find_jump_sizes(long lmin, long lmax)
171
{
206
{
172
    long *tb ;
207
	long *tb;
173
    mach_ins *p ;
208
	mach_ins *p;
174
    long i, n = lmax - lmin + 1 ;
209
	long i, n = lmax - lmin + 1;
175
 
210
 
176
    /* Allocate a temporary label position table */
211
	/* Allocate a temporary label position table */
177
    if ( n <= 0 ) return ;
212
	if (n <= 0) {
-
 
213
		return;
-
 
214
	}
178
#ifndef NO_ALLOCA
215
#ifndef NO_ALLOCA
179
    tb = ( long * ) alloca ( n * sizeof ( long ) ) ;
216
	tb = (long *)alloca(n * sizeof(long));
180
#else
217
#else
181
    tb = alloc_nof ( long, n ) ;
218
	tb = alloc_nof(long, n);
182
#endif
219
#endif
183
    for ( i = 0 ; i < n ; i++ ) tb [i] = 0 ;
220
	for (i = 0; i < n; i++) {
184
 
-
 
185
    /* Fill in label positions */
-
 
186
    for ( p = all_mach_ins, i = 1 ; p ; p = p->next ) {
-
 
187
	if ( p->ins_no == m_label_ins ) {
-
 
188
	    n = p->op1->def.num - lmin ;
-
 
189
	    tb [n] = i ;
221
		tb[i] = 0;
190
	} else {
-
 
191
	    i++ ;
-
 
192
	}
222
	}
193
    }
-
 
194
 
223
 
-
 
224
	/* Fill in label positions */
-
 
225
	for (p = all_mach_ins, i = 1; p; p = p->next) {
-
 
226
		if (p->ins_no == m_label_ins) {
-
 
227
			n = p->op1->def.num - lmin;
-
 
228
			tb[n] = i;
-
 
229
		} else {
-
 
230
			i++;
-
 
231
		}
-
 
232
	}
-
 
233
 
195
    /* Work out jump lengths */
234
	/* Work out jump lengths */
196
    for ( p = all_mach_ins, i = 1 ; p ; p = p->next ) {
235
	for (p = all_mach_ins, i = 1; p; p = p->next) {
197
	int r = p->ins_no ;
236
		int r = p->ins_no;
198
	if ( is_jump ( r ) ) {
237
		if (is_jump(r)) {
199
	    n = p->op1->def.num ;
238
			n = p->op1->def.num;
200
	    if ( just_ret && n == crt_ret_lab && r == m_bra ) {
239
			if (just_ret && n == crt_ret_lab && r == m_bra) {
201
		p->ins_no = m_rts ;
240
				p->ins_no = m_rts;
202
		free_mach_op ( p->op1 ) ;
241
				free_mach_op(p->op1);
203
		p->op1 = null ;
242
				p->op1 = null;
204
	    } else {
243
			} else {
205
		int m = long_jump ;
244
				int m = long_jump;
206
		long d = tb [ n - lmin ] ;
245
				long d = tb[n - lmin];
207
		if ( d ) {
246
				if (d) {
208
		    d -= i ;
247
					d -= i;
-
 
248
					if (d >= byte_len_min &&
209
		    if ( d >= byte_len_min && d <= byte_len_max && d ) {
249
					    d <= byte_len_max && d) {
210
			m = byte_jump ;
250
						m = byte_jump;
211
		    } else if ( d >= word_len_min && d <= word_len_max ) {
251
					} else if (d >= word_len_min &&
-
 
252
						   d <= word_len_max) {
212
			m = word_jump ;
253
						m = word_jump;
213
		    }
254
					}
-
 
255
				}
-
 
256
				p->ins_no = r + m;
-
 
257
			}
-
 
258
		}
-
 
259
		if (r != m_label_ins) {
-
 
260
			i++;
214
		}
261
		}
215
		p->ins_no = r + m ;
-
 
216
	    }
-
 
217
	}
262
	}
218
	if ( r != m_label_ins ) i++ ;
-
 
219
    }
-
 
220
 
263
 
221
#ifdef NO_ALLOCA
264
#ifdef NO_ALLOCA
222
    free ( tb ) ;
265
	free(tb);
223
#endif
266
#endif
224
    return ;
267
	return;
225
}
268
}
226
 
269
 
227
#endif
270
#endif
228
 
271
 
229
 
272
 
230
/*
273
/*
231
    MASK OF REGISTERS CHANGED BY PROCEDURE CALLS
274
    MASK OF REGISTERS CHANGED BY PROCEDURE CALLS
232
 
275
 
233
    Normally this is just ~save_msk, but if, for example D2 is renamed to
276
    Normally this is just ~save_msk, but if, for example D2 is renamed to
234
    D1 by epilogue then D2 has to be marked as changed by procedure calls.
277
    D1 by epilogue then D2 has to be marked as changed by procedure calls.
235
*/
278
*/
236
 
279
 
237
bitpattern callmsk = 0 ;
280
bitpattern callmsk = 0;
238
 
281
 
239
 
282
 
240
/*
283
/*
241
    APPLY ALL PEEPHOLE OPTIMIZATIONS
284
    APPLY ALL PEEPHOLE OPTIMIZATIONS
242
 
285
 
243
    This routine scans through the list of all instructions applying
286
    This routine scans through the list of all instructions applying
244
    various simple optimizations.
287
    various simple optimizations.
245
*/
288
*/
246
 
289
 
247
void peephole
290
void
248
    PROTO_Z ()
291
peephole(void)
249
{
292
{
250
    long a1, a2 ;
293
    long a1, a2;
251
    mach_ins *p, *q ;
294
    mach_ins *p, *q;
252
    mach_op *op1, *op2 ;
295
    mach_op *op1, *op2;
253
    int knock_on_effects ;
296
    int knock_on_effects;
254
 
-
 
255
    mach_op *hold [32] ;
-
 
256
    bitpattern unknown ;
-
 
257
 
297
 
258
    int removed_p ;
298
    mach_op *hold[32];
259
    mach_ins *p_up, *p_down ;
299
    bitpattern unknown;
260
 
300
 
-
 
301
    int removed_p;
-
 
302
    mach_ins *p_up, *p_down;
-
 
303
 
261
    long lmin = 100000, lmax = -100000 ;
304
    long lmin = 100000, lmax = -100000;
262
 
305
 
263
#define  remove_p()			\
306
#define  remove_p()			\
264
    if ( p_up == null ) {		\
307
    if (p_up == null) {			\
265
	all_mach_ins = p_down ;		\
308
	all_mach_ins = p_down;		\
266
    } else {				\
309
    } else {				\
267
	p_up->next = p_down ;		\
310
	p_up->next = p_down;		\
268
    }					\
311
    }					\
269
    removed_p = 1 ;
312
    removed_p = 1;
270
 
313
 
271
    do {
314
    do {
272
	knock_on_effects = 0 ;
315
	knock_on_effects = 0;
273
	unknown = 0xffffffff ;
316
	unknown = 0xffffffff;
274
	p_up = null ;
317
	p_up = null;
275
	p = all_mach_ins ;
318
	p = all_mach_ins;
276
	while ( p != null ) {
319
	while (p != null) {
277
	    int n = p->ins_no ;
320
	    int n = p->ins_no;
278
	    bitpattern ch = p->changed ;
321
	    bitpattern ch = p->changed;
279
 
322
 
280
	    removed_p = 0 ;
323
	    removed_p = 0;
281
	    p_down = p->next ;
324
	    p_down = p->next;
282
 
325
 
283
	    if ( n == m_lea ) {
326
	    if (n == m_lea) {
284
		/* Some lea's can be turned into moves */
327
		/* Some lea's can be turned into moves */
285
		op1 = p->op1 ;
328
		op1 = p->op1;
286
		if ( op1->type == MACH_CONT ) {
329
		if (op1->type == MACH_CONT) {
287
		    op2 = op1->of ;
330
		    op2 = op1->of;
288
		    if ( op2->type == MACH_REG && op2->plus == null ) {
331
		    if (op2->type == MACH_REG && op2->plus == null) {
289
			if ( op2->def.num == p->op2->def.num ) {
332
			if (op2->def.num == p->op2->def.num) {
290
			    /* The move may be nugatory */
333
			    /* The move may be nugatory */
291
			    remove_p () ;
334
			    remove_p();
292
			    reclaim_ins ( p ) ;
335
			    reclaim_ins(p);
293
			} else {
336
			} else {
294
			    /* Create the move */
337
			    /* Create the move */
295
			    p->ins_no = m_movl ;
338
			    p->ins_no = m_movl;
296
			    p->op1 = op2 ;
339
			    p->op1 = op2;
297
			    op1->of = null ;
340
			    op1->of = null;
298
			    free_mach_op ( op1 ) ;
341
			    free_mach_op(op1);
299
			}
342
			}
300
		    }
343
		    }
301
		}
344
		}
302
	    }
345
	    }
303
 
346
 
304
	    if ( n == m_pea ) {
347
	    if (n == m_pea) {
305
		/* Some pea's can be turned into pushes */
348
		/* Some pea's can be turned into pushes */
306
		op1 = p->op1 ;
349
		op1 = p->op1;
307
		if ( op1->type == MACH_CONT ) {
350
		if (op1->type == MACH_CONT) {
308
		    op2 = op1->of ;
351
		    op2 = op1->of;
309
		    if ( op2->type == MACH_REG && op2->plus == null ) {
352
		    if (op2->type == MACH_REG && op2->plus == null) {
310
			/* Create the push */
353
			/* Create the push */
311
			p->ins_no = m_movl ;
354
			p->ins_no = m_movl;
312
			p->op1 = op2 ;
355
			p->op1 = op2;
313
			op1->type = MACH_DEC ;
356
			op1->type = MACH_DEC;
314
			op1->def.num = REG_SP ;
357
			op1->def.num = REG_SP;
315
			op1->of = null ;
358
			op1->of = null;
316
			p->op2 = op1 ;
359
			p->op2 = op1;
317
		    }
360
		    }
318
		}
361
		}
319
	    }
362
	    }
320
 
363
 
321
	    if ( n == m_bra ) {
364
	    if (n == m_bra) {
322
		/* Remove unreachable code after unconditional jumps */
365
		/* Remove unreachable code after unconditional jumps */
323
		q = p_down ;
366
		q = p_down;
324
		while ( q && q->ins_no != m_label_ins ) {
367
		while (q && q->ins_no != m_label_ins) {
325
		    mach_ins *q1 = q->next ;
368
		    mach_ins *q1 = q->next;
326
		    reclaim_ins ( q ) ;
369
		    reclaim_ins(q);
327
		    knock_on_effects = 1 ;
370
		    knock_on_effects = 1;
328
		    q = q1 ;
371
		    q = q1;
329
		}
372
		}
330
		p->next = q ;
373
		p->next = q;
331
		p_down = q ;
374
		p_down = q;
332
	    }
375
	    }
333
 
376
 
334
	    if ( is_jump ( n ) ) {
377
	    if (is_jump(n)) {
335
		a1 = p->op1->def.num ;
378
		a1 = p->op1->def.num;
336
 
379
 
337
		/* Remove jumps to immediately following labels */
380
		/* Remove jumps to immediately following labels */
338
		q = p_down ;
381
		q = p_down;
339
		while ( q && q->ins_no == m_label_ins ) {
382
		while (q && q->ins_no == m_label_ins) {
340
		    a2 = q->op1->def.num ;
383
		    a2 = q->op1->def.num;
341
		    if ( a1 == a2 ) {
384
		    if (a1 == a2) {
342
			remove_p () ;
385
			remove_p();
343
			reclaim_ins ( p ) ;
386
			reclaim_ins(p);
344
			knock_on_effects = 1 ;
387
			knock_on_effects = 1;
345
		    }
-
 
346
		    q = q->next ;
-
 
347
		}
-
 
348
 
-
 
349
		if ( !knock_on_effects && n != m_bra && p_down ) {
-
 
350
		    int m = p_down->ins_no ;
-
 
351
 
-
 
352
		    if ( m == oppo_jump ( n ) ) {
-
 
353
			/* A jump following its opposite jump can be
-
 
354
			   made unconditional */
-
 
355
			p_down->ins_no = m_bra ;
-
 
356
			m = m_bra ;
-
 
357
		    }
388
		    }
-
 
389
		    q = q->next;
-
 
390
		}
-
 
391
 
-
 
392
		if (!knock_on_effects && n != m_bra && p_down) {
-
 
393
		    int m = p_down->ins_no;
358
 
394
 
-
 
395
		    if (m == oppo_jump(n)) {
-
 
396
			/* A jump following its opposite jump can be
-
 
397
			   made unconditional */
-
 
398
			p_down->ins_no = m_bra;
-
 
399
			m = m_bra;
-
 
400
		    }
-
 
401
 
359
		    if ( m == m_bra ) {
402
		    if (m == m_bra) {
360
			/* Negate conditionals if appropriate :
403
			/* Negate conditionals if appropriate :
361
 
404
 
362
				if ( cond ) goto L1
405
				if (cond) goto L1
363
				goto L2
406
				goto L2
364
				L1 : ....
407
				L1: ....
365
 
-
 
366
			   becomes :
-
 
367
 
-
 
368
				if ( !cond ) goto L2
-
 
369
				L1 : ....
-
 
370
			*/
-
 
371
			q = p_down->next ;
-
 
372
			while ( q && q->ins_no == m_label_ins ) {
-
 
373
			    a2 = q->op1->def.num ;
-
 
374
			    if ( a1 == a2 ) {
-
 
375
				remove_p () ;
-
 
376
				reclaim_ins ( p ) ;
-
 
377
				p_down->ins_no = oppo_jump ( n ) ;
-
 
378
				knock_on_effects = 1 ;
-
 
379
			    }
-
 
380
			    q = q->next ;
-
 
381
			}
-
 
382
 
408
 
-
 
409
			   becomes :
-
 
410
 
-
 
411
				if (!cond) goto L2
-
 
412
				L1: ....
-
 
413
			*/
-
 
414
			q = p_down->next;
-
 
415
			while (q && q->ins_no == m_label_ins) {
-
 
416
			    a2 = q->op1->def.num;
-
 
417
			    if (a1 == a2) {
-
 
418
				remove_p();
-
 
419
				reclaim_ins(p);
-
 
420
				p_down->ins_no = oppo_jump(n);
-
 
421
				knock_on_effects = 1;
-
 
422
			    }
-
 
423
			    q = q->next;
-
 
424
			}
-
 
425
 
383
		    } else if ( m == n ) {
426
		    } else if (m == n) {
384
			/* Consecutive identical jumps are unnecessary */
427
			/* Consecutive identical jumps are unnecessary */
385
			q = p_down ;
428
			q = p_down;
386
			p_down = q->next ;
429
			p_down = q->next;
387
			q->next = null ;
430
			q->next = null;
388
			reclaim_ins ( q ) ;
431
			reclaim_ins(q);
389
			p->next = p_down ;
432
			p->next = p_down;
390
			knock_on_effects = 1 ;
433
			knock_on_effects = 1;
391
 
434
 
392
		    } else if ( just_ret && m != m_label_ins ) {
435
		    } else if (just_ret && m != m_label_ins) {
393
			/* Negate certain simple returns :
436
			/* Negate certain simple returns :
394
 
437
 
395
				if ( cond ) goto L1
438
				if (cond) goto L1
396
				return x
439
				return x
397
				L1 : ....
440
				L1: ....
398
 
441
 
399
			   becomes :
442
			   becomes :
400
 
443
 
401
				if ( !cond ) goto L2
444
				if (!cond) goto L2
402
				L1 : ....
445
				L1: ....
403
				.....
446
				.....
404
				L2 : return x
447
				L2: return x
405
			*/
448
			*/
406
			q = p_down->next ;
449
			q = p_down->next;
407
			if ( q && q->ins_no == m_bra &&
450
			if (q && q->ins_no == m_bra &&
408
			     q->op1->def.num == crt_ret_lab ) {
451
			     q->op1->def.num == crt_ret_lab) {
409
			    bool go = 0 ;
452
			    bool go = 0;
410
			    q = q->next ;
453
			    q = q->next;
411
			    while ( q && q->ins_no == m_label_ins ) {
454
			    while (q && q->ins_no == m_label_ins) {
412
				a2 = q->op1->def.num ;
455
				a2 = q->op1->def.num;
413
				if ( a2 == a1 ) go = 1 ;
456
				if (a2 == a1) {
-
 
457
					go = 1;
-
 
458
				}
414
				if ( a2 == crt_ret_lab ) go = 0 ;
459
				if (a2 == crt_ret_lab) {
-
 
460
					go = 0;
-
 
461
				}
415
				q = q->next ;
462
				q = q->next;
416
			    }
463
			    }
417
			    if ( go ) {
464
			    if (go) {
418
				a2 = next_lab () ;
465
				a2 = next_lab();
419
				if ( a2 < lmin ) lmin = a2 ;
466
				if (a2 < lmin) {
-
 
467
					lmin = a2;
-
 
468
				}
420
				if ( a2 > lmax ) lmax = a2 ;
469
				if (a2 > lmax) {
-
 
470
					lmax = a2;
-
 
471
				}
421
				p->ins_no = oppo_jump ( n ) ;
472
				p->ins_no = oppo_jump(n);
422
				p->op1->def.num = a2 ;
473
				p->op1->def.num = a2;
423
				q = p_down->next ;
474
				q = p_down->next;
424
				p->next = q->next ;
475
				p->next = q->next;
425
				q->next = null ;
476
				q->next = null;
426
				reclaim_ins ( q ) ;
477
				reclaim_ins(q);
427
#ifndef no_align_directives
478
#ifndef no_align_directives
428
                                make_instr ( m_as_align4, null, null, 0 ) ;
479
                                make_instr(m_as_align4, null, null, 0);
429
#endif
480
#endif
430
				make_label ( a2 ) ;
481
				make_label(a2);
431
				current_ins->next = p_down ;
482
				current_ins->next = p_down;
432
				p_down->next = null ;
483
				p_down->next = null;
433
				current_ins = current_ins->next ;
484
				current_ins = current_ins->next;
434
				make_instr ( m_rts, null, null, 0 ) ;
485
				make_instr(m_rts, null, null, 0);
435
				p_down = p->next ;
486
				p_down = p->next;
436
			    }
487
			    }
437
			}
488
			}
438
		    }
489
		    }
439
		}
490
		}
440
	    }
491
	    }
441
 
492
 
442
	    if ( n == m_label_ins ) {
493
	    if (n == m_label_ins) {
443
		/* Update maximum and minimum label numbers */
494
		/* Update maximum and minimum label numbers */
444
		a1 = p->op1->def.num ;
495
		a1 = p->op1->def.num;
445
		if ( a1 < lmin ) lmin = a1 ;
496
		if (a1 < lmin) {
-
 
497
			lmin = a1;
-
 
498
		}
446
		if ( a1 > lmax ) lmax = a1 ;
499
		if (a1 > lmax) {
-
 
500
			lmax = a1;
-
 
501
		}
447
 
502
 
448
		/* Look for jump aliases :
503
		/* Look for jump aliases :
449
 
504
 
450
			L1 : goto L2
505
			L1 : goto L2
451
			....
506
			....
Line 458... Line 513...
458
			L2 :
513
			L2 :
459
			L1 : ....
514
			L1 : ....
460
 
515
 
461
		   provided L1=>L2 is not part of a cycle of jump aliases.
516
		   provided L1=>L2 is not part of a cycle of jump aliases.
462
		*/
517
		*/
463
		q = p->next ;
518
		q = p->next;
464
		while ( q && q->ins_no == m_label_ins ) q = q->next ;
519
		while (q && q->ins_no == m_label_ins)q = q->next;
465
		if ( q && q->ins_no == m_bra ) {
520
		if (q && q->ins_no == m_bra) {
466
		    a2 = q->op1->def.num ;
521
		    a2 = q->op1->def.num;
467
		    q = check_jump_alias ( a1, a2 ) ;
522
		    q = check_jump_alias(a1, a2);
468
		    if ( q != null ) {
523
		    if (q != null) {
469
			/* Move the label */
524
			/* Move the label */
470
			remove_p () ;
525
			remove_p();
471
			p->next = q->next ;
526
			p->next = q->next;
472
			q->next = p ;
527
			q->next = p;
473
			knock_on_effects = 1 ;
528
			knock_on_effects = 1;
474
		    }
529
		    }
475
		}
530
		}
476
	    }
531
	    }
477
 
532
 
478
	    /* Look at consecutive moves */
533
	    /* Look at consecutive moves */
479
	    if ( n == m_movl && p_down && p_down->ins_no == m_movl ) {
534
	    if (n == m_movl && p_down && p_down->ins_no == m_movl) {
480
		a1 = p->op1->type ;
535
		a1 = p->op1->type;
481
		a2 = p->op2->type ;
536
		a2 = p->op2->type;
482
		if ( a1 == MACH_REG && a2 != MACH_REG &&
537
		if (a1 == MACH_REG && a2 != MACH_REG &&
483
		     !check_op ( p->op2, p->op1->def.num ) &&
538
		     !check_op(p->op2, p->op1->def.num) &&
484
		     equal_op ( p->op2, p_down->op1 ) ) {
539
		     equal_op(p->op2, p_down->op1)) {
485
		    /* b = a, c = b => b = a, c = a */
540
		    /* b = a, c = b => b = a, c = a */
486
		    free_mach_op ( p_down->op1 ) ;
541
		    free_mach_op(p_down->op1);
487
		    p_down->op1 = make_register ( p->op1->def.num ) ;
542
		    p_down->op1 = make_register(p->op1->def.num);
488
		}
543
		}
489
		if ( a1 != MACH_REG && a2 == MACH_REG &&
544
		if (a1 != MACH_REG && a2 == MACH_REG &&
490
		     !check_op ( p->op1, p->op2->def.num ) &&
545
		     !check_op(p->op1, p->op2->def.num) &&
491
		     equal_op ( p->op1, p_down->op1 ) ) {
546
		     equal_op(p->op1, p_down->op1)) {
492
		    /* b = a, c = a => b = a, c = b */
547
		    /* b = a, c = a => b = a, c = b */
493
		    free_mach_op ( p_down->op1 ) ;
548
		    free_mach_op(p_down->op1);
494
		    p_down->op1 = make_register ( p->op2->def.num ) ;
549
		    p_down->op1 = make_register(p->op2->def.num);
495
		}
550
		}
496
	    }
551
	    }
497
 
552
 
498
	    /* Moving constants into registers */
553
	    /* Moving constants into registers */
499
	    if ( ( n == m_movl || n == m_moveq ) && p->op2->type == MACH_REG ) {
554
	    if ((n == m_movl || n == m_moveq) && p->op2->type == MACH_REG) {
500
		int t = p->op1->type ;
555
		int t = p->op1->type;
501
		if ( t == MACH_HEX ) t = MACH_VAL ;
556
		if (t == MACH_HEX) {
-
 
557
			t = MACH_VAL;
-
 
558
		}
502
		if ( ( t == MACH_VAL || t == MACH_EXT || t == MACH_LAB ) &&
559
		if ((t == MACH_VAL || t == MACH_EXT || t == MACH_LAB) &&
503
		     p->op1->plus == null ) {
560
		     p->op1->plus == null) {
504
		    long z = p->op2->def.num ;
561
		    long z = p->op2->def.num;
505
		    if ( !( unknown & regmsk ( z ) ) &&
562
		    if (!(unknown & regmsk(z)) &&
506
			 hold [z]->type == t &&
563
			 hold[z] ->type == t &&
507
			 hold [z]->def.num == p->op1->def.num ) {
564
			 hold[z] ->def.num == p->op1->def.num) {
508
			/* Move is strictly unnecessary */
565
			/* Move is strictly unnecessary */
509
			if ( p_down && is_jump ( p_down->ins_no ) ) {
566
			if (p_down && is_jump(p_down->ins_no)) {
510
			    /* Keep it in for test purposes */
567
			    /* Keep it in for test purposes */
511
			} else {
568
			} else {
512
			    remove_p () ;
569
			    remove_p();
513
			    reclaim_ins ( p ) ;
570
			    reclaim_ins(p);
514
			}
571
			}
515
		    } else {
572
		    } else {
516
			hold [z] = p->op1 ;
573
			hold[z] = p->op1;
517
			hold [z]->type = t ;
574
			hold[z] ->type = t;
518
			unknown &= ~ch ;
575
			unknown &= ~ch;
519
			ch = 0 ;
576
			ch = 0;
520
		    }
577
		    }
521
		}
578
		}
522
	    }
579
	    }
523
 
580
 
524
	    /* Remove ignore instructions */
581
	    /* Remove ignore instructions */
525
	    if ( n == m_ignore_ins ) {
582
	    if (n == m_ignore_ins) {
526
		remove_p () ;
583
		remove_p();
527
		reclaim_ins ( p ) ;
584
		reclaim_ins(p);
528
	    }
585
	    }
529
 
586
 
530
	    /* Deal with registers changed by procedure calls */
587
	    /* Deal with registers changed by procedure calls */
531
	    if ( n == m_call ) ch |= callmsk ;
588
	    if (n == m_call) {
-
 
589
		    ch |= callmsk;
-
 
590
	    }
532
 
591
 
533
	    /* Update p_up, p and unknown */
592
	    /* Update p_up, p and unknown */
534
	    if ( !removed_p ) {
593
	    if (!removed_p) {
535
		p_up = p ;
594
		p_up = p;
536
		unknown |= ch ;
595
		unknown |= ch;
537
	    }
596
	    }
538
	    p = p_down ;
597
	    p = p_down;
539
	}
598
	}
540
    } while ( knock_on_effects ) ;
599
    } while (knock_on_effects);
541
 
600
 
542
    /* Work out jump sizes */
601
    /* Work out jump sizes */
543
#ifndef asm_does_jump_lens
602
#ifndef asm_does_jump_lens
544
    find_jump_sizes ( lmin, lmax ) ;
603
    find_jump_sizes(lmin, lmax);
545
#endif
604
#endif
546
    return ;
605
    return;
547
}
606
}
548
 
607
 
549
 
608
 
550
/*
609
/*
551
    TABLE OF INSTRUCTION SIZES
610
    TABLE OF INSTRUCTION SIZES
552
 
611
 
553
    This table gives the correspondence between instruction numbers
612
    This table gives the correspondence between instruction numbers
554
    and instruction sizes.
613
    and instruction sizes.
555
*/
614
*/
556
 
615
 
557
static bool instr_sz [] = {
616
static bool instr_sz[] = {
558
#define INSTR_SIZES
617
#define INSTR_SIZES
559
#include "instr_aux.h"
618
#include "instr_aux.h"
560
} ;
619
};
561
 
620
 
562
 
621
 
563
/*
622
/*
564
    CHECK FOR POST-INCREMENT AND PRE-DECREMENT
623
    CHECK FOR POST-INCREMENT AND PRE-DECREMENT
565
 
624
 
566
    This routine checks for (some) possible uses of post-increment and
625
    This routine checks for (some) possible uses of post-increment and
567
    pre-decrement instructions.  It returns 1 if a change has been
626
    pre-decrement instructions.  It returns 1 if a change has been
568
    made.
627
    made.
569
*/
628
*/
570
 
629
 
571
bool post_inc_check
630
bool
572
    PROTO_N ( ( q, r ) )
-
 
573
    PROTO_T ( mach_ins *q X bitpattern r )
631
post_inc_check(mach_ins *q, bitpattern r)
574
{
632
{
575
    long r1, r2, sz ;
633
	long r1, r2, sz;
576
    int move_ins ;
634
	int move_ins;
577
    bool incr = 1, use_op1 = 1, use_op2 = 1 ;
635
	bool incr = 1, use_op1 = 1, use_op2 = 1;
578
 
636
 
579
    mach_op *op ;
637
	mach_op *op;
580
    mach_ins *p = q->next ;
638
	mach_ins *p = q->next;
581
 
639
 
582
    if ( p == null ) return ( 0 ) ;
640
	if (p == null) {
-
 
641
		return (0);
-
 
642
	}
583
 
643
 
584
    /* The first instruction may be m_subql */
644
	/* The first instruction may be m_subql */
585
    if ( p->ins_no == m_subql ) {
645
	if (p->ins_no == m_subql) {
586
	sz = p->op1->def.num ;
646
		sz = p->op1->def.num;
587
	r1 = p->op2->def.num ;
647
		r1 = p->op2->def.num;
588
	p = p->next ;
648
		p = p->next;
589
	if ( p == null ) return ( 0 ) ;
649
		if (p == null) {
-
 
650
			return (0);
-
 
651
		}
590
	incr = 0 ;
652
		incr = 0;
591
    }
653
	}
592
 
654
 
593
    /* The next instruction must be a move of two registers */
655
	/* The next instruction must be a move of two registers */
594
    if ( p->ins_no != m_movl ) return ( 0 ) ;
656
	if (p->ins_no != m_movl) {
-
 
657
		return (0);
-
 
658
	}
595
    if ( p->op1->type != MACH_REG ) return ( 0 ) ;
659
	if (p->op1->type != MACH_REG) {
-
 
660
		return (0);
-
 
661
	}
596
    if ( p->op2->type != MACH_REG ) return ( 0 ) ;
662
	if (p->op2->type != MACH_REG) {
-
 
663
		return (0);
-
 
664
	}
597
    if ( incr ) {
665
	if (incr) {
598
	r1 = p->op1->def.num ;
666
		r1 = p->op1->def.num;
599
    } else {
667
	} else {
600
	/* The first register must be the one in the m_subql */
668
		/* The first register must be the one in the m_subql */
601
	if ( p->op1->def.num != r1 ) return ( 0 ) ;
669
		if (p->op1->def.num != r1) {
-
 
670
			return (0);
602
    }
671
		}
-
 
672
	}
603
 
673
 
604
    /* The second register must be that given by r */
674
	/* The second register must be that given by r */
605
    r2 = p->op2->def.num ;
675
	r2 = p->op2->def.num;
606
    if ( regmsk ( r2 ) != r ) return ( 0 ) ;
676
	if (regmsk(r2) != r) {
-
 
677
		return (0);
-
 
678
	}
607
 
679
 
608
    if ( incr ) {
680
	if (incr) {
609
	/* The next instruction must be "lea sz(r2), r1" */
681
		/* The next instruction must be "lea sz(r2), r1" */
610
	p = p->next ;
682
		p = p->next;
611
	if ( p == null ) return ( 0 ) ;
683
		if (p == null) {
-
 
684
			return (0);
-
 
685
		}
612
	if ( p->ins_no != m_lea ) return ( 0 ) ;
686
		if (p->ins_no != m_lea) {
-
 
687
			return (0);
-
 
688
		}
613
	if ( p->op1->type != MACH_CONT ) return ( 0 ) ;
689
		if (p->op1->type != MACH_CONT) {
-
 
690
			return (0);
-
 
691
		}
614
	if ( p->op1->of->type != MACH_REG ) return ( 0 ) ;
692
		if (p->op1->of->type != MACH_REG) {
-
 
693
			return (0);
-
 
694
		}
615
	if ( p->op1->of->def.num != r2 ) return ( 0 ) ;
695
		if (p->op1->of->def.num != r2) {
-
 
696
			return (0);
-
 
697
		}
616
	if ( p->op1->of->plus->type != MACH_VAL ) return ( 0 ) ;
698
		if (p->op1->of->plus->type != MACH_VAL) {
-
 
699
			return (0);
-
 
700
		}
617
	sz = p->op1->of->plus->def.num ;
701
		sz = p->op1->of->plus->def.num;
618
	if ( p->op2->type != MACH_REG ) return ( 0 ) ;
702
		if (p->op2->type != MACH_REG) {
-
 
703
			return (0);
-
 
704
		}
619
	if ( p->op2->def.num != r1 ) return ( 0 ) ;
705
		if (p->op2->def.num != r1) {
-
 
706
			return (0);
-
 
707
		}
-
 
708
	}
-
 
709
 
-
 
710
	/* Check the value of sz */
-
 
711
	if (sz == 1) {
-
 
712
		move_ins = m_movb;
-
 
713
	} else if (sz == 2) {
-
 
714
		move_ins = m_movw;
-
 
715
	} else if (sz == 4) {
-
 
716
		move_ins = m_movl;
-
 
717
	} else {
-
 
718
		return (0);
-
 
719
	}
-
 
720
 
-
 
721
	p = p->next;
-
 
722
	if (p == null) {
-
 
723
		return (0);
-
 
724
	}
-
 
725
	if (p->next) {
-
 
726
		/* The next instruction may be "move (r2), reg" */
-
 
727
		if (p->next->next) {
-
 
728
			return (0);
-
 
729
		}
-
 
730
		if (p->next->ins_no != move_ins) {
-
 
731
			return (0);
-
 
732
		}
-
 
733
		op = p->next->op1;
-
 
734
		if (op->type != MACH_CONT) {
-
 
735
			return (0);
-
 
736
		}
-
 
737
		if (op->of->type != MACH_REG) {
-
 
738
			return (0);
-
 
739
		}
-
 
740
		if (op->of->def.num != r2) {
-
 
741
			return (0);
-
 
742
		}
-
 
743
		if (op->of->plus != null) {
-
 
744
			return (0);
-
 
745
		}
-
 
746
	}
-
 
747
 
-
 
748
	/* Check the size of the current operation */
-
 
749
	if (!is_simple(p->ins_no) || instr_sz[p->ins_no] != sz) {
-
 
750
		return (0);
-
 
751
	}
-
 
752
 
-
 
753
	/* Check if the first operand is (r2) */
-
 
754
	if (p->op1) {
-
 
755
		op = p->op1;
-
 
756
		if (op->type != MACH_CONT) {
-
 
757
			use_op1 = 0;
-
 
758
		} else {
-
 
759
			if (op->of->type != MACH_REG) {
-
 
760
				use_op1 = 0;
-
 
761
			}
-
 
762
			if (op->of->def.num != r2) {
-
 
763
				use_op1 = 0;
-
 
764
			}
-
 
765
			if (op->of->plus != null) {
-
 
766
				use_op1 = 0;
-
 
767
			}
-
 
768
		}
-
 
769
	} else {
-
 
770
		use_op1 = 0;
-
 
771
	}
-
 
772
 
-
 
773
	/* Check if the second operand is (r2) */
-
 
774
	if (p->op2) {
-
 
775
		op = p->op2;
-
 
776
		if (op->type != MACH_CONT) {
-
 
777
			use_op2 = 0;
-
 
778
		} else {
-
 
779
			if (op->of->type != MACH_REG) {
-
 
780
				use_op2 = 0;
-
 
781
			}
-
 
782
			if (op->of->def.num != r2) {
-
 
783
				use_op2 = 0;
-
 
784
			}
-
 
785
			if (op->of->plus != null) {
-
 
786
				use_op2 = 0;
620
    }
787
			}
-
 
788
		}
-
 
789
	} else {
-
 
790
		use_op2 = 0;
-
 
791
	}
621
 
792
 
622
    /* Check the value of sz */
793
	/* Check that the operands are alright */
623
    if ( sz == 1 ) {
794
	if (use_op1 + use_op2 != 1) {
624
	move_ins = m_movb ;
795
		return (0);
-
 
796
	}
625
    } else if ( sz == 2 ) {
797
	if (use_op1 && check_op(p->op2, r2)) {
626
	move_ins = m_movw ;
798
		return (0);
-
 
799
	}
627
    } else if ( sz == 4 ) {
800
	if (use_op2 && check_op(p->op1, r2)) {
628
	move_ins = m_movl ;
-
 
629
    } else {
-
 
630
	return ( 0 ) ;
801
		return (0);
631
    }
802
	}
632
 
803
 
633
    p = p->next ;
-
 
634
    if ( p == null ) return ( 0 ) ;
-
 
635
    if ( p->next ) {
804
	/* Make the change */
636
	/* The next instruction may be "move (r2), reg" */
-
 
637
	if ( p->next->next ) return ( 0 ) ;
-
 
638
	if ( p->next->ins_no != move_ins ) return ( 0 ) ;
-
 
639
	op = p->next->op1 ;
805
	reclaim_ins(q->next->next);
640
	if ( op->type != MACH_CONT ) return ( 0 ) ;
-
 
641
	if ( op->of->type != MACH_REG ) return ( 0 ) ;
-
 
642
	if ( op->of->def.num != r2 ) return ( 0 ) ;
-
 
643
	if ( op->of->plus != null ) return ( 0 ) ;
-
 
644
    }
-
 
645
 
-
 
646
    /* Check the size of the current operation */
-
 
647
    if ( !is_simple ( p->ins_no ) || instr_sz [ p->ins_no ] != sz ) {
-
 
648
	return ( 0 ) ;
806
	reclaim_ins(q->next);
649
    }
-
 
650
 
-
 
651
    /* Check if the first operand is (r2) */
-
 
652
    if ( p->op1 ) {
807
	if (use_op1) {
653
	op = p->op1 ;
808
		free_mach_op(p->op1);
654
	if ( op->type != MACH_CONT ) {
809
		p->op1 = (incr ? make_inc_sp(): make_dec_sp());
655
	    use_op1 = 0 ;
810
		p->op1->def.num = r1;
656
	} else {
811
	} else {
657
	    if ( op->of->type != MACH_REG ) use_op1 = 0 ;
812
		free_mach_op(p->op2);
658
	    if ( op->of->def.num != r2 ) use_op1 = 0 ;
813
		p->op2 = (incr ? make_inc_sp(): make_dec_sp());
659
	    if ( op->of->plus != null ) use_op1 = 0 ;
814
		p->op2->def.num = r1;
660
	}
815
	}
661
    } else {
-
 
662
	use_op1 = 0 ;
-
 
663
    }
-
 
664
 
-
 
665
    /* Check if the second operand is (r2) */
-
 
666
    if ( p->op2 ) {
-
 
667
	op = p->op2 ;
-
 
668
	if ( op->type != MACH_CONT ) {
-
 
669
	    use_op2 = 0 ;
-
 
670
	} else {
-
 
671
	    if ( op->of->type != MACH_REG ) use_op2 = 0 ;
-
 
672
	    if ( op->of->def.num != r2 ) use_op2 = 0 ;
-
 
673
	    if ( op->of->plus != null ) use_op2 = 0 ;
-
 
674
	}
-
 
675
    } else {
-
 
676
	use_op2 = 0 ;
-
 
677
    }
-
 
678
 
-
 
679
    /* Check that the operands are alright */
-
 
680
    if ( use_op1 + use_op2 != 1 ) return ( 0 ) ;
-
 
681
    if ( use_op1 && check_op ( p->op2, r2 ) ) return ( 0 ) ;
-
 
682
    if ( use_op2 && check_op ( p->op1, r2 ) ) return ( 0 ) ;
-
 
683
 
-
 
684
    /* Make the change */
-
 
685
    reclaim_ins ( q->next->next ) ;
-
 
686
    reclaim_ins ( q->next ) ;
-
 
687
    if ( use_op1 ) {
-
 
688
	free_mach_op ( p->op1 ) ;
-
 
689
	p->op1 = ( incr ? make_inc_sp () : make_dec_sp () ) ;
-
 
690
	p->op1->def.num = r1 ;
-
 
691
    } else {
-
 
692
	free_mach_op ( p->op2 ) ;
-
 
693
	p->op2 = ( incr ? make_inc_sp () : make_dec_sp () ) ;
-
 
694
	p->op2->def.num = r1 ;
-
 
695
    }
-
 
696
    p->changed |= regmsk ( r1 ) ;
816
	p->changed |= regmsk(r1);
697
    q->next = p ;
817
	q->next = p;
698
    if ( p->next ) {
818
	if (p->next) {
699
	p->next->op1->of->def.num = r1 ;
819
		p->next->op1->of->def.num = r1;
700
	if ( incr ) p->next->op1->of->plus = make_value ( -sz ) ;
820
		if (incr)p->next->op1->of->plus = make_value(-sz);
701
    } else {
821
	} else {
702
	if ( use_op2 ) have_cond = 0 ;
822
		if (use_op2)have_cond = 0;
703
    }
823
	}
704
    return ( 1 ) ;
824
	return (1);
705
}
825
}