1/*	Id: table.c,v 1.13 2015/10/27 14:48:50 ragge Exp 	*/
2/*	$NetBSD: table.c,v 1.1.1.2 2016/02/09 20:28:35 plunky Exp $	*/
3/*
4 * Copyright (c) 2014 Anders Magnusson (ragge@ludd.ltu.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 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28
29# include "pass2.h"
30
31#define TLL	TLONGLONG|TULONGLONG
32#define TAREG	TINT|TSHORT|TCHAR|TUNSIGNED|TUSHORT|TUCHAR
33#define SABREG	SAREG|SBREG
34#define TFP	TFLOAT|TDOUBLE|TLDOUBLE
35
36# define ANYSIGNED TINT|TSHORT|TCHAR
37# define ANYUSIGNED TUNSIGNED|TUSHORT|TUCHAR
38# define ANYFIXED ANYSIGNED|ANYUSIGNED
39# define TUWORD TUNSIGNED
40# define TSWORD TINT
41# define TWORD	TUWORD|TSWORD
42#define TANYINT TLL|ANYFIXED
43#define	 SHINT	SAREG	/* Any integer */
44#define	 ININT	INAREG
45#define	 SHFL	SCREG	/* shape for long double */
46#define	 INFL	INCREG	/* shape for long double */
47
48struct optab table[] = {
49/* First entry must be an empty entry */
50{ -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", },
51
52/* begin with all these casts */
53
54/* pointer to pointer (same reg class) */
55{ PCONV,	INBREG,
56	SBREG,		TPOINT,
57	SBREG,		TANY,
58		0,	RLEFT,
59		"", },
60
61/* (u)int -> pointer */
62{ PCONV,	INBREG,
63	SAREG,		TWORD,
64	SBREG,		TANY,
65		NBREG,	RESC1,
66		"	move.l AL,A1\n", },
67
68/* pointer to int/unsigned */
69{ SCONV,	INAREG,
70	SBREG,		TPOINT,
71	SAREG,		TWORD,
72		NAREG,	RESC1,
73		"	move.l AL,A1\n", },
74
75/* (u)char -> (u)char */
76{ SCONV,	INAREG,
77	SAREG,		TCHAR|TUCHAR,
78	SAREG,		TCHAR|TUCHAR,
79		0,	RLEFT,
80		"", },
81
82/* char -> short/ushort */
83{ SCONV,	INAREG|INBREG,
84	SABREG,		TCHAR,
85	SABREG,		TSHORT|TUSHORT,
86		0,	RLEFT,
87		"	ext.w AL\n", },
88
89/* uchar -> short/ushort */
90{ SCONV,	INAREG|INBREG,
91	SABREG,		TUCHAR,
92	SABREG,		TSHORT|TUSHORT,
93		0,	RLEFT,
94		"	and.l #255,AL\n", },
95
96/* char -> (u)int */
97{ SCONV,	INAREG,
98	SAREG,		TCHAR,
99	SAREG,		TINT|TUNSIGNED,
100		0,	RLEFT,
101		"	extb.l AL\n", },
102
103/* uchar -> (u)int */
104{ SCONV,	INAREG,
105	SAREG,		TUCHAR,
106	SAREG,		TINT|TUNSIGNED,
107		0,	RLEFT,
108		"	and.l #255,AL\n", },
109
110/* char -> (u)longlong */
111{ SCONV,	INCREG,
112	SAREG|SNAME|SOREG,	TCHAR,
113	SCREG,			TLL,
114		NCREG,	RESC1,
115		"	move.b AL,U1\n	extb.l U1\n"
116		"	smi A1\n	extb.l A1\n", },
117
118/* uchar -> (u)longlong */
119{ SCONV,	INCREG,
120	SAREG|SNAME|SOREG,	TUCHAR,
121	SCREG,			TLL,
122		NCREG,	RESC1,
123		"	move.b AL,U1\n	and.l #255,U1\n	clr.l A1\n", },
124
125/* char -> float/(l)double */
126{ SCONV,	INDREG,
127	SAREG,		TCHAR,
128	SDREG,		TFP,
129		NDREG,	RESC1,
130		"	fmove.ZL AL,A1\n", },
131
132/* (u)char -> float/(l)double */
133{ SCONV,	INDREG,
134	SAREG,		TUCHAR,
135	SDREG,		TFP,
136		NAREG|NDREG,	RESC2,
137		"	clr.l A1\n	move.b AL,A1\n	fmove.w A1,A2\n", },
138
139/* (u)short -> (u)char */
140{ SCONV,	INAREG,
141	SAREG,		TSHORT|TUSHORT,
142	SAREG,		TCHAR|TUCHAR,
143		0,	RLEFT,
144		"", },
145
146/* (u)short -> (u)short */
147{ SCONV,	INAREG,
148	SAREG,		TSHORT|TUSHORT,
149	SAREG,		TSHORT|TUSHORT,
150		0,	RLEFT,
151		"", },
152
153/* short -> (u)int */
154{ SCONV,	INAREG|INBREG,
155	SABREG,		TSHORT,
156	SABREG,		TINT|TUNSIGNED,
157		0,	RLEFT,
158		"	ext.l AL\n", },
159
160/* ushort -> (u)int */
161{ SCONV,	INAREG|INBREG,
162	SABREG,		TUSHORT,
163	SABREG,		TINT|TUNSIGNED,
164		0,	RLEFT,
165		"	and.l #65535,AL\n", },
166
167/* short -> (u)longlong */
168{ SCONV,	INCREG,
169	SAREG,		TSHORT,
170	SCREG,		TLL,
171		NCREG,	RESC1,
172		"	move AL,U1\n	ext.l U1\n"
173		"	smi A1\n	extb.l A1\n", },
174
175/* ushort -> (u)longlong */
176{ SCONV,	INCREG,
177	SAREG|SNAME|SOREG,	TUSHORT,
178	SCREG,			TLL,
179		NCREG,	RESC1,
180		"	move.l AL,U1\n	and.l #65535,U1\n	clr.l A1\n", },
181
182/* short -> float/(l)double */
183{ SCONV,	INDREG,
184	SAREG|SNAME|SOREG,	TSHORT,
185	SDREG,			TFP,
186		NDREG|NDSL,	RESC1,
187		"	fmove.w AL,A1\n", },
188
189/* ushort -> float/(l)double */
190{ SCONV,	INDREG,
191	SAREG|SNAME|SOREG,	TUSHORT,
192	SAREG|SDREG,		TFP,
193		NAREG|NDREG|NDSL,	RESC2,
194		"	move.w AL,A1\n	and.l #65535,A1\n"
195		"	fmove.l A1,A2\n", },
196
197/* (u)int -> (u)char */
198{ SCONV,	INAREG,
199	SAREG,		TWORD,
200	SAREG,		TCHAR|TUCHAR,
201		0,	RLEFT,
202		"	and.l #255,AL\n", },
203
204/* (u)int -> (u)short */
205{ SCONV,	INAREG,
206	SAREG,		TWORD,
207	SAREG,		TSHORT|TUSHORT,
208		0,	RLEFT,
209		"	and.l #65535,AL\n", },
210
211/* (u)int -> (u)int  - nothing */
212{ SCONV,	INAREG,
213	SAREG,		TWORD,
214	SAREG,		TWORD,
215		0,	RLEFT,
216		"", },
217
218/* int -> (u)longlong */
219{ SCONV,	INCREG,
220	SAREG|SOREG|SNAME,	TINT,
221	SCREG,			TLL,
222		NCREG,	RESC1,
223		"	move.l AL,U1\n	smi A1\n	extb.l A1\n", },
224
225/* (u)int -> (u)longlong */
226{ SCONV,	INCREG,
227	SAREG|SOREG|SNAME,	TUNSIGNED,
228	SCREG,			TLL,
229		NCREG,	RESC1,
230		"	move.l AL,U1\n	clr.l A1\n", },
231
232/* int -> float/(l)double */
233{ SCONV,	INDREG,
234	SAREG|SNAME|SOREG,	TINT,
235	SDREG,			TFP,
236		NDREG|NDSL,	RESC1,
237		"	fmove.l AL,A1\n", },
238
239/* uint -> double */
240{ SCONV,	INDREG,
241	SAREG,		TUNSIGNED,
242	SDREG,		TFLOAT|TDOUBLE,
243		NDREG|NDSL,	RESC1,
244		"	fmove.l AL,A1\n"
245		"	tst.l AL\n"
246		"	jge 1f\n"
247		"	fadd.d #0x41f0000000000000,A1\n"
248		"1:\n", },
249
250/* (u)longlong -> (u)char/(u)short/(u)int */
251{ SCONV,	INAREG,
252	SCREG|SOREG|SNAME,	TLL,
253	SAREG,			TAREG,
254		NAREG,	RESC1,
255		"	movl UL,A1\n", },
256
257/* (u)longlong to (u)longlong */
258{ SCONV,	INCREG,
259	SCREG,	TLL,
260	SCREG,	TLL,
261		0,	RLEFT,
262		"", },
263
264/* float/(l)double -> int/short/char (in reg) */
265{ SCONV,	INAREG,
266	SDREG,	TFP,
267	SAREG,	TINT|TSHORT|TCHAR,
268		NAREG,	RESC1,
269		"	fmove.ZA AL,A1\n", },
270
271/* float -> unsigned */
272{ SCONV,	INAREG,
273	SDREG,	TFLOAT,
274	SAREG,	TUNSIGNED,
275		NAREG|NDREG|NDSL,	RESC1,
276		"Z2	fcmp.s #0x4f000000,A2\n"
277		"	fjge 2f\n"
278		"	fintrz.x A2,A2\n"
279		"	fmove.l A2,A1\n"
280		"	jra 3f\n"
281		"2:	fsub.s #0x4f000000,A2\n"
282		"	fintrz.x A2,A2\n"
283		"	fmove.l A2,A1\n"
284		"	add.l #-2147483648,A1\n3:\n", },
285
286/* float -> (l)double */
287{ SCONV,	INDREG,
288	SDREG,	TFLOAT,
289	SDREG,	TDOUBLE|TLDOUBLE,
290		0,	RLEFT,
291		"", }, /* in fp regs -> do nothing */
292
293/* double -> ldouble */
294{ SCONV,	INDREG,
295	SDREG,	TDOUBLE,
296	SDREG,	TLDOUBLE,
297		0,	RLEFT,
298		"", }, /* in fp regs -> do nothing */
299
300/* double -> uchar */
301{ SCONV,	INAREG,
302	SDREG,	TDOUBLE,
303	SAREG,	TUCHAR,
304		NAREG|NDREG|NDSL,	RESC1,
305		"	fintrz.x AL,A2\n	fmove.w A2,A1\n", },
306
307/* double -> ushort */
308{ SCONV,	INAREG,
309	SDREG,	TDOUBLE,
310	SAREG,	TUSHORT,
311		NAREG|NDREG|NDSL,	RESC1,
312		"	fintrz.x AL,A2\n	fmove.l A2,A1\n", },
313
314/* double -> unsigned */
315{ SCONV,	INAREG,
316	SDREG,	TDOUBLE,
317	SAREG,	TUNSIGNED,
318		NAREG|NDREG|NDSL,	RESC1,
319		"Z2	fcmp.d #0x41e0000000000000,A2\n"
320		"	fjge 2f\n"
321		"	fintrz.x A2,A2\n"
322		"	fmove.l A2,A1\n"
323		"	jra 3f\n"
324		"2:	fsub.d #0x41e0000000000000,A2\n"
325		"	fintrz.x A2,A2\n"
326		"	fmove.l A2,A1\n"
327		"	add.l #-2147483648,A1\n3:\n", },
328
329/* (l)double -> float */
330{ SCONV,	INDREG,
331	SDREG,	TDOUBLE|TLDOUBLE,
332	SDREG,	TFLOAT,
333		NAREG,	RLEFT,
334		"	fmove.s AL,A1\n	fmove.s A1,AL\n", },
335
336/* ldouble -> double */
337{ SCONV,	INDREG,
338	SDREG,	TLDOUBLE,
339	SDREG,	TDOUBLE,
340		NTEMP*2,	RLEFT,
341		"	fmove.d AL,A1\n	fmove.d A1,AL\n", },
342
343/* assignment */
344{ ASSIGN,	FOREFF,
345	SCREG|SNAME|SOREG,	TLL,
346	SCREG|SNAME|SOREG,	TLL,
347		0,	0,
348		"	move.l AR,AL\n"
349		"	move.l UR,UL\n", },
350
351{ ASSIGN,	INCREG,
352	SCREG|SNAME|SOREG,	TLL,
353	SCREG,			TLL,
354		0,	RDEST,
355		"	move.l AR,AL\n"
356		"	move.l UR,UL\n", },
357
358{ ASSIGN,	FOREFF,
359	SAREG|SNAME|SOREG,	TAREG,
360	SAREG|SNAME|SOREG,	TAREG,
361		0,	0,
362		"	move.ZA AR,AL\n", },
363
364{ ASSIGN,	FOREFF,
365	SBREG|SNAME|SOREG,	TPOINT,
366	SBREG|SNAME|SOREG,	TPOINT,
367		0,	0,
368		"	move.l AR,AL\n", },
369
370{ ASSIGN,	FOREFF|INAREG,
371	SAREG|SNAME|SOREG,	TAREG,
372	SAREG,			TAREG,
373		0,	RDEST,
374		"	move.ZA AR,AL\n", },
375
376{ ASSIGN,	FOREFF|INBREG,
377	SBREG|SNAME|SOREG,	TPOINT,
378	SBREG,			TPOINT,
379		0,	RDEST,
380		"	move.l AR,AL\n", },
381
382{ ASSIGN,	FOREFF|INDREG,
383	SNAME|SOREG,	TFP,
384	SDREG,		TFP,
385		0,	RDEST,
386		"	fmove.ZA AR,AL\n", },
387
388{ ASSIGN,	FOREFF|INDREG,
389	SDREG,		TFP,
390	SNAME|SOREG,	TFP,
391		0,	RDEST,
392		"	fmove.ZA AR,AL\n", },
393
394{ ASSIGN,	FOREFF|INDREG,
395	SDREG,	TFP,
396	SDREG,	TFP,
397		0,	RDEST,
398		"	fmove.x AR,AL\n", },
399
400/* structure stuff */
401{ STASG,	INBREG|FOREFF,
402	SOREG|SNAME,	TANY,
403	SBREG,		TPTRTO|TANY,
404		NSPECIAL,	RDEST,
405		"ZQ", },
406/*
407 * Simple ops (add, sub, and, or, xor)
408 */
409/* Address registers may be added to (or subtracted from) */
410{ PLUS, FOREFF,
411	SBREG|SNAME|SOREG|SCON,		TWORD|TPOINT,
412	SAREG,				TWORD,
413		0,	0,
414		"	add.l AR,AL\n", },
415
416{ PLUS, FOREFF|INBREG,
417	SBREG,			TPOINT,
418	SAREG|SNAME|SOREG|SCON, TWORD,
419		0,	RLEFT|RESCC,
420		"	add.l AR,AL\n", },
421
422{ PLUS, FOREFF|INDREG,
423	SDREG,		TFP,
424	SNAME|SOREG|SCON, TFP,
425		0,	RLEFT|RESCC,
426		"	fadd.ZA AR,AL\n", },
427
428{ PLUS, FOREFF|INDREG,
429	SDREG,	TFP,
430	SDREG,	TFP,
431		0,	RLEFT|RESCC,
432		"	fadd.x AR,AL\n", },
433
434{ PLUS, FOREFF|INCREG|RESCC,
435	SCREG,	TLL,
436	SCREG,	TLL,
437		0,	RLEFT|RESCC,
438		"	add.l UR,UL\n	addx.l AR,AL\n", },
439
440{ MINUS, FOREFF,
441	SBREG|SNAME|SOREG|SCON,		TWORD|TPOINT,
442	SBREG,				TWORD,
443		0,	0,
444		"	sub.l AR,AL\n", },
445
446{ MINUS, INAREG,
447	SBREG,		TPOINT,
448	SBREG,		TPOINT,
449		NAREG,	RESC1,
450		"	move.l AL,A1\n	sub.l AR,A1\n", },
451
452{ MINUS, FOREFF|INBREG,
453	SBREG,				TWORD|TPOINT,
454	SABREG|SNAME|SOREG|SCON,	TWORD,
455		0,	RLEFT|RESCC,
456		"	sub.l AR,AL\n", },
457
458{ MINUS, FOREFF|INDREG,
459	SDREG,			TFP,
460	SNAME|SOREG|SCON, TFP,
461		0,	RLEFT|RESCC,
462		"	fsub.ZA AR,AL\n", },
463
464{ MINUS, FOREFF|INDREG,
465	SDREG,	TFP,
466	SDREG,	TFP,
467		0,	RLEFT|RESCC,
468		"	fsub.x AR,AL\n", },
469
470{ MINUS, FOREFF|INCREG|RESCC,
471	SCREG,	TLL,
472	SCREG,	TLL,
473		0,	RLEFT|RESCC,
474		"	sub.l UR,UL\n	subx.l AR,AL\n", },
475
476/* two pointers give a scalar */
477{ MINUS,	INAREG|FORCC,
478	SBREG|SNAME|SOREG|SCON, TPOINT,
479	SBREG|SNAME|SOREG|SCON, TPOINT,
480		NAREG,	RESC1|RESCC,
481		"	move.l AL,A1\n	sub.l AR,A1\n", },
482
483/* Hack to allow for opsimp later down */
484/* Fortunately xor is not that common */
485{ ER,	FOREFF|INAREG,
486	SAREG,				TAREG,
487	SNAME|SOREG|SCON,		TAREG,
488		NAREG,	RLEFT|RESCC,
489		"	move.ZA AR,A1\n	eor.ZA A1,AL\n", },
490
491{ ER,	FOREFF|INCREG|FORCC,
492	SCREG|SNAME|SOREG|SCON,		TLL,
493	SCREG,				TLL,
494		0,	RLEFT|RESCC,
495		"	eor.l AR,AL\n	eor.l UR,UL\n", },
496
497{ AND,	FOREFF|INCREG|FORCC,
498	SCREG,				TLL,
499	SCREG|SNAME|SOREG|SCON,		TLL,
500		0,	RLEFT|RESCC,
501		"	and.l AR,AL\n	and.l UR,UL\n", },
502
503{ OR,	FOREFF|INCREG|FORCC,
504	SCREG,				TLL,
505	SCREG|SNAME|SOREG|SCON,		TLL,
506		0,	RLEFT|RESCC,
507		"	or.l AR,AL\n	or.l UR,UL\n", },
508
509{ OPSIMP,	FOREFF|INAREG,
510	SAREG,				TAREG,
511	SAREG|SNAME|SOREG|SCON,		TAREG,
512		0,	RLEFT|RESCC,
513		"	Oz.ZA AR,AL\n", },
514
515{ OPSIMP,	FOREFF,
516	SAREG|SNAME|SOREG,	TAREG,
517	SAREG,			TAREG,
518		0,	RLEFT|RESCC,
519		"	Oz.ZA AR,AL\n", },
520
521/*
522 * Negate a word.
523 */
524
525{ UMINUS,	FOREFF|INCREG|FORCC,
526	SCREG,	TLL,
527	SCREG,	TLL,
528		0,	RLEFT|RESCC,
529		"	neg.l UL\n	negx.l AL\n", },
530
531{ UMINUS,	FOREFF|INAREG|FORCC,
532	SAREG,	TAREG,
533	SAREG,	TAREG,
534		0,	RLEFT|RESCC,
535		"	neg.ZA AL\n", },
536
537{ UMINUS,	INDREG|FORCC,
538	SDREG,	TFP,
539	SDREG,	TFP,
540		NDREG,	RESC1|RESCC,
541		"	fmovecr #0xf,A1\n	fsub.x AL,A1\n", },
542
543{ UMINUS,	INDREG|FORCC,
544	SNAME|SOREG,	TFP,
545	SDREG,		TFP,
546		NDREG,	RESC1|RESCC,
547		"	fmovecr #0xf,A1\n	fsub.ZA AL,A1\n", },
548
549{ COMPL,	FOREFF|INAREG|FORCC,
550	SAREG,	TAREG,
551	SAREG,	TAREG,
552		0,	RLEFT|RESCC,
553		"	not.ZA AL\n", },
554
555{ COMPL,	FOREFF|INCREG,
556	SCREG,	TLL,
557	SANY,	TANY,
558		0,	RLEFT,
559		"	not.l AL\n	not.l UL\n", },
560
561/*
562 * Shift operators.
563 */
564{ LS,	INAREG|FOREFF,
565	SAREG,	TAREG,
566	SAREG,	TAREG,
567		0,	RLEFT,
568		"	lsl.ZA AR,AL\n", },
569
570{ RS,	INAREG|FOREFF,
571	SAREG,	TUNSIGNED|TUSHORT|TUCHAR,
572	SAREG,	TAREG,
573		0,	RLEFT,
574		"	lsr.ZA AR,AL\n", },
575
576{ RS,	INAREG|FOREFF,
577	SAREG,	TINT|TSHORT|TCHAR,
578	SAREG,	TAREG,
579		0,	RLEFT,
580		"	asr.ZA AR,AL\n", },
581
582/*
583 * Leaf movements
584 */
585{ OPLTYPE,	INCREG,
586	SANY,			TANY,
587	SCREG|SCON|SOREG|SNAME,	TLL,
588		NCREG|NCSL,	RESC1,
589		"	move.l AL,A1\n	move.l UL,U1\n", },
590
591{ OPLTYPE,	INAREG,
592	SANY,	TANY,
593	SAREG|SCON|SOREG|SNAME, TAREG,
594		NAREG|NASL,	RESC1,
595		"	move.ZA AL,A1\n", },
596
597{ OPLTYPE,	INBREG,
598	SANY,	TANY,
599	SBREG|SCON|SOREG|SNAME, TPOINT,
600		NBREG|NBSL,	RESC1,
601		"	move.l AL,A1\n", },
602
603{ OPLTYPE,	INDREG,
604	SANY,		TANY,
605	SNAME|SOREG,	TFP,
606		NDREG|NDSL,	RESC1,
607		"	fmove.ZA AL,A1\n", },
608
609{ OPLTYPE,	INDREG,
610	SANY,	TANY,
611	SDREG,	TFP,
612		NDREG|NDSL,	RESC1,
613		"	fmove.x AL,A1\n", },
614
615/*
616 * Indirection operators.
617 */
618{ UMUL, INCREG,
619	SANY,	TPOINT,
620	SOREG,	TLL,
621		NCREG,	RESC1,
622		"	move.l AL,A1\n	move.l UL,U1\n", },
623
624{ UMUL, INAREG,
625	SANY,	TPOINT|TWORD,
626	SOREG,	TPOINT|TWORD,
627		NAREG|NASL,	RESC1,
628		"	move.l AL,A1\n", },
629
630{ UMUL, INBREG,
631	SANY,	TPOINT|TWORD,
632	SOREG,	TPOINT|TWORD,
633		NBREG|NBSL,	RESC1,
634		"	move.l AL,A1\n", },
635
636{ UMUL, INDREG,
637	SANY,	TPOINT|TFP,
638	SOREG,	TFP,
639		NDREG|NDSL,	RESC1,
640		"	fmove.ZA AL,A1\n", },
641
642{ UMUL, INAREG,
643	SANY,	TPOINT|TWORD,
644	SOREG,	TSHORT|TUSHORT,
645		NAREG|NASL,	RESC1,
646		"	move.w AL,A1\n", },
647
648{ UMUL, INAREG,
649	SANY,	TPOINT|TWORD,
650	SOREG,	TCHAR|TUCHAR,
651		NAREG|NASL,	RESC1,
652		"	move.b AL,A1\n", },
653
654
655/*
656 * DIV/MOD/MUL
657 */
658{ DIV,	INAREG,
659	SAREG|SNAME|SOREG,	TINT,
660	SAREG,			TINT,
661		0,	RLEFT,
662		"	divs.l AR,AL\n", },
663
664{ DIV,	INAREG,
665	SAREG|SNAME|SOREG,	TUNSIGNED,
666	SAREG,			TUNSIGNED,
667		0,	RLEFT,
668		"	divu.l AR,AL\n", },
669
670{ DIV,	INDREG,
671	SDREG,		TDOUBLE|TLDOUBLE,
672	SNAME|SOREG,	TDOUBLE|TLDOUBLE,
673		0,	RLEFT,
674		"	fdiv.ZA AR,AL\n", },
675
676{ DIV,	INDREG,
677	SDREG,	TFP,
678	SDREG,	TFP,
679		0,	RLEFT,
680		"	fdiv.x AR,AL\n", },
681
682{ DIV,	INDREG,
683	SDREG,		TFLOAT,
684	SNAME|SOREG,	TFLOAT,
685		0,	RLEFT,
686		"	fsgldiv.ZA AR,AL\n", },
687
688{ MOD,	INAREG,
689	SAREG,			TINT,
690	SAREG|SNAME|SOREG,	TINT,
691		NAREG*2,	RESC1,
692		"mov.l AL,A2\n	divsl.l AR,A1:A2\n", },
693
694{ MOD,	INAREG,
695	SAREG,			TUNSIGNED,
696	SAREG|SNAME|SOREG,	TUNSIGNED,
697		NAREG*2,	RESC1,
698		"mov.l AL,A2\n	divul.l AR,A1:A2\n", },
699
700{ MUL,	INAREG,
701	SAREG|SNAME|SOREG,	TWORD,
702	SAREG,			TWORD,
703		0,	RLEFT,
704		"	muls.l AR,AL\n", },
705
706{ MUL,	INDREG,
707	SDREG,		TDOUBLE|TLDOUBLE,
708	SNAME|SOREG,	TDOUBLE|TLDOUBLE,
709		0,	RLEFT,
710		"	fmul.ZA AR,AL\n", },
711
712{ MUL,	INDREG,
713	SDREG,	TFP,
714	SDREG,	TFP,
715		0,	RLEFT,
716		"	fmul.x AR,AL\n", },
717
718{ MUL,	INDREG,
719	SDREG,		TFLOAT,
720	SNAME|SOREG,	TFLOAT,
721		0,	RLEFT,
722		"	fsglmul.s AR,AL\n", },
723
724/*
725 * Function call nodes.
726 * Too many of them.
727 */
728/* FOREFF both direct and indirect */
729{ UCALL,	FOREFF,
730	SCON,	TANY,
731	SANY,	TANY,
732		0,	0,
733		"	ZC CL\n", },
734
735{ CALL,		FOREFF,
736	SCON,	TANY,
737	SANY,	TANY,
738		0,	0,
739		"	ZC CL\nZB", },
740
741{ UCALL,	FOREFF,
742	SBREG,	TANY,
743	SANY,	TANY,
744		0,	0,
745		"	jsr (AL)\n", },
746
747{ CALL,		FOREFF,
748	SBREG,	TANY,
749	SANY,	TANY,
750		0,	0,
751		"	jsr (AL)\nZB", },
752
753/* small scalar both direct and indirect */
754{ UCALL,	INAREG,
755	SCON,	TANY,
756	SAREG,	TAREG,
757		NAREG|NASL,	RESC1,
758		"	ZC CL\n", },
759
760{ CALL,		INAREG,
761	SCON,	TANY,
762	SAREG,	TAREG,
763		NAREG|NASL,	RESC1,
764		"	ZC CL\nZB", },
765
766{ UCALL,	INAREG,
767	SBREG,	TANY,
768	SAREG,	TAREG,
769		NAREG|NASL,	RESC1,
770		"	jsr (AL)\n", },
771
772{ CALL,		INAREG,
773	SBREG,	TANY,
774	SAREG,	TAREG,
775		NAREG|NASL,	RESC1,
776		"	jsr (AL)\nZB", },
777
778/* long long both direct and indirect */
779{ UCALL,	INCREG,
780	SCON,	TANY,
781	SCREG,	TLL,
782		NCREG|NCSL,	RESC1,
783		"	ZC CL\n", },
784
785{ CALL,		INCREG,
786	SCON,	TANY,
787	SCREG,	TLL,
788		NCREG|NCSL,	RESC1,
789		"	ZC CL\nZB", },
790
791{ UCALL,	INCREG,
792	SBREG,	TANY,
793	SCREG,	TLL,
794		NCREG|NCSL,	RESC1,
795		"	jsr (AL)\n", },
796
797{ CALL,		INCREG,
798	SBREG,	TANY,
799	SCREG,	TLL,
800		NCREG|NCSL,	RESC1,
801		"	jsr (AL)\nZB", },
802
803/* floats both direct and indirect */
804{ UCALL,	INDREG,
805	SCON,	TANY,
806	SDREG,	TFP,
807		NDREG|NDSL,	RESC1,
808		"	ZC CL\n", },
809
810{ CALL,		INDREG,
811	SCON,	TANY,
812	SDREG,	TFP,
813		NDREG|NDSL,	RESC1,
814		"	ZC CL\nZB", },
815
816{ UCALL,	INDREG,
817	SBREG,	TANY,
818	SDREG,	TFP,
819		NDREG|NDSL,	RESC1,
820		"	jsr (AL)\n", },
821
822{ CALL,		INDREG,
823	SBREG,	TANY,
824	SDREG,	TFP,
825		NDREG|NDSL,	RESC1,
826		"	jsr (AL)\nZB", },
827
828/* pointers both direct and indirect */
829{ UCALL,	INBREG,
830	SCON,	TANY,
831	SBREG,	TWORD|TPOINT,
832		NBREG|NBSL,	RESC1,
833		"	ZC CL\n", },
834
835{ CALL,		INBREG,
836	SCON,	TANY,
837	SBREG,	TWORD|TPOINT,
838		NBREG|NBSL,	RESC1,
839		"	ZC CL\nZB", },
840
841{ UCALL,	INBREG,
842	SBREG,	TANY,
843	SBREG,	TWORD|TPOINT,
844		NBREG|NBSL,	RESC1,
845		"	jsr (AL)\n", },
846
847{ CALL,		INBREG,
848	SBREG,	TANY,
849	SBREG,	TWORD|TPOINT,
850		NBREG|NBSL,	RESC1,
851		"	jsr (AL)\nZB", },
852
853
854/* struct return both direct and indirect */
855{ USTCALL,	INBREG|FOREFF,
856	SCON,	TANY,
857	SBREG,	TWORD|TPOINT,
858		NBREG|NBSL,	RESC1,
859		"ZP	ZC CL\n", },
860
861{ STCALL,	INBREG|FOREFF,
862	SCON,	TANY,
863	SBREG,	TWORD|TPOINT,
864		NBREG|NBSL,	RESC1,
865		"ZP	ZC CL\nZB", },
866
867{ USTCALL,	INBREG|FOREFF,
868	SBREG,	TANY,
869	SBREG,	TWORD|TPOINT,
870		NBREG|NBSL,	RESC1,
871		"ZP	jsr (AL)\n", },
872
873{ STCALL,		INBREG|FOREFF,
874	SBREG,	TANY,
875	SBREG,	TWORD|TPOINT,
876		NBREG|NBSL,	RESC1,
877		"ZP	jsr (AL)\nZB", },
878
879
880/*
881 * Arguments to functions.
882 */
883{ FUNARG,	FOREFF,
884	SAREG|SOREG|SNAME|SCON, TINT|TUNSIGNED,
885	SANY,			TANY,
886		0,	RNULL,
887		"	move.l AL,-(%sp)\n", },
888
889{ FUNARG,	FOREFF,
890	SCREG|SOREG|SNAME|SCON, TLL,
891	SANY,			TANY,
892		0,	RNULL,
893		"	move.l UL,-(%sp)\n	move.l AL,-(%sp)\n", },
894
895{ FUNARG,	FOREFF,
896	SCON,	TPOINT,
897	SANY,	TANY,
898		0,	RNULL,
899		"	pea CL\n", },
900
901{ FUNARG,	FOREFF,
902	SCON|SABREG|SNAME,	TWORD|TPOINT,
903	SANY,			TWORD|TPOINT,
904		0,	RNULL,
905		"	move.l AL,-(%sp)\n", },
906
907{ FUNARG,	FOREFF,
908	SOREG,	TWORD|TPOINT,
909	SANY,	TWORD|TPOINT,
910		0,	RNULL,
911		"	move.l AL,-(%sp)\n", },
912
913{ FUNARG,	FOREFF,
914	SDREG,	TFP,
915	SANY,	TFP,
916		0,	RNULL,
917		"	fmove.ZA AL,-(%sp)\n", },
918
919{ STARG,	FOREFF,
920	SBREG,	TPTRTO|TSTRUCT,
921	SANY,	TSTRUCT,
922		NAREG|NBREG,	RNULL,
923		"ZS", },
924
925/*
926 * Logical/branching operators
927 */
928
929/* Comparisions, take care of everything */
930#if 0
931{ OPLOG,	FORCC,
932	SHLL|SOREG|SNAME,	TLL,
933	SHLL,			TLL,
934		0,	0,
935		"ZD", },
936#endif
937
938{ OPLOG,	INCREG|FORCC,
939	SCREG,	TLL,
940	SCREG,	TLL,
941		0,	RESCC|RLEFT, /* trash left nodes */
942		"	sub.l UR,UL\n	subx.l AR,AL\n", },
943
944{ OPLOG,	FORCC,
945	SAREG,			TWORD,
946	SCON|SAREG|SOREG|SNAME, TWORD,
947		0,	RESCC,
948		"	cmp.l AR,AL\n", },
949
950{ OPLOG,	FORCC,
951	SBREG,			TPOINT,
952	SCON|SBREG|SOREG|SNAME, TPOINT,
953		0,	RESCC,
954		"	cmp.l AR,AL\n", },
955
956/* jumps below emitted in zzzcode */
957{ OPLOG,	FORCC,
958	SDREG,			TFP,
959	SCON|SOREG|SNAME,	TFP,
960		0,	0,
961		"	fcmp.ZL AR,AL\n	ZF", },
962
963{ OPLOG,	FORCC,
964	SDREG,	TFP,
965	SDREG,	TFP,
966		0,	0,
967		"	fcmp.x AR,AL\n	ZF", },
968
969
970/*
971 * Jumps.
972 */
973{ GOTO,		FOREFF,
974	SCON,	TANY,
975	SANY,	TANY,
976		0,	RNOP,
977		"	jmp LL\n", },
978
979#if defined(GCC_COMPAT) || defined(LANG_F77)
980{ GOTO,		FOREFF,
981	SBREG,	TANY,
982	SANY,	TANY,
983		0,	RNOP,
984		"	jmp (AL)\n", },
985#endif
986
987# define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
988
989{ UMUL, DF( UMUL ), },
990
991{ ASSIGN, DF(ASSIGN), },
992
993{ STASG, DF(STASG), },
994
995{ FLD, DF(FLD), },
996
997{ OPLEAF, DF(NAME), },
998
999/* { INIT, DF(INIT), }, */
1000
1001{ OPUNARY, DF(UMINUS), },
1002
1003{ OPANY, DF(BITYPE), },
1004
1005{ FREE, FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	"help; I'm in trouble\n" },
1006};
1007
1008int tablesize = sizeof(table)/sizeof(table[0]);
1009