Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251
WebSVN – tendra.SVN – Diff – /branches/tendra5/src/installers/680x0/common/ops_logic.c – Rev 5 and 6

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 124... Line 154...
124
    AND/OR/XOR BY A CONSTANT
154
    AND/OR/XOR BY A CONSTANT
125
 
155
 
126
    The value a of shape sha and size sz has the logical operator indicated
156
    The value a of shape sha and size sz has the logical operator indicated
127
    by logop applied to it and the constant c.  The result is stored in
157
    by logop applied to it and the constant c.  The result is stored in
128
    dest.  instr is one of m_andl, m_orl, eorl.
158
    dest.  instr is one of m_andl, m_orl, eorl.
129
*/
159
*/
130
 
160
 
131
static void andetc_const
161
static void
132
    PROTO_N ( ( instr, sha, sz, c, a, dest, logop ) )
-
 
133
    PROTO_T ( int instr X shape sha X long sz X long c X where a X where dest X int logop )
162
andetc_const(int instr, shape sha, long sz, long c, where a, where dest,
-
 
163
	     int logop)
134
{
164
{
135
    long whd ;
165
	long whd;
136
 
166
 
137
    /* First check that a is not a constant */
167
	/* First check that a is not a constant */
138
    if ( whereis ( a ) == Value ) {
168
	if (whereis(a) == Value) {
139
	long ca = nw ( a ) ;
169
		long ca = nw(a);
140
	switch ( logop ) {
170
		switch (logop) {
141
	    case AND : ca &= c ; break ;
171
		case AND:
-
 
172
			ca &= c;
-
 
173
			break;
-
 
174
		case OR:
142
	    case OR  : ca |= c ; break ;
175
			ca |= c;
-
 
176
			break;
143
	    case XOR : ca ^= c ; break ;
177
		case XOR:
-
 
178
			ca ^= c;
-
 
179
			break;
144
	}
180
		}
145
	move ( sha, mnw ( ca ), dest ) ;
181
		move(sha, mnw(ca), dest);
146
	return ;
182
		return;
147
    }
183
	}
148
 
184
 
149
    /* Now look for some special values of c */
185
	/* Now look for some special values of c */
150
    switch ( logop ) {
186
	switch (logop) {
151
 
-
 
152
	case AND : {
187
	case AND: {
153
	    long cc ;
188
		long cc;
154
	    if ( c == 0 ) {
189
		if (c == 0) {
155
		move ( sha, zero, dest ) ;
190
			move(sha, zero, dest);
156
		return ;
191
			return;
157
	    }
192
		}
158
	    cc = ~c ;
193
		cc = ~c;
159
	    if ( sz == 32 ) {
194
		if (sz == 32) {
160
		if ( cc == 0 ) {
195
			if (cc == 0) {
161
		    change_var ( sha, a, dest ) ;
196
				change_var(sha, a, dest);
162
		    return ;
197
				return;
163
		}
198
			}
164
		if ( is_pow2 ( cc ) ) {
199
			if (is_pow2(cc)) {
165
		    long p = log2 ( cc ) ;
200
				long p = log2(cc);
166
		    if ( whereis ( dest ) == Dreg ) {
201
				if (whereis(dest) == Dreg) {
167
			change_var ( sha, a, dest ) ;
202
					change_var(sha, a, dest);
168
			ins2n ( m_bclr, p, sz, dest, 1 ) ;
203
					ins2n(m_bclr, p, sz, dest, 1);
169
			have_cond = 0 ;
204
					have_cond = 0;
170
			return ;
205
					return;
171
		    }
206
				}
172
		}
207
			}
173
	    }
208
		}
174
	    break ;
209
		break;
175
	}
210
	}
176
 
-
 
177
	case OR : {
211
	case OR:
178
	    if ( c == 0 ) {
212
		if (c == 0) {
179
		change_var ( sha, a, dest ) ;
213
			change_var(sha, a, dest);
180
		return ;
214
			return;
181
	    }
215
		}
182
	    if ( is_pow2 ( c ) ) {
216
		if (is_pow2(c)) {
183
		long p = log2 ( c ) ;
217
			long p = log2(c);
184
		if ( whereis ( dest ) == Dreg ) {
218
			if (whereis(dest) == Dreg) {
185
		    change_var ( sha, a, dest ) ;
219
				change_var(sha, a, dest);
186
		    ins2n ( m_bset, p, sz, dest, 1 ) ;
220
				ins2n(m_bset, p, sz, dest, 1);
187
		    have_cond = 0 ;
221
				have_cond = 0;
188
		    return ;
222
				return;
189
		}
223
			}
190
	    }
224
		}
191
	    break ;
225
		break;
192
	}
-
 
193
 
-
 
194
	case XOR : {
226
	case XOR:
195
	    if ( c == 0 ) {
227
		if (c == 0) {
196
		change_var ( sha, a, dest ) ;
228
			change_var(sha, a, dest);
197
		return ;
229
			return;
198
	    }
230
		}
199
	    break ;
231
		break;
200
	}
232
	}
201
    }
-
 
202
 
233
 
203
    whd = whereis ( dest ) ;
234
	whd = whereis(dest);
204
    if ( whd != Areg && eq_where ( a, dest ) ) {
235
	if (whd != Areg && eq_where(a, dest)) {
205
	ins2h ( instr, c, sz, dest, 1 ) ;
236
		ins2h(instr, c, sz, dest, 1);
206
	set_cond ( dest, sz ) ;
237
		set_cond(dest, sz);
207
	return ;
238
		return;
208
    }
239
	}
209
    if ( whd == Dreg ) {
240
	if (whd == Dreg) {
210
	change_var ( sha, a, dest ) ;
241
		change_var(sha, a, dest);
211
	ins2h ( instr, c, sz, dest, 1 ) ;
242
		ins2h(instr, c, sz, dest, 1);
212
	set_cond ( dest, sz ) ;
243
		set_cond(dest, sz);
213
	return ;
244
		return;
214
    }
245
	}
215
    if ( whereis ( a ) == Dreg && last_use ( a ) ) {
246
	if (whereis(a) == Dreg && last_use(a)) {
216
	ins2h ( instr, c, sz, a, 1 ) ;
247
		ins2h(instr, c, sz, a, 1);
217
	change_var ( sha, a, dest ) ;
248
		change_var(sha, a, dest);
218
	set_cond ( dest, sz ) ;
249
		set_cond(dest, sz);
219
	return ;
250
		return;
220
    }
251
	}
221
    change_var ( sha, a, D0 ) ;
252
	change_var(sha, a, D0);
222
    ins2h ( instr, c, sz, D0, 1 ) ;
253
	ins2h(instr, c, sz, D0, 1);
223
    move ( sha, D0, dest ) ;
254
	move(sha, D0, dest);
224
    set_cond ( dest, sz ) ;
255
	set_cond(dest, sz);
225
    return ;
256
	return;
226
}
257
}
227
 
