xref: /netbsd-src/external/bsd/pcc/dist/pcc/arch/i386/table.c (revision 4391d5e9d4f291db41e3b3ba26a01b5e51364aae)
1 /*	Id: table.c,v 1.137 2011/08/06 15:11:48 ragge Exp 	*/
2 /*	$NetBSD: table.c,v 1.1.1.4 2011/09/01 12:46:36 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,
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 $15,1(%esp)\n"	/* 64-bit prec */
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 /* struct return */
574 { USTCALL,	FOREFF,
575 	SCON,	TANY,
576 	SANY,	TANY,
577 		NAREG|NASL,	0,
578 		"ZP	call CL\nZC", },
579 
580 { USTCALL,	INAREG,
581 	SCON,	TANY,
582 	SANY,	TANY,
583 		NAREG|NASL,	RESC1,	/* should be 0 */
584 		"ZP	call CL\nZC", },
585 
586 { USTCALL,	INAREG,
587 	SNAME|SAREG,	TANY,
588 	SANY,	TANY,
589 		NAREG|NASL,	RESC1,	/* should be 0 */
590 		"ZP	call *AL\nZC", },
591 
592 { STCALL,	FOREFF,
593 	SCON,	TANY,
594 	SANY,	TANY,
595 		NAREG|NASL,	0,
596 		"ZP	call CL\nZC", },
597 
598 { STCALL,	INAREG,
599 	SCON,	TANY,
600 	SANY,	TANY,
601 		NAREG|NASL,	RESC1,	/* should be 0 */
602 		"ZP	call CL\nZC", },
603 
604 { STCALL,	INAREG,
605 	SNAME|SAREG,	TANY,
606 	SANY,	TANY,
607 		NAREG|NASL,	RESC1,	/* should be 0 */
608 		"ZP	call *AL\nZC", },
609 
610 /*
611  * The next rules handle all binop-style operators.
612  */
613 /* Special treatment for long long */
614 { PLUS,		INLL|FOREFF,
615 	SHLL,		TLL,
616 	SHLL|SNAME|SOREG,	TLL,
617 		0,	RLEFT,
618 		"	addl AR,AL\n	adcl UR,UL\n", },
619 
620 { PLUS,		INLL|FOREFF,
621 	SHLL|SNAME|SOREG,	TLL,
622 	SHLL|SCON,		TLL,
623 		0,	RLEFT,
624 		"	addl AR,AL\n	adcl UR,UL\n", },
625 
626 /* Special treatment for long long  XXX - fix commutative check */
627 { PLUS,		INLL|FOREFF,
628 	SHLL|SNAME|SOREG,	TLL,
629 	SHLL,			TLL,
630 		0,	RRIGHT,
631 		"	addl AL,AR\n	adcl UL,UR\n", },
632 
633 { PLUS,		INFL,
634 	SHFL,		TDOUBLE,
635 	SNAME|SOREG,	TDOUBLE,
636 		0,	RLEFT,
637 		"	faddl AR\n", },
638 
639 { PLUS,		INFL|FOREFF,
640 	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
641 	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
642 		0,	RLEFT,
643 		"	faddp\n", },
644 
645 { PLUS,		INAREG|FOREFF,
646 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
647 	SONE,	TANY,
648 		0,	RLEFT,
649 		"	incl AL\n", },
650 
651 { PLUS,		INAREG|FOREFF,
652 	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
653 	SONE,	TANY,
654 		0,	RLEFT,
655 		"	incw AL\n", },
656 
657 { PLUS,		INCH|FOREFF,
658 	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
659 	SONE,	TANY,
660 		0,	RLEFT,
661 		"	incb AL\n", },
662 
663 { PLUS,		INAREG,
664 	SAREG,	TWORD,
665 	SAREG,	TWORD,
666 		NAREG|NASL|NASR,	RESC1,
667 		"	leal (AL,AR),A1\n", },
668 
669 { MINUS,	INAREG|FOREFF,
670 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
671 	SONE,			TANY,
672 		0,	RLEFT,
673 		"	decl AL\n", },
674 
675 { MINUS,	INAREG|FOREFF,
676 	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
677 	SONE,			TANY,
678 		0,	RLEFT,
679 		"	decw AL\n", },
680 
681 { MINUS,	INCH|FOREFF,
682 	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
683 	SONE,	TANY,
684 		0,	RLEFT,
685 		"	decb AL\n", },
686 
687 /* address as register offset, negative */
688 { MINUS,	INLL|FOREFF,
689 	SHLL,	TLL,
690 	SHLL|SNAME|SOREG,	TLL,
691 		0,	RLEFT,
692 		"	subl AR,AL\n	sbbl UR,UL\n", },
693 
694 { MINUS,	INLL|FOREFF,
695 	SHLL|SNAME|SOREG,	TLL,
696 	SHLL|SCON,	TLL,
697 		0,	RLEFT,
698 		"	subl AR,AL\n	sbbl UR,UL\n", },
699 
700 { MINUS,	INFL,
701 	SHFL,	TDOUBLE,
702 	SNAME|SOREG,	TDOUBLE,
703 		0,	RLEFT,
704 		"	fsubl AR\n", },
705 
706 { MINUS,	INFL|FOREFF,
707 	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
708 	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
709 		0,	RLEFT,
710 		"	fsubZAp\n", },
711 
712 /* Simple r/m->reg ops */
713 /* m/r |= r */
714 { OPSIMP,	INAREG|FOREFF|FORCC,
715 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
716 	SAREG,			TWORD|TPOINT,
717 		0,	RLEFT|RESCC,
718 		"	Ol AR,AL\n", },
719 
720 /* r |= r/m */
721 { OPSIMP,	INAREG|FOREFF|FORCC,
722 	SAREG,			TWORD|TPOINT,
723 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
724 		0,	RLEFT|RESCC,
725 		"	Ol AR,AL\n", },
726 
727 /* m/r |= r */
728 { OPSIMP,	INAREG|FOREFF|FORCC,
729 	SHINT|SNAME|SOREG,	TSHORT|TUSHORT,
730 	SHINT,		TSHORT|TUSHORT,
731 		0,	RLEFT|RESCC,
732 		"	Ow AR,AL\n", },
733 
734 /* r |= r/m */
735 { OPSIMP,	INAREG|FOREFF|FORCC,
736 	SHINT,		TSHORT|TUSHORT,
737 	SHINT|SNAME|SOREG,	TSHORT|TUSHORT,
738 		0,	RLEFT|RESCC,
739 		"	Ow AR,AL\n", },
740 
741 /* m/r |= r */
742 { OPSIMP,	INCH|FOREFF|FORCC,
743 	SHCH,		TCHAR|TUCHAR,
744 	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
745 		0,	RLEFT|RESCC,
746 		"	Ob AR,AL\n", },
747 
748 /* r |= r/m */
749 { OPSIMP,	INCH|FOREFF|FORCC,
750 	SHCH,		TCHAR|TUCHAR,
751 	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
752 		0,	RLEFT|RESCC,
753 		"	Ob AR,AL\n", },
754 
755 /* m/r |= const */
756 { OPSIMP,	INAREG|FOREFF|FORCC,
757 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
758 	SCON,	TWORD|TPOINT,
759 		0,	RLEFT|RESCC,
760 		"	Ol AR,AL\n", },
761 
762 { OPSIMP,	INAREG|FOREFF|FORCC,
763 	SHINT|SNAME|SOREG,	TSHORT|TUSHORT,
764 	SCON,	TANY,
765 		0,	RLEFT|RESCC,
766 		"	Ow AR,AL\n", },
767 
768 { OPSIMP,	INCH|FOREFF|FORCC,
769 	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
770 	SCON,	TANY,
771 		0,	RLEFT|RESCC,
772 		"	Ob AR,AL\n", },
773 
774 /* r |= r/m */
775 { OPSIMP,	INLL|FOREFF,
776 	SHLL,	TLL,
777 	SHLL|SNAME|SOREG,	TLL,
778 		0,	RLEFT,
779 		"	Ol AR,AL\n	Ol UR,UL\n", },
780 
781 /* m/r |= r/const */
782 { OPSIMP,	INLL|FOREFF,
783 	SHLL|SNAME|SOREG,	TLL,
784 	SHLL|SCON,	TLL,
785 		0,	RLEFT,
786 		"	Ol AR,AL\n	Ol UR,UL\n", },
787 
788 /* Try use-reg instructions first */
789 { PLUS,		INAREG,
790 	SAREG,	TWORD|TPOINT,
791 	SCON,	TANY,
792 		NAREG|NASL,	RESC1,
793 		"	leal CR(AL),A1\n", },
794 
795 { MINUS,	INAREG,
796 	SAREG,	TWORD|TPOINT,
797 	SPCON,	TANY,
798 		NAREG|NASL,	RESC1,
799 		"	leal -CR(AL),A1\n", },
800 
801 
802 /*
803  * The next rules handle all shift operators.
804  */
805 /* (u)longlong left shift is emulated */
806 { LS,	INCREG,
807 	SCREG,	TLL,
808 	SHCH,	TCHAR|TUCHAR,
809 		NSPECIAL,	RLEFT,
810 		"ZO", },
811 
812 /* r/m <<= r */
813 { LS,	INAREG|FOREFF,
814 	SAREG|SNAME|SOREG,	TWORD,
815 	SHCH,		TCHAR|TUCHAR,
816 		NSPECIAL,	RLEFT,
817 		"	sall AR,AL\n", },
818 
819 /* r/m <<= const */
820 { LS,	INAREG|FOREFF,
821 	SAREG|SNAME|SOREG,	TWORD,
822 	SCON,	TANY,
823 		0,	RLEFT,
824 		"	sall AR,AL\n", },
825 
826 /* r/m <<= r */
827 { LS,	INAREG|FOREFF,
828 	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
829 	SHCH,			TCHAR|TUCHAR,
830 		NSPECIAL,	RLEFT,
831 		"	shlw AR,AL\n", },
832 
833 /* r/m <<= const */
834 { LS,	INAREG|FOREFF,
835 	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
836 	SCON,	TANY,
837 		0,	RLEFT,
838 		"	shlw AR,AL\n", },
839 
840 { LS,	INCH|FOREFF,
841 	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
842 	SHCH,			TCHAR|TUCHAR,
843 		NSPECIAL,	RLEFT,
844 		"	salb AR,AL\n", },
845 
846 { LS,	INCH|FOREFF,
847 	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
848 	SCON,			TANY,
849 		0,	RLEFT,
850 		"	salb AR,AL\n", },
851 
852 /* (u)longlong right shift is emulated */
853 { RS,	INCREG,
854 	SCREG,	TLL,
855 	SHCH,	TCHAR|TUCHAR,
856 		NSPECIAL,	RLEFT,
857 		"ZO", },
858 
859 { RS,	INAREG|FOREFF,
860 	SAREG|SNAME|SOREG,	TSWORD,
861 	SHCH,			TCHAR|TUCHAR,
862 		NSPECIAL,	RLEFT,
863 		"	sarl AR,AL\n", },
864 
865 { RS,	INAREG|FOREFF,
866 	SAREG|SNAME|SOREG,	TSWORD,
867 	SCON,			TANY,
868 		0,		RLEFT,
869 		"	sarl AR,AL\n", },
870 
871 { RS,	INAREG|FOREFF,
872 	SAREG|SNAME|SOREG,	TUWORD,
873 	SHCH,			TCHAR|TUCHAR,
874 		NSPECIAL,	RLEFT,
875 		"	shrl AR,AL\n", },
876 
877 { RS,	INAREG|FOREFF,
878 	SAREG|SNAME|SOREG,	TUWORD,
879 	SCON,			TANY,
880 		0,		RLEFT,
881 		"	shrl AR,AL\n", },
882 
883 { RS,	INAREG|FOREFF,
884 	SAREG|SNAME|SOREG,	TSHORT,
885 	SHCH,			TCHAR|TUCHAR,
886 		NSPECIAL,	RLEFT,
887 		"	sarw AR,AL\n", },
888 
889 { RS,	INAREG|FOREFF,
890 	SAREG|SNAME|SOREG,	TSHORT,
891 	SCON,			TANY,
892 		0,		RLEFT,
893 		"	sarw AR,AL\n", },
894 
895 { RS,	INAREG|FOREFF,
896 	SAREG|SNAME|SOREG,	TUSHORT,
897 	SHCH,			TCHAR|TUCHAR,
898 		NSPECIAL,	RLEFT,
899 		"	shrw AR,AL\n", },
900 
901 { RS,	INAREG|FOREFF,
902 	SAREG|SNAME|SOREG,	TUSHORT,
903 	SCON,			TANY,
904 		0,		RLEFT,
905 		"	shrw AR,AL\n", },
906 
907 { RS,	INCH|FOREFF,
908 	SHCH|SNAME|SOREG,	TCHAR,
909 	SHCH,			TCHAR|TUCHAR,
910 		NSPECIAL,	RLEFT,
911 		"	sarb AR,AL\n", },
912 
913 { RS,	INCH|FOREFF,
914 	SHCH|SNAME|SOREG,	TCHAR,
915 	SCON,			TANY,
916 		0,		RLEFT,
917 		"	sarb AR,AL\n", },
918 
919 { RS,	INCH|FOREFF,
920 	SHCH|SNAME|SOREG,	TUCHAR,
921 	SHCH,			TCHAR|TUCHAR,
922 		NSPECIAL,	RLEFT,
923 		"	shrb AR,AL\n", },
924 
925 { RS,	INCH|FOREFF,
926 	SHCH|SNAME|SOREG,	TUCHAR,
927 	SCON,			TANY,
928 		0,		RLEFT,
929 		"	shrb AR,AL\n", },
930 
931 /*
932  * The next rules takes care of assignments. "=".
933  */
934 { ASSIGN,	FORCC|FOREFF|INLL,
935 	SHLL,		TLL,
936 	SMIXOR,		TANY,
937 		0,	RDEST,
938 		"	xorl AL,AL\n	xorl UL,UL\n", },
939 
940 { ASSIGN,	FORCC|FOREFF|INLL,
941 	SHLL,		TLL,
942 	SMILWXOR,	TANY,
943 		0,	RDEST,
944 		"	xorl AL,AL\n	movl UR,UL\n", },
945 
946 { ASSIGN,	FORCC|FOREFF|INLL,
947 	SHLL,		TLL,
948 	SMIHWXOR,	TANY,
949 		0,	RDEST,
950 		"	movl AR,AL\n	xorl UL,UL\n", },
951 
952 { ASSIGN,	FOREFF|INLL,
953 	SHLL,		TLL,
954 	SCON,		TANY,
955 		0,	RDEST,
956 		"	movl AR,AL\n	movl UR,UL\n", },
957 
958 { ASSIGN,	FOREFF,
959 	SHLL|SNAME|SOREG,	TLL,
960 	SCON,		TANY,
961 		0,	0,
962 		"	movl AR,AL\n	movl UR,UL\n", },
963 
964 { ASSIGN,	FORCC|FOREFF|INAREG,
965 	SAREG,	TWORD|TPOINT,
966 	SMIXOR,		TANY,
967 		0,	RDEST,
968 		"	xorl AL,AL\n", },
969 
970 { ASSIGN,	FOREFF,
971 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
972 	SCON,		TANY,
973 		0,	0,
974 		"	movl AR,AL\n", },
975 
976 { ASSIGN,	FOREFF|INAREG,
977 	SAREG,	TWORD|TPOINT,
978 	SCON,		TANY,
979 		0,	RDEST,
980 		"	movl AR,AL\n", },
981 
982 { ASSIGN,	FORCC|FOREFF|INAREG,
983 	SAREG,	TSHORT|TUSHORT,
984 	SMIXOR,		TANY,
985 		0,	RDEST,
986 		"	xorw AL,AL\n", },
987 
988 { ASSIGN,	FOREFF,
989 	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
990 	SCON,		TANY,
991 		0,	0,
992 		"	movw AR,AL\n", },
993 
994 { ASSIGN,	FOREFF|INAREG,
995 	SAREG,	TSHORT|TUSHORT,
996 	SCON,		TANY,
997 		0,	RDEST,
998 		"	movw AR,AL\n", },
999 
1000 { ASSIGN,	FOREFF,
1001 	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
1002 	SCON,		TANY,
1003 		0,	0,
1004 		"	movb AR,AL\n", },
1005 
1006 { ASSIGN,	FOREFF|INCH,
1007 	SHCH,		TCHAR|TUCHAR,
1008 	SCON,		TANY,
1009 		0,	RDEST,
1010 		"	movb AR,AL\n", },
1011 
1012 { ASSIGN,	FOREFF|INLL,
1013 	SNAME|SOREG,	TLL,
1014 	SHLL,		TLL,
1015 		0,	RDEST,
1016 		"	movl AR,AL\n	movl UR,UL\n", },
1017 
1018 { ASSIGN,	FOREFF|INLL,
1019 	SHLL,	TLL,
1020 	SHLL,	TLL,
1021 		0,	RDEST,
1022 		"ZH", },
1023 
1024 { ASSIGN,	FOREFF|INAREG,
1025 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
1026 	SAREG,		TWORD|TPOINT,
1027 		0,	RDEST,
1028 		"	movl AR,AL\n", },
1029 
1030 { ASSIGN,	FOREFF|INAREG,
1031 	SAREG,			TWORD|TPOINT,
1032 	SAREG|SNAME|SOREG,	TWORD|TPOINT,
1033 		0,	RDEST,
1034 		"	movl AR,AL\n", },
1035 
1036 { ASSIGN,	FOREFF|INAREG,
1037 	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
1038 	SAREG,		TSHORT|TUSHORT,
1039 		0,	RDEST,
1040 		"	movw AR,AL\n", },
1041 
1042 { ASSIGN,	FOREFF|INCH,
1043 	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
1044 	SHCH,		TCHAR|TUCHAR|TWORD,
1045 		0,	RDEST,
1046 		"	movb AR,AL\n", },
1047 
1048 { ASSIGN,	INDREG|FOREFF,
1049 	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1050 	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1051 		0,	RDEST,
1052 		"", }, /* This will always be in the correct register */
1053 
1054 /* order of table entries is very important here! */
1055 { ASSIGN,	INFL,
1056 	SNAME|SOREG,	TLDOUBLE,
1057 	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1058 		0,	RDEST,
1059 		"	fstpt AL\n	fldt AL\n", }, /* XXX */
1060 
1061 { ASSIGN,	FOREFF,
1062 	SNAME|SOREG,	TLDOUBLE,
1063 	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1064 		0,	0,
1065 		"	fstpt AL\n", },
1066 
1067 { ASSIGN,	INFL,
1068 	SNAME|SOREG,	TDOUBLE,
1069 	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1070 		0,	RDEST,
1071 		"	fstl AL\n", },
1072 
1073 { ASSIGN,	FOREFF,
1074 	SNAME|SOREG,	TDOUBLE,
1075 	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1076 		0,	0,
1077 		"	fstpl AL\n", },
1078 
1079 { ASSIGN,	INFL,
1080 	SNAME|SOREG,	TFLOAT,
1081 	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1082 		0,	RDEST,
1083 		"	fsts AL\n", },
1084 
1085 { ASSIGN,	FOREFF,
1086 	SNAME|SOREG,	TFLOAT,
1087 	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
1088 		0,	0,
1089 		"	fstps AL\n", },
1090 /* end very important order */
1091 
1092 { ASSIGN,	INFL|FOREFF,
1093 	SHFL,		TLDOUBLE,
1094 	SHFL|SOREG|SNAME,	TLDOUBLE,
1095 		0,	RDEST,
1096 		"	fldt AR\n", },
1097 
1098 { ASSIGN,	INFL|FOREFF,
1099 	SHFL,		TDOUBLE,
1100 	SHFL|SOREG|SNAME,	TDOUBLE,
1101 		0,	RDEST,
1102 		"	fldl AR\n", },
1103 
1104 { ASSIGN,	INFL|FOREFF,
1105 	SHFL,		TFLOAT,
1106 	SHFL|SOREG|SNAME,	TFLOAT,
1107 		0,	RDEST,
1108 		"	flds AR\n", },
1109 
1110 /* Do not generate memcpy if return from funcall */
1111 #if 0
1112 { STASG,	INAREG|FOREFF,
1113 	SOREG|SNAME|SAREG,	TPTRTO|TSTRUCT,
1114 	SFUNCALL,	TPTRTO|TSTRUCT,
1115 		0,	RRIGHT,
1116 		"", },
1117 #endif
1118 
1119 { STASG,	INAREG|FOREFF,
1120 	SOREG|SNAME,	TANY,
1121 	SAREG,		TPTRTO|TANY,
1122 		NSPECIAL,	RDEST,
1123 		"ZQ", },
1124 
1125 /*
1126  * DIV/MOD/MUL
1127  */
1128 /* long long div is emulated */
1129 { DIV,	INCREG,
1130 	SCREG|SNAME|SOREG|SCON, TLL,
1131 	SCREG|SNAME|SOREG|SCON, TLL,
1132 		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
1133 		"ZO", },
1134 
1135 { DIV,	INAREG,
1136 	SAREG,			TSWORD,
1137 	SAREG|SNAME|SOREG,	TWORD,
1138 		NSPECIAL,	RDEST,
1139 		"	cltd\n	idivl AR\n", },
1140 
1141 { DIV,	INAREG,
1142 	SAREG,			TUWORD|TPOINT,
1143 	SAREG|SNAME|SOREG,	TUWORD|TPOINT,
1144 		NSPECIAL,	RDEST,
1145 		"	xorl %edx,%edx\n	divl AR\n", },
1146 
1147 { DIV,	INAREG,
1148 	SAREG,			TUSHORT,
1149 	SAREG|SNAME|SOREG,	TUSHORT,
1150 		NSPECIAL,	RDEST,
1151 		"	xorl %edx,%edx\n	divw AR\n", },
1152 
1153 { DIV,	INCH,
1154 	SHCH,			TUCHAR,
1155 	SHCH|SNAME|SOREG,	TUCHAR,
1156 		NSPECIAL,	RDEST,
1157 		"	xorb %ah,%ah\n	divb AR\n", },
1158 
1159 { DIV,	INFL,
1160 	SHFL,		TDOUBLE,
1161 	SNAME|SOREG,	TDOUBLE,
1162 		0,	RLEFT,
1163 		"	fdivl AR\n", },
1164 
1165 { DIV,	INFL,
1166 	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
1167 	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
1168 		0,	RLEFT,
1169 		"	fdivZAp\n", },
1170 
1171 /* (u)longlong mod is emulated */
1172 { MOD,	INCREG,
1173 	SCREG|SNAME|SOREG|SCON, TLL,
1174 	SCREG|SNAME|SOREG|SCON, TLL,
1175 		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
1176 		"ZO", },
1177 
1178 { MOD,	INAREG,
1179 	SAREG,			TSWORD,
1180 	SAREG|SNAME|SOREG,	TSWORD,
1181 		NAREG|NSPECIAL,	RESC1,
1182 		"	cltd\n	idivl AR\n", },
1183 
1184 { MOD,	INAREG,
1185 	SAREG,			TWORD|TPOINT,
1186 	SAREG|SNAME|SOREG,	TUWORD|TPOINT,
1187 		NAREG|NSPECIAL,	RESC1,
1188 		"	xorl %edx,%edx\n	divl AR\n", },
1189 
1190 { MOD,	INAREG,
1191 	SAREG,			TUSHORT,
1192 	SAREG|SNAME|SOREG,	TUSHORT,
1193 		NAREG|NSPECIAL,	RESC1,
1194 		"	xorl %edx,%edx\n	divw AR\n", },
1195 
1196 { MOD,	INCH,
1197 	SHCH,			TUCHAR,
1198 	SHCH|SNAME|SOREG,	TUCHAR,
1199 		NBREG|NSPECIAL,	RESC1,
1200 		"	xorb %ah,%ah\n	divb AR\n", },
1201 
1202 /* (u)longlong mul is emulated */
1203 { MUL,	INCREG,
1204 	SCREG,	TLL,
1205 	SCREG,	TLL,
1206 		NSPECIAL,	RDEST,
1207 		"ZO", },
1208 
1209 { MUL,	INAREG,
1210 	SAREG,				TWORD|TPOINT,
1211 	SAREG|SNAME|SOREG|SCON,		TWORD|TPOINT,
1212 		0,	RLEFT,
1213 		"	imull AR,AL\n", },
1214 
1215 { MUL,	INAREG,
1216 	SAREG,			TSHORT|TUSHORT,
1217 	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
1218 		0,	RLEFT,
1219 		"	imulw AR,AL\n", },
1220 
1221 { MUL,	INCH,
1222 	SHCH,			TCHAR|TUCHAR,
1223 	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
1224 		NSPECIAL,	RDEST,
1225 		"	imulb AR\n", },
1226 
1227 { MUL,	INFL,
1228 	SHFL,		TDOUBLE,
1229 	SNAME|SOREG,	TDOUBLE,
1230 		0,	RLEFT,
1231 		"	fmull AR\n", },
1232 
1233 { MUL,	INFL,
1234 	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
1235 	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
1236 		0,	RLEFT,
1237 		"	fmulp\n", },
1238 
1239 /*
1240  * Indirection operators.
1241  */
1242 { UMUL,	INLL,
1243 	SANY,	TANY,
1244 	SOREG,	TLL,
1245 		NCREG,	RESC1,
1246 		"	movl UL,U1\n	movl AL,A1\n", },
1247 
1248 { UMUL,	INAREG,
1249 	SANY,	TPOINT|TWORD,
1250 	SOREG,	TPOINT|TWORD,
1251 		NAREG|NASL,	RESC1,
1252 		"	movl AL,A1\n", },
1253 
1254 { UMUL,	INCH,
1255 	SANY,	TANY,
1256 	SOREG,	TCHAR|TUCHAR,
1257 		NBREG|NBSL,	RESC1,
1258 		"	movb AL,A1\n", },
1259 
1260 { UMUL,	INAREG,
1261 	SANY,	TANY,
1262 	SOREG,	TSHORT|TUSHORT,
1263 		NAREG|NASL,	RESC1,
1264 		"	movw AL,A1\n", },
1265 
1266 { UMUL,	INFL,
1267 	SANY,	TANY,
1268 	SOREG,	TLDOUBLE,
1269 		NDREG|NDSL,	RESC1,
1270 		"	fldt AL\n", },
1271 
1272 { UMUL,	INFL,
1273 	SANY,	TANY,
1274 	SOREG,	TDOUBLE,
1275 		NDREG|NDSL,	RESC1,
1276 		"	fldl AL\n", },
1277 
1278 { UMUL,	INFL,
1279 	SANY,	TANY,
1280 	SOREG,	TFLOAT,
1281 		NDREG|NDSL,	RESC1,
1282 		"	flds AL\n", },
1283 
1284 /*
1285  * Logical/branching operators
1286  */
1287 
1288 /* Comparisions, take care of everything */
1289 { OPLOG,	FORCC,
1290 	SHLL|SOREG|SNAME,	TLL,
1291 	SHLL,			TLL,
1292 		0,	0,
1293 		"ZD", },
1294 
1295 { OPLOG,	FORCC,
1296 	SAREG|SOREG|SNAME,	TWORD|TPOINT,
1297 	SCON|SAREG,	TWORD|TPOINT,
1298 		0, 	RESCC,
1299 		"	cmpl AR,AL\n", },
1300 
1301 { OPLOG,	FORCC,
1302 	SCON|SAREG,	TWORD|TPOINT,
1303 	SAREG|SOREG|SNAME,	TWORD|TPOINT,
1304 		0, 	RESCC,
1305 		"	cmpl AR,AL\n", },
1306 
1307 { OPLOG,	FORCC,
1308 	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
1309 	SCON|SAREG,	TANY,
1310 		0, 	RESCC,
1311 		"	cmpw AR,AL\n", },
1312 
1313 { OPLOG,	FORCC,
1314 	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
1315 	SCON|SBREG,	TANY,
1316 		0, 	RESCC,
1317 		"	cmpb AR,AL\n", },
1318 
1319 { OPLOG,	FORCC,
1320 	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
1321 	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
1322 		0, 	RNOP,
1323 		"ZG", },
1324 
1325 { OPLOG,	FORCC,
1326 	SANY,	TANY,
1327 	SANY,	TANY,
1328 		REWRITE,	0,
1329 		"diediedie!", },
1330 
1331 /* AND/OR/ER/NOT */
1332 { AND,	INAREG|FOREFF,
1333 	SAREG|SOREG|SNAME,	TWORD,
1334 	SCON|SAREG,		TWORD,
1335 		0,	RLEFT,
1336 		"	andl AR,AL\n", },
1337 
1338 { AND,	INCREG|FOREFF,
1339 	SCREG,			TLL,
1340 	SCREG|SOREG|SNAME,	TLL,
1341 		0,	RLEFT,
1342 		"	andl AR,AL\n	andl UR,UL\n", },
1343 
1344 { AND,	INAREG|FOREFF,
1345 	SAREG,			TWORD,
1346 	SAREG|SOREG|SNAME,	TWORD,
1347 		0,	RLEFT,
1348 		"	andl AR,AL\n", },
1349 
1350 { AND,	INAREG|FOREFF,
1351 	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
1352 	SCON|SAREG,		TSHORT|TUSHORT,
1353 		0,	RLEFT,
1354 		"	andw AR,AL\n", },
1355 
1356 { AND,	INAREG|FOREFF,
1357 	SAREG,			TSHORT|TUSHORT,
1358 	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
1359 		0,	RLEFT,
1360 		"	andw AR,AL\n", },
1361 
1362 { AND,	INBREG|FOREFF,
1363 	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
1364 	SCON|SBREG,		TCHAR|TUCHAR,
1365 		0,	RLEFT,
1366 		"	andb AR,AL\n", },
1367 
1368 { AND,	INBREG|FOREFF,
1369 	SBREG,			TCHAR|TUCHAR,
1370 	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
1371 		0,	RLEFT,
1372 		"	andb AR,AL\n", },
1373 /* AND/OR/ER/NOT */
1374 
1375 /*
1376  * Jumps.
1377  */
1378 { GOTO, 	FOREFF,
1379 	SCON,	TANY,
1380 	SANY,	TANY,
1381 		0,	RNOP,
1382 		"	jmp LL\n", },
1383 
1384 #if defined(GCC_COMPAT) || defined(LANG_F77)
1385 { GOTO, 	FOREFF,
1386 	SAREG,	TANY,
1387 	SANY,	TANY,
1388 		0,	RNOP,
1389 		"	jmp *AL\n", },
1390 #endif
1391 
1392 /*
1393  * Convert LTYPE to reg.
1394  */
1395 { OPLTYPE,	FORCC|INLL,
1396 	SCREG,	TLL,
1397 	SMIXOR,	TANY,
1398 		NCREG,	RESC1,
1399 		"	xorl U1,U1\n	xorl A1,A1\n", },
1400 
1401 { OPLTYPE,	FORCC|INLL,
1402 	SCREG,	TLL,
1403 	SMILWXOR,	TANY,
1404 		NCREG,	RESC1,
1405 		"	movl UL,U1\n	xorl A1,A1\n", },
1406 
1407 { OPLTYPE,	FORCC|INLL,
1408 	SCREG,	TLL,
1409 	SMIHWXOR,	TANY,
1410 		NCREG,	RESC1,
1411 		"	xorl U1,U1\n	movl AL,A1\n", },
1412 
1413 { OPLTYPE,	INLL,
1414 	SANY,	TANY,
1415 	SCREG,	TLL,
1416 		NCREG,	RESC1,
1417 		"ZK", },
1418 
1419 { OPLTYPE,	INLL,
1420 	SANY,	TANY,
1421 	SCON|SOREG|SNAME,	TLL,
1422 		NCREG,	RESC1,
1423 		"	movl UL,U1\n	movl AL,A1\n", },
1424 
1425 { OPLTYPE,	FORCC|INAREG,
1426 	SAREG,	TWORD|TPOINT,
1427 	SMIXOR,	TANY,
1428 		NAREG|NASL,	RESC1,
1429 		"	xorl A1,A1\n", },
1430 
1431 { OPLTYPE,	INAREG,
1432 	SANY,	TANY,
1433 	SAREG|SCON|SOREG|SNAME,	TWORD|TPOINT,
1434 		NAREG|NASL,	RESC1,
1435 		"	movl AL,A1\n", },
1436 
1437 { OPLTYPE,	INBREG,
1438 	SANY,	TANY,
1439 	SBREG|SOREG|SNAME|SCON,	TCHAR|TUCHAR,
1440 		NBREG,	RESC1,
1441 		"	movb AL,A1\n", },
1442 
1443 { OPLTYPE,	FORCC|INAREG,
1444 	SAREG,	TSHORT|TUSHORT,
1445 	SMIXOR,	TANY,
1446 		NAREG,	RESC1,
1447 		"	xorw A1,A1\n", },
1448 
1449 { OPLTYPE,	INAREG,
1450 	SANY,	TANY,
1451 	SAREG|SOREG|SNAME|SCON,	TSHORT|TUSHORT,
1452 		NAREG,	RESC1,
1453 		"	movw AL,A1\n", },
1454 
1455 { OPLTYPE,	INDREG,
1456 	SANY,		TLDOUBLE,
1457 	SOREG|SNAME,	TLDOUBLE,
1458 		NDREG,	RESC1,
1459 		"	fldt AL\n", },
1460 
1461 { OPLTYPE,	INDREG,
1462 	SANY,		TDOUBLE,
1463 	SOREG|SNAME,	TDOUBLE,
1464 		NDREG,	RESC1,
1465 		"	fldl AL\n", },
1466 
1467 { OPLTYPE,	INDREG,
1468 	SANY,		TFLOAT,
1469 	SOREG|SNAME,	TFLOAT,
1470 		NDREG,	RESC1,
1471 		"	flds AL\n", },
1472 
1473 /* Only used in ?: constructs. The stack already contains correct value */
1474 { OPLTYPE,	INDREG,
1475 	SANY,	TFLOAT|TDOUBLE|TLDOUBLE,
1476 	SDREG,	TFLOAT|TDOUBLE|TLDOUBLE,
1477 		NDREG,	RESC1,
1478 		"", },
1479 
1480 /*
1481  * Negate a word.
1482  */
1483 
1484 { UMINUS,	INCREG|FOREFF,
1485 	SCREG,	TLL,
1486 	SCREG,	TLL,
1487 		0,	RLEFT,
1488 		"	negl AL\n	adcl $0,UL\n	negl UL\n", },
1489 
1490 { UMINUS,	INAREG|FOREFF,
1491 	SAREG,	TWORD|TPOINT,
1492 	SAREG,	TWORD|TPOINT,
1493 		0,	RLEFT,
1494 		"	negl AL\n", },
1495 
1496 { UMINUS,	INAREG|FOREFF,
1497 	SAREG,	TSHORT|TUSHORT,
1498 	SAREG,	TSHORT|TUSHORT,
1499 		0,	RLEFT,
1500 		"	negw AL\n", },
1501 
1502 { UMINUS,	INBREG|FOREFF,
1503 	SBREG,	TCHAR|TUCHAR,
1504 	SBREG,	TCHAR|TUCHAR,
1505 		0,	RLEFT,
1506 		"	negb AL\n", },
1507 
1508 { UMINUS,	INFL|FOREFF,
1509 	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
1510 	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
1511 		0,	RLEFT,
1512 		"	fchs\n", },
1513 
1514 { COMPL,	INCREG,
1515 	SCREG,	TLL,
1516 	SANY,	TANY,
1517 		0,	RLEFT,
1518 		"	notl AL\n	notl UL\n", },
1519 
1520 { COMPL,	INAREG,
1521 	SAREG,	TWORD,
1522 	SANY,	TANY,
1523 		0,	RLEFT,
1524 		"	notl AL\n", },
1525 
1526 { COMPL,	INAREG,
1527 	SAREG,	TSHORT|TUSHORT,
1528 	SANY,	TANY,
1529 		0,	RLEFT,
1530 		"	notw AL\n", },
1531 
1532 { COMPL,	INBREG,
1533 	SBREG,	TCHAR|TUCHAR,
1534 	SANY,	TANY,
1535 		0,	RLEFT,
1536 		"	notb AL\n", },
1537 
1538 /*
1539  * Arguments to functions.
1540  */
1541 { FUNARG,	FOREFF,
1542 	SCON|SCREG|SNAME|SOREG,	TLL,
1543 	SANY,	TLL,
1544 		0,	RNULL,
1545 		"	pushl UL\n	pushl AL\n", },
1546 
1547 { FUNARG,	FOREFF,
1548 	SCON|SAREG|SNAME|SOREG,	TWORD|TPOINT,
1549 	SANY,	TWORD|TPOINT,
1550 		0,	RNULL,
1551 		"	pushl AL\n", },
1552 
1553 { FUNARG,	FOREFF,
1554 	SCON,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
1555 	SANY,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
1556 		0,	RNULL,
1557 		"	pushl AL\n", },
1558 
1559 { FUNARG,	FOREFF,
1560 	SAREG|SNAME|SOREG,	TSHORT,
1561 	SANY,	TSHORT,
1562 		NAREG,	0,
1563 		"	movswl AL,ZN\n	pushl ZN\n", },
1564 
1565 { FUNARG,	FOREFF,
1566 	SAREG|SNAME|SOREG,	TUSHORT,
1567 	SANY,	TUSHORT,
1568 		NAREG,	0,
1569 		"	movzwl AL,ZN\n	pushl ZN\n", },
1570 
1571 { FUNARG,	FOREFF,
1572 	SHCH|SNAME|SOREG,	TCHAR,
1573 	SANY,			TCHAR,
1574 		NAREG,	0,
1575 		"	movsbl AL,A1\n	pushl A1\n", },
1576 
1577 { FUNARG,	FOREFF,
1578 	SHCH|SNAME|SOREG,	TUCHAR,
1579 	SANY,	TUCHAR,
1580 		NAREG,	0,
1581 		"	movzbl AL,A1\n	pushl A1\n", },
1582 
1583 { FUNARG,	FOREFF,
1584 	SNAME|SOREG,	TDOUBLE,
1585 	SANY,	TDOUBLE,
1586 		0,	0,
1587 		"	pushl UL\n	pushl AL\n", },
1588 
1589 { FUNARG,	FOREFF,
1590 	SDREG,	TDOUBLE,
1591 	SANY,		TDOUBLE,
1592 		0,	0,
1593 		"	subl $8,%esp\n	fstpl (%esp)\n", },
1594 
1595 { FUNARG,	FOREFF,
1596 	SNAME|SOREG,	TFLOAT,
1597 	SANY,		TFLOAT,
1598 		0,	0,
1599 		"	pushl AL\n", },
1600 
1601 { FUNARG,	FOREFF,
1602 	SDREG,	TFLOAT,
1603 	SANY,		TFLOAT,
1604 		0,	0,
1605 		"	subl $4,%esp\n	fstps (%esp)\n", },
1606 
1607 { FUNARG,	FOREFF,
1608 	SDREG,	TLDOUBLE,
1609 	SANY,		TLDOUBLE,
1610 		0,	0,
1611 		"	subl $12,%esp\n	fstpt (%esp)\n", },
1612 
1613 #if defined(MACHOABI)
1614 { STARG,	FOREFF,
1615 	SAREG|SOREG|SNAME|SCON,	TANY,
1616 	SANY,	TSTRUCT,
1617 		NSPECIAL|NAREG,	0,
1618 		"ZF", },
1619 #else
1620 { STARG,	FOREFF,
1621 	SAREG,	TPTRTO|TSTRUCT,
1622 	SANY,	TSTRUCT,
1623 		NSPECIAL,	0,
1624 		"ZF", },
1625 #endif
1626 
1627 # define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
1628 
1629 { UMUL, DF( UMUL ), },
1630 
1631 { ASSIGN, DF(ASSIGN), },
1632 
1633 { STASG, DF(STASG), },
1634 
1635 { FLD, DF(FLD), },
1636 
1637 { OPLEAF, DF(NAME), },
1638 
1639 /* { INIT, DF(INIT), }, */
1640 
1641 { OPUNARY, DF(UMINUS), },
1642 
1643 { OPANY, DF(BITYPE), },
1644 
1645 { FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	"help; I'm in trouble\n" },
1646 };
1647 
1648 int tablesize = sizeof(table)/sizeof(table[0]);
1649