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