258
 
228
 
259
 
229
/*
260
/*
230
    AUXILLARY ROUTINE FOR AND/OR/XOR
261
    AUXILLARY ROUTINE FOR AND/OR/XOR
231
 
262
 
232
    The values a1 and a2 of shape sha have the logical operation indicated
263
    The values a1 and a2 of shape sha have the logical operation indicated
233
    by logop applied to them and the result is stored in dest.  ( opb,
264
    by logop applied to them and the result is stored in dest.  ( opb,
234
    opw, opl ) is an ordered triple giving the byte, word and long forms of
265
    opw, opl ) is an ordered triple giving the byte, word and long forms of
235
    the appropriate machine instruction.
266
    the appropriate machine instruction.
236
*/
267
*/
237
 
268
 
238
static void andetc
269
static void
239
    PROTO_N ( ( opb, opw, opl, sha, a1, a2, dest, logop ) )
-
 
240
    PROTO_T ( int opb X int opw X int opl X shape sha X where a1 X where a2 X where dest X int logop )
270
andetc(int opb, int opw, int opl, shape sha, where a1, where a2, where dest,
-
 
271
       int logop)
241
{
272
{
242
    int instr ;
273
	int instr;
243
    long wha, whb, whd ;
274
	long wha, whb, whd;
244
    long sz = shape_size ( sha ) ;
275
	long sz = shape_size(sha);
245
 
-
 
246
    if ( eq_where ( a1, a2 ) ) {
-
 
247
	switch ( logop ) {
-
 
248
	    case AND : move ( sha, a1, dest ) ; return ;
-
 
249
	    case OR  : move ( sha, a1, dest ) ; return ;
-
 
250
	    case XOR : move ( sha, zero, dest ) ; return ;
-
 
251
	}
-
 
252
    }
-
 
253
 
-
 
254
    instr = ins ( sz, opb, opw, opl ) ;
-
 
255
 
-
 
256
    wha = whereis ( a1 ) ;
-
 
257
    whb = whereis ( a2 ) ;
-
 
258
 
-
 
259
    if ( wha == Freg ) {
-
 
260
	move ( sha, a1, D0 ) ;
-
 
261
	andetc ( opb, opw, opl, sha, D0, a2, dest, logop ) ;
-
 
262
	return ;
-
 
263
    }
-
 
264
 
-
 
265
    if ( whb == Freg ) {
-
 
266
	move ( sha, a2, D0 ) ;
-
 
267
	andetc ( opb, opw, opl, sha, a1, D0, dest, logop ) ;
-
 
268
	return ;
-
 
269
    }
-
 
270
 
-
 
271
    if ( wha == Value ) {
-
 
272
	long c = nw ( a1 ) ;
-
 
273
	andetc_const ( instr, sha, sz, c, a2, dest, logop ) ;
-
 
274
	return ;
-
 
275
    }
-
 
276
 
276
 
-
 
277
	if (eq_where(a1, a2)) {
-
 
278
		switch (logop) {
-
 
279
		case AND:
-
 
280
			move(sha, a1, dest);
-
 
281
			return;
-
 
282
		case OR:
-
 
283
			move(sha, a1, dest);
-
 
284
			return;
-
 
285
		case XOR:
-
 
286
			move(sha, zero, dest);
-
 
287
			return;
-
 
288
		}
-
 
289
	}
-
 
290
 
-
 
291
	instr = ins(sz, opb, opw, opl);
-
 
292
 
-
 
293
	wha = whereis(a1);
-
 
294
	whb = whereis(a2);
-
 
295
 
-
 
296
	if (wha == Freg) {
-
 
297
		move(sha, a1, D0);
-
 
298
		andetc(opb, opw, opl, sha, D0, a2, dest, logop);
-
 
299
		return;
-
 
300
	}
-
 
301
 
-
 
302
	if (whb == Freg) {
-
 
303
		move(sha, a2, D0);
-
 
304
		andetc(opb, opw, opl, sha, a1, D0, dest, logop);
-
 
305
		return;
-
 
306
	}
-
 
307
 
-
 
308
	if (wha == Value) {
-
 
309
		long c = nw(a1);
-
 
310
		andetc_const(instr, sha, sz, c, a2, dest, logop);
-
 
311
		return;
-
 
312
	}
-
 
313
 
277
    if ( whb == Value ) {
314
	if (whb == Value) {
278
	long c = nw ( a2 ) ;
315
		long c = nw(a2);
279
	andetc_const ( instr, sha, sz, c, a1, dest, logop ) ;
316
		andetc_const(instr, sha, sz, c, a1, dest, logop);
280
	return ;
317
		return;
281
    }
318
	}
282
 
319
 
283
    whd = whereis ( dest ) ;
320
	whd = whereis(dest);
284
 
321
 
285
    if ( eq_where ( a1, dest ) && whd != Areg ) {
322
	if (eq_where(a1, dest) && whd != Areg) {
286
	if ( whb == Dreg ) {
323
		if (whb == Dreg) {
287
	    ins2 ( instr, sz, sz, a2, dest, 1 ) ;
324
			ins2(instr, sz, sz, a2, dest, 1);
-
 
325
			return;
-
 
326
		}
-
 
327
		if (whd == Dreg) {
-
 
328
			if (logop == XOR || whb == Areg) {
-
 
329
				if (eq_where(dest, D0)) {
-
 
330
					regsinproc |= regmsk(REG_D1);
-
 
331
					move(sha, a2, D1);
-
 
332
					ins2(instr, sz, sz, D1, dest, 1);
-
 
333
					set_cond(dest, sz);
-
 
334
					return;
-
 
335
				} else {
-
 
336
					move(sha, a2, D0);
-
 
337
					ins2(instr, sz, sz, D0, dest, 1);
-
 
338
					set_cond(dest, sz);
288
	    return ;
339
					return;
-
 
340
				}
-
 
341
			} else {
-
 
342
				ins2(instr, sz, sz, a2, dest, 1);
-
 
343
				set_cond(dest, sz);
-
 
344
				return;
-
 
345
			}
-
 
346
		} else {
-
 
347
			move(sha, a2, D0);
-
 
348
			ins2(instr, sz, sz, D0, dest, 1);
-
 
349
			set_cond(dest, sz);
-
 
350
			return;
-
 
351
		}
289
	}
352
	}
290
	if ( whd == Dreg ) {
-
 
291
	    if ( logop == XOR || whb == Areg ) {
-
 
-
 
353
 
292
		if ( eq_where ( dest, D0 ) ) {
354
	if (eq_where(a2, dest) && whd != Areg) {
293
		    regsinproc |= regmsk ( REG_D1 ) ;
-
 
294
		    move ( sha, a2, D1 ) ;
355
		if (wha == Dreg) {
295
		    ins2 ( instr, sz, sz, D1, dest, 1 ) ;
356
			ins2(instr, sz, sz, a1, dest, 1);
296
		    set_cond ( dest, sz ) ;
-
 
297
		    return ;
-
 
298
		} else {
-
 
299
		    move ( sha, a2, D0 ) ;
-
 
300
		    ins2 ( instr, sz, sz, D0, dest, 1 ) ;
-
 
301
		    set_cond ( dest, sz ) ;
357
			set_cond(dest, sz);
302
		    return ;
358
			return;
303
		}
359
		}
304
	    } else {
360
		if (whd == Dreg) {
-
 
361
			if (logop == XOR || wha == Areg || wha == Freg) {
-
 
362
				if (eq_where(dest, D0)) {
-
 
363
					regsinproc |= regmsk(REG_D1);
-
 
364
					move(sha, a1, D1);
305
		ins2 ( instr, sz, sz, a2, dest, 1 ) ;
365
					ins2(instr, sz, sz, D1, dest, 1);
-
 
366
				} else {
306
		set_cond ( dest, sz ) ;
367
					move(sha, a1, D0);
-
 
368
					ins2(instr, sz, sz, D0, dest, 1);
-
 
369
				}
307
		return ;
370
			} else {
-
 
371
				ins2(instr, sz, sz, a1, dest, 1);
308
	    }
372
			}
309
	} else {
373
		} else {
310
	    move ( sha, a2, D0 ) ;
374
			move(sha, a1, D0);
311
	    ins2 ( instr, sz, sz, D0, dest, 1 ) ;
375
			ins2(instr, sz, sz, D0, dest, 1);
-
 
376
		}
312
	    set_cond ( dest, sz ) ;
377
		set_cond(dest, sz);
313
	    return ;
378
		return;
314
	}
379
	}
315
    }
-
 
316
 
380
 
317
    if ( eq_where ( a2, dest ) && whd != Areg ) {
-
 
318
	if ( wha == Dreg ) {
381
	if (whd == Dreg) {
319
	    ins2 ( instr, sz, sz, a1, dest, 1 ) ;
382
		if (!interfere(a2, dest)) {
320
	    set_cond ( dest, sz ) ;
383
			move(sha, a1, dest);
-
 
384
			andetc(opb, opw, opl, sha, a2, dest, dest, logop);
321
	    return ;
385
			return;
322
	}
386
		}
323
	if ( whd == Dreg ) {
-
 
324
	    if ( logop == XOR || wha == Areg || wha == Freg ) {
-
 
325
		if ( eq_where ( dest, D0 ) ) {
387
		if (!interfere(a1, dest)) {
326
		    regsinproc |= regmsk ( REG_D1 ) ;
-
 
327
		    move ( sha, a1, D1 ) ;
388
			move(sha, a2, dest);
328
		    ins2 ( instr, sz, sz, D1, dest, 1 ) ;
389
			andetc(opb, opw, opl, sha, a1, dest, dest, logop);
329
		} else {
390
			return;
330
		    move ( sha, a1, D0 ) ;
-
 
331
		    ins2 ( instr, sz, sz, D0, dest, 1 ) ;
-
 
332
		}
391
		}
333
	    } else {
-
 
334
		ins2 ( instr, sz, sz, a1, dest, 1 ) ;
-
 
335
	    }
-
 
336
	} else {
-
 
337
	    move ( sha, a1, D0 ) ;
-
 
338
	    ins2 ( instr, sz, sz, D0, dest, 1 ) ;
-
 
339
	}
-
 
340
	set_cond ( dest, sz ) ;
-
 
341
	return ;
-
 
342
    }
-
 
343
 
-
 
344
    if ( whd == Dreg ) {
-
 
345
	if ( !interfere ( a2, dest ) ) {
-
 
346
	    move ( sha, a1, dest ) ;
-
 
347
	    andetc ( opb, opw, opl, sha, a2, dest, dest, logop ) ;
-
 
348
	    return ;
-
 
349
	}
-
 
350
	if ( !interfere ( a1, dest ) ) {
-
 
351
	    move ( sha, a2, dest ) ;
-
 
352
	    andetc ( opb, opw, opl, sha, a1, dest, dest, logop ) ;
-
 
353
	    return ;
-
 
354
	}
392
	}
355
    }
-
 
356
 
393
 
357
    move ( sha, a1, D0 ) ;
394
	move(sha, a1, D0);
358
    andetc ( opb, opw, opl, sha, a2, D0, D0, logop ) ;
395
	andetc(opb, opw, opl, sha, a2, D0, D0, logop);
359
    move ( sha, D0, dest ) ;
396
	move(sha, D0, dest);
360
    return ;
397
	return;
361
}
398
}
362
 
