xref: /netbsd-src/external/bsd/pcc/dist/pcc/arch/i386/table.c (revision 411dcbec990c8aa9c57d3bd2f4bcacadec0b1ab5)
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 
49 struct 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 
1623 int tablesize = sizeof(table)/sizeof(table[0]);
1624