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
43struct 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
844int tablesize = sizeof(table)/sizeof(table[0]);
845