399
 
363
 
400
 
364
/*
401
/*
365
    AND INSTRUCTION
402
    AND INSTRUCTION
366
 
403
 
367
    The values a1 and a2 of shape sha are anded and the result is stored
404
    The values a1 and a2 of shape sha are anded and the result is stored
368
    in dested.
405
    in dested.
369
*/
406
*/
370
 
407
 
371
void and
408
void
372
    PROTO_N ( ( sha, a1, a2, dest ) )
-
 
373
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
409
and(shape sha, where a1, where a2, where dest)
374
{
410
{
375
    andetc ( ml_and, sha, a1, a2, dest, AND ) ;
411
	andetc(ml_and, sha, a1, a2, dest, AND);
376
    return ;
412
	return;
377
}
413
}
378
 
414
 
379
 
415
 
380
/*
416
/*
381
    OR INSTRUCTION
417
    OR INSTRUCTION
382
 
418
 
383
    The values a1 and a2 of shape sha are ored and the result is stored
419
    The values a1 and a2 of shape sha are ored and the result is stored
384
    in dested.
420
    in dested.
385
*/
421
*/
386
 
422
 
387
void or
423
void
388
    PROTO_N ( ( sha, a1, a2, dest ) )
-
 
389
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
424
or(shape sha, where a1, where a2, where dest)
390
{
425
{
391
    andetc ( ml_or, sha, a1, a2, dest, OR ) ;
426
	andetc(ml_or, sha, a1, a2, dest, OR);
392
    return ;
427
	return;
393
}
428
}
394
 
