[Midnightbsd-cvs] src: pcc/cpp: add i386 directory which contains files in arch/x86

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Thu May 15 01:43:58 EDT 2008


Log Message:
-----------
add i386 directory which contains files in arch/x86 (similar to openbsd setup).

Remove arch

Disable the man page for cpp since gcc installs one.

Modified Files:
--------------
    src/usr.bin/pcc/cpp:
        Makefile (r1.3 -> r1.4)

Added Files:
-----------
    src/usr.bin/pcc/i386:
        code.c (r1.1)
        local.c (r1.1)
        local2.c (r1.1)
        macdefs.h (r1.1)
        order.c (r1.1)
        table.c (r1.1)

Removed Files:
-------------
    src/usr.bin/pcc/arch/x86:
        code.c
        local.c
        local2.c
        macdefs.h
        order.c
        table.c

-------------- next part --------------
--- usr.bin/pcc/arch/x86/order.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*	$Id: order.c,v 1.49 2007/08/01 04:53:58 ragge Exp $	*/
-/*
- * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-# include "pass2.h"
-
-#include <string.h>
-
-int canaddr(NODE *);
-
-/* is it legal to make an OREG or NAME entry which has an
- * offset of off, (from a register of r), if the
- * resulting thing had type t */
-int
-notoff(TWORD t, int r, CONSZ off, char *cp)
-{
-	return(0);  /* YES */
-}
-
-/*
- * Turn a UMUL-referenced node into OREG.
- * Be careful about register classes, this is a place where classes change.
- */
-void
-offstar(NODE *p, int shape)
-{
-	NODE *r;
-
-	if (x2debug)
-		printf("offstar(%p)\n", p);
-
-	if (isreg(p))
-		return; /* Is already OREG */
-
-	r = p->n_right;
-	if( p->n_op == PLUS || p->n_op == MINUS ){
-		if( r->n_op == ICON ){
-			if (isreg(p->n_left) == 0)
-				(void)geninsn(p->n_left, INAREG);
-			/* Converted in ormake() */
-			return;
-		}
-		if (r->n_op == LS && r->n_right->n_op == ICON &&
-		    r->n_right->n_lval == 2 && p->n_op == PLUS) {
-			if (isreg(p->n_left) == 0)
-				(void)geninsn(p->n_left, INAREG);
-			if (isreg(r->n_left) == 0)
-				(void)geninsn(r->n_left, INAREG);
-			return;
-		}
-	}
-	(void)geninsn(p, INAREG);
-}
-
-/*
- * Do the actual conversion of offstar-found OREGs into real OREGs.
- */
-void
-myormake(NODE *q)
-{
-	NODE *p, *r;
-
-	if (x2debug)
-		printf("myormake(%p)\n", q);
-
-	p = q->n_left;
-	if (p->n_op == PLUS && (r = p->n_right)->n_op == LS &&
-	    r->n_right->n_op == ICON && r->n_right->n_lval == 2 &&
-	    p->n_left->n_op == REG && r->n_left->n_op == REG) {
-		q->n_op = OREG;
-		q->n_lval = 0;
-		q->n_rval = R2PACK(p->n_left->n_rval, r->n_left->n_rval, 0);
-		tfree(p);
-	}
-}
-
-/*
- * Shape matches for UMUL.  Cooperates with offstar().
- */
-int
-shumul(NODE *p)
-{
-
-	if (x2debug)
-		printf("shumul(%p)\n", p);
-
-	/* Turns currently anything into OREG on x86 */
-	return SOREG;
-}
-
-/*
- * Rewrite increment/decrement operation.
- */
-int
-setincr(NODE *p)
-{
-	if (x2debug)
-		printf("setincr(%p)\n", p);
-
-	return(0);
-}
-
-/*
- * Rewrite operations on binary operators (like +, -, etc...).
- * Called as a result of table lookup.
- */
-int
-setbin(NODE *p)
-{
-
-	if (x2debug)
-		printf("setbin(%p)\n", p);
-	return 0;
-
-}
-
-/* setup for assignment operator */
-int
-setasg(NODE *p, int cookie)
-{
-	if (x2debug)
-		printf("setasg(%p)\n", p);
-	return(0);
-}
-
-/* setup for unary operator */
-int
-setuni(NODE *p, int cookie)
-{
-	return 0;
-}
-
-/*
- * Special handling of some instruction register allocation.
- */
-struct rspecial *
-nspecial(struct optab *q)
-{
-	switch (q->op) {
-	case OPLOG:
-		{
-			static struct rspecial s[] = { { NEVER, EAX }, { 0 } };
-			return s;
-		}
-
-	case STASG:
-	case STARG:
-		{
-			static struct rspecial s[] = {
-				{ NEVER, EAX }, { NEVER, EDX },
-				{ NEVER, ECX }, { 0 } };
-			return s;
-		}
-
-	case SCONV:
-		if ((q->ltype & (TINT|TUNSIGNED|TSHORT|TUSHORT)) && 
-		    q->rtype == (TCHAR|TUCHAR)) {
-			static struct rspecial s[] = { 
-				{ NOLEFT, ESI }, { NOLEFT, EDI }, { 0 } };
-			return s;
-		} else if ((q->ltype & (TINT|TUNSIGNED)) &&
-		    q->rtype == TLONGLONG) {
-			static struct rspecial s[] = {
-				{ NLEFT, EAX }, { NRES, EAXEDX },
-				{ NEVER, EAX }, { NEVER, EDX }, { 0 } };
-			return s;
-		} else if (q->ltype == TSHORT &&
-		    q->rtype == (TLONGLONG|TULONGLONG)) {
-			static struct rspecial s[] = {
-				{ NRES, EAXEDX },
-				{ NEVER, EAX }, { NEVER, EDX }, { 0 } };
-			return s;
-		} else if (q->ltype == TCHAR &&
-		    q->rtype == (TLONGLONG|TULONGLONG)) {
-			static struct rspecial s[] = {
-				{ NRES, EAXEDX },
-				{ NEVER, EAX }, { NEVER, EDX }, { 0 } };
-			return s;
-		}
-		break;
-	case DIV:
-		if (q->lshape == SBREG) {
-			static struct rspecial s[] = {
-				{ NEVER, AL }, { NEVER, AH },
-				{ NLEFT, AL }, { NRES, AL },
-				{ NORIGHT, AH }, { NORIGHT, AL }, { 0 } };
-				return s;
-		} else if (q->lshape == SAREG) {
-			static struct rspecial s[] = {
-				{ NEVER, EAX }, { NEVER, EDX },
-				{ NLEFT, EAX }, { NRES, EAX },
-				{ NORIGHT, EDX }, { NORIGHT, EAX }, { 0 } };
-			return s;
-		} else if (q->lshape & SCREG) {
-			static struct rspecial s[] = {
-				{ NEVER, EAX }, { NEVER, EDX },
-				{ NEVER, ECX }, { NRES, EAXEDX }, { 0 } };
-			return s;
-		}
-		break;
-	case MOD:
-		if (q->lshape == SBREG) {
-			static struct rspecial s[] = {
-				{ NEVER, AL }, { NEVER, AH },
-				{ NLEFT, AL }, { NRES, AH },
-				{ NORIGHT, AH }, { NORIGHT, AL }, { 0 } };
-			return s;
-		} else if (q->lshape == SAREG) {
-			static struct rspecial s[] = {
-				{ NEVER, EAX }, { NEVER, EDX },
-				{ NLEFT, EAX }, { NRES, EDX },
-				{ NORIGHT, EDX }, { NORIGHT, EAX }, { 0 } };
-			return s;
-		} else if (q->lshape & SCREG) {
-			static struct rspecial s[] = {
-				{ NEVER, EAX }, { NEVER, EDX },
-				{ NEVER, ECX }, { NRES, EAXEDX }, { 0 } };
-			return s;
-		}
-		break;
-	case MUL:
-		if (q->lshape == SBREG) {
-			static struct rspecial s[] = {
-				{ NEVER, AL }, { NEVER, AH },
-				{ NLEFT, AL }, { NRES, AL }, { 0 } };
-			return s;
-		} else if (q->lshape & SCREG) {
-			static struct rspecial s[] = {
-				{ NEVER, EAX }, { NEVER, EDX },
-				{ NEVER, ECX }, { NRES, EAXEDX }, { 0 } };
-			return s;
-		}
-		break;
-	case LS:
-	case RS:
-		if (q->visit & (INAREG|INBREG)) {
-			static struct rspecial s[] = {
-				{ NRIGHT, CL }, { NOLEFT, ECX }, { 0 } };
-			return s;
-		} else if (q->visit & INCREG) {
-			static struct rspecial s[] = {
-				{ NEVER, EAX }, { NEVER, EDX },
-				{ NEVER, ECX }, { NRES, EAXEDX }, { 0 } };
-			return s;
-		}
-		break;
-
-	default:
-		break;
-	}
-	comperr("nspecial entry %d", q - table);
-	return 0; /* XXX gcc */
-}
-
-/*
- * Set evaluation order of a binary node if it differs from default.
- */
-int
-setorder(NODE *p)
-{
-	return 0; /* nothing differs on x86 */
-}
--- usr.bin/pcc/arch/x86/macdefs.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/*	$Id: macdefs.h,v 1.46 2007/08/19 19:25:22 ragge Exp $	*/
-/*
- * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Machine-dependent defines for both passes.
- */
-
-/*
- * Convert (multi-)character constant to integer.
- */
-#define makecc(val,i)	lastcon = (lastcon<<8)|((val<<24)>>24);
-
-#define ARGINIT		64	/* # bits above fp where arguments start */
-#define AUTOINIT	0	/* # bits below fp where automatics start */
-
-/*
- * Storage space requirements
- */
-#define SZCHAR		8
-#define SZBOOL		8
-#define SZINT		32
-#define SZFLOAT		32
-#define SZDOUBLE	64
-#define SZLDOUBLE	96
-#define SZLONG		32
-#define SZSHORT		16
-#define SZLONGLONG	64
-#define SZPOINT(t)	32
-
-/*
- * Alignment constraints
- */
-#define ALCHAR		8
-#define ALBOOL		8
-#define ALINT		32
-#define ALFLOAT		32
-#define ALDOUBLE	32
-#define ALLDOUBLE	32
-#define ALLONG		32
-#define ALLONGLONG	32
-#define ALSHORT		16
-#define ALPOINT		32
-#define ALSTRUCT	32
-#define ALSTACK		32 
-
-/*
- * Min/max values.
- */
-#define	MIN_CHAR	-128
-#define	MAX_CHAR	127
-#define	MAX_UCHAR	255
-#define	MIN_SHORT	-32768
-#define	MAX_SHORT	32767
-#define	MAX_USHORT	65535
-#define	MIN_INT		-1
-#define	MAX_INT		0x7fffffff
-#define	MAX_UNSIGNED	0xffffffff
-#define	MIN_LONG	MIN_INT
-#define	MAX_LONG	MAX_INT
-#define	MAX_ULONG	MAX_UNSIGNED
-#define	MIN_LONGLONG	0x8000000000000000LL
-#define	MAX_LONGLONG	0x7fffffffffffffffLL
-#define	MAX_ULONGLONG	0xffffffffffffffffULL
-
-/* Default char is signed */
-#undef	CHAR_UNSIGNED
-#define	BOOL_TYPE	CHAR	/* what used to store _Bool */
-#define	WCHAR_TYPE	INT	/* what used to store wchar_t */
-
-/*
- * Use large-enough types.
- */
-typedef	long long CONSZ;
-typedef	unsigned long long U_CONSZ;
-typedef long long OFFSZ;
-
-#define CONFMT	"%lld"		/* format for printing constants */
-#define LABFMT	".L%d"		/* format for printing labels */
-#define	STABLBL	".LL%d"		/* format for stab (debugging) labels */
-#ifdef FORTRAN
-#define XL 8
-#define	FLABELFMT "%s:\n"
-#define USETEXT ".text"
-#define USECONST ".data\t0" 	/* XXX - fix */
-#define USEBSS  ".data\t1" 	/* XXX - fix */
-#define USEINIT ".data\t2" 	/* XXX - fix */
-#define MAXREGVAR 3             /* XXX - fix */
-#define BLANKCOMMON "_BLNK_"
-#define MSKIREG  (M(TYSHORT)|M(TYLONG))
-#define TYIREG TYLONG
-#define FSZLENG  FSZLONG
-#define FUDGEOFFSET 1
-#define	AUTOREG	EBP
-#define	ARGREG	EBP
-#define ARGOFFSET 4
-#endif
-
-#define BACKAUTO 		/* stack grows negatively for automatics */
-#define BACKTEMP 		/* stack grows negatively for temporaries */
-
-#define	MYP2TREE(p) myp2tree(p);
-
-#undef	FIELDOPS		/* no bit-field instructions */
-#define	RTOLBYTES		/* bytes are numbered right to left */
-
-#define ENUMSIZE(high,low) INT	/* enums are always stored in full int */
-
-/* Definitions mostly used in pass2 */
-
-#define BYTEOFF(x)	((x)&03)
-#define wdal(k)		(BYTEOFF(k)==0)
-#define BITOOR(x)	(x)	/* bit offset to oreg offset XXX die! */
-
-#define STOARG(p)
-#define STOFARG(p)
-#define STOSTARG(p)
-#define genfcall(a,b)	gencall(a,b)
-
-#define	szty(t)	(((t) == DOUBLE || (t) == FLOAT || \
-	(t) == LONGLONG || (t) == ULONGLONG) ? 2 : (t) == LDOUBLE ? 3 : 1)
-
-/*
- * The x86 has a bunch of register classes, most of them interfering
- * with each other.  All registers are given a sequential number to
- * identify it which must match rnames[] in local2.c.
- * Class membership and overlaps are defined in the macros RSTATUS
- * and ROVERLAP below.
- *
- * The classes used on x86 are:
- *	A - short and int regs
- *	B - char regs
- *	C - long long regs
- *	D - floating point
- */
-#define	EAX	000	/* Scratch and return register */
-#define	EDX	001	/* Scratch and secondary return register */
-#define	ECX	002	/* Scratch (and shift count) register */
-#define	EBX	003	/* GDT pointer or callee-saved temporary register */
-#define	ESI	004	/* Callee-saved temporary register */
-#define	EDI	005	/* Callee-saved temporary register */
-#define	EBP	006	/* Frame pointer */
-#define	ESP	007	/* Stack pointer */
-
-#define	AL	010
-#define	AH	011
-#define	DL	012
-#define	DH	013
-#define	CL	014
-#define	CH	015
-#define	BL	016
-#define	BH	017
-
-#define	EAXEDX	020
-#define	EAXECX	021
-#define	EAXEBX	022
-#define	EAXESI	023
-#define	EAXEDI	024
-#define	EDXECX	025
-#define	EDXEBX	026
-#define	EDXESI	027
-#define	EDXEDI	030
-#define	ECXEBX	031
-#define	ECXESI	032
-#define	ECXEDI	033
-#define	EBXESI	034
-#define	EBXEDI	035
-#define	ESIEDI	036
-
-/* The 8 math registers in class D lacks names */
-
-#define	MAXREGS	047	/* 39 registers */
-
-#define	RSTATUS	\
-	SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|PERMREG,	\
-	SAREG|PERMREG, SAREG|PERMREG, 0, 0,	 			\
-	SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG,		\
-	SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, 	\
-	SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG,		\
-	SDREG, SDREG, SDREG, SDREG,  SDREG, SDREG, SDREG, SDREG,
-
-#define	ROVERLAP \
-	/* 8 basic registers */\
-	{ AL, AH, EAXEDX, EAXECX, EAXEBX, EAXESI, EAXEDI, -1 },\
-	{ DL, DH, EAXEDX, EDXECX, EDXEBX, EDXESI, EDXEDI, -1 },\
-	{ CL, CH, EAXECX, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
-	{ BL, BH, EAXEBX, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
-	{ EAXESI, EDXESI, ECXESI, EBXESI, ESIEDI, -1 },\
-	{ EAXEDI, EDXEDI, ECXEDI, EBXEDI, ESIEDI, -1 },\
-	{ -1 },\
-	{ -1 },\
-\
-	/* 8 char registers */\
-	{ EAX, EAXEDX, EAXECX, EAXEBX, EAXESI, EAXEDI, -1 },\
-	{ EAX, EAXEDX, EAXECX, EAXEBX, EAXESI, EAXEDI, -1 },\
-	{ EDX, EAXEDX, EDXECX, EDXEBX, EDXESI, EDXEDI, -1 },\
-	{ EDX, EAXEDX, EDXECX, EDXEBX, EDXESI, EDXEDI, -1 },\
-	{ ECX, EAXECX, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
-	{ ECX, EAXECX, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
-	{ EBX, EAXEBX, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
-	{ EBX, EAXEBX, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
-\
-	/* 15 long-long-emulating registers */\
-	{ EAX, AL, AH, EDX, DL, DH, EAXECX, EAXEBX, EAXESI,	/* eaxedx */\
-	  EAXEDI, EDXECX, EDXEBX, EDXESI, EDXEDI, -1, },\
-	{ EAX, AL, AH, ECX, CL, CH, EAXEDX, EAXEBX, EAXESI,	/* eaxecx */\
-	  EAXEDI, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
-	{ EAX, AL, AH, EBX, BL, BH, EAXEDX, EAXECX, EAXESI,	/* eaxebx */\
-	  EAXEDI, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
-	{ EAX, AL, AH, ESI, EAXEDX, EAXECX, EAXEBX, EAXEDI,	/* eaxesi */\
-	  EDXESI, ECXESI, EBXESI, ESIEDI, -1 },\
-	{ EAX, AL, AH, EDI, EAXEDX, EAXECX, EAXEBX, EAXESI,	/* eaxedi */\
-	  EDXEDI, ECXEDI, EBXEDI, ESIEDI, -1 },\
-	{ EDX, DL, DH, ECX, CL, CH, EAXEDX, EAXECX, EDXEBX,	/* edxecx */\
-	  EDXESI, EDXEDI, ECXEBX, ECXESI, ECXEDI, -1 },\
-	{ EDX, DL, DH, EBX, BL, BH, EAXEDX, EDXECX, EDXESI,	/* edxebx */\
-	  EDXEDI, EAXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
-	{ EDX, DL, DH, ESI, EAXEDX, EDXECX, EDXEBX, EDXEDI,	/* edxesi */\
-	  EAXESI, ECXESI, EBXESI, ESIEDI, -1 },\
-	{ EDX, DL, DH, EDI, EAXEDX, EDXECX, EDXEBX, EDXESI,	/* edxedi */\
-	  EAXEDI, ECXEDI, EBXEDI, ESIEDI, -1 },\
-	{ ECX, CL, CH, EBX, BL, BH, EAXECX, EDXECX, ECXESI,	/* ecxebx */\
-	  ECXEDI, EAXEBX, EDXEBX, EBXESI, EBXEDI, -1 },\
-	{ ECX, CL, CH, ESI, EAXECX, EDXECX, ECXEBX, ECXEDI,	/* ecxesi */\
-	  EAXESI, EDXESI, EBXESI, ESIEDI, -1 },\
-	{ ECX, CL, CH, EDI, EAXECX, EDXECX, ECXEBX, ECXESI,	/* ecxedi */\
-	  EAXEDI, EDXEDI, EBXEDI, ESIEDI, -1 },\
-	{ EBX, BL, BH, ESI, EAXEBX, EDXEBX, ECXEBX, EBXEDI,	/* ebxesi */\
-	  EAXESI, EDXESI, ECXESI, ESIEDI, -1 },\
-	{ EBX, BL, BH, EDI, EAXEBX, EDXEBX, ECXEBX, EBXESI,	/* ebxedi */\
-	  EAXEDI, EDXEDI, ECXEDI, ESIEDI, -1 },\
-	{ ESI, EDI, EAXESI, EDXESI, ECXESI, EBXESI,		/* esiedi */\
-	  EAXEDI, EDXEDI, ECXEDI, EBXEDI, -1 },\
-\
-	/* The fp registers do not overlap with anything */\
-	{ -1 },\
-	{ -1 },\
-	{ -1 },\
-	{ -1 },\
-	{ -1 },\
-	{ -1 },\
-	{ -1 },\
-	{ -1 },
-
-
-/* Return a register class based on the type of the node */
-#define PCLASS(p) (p->n_type <= UCHAR ? SBREG : \
-		  (p->n_type == LONGLONG || p->n_type == ULONGLONG ? SCREG : \
-		  (p->n_type >= FLOAT && p->n_type <= LDOUBLE ? SDREG : SAREG)))
-
-#define	NUMCLASS 	4	/* highest number of reg classes used */
-
-int COLORMAP(int c, int *r);
-#define	GCLASS(x) (x < 8 ? CLASSA : x < 16 ? CLASSB : x < 31 ? CLASSC : CLASSD)
-#define DECRA(x,y)	(((x) >> (y*6)) & 63)	/* decode encoded regs */
-#define	ENCRD(x)	(x)		/* Encode dest reg in n_reg */
-#define ENCRA1(x)	((x) << 6)	/* A1 */
-#define ENCRA2(x)	((x) << 12)	/* A2 */
-#define ENCRA(x,y)	((x) << (6+y*6))	/* encode regs in int */
-/* XXX - return char in al? */
-#define	RETREG(x)	(x == CHAR || x == UCHAR ? AL : \
-			 x == LONGLONG || x == ULONGLONG ? EAXEDX : \
-			 x == FLOAT || x == DOUBLE || x == LDOUBLE ? 31 : EAX)
-
-//#define R2REGS	1	/* permit double indexing */
-
-/* XXX - to die */
-#define FPREG	EBP	/* frame pointer */
-#define STKREG	ESP	/* stack pointer */
-
-#define MYREADER(p) myreader(p)
-#define MYCANON(p) mycanon(p)
-#define	MYOPTIM
-
-#define	SHSTR		(MAXSPECIAL+1)	/* short struct */
-#define	SFUNCALL	(MAXSPECIAL+2)	/* struct assign after function call */
-#define	SPCON		(MAXSPECIAL+3)	/* positive nonnamed constant */
--- usr.bin/pcc/arch/x86/table.c
+++ /dev/null
@@ -1,1464 +0,0 @@
-/*	$Id: table.c,v 1.96 2007/09/20 14:52:13 ragge Exp $	*/
-/*
- * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-# include "pass2.h"
-
-# define TLL TLONGLONG|TULONGLONG
-# define ANYSIGNED TINT|TLONG|TSHORT|TCHAR
-# define ANYUSIGNED TUNSIGNED|TULONG|TUSHORT|TUCHAR
-# define ANYFIXED ANYSIGNED|ANYUSIGNED
-# define TUWORD TUNSIGNED|TULONG
-# define TSWORD TINT|TLONG
-# define TWORD TUWORD|TSWORD
-#define	 SHINT	SAREG	/* short and int */
-#define	 ININT	INAREG
-#define	 SHCH	SBREG	/* shape for char */
-#define	 INCH	INBREG
-#define	 SHLL	SCREG	/* shape for long long */
-#define	 INLL	INCREG
-#define	 SHFL	SDREG	/* shape for float/double */
-#define	 INFL	INDREG	/* shape for float/double */
-
-struct optab table[] = {
-/* First entry must be an empty entry */
-{ -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", },
-
-/* PCONVs are usually not necessary */
-{ PCONV,	INAREG,
-	SAREG,	TWORD|TPOINT,
-	SAREG,	TWORD|TPOINT,
-		0,	RLEFT,
-		"", },
-
-/*
- * A bunch conversions of integral<->integral types
- * There are lots of them, first in table conversions to itself
- * and then conversions from each type to the others.
- */
-
-/* itself to itself, including pointers */
-
-/* convert (u)char to (u)char. */
-{ SCONV,	INCH,
-	SHCH,	TCHAR|TUCHAR,
-	SHCH,	TCHAR|TUCHAR,
-		0,	RLEFT,
-		"", },
-
-/* convert pointers to int. */
-{ SCONV,	ININT,
-	SHINT,	TPOINT|TWORD,
-	SANY,	TWORD,
-		0,	RLEFT,
-		"", },
-
-/* convert (u)longlong to (u)longlong. */
-{ SCONV,	INLL,
-	SHLL,	TLL,
-	SHLL,	TLL,
-		0,	RLEFT,
-		"", },
-
-/* convert double <-> float. nothing to do here */
-{ SCONV,	INFL,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-		0,	RLEFT,
-		"", },
-
-/* convert pointers to pointers. */
-{ SCONV,	ININT,
-	SHINT,	TPOINT,
-	SANY,	TPOINT,
-		0,	RLEFT,
-		"", },
-
-/* char to something */
-
-/* convert char to (unsigned) short. */
-{ SCONV,	ININT,
-	SBREG|SOREG|SNAME,	TCHAR,
-	SAREG,	TSHORT|TUSHORT,
-		NASL|NAREG,	RESC1,
-		"	movsbw AL,A1\n", },
-
-/* convert unsigned char to (u)short. */
-{ SCONV,	ININT,
-	SHCH|SOREG|SNAME,	TUCHAR,
-	SAREG,	TSHORT|TUSHORT,
-		NASL|NAREG,	RESC1,
-		"	movzbw AL,A1\n", },
-
-/* convert signed char to int (or pointer). */
-{ SCONV,	ININT,
-	SHCH|SOREG|SNAME,	TCHAR,
-	SAREG,	TWORD|TPOINT,
-		NASL|NAREG,	RESC1,
-		"	movsbl AL,A1\n", },
-
-/* convert unsigned char to (u)int. */
-{ SCONV,	ININT,
-	SHCH|SOREG|SNAME,	TUCHAR,
-	SAREG,	TWORD,
-		NASL|NAREG,	RESC1,
-		"	movzbl AL,A1\n", },
-
-/* convert char to (u)long long */
-{ SCONV,	INLL,
-	SHCH|SOREG|SNAME,	TCHAR,
-	SANY,	TLL,
-		NSPECIAL|NAREG|NASL,	RESC1,
-		"	movsbl AL,%eax\n	cltd\n", },
-
-/* convert unsigned char to (u)long long */
-{ SCONV,	INLL,
-	SHCH|SOREG|SNAME,	TUCHAR,
-	SANY,			TLL,
-		NCREG|NCSL,	RESC1,
-		"	movzbl AL,A1\n	xorl U1,U1\n", },
-
-/* convert char (in register) to double XXX - use NTEMP */
-{ SCONV,	INFL,
-	SHCH|SOREG|SNAME,	TCHAR,
-	SHFL,			TLDOUBLE|TDOUBLE|TFLOAT,
-		NAREG|NASL|NDREG,	RESC2,
-		"	movsbl AL,A1\n	pushl A1\n"
-		"	fildl (%esp)\n	addl $4,%esp\n", },
-
-/* convert (u)char (in register) to double XXX - use NTEMP */
-{ SCONV,	INFL,
-	SHCH|SOREG|SNAME,	TUCHAR,
-	SHFL,			TLDOUBLE|TDOUBLE|TFLOAT,
-		NAREG|NASL|NDREG,	RESC2,
-		"	movzbl AL,A1\n	pushl A1\n"
-		"	fildl (%esp)\n	addl $4,%esp\n", },
-
-/* short to something */
-
-/* convert short (in memory) to char */
-{ SCONV,	INCH,
-	SNAME|SOREG,	TSHORT|TUSHORT,
-	SHCH,		TCHAR|TUCHAR,
-		NBREG|NBSL,	RESC1,
-		"	movb AL,A1\n", },
-
-/* convert short (in reg) to char. */
-{ SCONV,	INCH,
-	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
-	SHCH,			TCHAR|TUCHAR,
-		NSPECIAL|NBREG|NBSL,	RESC1,
-		"ZM", },
-
-/* convert short to (u)int. */
-{ SCONV,	ININT,
-	SAREG|SOREG|SNAME,	TSHORT,
-	SAREG,	TWORD,
-		NASL|NAREG,	RESC1,
-		"	movswl AL,A1\n", },
-
-/* convert unsigned short to (u)int. */
-{ SCONV,	ININT,
-	SAREG|SOREG|SNAME,	TUSHORT,
-	SAREG,	TWORD,
-		NASL|NAREG,	RESC1,
-		"	movzwl AL,A1\n", },
-
-/* convert short to (u)long long */
-{ SCONV,	INLL,
-	SAREG|SOREG|SNAME,	TSHORT,
-	SHLL,			TLL,
-		NSPECIAL|NCREG|NCSL,	RESC1,
-		"	movswl AL,%eax\n	cltd\n", },
-
-/* convert unsigned short to (u)long long */
-{ SCONV,	INLL,
-	SAREG|SOREG|SNAME,	TUSHORT,
-	SHLL,			TLL,
-		NCREG|NCSL,	RESC1,
-		"	movzwl AL,A1\n	xorl U1,U1\n", },
-
-/* convert short (in memory) to float/double */
-{ SCONV,	INFL,
-	SOREG|SNAME,	TSHORT,
-	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
-		NDREG,	RESC1,
-		"	fild AL\n", },
-
-/* convert short (in register) to float/double */
-{ SCONV,	INFL,
-	SAREG,	TSHORT,
-	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
-		NTEMP|NDREG,	RESC1,
-		"	pushw AL\n	fild (%esp)\n	addl $2,%esp\n", },
-
-/* convert unsigned short to double XXX - use NTEMP */
-{ SCONV,	INFL,
-	SAREG|SOREG|SNAME,	TUSHORT,
-	SHFL,			TLDOUBLE|TDOUBLE|TFLOAT,
-		NAREG|NASL|NDREG|NTEMP,	RESC2,
-		"	movzwl AL,A1\n	pushl A1\n"
-		"	fildl (%esp)\n	addl $4,%esp\n", },
-
-/* int to something */
-
-/* convert int to char. This is done when register is loaded */
-{ SCONV,	INCH,
-	SAREG,	TWORD,
-	SANY,	TCHAR|TUCHAR,
-		NSPECIAL|NBREG|NBSL,	RESC1,
-		"ZM", },
-
-/* convert int to short. Nothing to do */
-{ SCONV,	INAREG,
-	SAREG,	TWORD,
-	SANY,	TSHORT|TUSHORT,
-		0,	RLEFT,
-		"", },
-
-/* convert int to long long */
-{ SCONV,	INLL,
-	SAREG,	TWORD|TPOINT,
-	SCREG,	TLONGLONG,
-		NSPECIAL|NCREG|NCSL,	RESC1,
-		"	cltd\n", },
-
-/* convert int to unsigned long long */
-{ SCONV,	INLL,
-	SAREG|SOREG|SNAME,	TWORD|TPOINT,
-	SHLL,	TULONGLONG,
-		NCSL|NCREG,	RESC1,
-		"	movl AL,A1\n	xorl U1,U1\n", },
-
-/* convert int (in memory) to double */
-{ SCONV,	INFL,
-	SOREG|SNAME,	TWORD,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-		NDREG,	RESC1,
-		"	fildl AL\n", },
-
-/* convert int (in register) to double */
-{ SCONV,	INFL,
-	SAREG,	TWORD,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-		NTEMP|NDREG,	RESC1,
-		"	pushl AL\n	fildl (%esp)\n	addl $4,%esp\n", },
-
-/* long long to something */
-
-/* convert (u)long long to (u)char (mem->reg) */
-{ SCONV,	INCH,
-	SOREG|SNAME,	TLL,
-	SANY,	TCHAR|TUCHAR,
-		NAREG|NASL,	RESC1,
-		"	movb AL,A1\n", },
-
-/* convert (u)long long to (u)char (reg->reg, hopefully nothing) */
-{ SCONV,	INCH,
-	SHLL,	TLL,
-	SANY,	TCHAR|TUCHAR,
-		NAREG|NASL,	RESC1,
-		"ZS", },
-
-/* convert (u)long long to (u)short (mem->reg) */
-{ SCONV,	INAREG,
-	SOREG|SNAME,	TLL,
-	SAREG,	TSHORT|TUSHORT,
-		NAREG|NASL,	RESC1,
-		"	movw AL,A1\n", },
-
-/* convert (u)long long to (u)short (reg->reg, hopefully nothing) */
-{ SCONV,	INAREG,
-	SHLL|SOREG|SNAME,	TLL,
-	SAREG,	TSHORT|TUSHORT,
-		NAREG|NASL,	RESC1,
-		"ZS", },
-
-/* convert long long to int (mem->reg) */
-{ SCONV,	INAREG,
-	SOREG|SNAME,	TLL,
-	SAREG,	TWORD|TPOINT,
-		NAREG|NASL,	RESC1,
-		"	movl AL,A1\n", },
-
-/* convert long long to int (reg->reg, hopefully nothing) */
-{ SCONV,	INAREG,
-	SHLL|SOREG|SNAME,	TLL,
-	SAREG,	TWORD|TPOINT,
-		NAREG|NASL,	RESC1,
-		"ZS", },
-
-/* convert long long (in memory) to floating */
-{ SCONV,	INFL,
-	SOREG|SNAME,	TLONGLONG,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-		NDREG,	RESC1,
-		"	fildq AL\n", },
-
-/* convert long long (in register) to floating */
-{ SCONV,	INFL,
-	SHLL,	TLONGLONG,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-		NTEMP|NDREG,	RESC1,
-		"	pushl UL\n	pushl AL\n"
-		"	fildq (%esp)\n	addl $8,%esp\n", },
-
-/* convert unsigned long long to floating */
-{ SCONV,	INFL,
-	SCREG,	TULONGLONG,
-	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
-		NDREG,	RESC1,
-		"ZJ", },
-
-/* float to something */
-
-#if 0 /* go via int by adding an extra sconv in clocal() */
-/* convert float/double to (u) char. XXX should use NTEMP here */
-{ SCONV,	INCH,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-	SHCH,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
-		NBREG,	RESC1,
-		"	subl $4,%esp\n	fistpl (%esp)\n	popl A1\n", },
-
-/* convert float/double to (u) int/short/char. XXX should use NTEMP here */
-{ SCONV,	INCH,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-	SHCH,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
-		NCREG,	RESC1,
-		"	subl $4,%esp\n	fistpl (%esp)\n	popl A1\n", },
-#endif
-
-/* convert float/double to (u)int. XXX should use NTEMP here */
-{ SCONV,	INAREG,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-	SAREG,	TWORD,
-		NAREG,	RESC1,
-		"	subl $4,%esp\n	fistpl (%esp)\n	popl A1\n", },
-
-/* convert float/double (in register) to (unsigned) long long */
-/* XXX - unsigned is not handled correct */
-{ SCONV,	INLL,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-	SHLL,	TLONGLONG|TULONGLONG,
-		NCREG,	RESC1,
-		"	subl $8,%esp\n	fistpq (%esp)\n"
-		"	popl A1\n	popl U1\n", },
-
-/* slut sconv */
-
-/*
- * Subroutine calls.
- */
-
-{ CALL,		FOREFF,
-	SCON,	TANY,
-	SANY,	TANY,
-		0,	0,
-		"	call CL\nZC", },
-
-{ UCALL,	FOREFF,
-	SCON,	TANY,
-	SAREG,	TWORD|TPOINT,
-		0,	0,
-		"	call CL\n", },
-
-{ CALL,	INAREG,
-	SCON,	TANY,
-	SAREG,	TWORD|TPOINT,
-		NAREG|NASL,	RESC1,	/* should be 0 */
-		"	call CL\nZC", },
-
-{ UCALL,	INAREG,
-	SCON,	TANY,
-	SAREG,	TWORD|TPOINT,
-		NAREG|NASL,	RESC1,	/* should be 0 */
-		"	call CL\n", },
-
-{ CALL,	INBREG,
-	SCON,	TANY,
-	SBREG,	TCHAR|TUCHAR,
-		NBREG,	RESC1,	/* should be 0 */
-		"	call CL\nZC", },
-
-{ UCALL,	INBREG,
-	SCON,	TANY,
-	SBREG,	TCHAR|TUCHAR,
-		NBREG,	RESC1,	/* should be 0 */
-		"	call CL\n", },
-
-{ CALL,		INCREG,
-	SCON,	TANY,
-	SCREG,	TANY,
-		NCREG|NCSL,	RESC1,	/* should be 0 */
-		"	call CL\nZC", },
-
-{ UCALL,	INCREG,
-	SCON,	TANY,
-	SCREG,	TANY,
-		NCREG|NCSL,	RESC1,	/* should be 0 */
-		"	call CL\n", },
-
-{ CALL,	INDREG,
-	SCON,	TANY,
-	SDREG,	TANY,
-		NDREG|NDSL,	RESC1,	/* should be 0 */
-		"	call CL\nZC", },
-
-{ UCALL,	INDREG,
-	SCON,	TANY,
-	SDREG,	TANY,
-		NDREG|NDSL,	RESC1,	/* should be 0 */
-		"	call CL\nZC", },
-
-{ CALL,		FOREFF,
-	SAREG,	TANY,
-	SANY,	TANY,
-		0,	0,
-		"	call *AL\nZC", },
-
-{ UCALL,	FOREFF,
-	SAREG,	TANY,
-	SANY,	TANY,
-		0,	0,
-		"	call *AL\nZC", },
-
-{ CALL,		INAREG,
-	SAREG,	TANY,
-	SANY,	TANY,
-		NAREG|NASL,	RESC1,	/* should be 0 */
-		"	call *AL\nZC", },
-
-{ UCALL,	INAREG,
-	SAREG,	TANY,
-	SANY,	TANY,
-		NAREG|NASL,	RESC1,	/* should be 0 */
-		"	call *AL\nZC", },
-
-{ CALL,		INBREG,
-	SAREG,	TANY,
-	SANY,	TANY,
-		NBREG|NBSL,	RESC1,	/* should be 0 */
-		"	call *AL\nZC", },
-
-{ UCALL,	INBREG,
-	SAREG,	TANY,
-	SANY,	TANY,
-		NBREG|NBSL,	RESC1,	/* should be 0 */
-		"	call *AL\nZC", },
-
-{ CALL,		INCREG,
-	SAREG,	TANY,
-	SANY,	TANY,
-		NCREG|NCSL,	RESC1,	/* should be 0 */
-		"	call *AL\nZC", },
-
-{ UCALL,	INCREG,
-	SAREG,	TANY,
-	SANY,	TANY,
-		NCREG|NCSL,	RESC1,	/* should be 0 */
-		"	call *AL\nZC", },
-
-{ CALL,		INDREG,
-	SAREG,	TANY,
-	SANY,	TANY,
-		NDREG|NDSL,	RESC1,	/* should be 0 */
-		"	call *AL\nZC", },
-
-{ UCALL,	INDREG,
-	SAREG,	TANY,
-	SANY,	TANY,
-		NDREG|NDSL,	RESC1,	/* should be 0 */
-		"	call *AL\nZC", },
-
-/* struct return */
-{ USTCALL,	FOREFF,
-	SCON,	TANY,
-	SANY,	TANY,
-		NAREG|NASL,	0,
-		"ZP	call CL\nZC", },
-
-{ USTCALL,	INAREG,
-	SCON,	TANY,
-	SANY,	TANY,
-		NAREG|NASL,	RESC1,	/* should be 0 */
-		"ZP	call CL\nZC", },
-
-{ USTCALL,	INAREG,
-	SNAME|SAREG,	TANY,
-	SANY,	TANY,
-		NAREG|NASL,	RESC1,	/* should be 0 */
-		"ZP	call *AL\nZC", },
-
-{ STCALL,	FOREFF,
-	SCON,	TANY,
-	SANY,	TANY,
-		NAREG|NASL,	0,
-		"ZP	call CL\nZC", },
-
-{ STCALL,	INAREG,
-	SCON,	TANY,
-	SANY,	TANY,
-		NAREG|NASL,	RESC1,	/* should be 0 */
-		"ZP	call CL\nZC", },
-
-{ STCALL,	INAREG,
-	SNAME|SAREG,	TANY,
-	SANY,	TANY,
-		NAREG|NASL,	RESC1,	/* should be 0 */
-		"ZP	call *AL\nZC", },
-
-/*
- * The next rules handle all binop-style operators.
- */
-/* Special treatment for long long */
-{ PLUS,		INLL|FOREFF,
-	SHLL,		TLL,
-	SHLL|SNAME|SOREG,	TLL,
-		0,	RLEFT,
-		"	addl AR,AL\n	adcl UR,UL\n", },
-
-/* Special treatment for long long  XXX - fix commutative check */
-{ PLUS,		INLL|FOREFF,
-	SHLL|SNAME|SOREG,	TLL,
-	SHLL,			TLL,
-		0,	RRIGHT,
-		"	addl AL,AR\n	adcl UL,UR\n", },
-
-{ PLUS,		INFL,
-	SHFL,		TDOUBLE,
-	SNAME|SOREG,	TDOUBLE,
-		0,	RLEFT,
-		"	faddl AR\n", },
-
-{ PLUS,		INFL|FOREFF,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-		0,	RLEFT,
-		"	faddp\n", },
-
-{ PLUS,		INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TWORD|TPOINT,
-	SONE,	TANY,
-		0,	RLEFT,
-		"	incl AL\n", },
-
-{ PLUS,		INAREG,
-	SAREG,	TWORD|TPOINT,
-	SCON,	TANY,
-		NAREG|NASL,	RESC1,
-		"	leal CR(AL),A1\n", },
-
-{ PLUS,		INCH|FOREFF,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
-	SONE,	TANY,
-		0,	RLEFT,
-		"	incb AL\n", },
-
-{ PLUS,		INAREG,
-	SAREG,	TWORD,
-	SAREG,	TWORD,
-		NAREG|NASL|NASR,	RESC1,
-		"	leal (AL,AR),A1\n", },
-
-{ MINUS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TWORD|TPOINT,
-	SONE,			TANY,
-		0,	RLEFT,
-		"	decl AL\n", },
-
-{ MINUS,	INCH|FOREFF,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
-	SONE,	TANY,
-		0,	RLEFT,
-		"	decb AL\n", },
-
-/* address as register offset, negative */
-{ MINUS,	INAREG,
-	SAREG,	TWORD|TPOINT,
-	SPCON,	TANY,
-		NAREG|NASL,	RESC1,
-		"	leal -CR(AL),A1\n", },
-
-{ MINUS,	INLL|FOREFF,
-	SHLL,	TLL,
-	SHLL|SNAME|SOREG,	TLL,
-		0,	RLEFT,
-		"	subl AR,AL\n	sbbl UR,UL\n", },
-
-{ MINUS,	INFL,
-	SHFL,	TDOUBLE,
-	SNAME|SOREG,	TDOUBLE,
-		0,	RLEFT,
-		"	fsubl AR\n", },
-
-{ MINUS,	INFL|FOREFF,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-		0,	RLEFT,
-		"	fsubZAp\n", },
-
-/* Simple r/m->reg ops */
-{ OPSIMP,	INAREG|FOREFF,
-	SAREG,			TWORD|TPOINT,
-	SAREG|SNAME|SOREG,	TWORD|TPOINT,
-		0,	RLEFT,
-		"	Ol AR,AL\n", },
-
-{ OPSIMP,	INAREG|FOREFF,
-	SHINT,		TSHORT|TUSHORT,
-	SHINT|SNAME|SOREG,	TSHORT|TUSHORT,
-		0,	RLEFT,
-		"	Ow AR,AL\n", },
-
-{ OPSIMP,	INCH|FOREFF,
-	SHCH,		TCHAR|TUCHAR,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
-		0,	RLEFT,
-		"	Ob AR,AL\n", },
-
-{ OPSIMP,	INAREG|FOREFF,
-	SAREG,	TWORD|TPOINT,
-	SCON,	TWORD|TPOINT,
-		0,	RLEFT,
-		"	Ol AR,AL\n", },
-
-{ OPSIMP,	INAREG|FOREFF,
-	SHINT|SNAME|SOREG,	TSHORT|TUSHORT,
-	SCON,	TANY,
-		0,	RLEFT,
-		"	Ow AR,AL\n", },
-
-{ OPSIMP,	INCH|FOREFF,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
-	SCON,	TANY,
-		0,	RLEFT,
-		"	Ob AR,AL\n", },
-
-{ OPSIMP,	INLL|FOREFF,
-	SHLL,	TLL,
-	SHLL|SNAME|SOREG,	TLL,
-		0,	RLEFT,
-		"	Ol AR,AL\n	Ol UR,UL\n", },
-
-
-/*
- * The next rules handle all shift operators.
- */
-/* (u)longlong left shift is emulated */
-{ LS,	INCREG,
-	SCREG|SNAME|SOREG|SCON, TLL,
-	SAREG|SNAME|SOREG|SCON, TINT, /* will be int */
-		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
-		"ZO", },
-
-{ LS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TWORD,
-	SHCH,		TCHAR|TUCHAR,
-		NSPECIAL,	RLEFT,
-		"	sall AR,AL\n", },
-
-{ LS,	INAREG|FOREFF,
-	SAREG,	TWORD,
-	SCON,	TANY,
-		0,	RLEFT,
-		"	sall AR,AL\n", },
-
-{ LS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
-	SHCH,			TCHAR|TUCHAR,
-		NSPECIAL,	RLEFT,
-		"	shlw AR,AL\n", },
-
-{ LS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
-	SCON,	TANY,
-		0,	RLEFT,
-		"	shlw AR,AL\n", },
-
-{ LS,	INCH|FOREFF,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
-	SHCH,			TCHAR|TUCHAR,
-		NSPECIAL,	RLEFT,
-		"	salb AR,AL\n", },
-
-{ LS,	INCH|FOREFF,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
-	SCON,			TANY,
-		0,	RLEFT,
-		"	salb AR,AL\n", },
-
-/* (u)longlong right shift is emulated */
-{ RS,	INCREG,
-	SCREG|SNAME|SOREG|SCON, TLL,
-	SAREG|SNAME|SOREG|SCON, TINT, /* will be int */
-		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
-		"ZO", },
-
-{ RS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TSWORD,
-	SHCH,			TCHAR|TUCHAR,
-		NSPECIAL,	RLEFT,
-		"	sarl AR,AL\n", },
-
-{ RS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TSWORD,
-	SCON,			TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
-		0,		RLEFT,
-		"	sarl AR,AL\n", },
-
-{ RS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TUWORD,
-	SHCH,			TCHAR|TUCHAR,
-		NSPECIAL,	RLEFT,
-		"	shrl AR,AL\n", },
-
-{ RS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TUWORD,
-	SCON,			TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
-		0,		RLEFT,
-		"	shrl AR,AL\n", },
-
-{ RS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TSHORT,
-	SHCH,			TCHAR|TUCHAR,
-		NSPECIAL,	RLEFT,
-		"	sarw AR,AL\n", },
-
-{ RS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TSHORT,
-	SCON,			TANY,
-		0,		RLEFT,
-		"	sarw AR,AL\n", },
-
-{ RS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TUSHORT,
-	SHCH,			TCHAR|TUCHAR,
-		NSPECIAL,	RLEFT,
-		"	shrw AR,AL\n", },
-
-{ RS,	INAREG|FOREFF,
-	SAREG|SNAME|SOREG,	TUSHORT,
-	SCON,			TANY,
-		0,		RLEFT,
-		"	shrw AR,AL\n", },
-
-{ RS,	INCH|FOREFF,
-	SHCH|SNAME|SOREG,	TCHAR,
-	SHCH,			TCHAR|TUCHAR,
-		NSPECIAL,	RLEFT,
-		"	sarb AR,AL\n", },
-
-{ RS,	INCH|FOREFF,
-	SHCH|SNAME|SOREG,	TCHAR,
-	SCON,			TANY,
-		0,		RLEFT,
-		"	sarb AR,AL\n", },
-
-{ RS,	INCH|FOREFF,
-	SHCH|SNAME|SOREG,	TUCHAR,
-	SHCH,			TCHAR|TUCHAR,
-		NSPECIAL,	RLEFT,
-		"	shrb AR,AL\n", },
-
-{ RS,	INCH|FOREFF,
-	SHCH|SNAME|SOREG,	TUCHAR,
-	SCON,			TANY,
-		0,		RLEFT,
-		"	shrb AR,AL\n", },
-
-/*
- * The next rules takes care of assignments. "=".
- */
-{ ASSIGN,	FOREFF,
-	SHLL|SNAME|SOREG,	TLL,
-	SCON,		TANY,
-		0,	0,
-		"	movl AR,AL\n	movl UR,UL\n", },
-
-{ ASSIGN,	FOREFF|INLL,
-	SHLL,		TLL,
-	SCON,		TANY,
-		0,	RDEST,
-		"	movl AR,AL\n	movl UR,UL\n", },
-
-{ ASSIGN,	FOREFF,
-	SAREG|SNAME|SOREG,	TWORD|TPOINT,
-	SCON,		TANY,
-		0,	0,
-		"	movl AR,AL\n", },
-
-{ ASSIGN,	FOREFF|INAREG,
-	SAREG,	TWORD|TPOINT,
-	SCON,		TANY,
-		0,	RDEST,
-		"	movl AR,AL\n", },
-
-{ ASSIGN,	FOREFF,
-	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
-	SCON,		TANY,
-		0,	0,
-		"	movw AR,AL\n", },
-
-{ ASSIGN,	FOREFF|INAREG,
-	SAREG,	TSHORT|TUSHORT,
-	SCON,		TANY,
-		0,	RDEST,
-		"	movw AR,AL\n", },
-
-{ ASSIGN,	FOREFF,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
-	SCON,		TANY,
-		0,	0,
-		"	movb AR,AL\n", },
-
-{ ASSIGN,	FOREFF|INCH,
-	SHCH,		TCHAR|TUCHAR,
-	SCON,		TANY,
-		0,	RDEST,
-		"	movb AR,AL\n", },
-
-{ ASSIGN,	FOREFF|INLL,
-	SHLL|SNAME|SOREG,	TLL,
-	SHLL,			TLL,
-		0,	RDEST,
-		"	movl AR,AL\n	movl UR,UL\n", },
-
-{ ASSIGN,	FOREFF|INAREG,
-	SAREG|SNAME|SOREG,	TWORD|TPOINT,
-	SAREG,		TWORD|TPOINT,
-		0,	RDEST,
-		"	movl AR,AL\n", },
-
-{ ASSIGN,	FOREFF|INAREG,
-	SAREG,			TWORD|TPOINT,
-	SAREG|SNAME|SOREG,	TWORD|TPOINT,
-		0,	RDEST,
-		"	movl AR,AL\n", },
-
-{ ASSIGN,	FOREFF|INAREG,
-	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
-	SAREG,		TSHORT|TUSHORT,
-		0,	RDEST,
-		"	movw AR,AL\n", },
-
-{ ASSIGN,	FOREFF|INCH,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
-	SHCH,		TCHAR|TUCHAR|TWORD,
-		0,	RDEST,
-		"	movb AR,AL\n", },
-
-{ ASSIGN,	FOREFF|INBREG,
-	SFLD,		TCHAR|TUCHAR,
-	SBREG|SCON,	TCHAR|TUCHAR,
-		NBREG,	RDEST,
-		"ZE", },
-
-{ ASSIGN,	FOREFF|INAREG,
-	SFLD,		TANY,
-	SAREG,	TANY,
-		NAREG,	RDEST,
-		"ZE", },
-
-{ ASSIGN,	FOREFF,
-	SFLD,		TANY,
-	SAREG|SNAME|SOREG|SCON,	TANY,
-		NAREG,	0,
-		"ZE", },
-
-{ ASSIGN,	INDREG|FOREFF,
-	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
-	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
-		0,	RDEST,
-		"", }, /* This will always be in the correct register */
-
-/* order of table entries is very important here! */
-{ ASSIGN,	INFL,
-	SNAME|SOREG,	TLDOUBLE,
-	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
-		0,	RDEST,
-		"	fstt AL\n", },
-
-{ ASSIGN,	FOREFF,
-	SNAME|SOREG,	TLDOUBLE,
-	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
-		0,	0,
-		"	fstpt AL\n", },
-
-{ ASSIGN,	INFL,
-	SNAME|SOREG,	TDOUBLE,
-	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
-		0,	RDEST,
-		"	fstl AL\n", },
-
-{ ASSIGN,	FOREFF,
-	SNAME|SOREG,	TDOUBLE,
-	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
-		0,	0,
-		"	fstpl AL\n", },
-
-{ ASSIGN,	INFL,
-	SNAME|SOREG,	TFLOAT,
-	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
-		0,	RDEST,
-		"	fsts AL\n", },
-
-{ ASSIGN,	FOREFF,
-	SNAME|SOREG,	TFLOAT,
-	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
-		0,	0,
-		"	fstps AL\n", },
-/* end very important order */
-
-{ ASSIGN,	INFL|FOREFF,
-	SHFL,		TLDOUBLE,
-	SHFL|SOREG|SNAME,	TLDOUBLE,
-		0,	RDEST,
-		"	fldt AR\n", },
-
-{ ASSIGN,	INFL|FOREFF,
-	SHFL,		TDOUBLE,
-	SHFL|SOREG|SNAME,	TDOUBLE,
-		0,	RDEST,
-		"	fldl AR\n", },
-
-{ ASSIGN,	INFL|FOREFF,
-	SHFL,		TFLOAT,
-	SHFL|SOREG|SNAME,	TFLOAT,
-		0,	RDEST,
-		"	flds AR\n", },
-
-/* Do not generate memcpy if return from funcall */
-#if 0
-{ STASG,	INAREG|FOREFF,
-	SOREG|SNAME|SAREG,	TPTRTO|TSTRUCT,
-	SFUNCALL,	TPTRTO|TSTRUCT,
-		0,	RRIGHT,
-		"", },
-#endif
-
-{ STASG,	INAREG|FOREFF,
-	SOREG|SNAME,	TANY,
-	SAREG|SOREG|SNAME,	TPTRTO|TANY,
-		NSPECIAL,	RRIGHT,
-		"ZQ", },
-
-/*
- * DIV/MOD/MUL 
- */
-/* long long div is emulated */
-{ DIV,	INCREG,
-	SCREG|SNAME|SOREG|SCON, TLL,
-	SCREG|SNAME|SOREG|SCON, TLL,
-		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
-		"ZO", },
-
-{ DIV,	INAREG,
-	SAREG,			TSWORD,
-	SAREG|SNAME|SOREG,	TWORD,
-		NSPECIAL,	RDEST,
-		"	cltd\n	idivl AR\n", },
-
-{ DIV,	INAREG,
-	SAREG,			TUWORD|TPOINT,
-	SAREG|SNAME|SOREG,	TUWORD|TPOINT,
-		NSPECIAL,	RDEST,
-		"	xorl %edx,%edx\n	divl AR\n", },
-
-{ DIV,	INAREG,
-	SAREG,			TUSHORT,
-	SAREG|SNAME|SOREG,	TUSHORT,
-		NSPECIAL,	RDEST,
-		"	xorl %edx,%edx\n	divw AR\n", },
-
-{ DIV,	INCH,
-	SHCH,			TUCHAR,
-	SHCH|SNAME|SOREG,	TUCHAR,
-		NSPECIAL,	RDEST,
-		"	xorb %ah,%ah\n	divb AR\n", },
-
-{ DIV,	INFL,
-	SHFL,		TDOUBLE,
-	SNAME|SOREG,	TDOUBLE,
-		0,	RLEFT,
-		"	fdivl AR\n", },
-
-{ DIV,	INFL,
-	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
-	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
-		0,	RLEFT,
-		"	fdivZAp\n", },
-
-/* (u)longlong mod is emulated */
-{ MOD,	INCREG,
-	SCREG|SNAME|SOREG|SCON, TLL,
-	SCREG|SNAME|SOREG|SCON, TLL,
-		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
-		"ZO", },
-
-{ MOD,	INAREG,
-	SAREG,			TSWORD,
-	SAREG|SNAME|SOREG,	TSWORD,
-		NAREG|NSPECIAL,	RESC1,
-		"	cltd\n	idivl AR\n", },
-
-{ MOD,	INAREG,
-	SAREG,			TWORD|TPOINT,
-	SAREG|SNAME|SOREG,	TUWORD|TPOINT,
-		NAREG|NSPECIAL,	RESC1,
-		"	xorl %edx,%edx\n	divl AR\n", },
-
-{ MOD,	INAREG,
-	SAREG,			TUSHORT,
-	SAREG|SNAME|SOREG,	TUSHORT,
-		NAREG|NSPECIAL,	RESC1,
-		"	xorl %edx,%edx\n	divw AR\n", },
-
-{ MOD,	INCH,
-	SHCH,			TUCHAR,
-	SHCH|SNAME|SOREG,	TUCHAR,
-		NBREG|NSPECIAL,	RESC1,
-		"	xorb %ah,%ah\n	divb AR\n", },
-
-/* (u)longlong mul is emulated */
-{ MUL,	INCREG,
-	SCREG|SNAME|SOREG|SCON, TLL,
-	SCREG|SNAME|SOREG|SCON, TLL,
-		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
-		"ZO", },
-
-{ MUL,	INAREG,
-	SAREG,				TWORD|TPOINT,
-	SAREG|SNAME|SOREG|SCON,		TWORD|TPOINT,
-		0,	RLEFT,
-		"	imull AR,AL\n", },
-
-{ MUL,	INAREG,
-	SAREG,			TSHORT|TUSHORT,
-	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
-		0,	RLEFT,
-		"	imulw AR,AL\n", },
-
-{ MUL,	INCH,
-	SHCH,			TCHAR|TUCHAR,
-	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
-		NSPECIAL,	RDEST,
-		"	imulb AR\n", },
-
-{ MUL,	INFL,
-	SHFL,		TDOUBLE,
-	SNAME|SOREG,	TDOUBLE,
-		0,	RLEFT,
-		"	fmull AR\n", },
-
-{ MUL,	INFL,
-	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
-	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
-		0,	RLEFT,
-		"	fmulp\n", },
-
-/*
- * Indirection operators.
- */
-{ UMUL,	INLL,
-	SANY,	TANY,
-	SOREG,	TLL,
-		NCREG|NCSL,	RESC1,
-		"	movl UL,U1\n	movl AL,A1\n", },
-
-{ UMUL,	INAREG,
-	SANY,	TPOINT|TWORD,
-	SOREG,	TPOINT|TWORD,
-		NAREG|NASL,	RESC1,
-		"	movl AL,A1\n", },
-
-{ UMUL,	INCH,
-	SANY,	TANY,
-	SOREG,	TCHAR|TUCHAR,
-		NBREG|NBSL,	RESC1,
-		"	movb AL,A1\n", },
-
-{ UMUL,	INAREG,
-	SANY,	TANY,
-	SOREG,	TSHORT|TUSHORT,
-		NAREG|NASL,	RESC1,
-		"	movw AL,A1\n", },
-
-{ UMUL,	INFL,
-	SANY,	TANY,
-	SOREG,	TLDOUBLE,
-		NDREG|NDSL,	RESC1,
-		"	fldt AL\n", },
-
-{ UMUL,	INFL,
-	SANY,	TANY,
-	SOREG,	TDOUBLE,
-		NDREG|NDSL,	RESC1,
-		"	fldl AL\n", },
-
-{ UMUL,	INFL,
-	SANY,	TANY,
-	SOREG,	TFLOAT,
-		NDREG|NDSL,	RESC1,
-		"	flds AL\n", },
-
-/*
- * Logical/branching operators
- */
-
-/* Comparisions, take care of everything */
-{ OPLOG,	FORCC,
-	SHLL|SOREG|SNAME,	TLL,
-	SHLL,			TLL,
-		0,	0,
-		"ZD", },
-
-{ OPLOG,	FORCC,
-	SAREG|SOREG|SNAME,	TWORD|TPOINT,
-	SCON|SAREG,	TWORD|TPOINT,
-		0, 	RESCC,
-		"	cmpl AR,AL\n", },
-
-{ OPLOG,	FORCC,
-	SCON|SAREG,	TWORD|TPOINT,
-	SAREG|SOREG|SNAME,	TWORD|TPOINT,
-		0, 	RESCC,
-		"	cmpl AR,AL\n", },
-
-{ OPLOG,	FORCC,
-	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
-	SCON|SAREG,	TANY,
-		0, 	RESCC,
-		"	cmpw AR,AL\n", },
-
-{ OPLOG,	FORCC,
-	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
-	SCON|SBREG,	TANY,
-		0, 	RESCC,
-		"	cmpb AR,AL\n", },
-
-{ OPLOG,	FORCC,
-	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
-	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
-		NSPECIAL, 	0,
-		"ZG", },
-
-{ OPLOG,	FORCC,
-	SOREG|SNAME,	TDOUBLE|TFLOAT,
-	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
-		NSPECIAL, 	0,
-		"ZG", },
-
-#if 0
-/* Ppro and later only */
-{ OPLOG,	FORCC,
-	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
-	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
-		0, 	RESCC,
-		"ZA	fucomip %st,%st(1)\n", },
-#endif
-
-{ OPLOG,	FORCC,
-	SANY,	TANY,
-	SANY,	TANY,
-		REWRITE,	0,
-		"diediedie!", },
-
-/* AND/OR/ER/NOT */
-{ AND,	INAREG|FOREFF,
-	SAREG|SOREG|SNAME,	TWORD,
-	SCON|SAREG,		TWORD,
-		0,	RLEFT,
-		"	andl AR,AL\n", },
-
-{ AND,	INCREG|FOREFF,
-	SCREG,			TLL,
-	SCREG|SOREG|SNAME,	TLL,
-		0,	RLEFT,
-		"	andl AR,AL\n	andl UR,UL\n", },
-
-{ AND,	INAREG|FOREFF,
-	SAREG,			TWORD,
-	SAREG|SOREG|SNAME,	TWORD,
-		0,	RLEFT,
-		"	andl AR,AL\n", },
-
-{ AND,	INAREG|FOREFF,  
-	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
-	SCON|SAREG,		TSHORT|TUSHORT,
-		0,	RLEFT,
-		"	andw AR,AL\n", },
-
-{ AND,	INAREG|FOREFF,  
-	SAREG,			TSHORT|TUSHORT,
-	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
-		0,	RLEFT,
-		"	andw AR,AL\n", },
-
-{ AND,	INBREG|FOREFF,
-	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
-	SCON|SBREG,		TCHAR|TUCHAR,
-		0,	RLEFT,
-		"	andb AR,AL\n", },
-
-{ AND,	INBREG|FOREFF,
-	SBREG,			TCHAR|TUCHAR,
-	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
-		0,	RLEFT,
-		"	andb AR,AL\n", },
-/* AND/OR/ER/NOT */
-
-/*
- * Jumps.
- */
-{ GOTO, 	FOREFF,
-	SCON,	TANY,
-	SANY,	TANY,
-		0,	RNOP,
-		"	jmp LL\n", },
-
-#ifdef GCC_COMPAT
-{ GOTO, 	FOREFF,
-	SAREG,	TANY,
-	SANY,	TANY,
-		0,	RNOP,
-		"	jmp *AL\n", },
-#endif
-
-/*
- * Convert LTYPE to reg.
- */
-{ OPLTYPE,	INLL,
-	SANY,	TANY,
-	SCREG|SCON|SOREG|SNAME,	TLL,
-		NCREG,	RESC1,
-		"	movl UL,U1\n	movl AL,A1\n", },
-
-{ OPLTYPE,	INAREG,
-	SANY,	TANY,
-	SAREG|SCON|SOREG|SNAME,	TWORD|TPOINT,
-		NAREG|NASL,	RESC1,
-		"	movl AL,A1\n", },
-
-{ OPLTYPE,	INBREG,
-	SANY,	TANY,
-	SBREG|SOREG|SNAME|SCON,	TCHAR|TUCHAR,
-		NBREG,	RESC1,
-		"	movb AL,A1\n", },
-
-{ OPLTYPE,	INAREG,
-	SANY,	TANY,
-	SAREG|SOREG|SNAME|SCON,	TSHORT|TUSHORT,
-		NAREG,	RESC1,
-		"	movw AL,A1\n", },
-
-{ OPLTYPE,	INDREG,
-	SANY,		TLDOUBLE,
-	SOREG|SNAME,	TLDOUBLE,
-		NDREG,	RESC1,
-		"	fldt AL\n", },
-
-{ OPLTYPE,	INDREG,
-	SANY,		TDOUBLE,
-	SOREG|SNAME,	TDOUBLE,
-		NDREG,	RESC1,
-		"	fldl AL\n", },
-
-{ OPLTYPE,	INDREG,
-	SANY,		TFLOAT,
-	SOREG|SNAME,	TFLOAT,
-		NDREG,	RESC1,
-		"	flds AL\n", },
-
-/* Only used in ?: constructs. The stack already contains correct value */
-{ OPLTYPE,	INDREG,
-	SANY,	TFLOAT|TDOUBLE|TLDOUBLE,
-	SDREG,	TFLOAT|TDOUBLE|TLDOUBLE,
-		NDREG,	RESC1,
-		"", },
-
-/*
- * Negate a word.
- */
-
-{ UMINUS,	INCREG|FOREFF,
-	SCREG,	TLL,
-	SCREG,	TLL,
-		0,	RLEFT,
-		"	negl AL\n	adcl $0,UL\n	negl UL\n", },
-
-{ UMINUS,	INAREG|FOREFF,
-	SAREG,	TWORD|TPOINT,
-	SAREG,	TWORD|TPOINT,
-		0,	RLEFT,
-		"	negl AL\n", },
-
-{ UMINUS,	INAREG|FOREFF,
-	SAREG,	TSHORT|TUSHORT,
-	SAREG,	TSHORT|TUSHORT,
-		0,	RLEFT,
-		"	negw AL\n", },
-
-{ UMINUS,	INBREG|FOREFF,
-	SBREG,	TCHAR|TUCHAR,
-	SBREG,	TCHAR|TUCHAR,
-		0,	RLEFT,
-		"	negb AL\n", },
-
-{ UMINUS,	INFL|FOREFF,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
-		0,	RLEFT,
-		"	fchs\n", },
-
-{ COMPL,	INCREG,
-	SCREG,	TLL,
-	SANY,	TANY,
-		0,	RLEFT,
-		"	notl AL\n	notl UL\n", },
-
-{ COMPL,	INAREG,
-	SAREG,	TWORD,
-	SANY,	TANY,
-		0,	RLEFT,
-		"	notl AL\n", },
-
-{ COMPL,	INAREG,
-	SAREG,	TSHORT|TUSHORT,
-	SANY,	TANY,
-		0,	RLEFT,
-		"	notw AL\n", },
-
-{ COMPL,	INBREG,
-	SBREG,	TCHAR|TUCHAR,
-	SANY,	TANY,
-		0,	RLEFT,
-		"	notb AL\n", },
-
-/*
- * Arguments to functions.
- */
-{ FUNARG,	FOREFF,
-	SCON|SCREG|SNAME|SOREG,	TLL,
-	SANY,	TLL,
-		0,	RNULL,
-		"	pushl UL\n	pushl AL\n", },
-
-{ FUNARG,	FOREFF,
-	SCON|SAREG|SNAME|SOREG,	TWORD|TPOINT,
-	SANY,	TWORD|TPOINT,
-		0,	RNULL,
-		"	pushl AL\n", },
-
-{ FUNARG,	FOREFF,
-	SCON,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
-	SANY,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
-		0,	RNULL,
-		"	pushl AL\n", },
-
-{ FUNARG,	FOREFF,
-	SAREG|SNAME|SOREG,	TSHORT,
-	SANY,	TSHORT,
-		NAREG,	0,
-		"	movswl AL,ZN\n	pushl ZN\n", },
-
-{ FUNARG,	FOREFF,
-	SAREG|SNAME|SOREG,	TUSHORT,
-	SANY,	TUSHORT,
-		NAREG,	0,
-		"	movzwl AL,ZN\n	pushl ZN\n", },
-
-{ FUNARG,	FOREFF,
-	SHCH|SNAME|SOREG,	TCHAR,
-	SANY,			TCHAR,
-		NAREG,	0,
-		"	movsbl AL,A1\n	pushl A1\n", },
-
-{ FUNARG,	FOREFF,
-	SHCH|SNAME|SOREG,	TUCHAR,
-	SANY,	TUCHAR,
-		NAREG,	0,
-		"	movzbl AL,A1\n	pushl A1\n", },
-
-{ FUNARG,	FOREFF,
-	SNAME|SOREG,	TDOUBLE,
-	SANY,	TDOUBLE,
-		0,	0,
-		"	pushl UL\n	pushl AL\n", },
-
-{ FUNARG,	FOREFF,
-	SDREG,	TDOUBLE,
-	SANY,		TDOUBLE,
-		0,	0,
-		"	subl $8,%esp\n	fstpl (%esp)\n", },
-
-{ FUNARG,	FOREFF,
-	SNAME|SOREG,	TFLOAT,
-	SANY,		TFLOAT,
-		0,	0,
-		"	pushl AL\n", },
-
-{ FUNARG,	FOREFF,
-	SDREG,	TFLOAT,
-	SANY,		TFLOAT,
-		0,	0,
-		"	subl $4,%esp\n	fstps (%esp)\n", },
-
-{ FUNARG,	FOREFF,
-	SDREG,	TLDOUBLE,
-	SANY,		TLDOUBLE,
-		0,	0,
-		"	subl $12,%esp\n	fstpt (%esp)\n", },
-
-{ STARG,	FOREFF,
-	SAREG|SOREG|SNAME|SCON,	TANY,
-	SANY,	TSTRUCT,
-		NSPECIAL|NAREG,	0,
-		"ZF", },
-
-# define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
-
-{ UMUL, DF( UMUL ), },
-
-{ ASSIGN, DF(ASSIGN), },
-
-{ STASG, DF(STASG), },
-
-{ FLD, DF(FLD), },
-
-{ OPLEAF, DF(NAME), },
-
-/* { INIT, DF(INIT), }, */
-
-{ OPUNARY, DF(UMINUS), },
-
-{ OPANY, DF(BITYPE), },
-
-{ FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	"help; I'm in trouble\n" },
-};
-
-int tablesize = sizeof(table)/sizeof(table[0]);
--- usr.bin/pcc/arch/x86/local2.c
+++ /dev/null
@@ -1,1052 +0,0 @@
-/*	$Id: local2.c,v 1.89 2007/09/16 19:08:16 ragge Exp $	*/
-/*
- * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-# include "pass2.h"
-# include <ctype.h>
-# include <string.h>
-
-void acon(NODE *p);
-int argsize(NODE *p);
-
-static int stkpos;
-
-void
-lineid(int l, char *fn)
-{
-	/* identify line l and file fn */
-	printf("#	line %d, file %s\n", l, fn);
-}
-
-void
-deflab(int label)
-{
-	printf(LABFMT ":\n", label);
-}
-
-static int regoff[7];
-static TWORD ftype;
-
-/*
- * Print out the prolog assembler.
- * addto and regoff are already calculated.
- */
-static void
-prtprolog(struct interpass_prolog *ipp, int addto)
-{
-	int i, j;
-
-	printf("	pushl %%ebp\n");
-	printf("	movl %%esp,%%ebp\n");
-	if (addto)
-		printf("	subl $%d,%%esp\n", addto);
-	for (i = ipp->ipp_regs, j = 0; i; i >>= 1, j++)
-		if (i & 1)
-			fprintf(stdout, "	movl %s,-%d(%s)\n",
-			    rnames[j], regoff[j], rnames[FPREG]);
-}
-
-/*
- * calculate stack size and offsets
- */
-static int
-offcalc(struct interpass_prolog *ipp)
-{
-	int i, j, addto;
-
-	addto = p2maxautooff;
-	if (addto >= AUTOINIT/SZCHAR)
-		addto -= AUTOINIT/SZCHAR;
-	for (i = ipp->ipp_regs, j = 0; i ; i >>= 1, j++) {
-		if (i & 1) {
-			addto += SZINT/SZCHAR;
-			regoff[j] = addto;
-		}
-	}
-	return addto;
-}
-
-void
-prologue(struct interpass_prolog *ipp)
-{
-	int addto;
-
-	ftype = ipp->ipp_type;
-	if (ipp->ipp_vis)
-		printf("	.globl %s\n", ipp->ipp_name);
-	printf("	.align 4\n");
-	printf("%s:\n", ipp->ipp_name);
-	/*
-	 * We here know what register to save and how much to 
-	 * add to the stack.
-	 */
-	addto = offcalc(ipp);
-	prtprolog(ipp, addto);
-}
-
-void
-eoftn(struct interpass_prolog *ipp)
-{
-	int i, j;
-
-	if (ipp->ipp_ip.ip_lbl == 0)
-		return; /* no code needs to be generated */
-
-	/* return from function code */
-	for (i = ipp->ipp_regs, j = 0; i ; i >>= 1, j++) {
-		if (i & 1)
-			fprintf(stdout, "	movl -%d(%s),%s\n",
-			    regoff[j], rnames[FPREG], rnames[j]);
-			
-	}
-
-	/* struct return needs special treatment */
-	if (ftype == STRTY || ftype == UNIONTY) {
-		printf("	movl 8(%%ebp),%%eax\n");
-		printf("	leave\n");
-		printf("	ret $4\n");
-	} else {
-		printf("	leave\n");
-		printf("	ret\n");
-	}
-}
-
-/*
- * add/sub/...
- *
- * Param given:
- */
-void
-hopcode(int f, int o)
-{
-	char *str;
-
-	switch (o) {
-	case PLUS:
-		str = "add";
-		break;
-	case MINUS:
-		str = "sub";
-		break;
-	case AND:
-		str = "and";
-		break;
-	case OR:
-		str = "or";
-		break;
-	case ER:
-		str = "xor";
-		break;
-	default:
-		comperr("hopcode2: %d", o);
-		str = 0; /* XXX gcc */
-	}
-	printf("%s%c", str, f);
-}
-
-/*
- * Return type size in bytes.  Used by R2REGS, arg 2 to offset().
- */
-int
-tlen(p) NODE *p;
-{
-	switch(p->n_type) {
-		case CHAR:
-		case UCHAR:
-			return(1);
-
-		case SHORT:
-		case USHORT:
-			return(SZSHORT/SZCHAR);
-
-		case DOUBLE:
-			return(SZDOUBLE/SZCHAR);
-
-		case INT:
-		case UNSIGNED:
-		case LONG:
-		case ULONG:
-			return(SZINT/SZCHAR);
-
-		case LONGLONG:
-		case ULONGLONG:
-			return SZLONGLONG/SZCHAR;
-
-		default:
-			if (!ISPTR(p->n_type))
-				comperr("tlen type %d not pointer");
-			return SZPOINT(p->n_type)/SZCHAR;
-		}
-}
-
-/*
- * Emit code to compare two longlong numbers.
- */
-static void
-twollcomp(NODE *p)
-{
-	int o = p->n_op;
-	int s = getlab();
-	int e = p->n_label;
-	int cb1, cb2;
-
-	if (o >= ULE)
-		o -= (ULE-LE);
-	switch (o) {
-	case NE:
-		cb1 = 0;
-		cb2 = NE;
-		break;
-	case EQ:
-		cb1 = NE;
-		cb2 = 0;
-		break;
-	case LE:
-	case LT:
-		cb1 = GT;
-		cb2 = LT;
-		break;
-	case GE:
-	case GT:
-		cb1 = LT;
-		cb2 = GT;
-		break;
-	
-	default:
-		cb1 = cb2 = 0; /* XXX gcc */
-	}
-	if (p->n_op >= ULE)
-		cb1 += 4, cb2 += 4;
-	expand(p, 0, "	cmpl UR,UL\n");
-	if (cb1) cbgen(cb1, s);
-	if (cb2) cbgen(cb2, e);
-	expand(p, 0, "	cmpl AR,AL\n");
-	cbgen(p->n_op, e);
-	deflab(s);
-}
-
-/*
- * Assign to a bitfield.
- * Clumsy at least, but what to do?
- */
-static void
-bfasg(NODE *p)
-{
-	NODE *fn = p->n_left;
-	int shift = UPKFOFF(fn->n_rval);
-	int fsz = UPKFSZ(fn->n_rval);
-	int andval, tch = 0;
-
-	/* get instruction size */
-	switch (p->n_type) {
-	case CHAR: case UCHAR: tch = 'b'; break;
-	case SHORT: case USHORT: tch = 'w'; break;
-	case INT: case UNSIGNED: tch = 'l'; break;
-	default: comperr("bfasg");
-	}
-
-	/* put src into a temporary reg */
-	fprintf(stdout, "	mov%c ", tch);
-	adrput(stdout, getlr(p, 'R'));
-	fprintf(stdout, ",");
-	adrput(stdout, getlr(p, '1'));
-	fprintf(stdout, "\n");
-
-	/* AND away the bits from dest */
-	andval = ~(((1 << fsz) - 1) << shift);
-	fprintf(stdout, "	and%c $%d,", tch, andval);
-	adrput(stdout, fn->n_left);
-	fprintf(stdout, "\n");
-
-	/* AND away unwanted bits from src */
-	andval = ((1 << fsz) - 1);
-	fprintf(stdout, "	and%c $%d,", tch, andval);
-	adrput(stdout, getlr(p, '1'));
-	fprintf(stdout, "\n");
-
-	/* SHIFT left src number of bits */
-	if (shift) {
-		fprintf(stdout, "	sal%c $%d,", tch, shift);
-		adrput(stdout, getlr(p, '1'));
-		fprintf(stdout, "\n");
-	}
-
-	/* OR in src to dest */
-	fprintf(stdout, "	or%c ", tch);
-	adrput(stdout, getlr(p, '1'));
-	fprintf(stdout, ",");
-	adrput(stdout, fn->n_left);
-	fprintf(stdout, "\n");
-}
-
-/*
- * Push a structure on stack as argument.
- * the scratch registers are already free here
- */
-static void
-starg(NODE *p)
-{
-	FILE *fp = stdout;
-
-	fprintf(fp, "	subl $%d,%%esp\n", p->n_stsize);
-	fprintf(fp, "	pushl $%d\n", p->n_stsize);
-	expand(p, 0, "	pushl AL\n");
-	expand(p, 0, "	leal 8(%esp),A1\n");
-	expand(p, 0, "	pushl A1\n");
-	fprintf(fp, "	call memcpy\n");
-	fprintf(fp, "	addl $12,%%esp\n");
-}
-
-/*
- * Compare two floating point numbers.
- */
-static void
-fcomp(NODE *p)  
-{
-	
-	if (p->n_left->n_op == REG) {
-		if (p->n_su & DORIGHT)
-			expand(p, 0, "	fxch\n");
-		expand(p, 0, "	fucompp\n");	/* emit compare insn  */
-	} else if (p->n_left->n_type == DOUBLE)
-		expand(p, 0, "	fcompl AL\n");	/* emit compare insn  */
-	else if (p->n_left->n_type == FLOAT)
-		expand(p, 0, "	fcomp AL\n");	/* emit compare insn  */
-	else
-		comperr("bad compare %p\n", p);
-	expand(p, 0, "	fnstsw %ax\n");	/* move status reg to ax */
-	
-	switch (p->n_op) {
-	case EQ:
-		expand(p, 0, "	andb $64,%ah\n	jne LC\n");
-		break;
-	case NE:
-		expand(p, 0, "	andb $64,%ah\n	je LC\n");
-		break;
-	case LE:
-		expand(p, 0, "	andb $65,%ah\n	cmpb $1,%ah\n	jne LC\n");
-		break;
-	case LT:
-		expand(p, 0, "	andb $65,%ah\n	je LC\n");
-		break;
-	case GT:
-		expand(p, 0, "	andb $1,%ah\n	jne LC\n");
-		break;
-	case GE:
-		expand(p, 0, "	andb $65,%ah\n	jne LC\n");
-		break;
-	default:
-		comperr("fcomp op %d\n", p->n_op);
-	}
-}
-
-/*
- * Convert an unsigned long long to floating point number.
- */
-static void
-ulltofp(NODE *p)
-{
-	static int loadlab;
-	int jmplab;
-
-	if (loadlab == 0) {
-		loadlab = getlab();
-		expand(p, 0, "	.data\n");
-		printf(LABFMT ":	.long 0,0x80000000,0x403f\n", loadlab);
-		expand(p, 0, "	.text\n");
-	}
-	jmplab = getlab();
-	expand(p, 0, "	pushl UL\n	pushl AL\n");
-	expand(p, 0, "	fildq (%esp)\n");
-	expand(p, 0, "	addl $8,%esp\n");
-	expand(p, 0, "	cmpl $0,UL\n");
-	printf("	jge " LABFMT "\n", jmplab);
-	printf("	fldt " LABFMT "\n", loadlab);
-	printf("	faddp %%st,%%st(1)\n");
-	printf(LABFMT ":\n", jmplab);
-}
-
-static int
-argsiz(NODE *p)
-{
-	TWORD t = p->n_type;
-
-	if (t < LONGLONG || t == FLOAT || t > BTMASK)
-		return 4;
-	if (t == LONGLONG || t == ULONGLONG || t == DOUBLE)
-		return 8;
-	if (t == LDOUBLE)
-		return 12;
-	if (t == STRTY || t == UNIONTY)
-		return p->n_stsize;
-	comperr("argsiz");
-	return 0;
-}
-
-void
-zzzcode(NODE *p, int c)
-{
-	NODE *r, *l;
-	int pr, lr, s;
-	char *ch;
-
-	switch (c) {
-	case 'A': /* swap st0 and st1 if right is evaluated second */
-		if ((p->n_su & DORIGHT) == 0) {
-			if (logop(p->n_op))
-				printf("	fxch\n");
-			else
-				printf("r");
-		}
-		break;
-
-	case 'C':  /* remove from stack after subroutine call */
-		pr = p->n_qual;
-		if (p->n_op == STCALL || p->n_op == USTCALL)
-			pr += 4;
-		if (p->n_op == UCALL)
-			return; /* XXX remove ZC from UCALL */
-		if (pr)
-			printf("	addl $%d, %s\n", pr, rnames[ESP]);
-		break;
-
-	case 'D': /* Long long comparision */
-		twollcomp(p);
-		break;
-
-	case 'E': /* Assign to bitfield */
-		bfasg(p);
-		break;
-
-	case 'F': /* Structure argument */
-		if (p->n_stalign != 0) /* already on stack */
-			starg(p);
-		break;
-
-	case 'G': /* Floating point compare */
-		fcomp(p);
-		break;
-
-	case 'J': /* convert unsigned long long to floating point */
-		ulltofp(p);
-		break;
-
-	case 'M': /* Output sconv move, if needed */
-		l = getlr(p, 'L');
-		/* XXX fixneed: regnum */
-		pr = DECRA(p->n_reg, 0);
-		lr = DECRA(l->n_reg, 0);
-		if ((pr == AL && lr == EAX) || (pr == BL && lr == EBX) ||
-		    (pr == CL && lr == ECX) || (pr == DL && lr == EDX))
-			;
-		else
-			printf("	movb %%%cl,%s\n",
-			    rnames[lr][2], rnames[pr]);
-		l->n_rval = l->n_reg = p->n_reg; /* XXX - not pretty */
-		break;
-
-	case 'N': /* output extended reg name */
-		printf("%s", rnames[getlr(p, '1')->n_rval]);
-		break;
-
-	case 'O': /* print out emulated ops */
-		pr = 16;
-		if (p->n_op == RS || p->n_op == LS) {
-			expand(p, INAREG, "\tpushl AR\n");
-			pr = 12;
-		} else
-			expand(p, INCREG, "\tpushl UR\n\tpushl AR\n");
-		expand(p, INCREG, "\tpushl UL\n\tpushl AL\n");
-		if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
-		else if (p->n_op == DIV) ch = "div";
-		else if (p->n_op == MUL) ch = "mul";
-		else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
-		else if (p->n_op == MOD) ch = "mod";
-		else if (p->n_op == RS && p->n_type == ULONGLONG) ch = "lshr";
-		else if (p->n_op == RS) ch = "ashr";
-		else if (p->n_op == LS) ch = "ashl";
-		else ch = 0, comperr("ZO");
-		printf("\tcall __%sdi3\n\taddl $%d,%s\n", ch, pr, rnames[ESP]);
-                break;
-
-	case 'P': /* push hidden argument on stack */
-		r = (NODE *)p->n_sue;
-		printf("\tleal -%d(%%ebp),", stkpos);
-		adrput(stdout, getlr(p, '1'));
-		printf("\n\tpushl ");
-		adrput(stdout, getlr(p, '1'));
-		putchar('\n');
-		break;
-
-	case 'Q': /* emit struct assign */
-		/* XXX - optimize for small structs */
-		printf("\tpushl $%d\n", p->n_stsize);
-		expand(p, INAREG, "\tpushl AR\n");
-		expand(p, INAREG, "\tleal AL,%eax\n\tpushl %eax\n");
-		printf("\tcall memcpy\n");
-		printf("\taddl $12,%%esp\n");
-		break;
-
-	case 'S': /* emit eventual move after cast from longlong */
-		pr = DECRA(p->n_reg, 0);
-		lr = p->n_left->n_rval;
-		switch (p->n_type) {
-		case CHAR:
-		case UCHAR:
-			if (rnames[pr][2] == 'l' && rnames[lr][2] == 'x' &&
-			    rnames[pr][1] == rnames[lr][1])
-				break;
-			if (rnames[lr][2] == 'x') {
-				printf("\tmovb %%%cl,%s\n",
-				    rnames[lr][1], rnames[pr]);
-				break;
-			}
-			/* Must go via stack */
-			s = BITOOR(freetemp(1));
-			printf("\tmovl %%e%ci,%d(%%ebp)\n", rnames[lr][1], s);
-			printf("\tmovb %d(%%ebp),%s\n", s, rnames[pr]);
-//			comperr("SCONV1 %s->%s", rnames[lr], rnames[pr]);
-			break;
-
-		case SHORT:
-		case USHORT:
-			if (rnames[lr][1] == rnames[pr][2] &&
-			    rnames[lr][2] == rnames[pr][3])
-				break;
-			printf("\tmovw %%%c%c,%%%s\n",
-			    rnames[lr][1], rnames[lr][2], rnames[pr]+2);
-			break;
-		case INT:
-		case UNSIGNED:
-			if (rnames[lr][1] == rnames[pr][2] &&
-			    rnames[lr][2] == rnames[pr][3])
-				break;
-			printf("\tmovl %%e%c%c,%s\n",
-				    rnames[lr][1], rnames[lr][2], rnames[pr]);
-			break;
-
-		default:
-			if (rnames[lr][1] == rnames[pr][2] &&
-			    rnames[lr][2] == rnames[pr][3])
-				break;
-			comperr("SCONV2 %s->%s", rnames[lr], rnames[pr]);
-			break;
-		}
-		break;
-
-	default:
-		comperr("zzzcode %c", c);
-	}
-}
-
-/*ARGSUSED*/
-int
-rewfld(NODE *p)
-{
-	return(1);
-}
-
-int canaddr(NODE *);
-int
-canaddr(NODE *p)
-{
-	int o = p->n_op;
-
-	if (o==NAME || o==REG || o==ICON || o==OREG ||
-	    (o==UMUL && shumul(p->n_left)))
-		return(1);
-	return(0);
-}
-
-/*
- * Does the bitfield shape match?
- */
-int
-flshape(NODE *p)
-{
-	int o = p->n_op;
-
-	if (o == OREG || o == REG || o == NAME)
-		return SRDIR; /* Direct match */
-	if (o == UMUL && shumul(p->n_left))
-		return SROREG; /* Convert into oreg */
-	return SRREG; /* put it into a register */
-}
-
-/* INTEMP shapes must not contain any temporary registers */
-/* XXX should this go away now? */
-int
-shtemp(NODE *p)
-{
-	return 0;
-#if 0
-	int r;
-
-	if (p->n_op == STARG )
-		p = p->n_left;
-
-	switch (p->n_op) {
-	case REG:
-		return (!istreg(p->n_rval));
-
-	case OREG:
-		r = p->n_rval;
-		if (R2TEST(r)) {
-			if (istreg(R2UPK1(r)))
-				return(0);
-			r = R2UPK2(r);
-		}
-		return (!istreg(r));
-
-	case UMUL:
-		p = p->n_left;
-		return (p->n_op != UMUL && shtemp(p));
-	}
-
-	if (optype(p->n_op) != LTYPE)
-		return(0);
-	return(1);
-#endif
-}
-
-void
-adrcon(CONSZ val)
-{
-	printf("$" CONFMT, val);
-}
-
-void
-conput(FILE *fp, NODE *p)
-{
-	int val = p->n_lval;
-
-	switch (p->n_op) {
-	case ICON:
-		if (p->n_name[0] != '\0') {
-			fprintf(fp, "%s", p->n_name);
-			if (val)
-				fprintf(fp, "+%d", val);
-		} else
-			fprintf(fp, "%d", val);
-		return;
-
-	default:
-		comperr("illegal conput, p %p", p);
-	}
-}
-
-/*ARGSUSED*/
-void
-insput(NODE *p)
-{
-	comperr("insput");
-}
-
-/*
- * Write out the upper address, like the upper register of a 2-register
- * reference, or the next memory location.
- */
-void
-upput(NODE *p, int size)
-{
-
-	size /= SZCHAR;
-	switch (p->n_op) {
-	case REG:
-		fprintf(stdout, "%%%s", &rnames[p->n_rval][3]);
-		break;
-
-	case NAME:
-	case OREG:
-		p->n_lval += size;
-		adrput(stdout, p);
-		p->n_lval -= size;
-		break;
-	case ICON:
-		fprintf(stdout, "$" CONFMT, p->n_lval >> 32);
-		break;
-	default:
-		comperr("upput bad op %d size %d", p->n_op, size);
-	}
-}
-
-void
-adrput(FILE *io, NODE *p)
-{
-	int r;
-	/* output an address, with offsets, from p */
-
-	if (p->n_op == FLD)
-		p = p->n_left;
-
-	switch (p->n_op) {
-
-	case NAME:
-		if (p->n_name[0] != '\0') {
-			fputs(p->n_name, io);
-			if (p->n_lval != 0)
-				fprintf(io, "+" CONFMT, p->n_lval);
-		} else
-			fprintf(io, CONFMT, p->n_lval);
-		return;
-
-	case OREG:
-		r = p->n_rval;
-		if (p->n_lval)
-			fprintf(io, "%d", (int)p->n_lval);
-		if (R2TEST(r)) {
-			fprintf(io, "(%s,%s,4)", rnames[R2UPK1(r)],
-			    rnames[R2UPK2(r)]);
-		} else
-			fprintf(io, "(%s)", rnames[p->n_rval]);
-		return;
-	case ICON:
-		/* addressable value of the constant */
-		fputc('$', io);
-		conput(io, p);
-		return;
-
-	case MOVE:
-	case REG:
-		switch (p->n_type) {
-		case LONGLONG:
-		case ULONGLONG:
-			fprintf(io, "%%%c%c%c", rnames[p->n_rval][0],
-			    rnames[p->n_rval][1], rnames[p->n_rval][2]);
-			break;
-		case SHORT:
-		case USHORT:
-			fprintf(io, "%%%s", &rnames[p->n_rval][2]);
-			break;
-		default:
-			fprintf(io, "%s", rnames[p->n_rval]);
-		}
-		return;
-
-	default:
-		comperr("illegal address, op %d, node %p", p->n_op, p);
-		return;
-
-	}
-}
-
-static char *
-ccbranches[] = {
-	"je",		/* jumpe */
-	"jne",		/* jumpn */
-	"jle",		/* jumple */
-	"jl",		/* jumpl */
-	"jge",		/* jumpge */
-	"jg",		/* jumpg */
-	"jbe",		/* jumple (jlequ) */
-	"jb",		/* jumpl (jlssu) */
-	"jae",		/* jumpge (jgequ) */
-	"ja",		/* jumpg (jgtru) */
-};
-
-
-/*   printf conditional and unconditional branches */
-void
-cbgen(int o, int lab)
-{
-	if (o < EQ || o > UGT)
-		comperr("bad conditional branch: %s", opst[o]);
-	printf("	%s " LABFMT "\n", ccbranches[o-EQ], lab);
-}
-
-static void
-fixcalls(NODE *p)
-{
-	/* Prepare for struct return by allocating bounce space on stack */
-	switch (p->n_op) {
-	case STCALL:
-	case USTCALL:
-		if (p->n_stsize+p2autooff > stkpos)
-			stkpos = p->n_stsize+p2autooff;
-		break;
-	}
-}
-
-/*
- * Must store floats in memory if there are two function calls involved.
- */
-static int
-storefloat(struct interpass *ip, NODE *p)
-{
-	int l, r;
-
-	switch (optype(p->n_op)) {
-	case BITYPE:
-		l = storefloat(ip, p->n_left);
-		r = storefloat(ip, p->n_right);
-		if (p->n_op == CM)
-			return 0; /* arguments, don't care */
-		if (callop(p->n_op))
-			return 1; /* found one */
-#define ISF(p) ((p)->n_type == FLOAT || (p)->n_type == DOUBLE || \
-	(p)->n_type == LDOUBLE)
-		if (ISF(p->n_left) && ISF(p->n_right) && l && r) {
-			/* must store one. store left */
-			struct interpass *nip;
-			TWORD t = p->n_left->n_type;
-			NODE *ll;
-			int off;
-
-                	off = BITOOR(freetemp(szty(t)));
-                	ll = mklnode(OREG, off, FPREG, t);
-			nip = ipnode(mkbinode(ASSIGN, ll, p->n_left, t));
-			p->n_left = mklnode(OREG, off, FPREG, t);
-                	DLIST_INSERT_BEFORE(ip, nip, qelem);
-		}
-		return l|r;
-
-	case UTYPE:
-		l = storefloat(ip, p->n_left);
-		if (callop(p->n_op))
-			l = 1;
-		return l;
-	default:
-		return 0;
-	}
-}
-
-void
-myreader(struct interpass *ipole)
-{
-	struct interpass *ip;
-
-	stkpos = p2autooff;
-	DLIST_FOREACH(ip, ipole, qelem) {
-		if (ip->type != IP_NODE)
-			continue;
-		walkf(ip->ip_node, fixcalls);
-		storefloat(ip, ip->ip_node);
-	}
-	if (stkpos > p2autooff)
-		p2autooff = stkpos;
-	if (stkpos > p2maxautooff)
-		p2maxautooff = stkpos;
-	if (x2debug)
-		printip(ipole);
-}
-
-/*
- * Remove some PCONVs after OREGs are created.
- */
-static void
-pconv2(NODE *p)
-{
-	NODE *q;
-
-	if (p->n_op == PLUS) {
-		if (p->n_type == (PTR|SHORT) || p->n_type == (PTR|USHORT)) {
-			if (p->n_right->n_op != ICON)
-				return;
-			if (p->n_left->n_op != PCONV)
-				return;
-			if (p->n_left->n_left->n_op != OREG)
-				return;
-			q = p->n_left->n_left;
-			nfree(p->n_left);
-			p->n_left = q;
-			/*
-			 * This will be converted to another OREG later.
-			 */
-		}
-	}
-}
-
-void
-mycanon(NODE *p)
-{
-	walkf(p, pconv2);
-}
-
-void
-myoptim(struct interpass *ip)
-{
-}
-
-static char rl[] =
-  { EAX, EAX, EAX, EAX, EAX, EDX, EDX, EDX, EDX, ECX, ECX, ECX, EBX, EBX, ESI };
-static char rh[] =
-  { EDX, ECX, EBX, ESI, EDI, ECX, EBX, ESI, EDI, EBX, ESI, EDI, ESI, EDI, EDI };
-
-void
-rmove(int s, int d, TWORD t)
-{
-	int sl, sh, dl, dh;
-
-	switch (t) {
-	case LONGLONG:
-	case ULONGLONG:
-#if 1
-		sl = rl[s-EAXEDX];
-		sh = rh[s-EAXEDX];
-		dl = rl[d-EAXEDX];
-		dh = rh[d-EAXEDX];
-
-		/* sanity checks, remove when satisfied */
-		if (memcmp(rnames[s], rnames[sl]+1, 3) != 0 ||
-		    memcmp(rnames[s]+3, rnames[sh]+1, 3) != 0)
-			comperr("rmove source error");
-		if (memcmp(rnames[d], rnames[dl]+1, 3) != 0 ||
-		    memcmp(rnames[d]+3, rnames[dh]+1, 3) != 0)
-			comperr("rmove dest error");
-#define	SW(x,y) { int i = x; x = y; y = i; }
-		if (sl == dh || sh == dl) {
-			/* Swap if moving to itself */
-			SW(sl, sh);
-			SW(dl, dh);
-		}
-		if (sl != dl)
-			printf("	movl %s,%s\n", rnames[sl], rnames[dl]);
-		if (sh != dh)
-			printf("	movl %s,%s\n", rnames[sh], rnames[dh]);
-#else
-		if (memcmp(rnames[s], rnames[d], 3) != 0)
-			printf("	movl %%%c%c%c,%%%c%c%c\n",
-			    rnames[s][0],rnames[s][1],rnames[s][2],
-			    rnames[d][0],rnames[d][1],rnames[d][2]);
-		if (memcmp(&rnames[s][3], &rnames[d][3], 3) != 0)
-			printf("	movl %%%c%c%c,%%%c%c%c\n",
-			    rnames[s][3],rnames[s][4],rnames[s][5],
-			    rnames[d][3],rnames[d][4],rnames[d][5]);
-#endif
-		break;
-	case CHAR:
-	case UCHAR:
-		printf("	movb %s,%s\n", rnames[s], rnames[d]);
-		break;
-	case FLOAT:
-	case DOUBLE:
-	case LDOUBLE:
-#ifdef notdef
-		/* a=b()*c(); will generate this */
-		comperr("bad float rmove: %d %d", s, d);
-#endif
-		break;
-	default:
-		printf("	movl %s,%s\n", rnames[s], rnames[d]);
-	}
-}
-
-/*
- * For class c, find worst-case displacement of the number of
- * registers in the array r[] indexed by class.
- */
-int
-COLORMAP(int c, int *r)
-{
-	int num;
-
-	switch (c) {
-	case CLASSA:
-		num = r[CLASSB] > 4 ? 4 : r[CLASSB];
-		num += 2*r[CLASSC];
-		num += r[CLASSA];
-		return num < 6;
-	case CLASSB:
-		num = r[CLASSA];
-		num += 2*r[CLASSC];
-		num += r[CLASSB];
-		return num < 4;
-	case CLASSC:
-		num = r[CLASSA];
-		num += r[CLASSB] > 4 ? 4 : r[CLASSB];
-		num += 2*r[CLASSC];
-		return num < 5;
-	case CLASSD:
-		return r[CLASSD] < DREGCNT;
-	}
-	return 0; /* XXX gcc */
-}
-
-char *rnames[] = {
-	"%eax", "%edx", "%ecx", "%ebx", "%esi", "%edi", "%ebp", "%esp",
-	"%al", "%ah", "%dl", "%dh", "%cl", "%ch", "%bl", "%bh",
-	"eaxedx", "eaxecx", "eaxebx", "eaxesi", "eaxedi", "edxecx",
-	"edxebx", "edxesi", "edxedi", "ecxebx", "ecxesi", "ecxedi",
-	"ebxesi", "ebxedi", "esiedi",
-	"%st0", "%st1", "%st2", "%st3", "%st4", "%st5", "%st6", "%st7",
-};
-
-/*
- * Return a class suitable for a specific type.
- */
-int
-gclass(TWORD t)
-{
-	if (t == CHAR || t == UCHAR)
-		return CLASSB;
-	if (t == LONGLONG || t == ULONGLONG)
-		return CLASSC;
-	if (t == FLOAT || t == DOUBLE || t == LDOUBLE)
-		return CLASSD;
-	return CLASSA;
-}
-
-/*
- * Calculate argument sizes.
- */
-void
-lastcall(NODE *p)
-{
-	NODE *op = p;
-	int size = 0;
-
-	p->n_qual = 0;
-	if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
-		return;
-	for (p = p->n_right; p->n_op == CM; p = p->n_left)
-		size += argsiz(p->n_right);
-	size += argsiz(p);
-	op->n_qual = size; /* XXX */
-}
-
-/*
- * Special shapes.
- */
-int
-special(NODE *p, int shape)
-{
-	int o = p->n_op;
-
-	switch (shape) {
-	case SFUNCALL:
-		if (o == STCALL || o == USTCALL)
-			return SRREG;
-		break;
-	case SPCON:
-		if (o != ICON || p->n_name[0] ||
-		    p->n_lval < 0 || p->n_lval > 0x7fffffff)
-			break;
-		return SRDIR;
-	}
-	return SRNOPE;
-}
--- usr.bin/pcc/arch/x86/code.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*	$Id: code.c,v 1.15 2007/07/06 17:02:27 ragge Exp $	*/
-/*
- * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-# include "pass1.h"
-
-/*
- * cause the alignment to become a multiple of n
- * never called for text segment.
- */
-void
-defalign(int n)
-{
-	n /= SZCHAR;
-	if (n == 1)
-		return;
-	printf("	.align %d\n", n);
-}
-
-/*
- * define the current location as the name p->sname
- * never called for text segment.
- */
-void
-defnam(struct symtab *p)
-{
-	char *c = p->sname;
-
-#ifdef GCC_COMPAT
-	c = gcc_findname(p);
-#endif
-	if (p->sclass == EXTDEF)
-		printf("	.globl %s\n", c);
-	printf("%s:\n", c);
-}
-
-
-/*
- * code for the end of a function
- * deals with struct return here
- */
-void
-efcode()
-{
-	NODE *p, *q;
-	int sz;
-
-	if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
-		return;
-	/* address of return struct is in eax */
-	/* create a call to memcpy() */
-	/* will get the result in eax */
-	p = block(REG, NIL, NIL, CHAR+PTR, 0, MKSUE(CHAR+PTR));
-	p->n_rval = EAX;
-	q = block(OREG, NIL, NIL, CHAR+PTR, 0, MKSUE(CHAR+PTR));
-	q->n_rval = EBP;
-	q->n_lval = 8; /* return buffer offset */
-	p = block(CM, q, p, INT, 0, MKSUE(INT));
-	sz = (tsize(STRTY, cftnsp->sdf, cftnsp->ssue)+SZCHAR-1)/SZCHAR;
-	p = block(CM, p, bcon(sz), INT, 0, MKSUE(INT));
-	p->n_right->n_name = "";
-	p = block(CALL, bcon(0), p, CHAR+PTR, 0, MKSUE(CHAR+PTR));
-	p->n_left->n_name = "memcpy";
-	p = clocal(p);
-	send_passt(IP_NODE, p);
-}
-
-/*
- * code for the beginning of a function; a is an array of
- * indices in symtab for the arguments; n is the number
- */
-void
-bfcode(struct symtab **a, int n)
-{
-	int i;
-
-	if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
-		return;
-	/* Function returns struct, adjust arg offset */
-	for (i = 0; i < n; i++)
-		a[i]->soffset += SZPOINT(INT);
-}
-
-
-/*
- * by now, the automatics and register variables are allocated
- */
-void
-bccode()
-{
-	SETOFF(autooff, SZINT);
-}
-
-/* called just before final exit */
-/* flag is 1 if errors, 0 if none */
-void
-ejobcode(int flag )
-{
-}
-
-void
-bjobcode()
-{
-}
-
-/*
- * Print character t at position i in one string, until t == -1.
- * Locctr & label is already defined.
- */
-void
-bycode(int t, int i)
-{
-	static	int	lastoctal = 0;
-
-	/* put byte i+1 in a string */
-
-	if (t < 0) {
-		if (i != 0)
-			puts("\"");
-	} else {
-		if (i == 0)
-			printf("\t.ascii \"");
-		if (t == '\\' || t == '"') {
-			lastoctal = 0;
-			putchar('\\');
-			putchar(t);
-		} else if (t < 040 || t >= 0177) {
-			lastoctal++;
-			printf("\\%o",t);
-		} else if (lastoctal && '0' <= t && t <= '9') {
-			lastoctal = 0;
-			printf("\"\n\t.ascii \"%c", t);
-		} else {	
-			lastoctal = 0;
-			putchar(t);
-		}
-	}
-}
-
-/*
- * n integer words of zeros
- */
-void
-zecode(int n)
-{
-	printf("	.zero %d\n", n * (SZINT/SZCHAR));
-//	inoff += n * SZINT;
-}
-
-/*
- * return the alignment of field of type t
- */
-int
-fldal(unsigned int t)
-{
-	uerror("illegal field type");
-	return(ALINT);
-}
-
-/* fix up type of field p */
-void
-fldty(struct symtab *p)
-{
-}
-
-/* p points to an array of structures, each consisting
- * of a constant value and a label.
- * The first is >=0 if there is a default label;
- * its value is the label number
- * The entries p[1] to p[n] are the nontrivial cases
- * XXX - fix genswitch.
- */
-void
-genswitch(int num, struct swents **p, int n)
-{
-	NODE *r;
-	int i;
-
-	/* simple switch code */
-	for (i = 1; i <= n; ++i) {
-		/* already in 1 */
-		r = tempnode(num, INT, 0, MKSUE(INT));
-		r = buildtree(NE, r, bcon(p[i]->sval));
-		cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab));
-	}
-	if (p[0]->slab > 0)
-		branch(p[0]->slab);
-}
--- usr.bin/pcc/arch/x86/local.c
+++ /dev/null
@@ -1,743 +0,0 @@
-/*	$Id: local.c,v 1.56 2007/09/24 16:23:36 ragge Exp $	*/
-/*
- * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include "pass1.h"
-
-/*	this file contains code which is dependent on the target machine */
-
-/* clocal() is called to do local transformations on
- * an expression tree preparitory to its being
- * written out in intermediate code.
- *
- * the major essential job is rewriting the
- * automatic variables and arguments in terms of
- * REG and OREG nodes
- * conversion ops which are not necessary are also clobbered here
- * in addition, any special features (such as rewriting
- * exclusive or) are easily handled here as well
- */
-NODE *
-clocal(NODE *p)
-{
-
-	register struct symtab *q;
-	register NODE *r, *l;
-	register int o;
-	register int m;
-	TWORD t;
-
-#ifdef PCC_DEBUG
-	if (xdebug) {
-		printf("clocal: %p\n", p);
-		fwalk(p, eprint, 0);
-	}
-#endif
-	switch( o = p->n_op ){
-
-	case NAME:
-		if ((q = p->n_sp) == NULL)
-			return p; /* Nothing to care about */
-
-		switch (q->sclass) {
-
-		case PARAM:
-		case AUTO:
-			/* fake up a structure reference */
-			r = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
-			r->n_lval = 0;
-			r->n_rval = FPREG;
-			p = stref(block(STREF, r, p, 0, 0, 0));
-			break;
-
-		case STATIC:
-			if (q->slevel == 0)
-				break;
-			p->n_lval = 0;
-			p->n_sp = q;
-			break;
-
-		case REGISTER:
-			p->n_op = REG;
-			p->n_lval = 0;
-			p->n_rval = q->soffset;
-			break;
-
-			}
-		break;
-
-	case STCALL:
-	case CALL:
-		/* Fix function call arguments. On x86, just add funarg */
-		for (r = p->n_right; r->n_op == CM; r = r->n_left) {
-			if (r->n_right->n_op != STARG &&
-			    r->n_right->n_op != FUNARG)
-				r->n_right = block(FUNARG, r->n_right, NIL, 
-				    r->n_right->n_type, r->n_right->n_df,
-				    r->n_right->n_sue);
-		}
-		if (r->n_op != STARG && r->n_op != FUNARG) {
-			l = talloc();
-			*l = *r;
-			r->n_op = FUNARG; r->n_left = l; r->n_type = l->n_type;
-		}
-		break;
-		
-	case CBRANCH:
-		l = p->n_left;
-
-		/*
-		 * Remove unneccessary conversion ops.
-		 */
-		if (clogop(l->n_op) && l->n_left->n_op == SCONV) {
-			if (coptype(l->n_op) != BITYPE)
-				break;
-			if (l->n_right->n_op == ICON) {
-				r = l->n_left->n_left;
-				if (r->n_type >= FLOAT && r->n_type <= LDOUBLE)
-					break;
-				/* Type must be correct */
-				t = r->n_type;
-				nfree(l->n_left);
-				l->n_left = r;
-				l->n_type = t;
-				l->n_right->n_type = t;
-			}
-		}
-		break;
-
-	case PCONV:
-		/* Remove redundant PCONV's. Be careful */
-		l = p->n_left;
-		if (l->n_op == ICON) {
-			l->n_lval = (unsigned)l->n_lval;
-			goto delp;
-		}
-		if (l->n_type < INT || l->n_type == LONGLONG || 
-		    l->n_type == ULONGLONG) {
-			/* float etc? */
-			p->n_left = block(SCONV, l, NIL,
-			    UNSIGNED, 0, MKSUE(UNSIGNED));
-			break;
-		}
-		/* if left is SCONV, cannot remove */
-		if (l->n_op == SCONV)
-			break;
-
-		/* avoid ADDROF TEMP */
-		if (l->n_op == ADDROF && l->n_left->n_op == TEMP)
-			break;
-
-		/* if conversion to another pointer type, just remove */
-		if (p->n_type > BTMASK && l->n_type > BTMASK)
-			goto delp;
-		break;
-
-	delp:	l->n_type = p->n_type;
-		l->n_qual = p->n_qual;
-		l->n_df = p->n_df;
-		l->n_sue = p->n_sue;
-		nfree(p);
-		p = l;
-		break;
-		
-	case SCONV:
-		l = p->n_left;
-
-		if (p->n_type == l->n_type) {
-			nfree(p);
-			return l;
-		}
-
-		if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
-		    btdims[p->n_type].suesize == btdims[l->n_type].suesize) {
-			if (p->n_type != FLOAT && p->n_type != DOUBLE &&
-			    l->n_type != FLOAT && l->n_type != DOUBLE &&
-			    l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
-				if (l->n_op == NAME || l->n_op == UMUL ||
-				    l->n_op == TEMP) {
-					l->n_type = p->n_type;
-					nfree(p);
-					return l;
-				}
-			}
-		}
-
-		if (DEUNSIGN(p->n_type) == INT && DEUNSIGN(l->n_type) == INT &&
-		    coptype(l->n_op) == BITYPE) {
-			l->n_type = p->n_type;
-			nfree(p);
-			return l;
-		}
-
-		o = l->n_op;
-		m = p->n_type;
-
-		if (o == ICON) {
-			CONSZ val = l->n_lval;
-
-			if (!ISPTR(m)) /* Pointers don't need to be conv'd */
-			    switch (m) {
-			case BOOL:
-				l->n_lval = l->n_lval != 0;
-				break;
-			case CHAR:
-				l->n_lval = (char)val;
-				break;
-			case UCHAR:
-				l->n_lval = val & 0377;
-				break;
-			case SHORT:
-				l->n_lval = (short)val;
-				break;
-			case USHORT:
-				l->n_lval = val & 0177777;
-				break;
-			case ULONG:
-			case UNSIGNED:
-				l->n_lval = val & 0xffffffff;
-				break;
-			case ENUMTY:
-			case MOETY:
-			case LONG:
-			case INT:
-				l->n_lval = (int)val;
-				break;
-			case LONGLONG:
-				l->n_lval = (long long)val;
-				break;
-			case ULONGLONG:
-				l->n_lval = val;
-				break;
-			case VOID:
-				break;
-			case LDOUBLE:
-			case DOUBLE:
-			case FLOAT:
-				l->n_op = FCON;
-				l->n_dcon = val;
-				break;
-			default:
-				cerror("unknown type %d", m);
-			}
-			l->n_type = m;
-			l->n_sue = MKSUE(m);
-			nfree(p);
-			return l;
-		}
-		if (DEUNSIGN(p->n_type) == SHORT &&
-		    DEUNSIGN(l->n_type) == SHORT) {
-			nfree(p);
-			p = l;
-		}
-		if ((p->n_type == CHAR || p->n_type == UCHAR ||
-		    p->n_type == SHORT || p->n_type == USHORT) &&
-		    (l->n_type == FLOAT || l->n_type == DOUBLE ||
-		    l->n_type == LDOUBLE)) {
-			p = block(SCONV, p, NIL, p->n_type, p->n_df, p->n_sue);
-			p->n_left->n_type = INT;
-			return p;
-		}
-		break;
-
-	case MOD:
-	case DIV:
-		if (o == DIV && p->n_type != CHAR && p->n_type != SHORT)
-			break;
-		if (o == MOD && p->n_type != CHAR && p->n_type != SHORT)
-			break;
-		/* make it an int division by inserting conversions */
-		p->n_left = block(SCONV, p->n_left, NIL, INT, 0, MKSUE(INT));
-		p->n_right = block(SCONV, p->n_right, NIL, INT, 0, MKSUE(INT));
-		p = block(SCONV, p, NIL, p->n_type, 0, MKSUE(p->n_type));
-		p->n_left->n_type = INT;
-		break;
-
-	case PMCONV:
-	case PVCONV:
-                if( p->n_right->n_op != ICON ) cerror( "bad conversion", 0);
-                nfree(p);
-                return(buildtree(o==PMCONV?MUL:DIV, p->n_left, p->n_right));
-
-	case FORCE:
-		/* put return value in return reg */
-		p->n_op = ASSIGN;
-		p->n_right = p->n_left;
-		p->n_left = block(REG, NIL, NIL, p->n_type, 0, MKSUE(INT));
-		p->n_left->n_rval = p->n_left->n_type == BOOL ? 
-		    RETREG(CHAR) : RETREG(p->n_type);
-		break;
-
-	case LS:
-	case RS:
-		/* shift count must be in a char
-		 * unless longlong, where it must be int */
-		if (p->n_right->n_op == ICON)
-			break; /* do not do anything */
-		if (p->n_type == LONGLONG || p->n_type == ULONGLONG) {
-			if (p->n_right->n_type != INT)
-				p->n_right = block(SCONV, p->n_right, NIL,
-				    INT, 0, MKSUE(INT));
-			break;
-		}
-		if (p->n_right->n_type == CHAR || p->n_right->n_type == UCHAR)
-			break;
-		p->n_right = block(SCONV, p->n_right, NIL,
-		    CHAR, 0, MKSUE(CHAR));
-		break;
-	}
-#ifdef PCC_DEBUG
-	if (xdebug) {
-		printf("clocal end: %p\n", p);
-		fwalk(p, eprint, 0);
-	}
-#endif
-	return(p);
-}
-
-void
-myp2tree(NODE *p)
-{
-}
-
-/*ARGSUSED*/
-int
-andable(NODE *p)
-{
-	return(1);  /* all names can have & taken on them */
-}
-
-/*
- * at the end of the arguments of a ftn, set the automatic offset
- */
-void
-cendarg()
-{
-	autooff = AUTOINIT;
-}
-
-/*
- * Return 1 if a variable of type type is OK to put in register.
- */
-int
-cisreg(TWORD t)
-{
-	if (t == FLOAT || t == DOUBLE || t == LDOUBLE)
-		return 0; /* not yet */
-	return 1;
-}
-
-/*
- * return a node, for structure references, which is suitable for
- * being added to a pointer of type t, in order to be off bits offset
- * into a structure
- * t, d, and s are the type, dimension offset, and sizeoffset
- * For pdp10, return the type-specific index number which calculation
- * is based on its size. For example, short a[3] would return 3.
- * Be careful about only handling first-level pointers, the following
- * indirections must be fullword.
- */
-NODE *
-offcon(OFFSZ off, TWORD t, union dimfun *d, struct suedef *sue)
-{
-	register NODE *p;
-
-	if (xdebug)
-		printf("offcon: OFFSZ %lld type %x dim %p siz %d\n",
-		    off, t, d, sue->suesize);
-
-	p = bcon(0);
-	p->n_lval = off/SZCHAR;	/* Default */
-	return(p);
-}
-
-/*
- * Allocate off bits on the stack.  p is a tree that when evaluated
- * is the multiply count for off, t is a storeable node where to write
- * the allocated address.
- */
-void
-spalloc(NODE *t, NODE *p, OFFSZ off)
-{
-	NODE *sp;
-
-	p = buildtree(MUL, p, bcon(off/SZCHAR)); /* XXX word alignment? */
-
-	/* sub the size from sp */
-	sp = block(REG, NIL, NIL, p->n_type, 0, MKSUE(INT));
-	sp->n_lval = 0;
-	sp->n_rval = STKREG;
-	ecomp(buildtree(MINUSEQ, sp, p));
-
-	/* save the address of sp */
-	sp = block(REG, NIL, NIL, PTR+INT, t->n_df, t->n_sue);
-	sp->n_lval = 0;
-	sp->n_rval = STKREG;
-	t->n_type = sp->n_type;
-	ecomp(buildtree(ASSIGN, t, sp)); /* Emit! */
-
-}
-
-#if 0
-/*
- * Print out an integer constant of size size.
- * can only be sizes <= SZINT.
- */
-void
-indata(CONSZ val, int size)
-{
-	switch (size) {
-	case SZCHAR:
-		printf("\t.byte %d\n", (int)val & 0xff);
-		break;
-	case SZSHORT:
-		printf("\t.word %d\n", (int)val & 0xffff);
-		break;
-	case SZINT:
-		printf("\t.long %d\n", (int)val & 0xffffffff);
-		break;
-	default:
-		cerror("indata");
-	}
-}
-#endif
-
-/*
- * Print out a string of characters.
- * Assume that the assembler understands C-style escape
- * sequences.  Location is already set.
- */
-void
-instring(char *str)
-{
-	char *s;
-
-	/* be kind to assemblers and avoid long strings */
-	printf("\t.ascii \"");
-	for (s = str; *s != 0; ) {
-		if (*s++ == '\\') {
-			(void)esccon(&s);
-		}
-		if (s - str > 64) {
-			fwrite(str, 1, s - str, stdout);
-			printf("\"\n\t.ascii \"");
-			str = s;
-		}
-	}
-	fwrite(str, 1, s - str, stdout);
-	printf("\\0\"\n");
-}
-
-static int inbits, inval;
-
-/*
- * set fsz bits in sequence to zero.
- */
-void
-zbits(OFFSZ off, int fsz)
-{
-	int m;
-
-	if (idebug)
-		printf("zbits off %lld, fsz %d inbits %d\n", off, fsz, inbits);
-	if ((m = (inbits % SZCHAR))) {
-		m = SZCHAR - m;
-		if (fsz < m) {
-			inbits += fsz;
-			return;
-		} else {
-			fsz -= m;
-			printf("\t.byte %d\n", inval);
-			inval = inbits = 0;
-		}
-	}
-	if (fsz >= SZCHAR) {
-		printf("\t.zero %d\n", fsz/SZCHAR);
-		fsz -= (fsz/SZCHAR) * SZCHAR;
-	}
-	if (fsz) {
-		inval = 0;
-		inbits = fsz;
-	}
-}
-
-/*
- * Initialize a bitfield.
- */
-void
-infld(CONSZ off, int fsz, CONSZ val)
-{
-	if (idebug)
-		printf("infld off %lld, fsz %d, val %lld inbits %d\n",
-		    off, fsz, val, inbits);
-	val &= ((CONSZ)1 << fsz)-1;
-	while (fsz + inbits >= SZCHAR) {
-		inval |= (val << inbits);
-		printf("\t.byte %d\n", inval & 255);
-		fsz -= (SZCHAR - inbits);
-		val >>= (SZCHAR - inbits);
-		inval = inbits = 0;
-	}
-	if (fsz) {
-		inval |= (val << inbits);
-		inbits += fsz;
-	}
-}
-
-/*
- * print out a constant node, may be associated with a label.
- * Do not free the node after use.
- * off is bit offset from the beginning of the aggregate
- * fsz is the number of bits this is referring to
- */
-void
-ninval(CONSZ off, int fsz, NODE *p)
-{
-	union { float f; double d; long double l; int i[3]; } u;
-	struct symtab *q;
-	TWORD t;
-	int i;
-
-	t = p->n_type;
-	if (t > BTMASK)
-		t = INT; /* pointer */
-
-	if (p->n_op != ICON && p->n_op != FCON)
-		cerror("ninval: init node not constant");
-
-	if (p->n_op == ICON && p->n_sp != NULL && DEUNSIGN(t) != INT)
-		uerror("element not constant");
-
-	switch (t) {
-	case LONGLONG:
-	case ULONGLONG:
-		i = (p->n_lval >> 32);
-		p->n_lval &= 0xffffffff;
-		p->n_type = INT;
-		ninval(off, 32, p);
-		p->n_lval = i;
-		ninval(off+32, 32, p);
-		break;
-	case INT:
-	case UNSIGNED:
-		printf("\t.long 0x%x", (int)p->n_lval);
-		if ((q = p->n_sp) != NULL) {
-			if ((q->sclass == STATIC && q->slevel > 0) ||
-			    q->sclass == ILABEL) {
-				printf("+" LABFMT, q->soffset);
-			} else
-				printf("+%s", exname(q->sname));
-		}
-		printf("\n");
-		break;
-	case SHORT:
-	case USHORT:
-		printf("\t.short 0x%x\n", (int)p->n_lval & 0xffff);
-		break;
-	case BOOL:
-		if (p->n_lval > 1)
-			p->n_lval = p->n_lval != 0;
-		/* FALLTHROUGH */
-	case CHAR:
-	case UCHAR:
-		printf("\t.byte %d\n", (int)p->n_lval & 0xff);
-		break;
-	case LDOUBLE:
-		u.i[2] = 0;
-		u.l = (long double)p->n_dcon;
-		printf("\t.long\t0x%x,0x%x,0x%x\n", u.i[0], u.i[1], u.i[2]);
-		break;
-	case DOUBLE:
-		u.d = (double)p->n_dcon;
-		printf("\t.long\t0x%x,0x%x\n", u.i[0], u.i[1]);
-		break;
-	case FLOAT:
-		u.f = (float)p->n_dcon;
-		printf("\t.long\t0x%x\n", u.i[0]);
-		break;
-	default:
-		cerror("ninval");
-	}
-}
-
-#if 0
-/*
- * print out an integer.
- */
-void
-inval(CONSZ word)
-{
-	word &= 0xffffffff;
-	printf("	.long 0x%llx\n", word);
-}
-
-/* output code to initialize a floating point value */
-/* the proper alignment has been obtained */
-void
-finval(NODE *p)
-{
-	union { float f; double d; long double l; int i[3]; } u;
-
-	switch (p->n_type) {
-	case LDOUBLE:
-		u.i[2] = 0;
-		u.l = (long double)p->n_dcon;
-		printf("\t.long\t0x%x,0x%x,0x%x\n", u.i[0], u.i[1], u.i[2]);
-		break;
-	case DOUBLE:
-		u.d = (double)p->n_dcon;
-		printf("\t.long\t0x%x,0x%x\n", u.i[0], u.i[1]);
-		break;
-	case FLOAT:
-		u.f = (float)p->n_dcon;
-		printf("\t.long\t0x%x\n", u.i[0]);
-		break;
-	}
-}
-#endif
-
-/* make a name look like an external name in the local machine */
-char *
-exname(char *p)
-{
-	if (p == NULL)
-		return "";
-	return p;
-}
-
-/*
- * map types which are not defined on the local machine
- */
-TWORD
-ctype(TWORD type)
-{
-	switch (BTYPE(type)) {
-	case LONG:
-		MODTYPE(type,INT);
-		break;
-
-	case ULONG:
-		MODTYPE(type,UNSIGNED);
-
-	}
-	return (type);
-}
-
-void
-calldec(NODE *p, NODE *q) 
-{
-}
-
-void
-extdec(struct symtab *q)
-{
-}
-
-/* make a common declaration for id, if reasonable */
-void
-commdec(struct symtab *q)
-{
-	int off;
-
-	off = tsize(q->stype, q->sdf, q->ssue);
-	off = (off+(SZCHAR-1))/SZCHAR;
-#ifdef GCC_COMPAT
-	printf("	.comm %s,0%o\n", gcc_findname(q), off);
-#else
-	printf("	.comm %s,0%o\n", exname(q->sname), off);
-#endif
-}
-
-/* make a local common declaration for id, if reasonable */
-void
-lcommdec(struct symtab *q)
-{
-	int off;
-
-	off = tsize(q->stype, q->sdf, q->ssue);
-	off = (off+(SZCHAR-1))/SZCHAR;
-	if (q->slevel == 0)
-#ifdef GCC_COMPAT
-		printf("	.lcomm %s,0%o\n", gcc_findname(q), off);
-#else
-		printf("	.lcomm %s,0%o\n", exname(q->sname), off);
-#endif
-	else
-		printf("	.lcomm " LABFMT ",0%o\n", q->soffset, off);
-}
-
-/*
- * print a (non-prog) label.
- */
-void
-deflab1(int label)
-{
-	printf(LABFMT ":\n", label);
-}
-
-static char *loctbl[] = { "text", "data", "section .rodata", "section .rodata" };
-
-void
-setloc1(int locc)
-{
-	if (locc == lastloc)
-		return;
-	lastloc = locc;
-	printf("	.%s\n", loctbl[locc]);
-}
-
-#if 0
-int
-ftoint(NODE *p, CONSZ **c)
-{
-	static CONSZ cc[3];
-	union { float f; double d; long double l; int i[3]; } u;
-	int n;
-
-	switch (p->n_type) {
-	case LDOUBLE:
-		u.i[2] = 0;
-		u.l = (long double)p->n_dcon;
-		n = SZLDOUBLE;
-		break;
-	case DOUBLE:
-		u.d = (double)p->n_dcon;
-		n = SZDOUBLE;
-		break;
-	case FLOAT:
-		u.f = (float)p->n_dcon;
-		n = SZFLOAT;
-		break;
-	}
-	cc[0] = u.i[0];
-	cc[1] = u.i[1];
-	cc[2] = u.i[2];
-	*c = cc;
-	return n;
-}
-#endif
Index: Makefile
===================================================================
RCS file: /home/cvs/src/usr.bin/pcc/cpp/Makefile,v
retrieving revision 1.3
retrieving revision 1.4
diff -L usr.bin/pcc/cpp/Makefile -L usr.bin/pcc/cpp/Makefile -u -r1.3 -r1.4
--- usr.bin/pcc/cpp/Makefile
+++ usr.bin/pcc/cpp/Makefile
@@ -5,6 +5,7 @@
 PROG=	cpp
 TARGOS=	midnightbsd
 BINDIR=	${libexecdir}
+NO_MAN=
 
 CFLAGS+=	-DCPP_DEBUG -Wall -Wmissing-prototypes -Wstrict-prototypes -Werror
 CFLAGS+=	-DLIBEXECDIR=\"${libexecdir}\"
--- /dev/null
+++ usr.bin/pcc/i386/order.c
@@ -0,0 +1,287 @@
+/*	$Id: order.c,v 1.49 2007/08/01 04:53:58 ragge Exp $	*/
+/*
+ * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+# include "pass2.h"
+
+#include <string.h>
+
+int canaddr(NODE *);
+
+/* is it legal to make an OREG or NAME entry which has an
+ * offset of off, (from a register of r), if the
+ * resulting thing had type t */
+int
+notoff(TWORD t, int r, CONSZ off, char *cp)
+{
+	return(0);  /* YES */
+}
+
+/*
+ * Turn a UMUL-referenced node into OREG.
+ * Be careful about register classes, this is a place where classes change.
+ */
+void
+offstar(NODE *p, int shape)
+{
+	NODE *r;
+
+	if (x2debug)
+		printf("offstar(%p)\n", p);
+
+	if (isreg(p))
+		return; /* Is already OREG */
+
+	r = p->n_right;
+	if( p->n_op == PLUS || p->n_op == MINUS ){
+		if( r->n_op == ICON ){
+			if (isreg(p->n_left) == 0)
+				(void)geninsn(p->n_left, INAREG);
+			/* Converted in ormake() */
+			return;
+		}
+		if (r->n_op == LS && r->n_right->n_op == ICON &&
+		    r->n_right->n_lval == 2 && p->n_op == PLUS) {
+			if (isreg(p->n_left) == 0)
+				(void)geninsn(p->n_left, INAREG);
+			if (isreg(r->n_left) == 0)
+				(void)geninsn(r->n_left, INAREG);
+			return;
+		}
+	}
+	(void)geninsn(p, INAREG);
+}
+
+/*
+ * Do the actual conversion of offstar-found OREGs into real OREGs.
+ */
+void
+myormake(NODE *q)
+{
+	NODE *p, *r;
+
+	if (x2debug)
+		printf("myormake(%p)\n", q);
+
+	p = q->n_left;
+	if (p->n_op == PLUS && (r = p->n_right)->n_op == LS &&
+	    r->n_right->n_op == ICON && r->n_right->n_lval == 2 &&
+	    p->n_left->n_op == REG && r->n_left->n_op == REG) {
+		q->n_op = OREG;
+		q->n_lval = 0;
+		q->n_rval = R2PACK(p->n_left->n_rval, r->n_left->n_rval, 0);
+		tfree(p);
+	}
+}
+
+/*
+ * Shape matches for UMUL.  Cooperates with offstar().
+ */
+int
+shumul(NODE *p)
+{
+
+	if (x2debug)
+		printf("shumul(%p)\n", p);
+
+	/* Turns currently anything into OREG on x86 */
+	return SOREG;
+}
+
+/*
+ * Rewrite increment/decrement operation.
+ */
+int
+setincr(NODE *p)
+{
+	if (x2debug)
+		printf("setincr(%p)\n", p);
+
+	return(0);
+}
+
+/*
+ * Rewrite operations on binary operators (like +, -, etc...).
+ * Called as a result of table lookup.
+ */
+int
+setbin(NODE *p)
+{
+
+	if (x2debug)
+		printf("setbin(%p)\n", p);
+	return 0;
+
+}
+
+/* setup for assignment operator */
+int
+setasg(NODE *p, int cookie)
+{
+	if (x2debug)
+		printf("setasg(%p)\n", p);
+	return(0);
+}
+
+/* setup for unary operator */
+int
+setuni(NODE *p, int cookie)
+{
+	return 0;
+}
+
+/*
+ * Special handling of some instruction register allocation.
+ */
+struct rspecial *
+nspecial(struct optab *q)
+{
+	switch (q->op) {
+	case OPLOG:
+		{
+			static struct rspecial s[] = { { NEVER, EAX }, { 0 } };
+			return s;
+		}
+
+	case STASG:
+	case STARG:
+		{
+			static struct rspecial s[] = {
+				{ NEVER, EAX }, { NEVER, EDX },
+				{ NEVER, ECX }, { 0 } };
+			return s;
+		}
+
+	case SCONV:
+		if ((q->ltype & (TINT|TUNSIGNED|TSHORT|TUSHORT)) && 
+		    q->rtype == (TCHAR|TUCHAR)) {
+			static struct rspecial s[] = { 
+				{ NOLEFT, ESI }, { NOLEFT, EDI }, { 0 } };
+			return s;
+		} else if ((q->ltype & (TINT|TUNSIGNED)) &&
+		    q->rtype == TLONGLONG) {
+			static struct rspecial s[] = {
+				{ NLEFT, EAX }, { NRES, EAXEDX },
+				{ NEVER, EAX }, { NEVER, EDX }, { 0 } };
+			return s;
+		} else if (q->ltype == TSHORT &&
+		    q->rtype == (TLONGLONG|TULONGLONG)) {
+			static struct rspecial s[] = {
+				{ NRES, EAXEDX },
+				{ NEVER, EAX }, { NEVER, EDX }, { 0 } };
+			return s;
+		} else if (q->ltype == TCHAR &&
+		    q->rtype == (TLONGLONG|TULONGLONG)) {
+			static struct rspecial s[] = {
+				{ NRES, EAXEDX },
+				{ NEVER, EAX }, { NEVER, EDX }, { 0 } };
+			return s;
+		}
+		break;
+	case DIV:
+		if (q->lshape == SBREG) {
+			static struct rspecial s[] = {
+				{ NEVER, AL }, { NEVER, AH },
+				{ NLEFT, AL }, { NRES, AL },
+				{ NORIGHT, AH }, { NORIGHT, AL }, { 0 } };
+				return s;
+		} else if (q->lshape == SAREG) {
+			static struct rspecial s[] = {
+				{ NEVER, EAX }, { NEVER, EDX },
+				{ NLEFT, EAX }, { NRES, EAX },
+				{ NORIGHT, EDX }, { NORIGHT, EAX }, { 0 } };
+			return s;
+		} else if (q->lshape & SCREG) {
+			static struct rspecial s[] = {
+				{ NEVER, EAX }, { NEVER, EDX },
+				{ NEVER, ECX }, { NRES, EAXEDX }, { 0 } };
+			return s;
+		}
+		break;
+	case MOD:
+		if (q->lshape == SBREG) {
+			static struct rspecial s[] = {
+				{ NEVER, AL }, { NEVER, AH },
+				{ NLEFT, AL }, { NRES, AH },
+				{ NORIGHT, AH }, { NORIGHT, AL }, { 0 } };
+			return s;
+		} else if (q->lshape == SAREG) {
+			static struct rspecial s[] = {
+				{ NEVER, EAX }, { NEVER, EDX },
+				{ NLEFT, EAX }, { NRES, EDX },
+				{ NORIGHT, EDX }, { NORIGHT, EAX }, { 0 } };
+			return s;
+		} else if (q->lshape & SCREG) {
+			static struct rspecial s[] = {
+				{ NEVER, EAX }, { NEVER, EDX },
+				{ NEVER, ECX }, { NRES, EAXEDX }, { 0 } };
+			return s;
+		}
+		break;
+	case MUL:
+		if (q->lshape == SBREG) {
+			static struct rspecial s[] = {
+				{ NEVER, AL }, { NEVER, AH },
+				{ NLEFT, AL }, { NRES, AL }, { 0 } };
+			return s;
+		} else if (q->lshape & SCREG) {
+			static struct rspecial s[] = {
+				{ NEVER, EAX }, { NEVER, EDX },
+				{ NEVER, ECX }, { NRES, EAXEDX }, { 0 } };
+			return s;
+		}
+		break;
+	case LS:
+	case RS:
+		if (q->visit & (INAREG|INBREG)) {
+			static struct rspecial s[] = {
+				{ NRIGHT, CL }, { NOLEFT, ECX }, { 0 } };
+			return s;
+		} else if (q->visit & INCREG) {
+			static struct rspecial s[] = {
+				{ NEVER, EAX }, { NEVER, EDX },
+				{ NEVER, ECX }, { NRES, EAXEDX }, { 0 } };
+			return s;
+		}
+		break;
+
+	default:
+		break;
+	}
+	comperr("nspecial entry %d", q - table);
+	return 0; /* XXX gcc */
+}
+
+/*
+ * Set evaluation order of a binary node if it differs from default.
+ */
+int
+setorder(NODE *p)
+{
+	return 0; /* nothing differs on x86 */
+}
--- /dev/null
+++ usr.bin/pcc/i386/macdefs.h
@@ -0,0 +1,301 @@
+/*	$Id: macdefs.h,v 1.46 2007/08/19 19:25:22 ragge Exp $	*/
+/*
+ * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Machine-dependent defines for both passes.
+ */
+
+/*
+ * Convert (multi-)character constant to integer.
+ */
+#define makecc(val,i)	lastcon = (lastcon<<8)|((val<<24)>>24);
+
+#define ARGINIT		64	/* # bits above fp where arguments start */
+#define AUTOINIT	0	/* # bits below fp where automatics start */
+
+/*
+ * Storage space requirements
+ */
+#define SZCHAR		8
+#define SZBOOL		8
+#define SZINT		32
+#define SZFLOAT		32
+#define SZDOUBLE	64
+#define SZLDOUBLE	96
+#define SZLONG		32
+#define SZSHORT		16
+#define SZLONGLONG	64
+#define SZPOINT(t)	32
+
+/*
+ * Alignment constraints
+ */
+#define ALCHAR		8
+#define ALBOOL		8
+#define ALINT		32
+#define ALFLOAT		32
+#define ALDOUBLE	32
+#define ALLDOUBLE	32
+#define ALLONG		32
+#define ALLONGLONG	32
+#define ALSHORT		16
+#define ALPOINT		32
+#define ALSTRUCT	32
+#define ALSTACK		32 
+
+/*
+ * Min/max values.
+ */
+#define	MIN_CHAR	-128
+#define	MAX_CHAR	127
+#define	MAX_UCHAR	255
+#define	MIN_SHORT	-32768
+#define	MAX_SHORT	32767
+#define	MAX_USHORT	65535
+#define	MIN_INT		-1
+#define	MAX_INT		0x7fffffff
+#define	MAX_UNSIGNED	0xffffffff
+#define	MIN_LONG	MIN_INT
+#define	MAX_LONG	MAX_INT
+#define	MAX_ULONG	MAX_UNSIGNED
+#define	MIN_LONGLONG	0x8000000000000000LL
+#define	MAX_LONGLONG	0x7fffffffffffffffLL
+#define	MAX_ULONGLONG	0xffffffffffffffffULL
+
+/* Default char is signed */
+#undef	CHAR_UNSIGNED
+#define	BOOL_TYPE	CHAR	/* what used to store _Bool */
+#define	WCHAR_TYPE	INT	/* what used to store wchar_t */
+
+/*
+ * Use large-enough types.
+ */
+typedef	long long CONSZ;
+typedef	unsigned long long U_CONSZ;
+typedef long long OFFSZ;
+
+#define CONFMT	"%lld"		/* format for printing constants */
+#define LABFMT	".L%d"		/* format for printing labels */
+#define	STABLBL	".LL%d"		/* format for stab (debugging) labels */
+#ifdef FORTRAN
+#define XL 8
+#define	FLABELFMT "%s:\n"
+#define USETEXT ".text"
+#define USECONST ".data\t0" 	/* XXX - fix */
+#define USEBSS  ".data\t1" 	/* XXX - fix */
+#define USEINIT ".data\t2" 	/* XXX - fix */
+#define MAXREGVAR 3             /* XXX - fix */
+#define BLANKCOMMON "_BLNK_"
+#define MSKIREG  (M(TYSHORT)|M(TYLONG))
+#define TYIREG TYLONG
+#define FSZLENG  FSZLONG
+#define FUDGEOFFSET 1
+#define	AUTOREG	EBP
+#define	ARGREG	EBP
+#define ARGOFFSET 4
+#endif
+
+#define BACKAUTO 		/* stack grows negatively for automatics */
+#define BACKTEMP 		/* stack grows negatively for temporaries */
+
+#define	MYP2TREE(p) myp2tree(p);
+
+#undef	FIELDOPS		/* no bit-field instructions */
+#define	RTOLBYTES		/* bytes are numbered right to left */
+
+#define ENUMSIZE(high,low) INT	/* enums are always stored in full int */
+
+/* Definitions mostly used in pass2 */
+
+#define BYTEOFF(x)	((x)&03)
+#define wdal(k)		(BYTEOFF(k)==0)
+#define BITOOR(x)	(x)	/* bit offset to oreg offset XXX die! */
+
+#define STOARG(p)
+#define STOFARG(p)
+#define STOSTARG(p)
+#define genfcall(a,b)	gencall(a,b)
+
+#define	szty(t)	(((t) == DOUBLE || (t) == FLOAT || \
+	(t) == LONGLONG || (t) == ULONGLONG) ? 2 : (t) == LDOUBLE ? 3 : 1)
+
+/*
+ * The x86 has a bunch of register classes, most of them interfering
+ * with each other.  All registers are given a sequential number to
+ * identify it which must match rnames[] in local2.c.
+ * Class membership and overlaps are defined in the macros RSTATUS
+ * and ROVERLAP below.
+ *
+ * The classes used on x86 are:
+ *	A - short and int regs
+ *	B - char regs
+ *	C - long long regs
+ *	D - floating point
+ */
+#define	EAX	000	/* Scratch and return register */
+#define	EDX	001	/* Scratch and secondary return register */
+#define	ECX	002	/* Scratch (and shift count) register */
+#define	EBX	003	/* GDT pointer or callee-saved temporary register */
+#define	ESI	004	/* Callee-saved temporary register */
+#define	EDI	005	/* Callee-saved temporary register */
+#define	EBP	006	/* Frame pointer */
+#define	ESP	007	/* Stack pointer */
+
+#define	AL	010
+#define	AH	011
+#define	DL	012
+#define	DH	013
+#define	CL	014
+#define	CH	015
+#define	BL	016
+#define	BH	017
+
+#define	EAXEDX	020
+#define	EAXECX	021
+#define	EAXEBX	022
+#define	EAXESI	023
+#define	EAXEDI	024
+#define	EDXECX	025
+#define	EDXEBX	026
+#define	EDXESI	027
+#define	EDXEDI	030
+#define	ECXEBX	031
+#define	ECXESI	032
+#define	ECXEDI	033
+#define	EBXESI	034
+#define	EBXEDI	035
+#define	ESIEDI	036
+
+/* The 8 math registers in class D lacks names */
+
+#define	MAXREGS	047	/* 39 registers */
+
+#define	RSTATUS	\
+	SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|PERMREG,	\
+	SAREG|PERMREG, SAREG|PERMREG, 0, 0,	 			\
+	SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG,		\
+	SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, 	\
+	SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG,		\
+	SDREG, SDREG, SDREG, SDREG,  SDREG, SDREG, SDREG, SDREG,
+
+#define	ROVERLAP \
+	/* 8 basic registers */\
+	{ AL, AH, EAXEDX, EAXECX, EAXEBX, EAXESI, EAXEDI, -1 },\
+	{ DL, DH, EAXEDX, EDXECX, EDXEBX, EDXESI, EDXEDI, -1 },\
+	{ CL, CH, EAXECX, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
+	{ BL, BH, EAXEBX, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
+	{ EAXESI, EDXESI, ECXESI, EBXESI, ESIEDI, -1 },\
+	{ EAXEDI, EDXEDI, ECXEDI, EBXEDI, ESIEDI, -1 },\
+	{ -1 },\
+	{ -1 },\
+\
+	/* 8 char registers */\
+	{ EAX, EAXEDX, EAXECX, EAXEBX, EAXESI, EAXEDI, -1 },\
+	{ EAX, EAXEDX, EAXECX, EAXEBX, EAXESI, EAXEDI, -1 },\
+	{ EDX, EAXEDX, EDXECX, EDXEBX, EDXESI, EDXEDI, -1 },\
+	{ EDX, EAXEDX, EDXECX, EDXEBX, EDXESI, EDXEDI, -1 },\
+	{ ECX, EAXECX, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
+	{ ECX, EAXECX, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
+	{ EBX, EAXEBX, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
+	{ EBX, EAXEBX, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
+\
+	/* 15 long-long-emulating registers */\
+	{ EAX, AL, AH, EDX, DL, DH, EAXECX, EAXEBX, EAXESI,	/* eaxedx */\
+	  EAXEDI, EDXECX, EDXEBX, EDXESI, EDXEDI, -1, },\
+	{ EAX, AL, AH, ECX, CL, CH, EAXEDX, EAXEBX, EAXESI,	/* eaxecx */\
+	  EAXEDI, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
+	{ EAX, AL, AH, EBX, BL, BH, EAXEDX, EAXECX, EAXESI,	/* eaxebx */\
+	  EAXEDI, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
+	{ EAX, AL, AH, ESI, EAXEDX, EAXECX, EAXEBX, EAXEDI,	/* eaxesi */\
+	  EDXESI, ECXESI, EBXESI, ESIEDI, -1 },\
+	{ EAX, AL, AH, EDI, EAXEDX, EAXECX, EAXEBX, EAXESI,	/* eaxedi */\
+	  EDXEDI, ECXEDI, EBXEDI, ESIEDI, -1 },\
+	{ EDX, DL, DH, ECX, CL, CH, EAXEDX, EAXECX, EDXEBX,	/* edxecx */\
+	  EDXESI, EDXEDI, ECXEBX, ECXESI, ECXEDI, -1 },\
+	{ EDX, DL, DH, EBX, BL, BH, EAXEDX, EDXECX, EDXESI,	/* edxebx */\
+	  EDXEDI, EAXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
+	{ EDX, DL, DH, ESI, EAXEDX, EDXECX, EDXEBX, EDXEDI,	/* edxesi */\
+	  EAXESI, ECXESI, EBXESI, ESIEDI, -1 },\
+	{ EDX, DL, DH, EDI, EAXEDX, EDXECX, EDXEBX, EDXESI,	/* edxedi */\
+	  EAXEDI, ECXEDI, EBXEDI, ESIEDI, -1 },\
+	{ ECX, CL, CH, EBX, BL, BH, EAXECX, EDXECX, ECXESI,	/* ecxebx */\
+	  ECXEDI, EAXEBX, EDXEBX, EBXESI, EBXEDI, -1 },\
+	{ ECX, CL, CH, ESI, EAXECX, EDXECX, ECXEBX, ECXEDI,	/* ecxesi */\
+	  EAXESI, EDXESI, EBXESI, ESIEDI, -1 },\
+	{ ECX, CL, CH, EDI, EAXECX, EDXECX, ECXEBX, ECXESI,	/* ecxedi */\
+	  EAXEDI, EDXEDI, EBXEDI, ESIEDI, -1 },\
+	{ EBX, BL, BH, ESI, EAXEBX, EDXEBX, ECXEBX, EBXEDI,	/* ebxesi */\
+	  EAXESI, EDXESI, ECXESI, ESIEDI, -1 },\
+	{ EBX, BL, BH, EDI, EAXEBX, EDXEBX, ECXEBX, EBXESI,	/* ebxedi */\
+	  EAXEDI, EDXEDI, ECXEDI, ESIEDI, -1 },\
+	{ ESI, EDI, EAXESI, EDXESI, ECXESI, EBXESI,		/* esiedi */\
+	  EAXEDI, EDXEDI, ECXEDI, EBXEDI, -1 },\
+\
+	/* The fp registers do not overlap with anything */\
+	{ -1 },\
+	{ -1 },\
+	{ -1 },\
+	{ -1 },\
+	{ -1 },\
+	{ -1 },\
+	{ -1 },\
+	{ -1 },
+
+
+/* Return a register class based on the type of the node */
+#define PCLASS(p) (p->n_type <= UCHAR ? SBREG : \
+		  (p->n_type == LONGLONG || p->n_type == ULONGLONG ? SCREG : \
+		  (p->n_type >= FLOAT && p->n_type <= LDOUBLE ? SDREG : SAREG)))
+
+#define	NUMCLASS 	4	/* highest number of reg classes used */
+
+int COLORMAP(int c, int *r);
+#define	GCLASS(x) (x < 8 ? CLASSA : x < 16 ? CLASSB : x < 31 ? CLASSC : CLASSD)
+#define DECRA(x,y)	(((x) >> (y*6)) & 63)	/* decode encoded regs */
+#define	ENCRD(x)	(x)		/* Encode dest reg in n_reg */
+#define ENCRA1(x)	((x) << 6)	/* A1 */
+#define ENCRA2(x)	((x) << 12)	/* A2 */
+#define ENCRA(x,y)	((x) << (6+y*6))	/* encode regs in int */
+/* XXX - return char in al? */
+#define	RETREG(x)	(x == CHAR || x == UCHAR ? AL : \
+			 x == LONGLONG || x == ULONGLONG ? EAXEDX : \
+			 x == FLOAT || x == DOUBLE || x == LDOUBLE ? 31 : EAX)
+
+//#define R2REGS	1	/* permit double indexing */
+
+/* XXX - to die */
+#define FPREG	EBP	/* frame pointer */
+#define STKREG	ESP	/* stack pointer */
+
+#define MYREADER(p) myreader(p)
+#define MYCANON(p) mycanon(p)
+#define	MYOPTIM
+
+#define	SHSTR		(MAXSPECIAL+1)	/* short struct */
+#define	SFUNCALL	(MAXSPECIAL+2)	/* struct assign after function call */
+#define	SPCON		(MAXSPECIAL+3)	/* positive nonnamed constant */
--- /dev/null
+++ usr.bin/pcc/i386/table.c
@@ -0,0 +1,1464 @@
+/*	$Id: table.c,v 1.96 2007/09/20 14:52:13 ragge Exp $	*/
+/*
+ * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+# include "pass2.h"
+
+# define TLL TLONGLONG|TULONGLONG
+# define ANYSIGNED TINT|TLONG|TSHORT|TCHAR
+# define ANYUSIGNED TUNSIGNED|TULONG|TUSHORT|TUCHAR
+# define ANYFIXED ANYSIGNED|ANYUSIGNED
+# define TUWORD TUNSIGNED|TULONG
+# define TSWORD TINT|TLONG
+# define TWORD TUWORD|TSWORD
+#define	 SHINT	SAREG	/* short and int */
+#define	 ININT	INAREG
+#define	 SHCH	SBREG	/* shape for char */
+#define	 INCH	INBREG
+#define	 SHLL	SCREG	/* shape for long long */
+#define	 INLL	INCREG
+#define	 SHFL	SDREG	/* shape for float/double */
+#define	 INFL	INDREG	/* shape for float/double */
+
+struct optab table[] = {
+/* First entry must be an empty entry */
+{ -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", },
+
+/* PCONVs are usually not necessary */
+{ PCONV,	INAREG,
+	SAREG,	TWORD|TPOINT,
+	SAREG,	TWORD|TPOINT,
+		0,	RLEFT,
+		"", },
+
+/*
+ * A bunch conversions of integral<->integral types
+ * There are lots of them, first in table conversions to itself
+ * and then conversions from each type to the others.
+ */
+
+/* itself to itself, including pointers */
+
+/* convert (u)char to (u)char. */
+{ SCONV,	INCH,
+	SHCH,	TCHAR|TUCHAR,
+	SHCH,	TCHAR|TUCHAR,
+		0,	RLEFT,
+		"", },
+
+/* convert pointers to int. */
+{ SCONV,	ININT,
+	SHINT,	TPOINT|TWORD,
+	SANY,	TWORD,
+		0,	RLEFT,
+		"", },
+
+/* convert (u)longlong to (u)longlong. */
+{ SCONV,	INLL,
+	SHLL,	TLL,
+	SHLL,	TLL,
+		0,	RLEFT,
+		"", },
+
+/* convert double <-> float. nothing to do here */
+{ SCONV,	INFL,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+		0,	RLEFT,
+		"", },
+
+/* convert pointers to pointers. */
+{ SCONV,	ININT,
+	SHINT,	TPOINT,
+	SANY,	TPOINT,
+		0,	RLEFT,
+		"", },
+
+/* char to something */
+
+/* convert char to (unsigned) short. */
+{ SCONV,	ININT,
+	SBREG|SOREG|SNAME,	TCHAR,
+	SAREG,	TSHORT|TUSHORT,
+		NASL|NAREG,	RESC1,
+		"	movsbw AL,A1\n", },
+
+/* convert unsigned char to (u)short. */
+{ SCONV,	ININT,
+	SHCH|SOREG|SNAME,	TUCHAR,
+	SAREG,	TSHORT|TUSHORT,
+		NASL|NAREG,	RESC1,
+		"	movzbw AL,A1\n", },
+
+/* convert signed char to int (or pointer). */
+{ SCONV,	ININT,
+	SHCH|SOREG|SNAME,	TCHAR,
+	SAREG,	TWORD|TPOINT,
+		NASL|NAREG,	RESC1,
+		"	movsbl AL,A1\n", },
+
+/* convert unsigned char to (u)int. */
+{ SCONV,	ININT,
+	SHCH|SOREG|SNAME,	TUCHAR,
+	SAREG,	TWORD,
+		NASL|NAREG,	RESC1,
+		"	movzbl AL,A1\n", },
+
+/* convert char to (u)long long */
+{ SCONV,	INLL,
+	SHCH|SOREG|SNAME,	TCHAR,
+	SANY,	TLL,
+		NSPECIAL|NAREG|NASL,	RESC1,
+		"	movsbl AL,%eax\n	cltd\n", },
+
+/* convert unsigned char to (u)long long */
+{ SCONV,	INLL,
+	SHCH|SOREG|SNAME,	TUCHAR,
+	SANY,			TLL,
+		NCREG|NCSL,	RESC1,
+		"	movzbl AL,A1\n	xorl U1,U1\n", },
+
+/* convert char (in register) to double XXX - use NTEMP */
+{ SCONV,	INFL,
+	SHCH|SOREG|SNAME,	TCHAR,
+	SHFL,			TLDOUBLE|TDOUBLE|TFLOAT,
+		NAREG|NASL|NDREG,	RESC2,
+		"	movsbl AL,A1\n	pushl A1\n"
+		"	fildl (%esp)\n	addl $4,%esp\n", },
+
+/* convert (u)char (in register) to double XXX - use NTEMP */
+{ SCONV,	INFL,
+	SHCH|SOREG|SNAME,	TUCHAR,
+	SHFL,			TLDOUBLE|TDOUBLE|TFLOAT,
+		NAREG|NASL|NDREG,	RESC2,
+		"	movzbl AL,A1\n	pushl A1\n"
+		"	fildl (%esp)\n	addl $4,%esp\n", },
+
+/* short to something */
+
+/* convert short (in memory) to char */
+{ SCONV,	INCH,
+	SNAME|SOREG,	TSHORT|TUSHORT,
+	SHCH,		TCHAR|TUCHAR,
+		NBREG|NBSL,	RESC1,
+		"	movb AL,A1\n", },
+
+/* convert short (in reg) to char. */
+{ SCONV,	INCH,
+	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
+	SHCH,			TCHAR|TUCHAR,
+		NSPECIAL|NBREG|NBSL,	RESC1,
+		"ZM", },
+
+/* convert short to (u)int. */
+{ SCONV,	ININT,
+	SAREG|SOREG|SNAME,	TSHORT,
+	SAREG,	TWORD,
+		NASL|NAREG,	RESC1,
+		"	movswl AL,A1\n", },
+
+/* convert unsigned short to (u)int. */
+{ SCONV,	ININT,
+	SAREG|SOREG|SNAME,	TUSHORT,
+	SAREG,	TWORD,
+		NASL|NAREG,	RESC1,
+		"	movzwl AL,A1\n", },
+
+/* convert short to (u)long long */
+{ SCONV,	INLL,
+	SAREG|SOREG|SNAME,	TSHORT,
+	SHLL,			TLL,
+		NSPECIAL|NCREG|NCSL,	RESC1,
+		"	movswl AL,%eax\n	cltd\n", },
+
+/* convert unsigned short to (u)long long */
+{ SCONV,	INLL,
+	SAREG|SOREG|SNAME,	TUSHORT,
+	SHLL,			TLL,
+		NCREG|NCSL,	RESC1,
+		"	movzwl AL,A1\n	xorl U1,U1\n", },
+
+/* convert short (in memory) to float/double */
+{ SCONV,	INFL,
+	SOREG|SNAME,	TSHORT,
+	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
+		NDREG,	RESC1,
+		"	fild AL\n", },
+
+/* convert short (in register) to float/double */
+{ SCONV,	INFL,
+	SAREG,	TSHORT,
+	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
+		NTEMP|NDREG,	RESC1,
+		"	pushw AL\n	fild (%esp)\n	addl $2,%esp\n", },
+
+/* convert unsigned short to double XXX - use NTEMP */
+{ SCONV,	INFL,
+	SAREG|SOREG|SNAME,	TUSHORT,
+	SHFL,			TLDOUBLE|TDOUBLE|TFLOAT,
+		NAREG|NASL|NDREG|NTEMP,	RESC2,
+		"	movzwl AL,A1\n	pushl A1\n"
+		"	fildl (%esp)\n	addl $4,%esp\n", },
+
+/* int to something */
+
+/* convert int to char. This is done when register is loaded */
+{ SCONV,	INCH,
+	SAREG,	TWORD,
+	SANY,	TCHAR|TUCHAR,
+		NSPECIAL|NBREG|NBSL,	RESC1,
+		"ZM", },
+
+/* convert int to short. Nothing to do */
+{ SCONV,	INAREG,
+	SAREG,	TWORD,
+	SANY,	TSHORT|TUSHORT,
+		0,	RLEFT,
+		"", },
+
+/* convert int to long long */
+{ SCONV,	INLL,
+	SAREG,	TWORD|TPOINT,
+	SCREG,	TLONGLONG,
+		NSPECIAL|NCREG|NCSL,	RESC1,
+		"	cltd\n", },
+
+/* convert int to unsigned long long */
+{ SCONV,	INLL,
+	SAREG|SOREG|SNAME,	TWORD|TPOINT,
+	SHLL,	TULONGLONG,
+		NCSL|NCREG,	RESC1,
+		"	movl AL,A1\n	xorl U1,U1\n", },
+
+/* convert int (in memory) to double */
+{ SCONV,	INFL,
+	SOREG|SNAME,	TWORD,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+		NDREG,	RESC1,
+		"	fildl AL\n", },
+
+/* convert int (in register) to double */
+{ SCONV,	INFL,
+	SAREG,	TWORD,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+		NTEMP|NDREG,	RESC1,
+		"	pushl AL\n	fildl (%esp)\n	addl $4,%esp\n", },
+
+/* long long to something */
+
+/* convert (u)long long to (u)char (mem->reg) */
+{ SCONV,	INCH,
+	SOREG|SNAME,	TLL,
+	SANY,	TCHAR|TUCHAR,
+		NAREG|NASL,	RESC1,
+		"	movb AL,A1\n", },
+
+/* convert (u)long long to (u)char (reg->reg, hopefully nothing) */
+{ SCONV,	INCH,
+	SHLL,	TLL,
+	SANY,	TCHAR|TUCHAR,
+		NAREG|NASL,	RESC1,
+		"ZS", },
+
+/* convert (u)long long to (u)short (mem->reg) */
+{ SCONV,	INAREG,
+	SOREG|SNAME,	TLL,
+	SAREG,	TSHORT|TUSHORT,
+		NAREG|NASL,	RESC1,
+		"	movw AL,A1\n", },
+
+/* convert (u)long long to (u)short (reg->reg, hopefully nothing) */
+{ SCONV,	INAREG,
+	SHLL|SOREG|SNAME,	TLL,
+	SAREG,	TSHORT|TUSHORT,
+		NAREG|NASL,	RESC1,
+		"ZS", },
+
+/* convert long long to int (mem->reg) */
+{ SCONV,	INAREG,
+	SOREG|SNAME,	TLL,
+	SAREG,	TWORD|TPOINT,
+		NAREG|NASL,	RESC1,
+		"	movl AL,A1\n", },
+
+/* convert long long to int (reg->reg, hopefully nothing) */
+{ SCONV,	INAREG,
+	SHLL|SOREG|SNAME,	TLL,
+	SAREG,	TWORD|TPOINT,
+		NAREG|NASL,	RESC1,
+		"ZS", },
+
+/* convert long long (in memory) to floating */
+{ SCONV,	INFL,
+	SOREG|SNAME,	TLONGLONG,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+		NDREG,	RESC1,
+		"	fildq AL\n", },
+
+/* convert long long (in register) to floating */
+{ SCONV,	INFL,
+	SHLL,	TLONGLONG,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+		NTEMP|NDREG,	RESC1,
+		"	pushl UL\n	pushl AL\n"
+		"	fildq (%esp)\n	addl $8,%esp\n", },
+
+/* convert unsigned long long to floating */
+{ SCONV,	INFL,
+	SCREG,	TULONGLONG,
+	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
+		NDREG,	RESC1,
+		"ZJ", },
+
+/* float to something */
+
+#if 0 /* go via int by adding an extra sconv in clocal() */
+/* convert float/double to (u) char. XXX should use NTEMP here */
+{ SCONV,	INCH,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+	SHCH,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+		NBREG,	RESC1,
+		"	subl $4,%esp\n	fistpl (%esp)\n	popl A1\n", },
+
+/* convert float/double to (u) int/short/char. XXX should use NTEMP here */
+{ SCONV,	INCH,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+	SHCH,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+		NCREG,	RESC1,
+		"	subl $4,%esp\n	fistpl (%esp)\n	popl A1\n", },
+#endif
+
+/* convert float/double to (u)int. XXX should use NTEMP here */
+{ SCONV,	INAREG,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+	SAREG,	TWORD,
+		NAREG,	RESC1,
+		"	subl $4,%esp\n	fistpl (%esp)\n	popl A1\n", },
+
+/* convert float/double (in register) to (unsigned) long long */
+/* XXX - unsigned is not handled correct */
+{ SCONV,	INLL,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+	SHLL,	TLONGLONG|TULONGLONG,
+		NCREG,	RESC1,
+		"	subl $8,%esp\n	fistpq (%esp)\n"
+		"	popl A1\n	popl U1\n", },
+
+/* slut sconv */
+
+/*
+ * Subroutine calls.
+ */
+
+{ CALL,		FOREFF,
+	SCON,	TANY,
+	SANY,	TANY,
+		0,	0,
+		"	call CL\nZC", },
+
+{ UCALL,	FOREFF,
+	SCON,	TANY,
+	SAREG,	TWORD|TPOINT,
+		0,	0,
+		"	call CL\n", },
+
+{ CALL,	INAREG,
+	SCON,	TANY,
+	SAREG,	TWORD|TPOINT,
+		NAREG|NASL,	RESC1,	/* should be 0 */
+		"	call CL\nZC", },
+
+{ UCALL,	INAREG,
+	SCON,	TANY,
+	SAREG,	TWORD|TPOINT,
+		NAREG|NASL,	RESC1,	/* should be 0 */
+		"	call CL\n", },
+
+{ CALL,	INBREG,
+	SCON,	TANY,
+	SBREG,	TCHAR|TUCHAR,
+		NBREG,	RESC1,	/* should be 0 */
+		"	call CL\nZC", },
+
+{ UCALL,	INBREG,
+	SCON,	TANY,
+	SBREG,	TCHAR|TUCHAR,
+		NBREG,	RESC1,	/* should be 0 */
+		"	call CL\n", },
+
+{ CALL,		INCREG,
+	SCON,	TANY,
+	SCREG,	TANY,
+		NCREG|NCSL,	RESC1,	/* should be 0 */
+		"	call CL\nZC", },
+
+{ UCALL,	INCREG,
+	SCON,	TANY,
+	SCREG,	TANY,
+		NCREG|NCSL,	RESC1,	/* should be 0 */
+		"	call CL\n", },
+
+{ CALL,	INDREG,
+	SCON,	TANY,
+	SDREG,	TANY,
+		NDREG|NDSL,	RESC1,	/* should be 0 */
+		"	call CL\nZC", },
+
+{ UCALL,	INDREG,
+	SCON,	TANY,
+	SDREG,	TANY,
+		NDREG|NDSL,	RESC1,	/* should be 0 */
+		"	call CL\nZC", },
+
+{ CALL,		FOREFF,
+	SAREG,	TANY,
+	SANY,	TANY,
+		0,	0,
+		"	call *AL\nZC", },
+
+{ UCALL,	FOREFF,
+	SAREG,	TANY,
+	SANY,	TANY,
+		0,	0,
+		"	call *AL\nZC", },
+
+{ CALL,		INAREG,
+	SAREG,	TANY,
+	SANY,	TANY,
+		NAREG|NASL,	RESC1,	/* should be 0 */
+		"	call *AL\nZC", },
+
+{ UCALL,	INAREG,
+	SAREG,	TANY,
+	SANY,	TANY,
+		NAREG|NASL,	RESC1,	/* should be 0 */
+		"	call *AL\nZC", },
+
+{ CALL,		INBREG,
+	SAREG,	TANY,
+	SANY,	TANY,
+		NBREG|NBSL,	RESC1,	/* should be 0 */
+		"	call *AL\nZC", },
+
+{ UCALL,	INBREG,
+	SAREG,	TANY,
+	SANY,	TANY,
+		NBREG|NBSL,	RESC1,	/* should be 0 */
+		"	call *AL\nZC", },
+
+{ CALL,		INCREG,
+	SAREG,	TANY,
+	SANY,	TANY,
+		NCREG|NCSL,	RESC1,	/* should be 0 */
+		"	call *AL\nZC", },
+
+{ UCALL,	INCREG,
+	SAREG,	TANY,
+	SANY,	TANY,
+		NCREG|NCSL,	RESC1,	/* should be 0 */
+		"	call *AL\nZC", },
+
+{ CALL,		INDREG,
+	SAREG,	TANY,
+	SANY,	TANY,
+		NDREG|NDSL,	RESC1,	/* should be 0 */
+		"	call *AL\nZC", },
+
+{ UCALL,	INDREG,
+	SAREG,	TANY,
+	SANY,	TANY,
+		NDREG|NDSL,	RESC1,	/* should be 0 */
+		"	call *AL\nZC", },
+
+/* struct return */
+{ USTCALL,	FOREFF,
+	SCON,	TANY,
+	SANY,	TANY,
+		NAREG|NASL,	0,
+		"ZP	call CL\nZC", },
+
+{ USTCALL,	INAREG,
+	SCON,	TANY,
+	SANY,	TANY,
+		NAREG|NASL,	RESC1,	/* should be 0 */
+		"ZP	call CL\nZC", },
+
+{ USTCALL,	INAREG,
+	SNAME|SAREG,	TANY,
+	SANY,	TANY,
+		NAREG|NASL,	RESC1,	/* should be 0 */
+		"ZP	call *AL\nZC", },
+
+{ STCALL,	FOREFF,
+	SCON,	TANY,
+	SANY,	TANY,
+		NAREG|NASL,	0,
+		"ZP	call CL\nZC", },
+
+{ STCALL,	INAREG,
+	SCON,	TANY,
+	SANY,	TANY,
+		NAREG|NASL,	RESC1,	/* should be 0 */
+		"ZP	call CL\nZC", },
+
+{ STCALL,	INAREG,
+	SNAME|SAREG,	TANY,
+	SANY,	TANY,
+		NAREG|NASL,	RESC1,	/* should be 0 */
+		"ZP	call *AL\nZC", },
+
+/*
+ * The next rules handle all binop-style operators.
+ */
+/* Special treatment for long long */
+{ PLUS,		INLL|FOREFF,
+	SHLL,		TLL,
+	SHLL|SNAME|SOREG,	TLL,
+		0,	RLEFT,
+		"	addl AR,AL\n	adcl UR,UL\n", },
+
+/* Special treatment for long long  XXX - fix commutative check */
+{ PLUS,		INLL|FOREFF,
+	SHLL|SNAME|SOREG,	TLL,
+	SHLL,			TLL,
+		0,	RRIGHT,
+		"	addl AL,AR\n	adcl UL,UR\n", },
+
+{ PLUS,		INFL,
+	SHFL,		TDOUBLE,
+	SNAME|SOREG,	TDOUBLE,
+		0,	RLEFT,
+		"	faddl AR\n", },
+
+{ PLUS,		INFL|FOREFF,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+		0,	RLEFT,
+		"	faddp\n", },
+
+{ PLUS,		INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TWORD|TPOINT,
+	SONE,	TANY,
+		0,	RLEFT,
+		"	incl AL\n", },
+
+{ PLUS,		INAREG,
+	SAREG,	TWORD|TPOINT,
+	SCON,	TANY,
+		NAREG|NASL,	RESC1,
+		"	leal CR(AL),A1\n", },
+
+{ PLUS,		INCH|FOREFF,
+	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
+	SONE,	TANY,
+		0,	RLEFT,
+		"	incb AL\n", },
+
+{ PLUS,		INAREG,
+	SAREG,	TWORD,
+	SAREG,	TWORD,
+		NAREG|NASL|NASR,	RESC1,
+		"	leal (AL,AR),A1\n", },
+
+{ MINUS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TWORD|TPOINT,
+	SONE,			TANY,
+		0,	RLEFT,
+		"	decl AL\n", },
+
+{ MINUS,	INCH|FOREFF,
+	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
+	SONE,	TANY,
+		0,	RLEFT,
+		"	decb AL\n", },
+
+/* address as register offset, negative */
+{ MINUS,	INAREG,
+	SAREG,	TWORD|TPOINT,
+	SPCON,	TANY,
+		NAREG|NASL,	RESC1,
+		"	leal -CR(AL),A1\n", },
+
+{ MINUS,	INLL|FOREFF,
+	SHLL,	TLL,
+	SHLL|SNAME|SOREG,	TLL,
+		0,	RLEFT,
+		"	subl AR,AL\n	sbbl UR,UL\n", },
+
+{ MINUS,	INFL,
+	SHFL,	TDOUBLE,
+	SNAME|SOREG,	TDOUBLE,
+		0,	RLEFT,
+		"	fsubl AR\n", },
+
+{ MINUS,	INFL|FOREFF,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+		0,	RLEFT,
+		"	fsubZAp\n", },
+
+/* Simple r/m->reg ops */
+{ OPSIMP,	INAREG|FOREFF,
+	SAREG,			TWORD|TPOINT,
+	SAREG|SNAME|SOREG,	TWORD|TPOINT,
+		0,	RLEFT,
+		"	Ol AR,AL\n", },
+
+{ OPSIMP,	INAREG|FOREFF,
+	SHINT,		TSHORT|TUSHORT,
+	SHINT|SNAME|SOREG,	TSHORT|TUSHORT,
+		0,	RLEFT,
+		"	Ow AR,AL\n", },
+
+{ OPSIMP,	INCH|FOREFF,
+	SHCH,		TCHAR|TUCHAR,
+	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
+		0,	RLEFT,
+		"	Ob AR,AL\n", },
+
+{ OPSIMP,	INAREG|FOREFF,
+	SAREG,	TWORD|TPOINT,
+	SCON,	TWORD|TPOINT,
+		0,	RLEFT,
+		"	Ol AR,AL\n", },
+
+{ OPSIMP,	INAREG|FOREFF,
+	SHINT|SNAME|SOREG,	TSHORT|TUSHORT,
+	SCON,	TANY,
+		0,	RLEFT,
+		"	Ow AR,AL\n", },
+
+{ OPSIMP,	INCH|FOREFF,
+	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
+	SCON,	TANY,
+		0,	RLEFT,
+		"	Ob AR,AL\n", },
+
+{ OPSIMP,	INLL|FOREFF,
+	SHLL,	TLL,
+	SHLL|SNAME|SOREG,	TLL,
+		0,	RLEFT,
+		"	Ol AR,AL\n	Ol UR,UL\n", },
+
+
+/*
+ * The next rules handle all shift operators.
+ */
+/* (u)longlong left shift is emulated */
+{ LS,	INCREG,
+	SCREG|SNAME|SOREG|SCON, TLL,
+	SAREG|SNAME|SOREG|SCON, TINT, /* will be int */
+		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
+		"ZO", },
+
+{ LS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TWORD,
+	SHCH,		TCHAR|TUCHAR,
+		NSPECIAL,	RLEFT,
+		"	sall AR,AL\n", },
+
+{ LS,	INAREG|FOREFF,
+	SAREG,	TWORD,
+	SCON,	TANY,
+		0,	RLEFT,
+		"	sall AR,AL\n", },
+
+{ LS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
+	SHCH,			TCHAR|TUCHAR,
+		NSPECIAL,	RLEFT,
+		"	shlw AR,AL\n", },
+
+{ LS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
+	SCON,	TANY,
+		0,	RLEFT,
+		"	shlw AR,AL\n", },
+
+{ LS,	INCH|FOREFF,
+	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
+	SHCH,			TCHAR|TUCHAR,
+		NSPECIAL,	RLEFT,
+		"	salb AR,AL\n", },
+
+{ LS,	INCH|FOREFF,
+	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
+	SCON,			TANY,
+		0,	RLEFT,
+		"	salb AR,AL\n", },
+
+/* (u)longlong right shift is emulated */
+{ RS,	INCREG,
+	SCREG|SNAME|SOREG|SCON, TLL,
+	SAREG|SNAME|SOREG|SCON, TINT, /* will be int */
+		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
+		"ZO", },
+
+{ RS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TSWORD,
+	SHCH,			TCHAR|TUCHAR,
+		NSPECIAL,	RLEFT,
+		"	sarl AR,AL\n", },
+
+{ RS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TSWORD,
+	SCON,			TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
+		0,		RLEFT,
+		"	sarl AR,AL\n", },
+
+{ RS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TUWORD,
+	SHCH,			TCHAR|TUCHAR,
+		NSPECIAL,	RLEFT,
+		"	shrl AR,AL\n", },
+
+{ RS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TUWORD,
+	SCON,			TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
+		0,		RLEFT,
+		"	shrl AR,AL\n", },
+
+{ RS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TSHORT,
+	SHCH,			TCHAR|TUCHAR,
+		NSPECIAL,	RLEFT,
+		"	sarw AR,AL\n", },
+
+{ RS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TSHORT,
+	SCON,			TANY,
+		0,		RLEFT,
+		"	sarw AR,AL\n", },
+
+{ RS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TUSHORT,
+	SHCH,			TCHAR|TUCHAR,
+		NSPECIAL,	RLEFT,
+		"	shrw AR,AL\n", },
+
+{ RS,	INAREG|FOREFF,
+	SAREG|SNAME|SOREG,	TUSHORT,
+	SCON,			TANY,
+		0,		RLEFT,
+		"	shrw AR,AL\n", },
+
+{ RS,	INCH|FOREFF,
+	SHCH|SNAME|SOREG,	TCHAR,
+	SHCH,			TCHAR|TUCHAR,
+		NSPECIAL,	RLEFT,
+		"	sarb AR,AL\n", },
+
+{ RS,	INCH|FOREFF,
+	SHCH|SNAME|SOREG,	TCHAR,
+	SCON,			TANY,
+		0,		RLEFT,
+		"	sarb AR,AL\n", },
+
+{ RS,	INCH|FOREFF,
+	SHCH|SNAME|SOREG,	TUCHAR,
+	SHCH,			TCHAR|TUCHAR,
+		NSPECIAL,	RLEFT,
+		"	shrb AR,AL\n", },
+
+{ RS,	INCH|FOREFF,
+	SHCH|SNAME|SOREG,	TUCHAR,
+	SCON,			TANY,
+		0,		RLEFT,
+		"	shrb AR,AL\n", },
+
+/*
+ * The next rules takes care of assignments. "=".
+ */
+{ ASSIGN,	FOREFF,
+	SHLL|SNAME|SOREG,	TLL,
+	SCON,		TANY,
+		0,	0,
+		"	movl AR,AL\n	movl UR,UL\n", },
+
+{ ASSIGN,	FOREFF|INLL,
+	SHLL,		TLL,
+	SCON,		TANY,
+		0,	RDEST,
+		"	movl AR,AL\n	movl UR,UL\n", },
+
+{ ASSIGN,	FOREFF,
+	SAREG|SNAME|SOREG,	TWORD|TPOINT,
+	SCON,		TANY,
+		0,	0,
+		"	movl AR,AL\n", },
+
+{ ASSIGN,	FOREFF|INAREG,
+	SAREG,	TWORD|TPOINT,
+	SCON,		TANY,
+		0,	RDEST,
+		"	movl AR,AL\n", },
+
+{ ASSIGN,	FOREFF,
+	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
+	SCON,		TANY,
+		0,	0,
+		"	movw AR,AL\n", },
+
+{ ASSIGN,	FOREFF|INAREG,
+	SAREG,	TSHORT|TUSHORT,
+	SCON,		TANY,
+		0,	RDEST,
+		"	movw AR,AL\n", },
+
+{ ASSIGN,	FOREFF,
+	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
+	SCON,		TANY,
+		0,	0,
+		"	movb AR,AL\n", },
+
+{ ASSIGN,	FOREFF|INCH,
+	SHCH,		TCHAR|TUCHAR,
+	SCON,		TANY,
+		0,	RDEST,
+		"	movb AR,AL\n", },
+
+{ ASSIGN,	FOREFF|INLL,
+	SHLL|SNAME|SOREG,	TLL,
+	SHLL,			TLL,
+		0,	RDEST,
+		"	movl AR,AL\n	movl UR,UL\n", },
+
+{ ASSIGN,	FOREFF|INAREG,
+	SAREG|SNAME|SOREG,	TWORD|TPOINT,
+	SAREG,		TWORD|TPOINT,
+		0,	RDEST,
+		"	movl AR,AL\n", },
+
+{ ASSIGN,	FOREFF|INAREG,
+	SAREG,			TWORD|TPOINT,
+	SAREG|SNAME|SOREG,	TWORD|TPOINT,
+		0,	RDEST,
+		"	movl AR,AL\n", },
+
+{ ASSIGN,	FOREFF|INAREG,
+	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
+	SAREG,		TSHORT|TUSHORT,
+		0,	RDEST,
+		"	movw AR,AL\n", },
+
+{ ASSIGN,	FOREFF|INCH,
+	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
+	SHCH,		TCHAR|TUCHAR|TWORD,
+		0,	RDEST,
+		"	movb AR,AL\n", },
+
+{ ASSIGN,	FOREFF|INBREG,
+	SFLD,		TCHAR|TUCHAR,
+	SBREG|SCON,	TCHAR|TUCHAR,
+		NBREG,	RDEST,
+		"ZE", },
+
+{ ASSIGN,	FOREFF|INAREG,
+	SFLD,		TANY,
+	SAREG,	TANY,
+		NAREG,	RDEST,
+		"ZE", },
+
+{ ASSIGN,	FOREFF,
+	SFLD,		TANY,
+	SAREG|SNAME|SOREG|SCON,	TANY,
+		NAREG,	0,
+		"ZE", },
+
+{ ASSIGN,	INDREG|FOREFF,
+	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
+	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
+		0,	RDEST,
+		"", }, /* This will always be in the correct register */
+
+/* order of table entries is very important here! */
+{ ASSIGN,	INFL,
+	SNAME|SOREG,	TLDOUBLE,
+	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
+		0,	RDEST,
+		"	fstt AL\n", },
+
+{ ASSIGN,	FOREFF,
+	SNAME|SOREG,	TLDOUBLE,
+	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
+		0,	0,
+		"	fstpt AL\n", },
+
+{ ASSIGN,	INFL,
+	SNAME|SOREG,	TDOUBLE,
+	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
+		0,	RDEST,
+		"	fstl AL\n", },
+
+{ ASSIGN,	FOREFF,
+	SNAME|SOREG,	TDOUBLE,
+	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
+		0,	0,
+		"	fstpl AL\n", },
+
+{ ASSIGN,	INFL,
+	SNAME|SOREG,	TFLOAT,
+	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
+		0,	RDEST,
+		"	fsts AL\n", },
+
+{ ASSIGN,	FOREFF,
+	SNAME|SOREG,	TFLOAT,
+	SHFL,	TFLOAT|TDOUBLE|TLDOUBLE,
+		0,	0,
+		"	fstps AL\n", },
+/* end very important order */
+
+{ ASSIGN,	INFL|FOREFF,
+	SHFL,		TLDOUBLE,
+	SHFL|SOREG|SNAME,	TLDOUBLE,
+		0,	RDEST,
+		"	fldt AR\n", },
+
+{ ASSIGN,	INFL|FOREFF,
+	SHFL,		TDOUBLE,
+	SHFL|SOREG|SNAME,	TDOUBLE,
+		0,	RDEST,
+		"	fldl AR\n", },
+
+{ ASSIGN,	INFL|FOREFF,
+	SHFL,		TFLOAT,
+	SHFL|SOREG|SNAME,	TFLOAT,
+		0,	RDEST,
+		"	flds AR\n", },
+
+/* Do not generate memcpy if return from funcall */
+#if 0
+{ STASG,	INAREG|FOREFF,
+	SOREG|SNAME|SAREG,	TPTRTO|TSTRUCT,
+	SFUNCALL,	TPTRTO|TSTRUCT,
+		0,	RRIGHT,
+		"", },
+#endif
+
+{ STASG,	INAREG|FOREFF,
+	SOREG|SNAME,	TANY,
+	SAREG|SOREG|SNAME,	TPTRTO|TANY,
+		NSPECIAL,	RRIGHT,
+		"ZQ", },
+
+/*
+ * DIV/MOD/MUL 
+ */
+/* long long div is emulated */
+{ DIV,	INCREG,
+	SCREG|SNAME|SOREG|SCON, TLL,
+	SCREG|SNAME|SOREG|SCON, TLL,
+		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
+		"ZO", },
+
+{ DIV,	INAREG,
+	SAREG,			TSWORD,
+	SAREG|SNAME|SOREG,	TWORD,
+		NSPECIAL,	RDEST,
+		"	cltd\n	idivl AR\n", },
+
+{ DIV,	INAREG,
+	SAREG,			TUWORD|TPOINT,
+	SAREG|SNAME|SOREG,	TUWORD|TPOINT,
+		NSPECIAL,	RDEST,
+		"	xorl %edx,%edx\n	divl AR\n", },
+
+{ DIV,	INAREG,
+	SAREG,			TUSHORT,
+	SAREG|SNAME|SOREG,	TUSHORT,
+		NSPECIAL,	RDEST,
+		"	xorl %edx,%edx\n	divw AR\n", },
+
+{ DIV,	INCH,
+	SHCH,			TUCHAR,
+	SHCH|SNAME|SOREG,	TUCHAR,
+		NSPECIAL,	RDEST,
+		"	xorb %ah,%ah\n	divb AR\n", },
+
+{ DIV,	INFL,
+	SHFL,		TDOUBLE,
+	SNAME|SOREG,	TDOUBLE,
+		0,	RLEFT,
+		"	fdivl AR\n", },
+
+{ DIV,	INFL,
+	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
+	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
+		0,	RLEFT,
+		"	fdivZAp\n", },
+
+/* (u)longlong mod is emulated */
+{ MOD,	INCREG,
+	SCREG|SNAME|SOREG|SCON, TLL,
+	SCREG|SNAME|SOREG|SCON, TLL,
+		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
+		"ZO", },
+
+{ MOD,	INAREG,
+	SAREG,			TSWORD,
+	SAREG|SNAME|SOREG,	TSWORD,
+		NAREG|NSPECIAL,	RESC1,
+		"	cltd\n	idivl AR\n", },
+
+{ MOD,	INAREG,
+	SAREG,			TWORD|TPOINT,
+	SAREG|SNAME|SOREG,	TUWORD|TPOINT,
+		NAREG|NSPECIAL,	RESC1,
+		"	xorl %edx,%edx\n	divl AR\n", },
+
+{ MOD,	INAREG,
+	SAREG,			TUSHORT,
+	SAREG|SNAME|SOREG,	TUSHORT,
+		NAREG|NSPECIAL,	RESC1,
+		"	xorl %edx,%edx\n	divw AR\n", },
+
+{ MOD,	INCH,
+	SHCH,			TUCHAR,
+	SHCH|SNAME|SOREG,	TUCHAR,
+		NBREG|NSPECIAL,	RESC1,
+		"	xorb %ah,%ah\n	divb AR\n", },
+
+/* (u)longlong mul is emulated */
+{ MUL,	INCREG,
+	SCREG|SNAME|SOREG|SCON, TLL,
+	SCREG|SNAME|SOREG|SCON, TLL,
+		NSPECIAL|NCREG|NCSL|NCSR,	RESC1,
+		"ZO", },
+
+{ MUL,	INAREG,
+	SAREG,				TWORD|TPOINT,
+	SAREG|SNAME|SOREG|SCON,		TWORD|TPOINT,
+		0,	RLEFT,
+		"	imull AR,AL\n", },
+
+{ MUL,	INAREG,
+	SAREG,			TSHORT|TUSHORT,
+	SAREG|SNAME|SOREG,	TSHORT|TUSHORT,
+		0,	RLEFT,
+		"	imulw AR,AL\n", },
+
+{ MUL,	INCH,
+	SHCH,			TCHAR|TUCHAR,
+	SHCH|SNAME|SOREG,	TCHAR|TUCHAR,
+		NSPECIAL,	RDEST,
+		"	imulb AR\n", },
+
+{ MUL,	INFL,
+	SHFL,		TDOUBLE,
+	SNAME|SOREG,	TDOUBLE,
+		0,	RLEFT,
+		"	fmull AR\n", },
+
+{ MUL,	INFL,
+	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
+	SHFL,		TLDOUBLE|TDOUBLE|TFLOAT,
+		0,	RLEFT,
+		"	fmulp\n", },
+
+/*
+ * Indirection operators.
+ */
+{ UMUL,	INLL,
+	SANY,	TANY,
+	SOREG,	TLL,
+		NCREG|NCSL,	RESC1,
+		"	movl UL,U1\n	movl AL,A1\n", },
+
+{ UMUL,	INAREG,
+	SANY,	TPOINT|TWORD,
+	SOREG,	TPOINT|TWORD,
+		NAREG|NASL,	RESC1,
+		"	movl AL,A1\n", },
+
+{ UMUL,	INCH,
+	SANY,	TANY,
+	SOREG,	TCHAR|TUCHAR,
+		NBREG|NBSL,	RESC1,
+		"	movb AL,A1\n", },
+
+{ UMUL,	INAREG,
+	SANY,	TANY,
+	SOREG,	TSHORT|TUSHORT,
+		NAREG|NASL,	RESC1,
+		"	movw AL,A1\n", },
+
+{ UMUL,	INFL,
+	SANY,	TANY,
+	SOREG,	TLDOUBLE,
+		NDREG|NDSL,	RESC1,
+		"	fldt AL\n", },
+
+{ UMUL,	INFL,
+	SANY,	TANY,
+	SOREG,	TDOUBLE,
+		NDREG|NDSL,	RESC1,
+		"	fldl AL\n", },
+
+{ UMUL,	INFL,
+	SANY,	TANY,
+	SOREG,	TFLOAT,
+		NDREG|NDSL,	RESC1,
+		"	flds AL\n", },
+
+/*
+ * Logical/branching operators
+ */
+
+/* Comparisions, take care of everything */
+{ OPLOG,	FORCC,
+	SHLL|SOREG|SNAME,	TLL,
+	SHLL,			TLL,
+		0,	0,
+		"ZD", },
+
+{ OPLOG,	FORCC,
+	SAREG|SOREG|SNAME,	TWORD|TPOINT,
+	SCON|SAREG,	TWORD|TPOINT,
+		0, 	RESCC,
+		"	cmpl AR,AL\n", },
+
+{ OPLOG,	FORCC,
+	SCON|SAREG,	TWORD|TPOINT,
+	SAREG|SOREG|SNAME,	TWORD|TPOINT,
+		0, 	RESCC,
+		"	cmpl AR,AL\n", },
+
+{ OPLOG,	FORCC,
+	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
+	SCON|SAREG,	TANY,
+		0, 	RESCC,
+		"	cmpw AR,AL\n", },
+
+{ OPLOG,	FORCC,
+	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
+	SCON|SBREG,	TANY,
+		0, 	RESCC,
+		"	cmpb AR,AL\n", },
+
+{ OPLOG,	FORCC,
+	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
+	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
+		NSPECIAL, 	0,
+		"ZG", },
+
+{ OPLOG,	FORCC,
+	SOREG|SNAME,	TDOUBLE|TFLOAT,
+	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
+		NSPECIAL, 	0,
+		"ZG", },
+
+#if 0
+/* Ppro and later only */
+{ OPLOG,	FORCC,
+	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
+	SDREG,	TLDOUBLE|TDOUBLE|TFLOAT,
+		0, 	RESCC,
+		"ZA	fucomip %st,%st(1)\n", },
+#endif
+
+{ OPLOG,	FORCC,
+	SANY,	TANY,
+	SANY,	TANY,
+		REWRITE,	0,
+		"diediedie!", },
+
+/* AND/OR/ER/NOT */
+{ AND,	INAREG|FOREFF,
+	SAREG|SOREG|SNAME,	TWORD,
+	SCON|SAREG,		TWORD,
+		0,	RLEFT,
+		"	andl AR,AL\n", },
+
+{ AND,	INCREG|FOREFF,
+	SCREG,			TLL,
+	SCREG|SOREG|SNAME,	TLL,
+		0,	RLEFT,
+		"	andl AR,AL\n	andl UR,UL\n", },
+
+{ AND,	INAREG|FOREFF,
+	SAREG,			TWORD,
+	SAREG|SOREG|SNAME,	TWORD,
+		0,	RLEFT,
+		"	andl AR,AL\n", },
+
+{ AND,	INAREG|FOREFF,  
+	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
+	SCON|SAREG,		TSHORT|TUSHORT,
+		0,	RLEFT,
+		"	andw AR,AL\n", },
+
+{ AND,	INAREG|FOREFF,  
+	SAREG,			TSHORT|TUSHORT,
+	SAREG|SOREG|SNAME,	TSHORT|TUSHORT,
+		0,	RLEFT,
+		"	andw AR,AL\n", },
+
+{ AND,	INBREG|FOREFF,
+	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
+	SCON|SBREG,		TCHAR|TUCHAR,
+		0,	RLEFT,
+		"	andb AR,AL\n", },
+
+{ AND,	INBREG|FOREFF,
+	SBREG,			TCHAR|TUCHAR,
+	SBREG|SOREG|SNAME,	TCHAR|TUCHAR,
+		0,	RLEFT,
+		"	andb AR,AL\n", },
+/* AND/OR/ER/NOT */
+
+/*
+ * Jumps.
+ */
+{ GOTO, 	FOREFF,
+	SCON,	TANY,
+	SANY,	TANY,
+		0,	RNOP,
+		"	jmp LL\n", },
+
+#ifdef GCC_COMPAT
+{ GOTO, 	FOREFF,
+	SAREG,	TANY,
+	SANY,	TANY,
+		0,	RNOP,
+		"	jmp *AL\n", },
+#endif
+
+/*
+ * Convert LTYPE to reg.
+ */
+{ OPLTYPE,	INLL,
+	SANY,	TANY,
+	SCREG|SCON|SOREG|SNAME,	TLL,
+		NCREG,	RESC1,
+		"	movl UL,U1\n	movl AL,A1\n", },
+
+{ OPLTYPE,	INAREG,
+	SANY,	TANY,
+	SAREG|SCON|SOREG|SNAME,	TWORD|TPOINT,
+		NAREG|NASL,	RESC1,
+		"	movl AL,A1\n", },
+
+{ OPLTYPE,	INBREG,
+	SANY,	TANY,
+	SBREG|SOREG|SNAME|SCON,	TCHAR|TUCHAR,
+		NBREG,	RESC1,
+		"	movb AL,A1\n", },
+
+{ OPLTYPE,	INAREG,
+	SANY,	TANY,
+	SAREG|SOREG|SNAME|SCON,	TSHORT|TUSHORT,
+		NAREG,	RESC1,
+		"	movw AL,A1\n", },
+
+{ OPLTYPE,	INDREG,
+	SANY,		TLDOUBLE,
+	SOREG|SNAME,	TLDOUBLE,
+		NDREG,	RESC1,
+		"	fldt AL\n", },
+
+{ OPLTYPE,	INDREG,
+	SANY,		TDOUBLE,
+	SOREG|SNAME,	TDOUBLE,
+		NDREG,	RESC1,
+		"	fldl AL\n", },
+
+{ OPLTYPE,	INDREG,
+	SANY,		TFLOAT,
+	SOREG|SNAME,	TFLOAT,
+		NDREG,	RESC1,
+		"	flds AL\n", },
+
+/* Only used in ?: constructs. The stack already contains correct value */
+{ OPLTYPE,	INDREG,
+	SANY,	TFLOAT|TDOUBLE|TLDOUBLE,
+	SDREG,	TFLOAT|TDOUBLE|TLDOUBLE,
+		NDREG,	RESC1,
+		"", },
+
+/*
+ * Negate a word.
+ */
+
+{ UMINUS,	INCREG|FOREFF,
+	SCREG,	TLL,
+	SCREG,	TLL,
+		0,	RLEFT,
+		"	negl AL\n	adcl $0,UL\n	negl UL\n", },
+
+{ UMINUS,	INAREG|FOREFF,
+	SAREG,	TWORD|TPOINT,
+	SAREG,	TWORD|TPOINT,
+		0,	RLEFT,
+		"	negl AL\n", },
+
+{ UMINUS,	INAREG|FOREFF,
+	SAREG,	TSHORT|TUSHORT,
+	SAREG,	TSHORT|TUSHORT,
+		0,	RLEFT,
+		"	negw AL\n", },
+
+{ UMINUS,	INBREG|FOREFF,
+	SBREG,	TCHAR|TUCHAR,
+	SBREG,	TCHAR|TUCHAR,
+		0,	RLEFT,
+		"	negb AL\n", },
+
+{ UMINUS,	INFL|FOREFF,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+	SHFL,	TLDOUBLE|TDOUBLE|TFLOAT,
+		0,	RLEFT,
+		"	fchs\n", },
+
+{ COMPL,	INCREG,
+	SCREG,	TLL,
+	SANY,	TANY,
+		0,	RLEFT,
+		"	notl AL\n	notl UL\n", },
+
+{ COMPL,	INAREG,
+	SAREG,	TWORD,
+	SANY,	TANY,
+		0,	RLEFT,
+		"	notl AL\n", },
+
+{ COMPL,	INAREG,
+	SAREG,	TSHORT|TUSHORT,
+	SANY,	TANY,
+		0,	RLEFT,
+		"	notw AL\n", },
+
+{ COMPL,	INBREG,
+	SBREG,	TCHAR|TUCHAR,
+	SANY,	TANY,
+		0,	RLEFT,
+		"	notb AL\n", },
+
+/*
+ * Arguments to functions.
+ */
+{ FUNARG,	FOREFF,
+	SCON|SCREG|SNAME|SOREG,	TLL,
+	SANY,	TLL,
+		0,	RNULL,
+		"	pushl UL\n	pushl AL\n", },
+
+{ FUNARG,	FOREFF,
+	SCON|SAREG|SNAME|SOREG,	TWORD|TPOINT,
+	SANY,	TWORD|TPOINT,
+		0,	RNULL,
+		"	pushl AL\n", },
+
+{ FUNARG,	FOREFF,
+	SCON,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+	SANY,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+		0,	RNULL,
+		"	pushl AL\n", },
+
+{ FUNARG,	FOREFF,
+	SAREG|SNAME|SOREG,	TSHORT,
+	SANY,	TSHORT,
+		NAREG,	0,
+		"	movswl AL,ZN\n	pushl ZN\n", },
+
+{ FUNARG,	FOREFF,
+	SAREG|SNAME|SOREG,	TUSHORT,
+	SANY,	TUSHORT,
+		NAREG,	0,
+		"	movzwl AL,ZN\n	pushl ZN\n", },
+
+{ FUNARG,	FOREFF,
+	SHCH|SNAME|SOREG,	TCHAR,
+	SANY,			TCHAR,
+		NAREG,	0,
+		"	movsbl AL,A1\n	pushl A1\n", },
+
+{ FUNARG,	FOREFF,
+	SHCH|SNAME|SOREG,	TUCHAR,
+	SANY,	TUCHAR,
+		NAREG,	0,
+		"	movzbl AL,A1\n	pushl A1\n", },
+
+{ FUNARG,	FOREFF,
+	SNAME|SOREG,	TDOUBLE,
+	SANY,	TDOUBLE,
+		0,	0,
+		"	pushl UL\n	pushl AL\n", },
+
+{ FUNARG,	FOREFF,
+	SDREG,	TDOUBLE,
+	SANY,		TDOUBLE,
+		0,	0,
+		"	subl $8,%esp\n	fstpl (%esp)\n", },
+
+{ FUNARG,	FOREFF,
+	SNAME|SOREG,	TFLOAT,
+	SANY,		TFLOAT,
+		0,	0,
+		"	pushl AL\n", },
+
+{ FUNARG,	FOREFF,
+	SDREG,	TFLOAT,
+	SANY,		TFLOAT,
+		0,	0,
+		"	subl $4,%esp\n	fstps (%esp)\n", },
+
+{ FUNARG,	FOREFF,
+	SDREG,	TLDOUBLE,
+	SANY,		TLDOUBLE,
+		0,	0,
+		"	subl $12,%esp\n	fstpt (%esp)\n", },
+
+{ STARG,	FOREFF,
+	SAREG|SOREG|SNAME|SCON,	TANY,
+	SANY,	TSTRUCT,
+		NSPECIAL|NAREG,	0,
+		"ZF", },
+
+# define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
+
+{ UMUL, DF( UMUL ), },
+
+{ ASSIGN, DF(ASSIGN), },
+
+{ STASG, DF(STASG), },
+
+{ FLD, DF(FLD), },
+
+{ OPLEAF, DF(NAME), },
+
+/* { INIT, DF(INIT), }, */
+
+{ OPUNARY, DF(UMINUS), },
+
+{ OPANY, DF(BITYPE), },
+
+{ FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	"help; I'm in trouble\n" },
+};
+
+int tablesize = sizeof(table)/sizeof(table[0]);
--- /dev/null
+++ usr.bin/pcc/i386/local2.c
@@ -0,0 +1,1052 @@
+/*	$Id: local2.c,v 1.89 2007/09/16 19:08:16 ragge Exp $	*/
+/*
+ * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+# include "pass2.h"
+# include <ctype.h>
+# include <string.h>
+
+void acon(NODE *p);
+int argsize(NODE *p);
+
+static int stkpos;
+
+void
+lineid(int l, char *fn)
+{
+	/* identify line l and file fn */
+	printf("#	line %d, file %s\n", l, fn);
+}
+
+void
+deflab(int label)
+{
+	printf(LABFMT ":\n", label);
+}
+
+static int regoff[7];
+static TWORD ftype;
+
+/*
+ * Print out the prolog assembler.
+ * addto and regoff are already calculated.
+ */
+static void
+prtprolog(struct interpass_prolog *ipp, int addto)
+{
+	int i, j;
+
+	printf("	pushl %%ebp\n");
+	printf("	movl %%esp,%%ebp\n");
+	if (addto)
+		printf("	subl $%d,%%esp\n", addto);
+	for (i = ipp->ipp_regs, j = 0; i; i >>= 1, j++)
+		if (i & 1)
+			fprintf(stdout, "	movl %s,-%d(%s)\n",
+			    rnames[j], regoff[j], rnames[FPREG]);
+}
+
+/*
+ * calculate stack size and offsets
+ */
+static int
+offcalc(struct interpass_prolog *ipp)
+{
+	int i, j, addto;
+
+	addto = p2maxautooff;
+	if (addto >= AUTOINIT/SZCHAR)
+		addto -= AUTOINIT/SZCHAR;
+	for (i = ipp->ipp_regs, j = 0; i ; i >>= 1, j++) {
+		if (i & 1) {
+			addto += SZINT/SZCHAR;
+			regoff[j] = addto;
+		}
+	}
+	return addto;
+}
+
+void
+prologue(struct interpass_prolog *ipp)
+{
+	int addto;
+
+	ftype = ipp->ipp_type;
+	if (ipp->ipp_vis)
+		printf("	.globl %s\n", ipp->ipp_name);
+	printf("	.align 4\n");
+	printf("%s:\n", ipp->ipp_name);
+	/*
+	 * We here know what register to save and how much to 
+	 * add to the stack.
+	 */
+	addto = offcalc(ipp);
+	prtprolog(ipp, addto);
+}
+
+void
+eoftn(struct interpass_prolog *ipp)
+{
+	int i, j;
+
+	if (ipp->ipp_ip.ip_lbl == 0)
+		return; /* no code needs to be generated */
+
+	/* return from function code */
+	for (i = ipp->ipp_regs, j = 0; i ; i >>= 1, j++) {
+		if (i & 1)
+			fprintf(stdout, "	movl -%d(%s),%s\n",
+			    regoff[j], rnames[FPREG], rnames[j]);
+			
+	}
+
+	/* struct return needs special treatment */
+	if (ftype == STRTY || ftype == UNIONTY) {
+		printf("	movl 8(%%ebp),%%eax\n");
+		printf("	leave\n");
+		printf("	ret $4\n");
+	} else {
+		printf("	leave\n");
+		printf("	ret\n");
+	}
+}
+
+/*
+ * add/sub/...
+ *
+ * Param given:
+ */
+void
+hopcode(int f, int o)
+{
+	char *str;
+
+	switch (o) {
+	case PLUS:
+		str = "add";
+		break;
+	case MINUS:
+		str = "sub";
+		break;
+	case AND:
+		str = "and";
+		break;
+	case OR:
+		str = "or";
+		break;
+	case ER:
+		str = "xor";
+		break;
+	default:
+		comperr("hopcode2: %d", o);
+		str = 0; /* XXX gcc */
+	}
+	printf("%s%c", str, f);
+}
+
+/*
+ * Return type size in bytes.  Used by R2REGS, arg 2 to offset().
+ */
+int
+tlen(p) NODE *p;
+{
+	switch(p->n_type) {
+		case CHAR:
+		case UCHAR:
+			return(1);
+
+		case SHORT:
+		case USHORT:
+			return(SZSHORT/SZCHAR);
+
+		case DOUBLE:
+			return(SZDOUBLE/SZCHAR);
+
+		case INT:
+		case UNSIGNED:
+		case LONG:
+		case ULONG:
+			return(SZINT/SZCHAR);
+
+		case LONGLONG:
+		case ULONGLONG:
+			return SZLONGLONG/SZCHAR;
+
+		default:
+			if (!ISPTR(p->n_type))
+				comperr("tlen type %d not pointer");
+			return SZPOINT(p->n_type)/SZCHAR;
+		}
+}
+
+/*
+ * Emit code to compare two longlong numbers.
+ */
+static void
+twollcomp(NODE *p)
+{
+	int o = p->n_op;
+	int s = getlab();
+	int e = p->n_label;
+	int cb1, cb2;
+
+	if (o >= ULE)
+		o -= (ULE-LE);
+	switch (o) {
+	case NE:
+		cb1 = 0;
+		cb2 = NE;
+		break;
+	case EQ:
+		cb1 = NE;
+		cb2 = 0;
+		break;
+	case LE:
+	case LT:
+		cb1 = GT;
+		cb2 = LT;
+		break;
+	case GE:
+	case GT:
+		cb1 = LT;
+		cb2 = GT;
+		break;
+	
+	default:
+		cb1 = cb2 = 0; /* XXX gcc */
+	}
+	if (p->n_op >= ULE)
+		cb1 += 4, cb2 += 4;
+	expand(p, 0, "	cmpl UR,UL\n");
+	if (cb1) cbgen(cb1, s);
+	if (cb2) cbgen(cb2, e);
+	expand(p, 0, "	cmpl AR,AL\n");
+	cbgen(p->n_op, e);
+	deflab(s);
+}
+
+/*
+ * Assign to a bitfield.
+ * Clumsy at least, but what to do?
+ */
+static void
+bfasg(NODE *p)
+{
+	NODE *fn = p->n_left;
+	int shift = UPKFOFF(fn->n_rval);
+	int fsz = UPKFSZ(fn->n_rval);
+	int andval, tch = 0;
+
+	/* get instruction size */
+	switch (p->n_type) {
+	case CHAR: case UCHAR: tch = 'b'; break;
+	case SHORT: case USHORT: tch = 'w'; break;
+	case INT: case UNSIGNED: tch = 'l'; break;
+	default: comperr("bfasg");
+	}
+
+	/* put src into a temporary reg */
+	fprintf(stdout, "	mov%c ", tch);
+	adrput(stdout, getlr(p, 'R'));
+	fprintf(stdout, ",");
+	adrput(stdout, getlr(p, '1'));
+	fprintf(stdout, "\n");
+
+	/* AND away the bits from dest */
+	andval = ~(((1 << fsz) - 1) << shift);
+	fprintf(stdout, "	and%c $%d,", tch, andval);
+	adrput(stdout, fn->n_left);
+	fprintf(stdout, "\n");
+
+	/* AND away unwanted bits from src */
+	andval = ((1 << fsz) - 1);
+	fprintf(stdout, "	and%c $%d,", tch, andval);
+	adrput(stdout, getlr(p, '1'));
+	fprintf(stdout, "\n");
+
+	/* SHIFT left src number of bits */
+	if (shift) {
+		fprintf(stdout, "	sal%c $%d,", tch, shift);
+		adrput(stdout, getlr(p, '1'));
+		fprintf(stdout, "\n");
+	}
+
+	/* OR in src to dest */
+	fprintf(stdout, "	or%c ", tch);
+	adrput(stdout, getlr(p, '1'));
+	fprintf(stdout, ",");
+	adrput(stdout, fn->n_left);
+	fprintf(stdout, "\n");
+}
+
+/*
+ * Push a structure on stack as argument.
+ * the scratch registers are already free here
+ */
+static void
+starg(NODE *p)
+{
+	FILE *fp = stdout;
+
+	fprintf(fp, "	subl $%d,%%esp\n", p->n_stsize);
+	fprintf(fp, "	pushl $%d\n", p->n_stsize);
+	expand(p, 0, "	pushl AL\n");
+	expand(p, 0, "	leal 8(%esp),A1\n");
+	expand(p, 0, "	pushl A1\n");
+	fprintf(fp, "	call memcpy\n");
+	fprintf(fp, "	addl $12,%%esp\n");
+}
+
+/*
+ * Compare two floating point numbers.
+ */
+static void
+fcomp(NODE *p)  
+{
+	
+	if (p->n_left->n_op == REG) {
+		if (p->n_su & DORIGHT)
+			expand(p, 0, "	fxch\n");
+		expand(p, 0, "	fucompp\n");	/* emit compare insn  */
+	} else if (p->n_left->n_type == DOUBLE)
+		expand(p, 0, "	fcompl AL\n");	/* emit compare insn  */
+	else if (p->n_left->n_type == FLOAT)
+		expand(p, 0, "	fcomp AL\n");	/* emit compare insn  */
+	else
+		comperr("bad compare %p\n", p);
+	expand(p, 0, "	fnstsw %ax\n");	/* move status reg to ax */
+	
+	switch (p->n_op) {
+	case EQ:
+		expand(p, 0, "	andb $64,%ah\n	jne LC\n");
+		break;
+	case NE:
+		expand(p, 0, "	andb $64,%ah\n	je LC\n");
+		break;
+	case LE:
+		expand(p, 0, "	andb $65,%ah\n	cmpb $1,%ah\n	jne LC\n");
+		break;
+	case LT:
+		expand(p, 0, "	andb $65,%ah\n	je LC\n");
+		break;
+	case GT:
+		expand(p, 0, "	andb $1,%ah\n	jne LC\n");
+		break;
+	case GE:
+		expand(p, 0, "	andb $65,%ah\n	jne LC\n");
+		break;
+	default:
+		comperr("fcomp op %d\n", p->n_op);
+	}
+}
+
+/*
+ * Convert an unsigned long long to floating point number.
+ */
+static void
+ulltofp(NODE *p)
+{
+	static int loadlab;
+	int jmplab;
+
+	if (loadlab == 0) {
+		loadlab = getlab();
+		expand(p, 0, "	.data\n");
+		printf(LABFMT ":	.long 0,0x80000000,0x403f\n", loadlab);
+		expand(p, 0, "	.text\n");
+	}
+	jmplab = getlab();
+	expand(p, 0, "	pushl UL\n	pushl AL\n");
+	expand(p, 0, "	fildq (%esp)\n");
+	expand(p, 0, "	addl $8,%esp\n");
+	expand(p, 0, "	cmpl $0,UL\n");
+	printf("	jge " LABFMT "\n", jmplab);
+	printf("	fldt " LABFMT "\n", loadlab);
+	printf("	faddp %%st,%%st(1)\n");
+	printf(LABFMT ":\n", jmplab);
+}
+
+static int
+argsiz(NODE *p)
+{
+	TWORD t = p->n_type;
+
+	if (t < LONGLONG || t == FLOAT || t > BTMASK)
+		return 4;
+	if (t == LONGLONG || t == ULONGLONG || t == DOUBLE)
+		return 8;
+	if (t == LDOUBLE)
+		return 12;
+	if (t == STRTY || t == UNIONTY)
+		return p->n_stsize;
+	comperr("argsiz");
+	return 0;
+}
+
+void
+zzzcode(NODE *p, int c)
+{
+	NODE *r, *l;
+	int pr, lr, s;
+	char *ch;
+
+	switch (c) {
+	case 'A': /* swap st0 and st1 if right is evaluated second */
+		if ((p->n_su & DORIGHT) == 0) {
+			if (logop(p->n_op))
+				printf("	fxch\n");
+			else
+				printf("r");
+		}
+		break;
+
+	case 'C':  /* remove from stack after subroutine call */
+		pr = p->n_qual;
+		if (p->n_op == STCALL || p->n_op == USTCALL)
+			pr += 4;
+		if (p->n_op == UCALL)
+			return; /* XXX remove ZC from UCALL */
+		if (pr)
+			printf("	addl $%d, %s\n", pr, rnames[ESP]);
+		break;
+
+	case 'D': /* Long long comparision */
+		twollcomp(p);
+		break;
+
+	case 'E': /* Assign to bitfield */
+		bfasg(p);
+		break;
+
+	case 'F': /* Structure argument */
+		if (p->n_stalign != 0) /* already on stack */
+			starg(p);
+		break;
+
+	case 'G': /* Floating point compare */
+		fcomp(p);
+		break;
+
+	case 'J': /* convert unsigned long long to floating point */
+		ulltofp(p);
+		break;
+
+	case 'M': /* Output sconv move, if needed */
+		l = getlr(p, 'L');
+		/* XXX fixneed: regnum */
+		pr = DECRA(p->n_reg, 0);
+		lr = DECRA(l->n_reg, 0);
+		if ((pr == AL && lr == EAX) || (pr == BL && lr == EBX) ||
+		    (pr == CL && lr == ECX) || (pr == DL && lr == EDX))
+			;
+		else
+			printf("	movb %%%cl,%s\n",
+			    rnames[lr][2], rnames[pr]);
+		l->n_rval = l->n_reg = p->n_reg; /* XXX - not pretty */
+		break;
+
+	case 'N': /* output extended reg name */
+		printf("%s", rnames[getlr(p, '1')->n_rval]);
+		break;
+
+	case 'O': /* print out emulated ops */
+		pr = 16;
+		if (p->n_op == RS || p->n_op == LS) {
+			expand(p, INAREG, "\tpushl AR\n");
+			pr = 12;
+		} else
+			expand(p, INCREG, "\tpushl UR\n\tpushl AR\n");
+		expand(p, INCREG, "\tpushl UL\n\tpushl AL\n");
+		if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
+		else if (p->n_op == DIV) ch = "div";
+		else if (p->n_op == MUL) ch = "mul";
+		else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
+		else if (p->n_op == MOD) ch = "mod";
+		else if (p->n_op == RS && p->n_type == ULONGLONG) ch = "lshr";
+		else if (p->n_op == RS) ch = "ashr";
+		else if (p->n_op == LS) ch = "ashl";
+		else ch = 0, comperr("ZO");
+		printf("\tcall __%sdi3\n\taddl $%d,%s\n", ch, pr, rnames[ESP]);
+                break;
+
+	case 'P': /* push hidden argument on stack */
+		r = (NODE *)p->n_sue;
+		printf("\tleal -%d(%%ebp),", stkpos);
+		adrput(stdout, getlr(p, '1'));
+		printf("\n\tpushl ");
+		adrput(stdout, getlr(p, '1'));
+		putchar('\n');
+		break;
+
+	case 'Q': /* emit struct assign */
+		/* XXX - optimize for small structs */
+		printf("\tpushl $%d\n", p->n_stsize);
+		expand(p, INAREG, "\tpushl AR\n");
+		expand(p, INAREG, "\tleal AL,%eax\n\tpushl %eax\n");
+		printf("\tcall memcpy\n");
+		printf("\taddl $12,%%esp\n");
+		break;
+
+	case 'S': /* emit eventual move after cast from longlong */
+		pr = DECRA(p->n_reg, 0);
+		lr = p->n_left->n_rval;
+		switch (p->n_type) {
+		case CHAR:
+		case UCHAR:
+			if (rnames[pr][2] == 'l' && rnames[lr][2] == 'x' &&
+			    rnames[pr][1] == rnames[lr][1])
+				break;
+			if (rnames[lr][2] == 'x') {
+				printf("\tmovb %%%cl,%s\n",
+				    rnames[lr][1], rnames[pr]);
+				break;
+			}
+			/* Must go via stack */
+			s = BITOOR(freetemp(1));
+			printf("\tmovl %%e%ci,%d(%%ebp)\n", rnames[lr][1], s);
+			printf("\tmovb %d(%%ebp),%s\n", s, rnames[pr]);
+//			comperr("SCONV1 %s->%s", rnames[lr], rnames[pr]);
+			break;
+
+		case SHORT:
+		case USHORT:
+			if (rnames[lr][1] == rnames[pr][2] &&
+			    rnames[lr][2] == rnames[pr][3])
+				break;
+			printf("\tmovw %%%c%c,%%%s\n",
+			    rnames[lr][1], rnames[lr][2], rnames[pr]+2);
+			break;
+		case INT:
+		case UNSIGNED:
+			if (rnames[lr][1] == rnames[pr][2] &&
+			    rnames[lr][2] == rnames[pr][3])
+				break;
+			printf("\tmovl %%e%c%c,%s\n",
+				    rnames[lr][1], rnames[lr][2], rnames[pr]);
+			break;
+
+		default:
+			if (rnames[lr][1] == rnames[pr][2] &&
+			    rnames[lr][2] == rnames[pr][3])
+				break;
+			comperr("SCONV2 %s->%s", rnames[lr], rnames[pr]);
+			break;
+		}
+		break;
+
+	default:
+		comperr("zzzcode %c", c);
+	}
+}
+
+/*ARGSUSED*/
+int
+rewfld(NODE *p)
+{
+	return(1);
+}
+
+int canaddr(NODE *);
+int
+canaddr(NODE *p)
+{
+	int o = p->n_op;
+
+	if (o==NAME || o==REG || o==ICON || o==OREG ||
+	    (o==UMUL && shumul(p->n_left)))
+		return(1);
+	return(0);
+}
+
+/*
+ * Does the bitfield shape match?
+ */
+int
+flshape(NODE *p)
+{
+	int o = p->n_op;
+
+	if (o == OREG || o == REG || o == NAME)
+		return SRDIR; /* Direct match */
+	if (o == UMUL && shumul(p->n_left))
+		return SROREG; /* Convert into oreg */
+	return SRREG; /* put it into a register */
+}
+
+/* INTEMP shapes must not contain any temporary registers */
+/* XXX should this go away now? */
+int
+shtemp(NODE *p)
+{
+	return 0;
+#if 0
+	int r;
+
+	if (p->n_op == STARG )
+		p = p->n_left;
+
+	switch (p->n_op) {
+	case REG:
+		return (!istreg(p->n_rval));
+
+	case OREG:
+		r = p->n_rval;
+		if (R2TEST(r)) {
+			if (istreg(R2UPK1(r)))
+				return(0);
+			r = R2UPK2(r);
+		}
+		return (!istreg(r));
+
+	case UMUL:
+		p = p->n_left;
+		return (p->n_op != UMUL && shtemp(p));
+	}
+
+	if (optype(p->n_op) != LTYPE)
+		return(0);
+	return(1);
+#endif
+}
+
+void
+adrcon(CONSZ val)
+{
+	printf("$" CONFMT, val);
+}
+
+void
+conput(FILE *fp, NODE *p)
+{
+	int val = p->n_lval;
+
+	switch (p->n_op) {
+	case ICON:
+		if (p->n_name[0] != '\0') {
+			fprintf(fp, "%s", p->n_name);
+			if (val)
+				fprintf(fp, "+%d", val);
+		} else
+			fprintf(fp, "%d", val);
+		return;
+
+	default:
+		comperr("illegal conput, p %p", p);
+	}
+}
+
+/*ARGSUSED*/
+void
+insput(NODE *p)
+{
+	comperr("insput");
+}
+
+/*
+ * Write out the upper address, like the upper register of a 2-register
+ * reference, or the next memory location.
+ */
+void
+upput(NODE *p, int size)
+{
+
+	size /= SZCHAR;
+	switch (p->n_op) {
+	case REG:
+		fprintf(stdout, "%%%s", &rnames[p->n_rval][3]);
+		break;
+
+	case NAME:
+	case OREG:
+		p->n_lval += size;
+		adrput(stdout, p);
+		p->n_lval -= size;
+		break;
+	case ICON:
+		fprintf(stdout, "$" CONFMT, p->n_lval >> 32);
+		break;
+	default:
+		comperr("upput bad op %d size %d", p->n_op, size);
+	}
+}
+
+void
+adrput(FILE *io, NODE *p)
+{
+	int r;
+	/* output an address, with offsets, from p */
+
+	if (p->n_op == FLD)
+		p = p->n_left;
+
+	switch (p->n_op) {
+
+	case NAME:
+		if (p->n_name[0] != '\0') {
+			fputs(p->n_name, io);
+			if (p->n_lval != 0)
+				fprintf(io, "+" CONFMT, p->n_lval);
+		} else
+			fprintf(io, CONFMT, p->n_lval);
+		return;
+
+	case OREG:
+		r = p->n_rval;
+		if (p->n_lval)
+			fprintf(io, "%d", (int)p->n_lval);
+		if (R2TEST(r)) {
+			fprintf(io, "(%s,%s,4)", rnames[R2UPK1(r)],
+			    rnames[R2UPK2(r)]);
+		} else
+			fprintf(io, "(%s)", rnames[p->n_rval]);
+		return;
+	case ICON:
+		/* addressable value of the constant */
+		fputc('$', io);
+		conput(io, p);
+		return;
+
+	case MOVE:
+	case REG:
+		switch (p->n_type) {
+		case LONGLONG:
+		case ULONGLONG:
+			fprintf(io, "%%%c%c%c", rnames[p->n_rval][0],
+			    rnames[p->n_rval][1], rnames[p->n_rval][2]);
+			break;
+		case SHORT:
+		case USHORT:
+			fprintf(io, "%%%s", &rnames[p->n_rval][2]);
+			break;
+		default:
+			fprintf(io, "%s", rnames[p->n_rval]);
+		}
+		return;
+
+	default:
+		comperr("illegal address, op %d, node %p", p->n_op, p);
+		return;
+
+	}
+}
+
+static char *
+ccbranches[] = {
+	"je",		/* jumpe */
+	"jne",		/* jumpn */
+	"jle",		/* jumple */
+	"jl",		/* jumpl */
+	"jge",		/* jumpge */
+	"jg",		/* jumpg */
+	"jbe",		/* jumple (jlequ) */
+	"jb",		/* jumpl (jlssu) */
+	"jae",		/* jumpge (jgequ) */
+	"ja",		/* jumpg (jgtru) */
+};
+
+
+/*   printf conditional and unconditional branches */
+void
+cbgen(int o, int lab)
+{
+	if (o < EQ || o > UGT)
+		comperr("bad conditional branch: %s", opst[o]);
+	printf("	%s " LABFMT "\n", ccbranches[o-EQ], lab);
+}
+
+static void
+fixcalls(NODE *p)
+{
+	/* Prepare for struct return by allocating bounce space on stack */
+	switch (p->n_op) {
+	case STCALL:
+	case USTCALL:
+		if (p->n_stsize+p2autooff > stkpos)
+			stkpos = p->n_stsize+p2autooff;
+		break;
+	}
+}
+
+/*
+ * Must store floats in memory if there are two function calls involved.
+ */
+static int
+storefloat(struct interpass *ip, NODE *p)
+{
+	int l, r;
+
+	switch (optype(p->n_op)) {
+	case BITYPE:
+		l = storefloat(ip, p->n_left);
+		r = storefloat(ip, p->n_right);
+		if (p->n_op == CM)
+			return 0; /* arguments, don't care */
+		if (callop(p->n_op))
+			return 1; /* found one */
+#define ISF(p) ((p)->n_type == FLOAT || (p)->n_type == DOUBLE || \
+	(p)->n_type == LDOUBLE)
+		if (ISF(p->n_left) && ISF(p->n_right) && l && r) {
+			/* must store one. store left */
+			struct interpass *nip;
+			TWORD t = p->n_left->n_type;
+			NODE *ll;
+			int off;
+
+                	off = BITOOR(freetemp(szty(t)));
+                	ll = mklnode(OREG, off, FPREG, t);
+			nip = ipnode(mkbinode(ASSIGN, ll, p->n_left, t));
+			p->n_left = mklnode(OREG, off, FPREG, t);
+                	DLIST_INSERT_BEFORE(ip, nip, qelem);
+		}
+		return l|r;
+
+	case UTYPE:
+		l = storefloat(ip, p->n_left);
+		if (callop(p->n_op))
+			l = 1;
+		return l;
+	default:
+		return 0;
+	}
+}
+
+void
+myreader(struct interpass *ipole)
+{
+	struct interpass *ip;
+
+	stkpos = p2autooff;
+	DLIST_FOREACH(ip, ipole, qelem) {
+		if (ip->type != IP_NODE)
+			continue;
+		walkf(ip->ip_node, fixcalls);
+		storefloat(ip, ip->ip_node);
+	}
+	if (stkpos > p2autooff)
+		p2autooff = stkpos;
+	if (stkpos > p2maxautooff)
+		p2maxautooff = stkpos;
+	if (x2debug)
+		printip(ipole);
+}
+
+/*
+ * Remove some PCONVs after OREGs are created.
+ */
+static void
+pconv2(NODE *p)
+{
+	NODE *q;
+
+	if (p->n_op == PLUS) {
+		if (p->n_type == (PTR|SHORT) || p->n_type == (PTR|USHORT)) {
+			if (p->n_right->n_op != ICON)
+				return;
+			if (p->n_left->n_op != PCONV)
+				return;
+			if (p->n_left->n_left->n_op != OREG)
+				return;
+			q = p->n_left->n_left;
+			nfree(p->n_left);
+			p->n_left = q;
+			/*
+			 * This will be converted to another OREG later.
+			 */
+		}
+	}
+}
+
+void
+mycanon(NODE *p)
+{
+	walkf(p, pconv2);
+}
+
+void
+myoptim(struct interpass *ip)
+{
+}
+
+static char rl[] =
+  { EAX, EAX, EAX, EAX, EAX, EDX, EDX, EDX, EDX, ECX, ECX, ECX, EBX, EBX, ESI };
+static char rh[] =
+  { EDX, ECX, EBX, ESI, EDI, ECX, EBX, ESI, EDI, EBX, ESI, EDI, ESI, EDI, EDI };
+
+void
+rmove(int s, int d, TWORD t)
+{
+	int sl, sh, dl, dh;
+
+	switch (t) {
+	case LONGLONG:
+	case ULONGLONG:
+#if 1
+		sl = rl[s-EAXEDX];
+		sh = rh[s-EAXEDX];
+		dl = rl[d-EAXEDX];
+		dh = rh[d-EAXEDX];
+
+		/* sanity checks, remove when satisfied */
+		if (memcmp(rnames[s], rnames[sl]+1, 3) != 0 ||
+		    memcmp(rnames[s]+3, rnames[sh]+1, 3) != 0)
+			comperr("rmove source error");
+		if (memcmp(rnames[d], rnames[dl]+1, 3) != 0 ||
+		    memcmp(rnames[d]+3, rnames[dh]+1, 3) != 0)
+			comperr("rmove dest error");
+#define	SW(x,y) { int i = x; x = y; y = i; }
+		if (sl == dh || sh == dl) {
+			/* Swap if moving to itself */
+			SW(sl, sh);
+			SW(dl, dh);
+		}
+		if (sl != dl)
+			printf("	movl %s,%s\n", rnames[sl], rnames[dl]);
+		if (sh != dh)
+			printf("	movl %s,%s\n", rnames[sh], rnames[dh]);
+#else
+		if (memcmp(rnames[s], rnames[d], 3) != 0)
+			printf("	movl %%%c%c%c,%%%c%c%c\n",
+			    rnames[s][0],rnames[s][1],rnames[s][2],
+			    rnames[d][0],rnames[d][1],rnames[d][2]);
+		if (memcmp(&rnames[s][3], &rnames[d][3], 3) != 0)
+			printf("	movl %%%c%c%c,%%%c%c%c\n",
+			    rnames[s][3],rnames[s][4],rnames[s][5],
+			    rnames[d][3],rnames[d][4],rnames[d][5]);
+#endif
+		break;
+	case CHAR:
+	case UCHAR:
+		printf("	movb %s,%s\n", rnames[s], rnames[d]);
+		break;
+	case FLOAT:
+	case DOUBLE:
+	case LDOUBLE:
+#ifdef notdef
+		/* a=b()*c(); will generate this */
+		comperr("bad float rmove: %d %d", s, d);
+#endif
+		break;
+	default:
+		printf("	movl %s,%s\n", rnames[s], rnames[d]);
+	}
+}
+
+/*
+ * For class c, find worst-case displacement of the number of
+ * registers in the array r[] indexed by class.
+ */
+int
+COLORMAP(int c, int *r)
+{
+	int num;
+
+	switch (c) {
+	case CLASSA:
+		num = r[CLASSB] > 4 ? 4 : r[CLASSB];
+		num += 2*r[CLASSC];
+		num += r[CLASSA];
+		return num < 6;
+	case CLASSB:
+		num = r[CLASSA];
+		num += 2*r[CLASSC];
+		num += r[CLASSB];
+		return num < 4;
+	case CLASSC:
+		num = r[CLASSA];
+		num += r[CLASSB] > 4 ? 4 : r[CLASSB];
+		num += 2*r[CLASSC];
+		return num < 5;
+	case CLASSD:
+		return r[CLASSD] < DREGCNT;
+	}
+	return 0; /* XXX gcc */
+}
+
+char *rnames[] = {
+	"%eax", "%edx", "%ecx", "%ebx", "%esi", "%edi", "%ebp", "%esp",
+	"%al", "%ah", "%dl", "%dh", "%cl", "%ch", "%bl", "%bh",
+	"eaxedx", "eaxecx", "eaxebx", "eaxesi", "eaxedi", "edxecx",
+	"edxebx", "edxesi", "edxedi", "ecxebx", "ecxesi", "ecxedi",
+	"ebxesi", "ebxedi", "esiedi",
+	"%st0", "%st1", "%st2", "%st3", "%st4", "%st5", "%st6", "%st7",
+};
+
+/*
+ * Return a class suitable for a specific type.
+ */
+int
+gclass(TWORD t)
+{
+	if (t == CHAR || t == UCHAR)
+		return CLASSB;
+	if (t == LONGLONG || t == ULONGLONG)
+		return CLASSC;
+	if (t == FLOAT || t == DOUBLE || t == LDOUBLE)
+		return CLASSD;
+	return CLASSA;
+}
+
+/*
+ * Calculate argument sizes.
+ */
+void
+lastcall(NODE *p)
+{
+	NODE *op = p;
+	int size = 0;
+
+	p->n_qual = 0;
+	if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
+		return;
+	for (p = p->n_right; p->n_op == CM; p = p->n_left)
+		size += argsiz(p->n_right);
+	size += argsiz(p);
+	op->n_qual = size; /* XXX */
+}
+
+/*
+ * Special shapes.
+ */
+int
+special(NODE *p, int shape)
+{
+	int o = p->n_op;
+
+	switch (shape) {
+	case SFUNCALL:
+		if (o == STCALL || o == USTCALL)
+			return SRREG;
+		break;
+	case SPCON:
+		if (o != ICON || p->n_name[0] ||
+		    p->n_lval < 0 || p->n_lval > 0x7fffffff)
+			break;
+		return SRDIR;
+	}
+	return SRNOPE;
+}
--- /dev/null
+++ usr.bin/pcc/i386/code.c
@@ -0,0 +1,213 @@
+/*	$Id: code.c,v 1.15 2007/07/06 17:02:27 ragge Exp $	*/
+/*
+ * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+# include "pass1.h"
+
+/*
+ * cause the alignment to become a multiple of n
+ * never called for text segment.
+ */
+void
+defalign(int n)
+{
+	n /= SZCHAR;
+	if (n == 1)
+		return;
+	printf("	.align %d\n", n);
+}
+
+/*
+ * define the current location as the name p->sname
+ * never called for text segment.
+ */
+void
+defnam(struct symtab *p)
+{
+	char *c = p->sname;
+
+#ifdef GCC_COMPAT
+	c = gcc_findname(p);
+#endif
+	if (p->sclass == EXTDEF)
+		printf("	.globl %s\n", c);
+	printf("%s:\n", c);
+}
+
+
+/*
+ * code for the end of a function
+ * deals with struct return here
+ */
+void
+efcode()
+{
+	NODE *p, *q;
+	int sz;
+
+	if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
+		return;
+	/* address of return struct is in eax */
+	/* create a call to memcpy() */
+	/* will get the result in eax */
+	p = block(REG, NIL, NIL, CHAR+PTR, 0, MKSUE(CHAR+PTR));
+	p->n_rval = EAX;
+	q = block(OREG, NIL, NIL, CHAR+PTR, 0, MKSUE(CHAR+PTR));
+	q->n_rval = EBP;
+	q->n_lval = 8; /* return buffer offset */
+	p = block(CM, q, p, INT, 0, MKSUE(INT));
+	sz = (tsize(STRTY, cftnsp->sdf, cftnsp->ssue)+SZCHAR-1)/SZCHAR;
+	p = block(CM, p, bcon(sz), INT, 0, MKSUE(INT));
+	p->n_right->n_name = "";
+	p = block(CALL, bcon(0), p, CHAR+PTR, 0, MKSUE(CHAR+PTR));
+	p->n_left->n_name = "memcpy";
+	p = clocal(p);
+	send_passt(IP_NODE, p);
+}
+
+/*
+ * code for the beginning of a function; a is an array of
+ * indices in symtab for the arguments; n is the number
+ */
+void
+bfcode(struct symtab **a, int n)
+{
+	int i;
+
+	if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
+		return;
+	/* Function returns struct, adjust arg offset */
+	for (i = 0; i < n; i++)
+		a[i]->soffset += SZPOINT(INT);
+}
+
+
+/*
+ * by now, the automatics and register variables are allocated
+ */
+void
+bccode()
+{
+	SETOFF(autooff, SZINT);
+}
+
+/* called just before final exit */
+/* flag is 1 if errors, 0 if none */
+void
+ejobcode(int flag )
+{
+}
+
+void
+bjobcode()
+{
+}
+
+/*
+ * Print character t at position i in one string, until t == -1.
+ * Locctr & label is already defined.
+ */
+void
+bycode(int t, int i)
+{
+	static	int	lastoctal = 0;
+
+	/* put byte i+1 in a string */
+
+	if (t < 0) {
+		if (i != 0)
+			puts("\"");
+	} else {
+		if (i == 0)
+			printf("\t.ascii \"");
+		if (t == '\\' || t == '"') {
+			lastoctal = 0;
+			putchar('\\');
+			putchar(t);
+		} else if (t < 040 || t >= 0177) {
+			lastoctal++;
+			printf("\\%o",t);
+		} else if (lastoctal && '0' <= t && t <= '9') {
+			lastoctal = 0;
+			printf("\"\n\t.ascii \"%c", t);
+		} else {	
+			lastoctal = 0;
+			putchar(t);
+		}
+	}
+}
+
+/*
+ * n integer words of zeros
+ */
+void
+zecode(int n)
+{
+	printf("	.zero %d\n", n * (SZINT/SZCHAR));
+//	inoff += n * SZINT;
+}
+
+/*
+ * return the alignment of field of type t
+ */
+int
+fldal(unsigned int t)
+{
+	uerror("illegal field type");
+	return(ALINT);
+}
+
+/* fix up type of field p */
+void
+fldty(struct symtab *p)
+{
+}
+
+/* p points to an array of structures, each consisting
+ * of a constant value and a label.
+ * The first is >=0 if there is a default label;
+ * its value is the label number
+ * The entries p[1] to p[n] are the nontrivial cases
+ * XXX - fix genswitch.
+ */
+void
+genswitch(int num, struct swents **p, int n)
+{
+	NODE *r;
+	int i;
+
+	/* simple switch code */
+	for (i = 1; i <= n; ++i) {
+		/* already in 1 */
+		r = tempnode(num, INT, 0, MKSUE(INT));
+		r = buildtree(NE, r, bcon(p[i]->sval));
+		cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab));
+	}
+	if (p[0]->slab > 0)
+		branch(p[0]->slab);
+}
--- /dev/null
+++ usr.bin/pcc/i386/local.c
@@ -0,0 +1,743 @@
+/*	$Id: local.c,v 1.56 2007/09/24 16:23:36 ragge Exp $	*/
+/*
+ * Copyright (c) 2003 Anders Magnusson (ragge at ludd.luth.se).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "pass1.h"
+
+/*	this file contains code which is dependent on the target machine */
+
+/* clocal() is called to do local transformations on
+ * an expression tree preparitory to its being
+ * written out in intermediate code.
+ *
+ * the major essential job is rewriting the
+ * automatic variables and arguments in terms of
+ * REG and OREG nodes
+ * conversion ops which are not necessary are also clobbered here
+ * in addition, any special features (such as rewriting
+ * exclusive or) are easily handled here as well
+ */
+NODE *
+clocal(NODE *p)
+{
+
+	register struct symtab *q;
+	register NODE *r, *l;
+	register int o;
+	register int m;
+	TWORD t;
+
+#ifdef PCC_DEBUG
+	if (xdebug) {
+		printf("clocal: %p\n", p);
+		fwalk(p, eprint, 0);
+	}
+#endif
+	switch( o = p->n_op ){
+
+	case NAME:
+		if ((q = p->n_sp) == NULL)
+			return p; /* Nothing to care about */
+
+		switch (q->sclass) {
+
+		case PARAM:
+		case AUTO:
+			/* fake up a structure reference */
+			r = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
+			r->n_lval = 0;
+			r->n_rval = FPREG;
+			p = stref(block(STREF, r, p, 0, 0, 0));
+			break;
+
+		case STATIC:
+			if (q->slevel == 0)
+				break;
+			p->n_lval = 0;
+			p->n_sp = q;
+			break;
+
+		case REGISTER:
+			p->n_op = REG;
+			p->n_lval = 0;
+			p->n_rval = q->soffset;
+			break;
+
+			}
+		break;
+
+	case STCALL:
+	case CALL:
+		/* Fix function call arguments. On x86, just add funarg */
+		for (r = p->n_right; r->n_op == CM; r = r->n_left) {
+			if (r->n_right->n_op != STARG &&
+			    r->n_right->n_op != FUNARG)
+				r->n_right = block(FUNARG, r->n_right, NIL, 
+				    r->n_right->n_type, r->n_right->n_df,
+				    r->n_right->n_sue);
+		}
+		if (r->n_op != STARG && r->n_op != FUNARG) {
+			l = talloc();
+			*l = *r;
+			r->n_op = FUNARG; r->n_left = l; r->n_type = l->n_type;
+		}
+		break;
+		
+	case CBRANCH:
+		l = p->n_left;
+
+		/*
+		 * Remove unneccessary conversion ops.
+		 */
+		if (clogop(l->n_op) && l->n_left->n_op == SCONV) {
+			if (coptype(l->n_op) != BITYPE)
+				break;
+			if (l->n_right->n_op == ICON) {
+				r = l->n_left->n_left;
+				if (r->n_type >= FLOAT && r->n_type <= LDOUBLE)
+					break;
+				/* Type must be correct */
+				t = r->n_type;
+				nfree(l->n_left);
+				l->n_left = r;
+				l->n_type = t;
+				l->n_right->n_type = t;
+			}
+		}
+		break;
+
+	case PCONV:
+		/* Remove redundant PCONV's. Be careful */
+		l = p->n_left;
+		if (l->n_op == ICON) {
+			l->n_lval = (unsigned)l->n_lval;
+			goto delp;
+		}
+		if (l->n_type < INT || l->n_type == LONGLONG || 
+		    l->n_type == ULONGLONG) {
+			/* float etc? */
+			p->n_left = block(SCONV, l, NIL,
+			    UNSIGNED, 0, MKSUE(UNSIGNED));
+			break;
+		}
+		/* if left is SCONV, cannot remove */
+		if (l->n_op == SCONV)
+			break;
+
+		/* avoid ADDROF TEMP */
+		if (l->n_op == ADDROF && l->n_left->n_op == TEMP)
+			break;
+
+		/* if conversion to another pointer type, just remove */
+		if (p->n_type > BTMASK && l->n_type > BTMASK)
+			goto delp;
+		break;
+
+	delp:	l->n_type = p->n_type;
+		l->n_qual = p->n_qual;
+		l->n_df = p->n_df;
+		l->n_sue = p->n_sue;
+		nfree(p);
+		p = l;
+		break;
+		
+	case SCONV:
+		l = p->n_left;
+
+		if (p->n_type == l->n_type) {
+			nfree(p);
+			return l;
+		}
+
+		if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
+		    btdims[p->n_type].suesize == btdims[l->n_type].suesize) {
+			if (p->n_type != FLOAT && p->n_type != DOUBLE &&
+			    l->n_type != FLOAT && l->n_type != DOUBLE &&
+			    l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
+				if (l->n_op == NAME || l->n_op == UMUL ||
+				    l->n_op == TEMP) {
+					l->n_type = p->n_type;
+					nfree(p);
+					return l;
+				}
+			}
+		}
+
+		if (DEUNSIGN(p->n_type) == INT && DEUNSIGN(l->n_type) == INT &&
+		    coptype(l->n_op) == BITYPE) {
+			l->n_type = p->n_type;
+			nfree(p);
+			return l;
+		}
+
+		o = l->n_op;
+		m = p->n_type;
+
+		if (o == ICON) {
+			CONSZ val = l->n_lval;
+
+			if (!ISPTR(m)) /* Pointers don't need to be conv'd */
+			    switch (m) {
+			case BOOL:
+				l->n_lval = l->n_lval != 0;
+				break;
+			case CHAR:
+				l->n_lval = (char)val;
+				break;
+			case UCHAR:
+				l->n_lval = val & 0377;
+				break;
+			case SHORT:
+				l->n_lval = (short)val;
+				break;
+			case USHORT:
+				l->n_lval = val & 0177777;
+				break;
+			case ULONG:
+			case UNSIGNED:
+				l->n_lval = val & 0xffffffff;
+				break;
+			case ENUMTY:
+			case MOETY:
+			case LONG:
+			case INT:
+				l->n_lval = (int)val;
+				break;
+			case LONGLONG:
+				l->n_lval = (long long)val;
+				break;
+			case ULONGLONG:
+				l->n_lval = val;
+				break;
+			case VOID:
+				break;
+			case LDOUBLE:
+			case DOUBLE:
+			case FLOAT:
+				l->n_op = FCON;
+				l->n_dcon = val;
+				break;
+			default:
+				cerror("unknown type %d", m);
+			}
+			l->n_type = m;
+			l->n_sue = MKSUE(m);
+			nfree(p);
+			return l;
+		}
+		if (DEUNSIGN(p->n_type) == SHORT &&
+		    DEUNSIGN(l->n_type) == SHORT) {
+			nfree(p);
+			p = l;
+		}
+		if ((p->n_type == CHAR || p->n_type == UCHAR ||
+		    p->n_type == SHORT || p->n_type == USHORT) &&
+		    (l->n_type == FLOAT || l->n_type == DOUBLE ||
+		    l->n_type == LDOUBLE)) {
+			p = block(SCONV, p, NIL, p->n_type, p->n_df, p->n_sue);
+			p->n_left->n_type = INT;
+			return p;
+		}
+		break;
+
+	case MOD:
+	case DIV:
+		if (o == DIV && p->n_type != CHAR && p->n_type != SHORT)
+			break;
+		if (o == MOD && p->n_type != CHAR && p->n_type != SHORT)
+			break;
+		/* make it an int division by inserting conversions */
+		p->n_left = block(SCONV, p->n_left, NIL, INT, 0, MKSUE(INT));
+		p->n_right = block(SCONV, p->n_right, NIL, INT, 0, MKSUE(INT));
+		p = block(SCONV, p, NIL, p->n_type, 0, MKSUE(p->n_type));
+		p->n_left->n_type = INT;
+		break;
+
+	case PMCONV:
+	case PVCONV:
+                if( p->n_right->n_op != ICON ) cerror( "bad conversion", 0);
+                nfree(p);
+                return(buildtree(o==PMCONV?MUL:DIV, p->n_left, p->n_right));
+
+	case FORCE:
+		/* put return value in return reg */
+		p->n_op = ASSIGN;
+		p->n_right = p->n_left;
+		p->n_left = block(REG, NIL, NIL, p->n_type, 0, MKSUE(INT));
+		p->n_left->n_rval = p->n_left->n_type == BOOL ? 
+		    RETREG(CHAR) : RETREG(p->n_type);
+		break;
+
+	case LS:
+	case RS:
+		/* shift count must be in a char
+		 * unless longlong, where it must be int */
+		if (p->n_right->n_op == ICON)
+			break; /* do not do anything */
+		if (p->n_type == LONGLONG || p->n_type == ULONGLONG) {
+			if (p->n_right->n_type != INT)
+				p->n_right = block(SCONV, p->n_right, NIL,
+				    INT, 0, MKSUE(INT));
+			break;
+		}
+		if (p->n_right->n_type == CHAR || p->n_right->n_type == UCHAR)
+			break;
+		p->n_right = block(SCONV, p->n_right, NIL,
+		    CHAR, 0, MKSUE(CHAR));
+		break;
+	}
+#ifdef PCC_DEBUG
+	if (xdebug) {
+		printf("clocal end: %p\n", p);
+		fwalk(p, eprint, 0);
+	}
+#endif
+	return(p);
+}
+
+void
+myp2tree(NODE *p)
+{
+}
+
+/*ARGSUSED*/
+int
+andable(NODE *p)
+{
+	return(1);  /* all names can have & taken on them */
+}
+
+/*
+ * at the end of the arguments of a ftn, set the automatic offset
+ */
+void
+cendarg()
+{
+	autooff = AUTOINIT;
+}
+
+/*
+ * Return 1 if a variable of type type is OK to put in register.
+ */
+int
+cisreg(TWORD t)
+{
+	if (t == FLOAT || t == DOUBLE || t == LDOUBLE)
+		return 0; /* not yet */
+	return 1;
+}
+
+/*
+ * return a node, for structure references, which is suitable for
+ * being added to a pointer of type t, in order to be off bits offset
+ * into a structure
+ * t, d, and s are the type, dimension offset, and sizeoffset
+ * For pdp10, return the type-specific index number which calculation
+ * is based on its size. For example, short a[3] would return 3.
+ * Be careful about only handling first-level pointers, the following
+ * indirections must be fullword.
+ */
+NODE *
+offcon(OFFSZ off, TWORD t, union dimfun *d, struct suedef *sue)
+{
+	register NODE *p;
+
+	if (xdebug)
+		printf("offcon: OFFSZ %lld type %x dim %p siz %d\n",
+		    off, t, d, sue->suesize);
+
+	p = bcon(0);
+	p->n_lval = off/SZCHAR;	/* Default */
+	return(p);
+}
+
+/*
+ * Allocate off bits on the stack.  p is a tree that when evaluated
+ * is the multiply count for off, t is a storeable node where to write
+ * the allocated address.
+ */
+void
+spalloc(NODE *t, NODE *p, OFFSZ off)
+{
+	NODE *sp;
+
+	p = buildtree(MUL, p, bcon(off/SZCHAR)); /* XXX word alignment? */
+
+	/* sub the size from sp */
+	sp = block(REG, NIL, NIL, p->n_type, 0, MKSUE(INT));
+	sp->n_lval = 0;
+	sp->n_rval = STKREG;
+	ecomp(buildtree(MINUSEQ, sp, p));
+
+	/* save the address of sp */
+	sp = block(REG, NIL, NIL, PTR+INT, t->n_df, t->n_sue);
+	sp->n_lval = 0;
+	sp->n_rval = STKREG;
+	t->n_type = sp->n_type;
+	ecomp(buildtree(ASSIGN, t, sp)); /* Emit! */
+
+}
+
+#if 0
+/*
+ * Print out an integer constant of size size.
+ * can only be sizes <= SZINT.
+ */
+void
+indata(CONSZ val, int size)
+{
+	switch (size) {
+	case SZCHAR:
+		printf("\t.byte %d\n", (int)val & 0xff);
+		break;
+	case SZSHORT:
+		printf("\t.word %d\n", (int)val & 0xffff);
+		break;
+	case SZINT:
+		printf("\t.long %d\n", (int)val & 0xffffffff);
+		break;
+	default:
+		cerror("indata");
+	}
+}
+#endif
+
+/*
+ * Print out a string of characters.
+ * Assume that the assembler understands C-style escape
+ * sequences.  Location is already set.
+ */
+void
+instring(char *str)
+{
+	char *s;
+
+	/* be kind to assemblers and avoid long strings */
+	printf("\t.ascii \"");
+	for (s = str; *s != 0; ) {
+		if (*s++ == '\\') {
+			(void)esccon(&s);
+		}
+		if (s - str > 64) {
+			fwrite(str, 1, s - str, stdout);
+			printf("\"\n\t.ascii \"");
+			str = s;
+		}
+	}
+	fwrite(str, 1, s - str, stdout);
+	printf("\\0\"\n");
+}
+
+static int inbits, inval;
+
+/*
+ * set fsz bits in sequence to zero.
+ */
+void
+zbits(OFFSZ off, int fsz)
+{
+	int m;
+
+	if (idebug)
+		printf("zbits off %lld, fsz %d inbits %d\n", off, fsz, inbits);
+	if ((m = (inbits % SZCHAR))) {
+		m = SZCHAR - m;
+		if (fsz < m) {
+			inbits += fsz;
+			return;
+		} else {
+			fsz -= m;
+			printf("\t.byte %d\n", inval);
+			inval = inbits = 0;
+		}
+	}
+	if (fsz >= SZCHAR) {
+		printf("\t.zero %d\n", fsz/SZCHAR);
+		fsz -= (fsz/SZCHAR) * SZCHAR;
+	}
+	if (fsz) {
+		inval = 0;
+		inbits = fsz;
+	}
+}
+
+/*
+ * Initialize a bitfield.
+ */
+void
+infld(CONSZ off, int fsz, CONSZ val)
+{
+	if (idebug)
+		printf("infld off %lld, fsz %d, val %lld inbits %d\n",
+		    off, fsz, val, inbits);
+	val &= ((CONSZ)1 << fsz)-1;
+	while (fsz + inbits >= SZCHAR) {
+		inval |= (val << inbits);
+		printf("\t.byte %d\n", inval & 255);
+		fsz -= (SZCHAR - inbits);
+		val >>= (SZCHAR - inbits);
+		inval = inbits = 0;
+	}
+	if (fsz) {
+		inval |= (val << inbits);
+		inbits += fsz;
+	}
+}
+
+/*
+ * print out a constant node, may be associated with a label.
+ * Do not free the node after use.
+ * off is bit offset from the beginning of the aggregate
+ * fsz is the number of bits this is referring to
+ */
+void
+ninval(CONSZ off, int fsz, NODE *p)
+{
+	union { float f; double d; long double l; int i[3]; } u;
+	struct symtab *q;
+	TWORD t;
+	int i;
+
+	t = p->n_type;
+	if (t > BTMASK)
+		t = INT; /* pointer */
+
+	if (p->n_op != ICON && p->n_op != FCON)
+		cerror("ninval: init node not constant");
+
+	if (p->n_op == ICON && p->n_sp != NULL && DEUNSIGN(t) != INT)
+		uerror("element not constant");
+
+	switch (t) {
+	case LONGLONG:
+	case ULONGLONG:
+		i = (p->n_lval >> 32);
+		p->n_lval &= 0xffffffff;
+		p->n_type = INT;
+		ninval(off, 32, p);
+		p->n_lval = i;
+		ninval(off+32, 32, p);
+		break;
+	case INT:
+	case UNSIGNED:
+		printf("\t.long 0x%x", (int)p->n_lval);
+		if ((q = p->n_sp) != NULL) {
+			if ((q->sclass == STATIC && q->slevel > 0) ||
+			    q->sclass == ILABEL) {
+				printf("+" LABFMT, q->soffset);
+			} else
+				printf("+%s", exname(q->sname));
+		}
+		printf("\n");
+		break;
+	case SHORT:
+	case USHORT:
+		printf("\t.short 0x%x\n", (int)p->n_lval & 0xffff);
+		break;
+	case BOOL:
+		if (p->n_lval > 1)
+			p->n_lval = p->n_lval != 0;
+		/* FALLTHROUGH */
+	case CHAR:
+	case UCHAR:
+		printf("\t.byte %d\n", (int)p->n_lval & 0xff);
+		break;
+	case LDOUBLE:
+		u.i[2] = 0;
+		u.l = (long double)p->n_dcon;
+		printf("\t.long\t0x%x,0x%x,0x%x\n", u.i[0], u.i[1], u.i[2]);
+		break;
+	case DOUBLE:
+		u.d = (double)p->n_dcon;
+		printf("\t.long\t0x%x,0x%x\n", u.i[0], u.i[1]);
+		break;
+	case FLOAT:
+		u.f = (float)p->n_dcon;
+		printf("\t.long\t0x%x\n", u.i[0]);
+		break;
+	default:
+		cerror("ninval");
+	}
+}
+
+#if 0
+/*
+ * print out an integer.
+ */
+void
+inval(CONSZ word)
+{
+	word &= 0xffffffff;
+	printf("	.long 0x%llx\n", word);
+}
+
+/* output code to initialize a floating point value */
+/* the proper alignment has been obtained */
+void
+finval(NODE *p)
+{
+	union { float f; double d; long double l; int i[3]; } u;
+
+	switch (p->n_type) {
+	case LDOUBLE:
+		u.i[2] = 0;
+		u.l = (long double)p->n_dcon;
+		printf("\t.long\t0x%x,0x%x,0x%x\n", u.i[0], u.i[1], u.i[2]);
+		break;
+	case DOUBLE:
+		u.d = (double)p->n_dcon;
+		printf("\t.long\t0x%x,0x%x\n", u.i[0], u.i[1]);
+		break;
+	case FLOAT:
+		u.f = (float)p->n_dcon;
+		printf("\t.long\t0x%x\n", u.i[0]);
+		break;
+	}
+}
+#endif
+
+/* make a name look like an external name in the local machine */
+char *
+exname(char *p)
+{
+	if (p == NULL)
+		return "";
+	return p;
+}
+
+/*
+ * map types which are not defined on the local machine
+ */
+TWORD
+ctype(TWORD type)
+{
+	switch (BTYPE(type)) {
+	case LONG:
+		MODTYPE(type,INT);
+		break;
+
+	case ULONG:
+		MODTYPE(type,UNSIGNED);
+
+	}
+	return (type);
+}
+
+void
+calldec(NODE *p, NODE *q) 
+{
+}
+
+void
+extdec(struct symtab *q)
+{
+}
+
+/* make a common declaration for id, if reasonable */
+void
+commdec(struct symtab *q)
+{
+	int off;
+
+	off = tsize(q->stype, q->sdf, q->ssue);
+	off = (off+(SZCHAR-1))/SZCHAR;
+#ifdef GCC_COMPAT
+	printf("	.comm %s,0%o\n", gcc_findname(q), off);
+#else
+	printf("	.comm %s,0%o\n", exname(q->sname), off);
+#endif
+}
+
+/* make a local common declaration for id, if reasonable */
+void
+lcommdec(struct symtab *q)
+{
+	int off;
+
+	off = tsize(q->stype, q->sdf, q->ssue);
+	off = (off+(SZCHAR-1))/SZCHAR;
+	if (q->slevel == 0)
+#ifdef GCC_COMPAT
+		printf("	.lcomm %s,0%o\n", gcc_findname(q), off);
+#else
+		printf("	.lcomm %s,0%o\n", exname(q->sname), off);
+#endif
+	else
+		printf("	.lcomm " LABFMT ",0%o\n", q->soffset, off);
+}
+
+/*
+ * print a (non-prog) label.
+ */
+void
+deflab1(int label)
+{
+	printf(LABFMT ":\n", label);
+}
+
+static char *loctbl[] = { "text", "data", "section .rodata", "section .rodata" };
+
+void
+setloc1(int locc)
+{
+	if (locc == lastloc)
+		return;
+	lastloc = locc;
+	printf("	.%s\n", loctbl[locc]);
+}
+
+#if 0
+int
+ftoint(NODE *p, CONSZ **c)
+{
+	static CONSZ cc[3];
+	union { float f; double d; long double l; int i[3]; } u;
+	int n;
+
+	switch (p->n_type) {
+	case LDOUBLE:
+		u.i[2] = 0;
+		u.l = (long double)p->n_dcon;
+		n = SZLDOUBLE;
+		break;
+	case DOUBLE:
+		u.d = (double)p->n_dcon;
+		n = SZDOUBLE;
+		break;
+	case FLOAT:
+		u.f = (float)p->n_dcon;
+		n = SZFLOAT;
+		break;
+	}
+	cc[0] = u.i[0];
+	cc[1] = u.i[1];
+	cc[2] = u.i[2];
+	*c = cc;
+	return n;
+}
+#endif


More information about the Midnightbsd-cvs mailing list