xref: /netbsd/external/bsd/pcc/dist/pcc/arch/pdp11/table.c (revision 6550d01e)
1 /*	Id: table.c,v 1.5 2008/10/19 15:25:25 ragge Exp 	*/
2 /*	$NetBSD: table.c,v 1.1.1.2 2010/06/03 18:57:25 plunky Exp $	*/
3 /*
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 
31 # include "pass2.h"
32 
33 # define TLL TLONGLONG|TULONGLONG
34 # define ANYSIGNED TINT|TLONG|TSHORT|TCHAR
35 # define ANYUSIGNED TUNSIGNED|TULONG|TUSHORT|TUCHAR
36 # define ANYFIXED ANYSIGNED|ANYUSIGNED
37 # define TUWORD TUNSIGNED
38 # define TSWORD TINT
39 # define TWORD TUWORD|TSWORD
40 # define ANYSH	SCON|SAREG|SOREG|SNAME
41 # define ARONS	SAREG|SOREG|SNAME|STARNM
42 
43 struct optab table[] = {
44 /* First entry must be an empty entry */
45 { -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", },
46 
47 /* PCONVs are usually not necessary */
48 { PCONV,	INAREG,
49 	SAREG,	TWORD|TPOINT,
50 	SAREG,	TWORD|TPOINT,
51 		0,	RLEFT,
52 		"", },
53 
54 /* convert char to int or unsigned */
55 { SCONV,	INAREG,
56 	SAREG,	TCHAR,
57 	SAREG,	TINT|TUNSIGNED,
58 		NAREG|NASL,	RESC1,
59 		"", }, /* chars are stored as ints in registers */
60 
61 { SCONV,	INAREG,
62 	SOREG|SCON|SNAME,	TCHAR,
63 	SAREG,	TINT,
64 		NAREG|NASL,	RESC1,
65 		"movb	AL,A1\n", },
66 
67 /* convert uchar to int or unsigned */
68 { SCONV,	INAREG,
69 	SAREG|SOREG|SCON|SNAME,	TUCHAR,
70 	SAREG,	TINT|TUNSIGNED,
71 		NAREG,	RESC1,
72 		"clr	A1\nbisb	AL,A1\n", },
73 
74 /* convert (u)int to (u)char.  Nothing to do. */
75 { SCONV,	INAREG,
76 	SAREG,	TWORD,
77 	SANY,	TCHAR|TUCHAR,
78 		0,	RLEFT,
79 		"", },
80 
81 /* convert (u)int to (u)int */
82 { SCONV,	INAREG,
83 	SAREG,	TWORD,
84 	SANY,	TWORD,
85 		0,	RLEFT,
86 		"", },
87 
88 /* convert pointer to (u)int */
89 { SCONV,	INAREG,
90 	SAREG,	TPOINT,
91 	SANY,	TWORD,
92 		0,	RLEFT,
93 		"", },
94 
95 /* convert int to long from memory */
96 { SCONV,	INBREG,
97 	SNAME|SOREG,	TINT,
98 	SANY,	TLONG,
99 		NBREG,	RESC1,
100 		"mov	AL,U1\nsxt	A1\n", },
101 
102 /* int -> (u)long. XXX - only in r0 and r1 */
103 { SCONV,	INBREG,
104 	SAREG,	TINT,
105 	SANY,	TLONG|TULONG,
106 		NSPECIAL|NBREG|NBSL,	RESC1,
107 		"tst	AL\nsxt	r0\n", },
108 
109 /* unsigned -> (u)long. XXX - only in r0 and r1 */
110 { SCONV,	INBREG,
111 	SAREG,	TUNSIGNED,
112 	SANY,	TLONG|TULONG,
113 		NSPECIAL|NBREG|NBSL,	RESC1,
114 		"clr	r0\n", },
115 
116 /* uint -> double */
117 { SCONV,	INCREG,
118 	SAREG|SNAME|SOREG|SCON,	TUNSIGNED,
119 	SANY,			TFLOAT|TDOUBLE,
120 		NCREG|NCSL,	RESC1,
121 		"mov	AL,-(sp)\nclr	-(sp)\n"
122 		"setl\nmovif	(sp)+,A1\nseti\n", },
123 
124 /* long -> int */
125 { SCONV,	INAREG,
126 	SBREG|SOREG|SNAME,	TLONG|TULONG,
127 	SAREG,			TWORD,
128 		NAREG|NASL,	RESC1,
129 		"mov	UL,A1\n", },
130 
131 
132 /* (u)long -> (u)long, nothing */
133 { SCONV,	INBREG,
134 	SBREG,	TLONG|TULONG,
135 	SANY,	TLONG|TULONG,
136 		NBREG|NBSL,	RESC1,
137 		"", },
138 
139 /* long -> double */
140 { SCONV,	INCREG,
141 	SBREG|SNAME|SOREG|SCON,	TLONG,
142 	SANY,		TFLOAT|TDOUBLE,
143 		NCREG|NCSL,	RESC1,
144 		"mov	UL,-(sp)\nmov	AL,-(sp)\n"
145 		"setl\nmovif	(sp)+,A1\nseti\n", },
146 
147 /*
148  * Subroutine calls.
149  */
150 { CALL,		INBREG,
151 	SCON,	TANY,
152 	SBREG,	TLONG|TULONG,
153 		NBREG|NBSL,	RESC1,
154 		"jsr	pc,*CL\nZC", },
155 
156 { UCALL,	INBREG,
157 	SCON,	TANY,
158 	SBREG,	TLONG|TULONG,
159 		NBREG|NBSL,	RESC1,
160 		"jsr	pc,*CL\n", },
161 
162 { CALL,		FOREFF,
163 	SCON|SNAME|SOREG,	TANY,
164 	SANY,	TANY,
165 		0,	0,
166 		"jsr	pc,*AL\nZC", },
167 
168 { UCALL,	FOREFF,
169 	SCON|SNAME|SOREG,	TANY,
170 	SANY,	TANY,
171 		0,	0,
172 		"jsr	pc,*AL\n", },
173 
174 { CALL,		INAREG,
175 	SCON|SOREG|SNAME,	TANY,
176 	SAREG,	TWORD|TPOINT|TCHAR|TUCHAR,
177 		NAREG|NASL,	RESC1,
178 		"jsr	pc,*AL\nZC", },
179 
180 { UCALL,	INAREG,
181 	SCON|SOREG|SNAME,	TANY,
182 	SAREG,	TWORD|TPOINT|TCHAR|TUCHAR,
183 		NAREG|NASL,	RESC1,
184 		"jsr	pc,*AL\n", },
185 
186 { CALL,		FOREFF,
187 	SAREG,	TANY,
188 	SANY,	TANY,
189 		0,	0,
190 		"jsr	pc,(AL)\nZC", },
191 
192 { UCALL,	FOREFF,
193 	SAREG,	TANY,
194 	SANY,	TANY,
195 		0,	0,
196 		"jsr	pc,(AL)\n", },
197 
198 { CALL,		INAREG,
199 	SAREG,	TANY,
200 	SANY,	TANY,
201 		NAREG|NASL,	RESC1,	/* should be 0 */
202 		"jsr	pc,(AL)\nZC", },
203 
204 { UCALL,	INAREG,
205 	SAREG,	TANY,
206 	SANY,	TANY,
207 		NAREG|NASL,	RESC1,	/* should be 0 */
208 		"jsr	pc,(AL)\n", },
209 
210 /*
211  * The next rules handle all binop-style operators.
212  */
213 /* Add one to anything left but use only for side effects */
214 { PLUS,		FOREFF|INAREG|FORCC,
215 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
216 	SONE,			TANY,
217 		0,	RLEFT|RESCC,
218 		"inc	AL\n", },
219 
220 /* add one for char to reg, special handling */
221 { PLUS,		FOREFF|INAREG|FORCC,
222 	SAREG,	TCHAR|TUCHAR,
223 	SONE,		TANY,
224 		0,	RLEFT|RESCC,
225 		"inc	AL\n", },
226 
227 /* add one for char to memory */
228 { PLUS,		FOREFF|FORCC,
229 	SNAME|SOREG|STARNM,	TCHAR|TUCHAR,
230 	SONE,			TANY,
231 		0,	RLEFT|RESCC,
232 		"incb	AL\n", },
233 
234 { PLUS,		INBREG|FOREFF,
235 	SBREG,			TLONG,
236 	SBREG|SNAME|SOREG|SCON,	TLONG,
237 		0,	RLEFT,
238 		"add	AR,AL\nadd	UR,UL\nadc	AL\n", },
239 
240 /* Add to reg left and reclaim reg */
241 { PLUS,		INAREG|FOREFF|FORCC,
242 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
243 	SAREG|SNAME|SOREG|SCON,	TWORD|TPOINT,
244 		0,	RLEFT|RESCC,
245 		"add	AR,AL\n", },
246 
247 /* Add to anything left but use only for side effects */
248 { PLUS,		FOREFF|FORCC,
249 	SNAME|SOREG,	TWORD|TPOINT,
250 	SAREG|SNAME|SOREG|SCON,	TWORD|TPOINT,
251 		0,	RLEFT|RESCC,
252 		"add	AR,AL\n", },
253 
254 { PLUS,		INAREG|FOREFF|FORCC,
255 	SAREG,			TCHAR|TUCHAR,
256 	SAREG|SNAME|SOREG|SCON,	TCHAR|TUCHAR,
257 		0,	RLEFT|RESCC,
258 		"add	AR,AL\n", },
259 
260 /* Post-increment read, byte */
261 { MINUS,	INAREG,
262 	SINCB,	TCHAR|TUCHAR,
263 	SONE,	TANY,
264 		NAREG,	RESC1,
265 		"movb	ZG,A1\nincb	ZG\n", },
266 
267 /* Post-increment read, int */
268 { MINUS,	INAREG,
269 	SINCB,	TWORD|TPOINT,
270 	SONE,	TANY,
271 		NAREG,	RESC1,
272 		"mov	ZG,A1\ninc	ZG\n", },
273 
274 { MINUS,		INBREG|FOREFF,
275 	SBREG,			TLONG|TULONG,
276 	SBREG|SNAME|SOREG|SCON,	TLONG|TULONG,
277 		0,	RLEFT,
278 		"sub	AR,AL\nsub	UR,UL\nsbc	AL\n", },
279 
280 /* Sub one from anything left */
281 { MINUS,	FOREFF|INAREG|FORCC,
282 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
283 	SONE,			TANY,
284 		0,	RLEFT|RESCC,
285 		"dec	AL\n", },
286 
287 { MINUS,		INAREG|FOREFF,
288 	SAREG,			TWORD|TPOINT,
289 	SAREG|SNAME|SOREG|SCON,	TWORD|TPOINT,
290 		0,	RLEFT,
291 		"sub	AR,AL\n", },
292 
293 /* Sub from anything left but use only for side effects */
294 { MINUS,	FOREFF|INAREG|FORCC,
295 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
296 	SAREG|SNAME|SOREG|SCON,	TWORD|TPOINT,
297 		0,	RLEFT|RESCC,
298 		"sub	AR,AL\n", },
299 
300 /* Sub one left but use only for side effects */
301 { MINUS,	FOREFF|FORCC,
302 	SAREG|SNAME|SOREG,	TCHAR|TUCHAR,
303 	SONE,			TANY,
304 		0,	RLEFT|RESCC,
305 		"decb	AL\n", },
306 
307 /* Sub from anything left but use only for side effects */
308 { MINUS,		FOREFF|FORCC,
309 	SAREG|SNAME|SOREG,	TCHAR|TUCHAR,
310 	SAREG|SNAME|SOREG|SCON,	TCHAR|TUCHAR|TWORD|TPOINT,
311 		0,	RLEFT|RESCC,
312 		"subb	AR,AL\n", },
313 
314 /*
315  * The next rules handle all shift operators.
316  */
317 { LS,	INBREG|FOREFF,
318 	SBREG,	TLONG|TULONG,
319 	SANY,	TANY,
320 		0,	RLEFT,
321 		"ashc	AR,AL\n", },
322 
323 { LS,	INAREG|FOREFF,
324 	SAREG,	TWORD,
325 	SONE,	TANY,
326 		0,	RLEFT,
327 		"asl	AL\n", },
328 
329 { LS,	INAREG|FOREFF,
330 	SAREG,	TWORD,
331 	ANYSH,	TWORD,
332 		0,	RLEFT,
333 		"ash	AR,AL\n", },
334 
335 /*
336  * The next rules takes care of assignments. "=".
337  */
338 
339 /* First optimizations, in lack of weight it uses first found */
340 /* Start with class A registers */
341 
342 /* Clear word at address */
343 { ASSIGN,	FOREFF|FORCC,
344 	ARONS,	TWORD|TPOINT,
345 	SZERO,		TANY,
346 		0,	RESCC,
347 		"clr	AL\n", },
348 
349 /* Clear word at reg */
350 { ASSIGN,	FOREFF|INAREG,
351 	SAREG,	TWORD|TPOINT,
352 	SZERO,		TANY,
353 		0,	RDEST,
354 		"clr	AL\n", },
355 
356 /* Clear byte at address.  No reg here. */
357 { ASSIGN,	FOREFF,
358 	SNAME|SOREG|STARNM,	TCHAR|TUCHAR,
359 	SZERO,		TANY,
360 		0,	RDEST,
361 		"clrb	AL\n", },
362 
363 /* Clear byte in reg. must clear the whole register. */
364 { ASSIGN,	FOREFF|INAREG,
365 	SAREG,	TCHAR|TUCHAR,
366 	SZERO,	TANY,
367 		0,	RDEST,
368 		"clr	AL\n", },
369 
370 /* The next is class B regs */
371 
372 /* Clear long at address or in reg */
373 { ASSIGN,	FOREFF|INBREG,
374 	SNAME|SOREG|SBREG,	TLONG|TULONG,
375 	SZERO,			TANY,
376 		0,	RDEST,
377 		"clr	AL\nclr	UL\n", },
378 
379 /* Save 2 bytes if high-order bits are zero */
380 { ASSIGN,	FOREFF|INBREG,
381 	SBREG,	TLONG|TULONG,
382 	SSCON,	TLONG,
383 		0,	RDEST,
384 		"mov	UR,UL\nsxt	AL\n", },
385 
386 /* Must have multiple rules for long otherwise regs may be trashed */
387 { ASSIGN,	FOREFF|INBREG,
388 	SBREG,			TLONG|TULONG,
389 	SCON|SNAME|SOREG,	TLONG|TULONG,
390 		0,	RDEST,
391 		"mov	AR,AL\nmov	UR,UL\n", },
392 
393 { ASSIGN,	FOREFF|INBREG,
394 	SNAME|SOREG,	TLONG|TULONG,
395 	SBREG,			TLONG|TULONG,
396 		0,	RDEST,
397 		"mov	AR,AL\nmov	UR,UL\n", },
398 
399 { ASSIGN,	FOREFF,
400 	SNAME|SOREG,	TLONG|TULONG,
401 	SCON|SNAME|SOREG,	TLONG|TULONG,
402 		0,	0,
403 		"mov	AR,AL\nmov	UR,UL\n", },
404 
405 { ASSIGN,	INBREG|FOREFF,
406 	SBREG,	TLONG|TULONG,
407 	SBREG,	TLONG|TULONG,
408 		0,	RDEST,
409 		"ZE\n", },
410 
411 { ASSIGN,	FOREFF|INAREG|FORCC,
412 	SAREG,			TWORD|TPOINT,
413 	SAREG|SNAME|SOREG|SCON,	TWORD|TPOINT,
414 		0,	RDEST|RESCC,
415 		"mov	AR,AL\n", },
416 
417 { ASSIGN,	FOREFF|INAREG|FORCC,
418 	ARONS,	TWORD|TPOINT,
419 	SAREG,	TWORD|TPOINT,
420 		0,	RDEST|RESCC,
421 		"mov	AR,AL\n", },
422 
423 { ASSIGN,	FOREFF|FORCC,
424 	SNAME|SOREG,		TWORD|TPOINT,
425 	SNAME|SOREG|SCON,	TWORD|TPOINT,
426 		0,	RESCC,
427 		"mov	AR,AL\n", },
428 
429 { ASSIGN,	FOREFF|INAREG|FORCC,
430 	SAREG,		TCHAR|TUCHAR,
431 	ARONS|SCON,	TCHAR|TUCHAR,
432 		0,	RDEST|RESCC,
433 		"movb	AR,AL\n", },
434 
435 { ASSIGN,	FOREFF|INAREG|FORCC,
436 	ARONS,	TCHAR|TUCHAR,
437 	SAREG,	TCHAR|TUCHAR,
438 		0,	RDEST|RESCC,
439 		"movb	AR,AL\n", },
440 
441 { ASSIGN,	FOREFF|FORCC,
442 	SNAME|SOREG|STARNM,		TCHAR|TUCHAR,
443 	SNAME|SOREG|SCON|STARNM,	TCHAR|TUCHAR,
444 		0,	RDEST|RESCC,
445 		"movb	AR,AL\n", },
446 
447 { ASSIGN,	FOREFF|INCREG,
448 	SCREG,		TDOUBLE,
449 	SNAME|SOREG|SCON,	TDOUBLE,
450 		0,	RDEST,
451 		"movf	AR,AL\n", },
452 
453 { ASSIGN,	FOREFF|INCREG,
454 	SCREG,		TFLOAT,
455 	SNAME|SOREG|SCON,	TFLOAT,
456 		0,	RDEST,
457 		"movof	AR,AL\n", },
458 
459 { ASSIGN,	FOREFF|INCREG,
460 	SNAME|SOREG|SCREG,	TDOUBLE,
461 	SCREG,			TDOUBLE,
462 		0,	RDEST,
463 		"movf	AR,AL\n", },
464 
465 { ASSIGN,	FOREFF|INCREG,
466 	SNAME|SOREG|SCREG,	TFLOAT,
467 	SCREG,			TFLOAT,
468 		0,	RDEST,
469 		"movfo	AR,AL\n", },
470 
471 /*
472  * DIV/MOD/MUL
473  */
474 /* XXX - mul may use any odd register, only r1 for now */
475 { MUL,	INAREG,
476 	SAREG,				TWORD|TPOINT,
477 	SAREG|SNAME|SOREG|SCON,		TWORD|TPOINT,
478 		NSPECIAL,	RLEFT,
479 		"mul	AR,AL\n", },
480 
481 { MUL,	INBREG,
482 	SBREG|SNAME|SCON|SOREG,		TLONG|TULONG,
483 	SBREG|SNAME|SCON|SOREG,		TLONG|TULONG,
484 		NSPECIAL|NBREG|NBSL|NBSR,		RESC1,
485 		"mov	UR,-(sp)\nmov	AR,-(sp)\n"
486 		"mov	UL,-(sp)\nmov	AL,-(sp)\n"
487 		"jsr	pc,lmul\nadd	$10,sp\n", },
488 
489 { MUL,	INCREG,
490 	SCREG,				TFLOAT|TDOUBLE,
491 	SCREG|SNAME|SOREG,		TFLOAT|TDOUBLE,
492 		0,	RLEFT,
493 		"mulf	AR,AL\n", },
494 
495 /* need extra move to be sure N flag is correct for sxt */
496 { DIV,	INAREG,
497 	ANYSH,		TINT|TPOINT,
498 	ANYSH,		TINT|TPOINT,
499 		NSPECIAL,	RDEST,
500 		"mov	AL,r1\nsxt	r0\ndiv	AR,r0\n", },
501 
502 /* udiv uses args in registers */
503 { DIV,	INAREG,
504 	SAREG,		TUNSIGNED,
505 	SAREG,		TUNSIGNED,
506 		NSPECIAL|NAREG|NASL|NASR,		RESC1,
507 		"jsr	pc,udiv\n", },
508 
509 { DIV,	INBREG,
510 	SBREG|SNAME|SCON|SOREG,		TLONG|TULONG,
511 	SBREG|SNAME|SCON|SOREG,		TLONG|TULONG,
512 		NSPECIAL|NBREG|NBSL|NBSR,		RESC1,
513 		"mov	UR,-(sp)\nmov	AR,-(sp)\n"
514 		"mov	UL,-(sp)\nmov	AL,-(sp)\n"
515 		"jsr	pc,ldiv\nadd	$10,sp\n", },
516 
517 { DIV,	INCREG,
518 	SCREG,			TFLOAT|TDOUBLE,
519 	SCREG|SNAME|SOREG,	TFLOAT|TDOUBLE,
520 		0,	RLEFT,
521 		"divf	AR,AL\n", },
522 
523 /* XXX merge the two below to one */
524 { MOD,	INBREG,
525 	SBREG|SNAME|SCON|SOREG,		TLONG,
526 	SBREG|SNAME|SCON|SOREG,		TLONG,
527 		NSPECIAL|NBREG|NBSL|NBSR,		RESC1,
528 		"mov	UR,-(sp)\nmov	AR,-(sp)\n"
529 		"mov	UL,-(sp)\nmov	AL,-(sp)\n"
530 		"jsr	pc,lrem\nadd	$10,sp\n", },
531 
532 { MOD,	INBREG,
533 	SBREG|SNAME|SCON|SOREG,		TULONG,
534 	SBREG|SNAME|SCON|SOREG,		TULONG,
535 		NSPECIAL|NBREG|NBSL|NBSR,		RESC1,
536 		"mov	UR,-(sp)\nmov	AR,-(sp)\n"
537 		"mov	UL,-(sp)\nmov	AL,-(sp)\n"
538 		"jsr	pc,ulrem\nadd	$10,sp\n", },
539 
540 /* urem uses args in registers */
541 { MOD,	INAREG,
542 	SAREG,		TUNSIGNED,
543 	SAREG,		TUNSIGNED,
544 		NSPECIAL|NAREG|NASL|NASR,		RESC1,
545 		"jsr	pc,urem\n", },
546 
547 /*
548  * Indirection operators.
549  */
550 { UMUL,	INBREG,
551 	SANY,	TPOINT|TWORD,
552 	SOREG,	TLONG|TULONG,
553 		NBREG,	RESC1, /* |NBSL - may overwrite index reg */
554 		"mov	AR,A1\nmov	UR,U1\n", },
555 
556 { UMUL,	INAREG,
557 	SANY,	TPOINT|TWORD,
558 	SOREG,	TPOINT|TWORD,
559 		NAREG|NASL,	RESC1,
560 		"mov	AR,A1\n", },
561 
562 { UMUL,	INAREG,
563 	SANY,	TANY,
564 	SOREG,	TCHAR|TUCHAR,
565 		NAREG|NASL,	RESC1,
566 		"movb	AR,A1\n", },
567 
568 /*
569  * Logical/branching operators
570  */
571 { OPLOG,	FORCC,
572 	SAREG|SOREG|SNAME|SCON,	TWORD|TPOINT,
573 	SZERO,	TANY,
574 		0, 	RESCC,
575 		"tst	AL\n", },
576 
577 { OPLOG,	FORCC,
578 	SAREG|SOREG|SNAME|SCON,	TCHAR|TUCHAR,
579 	SZERO,	TANY,
580 		0, 	RESCC,
581 		"tstb	AL\n", },
582 
583 { OPLOG,	FORCC,
584 	SAREG|SOREG|SNAME|SCON,	TWORD|TPOINT,
585 	SAREG|SOREG|SNAME|SCON,	TWORD|TPOINT,
586 		0, 	RESCC,
587 		"cmp	AL,AR\n", },
588 
589 { OPLOG,	FORCC,
590 	SAREG|SOREG|SNAME|SCON,	TCHAR|TUCHAR,
591 	SAREG|SOREG|SNAME|SCON,	TCHAR|TUCHAR,
592 		0, 	RESCC,
593 		"cmpb	AL,AR\n", },
594 
595 { OPLOG,	FORCC,
596 	SBREG|SOREG|SNAME|SCON,	TLONG|TULONG,
597 	SZERO,	TANY,
598 		0,	RNULL,
599 		"ZD", },
600 
601 { OPLOG,	FORCC,
602 	SBREG|SOREG|SNAME,	TLONG|TULONG,
603 	SBREG|SOREG|SNAME,	TLONG|TULONG,
604 		0,	RNULL,
605 		"ZF", },
606 
607 /* AND/OR/ER/NOT */
608 /* Optimize if high order bits are zero */
609 { AND,	FOREFF|INBREG|FORCC,
610 	SOREG|SNAME|SBREG,	TLONG|TULONG,
611 	SANDSCON,		TLONG|TULONG,
612 		0,	RLEFT|RESCC,
613 		"clr	AL\nbic	UR,UL\n", },
614 
615 { AND,	INBREG|FORCC,
616 	SBREG,			TLONG|TULONG,
617 	SCON|SBREG|SOREG|SNAME,	TLONG|TULONG,
618 		0,	RLEFT|RESCC,
619 		"bic	AR,AL\nbic	UR,UL\n", },
620 
621 /* set status bits */
622 { AND,	FORCC,
623 	ARONS|SCON,	TWORD|TPOINT,
624 	ARONS|SCON,	TWORD|TPOINT,
625 		0,	RESCC,
626 		"bit	AR,AL\n", },
627 
628 /* AND with int */
629 { AND,	INAREG|FORCC|FOREFF,
630 	SAREG|SNAME|SOREG,	TWORD,
631 	SCON|SAREG|SOREG|SNAME,	TWORD,
632 		0,	RLEFT|RESCC,
633 		"bic	AR,AL\n", },
634 
635 /* AND with char */
636 { AND,	INAREG|FORCC,
637 	SAREG|SOREG|SNAME,	TCHAR|TUCHAR,
638 	ARONS|SCON,		TCHAR|TUCHAR,
639 		0,	RLEFT|RESCC,
640 		"bicb	AR,AL\n", },
641 
642 { OR,	INBREG|FORCC,
643 	SBREG,			TLONG|TULONG,
644 	SCON|SBREG|SOREG|SNAME,	TLONG|TULONG,
645 		0,	RLEFT|RESCC,
646 		"bis	AR,AL\nbis	UR,UL\n", },
647 
648 /* OR with int */
649 { OR,	FOREFF|INAREG|FORCC,
650 	ARONS,		TWORD,
651 	ARONS|SCON,	TWORD,
652 		0,	RLEFT|RESCC,
653 		"bis	AR,AL\n", },
654 
655 /* OR with char */
656 { OR,	INAREG|FORCC,
657 	SAREG|SOREG|SNAME,	TCHAR|TUCHAR,
658 	ARONS|SCON,		TCHAR|TUCHAR,
659 		0,	RLEFT|RESCC,
660 		"bisb	AR,AL\n", },
661 
662 /* XOR with int (extended insn)  */
663 { ER,	INAREG|FORCC,
664 	ARONS,	TWORD,
665 	SAREG,	TWORD,
666 		0,	RLEFT|RESCC,
667 		"xor	AR,AL\n", },
668 
669 /* XOR with char (extended insn)  */
670 { ER,	INAREG|FORCC,
671 	SAREG,	TCHAR|TUCHAR,
672 	SAREG,	TCHAR|TUCHAR,
673 		0,	RLEFT|RESCC,
674 		"xor	AR,AL\n", },
675 
676 /*
677  * Jumps.
678  */
679 { GOTO, 	FOREFF,
680 	SCON,	TANY,
681 	SANY,	TANY,
682 		0,	RNOP,
683 		"jbr	LL\n", },
684 
685 /*
686  * Convert LTYPE to reg.
687  */
688 /* Two bytes less if high half of constant is zero */
689 { OPLTYPE,	INBREG,
690 	SANY,	TANY,
691 	SSCON,	TLONG|TULONG,
692 		NBREG,	RESC1,
693 		"mov	UL,U1\nsxt	A1\n", },
694 
695 /* XXX - avoid OREG index register to be overwritten */
696 { OPLTYPE,	INBREG,
697 	SANY,	TANY,
698 	SCON|SBREG|SNAME|SOREG,	TLONG|TULONG,
699 		NBREG,	RESC1,
700 		"mov	AL,A1\nmov	UL,U1\n", },
701 
702 { OPLTYPE,	INAREG,
703 	SANY,	TANY,
704 	SAREG|SCON|SOREG|SNAME,	TWORD|TPOINT,
705 		NAREG|NASR,	RESC1,
706 		"mov	AL,A1\n", },
707 
708 { OPLTYPE,	INAREG,
709 	SANY,	TANY,
710 	SAREG|SCON|SOREG|SNAME,	TCHAR,
711 		NAREG,		RESC1,
712 		"movb	AR,A1\n", },
713 
714 { OPLTYPE,	INAREG,
715 	SANY,	TANY,
716 	SAREG|SCON|SOREG|SNAME,	TUCHAR,
717 		NAREG,		RESC1,
718 		"clr	A1\nbisb	AL,A1\n", },
719 
720 { OPLTYPE,	INCREG,
721 	SANY,	TANY,
722 	SCREG|SCON|SOREG|SNAME,	TDOUBLE,
723 		NCREG,		RESC1,
724 		"movf	AL,A1\n", },
725 
726 { OPLTYPE,	INCREG,
727 	SANY,	TANY,
728 	SCREG|SCON|SOREG|SNAME,	TFLOAT,
729 		NCREG,		RESC1,
730 		"movof	AL,A1\n", },
731 
732 /*
733  * Negate a word.
734  */
735 { UMINUS,	INAREG|FOREFF,
736 	SAREG,	TWORD|TPOINT|TCHAR|TUCHAR,
737 	SANY,	TANY,
738 		0,	RLEFT,
739 		"neg	AL\n", },
740 
741 { UMINUS,	INBREG|FOREFF,
742 	SBREG|SOREG|SNAME,	TLONG,
743 	SANY,			TANY,
744 		0,	RLEFT,
745 		"neg	AL\nneg	UL\nsbc	AL\n", },
746 
747 
748 { COMPL,	INBREG,
749 	SBREG,	TLONG|TULONG,
750 	SANY,	TANY,
751 		0,	RLEFT,
752 		"com	AL\ncom	UL\n", },
753 
754 { COMPL,	INAREG,
755 	SAREG,	TWORD,
756 	SANY,	TANY,
757 		0,	RLEFT,
758 		"com	AL\n", },
759 
760 /*
761  * Arguments to functions.
762  */
763 { FUNARG,	FOREFF,
764 	SCON|SBREG|SNAME|SOREG,	TLONG|TULONG,
765 	SANY,	TLONG|TULONG,
766 		0,	RNULL,
767 		"mov	UL,ZA(sp)\nmov	AL,-(sp)\n", },
768 
769 { FUNARG,	FOREFF,
770 	SZERO,	TANY,
771 	SANY,	TANY,
772 		0,	RNULL,
773 		"clr	ZA(sp)\n", },
774 
775 { FUNARG,	FOREFF,
776 	SARGSUB,	TWORD|TPOINT,
777 	SANY,		TWORD|TPOINT,
778 		0,	RNULL,
779 		"ZB", },
780 
781 { FUNARG,	FOREFF,
782 	SARGINC,	TWORD|TPOINT,
783 	SANY,		TWORD|TPOINT,
784 		0,	RNULL,
785 		"ZH", },
786 
787 { FUNARG,	FOREFF,
788 	SCON|SAREG|SNAME|SOREG,	TWORD|TPOINT,
789 	SANY,	TWORD|TPOINT,
790 		0,	RNULL,
791 		"mov	AL,ZA(sp)\n", },
792 
793 { FUNARG,	FOREFF,
794 	SCON,	TCHAR|TUCHAR,
795 	SANY,	TANY,
796 		0,	RNULL,
797 		"mov	AL,ZA(sp)\n", },
798 
799 { FUNARG,	FOREFF,
800 	SNAME|SOREG,	TCHAR,
801 	SANY,		TCHAR,
802 		NAREG,	RNULL,
803 		"movb	AL,A1\nmov	A1,ZA(sp)\n", },
804 
805 { FUNARG,	FOREFF,
806 	SNAME|SOREG,	TUCHAR,
807 	SANY,		TUCHAR,
808 		NAREG,	RNULL,
809 		"clr	ZA(sp)\nbisb	AL,(sp)\n", },
810 
811 { FUNARG,	FOREFF,
812 	SAREG,	TUCHAR|TCHAR,
813 	SANY,	TUCHAR|TCHAR,
814 		0,	RNULL,
815 		"mov	AL,ZA(sp)\n", },
816 
817 { FUNARG,	FOREFF,
818 	SCREG,	TFLOAT|TDOUBLE,
819 	SANY,		TANY,
820 		0,	RNULL,
821 		"movf	AL,ZA(sp)\n", },
822 
823 # define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
824 
825 { UMUL, DF( UMUL ), },
826 
827 { ASSIGN, DF(ASSIGN), },
828 
829 { STASG, DF(STASG), },
830 
831 { FLD, DF(FLD), },
832 
833 { OPLEAF, DF(NAME), },
834 
835 /* { INIT, DF(INIT), }, */
836 
837 { OPUNARY, DF(UMINUS), },
838 
839 { OPANY, DF(BITYPE), },
840 
841 { FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	"help; I'm in trouble\n" },
842 };
843 
844 int tablesize = sizeof(table)/sizeof(table[0]);
845