429
 
395
 
430
 
396
/*
431
/*
397
    XOR INSTRUCTION
432
    XOR INSTRUCTION
398
 
433
 
399
    The values a1 and a2 of shape sha are xored and the result is stored
434
    The values a1 and a2 of shape sha are xored and the result is stored
400
    in dested.
435
    in dested.
401
*/
436
*/
402
 
437
 
403
void xor
438
void
404
    PROTO_N ( ( sha, a1, a2, dest ) )
-
 
405
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
439
xor(shape sha, where a1, where a2, where dest)
406
{
440
{
407
    andetc ( ml_eor, sha, a1, a2, dest, XOR ) ;
441
	andetc(ml_eor, sha, a1, a2, dest, XOR);
408
    return ;
442
	return;
409
}
443
}
410
 
444
 
411
 
445
 
412
/*
446
/*
413
    LOGICAL NEGATION INSTRUCTION
447
    LOGICAL NEGATION INSTRUCTION
414
 
448
 
415
    The value a of shape sha is logically negated and the result is stored
449
    The value a of shape sha is logically negated and the result is stored
416
    in dest.
450
    in dest.
417
*/
451
*/
418
 
452
 
419
void not
453
void
420
    PROTO_N ( ( sha, a, dest ) )
-
 
421
    PROTO_T ( shape sha X where a X where dest )
454
not(shape sha, where a, where dest)
422
{
455
{
423
    int instr ;
456
	int instr;
424
    long sz = shape_size ( sha ) ;
457
	long sz = shape_size(sha);
425
    long wha = whereis ( a ) ;
458
	long wha = whereis(a);
426
    long whd = whereis ( dest ) ;
459
	long whd = whereis(dest);
427
 
-
 
428
    if ( wha == Value ) {
-
 
429
	long c = nw ( a ) ;
-
 
430
	move ( sha, mnw ( ~c ), dest ) ;
-
 
431
	return ;
-
 
432
    }
-
 
433
 
-
 
434
    if ( eq_where ( a, dest ) && whd != Areg ) {
-
 
435
	instr = ins ( sz, ml_not ) ;
-
 
436
	ins1 ( instr, sz, dest, 1 ) ;
-
 
437
	set_cond ( dest, sz ) ;
-
 
438
	return ;
-
 
439
    }
-
 
440
 
-
 
441
    if ( whd == Dreg ) {
-
 
442
	move ( sha, a, dest ) ;
-
 
443
	not ( sha, dest, dest ) ;
-
 
444
	return ;
-
 
445
    }
-
 
446
 
-
 
447
    if ( wha == Dreg && last_use ( a ) ) {
-
 
448
	not ( sha, a, a ) ;
-
 
449
	move ( sha, a, dest ) ;
-
 
450
	return ;
-
 
451
    }
-
 
452
 
460
 
-
 
461
	if (wha == Value) {
-
 
462
		long c = nw(a);
-
 
463
		move(sha, mnw(~c), dest);
-
 
464
		return;
-
 
465
	}
-
 
466
 
-
 
467
	if (eq_where(a, dest) && whd != Areg) {
-
 
468
		instr = ins(sz, ml_not);
-
 
469
		ins1(instr, sz, dest, 1);
-
 
470
		set_cond(dest, sz);
-
 
471
		return;
-
 
472
	}
-
 
473
 
-
 
474
	if (whd == Dreg) {
-
 
475
		move(sha, a, dest);
-
 
476
		not(sha, dest, dest);
-
 
477
		return;
-
 
478
	}
-
 
479
 
-
 
480
	if (wha == Dreg && last_use(a)) {
-
 
481
		not(sha, a, a);
-
 
482
		move(sha, a, dest);
-
 
483
		return;
-
 
484
	}
-
 
485
 
453
    move ( sha, a, D0 ) ;
486
	move(sha, a, D0);
454
    not ( sha, D0, D0 ) ;
487
	not(sha, D0, D0);
455
    move ( sha, D0, dest ) ;
488
	move(sha, D0, dest);
456
    return ;
489
	return;
457
}
490
}
458
 
491
 
459
 
492
 
460
/*
493
/*
461
    LOW LEVEL SHIFT
494
    LOW LEVEL SHIFT
462
 
495
 
463
    This routine outputs a simple shift instruction, taking overflow
496
    This routine outputs a simple shift instruction, taking overflow
464
    into account if necessary (not right yet).
497
    into account if necessary (not right yet).
465
*/
498
*/
466
 
499
 
467
static void shift_it
500
static void
468
    PROTO_N ( ( sha, shb, instr, by, to ) )
-
 
469
    PROTO_T ( shape sha X shape shb X int instr X where by X where to )
501
shift_it(shape sha, shape shb, int instr, where by, where to)
470
{
502
{
471
    long sz = shape_size ( sha ) ;
503
	long sz = shape_size(sha);
472
    ins2 ( instr, L8, sz, by, to, 1 ) ;
504
	ins2(instr, L8, sz, by, to, 1);
473
    have_cond = 0 ;
505
	have_cond = 0;
474
    test_overflow( ON_OVERFLOW ) ;
506
	test_overflow(ON_OVERFLOW);
475
    return ;
507
	return;
476
}
508
}
477
 
509
 
478
 
510
 
479
/*
511
/*
480
    AUXILIARY SHIFT ROUTINE
512
    AUXILIARY SHIFT ROUTINE
481
 
513
 
482
    The value from of shape sha is shifted, either left if sw is 0, or
514
    The value from of shape sha is shifted, either left if sw is 0, or
483
    right otherwise, by the value by.  The result is stored in to.
515
    right otherwise, by the value by.  The result is stored in to.
484
    The dont_use_D1 flag indicates that register D1 should not be used.
516
    The dont_use_D1 flag indicates that register D1 should not be used.
485
    It is always false for simple shifts, but may be true for certain
517
    It is always false for simple shifts, but may be true for certain
486
    multiplications which are done by shifts.
518
    multiplications which are done by shifts.
487
*/
519
*/
488
 
