1/*	Id: table.c,v 1.144 2015/10/07 11:30:21 ragge Exp 	*/
2/*	$NetBSD: table.c,v 1.1.1.6 2016/02/09 20:28:18 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|TULONG
38# define TSWORD TINT|TLONG
39# define TWORD TUWORD|TSWORD
40#define	 SHINT	SAREG	/* short and int */
41#define	 ININT	INAREG
42#define	 SHCH	SBREG	/* shape for char */
43#define	 INCH	INBREG
44#define	 SHLL	SCREG	/* shape for long long */
45#define	 INLL	INCREG
46#define	 SHFL	SDREG	/* shape for float/double */
47#define	 INFL	INDREG	/* shape for float/double */
48
49struct optab table[] = {
50/* First entry must be an empty entry */
51{ -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", },
52
53/* PCONVs are usually not necessary */
54{ PCONV,	INAREG,
55	SAREG,	TWORD|TPOINT,
56	SAREG,	TWORD|TPOINT,
57		0,	RLEFT,
58		"", },
59
60/*
61 * A bunch conversions of integral<->integral types
62 * There are lots of them, first in table conversions to itself
63 * and then conversions from each type to the others.
64 */
65
66/* itself to itself, including pointers */
67
68/* convert (u)char to (u)char. */
69{ SCONV,	INCH,
70	SHCH,	TCHAR|TUCHAR,
71	SHCH,	TCHAR|TUCHAR,
72		0,	RLEFT,
73		"", },
74
75/* convert pointers to int. */
76{ SCONV,	ININT,
77	SHINT,	TPOINT|TWORD,
78	SANY,	TWORD,
79		0,	RLEFT,
80		"", },
81
82/* convert (u)longlong to (u)longlong. */
83{ SCONV,	INLL,
84	SHLL,	TLL,
85	SHLL,	TLL,
86		0,	RLEFT,
87		"", },
88
89/* convert between float/double/long double. */
90{ SCONV,	INFL,
91	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
92	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
93		0,	RLEFT,
94		"ZI", },
95
96/* convert pointers to pointers. */
97{ SCONV,	ININT,
98	SHINT,	TPOINT,
99	SANY,	TPOINT,
100		0,	RLEFT,
101		"", },
102
103/* char to something */
104
105/* convert char to (unsigned) short. */
106{ SCONV,	ININT,
107	SBREG|SOREG|SNAME,	TCHAR,
108	SAREG,	TSHORT|TUSHORT,
109		NASL|NAREG,	RESC1,
110		"	movsbw AL,A1\n", },
111
112/* convert unsigned char to (u)short. */
113{ SCONV,	ININT,
114	SHCH|SOREG|SNAME,	TUCHAR,
115	SAREG,	TSHORT|TUSHORT,
116		NASL|NAREG,	RESC1,
117		"	movzbw AL,A1\n", },
118
119/* convert signed char to int (or pointer). */
120{ SCONV,	ININT,
121	SHCH|SOREG|SNAME,	TCHAR,
122	SAREG,	TWORD|TPOINT,
123		NASL|NAREG,	RESC1,
124		"	movsbl AL,A1\n", },
125
126/* convert unsigned char to (u)int. */
127{ SCONV,	ININT,
128	SHCH|SOREG|SNAME,	TUCHAR,
129	SAREG,	TWORD,
130		NASL|NAREG,	RESC1,
131		"	movzbl AL,A1\n", },
132
133/* convert char to (u)long long */
134{ SCONV,	INLL,
135	SHCH|SOREG|SNAME,	TCHAR,
136	SANY,	TLL,
137		NSPECIAL|NCREG|NCSL,	RESC1,
138		"	movsbl AL,%eax\n	cltd\n", },
139
140/* convert unsigned char to (u)long long */
141{ SCONV,	INLL,
142	SHCH|SOREG|SNAME,	TUCHAR,
143	SANY,			TLL,
144		NCREG|NCSL,	RESC1,
145		"	movzbl AL,A1\n	xorl U1,U1\n", },
146
147/* convert char (in register) to double XXX - use NTEMP */
148{ SCONV,	INFL,
149	SHCH|SOREG|SNAME,	TCHAR,
150	SHFL,			TLDOUBLE|TDOUBLE|TFLOAT,
151		NAREG|NASL|NDREG,	RESC2,
152		"	movsbl AL,A1\n	pushl A1\n"
153		"	fildl (%esp)\n	addl $4,%esp\n", },
154
155/* convert (u)char (in register) to double XXX - use NTEMP */
156{ SCONV,	INFL,
157	SHCH|SOREG|SNAME,	TUCHAR,
158	SHFL,			TLDOUBLE|TDOUBLE|TFLOAT,
159		NAREG|NASL|NDREG,	RESC2,
160		"	movzbl AL,A1\n	pushl A1\n"
161		"	fildl (%esp)\n	addl $4,%esp\n", },
162
163/* short to something */
164
165/* convert (u)short to (u)short. */
166{ SCONV,	INAREG,
167	SAREG,	TSHORT|TUSHORT,
168	SAREG,	TSHORT|TUSHORT,
169		0,	RLEFT,
170		"", },
171
172/* convert short (in memory) to char */
173{ SCONV,	INCH,
174	SNAME|SOREG,	TSHORT|TUSHORT,
175	SHCH,		TCHAR|TUCHAR,
176		NBREG|NBSL,	RESC1,
177		"	movb AL,A1\n", },
178
179/* convert short (in reg) to char. */
180{ SCONV,	INCH,
181	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
182	SHCH,			TCHAR|TUCHAR,
183		NSPECIAL|NBREG|NBSL,	RESC1,
184		"ZM", },
185
186/* convert short to (u)int. */
187{ SCONV,	ININT,
188	SAREG|SOREG|SNAME,	TSHORT,
189	SAREG,	TWORD,
190		NASL|NAREG,	RESC1,
191		"	movswl AL,A1\n", },
192
193/* convert unsigned short to (u)int. */
194{ SCONV,	ININT,
195	SAREG|SOREG|SNAME,	TUSHORT,
196	SAREG,	TWORD,
197		NASL|NAREG,	RESC1,
198		"	movzwl AL,A1\n", },
199
200/* convert short to (u)long long */
201{ SCONV,	INLL,
202	SAREG|SOREG|SNAME,	TSHORT,
203	SHLL,			TLL,
204		NSPECIAL|NCREG|NCSL,	RESC1,
205		"	movswl AL,%eax\n	cltd\n", },
206
207/* convert unsigned short to (u)long long */
208{ SCONV,	INLL,
209	SAREG|SOREG|SNAME,	TUSHORT,
210	SHLL,			TLL,
211		NCREG|NCSL,	RESC1,
212		"	movzwl AL,A1\n	xorl U1,U1\n", },
213
214/* convert short (in memory) to float/double */
215{ SCONV,	INFL,
216	SOREG|SNAME,	TSHORT,
217	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
218		NDREG,	RESC1,
219		"	fild AL\n", },
220
221/* convert short (in register) to float/double */
222{ SCONV,	INFL,
223	SAREG,	TSHORT,
224	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
225		NTEMP|NDREG,	RESC1,
226		"	pushw AL\n	fild (%esp)\n	addl $2,%esp\n", },
227
228/* convert unsigned short to double XXX - use NTEMP */
229{ SCONV,	INFL,
230	SAREG|SOREG|SNAME,	TUSHORT,
231	SHFL,			TLDOUBLE|TDOUBLE|TFLOAT,
232		NAREG|NASL|NDREG|NTEMP,	RESC2,
233		"	movzwl AL,A1\n	pushl A1\n"
234		"	fildl (%esp)\n	addl $4,%esp\n", },
235
236/* int to something */
237
238/* convert int to char. This is done when register is loaded */
239{ SCONV,	INCH,
240	SAREG,	TWORD|TPOINT,
241	SANY,	TCHAR|TUCHAR,
242		NSPECIAL|NBREG|NBSL,	RESC1,
243		"ZM", },
244
245/* convert int to short. Nothing to do */
246{ SCONV,	INAREG,
247	SAREG,	TWORD|TPOINT,
248	SANY,	TSHORT|TUSHORT,
249		0,	RLEFT,
250		"", },
251
252/* convert signed int to (u)long long */
253{ SCONV,	INLL,
254	SHINT,	TSWORD,
255	SHLL,	TLL,
256		NSPECIAL|NCREG|NCSL,	RESC1,
257		"	cltd\n", },
258
259/* convert unsigned int to (u)long long */
260{ SCONV,	INLL,
261	SHINT|SOREG|SNAME,	TUWORD|TPOINT,
262	SHLL,	TLL,
263		NCSL|NCREG,	RESC1,
264		"	movl AL,A1\n	xorl U1,U1\n", },
265
266/* convert signed int (in memory) to double */
267{ SCONV,	INFL,
268	SOREG|SNAME,	TSWORD,
269	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
270		NDREG,	RESC1,
271		"	fildl AL\n", },
272
273/* convert signed int (in register) to double */
274{ SCONV,	INFL,
275	SAREG,	TSWORD,
276	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
277		NDREG,	RESC1,
278		"	pushl AL\n	fildl (%esp)\n	addl $4,%esp\n", },
279
280/* convert unsigned int (reg&mem) to double */
281{ SCONV,       INFL,
282	SOREG|SNAME|SAREG,	TUWORD,
283	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
284		NDREG,	RESC1,
285		"	pushl $0\n"
286		"	pushl AL\n"
287		"	fildq (%esp)\n"
288		"	addl $8,%esp\n", },
289
290/* long long to something */
291
292/* convert (u)long long to (u)char (mem->reg) */
293{ SCONV,	INCH,
294	SOREG|SNAME,	TLL,
295	SANY,	TCHAR|TUCHAR,
296		NBREG|NBSL,	RESC1,
297		"	movb AL,A1\n", },
298
299/* convert (u)long long to (u)char (reg->reg, hopefully nothing) */
300{ SCONV,	INCH,
301	SHLL,	TLL,
302	SANY,	TCHAR|TUCHAR,
303		NBREG|NBSL|NTEMP,	RESC1,
304		"ZS", },
305
306/* convert (u)long long to (u)short (mem->reg) */
307{ SCONV,	INAREG,
308	SOREG|SNAME,	TLL,
309	SAREG,	TSHORT|TUSHORT,
310		NAREG|NASL,	RESC1,
311		"	movw AL,A1\n", },
312
313/* convert (u)long long to (u)short (reg->reg, hopefully nothing) */
314{ SCONV,	INAREG,
315	SHLL|SOREG|SNAME,	TLL,
316	SAREG,	TSHORT|TUSHORT,
317		NAREG|NASL|NTEMP,	RESC1,
318		"ZS", },
319
320/* convert long long to int (mem->reg) */
321{ SCONV,	INAREG,
322	SOREG|SNAME,	TLL,
323	SAREG,	TWORD|TPOINT,
324		NAREG|NASL,	RESC1,
325		"	movl AL,A1\n", },
326
327/* convert long long to int (reg->reg, hopefully nothing) */
328{ SCONV,	INAREG,
329	SHLL|SOREG|SNAME,	TLL,
330	SAREG,	TWORD|TPOINT,
331		NAREG|NASL|NTEMP,	RESC1,
332		"ZS", },
333
334/* convert long long (in memory) to floating */
335{ SCONV,	INFL,
336	SOREG|SNAME,	TLONGLONG,
337	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
338		NDREG,	RESC1,
339		"	fildq AL\n", },
340
341/* convert long long (in register) to floating */
342{ SCONV,	INFL,
343	SHLL,	TLONGLONG,
344	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
345		NTEMP|NDREG,	RESC1,
346		"	pushl UL\n	pushl AL\n"
347		"	fildq (%esp)\n	addl $8,%esp\n", },
348
349/* convert unsigned long long to floating */
350{ SCONV,	INFL,
351	SCREG,	TULONGLONG,
352	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
353		NDREG,	RESC1,
354		"ZJ", },
355
356/* float to something */
357
358#if 0 /* go via int by adding an extra sconv in clocal() */
359/* convert float/double to (u) char. XXX should use NTEMP here */
360{ SCONV,	INCH,
361	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
362	SHCH,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
363		NBREG,	RESC1,
364		"	subl $4,%esp\n	fistpl (%esp)\n	popl A1\n", },
365
366/* convert float/double to (u) int/short/char. XXX should use NTEMP here */
367{ SCONV,	INCH,
368	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
369	SHCH,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
370		NCREG,	RESC1,
371		"	subl $4,%esp\n	fistpl (%esp)\n	popl A1\n", },
372#endif
373
374/* convert float/double to int. XXX should use NTEMP here */
375{ SCONV,	INAREG,
376	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
377	SAREG,	TSWORD,
378		NAREG,	RESC1,
379		"	subl $12,%esp\n"
380		"	fnstcw (%esp)\n"
381		"	fnstcw 4(%esp)\n"
382		"	movb $12,1(%esp)\n"
383		"	fldcw (%esp)\n"
384		"	fistpl 8(%esp)\n"
385		"	movl 8(%esp),A1\n"
386		"	fldcw 4(%esp)\n"
387		"	addl $12,%esp\n", },
388
389/* convert float/double to unsigned int. XXX should use NTEMP here */
390{ SCONV,       INAREG,
391	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
392	SAREG,	TUWORD,
393		NAREG,	RESC1,
394		"	subl $16,%esp\n"
395		"	fnstcw (%esp)\n"
396		"	fnstcw 4(%esp)\n"
397		"	movb $12,1(%esp)\n"
398		"	fldcw (%esp)\n"
399		"	fistpq 8(%esp)\n"
400		"	movl 8(%esp),A1\n"
401		"	fldcw 4(%esp)\n"
402		"	addl $16,%esp\n", },
403
404/* convert float/double (in register) to long long */
405{ SCONV,	INLL,
406	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
407	SHLL,	TLONGLONG,
408		NCREG,	RESC1,
409		"	subl $16,%esp\n"
410		"	fnstcw (%esp)\n"
411		"	fnstcw 4(%esp)\n"
412		"	movb $12,1(%esp)\n"
413		"	fldcw (%esp)\n"
414		"	fistpq 8(%esp)\n"
415		"	movl 8(%esp),A1\n"
416		"	movl 12(%esp),U1\n"
417		"	fldcw 4(%esp)\n"
418		"	addl $16,%esp\n", },
419
420/* convert float/double (in register) to unsigned long long */
421{ SCONV,	INLL,
422	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
423	SHLL,	TULONGLONG,
424		NCREG,	RESC1,
425		"	subl $16,%esp\n"
426		"	fnstcw (%esp)\n"
427		"	fnstcw 4(%esp)\n"
428		"	movb $7,1(%esp)\n"	/* 64-bit, round down  */
429		"	fldcw (%esp)\n"
430		"	movl $0x5f000000, 8(%esp)\n"	/* (float)(1<<63) */
431		"	fsubs 8(%esp)\n"	/* keep in range of fistpq */
432		"	fistpq 8(%esp)\n"
433		"	xorb $0x80,15(%esp)\n"	/* addq $1>>63 to 8(%esp) */
434		"	movl 8(%esp),A1\n"
435		"	movl 12(%esp),U1\n"
436		"	fldcw 4(%esp)\n"
437		"	addl $16,%esp\n", },
438
439
440
441/* slut sconv */
442
443/*
444 * Subroutine calls.
445 */
446
447{ UCALL,	FOREFF,
448	SCON,	TANY,
449	SANY,	TANY,
450		0,	0,
451		"	call CL\nZC", },
452
453{ CALL,		FOREFF,
454	SCON,	TANY,
455	SANY,	TANY,
456		0,	0,
457		"	call CL\nZC", },
458
459{ UCALL,	FOREFF,
460	SCON,	TANY,
461	SAREG,	TWORD|TPOINT,
462		0,	0,
463		"	call CL\nZC", },
464
465{ CALL,	INAREG,
466	SCON,	TANY,
467	SAREG,	TSHORT|TUSHORT|TWORD|TPOINT,
468		NAREG|NASL,	RESC1,	/* should be 0 */
469		"	call CL\nZC", },
470
471{ UCALL,	INAREG,
472	SCON,	TANY,
473	SAREG,	TSHORT|TUSHORT|TWORD|TPOINT,
474		NAREG|NASL,	RESC1,	/* should be 0 */
475		"	call CL\nZC", },
476
477{ CALL,	INBREG,
478	SCON,	TANY,
479	SBREG,	TCHAR|TUCHAR,
480		NBREG,	RESC1,	/* should be 0 */
481		"	call CL\nZC", },
482
483{ UCALL,	INBREG,
484	SCON,	TANY,
485	SBREG,	TCHAR|TUCHAR,
486		NBREG,	RESC1,	/* should be 0 */
487		"	call CL\nZC", },
488
489{ CALL,		INCREG,
490	SCON,	TANY,
491	SCREG,	TANY,
492		NCREG|NCSL,	RESC1,	/* should be 0 */
493		"	call CL\nZC", },
494
495{ UCALL,	INCREG,
496	SCON,	TANY,
497	SCREG,	TANY,
498		NCREG|NCSL,	RESC1,	/* should be 0 */
499		"	call CL\nZC", },
500
501{ CALL,	INDREG,
502	SCON,	TANY,
503	SDREG,	TANY,
504		NDREG|NDSL,	RESC1,	/* should be 0 */
505		"	call CL\nZC", },
506
507{ UCALL,	INDREG,
508	SCON,	TANY,
509	SDREG,	TANY,
510		NDREG|NDSL,	RESC1,	/* should be 0 */
511		"	call CL\nZC", },
512
513{ CALL,		FOREFF,
514	SAREG,	TANY,
515	SANY,	TANY,
516		0,	0,
517		"	call *AL\nZC", },
518
519{ UCALL,	FOREFF,
520	SAREG,	TANY,
521	SANY,	TANY,
522		0,	0,
523		"	call *AL\nZC", },
524
525{ CALL,		INAREG,
526	SAREG,	TANY,
527	SANY,	TANY,
528		NAREG|NASL,	RESC1,	/* should be 0 */
529		"	call *AL\nZC", },
530
531{ UCALL,	INAREG,
532	SAREG,	TANY,
533	SANY,	TANY,
534		NAREG|NASL,	RESC1,	/* should be 0 */
535		"	call *AL\nZC", },
536
537{ CALL,		INBREG,
538	SAREG,	TANY,
539	SANY,	TANY,
540		NBREG|NBSL,	RESC1,	/* should be 0 */
541		"	call *AL\nZC", },
542
543{ UCALL,	INBREG,
544	SAREG,	TANY,
545	SANY,	TANY,
546		NBREG|NBSL,	RESC1,	/* should be 0 */
547		"	call *AL\nZC", },
548
549{ CALL,		INCREG,
550	SAREG,	TANY,
551	SANY,	TANY,
552		NCREG|NCSL,	RESC1,	/* should be 0 */
553		"	call *AL\nZC", },
554
555{ UCALL,	INCREG,
556	SAREG,	TANY,
557	SANY,	TANY,
558		NCREG|NCSL,	RESC1,	/* should be 0 */
559		"	call *AL\nZC", },
560
561{ CALL,		INDREG,
562	SAREG,	TANY,
563	SANY,	TANY,
564		NDREG|NDSL,	RESC1,	/* should be 0 */
565		"	call *AL\nZC", },
566
567{ UCALL,	INDREG,
568	SAREG,	TANY,
569	SANY,	TANY,
570		NDREG|NDSL,	RESC1,	/* should be 0 */
571		"	call *AL\nZC", },
572
573{ STCALL,	FOREFF,
574	SCON,	TANY,
575	SANY,	TANY,
576		NAREG|NASL,	0,
577		"	call CL\nZC", },
578
579{ STCALL,	INAREG,
580	SCON,	TANY,
581	SANY,	TANY,
582		NAREG|NASL,	RESC1,	/* should be 0 */
583		"	call CL\nZC", },
584
585{ STCALL,	INAREG,
586	SNAME|SAREG,	TANY,
587	SANY,	TANY,
588		NAREG|NASL,	RESC1,	/* should be 0 */
589		"	call *AL\nZC", },
590
591/*
592 * The next rules handle all binop-style operators.
593 */
594/* Special treatment for long long */
595{ PLUS,		INLL|FOREFF,
596	SHLL,		TLL,
597	SHLL|SNAME|SOREG,	TLL,
598		0,	RLEFT,
599		"	addl AR,AL\n	adcl UR,UL\n", },
600
601{ PLUS,		INLL|FOREFF,
602	SHLL|SNAME|SOREG,	TLL,
603	SHLL|SCON,		TLL,
604		0,	RLEFT,
605		"	addl AR,AL\n	adcl UR,UL\n", },
606
607/* Special treatment for long long  XXX - fix commutative check */
608{ PLUS,		INLL|FOREFF,
609	SHLL|SNAME|SOREG,	TLL,
610	SHLL,			TLL,
611		0,	RRIGHT,
612		"	addl AL,AR\n	adcl UL,UR\n", },
613
614{ PLUS,		INFL,
615	SHFL,		TDOUBLE,
616	SNAME|SOREG,	TDOUBLE,
617		0,	RLEFT,
618		"	faddl AR\n", },
619
620{ PLUS,		INFL|FOREFF,
621	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
622	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
623		0,	RLEFT,
624		"	faddp\n", },
625
626{ PLUS,		INAREG|FOREFF,
627	SAREG|SNAME|SOREG,	TWORD|TPOINT,
628	SONE,	TANY,
629		0,	RLEFT,
630		"	incl AL\n", },
631
632{ PLUS,		INAREG|FOREFF,
633	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
634	SONE,	TANY,
635		0,	RLEFT,
636		"	incw AL\n", },
637
638{ PLUS,		INCH|FOREFF,
639	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
640	SONE,	TANY,
641		0,	RLEFT,
642		"	incb AL\n", },
643
644{ PLUS,		INAREG,
645	SAREG,	TWORD,
646	SAREG,	TWORD,
647		NAREG|NASL|NASR,	RESC1,
648		"	leal (AL,AR),A1\n", },
649
650{ MINUS,	INAREG|FOREFF,
651	SAREG|SNAME|SOREG,	TWORD|TPOINT,
652	SONE,			TANY,
653		0,	RLEFT,
654		"	decl AL\n", },
655
656{ MINUS,	INAREG|FOREFF,
657	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
658	SONE,			TANY,
659		0,	RLEFT,
660		"	decw AL\n", },
661
662{ MINUS,	INCH|FOREFF,
663	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
664	SONE,	TANY,
665		0,	RLEFT,
666		"	decb AL\n", },
667
668/* address as register offset, negative */
669{ MINUS,	INLL|FOREFF,
670	SHLL,	TLL,
671	SHLL|SNAME|SOREG,	TLL,
672		0,	RLEFT,
673		"	subl AR,AL\n	sbbl UR,UL\n", },
674
675{ MINUS,	INLL|FOREFF,
676	SHLL|SNAME|SOREG,	TLL,
677	SHLL|SCON,	TLL,
678		0,	RLEFT,
679		"	subl AR,AL\n	sbbl UR,UL\n", },
680
681{ MINUS,	INFL,
682	SHFL,	TDOUBLE,
683	SNAME|SOREG,	TDOUBLE,
684		0,	RLEFT,
685		"	fsubl AR\n", },
686
687{ MINUS,	INFL|FOREFF,
688	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
689	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
690		0,	RLEFT,
691		"	fsubZAp\n", },
692
693/* Simple r/m->reg ops */
694/* m/r |= r */
695{ OPSIMP,	INAREG|FOREFF|FORCC,
696	SAREG|SNAME|SOREG,	TWORD|TPOINT,
697	SAREG,			TWORD|TPOINT,
698		0,	RLEFT|RESCC,
699		"	Ol AR,AL\n", },
700
701/* r |= r/m */
702{ OPSIMP,	INAREG|FOREFF|FORCC,
703	SAREG,			TWORD|TPOINT,
704	SAREG|SNAME|SOREG,	TWORD|TPOINT,
705		0,	RLEFT|RESCC,
706		"	Ol AR,AL\n", },
707
708/* m/r |= r */
709{ OPSIMP,	INAREG|FOREFF|FORCC,
710	SHINT|SNAME|SOREG,	TSHORT|TUSHORT,
711	SHINT,		TSHORT|TUSHORT,
712		0,	RLEFT|RESCC,
713		"	Ow AR,AL\n", },
714
715/* r |= r/m */
716{ OPSIMP,	INAREG|FOREFF|FORCC,
717	SHINT,		TSHORT|TUSHORT,
718	SHINT|SNAME|SOREG,	TSHORT|TUSHORT,
719		0,	RLEFT|RESCC,
720		"	Ow AR,AL\n", },
721
722/* m/r |= r */
723{ OPSIMP,	INCH|FOREFF|FORCC,
724	SHCH,		TCHAR|TUCHAR,
725	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
726		0,	RLEFT|RESCC,
727		"	Ob AR,AL\n", },
728
729/* r |= r/m */
730{ OPSIMP,	INCH|FOREFF|FORCC,
731	SHCH,		TCHAR|TUCHAR,
732	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
733		0,	RLEFT|RESCC,
734		"	Ob AR,AL\n", },
735
736/* m/r |= const */
737{ OPSIMP,	INAREG|FOREFF|FORCC,
738	SAREG|SNAME|SOREG,	TWORD|TPOINT,
739	SCON,	TWORD|TPOINT,
740		0,	RLEFT|RESCC,
741		"	Ol AR,AL\n", },
742
743{ OPSIMP,	INAREG|FOREFF|FORCC,
744	SHINT|SNAME|SOREG,	TSHORT|TUSHORT,
745	SCON,	TANY,
746		0,	RLEFT|RESCC,
747		"	Ow AR,AL\n", },
748
749{ OPSIMP,	INCH|FOREFF|FORCC,
750	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
751	SCON,	TANY,
752		0,	RLEFT|RESCC,
753		"	Ob AR,AL\n", },
754
755/* r |= r/m */
756{ OPSIMP,	INLL|FOREFF,
757	SHLL,	TLL,
758	SHLL|SNAME|SOREG,	TLL,
759		0,	RLEFT,
760		"	Ol AR,AL\n	Ol UR,UL\n", },
761
762/* m/r |= r/const */
763{ OPSIMP,	INLL|FOREFF,
764	SHLL|SNAME|SOREG,	TLL,
765	SHLL|SCON,	TLL,
766		0,	RLEFT,
767		"	Ol AR,AL\n	Ol UR,UL\n", },
768
769/* Try use-reg instructions first */
770{ PLUS,		INAREG,
771	SAREG,	TWORD|TPOINT,
772	SCON,	TANY,
773		NAREG|NASL,	RESC1,
774		"	leal CR(AL),A1\n", },
775
776{ MINUS,	INAREG,
777	SAREG,	TWORD|TPOINT,
778	SPCON,	TANY,
779		NAREG|NASL,	RESC1,
780		"	leal -CR(AL),A1\n", },
781
782
783/*
784 * The next rules handle all shift operators.
785 */
786/* (u)longlong left shift is emulated */
787{ LS,	INCREG,
788	SCREG,	TLL,
789	SHCH,	TCHAR|TUCHAR,
790		NSPECIAL,	RLEFT,
791		"ZO", },
792
793/* r/m <<= r */
794{ LS,	INAREG|FOREFF,
795	SAREG|SNAME|SOREG,	TWORD,
796	SHCH,		TCHAR|TUCHAR,
797		NSPECIAL,	RLEFT,
798		"	sall AR,AL\n", },
799
800/* r/m <<= const */
801{ LS,	INAREG|FOREFF,
802	SAREG|SNAME|SOREG,	TWORD,
803	SCON,	TANY,
804		0,	RLEFT,
805		"	sall AR,AL\n", },
806
807/* r/m <<= r */
808{ LS,	INAREG|FOREFF,
809	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
810	SHCH,			TCHAR|TUCHAR,
811		NSPECIAL,	RLEFT,
812		"	shlw AR,AL\n", },
813
814/* r/m <<= const */
815{ LS,	INAREG|FOREFF,
816	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
817	SCON,	TANY,
818		0,	RLEFT,
819		"	shlw AR,AL\n", },
820
821{ LS,	INCH|FOREFF,
822	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
823	SHCH,			TCHAR|TUCHAR,
824		NSPECIAL,	RLEFT,
825		"	salb AR,AL\n", },
826
827{ LS,	INCH|FOREFF,
828	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
829	SCON,			TANY,
830		0,	RLEFT,
831		"	salb AR,AL\n", },
832
833/* (u)longlong right shift is emulated */
834{ RS,	INCREG,
835	SCREG,	TLL,
836	SHCH,	TCHAR|TUCHAR,
837		NSPECIAL,	RLEFT,
838		"ZO", },
839
840{ RS,	INAREG|FOREFF,
841	SAREG|SNAME|SOREG,	TSWORD,
842	SHCH,			TCHAR|TUCHAR,
843		NSPECIAL,	RLEFT,
844		"	sarl AR,AL\n", },
845
846{ RS,	INAREG|FOREFF,
847	SAREG|SNAME|SOREG,	TSWORD,
848	SCON,			TANY,
849		0,		RLEFT,
850		"	sarl AR,AL\n", },
851
852{ RS,	INAREG|FOREFF,
853	SAREG|SNAME|SOREG,	TUWORD,
854	SHCH,			TCHAR|TUCHAR,
855		NSPECIAL,	RLEFT,
856		"	shrl AR,AL\n", },
857
858{ RS,	INAREG|FOREFF,
859	SAREG|SNAME|SOREG,	TUWORD,
860	SCON,			TANY,
861		0,		RLEFT,
862		"	shrl AR,AL\n", },
863
864{ RS,	INAREG|FOREFF,
865	SAREG|SNAME|SOREG,	TSHORT,
866	SHCH,			TCHAR|TUCHAR,
867		NSPECIAL,	RLEFT,
868		"	sarw AR,AL\n", },
869
870{ RS,	INAREG|FOREFF,
871	SAREG|SNAME|SOREG,	TSHORT,
872	SCON,			TANY,
873		0,		RLEFT,
874		"	sarw AR,AL\n", },
875
876{ RS,	INAREG|FOREFF,
877	SAREG|SNAME|SOREG,	TUSHORT,
878	SHCH,			TCHAR|TUCHAR,
879		NSPECIAL,	RLEFT,
880		"	shrw AR,AL\n", },
881
882{ RS,	INAREG|FOREFF,
883	SAREG|SNAME|SOREG,	TUSHORT,
884	SCON,			TANY,
885		0,		RLEFT,
886		"	shrw AR,AL\n", },
887
888{ RS,	INCH|FOREFF,
889	SHCH|SNAME|SOREG,	TCHAR,
890	SHCH,			TCHAR|TUCHAR,
891		NSPECIAL,	RLEFT,
892		"	sarb AR,AL\n", },
893
894{ RS,	INCH|FOREFF,
895	SHCH|SNAME|SOREG,	TCHAR,
896	SCON,			TANY,
897		0,		RLEFT,
898		"	sarb AR,AL\n", },
899
900{ RS,	INCH|FOREFF,
901	SHCH|SNAME|SOREG,	TUCHAR,
902	SHCH,			TCHAR|TUCHAR,
903		NSPECIAL,	RLEFT,
904		"	shrb AR,AL\n", },
905
906{ RS,	INCH|FOREFF,
907	SHCH|SNAME|SOREG,	TUCHAR,
908	SCON,			TANY,
909		0,		RLEFT,
910		"	shrb AR,AL\n", },
911
912/*
913 * The next rules takes care of assignments. "=".
914 */
915{ ASSIGN,	FORCC|FOREFF|INLL,
916	SHLL,		TLL,
917	SMIXOR,		TANY,
918		0,	RDEST,
919		"	xorl AL,AL\n	xorl UL,UL\n", },
920
921{ ASSIGN,	FORCC|FOREFF|INLL,
922	SHLL,		TLL,
923	SMILWXOR,	TANY,
924		0,	RDEST,
925		"	xorl AL,AL\n	movl UR,UL\n", },
926
927{ ASSIGN,	FORCC|FOREFF|INLL,
928	SHLL,		TLL,
929	SMIHWXOR,	TANY,
930		0,	RDEST,
931		"	movl AR,AL\n	xorl UL,UL\n", },
932
933{ ASSIGN,	FOREFF|INLL,
934	SHLL,		TLL,
935	SCON,		TANY,
936		0,	RDEST,
937		"	movl AR,AL\n	movl UR,UL\n", },
938
939{ ASSIGN,	FOREFF,
940	SHLL|SNAME|SOREG,	TLL,
941	SCON,		TANY,
942		0,	0,
943		"	movl AR,AL\n	movl UR,UL\n", },
944
945{ ASSIGN,	FORCC|FOREFF|INAREG,
946	SAREG,	TWORD|TPOINT,
947	SMIXOR,		TANY,
948		0,	RDEST,
949		"	xorl AL,AL\n", },
950
951{ ASSIGN,	FOREFF,
952	SAREG|SNAME|SOREG,	TWORD|TPOINT,
953	SCON,		TANY,
954		0,	0,
955		"	movl AR,AL\n", },
956
957{ ASSIGN,	FOREFF|INAREG,
958	SAREG,	TWORD|TPOINT,
959	SCON,		TANY,
960		0,	RDEST,
961		"	movl AR,AL\n", },
962
963{ ASSIGN,	FORCC|FOREFF|INAREG,
964	SAREG,	TSHORT|TUSHORT,
965	SMIXOR,		TANY,
966		0,	RDEST,
967		"	xorw AL,AL\n", },
968
969{ ASSIGN,	FOREFF,
970	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
971	SCON,		TANY,
972		0,	0,
973		"	movw AR,AL\n", },
974
975{ ASSIGN,	FOREFF|INAREG,
976	SAREG,	TSHORT|TUSHORT,
977	SCON,		TANY,
978		0,	RDEST,
979		"	movw AR,AL\n", },
980
981{ ASSIGN,	FOREFF,
982	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
983	SCON,		TANY,
984		0,	0,
985		"	movb AR,AL\n", },
986
987{ ASSIGN,	FOREFF|INCH,
988	SHCH,		TCHAR|TUCHAR,
989	SCON,		TANY,
990		0,	RDEST,
991		"	movb AR,AL\n", },
992
993{ ASSIGN,	FOREFF|INLL,
994	SNAME|SOREG,	TLL,
995	SHLL,		TLL,
996		0,	RDEST,
997		"	movl AR,AL\n	movl UR,UL\n", },
998
999{ ASSIGN,	FOREFF|INLL,
1000	SHLL,	TLL,
1001	SHLL,	TLL,
1002		0,	RDEST,
1003		"ZH", },
1004
1005{ ASSIGN,	FOREFF|INAREG,
1006	SAREG|SNAME|SOREG,	TWORD|TPOINT,
1007	SAREG,		TWORD|TPOINT,
1008		0,	RDEST,
1009		"	movl AR,AL\n", },
1010
1011{ ASSIGN,	FOREFF|INAREG,
1012	SAREG,			TWORD|TPOINT,
1013	SAREG|SNAME|SOREG,	TWORD|TPOINT,
1014		0,	RDEST,
1015		"	movl AR,AL\n", },
1016
1017{ ASSIGN,	FOREFF|INAREG,
1018	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
1019	SAREG,		TSHORT|TUSHORT,
1020		0,	RDEST,
1021		"	movw AR,AL\n", },
1022
1023{ ASSIGN,	FOREFF|INCH,
1024	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
1025	SHCH,		TCHAR|TUCHAR|TWORD,
1026		0,	RDEST,
1027		"	movb AR,AL\n", },
1028
1029{ ASSIGN,	INDREG|FOREFF,
1030	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1031	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1032		0,	RDEST,
1033		"", }, /* This will always be in the correct register */
1034
1035/* order of table entries is very important here! */
1036{ ASSIGN,	INFL,
1037	SNAME|SOREG,	TLDOUBLE,
1038	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1039		0,	RDEST,
1040		"	fstpt AL\n	fldt AL\n", }, /* XXX */
1041
1042{ ASSIGN,	FOREFF,
1043	SNAME|SOREG,	TLDOUBLE,
1044	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1045		0,	0,
1046		"	fstpt AL\n", },
1047
1048{ ASSIGN,	INFL,
1049	SNAME|SOREG,	TDOUBLE,
1050	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1051		0,	RDEST,
1052		"	fstl AL\n", },
1053
1054{ ASSIGN,	FOREFF,
1055	SNAME|SOREG,	TDOUBLE,
1056	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1057		0,	0,
1058		"	fstpl AL\n", },
1059
1060{ ASSIGN,	INFL,
1061	SNAME|SOREG,	TFLOAT,
1062	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1063		0,	RDEST,
1064		"	fsts AL\n", },
1065
1066{ ASSIGN,	FOREFF,
1067	SNAME|SOREG,	TFLOAT,
1068	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1069		0,	0,
1070		"	fstps AL\n", },
1071/* end very important order */
1072
1073{ ASSIGN,	INFL|FOREFF,
1074	SHFL,		TLDOUBLE,
1075	SHFL|SOREG|SNAME,	TLDOUBLE,
1076		0,	RDEST,
1077		"	fldt AR\n", },
1078
1079{ ASSIGN,	INFL|FOREFF,
1080	SHFL,		TDOUBLE,
1081	SHFL|SOREG|SNAME,	TDOUBLE,
1082		0,	RDEST,
1083		"	fldl AR\n", },
1084
1085{ ASSIGN,	INFL|FOREFF,
1086	SHFL,		TFLOAT,
1087	SHFL|SOREG|SNAME,	TFLOAT,
1088		0,	RDEST,
1089		"	flds AR\n", },
1090
1091/* Do not generate memcpy if return from funcall */
1092#if 0
1093{ STASG,	INAREG|FOREFF,
1094	SOREG|SNAME|SAREG,	TPTRTO|TSTRUCT,
1095	SFUNCALL,	TPTRTO|TSTRUCT,
1096		0,	RRIGHT,
1097		"", },
1098#endif
1099
1100{ STASG,	INAREG|FOREFF,
1101	SOREG|SNAME,	TANY,
1102	SAREG,		TPTRTO|TANY,
1103		NSPECIAL|NAREG,	RDEST,
1104		"F	movl %esi,A1\nZQF	movl A1,%esi\n", },
1105
1106/*
1107 * DIV/MOD/MUL
1108 */
1109/* long long div is emulated */
1110{ DIV,	INCREG,
1111	SCREG|SNAME|SOREG|SCON, TLL,
1112	SCREG|SNAME|SOREG|SCON, TLL,
1113		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
1114		"ZO", },
1115
1116{ DIV,	INAREG,
1117	SAREG,			TSWORD,
1118	SAREG|SNAME|SOREG,	TWORD,
1119		NSPECIAL,	RDEST,
1120		"	cltd\n	idivl AR\n", },
1121
1122{ DIV,	INAREG,
1123	SAREG,			TUWORD|TPOINT,
1124	SAREG|SNAME|SOREG,	TUWORD|TPOINT,
1125		NSPECIAL,	RDEST,
1126		"	xorl %edx,%edx\n	divl AR\n", },
1127
1128{ DIV,	INAREG,
1129	SAREG,			TUSHORT,
1130	SAREG|SNAME|SOREG,	TUSHORT,
1131		NSPECIAL,	RDEST,
1132		"	xorl %edx,%edx\n	divw AR\n", },
1133
1134{ DIV,	INCH,
1135	SHCH,			TUCHAR,
1136	SHCH|SNAME|SOREG,	TUCHAR,
1137		NSPECIAL,	RDEST,
1138		"	xorb %ah,%ah\n	divb AR\n", },
1139
1140{ DIV,	INFL,
1141	SHFL,		TDOUBLE,
1142	SNAME|SOREG,	TDOUBLE,
1143		0,	RLEFT,
1144		"	fdivl AR\n", },
1145
1146{ DIV,	INFL,
1147	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
1148	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
1149		0,	RLEFT,
1150		"	fdivZAp\n", },
1151
1152/* (u)longlong mod is emulated */
1153{ MOD,	INCREG,
1154	SCREG|SNAME|SOREG|SCON, TLL,
1155	SCREG|SNAME|SOREG|SCON, TLL,
1156		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
1157		"ZO", },
1158
1159{ MOD,	INAREG,
1160	SAREG,			TSWORD,
1161	SAREG|SNAME|SOREG,	TSWORD,
1162		NAREG|NSPECIAL,	RESC1,
1163		"	cltd\n	idivl AR\n", },
1164
1165{ MOD,	INAREG,
1166	SAREG,			TWORD|TPOINT,
1167	SAREG|SNAME|SOREG,	TUWORD|TPOINT,
1168		NAREG|NSPECIAL,	RESC1,
1169		"	xorl %edx,%edx\n	divl AR\n", },
1170
1171{ MOD,	INAREG,
1172	SAREG,			TUSHORT,
1173	SAREG|SNAME|SOREG,	TUSHORT,
1174		NAREG|NSPECIAL,	RESC1,
1175		"	xorl %edx,%edx\n	divw AR\n", },
1176
1177{ MOD,	INCH,
1178	SHCH,			TUCHAR,
1179	SHCH|SNAME|SOREG,	TUCHAR,
1180		NBREG|NSPECIAL,	RESC1,
1181		"	xorb %ah,%ah\n	divb AR\n", },
1182
1183/* (u)longlong mul is emulated */
1184{ MUL,	INCREG,
1185	SCREG,	TLL,
1186	SCREG,	TLL,
1187		NSPECIAL,	RDEST,
1188		"ZO", },
1189
1190{ MUL,	INAREG,
1191	SAREG,				TWORD|TPOINT,
1192	SAREG|SNAME|SOREG|SCON,		TWORD|TPOINT,
1193		0,	RLEFT,
1194		"	imull AR,AL\n", },
1195
1196{ MUL,	INAREG,
1197	SAREG,			TSHORT|TUSHORT,
1198	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
1199		0,	RLEFT,
1200		"	imulw AR,AL\n", },
1201
1202{ MUL,	INCH,
1203	SHCH,			TCHAR|TUCHAR,
1204	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
1205		NSPECIAL,	RDEST,
1206		"	imulb AR\n", },
1207
1208{ MUL,	INFL,
1209	SHFL,		TDOUBLE,
1210	SNAME|SOREG,	TDOUBLE,
1211		0,	RLEFT,
1212		"	fmull AR\n", },
1213
1214{ MUL,	INFL,
1215	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
1216	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
1217		0,	RLEFT,
1218		"	fmulp\n", },
1219
1220/*
1221 * Indirection operators.
1222 */
1223{ UMUL,	INLL,
1224	SANY,	TANY,
1225	SOREG,	TLL,
1226		NCREG,	RESC1,
1227		"	movl UL,U1\n	movl AL,A1\n", },
1228
1229{ UMUL,	INAREG,
1230	SANY,	TPOINT|TWORD,
1231	SOREG,	TPOINT|TWORD,
1232		NAREG|NASL,	RESC1,
1233		"	movl AL,A1\n", },
1234
1235{ UMUL,	INCH,
1236	SANY,	TANY,
1237	SOREG,	TCHAR|TUCHAR,
1238		NBREG|NBSL,	RESC1,
1239		"	movb AL,A1\n", },
1240
1241{ UMUL,	INAREG,
1242	SANY,	TANY,
1243	SOREG,	TSHORT|TUSHORT,
1244		NAREG|NASL,	RESC1,
1245		"	movw AL,A1\n", },
1246
1247{ UMUL,	INFL,
1248	SANY,	TANY,
1249	SOREG,	TLDOUBLE,
1250		NDREG|NDSL,	RESC1,
1251		"	fldt AL\n", },
1252
1253{ UMUL,	INFL,
1254	SANY,	TANY,
1255	SOREG,	TDOUBLE,
1256		NDREG|NDSL,	RESC1,
1257		"	fldl AL\n", },
1258
1259{ UMUL,	INFL,
1260	SANY,	TANY,
1261	SOREG,	TFLOAT,
1262		NDREG|NDSL,	RESC1,
1263		"	flds AL\n", },
1264
1265/*
1266 * Logical/branching operators
1267 */
1268
1269/* Comparisions, take care of everything */
1270{ OPLOG,	FORCC,
1271	SHLL|SOREG|SNAME,	TLL,
1272	SHLL,			TLL,
1273		0,	0,
1274		"ZD", },
1275
1276{ OPLOG,	FORCC,
1277	SAREG|SOREG|SNAME,	TWORD|TPOINT,
1278	SCON|SAREG,	TWORD|TPOINT,
1279		0, 	RESCC,
1280		"	cmpl AR,AL\n", },
1281
1282#if 0
1283{ OPLOG,	FORCC,
1284	SCON|SAREG,	TWORD|TPOINT,
1285	SAREG|SOREG|SNAME,	TWORD|TPOINT,
1286		0, 	RESCC,
1287		"	cmpl AR,AL\n", },
1288#endif
1289
1290{ OPLOG,	FORCC,
1291	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
1292	SCON|SAREG,	TANY,
1293		0, 	RESCC,
1294		"	cmpw AR,AL\n", },
1295
1296{ OPLOG,	FORCC,
1297	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
1298	SCON|SBREG,	TANY,
1299		0, 	RESCC,
1300		"	cmpb AR,AL\n", },
1301
1302{ OPLOG,	FORCC,
1303	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
1304	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
1305		NSPECIAL, 	RNOP,
1306		"ZG", },
1307
1308{ OPLOG,	FORCC,
1309	SANY,	TANY,
1310	SANY,	TANY,
1311		REWRITE,	0,
1312		"diediedie!", },
1313
1314/* AND/OR/ER/NOT */
1315{ AND,	INAREG|FOREFF,
1316	SAREG|SOREG|SNAME,	TWORD,
1317	SCON|SAREG,		TWORD,
1318		0,	RLEFT,
1319		"	andl AR,AL\n", },
1320
1321{ AND,	INCREG|FOREFF,
1322	SCREG,			TLL,
1323	SCREG|SOREG|SNAME,	TLL,
1324		0,	RLEFT,
1325		"	andl AR,AL\n	andl UR,UL\n", },
1326
1327{ AND,	INAREG|FOREFF,
1328	SAREG,			TWORD,
1329	SAREG|SOREG|SNAME,	TWORD,
1330		0,	RLEFT,
1331		"	andl AR,AL\n", },
1332
1333{ AND,	INAREG|FOREFF,
1334	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
1335	SCON|SAREG,		TSHORT|TUSHORT,
1336		0,	RLEFT,
1337		"	andw AR,AL\n", },
1338
1339{ AND,	INAREG|FOREFF,
1340	SAREG,			TSHORT|TUSHORT,
1341	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
1342		0,	RLEFT,
1343		"	andw AR,AL\n", },
1344
1345{ AND,	INBREG|FOREFF,
1346	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
1347	SCON|SBREG,		TCHAR|TUCHAR,
1348		0,	RLEFT,
1349		"	andb AR,AL\n", },
1350
1351{ AND,	INBREG|FOREFF,
1352	SBREG,			TCHAR|TUCHAR,
1353	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
1354		0,	RLEFT,
1355		"	andb AR,AL\n", },
1356/* AND/OR/ER/NOT */
1357
1358/*
1359 * Jumps.
1360 */
1361{ GOTO, 	FOREFF,
1362	SCON,	TANY,
1363	SANY,	TANY,
1364		0,	RNOP,
1365		"	jmp LL\n", },
1366
1367#if defined(GCC_COMPAT) || defined(LANG_F77)
1368{ GOTO, 	FOREFF,
1369	SAREG,	TANY,
1370	SANY,	TANY,
1371		0,	RNOP,
1372		"	jmp *AL\n", },
1373#endif
1374
1375/*
1376 * Convert LTYPE to reg.
1377 */
1378{ OPLTYPE,	FORCC|INLL,
1379	SCREG,	TLL,
1380	SMIXOR,	TANY,
1381		NCREG,	RESC1,
1382		"	xorl U1,U1\n	xorl A1,A1\n", },
1383
1384{ OPLTYPE,	FORCC|INLL,
1385	SCREG,	TLL,
1386	SMILWXOR,	TANY,
1387		NCREG,	RESC1,
1388		"	movl UL,U1\n	xorl A1,A1\n", },
1389
1390{ OPLTYPE,	FORCC|INLL,
1391	SCREG,	TLL,
1392	SMIHWXOR,	TANY,
1393		NCREG,	RESC1,
1394		"	xorl U1,U1\n	movl AL,A1\n", },
1395
1396{ OPLTYPE,	INLL,
1397	SANY,	TANY,
1398	SCREG,	TLL,
1399		NCREG,	RESC1,
1400		"ZK", },
1401
1402{ OPLTYPE,	INLL,
1403	SANY,	TANY,
1404	SCON|SOREG|SNAME,	TLL,
1405		NCREG,	RESC1,
1406		"	movl UL,U1\n	movl AL,A1\n", },
1407
1408{ OPLTYPE,	FORCC|INAREG,
1409	SAREG,	TWORD|TPOINT,
1410	SMIXOR,	TANY,
1411		NAREG|NASL,	RESC1,
1412		"	xorl A1,A1\n", },
1413
1414{ OPLTYPE,	INAREG,
1415	SANY,	TANY,
1416	SAREG|SCON|SOREG|SNAME,	TWORD|TPOINT,
1417		NAREG|NASL,	RESC1,
1418		"	movl AL,A1\n", },
1419
1420{ OPLTYPE,	INBREG,
1421	SANY,	TANY,
1422	SBREG|SOREG|SNAME|SCON,	TCHAR|TUCHAR,
1423		NBREG,	RESC1,
1424		"	movb AL,A1\n", },
1425
1426{ OPLTYPE,	FORCC|INAREG,
1427	SAREG,	TSHORT|TUSHORT,
1428	SMIXOR,	TANY,
1429		NAREG,	RESC1,
1430		"	xorw A1,A1\n", },
1431
1432{ OPLTYPE,	INAREG,
1433	SANY,	TANY,
1434	SAREG|SOREG|SNAME|SCON,	TSHORT|TUSHORT,
1435		NAREG,	RESC1,
1436		"	movw AL,A1\n", },
1437
1438{ OPLTYPE,	INDREG,
1439	SANY,		TLDOUBLE,
1440	SOREG|SNAME,	TLDOUBLE,
1441		NDREG,	RESC1,
1442		"	fldt AL\n", },
1443
1444{ OPLTYPE,	INDREG,
1445	SANY,		TDOUBLE,
1446	SOREG|SNAME,	TDOUBLE,
1447		NDREG,	RESC1,
1448		"	fldl AL\n", },
1449
1450{ OPLTYPE,	INDREG,
1451	SANY,		TFLOAT,
1452	SOREG|SNAME,	TFLOAT,
1453		NDREG,	RESC1,
1454		"	flds AL\n", },
1455
1456/* Only used in ?: constructs. The stack already contains correct value */
1457{ OPLTYPE,	INDREG,
1458	SANY,	TFLOAT|TDOUBLE|TLDOUBLE,
1459	SDREG,	TFLOAT|TDOUBLE|TLDOUBLE,
1460		NDREG,	RESC1,
1461		"", },
1462
1463/*
1464 * Negate a word.
1465 */
1466
1467{ UMINUS,	INCREG|FOREFF,
1468	SCREG,	TLL,
1469	SCREG,	TLL,
1470		0,	RLEFT,
1471		"	negl AL\n	adcl $0,UL\n	negl UL\n", },
1472
1473{ UMINUS,	INAREG|FOREFF,
1474	SAREG,	TWORD|TPOINT,
1475	SAREG,	TWORD|TPOINT,
1476		0,	RLEFT,
1477		"	negl AL\n", },
1478
1479{ UMINUS,	INAREG|FOREFF,
1480	SAREG,	TSHORT|TUSHORT,
1481	SAREG,	TSHORT|TUSHORT,
1482		0,	RLEFT,
1483		"	negw AL\n", },
1484
1485{ UMINUS,	INBREG|FOREFF,
1486	SBREG,	TCHAR|TUCHAR,
1487	SBREG,	TCHAR|TUCHAR,
1488		0,	RLEFT,
1489		"	negb AL\n", },
1490
1491{ UMINUS,	INFL|FOREFF,
1492	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
1493	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
1494		0,	RLEFT,
1495		"	fchs\n", },
1496
1497{ COMPL,	INCREG,
1498	SCREG,	TLL,
1499	SANY,	TANY,
1500		0,	RLEFT,
1501		"	notl AL\n	notl UL\n", },
1502
1503{ COMPL,	INAREG,
1504	SAREG,	TWORD,
1505	SANY,	TANY,
1506		0,	RLEFT,
1507		"	notl AL\n", },
1508
1509{ COMPL,	INAREG,
1510	SAREG,	TSHORT|TUSHORT,
1511	SANY,	TANY,
1512		0,	RLEFT,
1513		"	notw AL\n", },
1514
1515{ COMPL,	INBREG,
1516	SBREG,	TCHAR|TUCHAR,
1517	SANY,	TANY,
1518		0,	RLEFT,
1519		"	notb AL\n", },
1520
1521/*
1522 * Arguments to functions.
1523 */
1524{ FUNARG,	FOREFF,
1525	SCON|SCREG|SNAME|SOREG,	TLL,
1526	SANY,	TLL,
1527		0,	RNULL,
1528		"	pushl UL\n	pushl AL\n", },
1529
1530{ FUNARG,	FOREFF,
1531	SCON|SAREG|SNAME|SOREG,	TWORD|TPOINT,
1532	SANY,	TWORD|TPOINT,
1533		0,	RNULL,
1534		"	pushl AL\n", },
1535
1536{ FUNARG,	FOREFF,
1537	SCON,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
1538	SANY,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
1539		0,	RNULL,
1540		"	pushl AL\n", },
1541
1542{ FUNARG,	FOREFF,
1543	SAREG|SNAME|SOREG,	TSHORT,
1544	SANY,	TSHORT,
1545		NAREG,	0,
1546		"	movswl AL,ZN\n	pushl ZN\n", },
1547
1548{ FUNARG,	FOREFF,
1549	SAREG|SNAME|SOREG,	TUSHORT,
1550	SANY,	TUSHORT,
1551		NAREG,	0,
1552		"	movzwl AL,ZN\n	pushl ZN\n", },
1553
1554{ FUNARG,	FOREFF,
1555	SHCH|SNAME|SOREG,	TCHAR,
1556	SANY,			TCHAR,
1557		NAREG,	0,
1558		"	movsbl AL,A1\n	pushl A1\n", },
1559
1560{ FUNARG,	FOREFF,
1561	SHCH|SNAME|SOREG,	TUCHAR,
1562	SANY,	TUCHAR,
1563		NAREG,	0,
1564		"	movzbl AL,A1\n	pushl A1\n", },
1565
1566{ FUNARG,	FOREFF,
1567	SNAME|SOREG,	TDOUBLE,
1568	SANY,	TDOUBLE,
1569		0,	0,
1570		"	pushl UL\n	pushl AL\n", },
1571
1572{ FUNARG,	FOREFF,
1573	SDREG,	TDOUBLE,
1574	SANY,		TDOUBLE,
1575		0,	0,
1576		"	subl $8,%esp\n	fstpl (%esp)\n", },
1577
1578{ FUNARG,	FOREFF,
1579	SNAME|SOREG,	TFLOAT,
1580	SANY,		TFLOAT,
1581		0,	0,
1582		"	pushl AL\n", },
1583
1584{ FUNARG,	FOREFF,
1585	SDREG,	TFLOAT,
1586	SANY,		TFLOAT,
1587		0,	0,
1588		"	subl $4,%esp\n	fstps (%esp)\n", },
1589
1590{ FUNARG,	FOREFF,
1591	SDREG,	TLDOUBLE,
1592	SANY,		TLDOUBLE,
1593		0,	0,
1594		"	subl $12,%esp\n	fstpt (%esp)\n", },
1595
1596{ STARG,	FOREFF,
1597	SAREG,	TPTRTO|TSTRUCT,
1598	SANY,	TSTRUCT,
1599		NSPECIAL,	0,
1600		"ZF", },
1601
1602# define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
1603
1604{ UMUL, DF( UMUL ), },
1605
1606{ ASSIGN, DF(ASSIGN), },
1607
1608{ STASG, DF(STASG), },
1609
1610{ FLD, DF(FLD), },
1611
1612{ OPLEAF, DF(NAME), },
1613
1614/* { INIT, DF(INIT), }, */
1615
1616{ OPUNARY, DF(UMINUS), },
1617
1618{ OPANY, DF(BITYPE), },
1619
1620{ FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	"help; I'm in trouble\n" },
1621};
1622
1623int tablesize = sizeof(table)/sizeof(table[0]);
1624