520
 
489
void shift_aux
521
void
490
    PROTO_N ( ( sha, by, from, to, sw, dont_use_D1 ) )
-
 
491
    PROTO_T ( shape sha X where by X where from X where to X int sw X int dont_use_D1 )
522
shift_aux(shape sha, where by, where from, where to, int sw, int dont_use_D1)
492
{
523
{
609
}
621
}
610
 
622
 
611
 
623
 
612
/*
624
/*
-
 
625
    MAIN LEFT SHIFT ROUTINE
-
 
626
 
-
 
627
    The value from of shape sha is shifted left by the value by.  The
-
 
628
    result is stored in to.
-
 
629
*/
-
 
630
 
-
 
631
void
-
 
632
shift(shape sha, where by, where from, where to)
-
 
633
{
-
 
634
	shift_aux(sha, by, from, to, 0, 0);
-
 
635
	return;
-
 
636
}
-
 
637
 
-
 
638
 
-
 
639
/*
613
    MAIN RIGHT SHIFT ROUTINE
640
    MAIN RIGHT SHIFT ROUTINE
614
 
641
 
615
    The value from of shape sha is shifted right by the value by.  The
642
    The value from of shape sha is shifted right by the value by.  The
616
    result is stored in to.
643
    result is stored in to.
617
*/
644
*/
618
 
645
 
619
void rshift
646
void
620
    PROTO_N ( ( sha, by, from, to ) )
-
 
621
    PROTO_T ( shape sha X where by X where from X where to )
647
rshift(shape sha, where by, where from, where to)
622
{
648
{
623
    shift_aux ( sha, by, from, to, 1, 0 ) ;
649
	shift_aux(sha, by, from, to, 1, 0);
624
    return ;
650
	return;
625
}
651
}
626
 
652
 
627
 
653
 
628
/*
654
/*
629
    ADJUST AN EXPRESSION READY FOR A BITFIELD OPERATION
655
    ADJUST AN EXPRESSION READY FOR A BITFIELD OPERATION
630
 
656
 
631
    The value in the no field of e is rounded down to a multiple of 32.
657
    The value in the no field of e is rounded down to a multiple of 32.
632
    The remainder is the bitfield offset and is returned.
658
    The remainder is the bitfield offset and is returned.
633
*/
659
*/
634
 
660
 
635
static long adjust_bitf
661
static long
636
    PROTO_N ( ( e ) )
-
 
637
    PROTO_T ( exp e )
662
adjust_bitf(exp e)
638
{
663
{
639
    long boff = no ( e ) % 32 ;
664
	long boff = no(e)% 32;
640
    no ( e ) -= boff ;
665
	no(e) -= boff;
641
    return ( boff ) ;
666
	return (boff);
-
 
667
}
-
 
668
 
-
 
669
 
-
 
670
/*
-
 
671
    FIND POSITION OF A CONTENTS BITFIELD
-
 
672
*/
-
 
673
 
-
 
674
static long
-
 
675
contents_bitf(exp e)
-
 
676
{
-
 
677
	char n = name(e);
-
 
678
	if (n == name_tag || n == reff_tag) {
-
 
679
		return (adjust_bitf(e));
-
 
680
	}
-
 
681
	if (n == ident_tag) {
-
 
682
		exp s = son(e);
-
 
683
		exp b = bro(s);
-
 
684
		if (name(b) == reff_tag) {
-
 
685
			return (adjust_bitf(b));
-
 
686
		}
-
 
687
		if (name(b) == ident_tag) {
-
 
688
			return (contents_bitf(b));
-
 
689
		}
-
 
690
		if (name(b) == name_tag && son(b) == e &&
-
 
691
		    name(s) == name_tag) {
-
 
692
			return (contents_bitf(son(s)));
-
 
693
		}
-
 
694
		if (name(s) == name_tag) {
-
 
695
			return (adjust_bitf(s));
-
 
696
		}
-
 
697
	}
-
 
698
	error("Illegal bitfield operation");
-
 
699
	return (0);
642
}
700
}
643
 
701
 
644
 
702
 
645
/*
703
/*
646
    FIND POSITION OF A CONTENTS BITFIELD
704
    FIND POSITION OF A BITFIELD OPERATION
647
*/
705
*/
648
 
706
 
649
static long contents_bitf
707
static long
650
    PROTO_N ( ( e ) )
-
 
651
    PROTO_T ( exp e )
708
bitf_posn(exp e)
652
{
709
{
653
    char n = name ( e ) ;
710
	char n = name(e);
654
    if ( n == name_tag || n == reff_tag ) return ( adjust_bitf ( e ) ) ;
-
 
655
    if ( n == ident_tag ) {
711
	if (n == name_tag) {
656
	exp s = son ( e ) ;
712
		return (adjust_bitf(e));
657
	exp b = bro ( s ) ;
713
	}
658
	if ( name ( b ) == reff_tag ) return ( adjust_bitf ( b ) ) ;
714
	if (n == cont_tag || n == ass_tag) {
659
	if ( name ( b ) == ident_tag ) return ( contents_bitf ( b ) ) ;
-
 
660
	if ( name ( b ) == name_tag && son ( b ) == e &&
715
		return (bitf_posn(son(e)));
-
 
716
	}
661
	     name ( s ) == name_tag ) {
717
	if (n == ident_tag) {
662
	    return ( contents_bitf ( son ( s ) ) ) ;
718
		return (0);
663
	}
719
	}
664
	if ( name ( s ) == name_tag ) return ( adjust_bitf ( s ) ) ;
-
 
665
    }
-
 
666
    error ( "Illegal bitfield operation" ) ;
720
	error("Illegal bitfield operation");
667
    return ( 0 ) ;
-
 
668
}
-
 
669
 
-
 
670
 
-
 
671
/*
-
 
672
    FIND POSITION OF A BITFIELD OPERATION
-
 
673
*/
-
 
674
 
-
 
675
static long bitf_posn
-
 
676
    PROTO_N ( ( e ) )
-
 
677
    PROTO_T ( exp e )
-
 
678
{
-
 
679
    char n = name ( e ) ;
-
 
680
    if ( n == name_tag ) return ( adjust_bitf ( e ) ) ;
-
 
681
    if ( n == cont_tag || n == ass_tag ) {
-
 
682
	return ( bitf_posn ( son ( e ) ) ) ;
-
 
683
    }
-
 
684
    if ( n == ident_tag ) return ( 0 ) ;
-
 
685
    error ( "Illegal bitfield operation" ) ;
-
 
686
    return ( 0 ) ;
721
	return (0);
687
}
722
}
688
 
723
 
689
 
724
 
690
/*
725
/*
691
    EXTRACT A BITFIELD
726
    EXTRACT A BITFIELD
692
 
727
 
693
    The bitfield e of shape sha is extracted into dest.  The current state
728
    The bitfield e of shape sha is extracted into dest.  The current state
694
    of the stack is also given.
729
    of the stack is also given.
695
*/
730
*/
696
 
731
 
697
void bitf_to_int
732
void
698
    PROTO_N ( ( e, sha, dest, stack ) )
-
 
699
    PROTO_T ( exp e X shape sha X where dest X ash stack )
733
bitf_to_int(exp e, shape sha, where dest, ash stack)
700
{
734
{
701
    where bf, d ;
735
	where bf, d;
702
    exp t = dest.wh_exp ;
736
	exp t = dest.wh_exp;
703
    shape dsha = sh ( t ) ;
737
	shape dsha = sh(t);
704
 
738
 
705
    int extend = ( is_signed ( sha ) ? 1 : 0 ) ;
739
	int extend = (is_signed(sha)? 1 : 0);
706
    int instr = ( extend ? m_bfexts : m_bfextu ) ;
740
	int instr = (extend ? m_bfexts : m_bfextu);
707
 
741
 
708
    long off, sz, bstart ;
742
	long off, sz, bstart;
709
    bitpattern pmask ;
743
	bitpattern pmask;
710
    long nbits = shape_size ( sha ) ;
744
	long nbits = shape_size(sha);
711
    long boff = bitf_posn ( e ) ;
745
	long boff = bitf_posn(e);
712
 
746
 
713
    off = 8 * ( boff / 8 ) ;
747
	off = 8 *(boff / 8);
714
    sz = 8 * ( ( boff + nbits - 1 ) / 8 ) + 8 - off ;
748
	sz = 8 *((boff + nbits - 1) / 8) + 8 - off;
715
    if ( sz == 24 ) { sz = 32 ; off -= 8 ; }
749
	if (sz == 24) {
-
 
750
		sz = 32;
-
 
751
		off -= 8;
-
 
752
	}
716
    bstart = boff - off ;
753
	bstart = boff - off;
717
 
754
 
718
    pmask = ( ( hi_bits [ nbits ] ) >> bstart ) >> ( 32 - sz ) ;
755
	pmask = ((hi_bits[nbits]) >> bstart) >> (32 - sz);
719
 
756
 
720
    switch ( name ( t ) ) {
757
	switch (name(t)) {
-
 
758
	case ident_tag:
721
	case ident_tag : dsha = sh ( son ( t ) ) ; break ;
759
		dsha = sh(son(t));
-
 
760
		break;
-
 
761
	case ass_tag:
722
	case ass_tag : dsha = sh ( bro ( son ( t ) ) ) ; break ;
762
		dsha = sh(bro(son(t)));
-
 
763
		break;
723
    }
764
	}
-
 
765
	if (name(dsha) == bitfhd) {
724
    if ( name ( dsha ) == bitfhd ) dsha = ( extend ? slongsh : ulongsh ) ;
766
		dsha = (extend ? slongsh : ulongsh);
-
 
767
	}
-
 
768
	if (name(dsha) == tophd) {
725
    if ( name ( dsha ) == tophd ) warning ( "Top in bitfield assignment" ) ;
769
		warning("Top in bitfield assignment");
-
 
770
	}
726
 
771
 
727
    bf = mw ( e, off ) ;
772
	bf = mw(e, off);
728
 
773
 
729
    if ( bstart == 0 && nbits == sz ) {
774
	if (bstart == 0 && nbits == sz) {
730
	shape bsha ;
775
		shape bsha;
731
	switch ( sz ) {
776
		switch (sz) {
-
 
777
		case 8:
732
	    case 8 : bsha = scharsh ; break ;
778
			bsha = scharsh;
-
 
779
			break;
-
 
780
		case 16:
733
	    case 16 : bsha = swordsh ; break ;
781
			bsha = swordsh;
-
 
782
			break;
-
 
783
		case 32:
734
	    case 32 : bsha = slongsh ; break ;
784
			bsha = slongsh;
-
 
785
			break;
735
	}
786
		}
736
	change_var_sh ( dsha, bsha, bf, dest ) ;
787
		change_var_sh(dsha, bsha, bf, dest);
737
	return ;
788
		return;
738
    }
789
	}
739
 
790
 
740
    if ( whereis ( bf ) == Dreg ) {
791
	if (whereis(bf) == Dreg) {
741
	bitpattern m = ( lo_bits [ nbits ] <<  boff ) ;
792
		bitpattern m = (lo_bits[nbits] <<  boff);
742
	d = ( whereis ( dest ) == Dreg ? dest : D0 ) ;
793
		d = (whereis(dest) == Dreg ? dest : D0);
743
	and ( slongsh, bf, mnw ( m ), d ) ;
794
		and(slongsh, bf, mnw(m), d);
744
	if ( extend ) {
795
		if (extend) {
745
	    long r = 32 - nbits - boff ;
796
			long r = 32 - nbits - boff;
746
	    if ( r ) {
797
			if (r) {
747
		if ( r <= 8 ) {
798
				if (r <= 8) {
748
		    ins2n ( m_lsll, r, L32, d, 1 ) ;
799
					ins2n(m_lsll, r, L32, d, 1);
749
		    ins2n ( m_asrl, r, L32, d, 1 ) ;
800
					ins2n(m_asrl, r, L32, d, 1);
750
		} else {
801
				} else {
751
		    regsinproc |= regmsk ( REG_D1 ) ;
802
					regsinproc |= regmsk(REG_D1);
752
		    ins2n ( m_moveq, r, L32, D1, 1 ) ;
803
					ins2n(m_moveq, r, L32, D1, 1);
753
		    ins2 ( m_lsll, L32, L32, D1, d, 1 ) ;
804
					ins2(m_lsll, L32, L32, D1, d, 1);
754
		    ins2 ( m_asrl, L32, L32, D1, d, 1 ) ;
805
					ins2(m_asrl, L32, L32, D1, d, 1);
755
		}
806
				}
756
	    }
807
			}
757
	}
808
		}
758
	have_cond = 0 ;
809
		have_cond = 0;
759
	change_var_sh ( dsha, slongsh, d, dest ) ;
810
		change_var_sh(dsha, slongsh, d, dest);
760
	return ;
811
		return;
761
    } else {
812
	} else {
762
	mach_op *op1, *op2 ;
813
		mach_op *op1, *op2;
763
	d = ( whereis ( dest ) == Dreg ? dest : D0 ) ;
814
		d = (whereis(dest) == Dreg ? dest : D0);
764
	op1 = operand ( L32, bf ) ;
815
		op1 = operand(L32, bf);
765
	op1 = make_bitfield_op ( op1, ( int ) bstart, ( int ) nbits ) ;
816
		op1 = make_bitfield_op(op1,(int)bstart,(int)nbits);
766
	op2 = operand ( L32, d ) ;
817
		op2 = operand(L32, d);
767
	make_instr ( instr, op1, op2, regs_changed ( op2, 1 ) ) ;
818
		make_instr(instr, op1, op2, regs_changed(op2, 1));
768
	have_cond = 0 ;
819
		have_cond = 0;
769
	change_var_sh ( dsha, slongsh, d, dest ) ;
820
		change_var_sh(dsha, slongsh, d, dest);
770
	return ;
821
		return;
771
    }
822
	}
772
}
823
}
773
 
824
 
774
 
825
 
775
/*
826
/*
776
    INSERT A BITFIELD
827
    INSERT A BITFIELD
777
 
828
 
778
    The value e is inserted into the bitfield d.  The state of the stack
829
    The value e is inserted into the bitfield d.  The state of the stack
779
    is also given.
830
    is also given.
780
*/
831
*/
781
 
832
 
782
void int_to_bitf
833
void
783
    PROTO_N ( ( e, d, stack ) )
-
 
784
    PROTO_T ( exp e X exp d X ash stack )
834
int_to_bitf(exp e, exp d, ash stack)
785
{
835
{
786
    shape sha ;
836
	shape sha;
787
    where dest, f ;
837
	where dest, f;
788
 
838
 
789
    long off, sz, bstart, bend ;
839
	long off, sz, bstart, bend;
790
    bitpattern pmask, nmask, v ;
840
	bitpattern pmask, nmask, v;
791
    long nbits = shape_size ( sh ( e ) ) ;
841
	long nbits = shape_size(sh(e));
792
    long boff = bitf_posn ( d ) ;
842
	long boff = bitf_posn(d);
793
 
843
 
794
    off = 8 * ( boff / 8 ) ;
844
	off = 8 *(boff / 8);
795
    sz = 8 * ( ( boff + nbits - 1 ) / 8 ) + 8 - off ;
845
	sz = 8 *((boff + nbits - 1) / 8) + 8 - off;
796
    if ( sz == 24 ) { sz = 32 ; off -= 8 ; }
846
	if (sz == 24) {
-
 
847
		sz = 32;
-
 
848
		off -= 8;
-
 
849
	}
797
    bstart = boff - off ;
850
	bstart = boff - off;
798
    bend = sz - nbits - bstart ;
851
	bend = sz - nbits - bstart;
799
 
852
 
800
    pmask = ( ( hi_bits [ nbits ] ) >> bstart ) >> ( 32 - sz ) ;
853
	pmask = ((hi_bits[nbits]) >> bstart) >> (32 - sz);
801
    nmask = ~pmask ;
854
	nmask = ~pmask;
802
 
855
 
803
    switch ( sz ) {
856
	switch (sz) {
-
 
857
	case 8:
-
 
858
		nmask &= 0xff;
804
	case 8 : nmask &= 0xff ; sha = scharsh ; break ;
859
		sha = scharsh;
-
 
860
		break;
-
 
861
	case 16:
805
	case 16 : nmask &= 0xffff ; sha = swordsh ; break ;
862
		nmask &= 0xffff;
-
 
863
		sha = swordsh;
-
 
864
		break;
-
 
865
	default:
806
	default : sha = slongsh ; break ;
866
		sha = slongsh;
-
 
867
		break;
807
    }
868
	}
808
 
869
 
809
    if ( name ( e ) == int_to_bitf_tag ) {
870
	if (name(e) == int_to_bitf_tag) {
810
	exp s = son ( e ) ;
871
		exp s = son(e);
811
	if ( is_o ( name ( s ) ) ) {
872
		if (is_o(name(s))) {
812
	    e = s ;
873
			e = s;
813
	} else {
874
		} else {
814
	    regsinproc |= regmsk ( REG_D1 ) ;
875
			regsinproc |= regmsk(REG_D1);
815
	    coder ( D1, stack, s ) ;
876
			coder(D1, stack, s);
816
	    if ( shape_size ( sh ( s ) ) < 32 ) warning ( "Think again!" ) ;
877
			if (shape_size(sh(s)) < 32) {
-
 
878
				warning("Think again!");
-
 
879
			}
817
	    e = D1.wh_exp ;
880
			e = D1.wh_exp;
818
	}
881
		}
819
    }
882
	}
820
 
883
 
821
    dest = mw ( d, off ) ;
884
	dest = mw(d, off);
822
 
885
 
823
    if ( bstart == 0 && nbits == sz ) {
886
	if (bstart == 0 && nbits == sz) {
824
	change_var_sh ( sha, sh ( e ), zw ( e ), dest ) ;
887
		change_var_sh(sha, sh(e), zw(e), dest);
825
	return ;
888
		return;
826
    }
889
	}
827
 
890
 
828
    if ( ( bstart + nbits > 32 ) || ( name ( e ) != val_tag ) ) {
891
	if ((bstart + nbits > 32) || (name(e)!= val_tag)) {
829
	where dd ;
892
		where dd;
830
	bitpattern ch ;
893
		bitpattern ch;
831
	mach_op *op1, *op2 ;
894
		mach_op *op1, *op2;
832
	dd = zw ( e ) ;
895
		dd = zw(e);
833
	if ( whereis ( dd ) != Dreg || shape_size ( sh ( e ) ) != 32 ) {
896
		if (whereis(dd)!= Dreg || shape_size(sh(e))!= 32) {
834
	    change_var_sh ( slongsh, sh ( e ), dd, D0 ) ;
897
			change_var_sh(slongsh, sh(e), dd, D0);
835
	    dd = D0 ;
898
			dd = D0;
836
	}
899
		}
837
	op1 = operand ( L32, dd ) ;
900
		op1 = operand(L32, dd);
838
	op2 = operand ( L32, dest ) ;
901
		op2 = operand(L32, dest);
839
	ch = regs_changed ( op2, 1 ) ;
902
		ch = regs_changed(op2, 1);
840
	op2 = make_bitfield_op ( op2, ( int ) bstart, ( int ) nbits ) ;
903
		op2 = make_bitfield_op(op2,(int)bstart,(int)nbits);
841
	make_instr ( m_bfins, op1, op2, ch ) ;
904
		make_instr(m_bfins, op1, op2, ch);
842
	have_cond = 0 ;
905
		have_cond = 0;
843
	return ;
906
		return;
844
    }
907
	}
845
 
908
 
846
    v = ( bitpattern ) no ( e ) ;
909
	v = (bitpattern)no(e);
847
    v = ( ( v << bend ) & pmask ) ;
910
	v = ((v << bend) & pmask);
848
 
911
 
849
    if ( v == 0 ) {
912
	if (v == 0) {
850
	and ( sha, mnw ( nmask ), dest, dest ) ;
913
		and(sha, mnw(nmask), dest, dest);
851
	return ;
914
		return;
852
    }
915
	}
853
 
916
 
854
    if ( v == pmask ) {
917
	if (v == pmask) {
855
	or ( sha, mnw ( pmask ), dest, dest ) ;
918
		or(sha, mnw(pmask), dest, dest);
856
	return ;
919
		return;
857
    }
920
	}
858
 
921
 
859
    f = ( ( whereis ( dest ) == Dreg ) ? dest : D0 ) ;
922
	f = ((whereis(dest) == Dreg)? dest : D0);
860
    and ( sha, mnw ( nmask ), dest, f ) ;
923
	and(sha, mnw(nmask), dest, f);
861
    or ( sha, mnw ( v ), f, dest ) ;
924
	or(sha, mnw(v), f, dest);
862
    return ;
925
	return;
863
}
926
}
864
 
927
 
865
 
928
 
866
/*
929
/*
867
    TEST A NUMBER OF BITS
930
    TEST A NUMBER OF BITS
868
 
931
 
Line 870... Line 933...
870
    the value a2 are set.  If a2 is a constant power of 2 then a bit
933
    the value a2 are set.  If a2 is a constant power of 2 then a bit
871
    test operation is used.  Otherwise a1 is anded with a2 and the
934
    test operation is used.  Otherwise a1 is anded with a2 and the
872
    result is stored in an unwanted D-register.
935
    result is stored in an unwanted D-register.
873
*/
936
*/
874
 
937
 
875
void bit_test
938
void
876
    PROTO_N ( ( sha, a1, a2 ) )
-
 
877
    PROTO_T ( shape sha X where a1 X where a2 )
939
bit_test(shape sha, where a1, where a2)
878
{
940
{
879
    long sz = shape_size ( sha ) ;
941
	long sz = shape_size(sha);
880
    long wh1 = whereis ( a1 ) ;
942
	long wh1 = whereis(a1);
881
    long wh2 = whereis ( a2 ) ;
943
	long wh2 = whereis(a2);
882
    if ( wh2 == Value ) {
944
	if (wh2 == Value) {
883
	if ( wh1 == External || wh1 == Parameter || wh1 == RegInd ) {
945
		if (wh1 == External || wh1 == Parameter || wh1 == RegInd) {
884
	    long v = nw ( a2 ) ;
946
			long v = nw(a2);
885
	    if ( is_pow2 ( v ) ) {
947
			if (is_pow2(v)) {
886
		where w ;
948
				where w;
887
		long n = log2 ( v ) ;
949
				long n = log2(v);
888
		long off = sz - 8 * ( 1 + ( n / 8 ) ) ;
950
				long off = sz - 8 *(1 + (n / 8));
889
		w = mw ( a1.wh_exp, a1.wh_off + off ) ;
951
				w = mw(a1.wh_exp, a1.wh_off + off);
890
		ins2n ( m_btstb, n % 8, 8, w, 1 ) ;
952
				ins2n(m_btstb, n % 8, 8, w, 1);
-
 
953
				have_cond = 0;
-
 
954
				return;
-
 
955
			}
-
 
956
		}
-
 
957
		if (wh1 == Dreg) {
-
 
958
			long v = nw(a2);
-
 
959
			if (last_use(a1)) {
-
 
960
				and(sha, a2, a1, a1);
-
 
961
				return;
-
 
962
			}
-
 
963
			if (is_pow2(v) && sz == 32) {
-
 
964
				long n = log2(v);
-
 
965
				ins2n(m_btstl, n, sz, a1, 1);
891
		have_cond = 0 ;
966
				have_cond = 0;
892
		return ;
967
				return;
893
	    }
968
			}
-
 
969
		}
-
 
970
	}
-
 
971
	if (wh1 == Dreg && last_use(a1)) {
-
 
972
		and(sha, a2, a1, a1);
-
 
973
		return;
894
	}
974
	}
895
	if ( wh1 == Dreg ) {
-
 
896
	    long v = nw ( a2 ) ;
-
 
897
	    if ( last_use ( a1 ) ) {
975
	if (wh2 == Dreg && last_use(a2)) {
898
		and ( sha, a2, a1, a1 ) ;
976
		and(sha, a1, a2, a2);
899
		return ;
-
 
900
	    }
-
 
901
	    if ( is_pow2 ( v ) && sz == 32 ) {
-
 
902
		long n = log2 ( v ) ;
-
 
903
		ins2n ( m_btstl, n, sz, a1, 1 ) ;
-
 
904
		have_cond = 0 ;
-
 
905
		return ;
977
		return;
906
	    }
-
 
907
	}
978
	}
908
    }
-
 
909
    if ( wh1 == Dreg && last_use ( a1 ) ) {
-
 
910
	and ( sha, a2, a1, a1 ) ;
979
	move(sha, a1, D0);
911
	return ;
-
 
912
    }
-
 
913
    if ( wh2 == Dreg && last_use ( a2 ) ) {
-
 
914
	and ( sha, a1, a2, a2 ) ;
980
	and(sha, a2, D0, D0);
915
	return ;
981
	return;
916
    }
-
 
917
    move ( sha, a1, D0 ) ;
-
 
918
    and ( sha, a2, D0, D0 ) ;
-
 
919
    return ;
-
 
920
}
982
}