diff options
author | gmcgarry <gmcgarry@pkgsrc.org> | 2001-07-21 02:51:35 +0000 |
---|---|---|
committer | gmcgarry <gmcgarry@pkgsrc.org> | 2001-07-21 02:51:35 +0000 |
commit | 973a0de16ae2afcbc02fd1e5e79180b82eb432f9 (patch) | |
tree | 597e5c56723b7b0eb1538252b462b7507586eb81 | |
parent | 68eec7a070836a422801d3bf8bc8079efe425c06 (diff) | |
download | pkgsrc-973a0de16ae2afcbc02fd1e5e79180b82eb432f9.tar.gz |
Import of lcc-4.1: retargetable ANSI C compiler
-rw-r--r-- | devel/lcc/Makefile | 43 | ||||
-rw-r--r-- | devel/lcc/distinfo | 7 | ||||
-rw-r--r-- | devel/lcc/files/cdefs.h | 64 | ||||
-rw-r--r-- | devel/lcc/files/netbsd.c | 112 | ||||
-rw-r--r-- | devel/lcc/files/x86bsd.md | 1313 | ||||
-rw-r--r-- | devel/lcc/patches/patch-aa | 46 | ||||
-rw-r--r-- | devel/lcc/patches/patch-ab | 21 | ||||
-rw-r--r-- | devel/lcc/patches/patch-ac | 46 | ||||
-rw-r--r-- | devel/lcc/pkg/COMMENT | 1 | ||||
-rw-r--r-- | devel/lcc/pkg/DESCR | 3 | ||||
-rw-r--r-- | devel/lcc/pkg/PLIST | 10 |
11 files changed, 1666 insertions, 0 deletions
diff --git a/devel/lcc/Makefile b/devel/lcc/Makefile new file mode 100644 index 00000000000..8af44873f83 --- /dev/null +++ b/devel/lcc/Makefile @@ -0,0 +1,43 @@ +# $NetBSD: Makefile,v 1.1.1.1 2001/07/21 02:51:35 gmcgarry Exp $ + +DISTNAME= lcc-4.1 +CATEGORIES= devel lang +MASTER_SITES= ftp://ftp.cs.princeton.edu/pub/lcc/ + +MAINTAINER= packages@netbsd.org +HOMEPAGE= http://www.research.microsoft.com/~cwfraser/ + +MAKE_ENV+= BUILDDIR=${WRKSRC}/bin HOSTFILE=etc/netbsd.c + +.include "../../mk/bsd.prefs.mk" + +BUILDDIR= ${WRKSRC}/src +MAKEFILE= makefile + +post-extract: + ${CP} ${FILESDIR}/x86bsd.md ${WRKSRC}/src/ + ${CP} ${FILESDIR}/netbsd.c ${WRKSRC}/etc/ + +pre-build: + ${MKDIR} ${WRKSRC}/bin + cd ${WRKSRC}/etc ; \ + [ -f netbsd.c.bak ] || ${MV} netbsd.c netbsd.c.bak ; \ + ${SED} \ + -e 's|@PREFIX@|${PREFIX}|g' < netbsd.c.bak > netbsd.c + +do-install: + ${INSTALL_PROGRAM} ${WRKSRC}/bin/bprint ${PREFIX}/libexec + ${INSTALL_PROGRAM} ${WRKSRC}/bin/cpp ${PREFIX}/libexec + ${INSTALL_PROGRAM} ${WRKSRC}/bin/lburg ${PREFIX}/libexec + ${INSTALL_PROGRAM} ${WRKSRC}/bin/lcc ${PREFIX}/bin + ${INSTALL_PROGRAM} ${WRKSRC}/bin/rcc ${PREFIX}/libexec + ${INSTALL_DATA_DIR} ${PREFIX}/share/lcc/include + ${INSTALL_DATA_DIR} ${PREFIX}/share/lcc/include/sys + ${INSTALL_DATA} ${WRKSRC}/include/x86/linux/stdarg.h \ + ${PREFIX}/share/lcc/include + ${INSTALL_DATA} ${FILESDIR}/cdefs.h \ + ${PREFIX}/share/lcc/include/sys + ${INSTALL_MAN} ${WRKSRC}/doc/lcc.1 ${PREFIX}/man/man1 + ${INSTALL_MAN} ${WRKSRC}/doc/bprint.1 ${PREFIX}/man/man1 + +.include "../../mk/bsd.pkg.mk" diff --git a/devel/lcc/distinfo b/devel/lcc/distinfo new file mode 100644 index 00000000000..a21aaeab67f --- /dev/null +++ b/devel/lcc/distinfo @@ -0,0 +1,7 @@ +$NetBSD: distinfo,v 1.1.1.1 2001/07/21 02:51:35 gmcgarry Exp $ + +SHA1 (lcc-4.1.tar.gz) = aa5a0dd3c5317a8aa176e50d4c8c8799ae61fe8c +Size (lcc-4.1.tar.gz) = 664562 bytes +SHA1 (patch-aa) = d8ccdc999f0afe95154037762890bcce129943b7 +SHA1 (patch-ab) = 516d8aa8e48e080b673f1e1a4b6c847ae1906dd4 +SHA1 (patch-ac) = ce17a2edf165276869e1ecedd243f331d7420cbb diff --git a/devel/lcc/files/cdefs.h b/devel/lcc/files/cdefs.h new file mode 100644 index 00000000000..682ad6e06f8 --- /dev/null +++ b/devel/lcc/files/cdefs.h @@ -0,0 +1,64 @@ +/* $NetBSD: cdefs.h,v 1.1.1.1 2001/07/21 02:51:35 gmcgarry Exp $ */ + +/* + * cdefs.h compatibility file to compile NetBSD with lcc 4.1 + */ + +#ifndef _SYS_CDEFS_H_ +#define _SYS_CDEFS_H_ + +#define __asm__(x) +#define __attribute__(x) + +/* + * The rest of this is based on: + * + * NetBSD: cdefs.h,v 1.36 2000/05/27 12:22:24 kleink Exp + */ + +#include <machine/cdefs.h> +#ifdef __ELF__ +#include <sys/cdefs_elf.h> +#else +#include <sys/cdefs_aout.h> +#endif + +#define __BEGIN_DECLS +#define __END_DECLS + +#define ___STRING(x) __STRING(x) +#define ___CONCAT(x,y) __CONCAT(x,y) + +#define __P(protos) protos /* full-blown ANSI C */ +#define __CONCAT(x,y) x ## y +#define __STRING(x) #x + +#define __const const /* define reserved names to standard */ +#define __signed signed +#define __volatile volatile + +#define __inline /* delete GCC keyword */ + +#define __kprintf_attribute__(a) +#define __extension__ /* delete __extension__ if non-gcc or gcc1 */ + +#define __dead +#define __pure + +#define __RENAME(x) +#define __GNUC_PREREQ__(x, y) 0 + +#ifdef __AUDIT__ +#define __aconst __const +#else +#define __aconst +#endif + +#if defined(_KERNEL) +#if defined(NO_KERNEL_RCSIDS) +#undef __KERNEL_RCSID +#define __KERNEL_RCSID(_n, _s) /* nothing */ +#endif /* NO_KERNEL_RCSIDS */ +#endif /* _KERNEL */ + +#endif diff --git a/devel/lcc/files/netbsd.c b/devel/lcc/files/netbsd.c new file mode 100644 index 00000000000..0f0599f1358 --- /dev/null +++ b/devel/lcc/files/netbsd.c @@ -0,0 +1,112 @@ +/* + * $NetBSD: netbsd.c,v 1.1.1.1 2001/07/21 02:51:35 gmcgarry Exp $ + * + * i386 netbsd (GNU as, GNU ld) + */ + +#include <string.h> + +#define LCC_LIBPATH "@PREFIX@/libexec/" +#define LCC_INCPATH "@PREFIX@/share/lcc/include" + +char *suffixes[] = { ".c", ".i", ".s", ".o", ".out", 0 }; + +char inputs[256] = ""; + +char *cpp[] = { + LCC_LIBPATH "cpp", + "-D__STDC__=1", +#ifdef __ELF__ + "-D__ELF__", +#else + "", +#endif + "-Di386", + "-D__NetBSD__", + "-D__KPRINTF_ATTRIBUTE__", + "-D__STRICT_ANSI__", + "", /* _POSIX_SOURCE */ + "$1", + "$2", + "$3", + 0 +}; +char *include[] = { + "-I" LCC_INCPATH, + "-I/usr/include", + 0 +}; +char *com[] = { + LCC_LIBPATH "rcc", +#ifdef __ELF__ + "-target=x86/netbsdelf", +#else + "-target=x86/netbsd", +#endif + "$1", + "$2", + "$3", + 0 +}; +char *as[] = { + "/usr/bin/as", + "-o", + "$3", + "$1", + "$2", + 0 +}; +char *ld[] = { + "/usr/bin/ld", + "-m", +#ifdef __ELF__ + "elf_i386", +#else + "i386nbsd", +#endif + "-dynamic-linker", +#ifdef __ELF__ + "/usr/libexec/ld.elf_so", +#else + "/usr/libexec/ld.aout_so", +#endif + "-o", + "$3", + "$1", + "/usr/lib/crt0.o", + "/usr/lib/crtbegin.o", + "$2", + "", /* -b */ + "-lc", + "/usr/lib/crtend.o", + 0 +}; +static char *bbexit = LCC_LIBPATH "bbexit.o"; + +extern char *concat(char *, char *); +extern int access(const char *, int); + +int option(char *arg) { + if (strncmp(arg, "-lccdir=", 8) == 0) { + cpp[0] = concat(&arg[8], "/cpp"); + include[0] = concat("-I", concat(&arg[8], "/include")); + com[0] = concat(&arg[8], "/rcc"); + bbexit = concat(&arg[8], "/bbexit.o"); + } else if (strncmp(arg, "-posix",6) == 0) { + cpp[7] = "-D_POSIX_SOURCE"; + } else if (strcmp(arg, "-g") == 0) + ; + else if (strcmp(arg, "-b") == 0 && access(bbexit, 4) == 0) + ld[11] = bbexit; + else if (strcmp(arg, "-p") == 0) { + ld[8] = "/usr/lib/gcrt0.o"; + ld[14] = "-lc_p"; + } + else if (strcmp(arg, "-static") == 0) { + ld[3] = "-static"; + ld[4] = ""; + } + else + return 0; + return 1; +} diff --git a/devel/lcc/files/x86bsd.md b/devel/lcc/files/x86bsd.md new file mode 100644 index 00000000000..e8614cf2ed2 --- /dev/null +++ b/devel/lcc/files/x86bsd.md @@ -0,0 +1,1313 @@ +%{ +enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 }; +#include "c.h" +#define NODEPTR_TYPE Node +#define OP_LABEL(p) ((p)->op) +#define LEFT_CHILD(p) ((p)->kids[0]) +#define RIGHT_CHILD(p) ((p)->kids[1]) +#define STATE_LABEL(p) ((p)->x.state) +static void address(Symbol, Symbol, long); +static void blkfetch(int, int, int, int); +static void blkloop(int, int, int, int, int, int[]); +static void blkstore(int, int, int, int); +static void defaddress(Symbol); +static void defconst(int, int, Value); +static void defstring(int, char *); +static void defsymbol(Symbol); +static void defsymbolelf(Symbol); +static void doarg(Node); +static void emit2(Node); +static void export(Symbol); +static void clobber(Node); +static void function(Symbol, Symbol [], Symbol [], int); +static void global(Symbol); +static void import(Symbol); +static void local(Symbol); +static void progbeg(int, char **); +static void progend(void); +static void segment(int); +static void space(int); +static void target(Node); +static int ckstack(Node, int); +static int memop(Node); +static int hasargs (Node); +static int sametree(Node, Node); +static void globalend(void); +static Symbol charreg[32], shortreg[32], intreg[32]; +static Symbol charregw, shortregw, intregw, fltregw; +static Symbol fltreg[32]; +static Symbol quo, rem; +static int cseg, profile = 0; + +%} +%start stmt + +%term CNSTF4=4113 CNSTF8=8209 CNSTF16=16401 +%term CNSTI1=1045 CNSTI2=2069 CNSTI4=4117 +%term CNSTP4=4119 +%term CNSTU1=1046 CNSTU2=2070 CNSTU4=4118 + +%term ARGB=41 +%term ARGF4=4129 ARGF8=8225 ARGF16=16417 +%term ARGI4=4133 +%term ARGP4=4135 +%term ARGU4=4134 + +%term ASGNB=57 +%term ASGNF4=4145 ASGNF8=8241 ASGNF16=16433 +%term ASGNI1=1077 ASGNI2=2101 ASGNI4=4149 +%term ASGNP4=4151 +%term ASGNU1=1078 ASGNU2=2102 ASGNU4=4150 + +%term INDIRB=73 +%term INDIRF4=4161 INDIRF8=8257 INDIRF16=16449 +%term INDIRI1=1093 INDIRI2=2117 INDIRI4=4165 +%term INDIRP4=4167 +%term INDIRU1=1094 INDIRU2=2118 INDIRU4=4166 + +%term CVFF4=4209 CVFF8=8305 CVFF16=16497 +%term CVFI4=4213 + +%term CVIF4=4225 CVIF8=8321 CVIF16=16513 +%term CVII1=1157 CVII2=2181 CVII4=4229 +%term CVIU1=1158 CVIU2=2182 CVIU4=4230 + +%term CVPU4=4246 + +%term CVUI1=1205 CVUI2=2229 CVUI4=4277 +%term CVUP4=4279 +%term CVUU1=1206 CVUU2=2230 CVUU4=4278 + +%term NEGF4=4289 NEGF8=8385 NEGF16=16577 +%term NEGI4=4293 + +%term CALLB=217 +%term CALLF4=4305 CALLF8=8401 CALLF16=16593 +%term CALLI4=4309 +%term CALLP4=4311 +%term CALLU4=4310 +%term CALLV=216 + +%term RETF4=4337 RETF8=8433 RETF16=16625 +%term RETI4=4341 +%term RETP4=4343 +%term RETU4=4342 +%term RETV=248 + +%term ADDRGP4=4359 + +%term ADDRFP4=4375 + +%term ADDRLP4=4391 + +%term ADDF4=4401 ADDF8=8497 ADDF16=16689 +%term ADDI4=4405 +%term ADDP4=4407 +%term ADDU4=4406 + +%term SUBF4=4417 SUBF8=8513 SUBF16=16705 +%term SUBI4=4421 +%term SUBP4=4423 +%term SUBU4=4422 + +%term LSHI4=4437 +%term LSHU4=4438 + +%term MODI4=4453 +%term MODU4=4454 + +%term RSHI4=4469 +%term RSHU4=4470 + +%term BANDI4=4485 +%term BANDU4=4486 + +%term BCOMI4=4501 +%term BCOMU4=4502 + +%term BORI4=4517 +%term BORU4=4518 + +%term BXORI4=4533 +%term BXORU4=4534 + +%term DIVF4=4545 DIVF8=8641 DIVF16=16833 +%term DIVI4=4549 +%term DIVU4=4550 + +%term MULF4=4561 MULF8=8657 MULF16=16849 +%term MULI4=4565 +%term MULU4=4566 + +%term EQF4=4577 EQF8=8673 EQF16=16865 +%term EQI4=4581 +%term EQU4=4582 + +%term GEF4=4593 GEF8=8689 GEF16=16881 +%term GEI4=4597 +%term GEU4=4598 + +%term GTF4=4609 GTF8=8705 GTF16=16897 +%term GTI4=4613 +%term GTU4=4614 + +%term LEF4=4625 LEF8=8721 LEF16=16913 +%term LEI4=4629 +%term LEU4=4630 + +%term LTF4=4641 LTF8=8737 LTF16=16929 +%term LTI4=4645 +%term LTU4=4646 + +%term NEF4=4657 NEF8=8753 NEF16=16945 +%term NEI4=4661 +%term NEU4=4662 + +%term JUMPV=584 + +%term LABELV=600 + +%term LOADB=233 +%term LOADF4=4321 LOADF8=8417 LOADF16=16609 +%term LOADI1=1253 LOADI2=2277 LOADI4=4325 +%term LOADP4=4327 +%term LOADU1=1254 LOADU2=2278 LOADU4=4326 + +%term VREGP=711 +%% +reg: INDIRI1(VREGP) "# read register\n" +reg: INDIRU1(VREGP) "# read register\n" + +reg: INDIRI2(VREGP) "# read register\n" +reg: INDIRU2(VREGP) "# read register\n" + +reg: INDIRI4(VREGP) "# read register\n" +reg: INDIRP4(VREGP) "# read register\n" +reg: INDIRU4(VREGP) "# read register\n" + +freg: INDIRF4(VREGP) "# read register\n" +freg: INDIRF8(VREGP) "# read register\n" + +stmt: ASGNI1(VREGP,reg) "# write register\n" +stmt: ASGNU1(VREGP,reg) "# write register\n" + +stmt: ASGNI2(VREGP,reg) "# write register\n" +stmt: ASGNU2(VREGP,reg) "# write register\n" + +stmt: ASGNF4(VREGP,reg) "# write register\n" +stmt: ASGNI4(VREGP,reg) "# write register\n" +stmt: ASGNP4(VREGP,reg) "# write register\n" +stmt: ASGNU4(VREGP,reg) "# write register\n" + +stmt: ASGNF8(VREGP,reg) "# write register\n" + +cnst: CNSTI1 "%a" +cnst: CNSTU1 "%a" + +cnst: CNSTI2 "%a" +cnst: CNSTU2 "%a" + +cnst: CNSTI4 "%a" +cnst: CNSTU4 "%a" +cnst: CNSTP4 "%a" + +con: cnst "$%0" + +stmt: reg "" +stmt: freg "" + +acon: ADDRGP4 "%a" +acon: cnst "%0" + +baseaddr: ADDRGP4 "%a" +base: reg "(%0)" +base: ADDI4(reg,acon) "%1(%0)" +base: ADDP4(reg,acon) "%1(%0)" +base: ADDU4(reg,acon) "%1(%0)" +base: ADDRFP4 "%a(%%ebp)" +base: ADDRLP4 "%a(%%ebp)" + +index: reg "%0" +index: LSHI4(reg,con1) "%0,2" +index: LSHI4(reg,con2) "%0,4" +index: LSHI4(reg,con3) "%0,8" +index: LSHU4(reg,con1) "%0,2" +index: LSHU4(reg,con2) "%0,4" +index: LSHU4(reg,con3) "%0,8" + +con0: CNSTI4 "1" range(a, 0, 0) +con0: CNSTU4 "1" range(a, 0, 0) +con1: CNSTI4 "1" range(a, 1, 1) +con1: CNSTU4 "1" range(a, 1, 1) +con2: CNSTI4 "2" range(a, 2, 2) +con2: CNSTU4 "2" range(a, 2, 2) +con3: CNSTI4 "3" range(a, 3, 3) +con3: CNSTU4 "3" range(a, 3, 3) + +addr: base "%0" +addr: baseaddr "%0" +addr: ADDI4(index,baseaddr) "%1(,%0)" +addr: ADDP4(index,baseaddr) "%1(,%0)" +addr: ADDU4(index,baseaddr) "%1(,%0)" + +addr: ADDI4(reg,baseaddr) "%1(%0)" +addr: ADDP4(reg,baseaddr) "%1(%0)" +addr: ADDU4(reg,baseaddr) "%1(%0)" + +addr: ADDI4(index,reg) "(%1,%0)" +addr: ADDP4(index,reg) "(%1,%0)" +addr: ADDU4(index,reg) "(%1,%0)" + +addr: index "(,%0)" + +mem1: INDIRI1(addr) "%0" +mem1: INDIRU1(addr) "%0" +mem2: INDIRI2(addr) "%0" +mem2: INDIRU2(addr) "%0" +mem4: INDIRI4(addr) "%0" +mem4: INDIRU4(addr) "%0" +mem4: INDIRP4(addr) "%0" + +rc: reg "%0" +rc: con "%0" + +mr: reg "%0" +mr: mem4 "%0" + +mr1: reg "%0" +mr1: mem1 "%0" + +mr2: reg "%0" +mr2: mem2 "%0" + +mrc: mem4 "%0" 1 +mrc: mem1 "%0" 1 +mrc: mem2 "%0" 1 +mrc: rc "%0" + +reg: addr "\tleal %0,%c\n" 1 +reg: mr "\tmovl %0,%c\n" 1 +reg: mr1 "\tmovb %0,%c\n" 1 +reg: mr2 "\tmovw %0,%c\n" 1 +reg: con "\tmovl %0,%c\n" 1 + +reg: LOADI1(reg) "# move\n" 1 +reg: LOADI2(reg) "# move\n" 1 +reg: LOADI4(reg) "# move\n" move(a) +reg: LOADU1(reg) "# move\n" 1 +reg: LOADU2(reg) "# move\n" 1 +reg: LOADU4(reg) "# move\n" move(a) +reg: LOADP4(reg) "# move\n" move(a) +reg: ADDI4(reg,mrc) "?\tmovl %0,%c\n\taddl %1,%c\n" 1 +reg: ADDP4(reg,mrc) "?\tmovl %0,%c\n\taddl %1,%c\n" 1 +reg: ADDU4(reg,mrc) "?\tmovl %0,%c\n\taddl %1,%c\n" 1 +reg: SUBI4(reg,mrc) "?\tmovl %0,%c\n\tsubl %1,%c\n" 1 +reg: SUBP4(reg,mrc) "?\tmovl %0,%c\n\tsubl %1,%c\n" 1 +reg: SUBU4(reg,mrc) "?\tmovl %0,%c\n\tsubl %1,%c\n" 1 +reg: BANDI4(reg,mrc) "?\tmovl %0,%c\n\tandl %1,%c\n" 1 +reg: BORI4(reg,mrc) "?\tmovl %0,%c\n\torl %1,%c\n" 1 +reg: BXORI4(reg,mrc) "?\tmovl %0,%c\n\txorl %1,%c\n" 1 +reg: BANDU4(reg,mrc) "?\tmovl %0,%c\n\tandl %1,%c\n" 1 +reg: BORU4(reg,mrc) "?\tmovl %0,%c\n\torl %1,%c\n" 1 +reg: BXORU4(reg,mrc) "?\tmovl %0,%c\n\txorl %1,%c\n" 1 + +stmt: ASGNI4(addr,ADDI4(mem4,con1)) "\tincl %1\n" memop(a) +stmt: ASGNI4(addr,ADDU4(mem4,con1)) "\tincl %1\n" memop(a) +stmt: ASGNP4(addr,ADDP4(mem4,con1)) "\tincl %1\n" memop(a) +stmt: ASGNI4(addr,SUBI4(mem4,con1)) "\tdecl %1\n" memop(a) +stmt: ASGNI4(addr,SUBU4(mem4,con1)) "\tdecl %1\n" memop(a) +stmt: ASGNP4(addr,SUBP4(mem4,con1)) "\tdecl %1\n" memop(a) +stmt: ASGNI4(addr,ADDI4(mem4,rc)) "\taddl %2,%1\n" memop(a) +stmt: ASGNI4(addr,SUBI4(mem4,rc)) "\tsubl %2,%1\n" memop(a) +stmt: ASGNU4(addr,ADDU4(mem4,rc)) "\taddl %2,%1\n" memop(a) +stmt: ASGNU4(addr,SUBU4(mem4,rc)) "\tsubl %2,%1\n" memop(a) + +stmt: ASGNI4(addr,BANDI4(mem4,rc)) "\tandl %2,%1\n" memop(a) +stmt: ASGNI4(addr,BORI4(mem4,rc)) "\torl %2,%1\n" memop(a) +stmt: ASGNI4(addr,BXORI4(mem4,rc)) "\txorl %2,%1\n" memop(a) +stmt: ASGNU4(addr,BANDU4(mem4,rc)) "\tandl %2,%1\n" memop(a) +stmt: ASGNU4(addr,BORU4(mem4,rc)) "\torl %2,%1\n" memop(a) +stmt: ASGNU4(addr,BXORU4(mem4,rc)) "\txorl %2,%1\n" memop(a) + +reg: BCOMI4(reg) "?\tmovl %0,%c\n\tnotl %c\n" 2 +reg: BCOMU4(reg) "?\tmovl %0,%c\n\tnotl %c\n" 2 +reg: NEGI4(reg) "?\tmovl %0,%c\n\tnegl %c\n" 2 + +stmt: ASGNI4(addr,BCOMI4(mem4)) "\tnotl %1\n" memop(a) +stmt: ASGNU4(addr,BCOMU4(mem4)) "\tnotl %1\n" memop(a) +stmt: ASGNI4(addr,NEGI4(mem4)) "\tnegl %1\n" memop(a) +reg: LSHI4(reg,rc5) "?\tmovl %0,%c\n\tsall %1,%c\n" 2 +reg: LSHU4(reg,rc5) "?\tmovl %0,%c\n\tshll %1,%c\n" 2 +reg: RSHI4(reg,rc5) "?\tmovl %0,%c\n\tsarl %1,%c\n" 2 +reg: RSHU4(reg,rc5) "?\tmovl %0,%c\n\tshrl %1,%c\n" 2 + +stmt: ASGNI4(addr,LSHI4(mem4,rc5)) "\tsall %2,%1\n" memop(a) +stmt: ASGNI4(addr,LSHU4(mem4,rc5)) "\tshll %2,%1\n" memop(a) +stmt: ASGNI4(addr,RSHI4(mem4,rc5)) "\tsarl %2,%1\n" memop(a) +stmt: ASGNI4(addr,RSHU4(mem4,rc5)) "\tshrl %2,%1\n" memop(a) + +rc5: CNSTI4 "$%a" range(a, 0, 31) +rc5: reg "%%cl" +reg: MULI4(reg,mrc) "?\tmovl %0,%c\n\timull %1,%c\n" 14 +reg: MULI4(con,mr) "\timul %0,%1,%c\n" 13 +reg: MULU4(reg,mr) "\tmull %1\n" 13 +reg: DIVU4(reg,reg) "\txorl %%edx,%%edx\n\tdivl %1\n" +reg: MODU4(reg,reg) "\txorl %%edx,%%edx\n\tdivl %1\n" +reg: DIVI4(reg,reg) "\tcdq\n\tidivl %1\n" +reg: MODI4(reg,reg) "\tcdq\n\tidivl %1\n" +reg: CVPU4(reg) "\tmovl %0,%c\n" move(a) +reg: CVUP4(reg) "\tmovl %0,%c\n" move(a) +reg: CVII4(INDIRI1(addr)) "\tmovsbl %0,%c\n" 3 +reg: CVII4(INDIRI2(addr)) "\tmovswl %0,%c\n" 3 +reg: CVUU4(INDIRU1(addr)) "movzbl %0,%c\n" 3 +reg: CVUU4(INDIRU2(addr)) "movzwl %0,%c\n" 3 +reg: CVII4(reg) "# extend\n" 3 +reg: CVIU4(reg) "# extend\n" 3 +reg: CVUI4(reg) "# extend\n" 3 +reg: CVUU4(reg) "# extend\n" 3 + +reg: CVII1(reg) "# truncate\n" 1 +reg: CVII2(reg) "# truncate\n" 1 +reg: CVUU1(reg) "# truncate\n" 1 +reg: CVUU2(reg) "# truncate\n" 1 + +mrca: mem4 "%0" +mrca: rc "%0" +mrca: ADDRGP4 "$%a" + +stmt: ASGNI1(addr,rc) "\tmovb %1,%0\n" 1 +stmt: ASGNI2(addr,rc) "\tmovw %1,%0\n" 1 +stmt: ASGNI4(addr,rc) "\tmovl %1,%0\n" 1 +stmt: ASGNU1(addr,rc) "\tmovb %1,%0\n" 1 +stmt: ASGNU2(addr,rc) "\tmovw %1,%0\n" 1 +stmt: ASGNU4(addr,rc) "\tmovl %1,%0\n" 1 +stmt: ASGNP4(addr,rc) "\tmovl %1,%0\n" 1 +stmt: ARGI4(mrca) "\tpushl %0\n" 1 +stmt: ARGU4(mrca) "\tpushl %0\n" 1 +stmt: ARGP4(mrca) "\tpushl %0\n" 1 +stmt: ASGNB(reg,INDIRB(reg)) "\tmovl $%a,%%ecx\n\trep\n\tmovsb\n" +stmt: ARGB(INDIRB(reg)) "\tsubl $%a,%%esp\n\tmovl %%esp,%%edi\n\tmovl $%a,%%ecx\n\trep\n\tmovsb\n" + +memf: INDIRF8(addr) "l %0" +memf: INDIRF4(addr) "s %0" +memf: CVFF8(INDIRF4(addr)) "s %0" +memf: CVFF4(INDIRF8(addr)) "l %0" + +freg: memf "\tfld%0\n" 3 + +stmt: ASGNF8(addr,freg) "\tfstpl %0\n" 7 +stmt: ASGNF4(addr,freg) "\tfstps %0\n" 7 +stmt: ASGNF4(addr,CVFF4(freg)) "\tfstps %0\n" 7 + +stmt: ARGF8(freg) "\tsubl $8,%%esp\n\tfstpl (%%esp)\n" +stmt: ARGF4(freg) "\tsubl $4,%%esp\n\tfstps (%%esp)\n" +freg: NEGF8(freg) "\tfchs\n" +freg: NEGF4(freg) "\tfchs\n" + +flt: memf "%0" +flt: freg "p %%st(1),%%st" + +freg: ADDF8(freg,flt) "\tfadd%1\n" +freg: ADDF4(freg,flt) "\tfadd%1\n" + +freg: DIVF8(freg,flt) "\tfdiv%1\n" +freg: DIVF4(freg,flt) "\tfdiv%1\n" + +freg: MULF8(freg,flt) "\tfmul%1\n" +freg: MULF4(freg,flt) "\tfmul%1\n" + +freg: SUBF8(freg,flt) "\tfsub%1\n" +freg: SUBF4(freg,flt) "\tfsub%1\n" + +freg: CVFF8(freg) "# CVFF8\n" +freg: CVFF4(freg) "\tsub $4,%%esp\n\tfstps (%%esp)\n\tflds (%%esp)\n\taddl $4,%%esp\n" 12 + +stmt: ASGNI4(addr,CVFI4(freg)) "\tfistpl %0\n" 29 +reg: CVFI4(freg) "\tsubl $4,%%esp\n\tfistpl 0(%%esp)\n\tpopl %c\n" 31 + +freg: CVIF8(INDIRI4(addr)) "\tfildl %0\n" 10 +freg: CVIF8(reg) "\tpushl %0\n\tfildl (%%esp)\n\taddl $4,%%esp\n" 12 + +freg: CVIF4(INDIRI4(addr)) "\tfildl %0\n" 10 +freg: CVIF4(reg) "\tpushl %0\n\tfildl (%%esp)\n\taddl $4,%%esp\n" 12 + +addrj: ADDRGP4 "%a" +addrj: reg "*%0" 2 +addrj: mem4 "*%0" 2 + +stmt: LABELV "%a:\n" +stmt: JUMPV(addrj) "\tjmp %0\n" 3 + +stmt: EQI4(mem4,rc) "\tcmpl %1,%0\n\tje %a\n" 5 +stmt: GEI4(mem4,rc) "\tcmpl %1,%0\n\tjge %a\n" 5 +stmt: GTI4(mem4,rc) "\tcmpl %1,%0\n\tjg %a\n" 5 +stmt: LEI4(mem4,rc) "\tcmpl %1,%0\n\tjle %a\n" 5 +stmt: LTI4(mem4,rc) "\tcmpl %1,%0\n\tjl %a\n" 5 +stmt: NEI4(mem4,rc) "\tcmpl %1,%0\n\tjne %a\n" 5 +stmt: GEU4(mem4,rc) "\tcmpl %1,%0\n\tjae %a\n" 5 +stmt: GTU4(mem4,rc) "\tcmpl %1,%0\n\tja %a\n" 5 +stmt: LEU4(mem4,rc) "\tcmpl %1,%0\n\tjbe %a\n" 5 +stmt: LTU4(mem4,rc) "\tcmpl %1,%0\n\tjb %a\n" 5 +stmt: EQI4(reg,mrc) "\tcmpl %1,%0\n\tje %a\n" 4 +stmt: GEI4(reg,mrc) "\tcmpl %1,%0\n\tjge %a\n" 4 +stmt: GTI4(reg,mrc) "\tcmpl %1,%0\n\tjg %a\n" 4 +stmt: LEI4(reg,mrc) "\tcmpl %1,%0\n\tjle %a\n" 4 +stmt: LTI4(reg,mrc) "\tcmpl %1,%0\n\tjl %a\n" 4 +stmt: NEI4(reg,mrc) "\tcmpl %1,%0\n\tjne %a\n" 4 + +stmt: EQU4(reg,mrc) "\tcmpl %1,%0\n\tje %a\n" 4 +stmt: GEU4(reg,mrc) "\tcmpl %1,%0\n\tjae %a\n" 4 +stmt: GTU4(reg,mrc) "\tcmpl %1,%0\n\tja %a\n" 4 +stmt: LEU4(reg,mrc) "\tcmpl %1,%0\n\tjbe %a\n" 4 +stmt: LTU4(reg,mrc) "\tcmpl %1,%0\n\tjb %a\n" 4 +stmt: NEU4(reg,mrc) "\tcmpl %1,%0\n\tjne %a\n" 4 + + +stmt: EQI4(BANDU4(mr,con),con0) "\ttestl\t%1,%0\n\tje\t%a\n" 3 +stmt: NEI4(BANDU4(mr,con),con0) "\ttestl\t%1,%0\n\tjne\t%a\n" + +stmt: EQI4(BANDU4(CVII2(INDIRI2(addr)),con),con0) "\ttestw\t%1,%0\n\tje\t%a\n" +stmt: NEI4(BANDU4(CVII2(INDIRI2(addr)),con),con0) "\ttestw\t%1,%0\n\tjne\t%a\n" +stmt: EQI4(BANDU4(CVIU2(INDIRI2(addr)),con),con0) "\ttestw\t%1,%0\n\tje\t%a\n" +stmt: NEI4(BANDU4(CVIU2(INDIRI2(addr)),con),con0) "\ttestw\t%1,%0\n\tjne\t%a\n" +stmt: EQI4(BANDU4(CVII1(INDIRI1(addr)),con),con0) "\ttestb\t%1,%0\n\tje\t%a\n" + +cmpf: INDIRF8(addr) "l %0" +cmpf: INDIRF4(addr) "s %0" +cmpf: CVFF8(INDIRF4(addr)) "s %0" +cmpf: freg "p" + +stmt: EQF8(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tje %a\n" +stmt: GEF8(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tjbe %a\n" +stmt: GTF8(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tjb %a\n" +stmt: LEF8(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tjae %a\n" +stmt: LTF8(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tja %a\n" +stmt: NEF8(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tjne %a\n" + +stmt: EQF4(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tje %a\n" +stmt: GEF4(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tjbe %a\n" +stmt: GTF4(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tjb %a\n" +stmt: LEF4(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tjae %a\n" +stmt: LTF4(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tja %a\n" +stmt: NEF4(cmpf,freg) "\tfcomp%0\n\tfstsw %%ax\n\tsahf\n\tjne %a\n" + + +freg: DIVF8(freg,CVIF8(INDIRI4(addr))) "\tfidivl\t%1\n" +freg: DIVF8(CVIF8(INDIRI4(addr)),freg) "\tfidivrl\t%0\n" +freg: DIVF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "\tfidivs\t%1\n" +freg: DIVF8(CVIF8(CVII2(INDIRI2(addr))),freg) "\tfidivrs\t%0\n" +freg: MULF8(freg,CVIF8(INDIRI4(addr))) "\tfimull\t%1\n" +freg: MULF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "\tfimuls\t%1\n" +freg: SUBF8(freg,CVIF8(INDIRI4(addr))) "\tfisubl\t%1\n" +freg: SUBF8(CVIF8(INDIRI4(addr)),freg) "\tfisubrl\t%0\n" +freg: SUBF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "\tfisubs\t%1\n" +freg: SUBF8(CVIF8(CVII2(INDIRI2(addr))),freg) "\tfisubrs\t%0\n" +freg: ADDF8(freg,CVIF8(INDIRI4(addr))) "\tfiaddl\t%1\n" +freg: ADDF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "\tfiadds\t%1\n" +freg: ADDF8(freg,CVFF8(INDIRF4(addr))) "\tfdivs\t%1\n" +freg: SUBF8(freg,CVFF8(INDIRF4(addr))) "\tfsubs\t%1\n" +freg: MULF8(freg,CVFF8(INDIRF4(addr))) "\tfmuls\t%1\n" +freg: DIVF8(freg,CVFF8(INDIRF4(addr))) "\tfdivs\t%1\n" +freg: LOADF8(memf) "\tfld%0\n" + +stmt: CALLV(addrj) "\tcall %0\n\taddl $%a,%%esp\n" hasargs(a) +reg: CALLI4(addrj) "\tcall %0\n\taddl $%a,%%esp\n" hasargs(a) +reg: CALLU4(addrj) "\tcall %0\n\taddl $%a,%%esp\n" hasargs(a) +reg: CALLP4(addrj) "\tcall %0\n\taddl $%a,%%esp\n" hasargs(a) +freg: CALLF4(addrj) "\tcall %0\n\taddl $%a,%%esp\n" hasargs(a) +stmt: CALLF4(addrj) "\tcall %0\n\taddl $%a,%%esp\n\tfstp %%st(0)\n" hasargs(a) +freg: CALLF8(addrj) "\tcall %0\n\taddl $%a,%%esp\n" hasargs(a) +stmt: CALLF8(addrj) "\tcall %0\n\taddl $%a,%%esp\n\tfstp %%st(0)\n" hasargs(a) + +stmt: CALLV(addrj) "\tcall %0\n" 1 +reg: CALLI4(addrj) "\tcall %0\n" 1 +reg: CALLU4(addrj) "\tcall %0\n" 1 +reg: CALLP4(addrj) "\tcall %0\n" 1 +freg: CALLF4(addrj) "\tcall %0\n" 1 +stmt: CALLF4(addrj) "\tcall %0\n\tfstp %%st(0)\n" 1 +freg: CALLF8(addrj) "\tcall %0\n" 1 +stmt: CALLF8(addrj) "\tcall %0\n\tfstp %%st(0)\n" 1 + +stmt: RETI4(reg) "# ret\n" +stmt: RETU4(reg) "# ret\n" +stmt: RETP4(reg) "# ret\n" +stmt: RETF4(freg) "# ret\n" +stmt: RETF8(freg) "# ret\n" + +%% +static void progbeg(int argc, char *argv[]) { + int i; + + { + union { + char c; + int i; + } u; + u.i = 0; + u.c = 1; + swap = ((int)(u.i == 1)) != IR->little_endian; + } + + parseflags(argc, argv); + for (i = 0; i < argc; i++) + if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "-pg")) + profile = 1; + + intreg[EAX] = mkreg("%%eax", EAX, 1, IREG); + intreg[EDX] = mkreg("%%edx", EDX, 1, IREG); + intreg[ECX] = mkreg("%%ecx", ECX, 1, IREG); + intreg[EBX] = mkreg("%%ebx", EBX, 1, IREG); + intreg[ESI] = mkreg("%%esi", ESI, 1, IREG); + intreg[EDI] = mkreg("%%edi", EDI, 1, IREG); + shortreg[EAX] = mkreg("%%ax", EAX, 1, IREG); + shortreg[ECX] = mkreg("%%cx", ECX, 1, IREG); + shortreg[EDX] = mkreg("%%dx", EDX, 1, IREG); + shortreg[EBX] = mkreg("%%bx", EBX, 1, IREG); + shortreg[ESI] = mkreg("%%si", ESI, 1, IREG); + shortreg[EDI] = mkreg("%%di", EDI, 1, IREG); + + charreg[EAX] = mkreg("%%al", EAX, 1, IREG); + charreg[ECX] = mkreg("%%cl", ECX, 1, IREG); + charreg[EDX] = mkreg("%%dl", EDX, 1, IREG); + charreg[EBX] = mkreg("%%bl", EBX, 1, IREG); + for (i = 0; i < 8; i++) + fltreg[i] = mkreg("%d", i, 0, FREG); + charregw = mkwildcard(charreg); + shortregw = mkwildcard(shortreg); + intregw = mkwildcard(intreg); + fltregw = mkwildcard(fltreg); + + tmask[IREG] = (1<<EDI) | (1<<ESI) | (1<<EBX) + | (1<<EDX) | (1<<ECX) | (1<<EAX); + vmask[IREG] = 0; + tmask[FREG] = 0xff; + vmask[FREG] = 0; + cseg = 0; + print("\t.text\n"); + quo = mkreg("%%eax", EAX, 1, IREG); + quo->x.regnode->mask |= 1<<EDX; + rem = mkreg("%%edx", EDX, 1, IREG); + rem->x.regnode->mask |= 1<<EAX; +} +static Symbol rmap(int opk) { + switch (optype(opk)) { + case B: case P: + return intregw; + case I: case U: + if (opsize(opk) == 1) + return charregw; + else if (opsize(opk) == 2) + return shortregw; + else + return intregw; + case F: + return fltregw; + default: + return 0; + } +} +static void segment(int n) { + if (n == cseg) + return; + cseg = n; + if (cseg == CODE) + print("\t.text\n"); + else if (cseg == BSS) + print("\t.bss\n"); + else if (cseg == DATA || cseg == LIT) + print("\t.data\n"); +} +static void progend(void) { + segment(0); +} +static void target(Node p) { + assert(p); + switch (specific(p->op)) { + case RSH+I: case RSH+U: case LSH+I: case LSH+U: + if (generic(p->kids[1]->op) != CNST + && !( generic(p->kids[1]->op) == INDIR + && specific(p->kids[1]->kids[0]->op) == VREG+P + && p->kids[1]->syms[RX]->u.t.cse + && generic(p->kids[1]->syms[RX]->u.t.cse->op) == CNST +)) { + rtarget(p, 1, intreg[ECX]); + setreg(p, intreg[EAX]); + } + break; + case MUL+U: + setreg(p, quo); + rtarget(p, 0, intreg[EAX]); + break; + case DIV+I: case DIV+U: + setreg(p, quo); + rtarget(p, 0, intreg[EAX]); + rtarget(p, 1, intreg[ECX]); + break; + case MOD+I: case MOD+U: + setreg(p, rem); + rtarget(p, 0, intreg[EAX]); + rtarget(p, 1, intreg[ECX]); + break; + case ASGN+B: + rtarget(p, 0, intreg[EDI]); + rtarget(p->kids[1], 0, intreg[ESI]); + break; + case ARG+B: + rtarget(p->kids[0], 0, intreg[ESI]); + break; + case CVF+I: + setreg(p, intreg[EAX]); + break; + case CALL+I: case CALL+U: case CALL+P: case CALL+V: + setreg(p, intreg[EAX]); + break; + case RET+I: case RET+U: case RET+P: + rtarget(p, 0, intreg[EAX]); + break; + } +} + +static void clobber(Node p) { + static int nstack = 0; + + assert(p); + nstack = ckstack(p, nstack); + switch (specific(p->op)) { + case ASGN+B: case ARG+B: + spill(1<<ECX | 1<<ESI | 1<<EDI, IREG, p); + break; + case EQ+F: case LE+F: case GE+F: case LT+F: case GT+F: case NE+F: + spill(1<<EAX, IREG, p); + break; + case CALL+F: + spill(1<<EDX | 1<<EAX, IREG, p); + break; + } +} +#define isfp(p) (optype((p)->op)==F) + +static int ckstack(Node p, int n) { + int i; + + for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) + if (isfp(p->x.kids[i])) + n--; + if (isfp(p) && p->count > 0) + n++; + if (n > 8) + error("expression too complicated\n"); + debug(fprint(stderr, "(ckstack(%x)=%d)\n", p, n)); + assert(n >= 0); + return n; +} +static int hasargs(Node p) { + assert(p); + assert(generic(p->op) == CALL); + assert(p->syms[0]); + if (p->syms[0]->u.c.v.i > 0) + return 0; + return LBURG_MAX; +} +static int memop(Node p) { + assert(p); + assert(generic(p->op) == ASGN); + assert(p->kids[0]); + assert(p->kids[1]); + if (generic(p->kids[1]->kids[0]->op) == INDIR + && sametree(p->kids[0], p->kids[1]->kids[0]->kids[0])) + return 3; + else + return LBURG_MAX; +} +static int sametree(Node p, Node q) { + return p == NULL && q == NULL + || p && q && p->op == q->op && p->syms[0] == q->syms[0] + && sametree(p->kids[0], q->kids[0]) + && sametree(p->kids[1], q->kids[1]); +} +static void emit2(Node p) { + int op = specific(p->op); +#define preg(f) ((f)[getregnum(p->x.kids[0])]->x.name) + + if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) + print("\tmovsbl\t%s,%s\n", preg(charreg), p->syms[RX]->x.name); + else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) + print("\tmovsbl\t%s,%s\n", preg(charreg), p->syms[RX]->x.name); + else if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) + print("\tmovswl\t%s,%s\n", preg(shortreg), p->syms[RX]->x.name); + else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) + print("\tmovswl\t%s,%s\n", preg(shortreg), p->syms[RX]->x.name); + else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) + print("\tmovzbl\t%s,%s\n", preg(charreg), p->syms[RX]->x.name); + else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) + print("\tmovzbl\t%s,%s\n", preg(charreg), p->syms[RX]->x.name); + else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) + print("\tmovzwl\t%s,%s\n", preg(shortreg), p->syms[RX]->x.name); + else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) + print("\tmovzwl\t%s,%s\n", preg(shortreg), p->syms[RX]->x.name); + else if (generic(op) == CVI || generic(op) == CVU || generic(op) == LOAD) { + char *dst = intreg[getregnum(p)]->x.name; + char *src = preg(intreg); + assert(opsize(p->op) <= opsize(p->x.kids[0]->op)); + if (dst != src) + print("\tmovl\t%s,%s\n", src, dst); + } +} + +static void doarg(Node p) { + assert(p && p->syms[0]); + mkactual(4, p->syms[0]->u.c.v.i); +} +static void blkfetch(int k, int off, int reg, int tmp) {} +static void blkstore(int k, int off, int reg, int tmp) {} +static void blkloop(int dreg, int doff, int sreg, int soff, + int size, int tmps[]) {} +static void local(Symbol p) { + if (isfloat(p->type)) + p->sclass = AUTO; + if (askregvar(p, rmap(ttob(p->type))) == 0) + mkauto(p); +} +static void function(Symbol f, Symbol caller[], Symbol callee[], int n) { + int i; + + print("\t.type\t%s,@function\n", f->x.name); + print("%s:\n", f->x.name); + print("\tpushl\t%%ebp\n"); + if (profile) { + static int profile_label; + print("\tmovl\t%%esp,%%ebp\n"); + segment(DATA); + print("\t.align 4\nLP%d:\n\t.long\t0\n", profile_label); + segment(CODE); + print("\tmovl\t$LP%d,%%edx\n\tcall\tmcount\n", profile_label); + profile_label++; + } + print("\tpushl\t%%ebx\n"); + print("\tpushl\t%%esi\n"); + print("\tpushl\t%%edi\n"); + print("\tmovl\t%%esp,%%ebp\n"); + usedmask[0] = usedmask[1] = 0; + freemask[0] = freemask[1] = ~(unsigned)0; + offset = 16 + 4; + for (i = 0; callee[i]; i++) { + Symbol p = callee[i]; + Symbol q = caller[i]; + assert(q); + p->x.offset = q->x.offset = offset; + p->x.name = q->x.name = stringf("%d", p->x.offset); + p->sclass = q->sclass = AUTO; + offset += roundup(q->type->size, 4); + } + assert(caller[i] == 0); + offset = maxoffset = 0; + gencode(caller, callee); + framesize = roundup(maxoffset, 4); + if (framesize > 0) + print("\tsubl\t$%d,%%esp\n", framesize); + emitcode(); + print("\tmovl\t%%ebp,%%esp\n"); + print("\tpopl\t%%edi\n"); + print("\tpopl\t%%esi\n"); + print("\tpopl\t%%ebx\n"); + print("\tpopl\t%%ebp\n"); + print("\tret\n"); + i = genlabel(1); + print("L%d:\n", i); + print("\t.size\t%s,L%d-%s\n", f->x.name, i, f->x.name); +} +static void defsymbol(Symbol p) { + if (p->scope >= LOCAL && p->sclass == STATIC) + p->x.name = stringf("L%d", genlabel(1)); + else if (p->generated) + p->x.name = stringf("L%s", p->name); + else if (p->scope == GLOBAL || p->sclass == EXTERN) + p->x.name = stringf("_%s", p->name); +/* + else if (p->scope == CONSTANTS + && (isint(p->type) || isptr(p->type)) + && p->name[0] == '0' && p->name[1] == 'x') + p->x.name = stringf("0%sH", &p->name[2]); +*/ + else + p->x.name = p->name; +} +static void defsymbolelf(Symbol p) { + if (p->scope >= LOCAL && p->sclass == STATIC) + p->x.name = stringf("L%d", genlabel(1)); + else if (p->generated) + p->x.name = stringf("L%s", p->name); + else if (p->scope == GLOBAL || p->sclass == EXTERN) + p->x.name = stringf("%s", p->name); +/* + else if (p->scope == CONSTANTS + && (isint(p->type) || isptr(p->type)) + && p->name[0] == '0' && p->name[1] == 'x') + p->x.name = stringf("0%sH", &p->name[2]); +*/ + else + p->x.name = p->name; +} +static void address(Symbol q, Symbol p, long n) { + if (p->scope == GLOBAL + || p->sclass == STATIC || p->sclass == EXTERN) + q->x.name = stringf("%s%s%d", + p->x.name, n >= 0 ? "+" : "", n); + else { + q->x.offset = p->x.offset + n; + q->x.name = stringd(q->x.offset); + } +} +static void defconst(int suffix, int size, Value v) { + if (suffix == I && size == 1) + print("\t.byte\t%d\n", v.u); + else if (suffix == I && size == 2) + print("\t.word\t%d\n", v.i); + else if (suffix == I && size == 4) + print("\t.long\t%d\n", v.i); + else if (suffix == U && size == 1) + print("\t.byte\t0x%x\n", v.u); + else if (suffix == U && size == 2) + print("\t.word\t0x%x\n", v.u); + else if (suffix == U && size == 4) + print("\t.long\t0x%x\n", v.u); + else if (suffix == P && size == 4) + print("\t.long\t0x%x\n", v.p); + else if (suffix == F && size == 4) { + float f = v.d; + print("\t.long\t0x%x\n", *(unsigned *)&f); + } + else if (suffix == F && size == 8) { + double d = v.d; + unsigned *p = (unsigned *)&d; + print("\t.long\t0x%x\n\t.long\t0x%x\n", p[swap], p[!swap]); + } + else assert(0); +} +static void defaddress(Symbol p) { + print("\t.long\t%s\n", p->x.name); +} +static void defstring(int n, char *str) { + char *s; + + for (s = str; s < str + n; s++) + print("\t.byte\t%d\n", (*s)&0377); +} +static void export(Symbol p) { + print("\t.globl\t%s\n", p->x.name); +} +static void import(Symbol p) { + int oldseg = cseg; + + if (p->ref > 0) { + segment(0); + print("\t.extern\t%s\n", p->x.name); + segment(oldseg); + } +} +static void global(Symbol p) { + print("\t.align\t%d\n", p->type->align > 4 ? 4 : p->type->align); + if (!p->generated) + print("\t.type\t%s,@%s\n", p->x.name, + isfunc(p->type) ? "function" : "object"); + if (p->u.seg == BSS) { + if (p->sclass == STATIC) + print("\t.lcomm\t%s,%d\n", p->x.name, p->type->size); + else + print("\t.comm\t%s,%d\n", p->x.name, p->type->size); + } else { + if (!p->generated) + print("\t.size\t%s,%d\n", p->x.name, p->type->size); + print("%s:\n", p->x.name); + } +} +static void space(int n) { + if (cseg != BSS) + print("\t.space\t%d\n", n); +} + +#include <stab.h> +static char *currentfile; /* current file name */ +static int ntypes; + +/* + * emittype - emit ty's type number, emitting its definition if necessary. + * Returns the output column number after emission; col is the approximate + * output column before emission and is used to emit continuation lines for long + * struct, union, and enum types. Continuations are not emitted for other types, + * even if the definition is long. lev is the depth of calls to emittype. + */ +static int emittype(ty, lev, col) Type ty; { + int tc = ty->x.typeno; + + if (isconst(ty) || isvolatile(ty)) { + col = emittype(ty->type, lev, col); + ty->x.typeno = ty->type->x.typeno; + ty->x.printed = 1; + return col; + } + if (tc == 0) { + ty->x.typeno = tc = ++ntypes; +/* fprint(2,"`%t'=%d\n", ty, tc); */ + } + print("%d", tc), col += 3; + if (ty->x.printed) + return col; + ty->x.printed = 1; + switch (ty->op) { + case VOID: /* void is defined as itself */ + print("=%d", tc), col += 1+3; + break; + case CHAR: /* unsigned char is a subrange of int */ + if (ty == unsignedchar) + print("=r1;0;255;"), col += 10; + else /* following pcc, char is a subrange of itself */ + print("=r%d;-128;127;", tc), col += 2+3+10; + break; + case SHORT: /* short is a subrange of int */ + if (ty == unsignedshort) + print("=r1;0;65535;"), col += 12; + else /* signed */ + print("=r1;-32768;32767;"), col += 17; + break; + case INT: /* int is a subrange of itself */ + print("=r1;%d;%d;", INT_MIN, INT_MAX), col += 4+11+1+10+1; + break; + case UNSIGNED: /* unsigned is a subrange of int */ + print("=r1;0;-1;"), col += 9; + break; + case FLOAT: + case DOUBLE: /* float, double get sizes instead of ranges */ + print("=r1;%d;0;", ty->size), col += 4+1+3; + break; + case POINTER: + print("=*"), col += 2; + col = emittype(ty->type, lev + 1, col); + break; + case FUNCTION: + print("=f"), col += 2; + col = emittype(ty->type, lev + 1, col); + break; + case ARRAY: /* array includes subscript as an int range */ + if (ty->size && ty->type->size) + print("=ar1;0;%d;", ty->size/ty->type->size - 1), col += 7+3+1; + else + print("=ar1;0;-1;"), col += 10; + col = emittype(ty->type, lev + 1, col); + break; + case STRUCT: case UNION: { + Field p; + if (!ty->u.sym->defined) { + print("=x%c%s:", ty->op == STRUCT ? 's' : 'u', ty->u.sym->name); + col += 2+1+strlen(ty->u.sym->name)+1; + break; + } + if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) { + ty->x.printed = 0; + break; + } + print("=%c%d", ty->op == STRUCT ? 's' : 'u', ty->size), col += 1+1+3; + for (p = fieldlist(ty); p; p = p->link) { + if (p->name) + print("%s:", p->name), col += strlen(p->name)+1; + else + print(":"), col += 1; + col = emittype(p->type, lev + 1, col); + if (p->lsb) + print(",%d,%d;", 8*p->offset + + (IR->little_endian ? fieldright(p) : fieldleft(p)), + fieldsize(p)); + else + print(",%d,%d;", 8*p->offset, 8*p->type->size); + col += 1+3+1+3+1; /* accounts for ,%d,%d; */ + if (col >= 80 && p->link) { + print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM); + col = 8; + } + } + print(";"), col += 1; + break; + } + case ENUM: { + Symbol *p; + if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) { + ty->x.printed = 0; + break; + } + print("=e"), col += 2; + for (p = ty->u.sym->u.idlist; *p; p++) { + print("%s:%d,", (*p)->name, (*p)->u.value), col += strlen((*p)->name)+3; + if (col >= 80 && p[1]) { + print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM); + col = 8; + } + } + print(";"), col += 1; + break; + } + default: + assert(0); + } + return col; +} + +/* dbxout - output .stabs entry for type ty */ +static void dbxout(ty) Type ty; { + ty = unqual(ty); + if (!ty->x.printed) { + int col = 0; + print(".stabs \""), col += 8; + if (ty->u.sym && !(isfunc(ty) || isarray(ty) || isptr(ty))) + print("%s", ty->u.sym->name), col += strlen(ty->u.sym->name); + print(":%c", isstruct(ty) || isenum(ty) ? 'T' : 't'), col += 2; + emittype(ty, 0, col); + print("\",%d,0,0,0\n", N_LSYM); + } +} + +/* asgncode - assign type code to ty */ +static void asgncode(ty, lev) Type ty; { + if (ty->x.marked || ty->x.typeno) + return; + ty->x.marked = 1; + switch (ty->op) { + case VOLATILE: case CONST: case VOLATILE+CONST: + asgncode(ty->type, lev); + ty->x.typeno = ty->type->x.typeno; + break; + case POINTER: case FUNCTION: case ARRAY: + asgncode(ty->type, lev + 1); + /* fall thru */ + case VOID: case CHAR: case SHORT: case INT: case UNSIGNED: + case FLOAT: case DOUBLE: + break; + case STRUCT: case UNION: { + Field p; + for (p = fieldlist(ty); p; p = p->link) + asgncode(p->type, lev + 1); + /* fall thru */ + case ENUM: + if (ty->x.typeno == 0) + ty->x.typeno = ++ntypes; + if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) + dbxout(ty); + break; + } + default: + assert(0); + } +} + +/* dbxtype - emit a stabs entry for type ty, return type code */ +static int dbxtype(ty) Type ty; { + asgncode(ty, 0); + dbxout(ty); + return ty->x.typeno; +} + +/* stabsym - output a stab entry for symbol p */ +static void stabsym(p) Symbol p; { + int code, tc, sz = p->type->size; + + if (p->generated || p->computed) + return; + if (isfunc(p->type)) { + print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, + p->sclass == STATIC ? 'f' : 'F', dbxtype(freturn(p->type)), + N_FUN, p->x.name); + return; + } + if (!IR->wants_argb && p->scope == PARAM && p->structarg) { + assert(isptr(p->type) && isstruct(p->type->type)); + tc = dbxtype(p->type->type); + sz = p->type->type->size; + } else + tc = dbxtype(p->type); + if (p->sclass == AUTO && p->scope == GLOBAL || p->sclass == EXTERN) { + print(".stabs \"%s:G", p->name); + code = N_GSYM; + } else if (p->sclass == STATIC) { + print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, p->scope == GLOBAL ? 'S' : 'V', + tc, p->u.seg == BSS ? N_LCSYM : N_STSYM, p->x.name); + return; + } else if (p->sclass == REGISTER) { + if (p->scope > PARAM) { + int r = p->x.regnode->number; + if (p->x.regnode->set == FREG) + r += 32; /* floating point */ + print(".stabs \"%s:r%d\",%d,0,", p->name, tc, N_RSYM); + print("%d,%d\n", sz, r); + } + return; + } else if (p->scope == PARAM) { + print(".stabs \"%s:p", p->name); + code = N_PSYM; + } else if (p->scope >= LOCAL) { + print(".stabs \"%s:", p->name); + code = N_LSYM; + } else + assert(0); + print("%d\",%d,0,0,%s\n", tc, code, + p->scope >= PARAM && p->sclass != EXTERN ? p->x.name : "0"); +} + +/* stabtype - output a stab entry for type *p */ +static void stabtype(p) Symbol p; { + if (p->type) { + if (p->sclass == 0) + dbxtype(p->type); + else if (p->sclass == TYPEDEF) + print(".stabs \"%s:t%d\",%d,0,0,0\n", p->name, dbxtype(p->type), N_LSYM); + } +} + +/* stabblock - output a stab entry for '{' or '}' at level lev */ +static void stabblock(brace, lev, p) Symbol *p; { + if (brace == '{') + while (*p) + stabsym(*p++); + print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev); +} + +/* stabinit - initialize stab output */ +static void stabinit(file, argc, argv) char *file; int argc; char *argv[]; { + typedef void (*Closure) (Symbol, void *); + + if (file && *file) { + (*IR->segment)(CODE); + print("Ltext:.stabs \"%s\",0x%x,0,0,Ltext\n", file, N_SO); + currentfile = file; + } + dbxtype(inttype); + dbxtype(chartype); + dbxtype(doubletype); + dbxtype(floattype); + dbxtype(longdouble); + dbxtype(longtype); + dbxtype(shorttype); + dbxtype(signedchar); + dbxtype(unsignedchar); + dbxtype(unsignedlong); + dbxtype(unsignedshort); + dbxtype(unsignedtype); + dbxtype(voidtype); + foreach(types, GLOBAL, (Closure)stabtype, NULL); +} + +/* stabline - emit stab entry for source coordinate *cp */ +static void stabline(cp) Coordinate *cp; { + if (cp->file && cp->file != currentfile) { + int lab = genlabel(1); + print("L%d: .stabs \"%s\",0x%x,0,0,L%d\n", lab, + cp->file, N_SOL, lab); + currentfile = cp->file; + } + print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y); +} + +Interface x86bsdIR = { + 1, 1, 0, /* char */ + 2, 2, 0, /* short */ + 4, 4, 0, /* int */ + 4, 4, 0, /* long */ + 4, 4, 0, /* long long */ + 4, 4, 1, /* float */ + 8, 4, 1, /* double */ + 8, 4, 1, /* long double */ + 4, 4, 0, /* T * */ + 0, 4, 0, /* struct; so that ARGB keeps stack aligned */ + 1, /* little_endian */ + 0, /* mulops_calls */ + 0, /* wants_callb */ + 1, /* wants_argb */ + 0, /* left_to_right */ + 0, /* wants_dag */ + 0, /* unsigned char */ + address, + blockbeg, + blockend, + defaddress, + defconst, + defstring, + defsymbol, + emit, + export, + function, + gen, + global, + import, + local, + progbeg, + progend, + segment, + space, + stabblock, 0, 0, stabinit, stabline, stabsym, stabtype, + {1, rmap, + blkfetch, blkstore, blkloop, + _label, + _rule, + _nts, + _kids, + _string, + _templates, + _isinstruction, + _ntname, + emit2, + doarg, + target, + clobber, + } +}; +Interface x86bsdelfIR = { + 1, 1, 0, /* char */ + 2, 2, 0, /* short */ + 4, 4, 0, /* int */ + 4, 4, 0, /* long */ + 4, 4, 0, /* long long */ + 4, 4, 1, /* float */ + 8, 4, 1, /* double */ + 8, 4, 1, /* long double */ + 4, 4, 0, /* T * */ + 0, 4, 0, /* struct; so that ARGB keeps stack aligned */ + 1, /* little_endian */ + 0, /* mulops_calls */ + 0, /* wants_callb */ + 1, /* wants_argb */ + 0, /* left_to_right */ + 0, /* wants_dag */ + 0, /* unsigned char */ + address, + blockbeg, + blockend, + defaddress, + defconst, + defstring, + defsymbolelf, + emit, + export, + function, + gen, + global, + import, + local, + progbeg, + progend, + segment, + space, + stabblock, 0, 0, stabinit, stabline, stabsym, stabtype, + {1, rmap, + blkfetch, blkstore, blkloop, + _label, + _rule, + _nts, + _kids, + _string, + _templates, + _isinstruction, + _ntname, + emit2, + doarg, + target, + clobber, + } +}; diff --git a/devel/lcc/patches/patch-aa b/devel/lcc/patches/patch-aa new file mode 100644 index 00000000000..bc287d65448 --- /dev/null +++ b/devel/lcc/patches/patch-aa @@ -0,0 +1,46 @@ +$NetBSD: patch-aa,v 1.1.1.1 2001/07/21 02:51:36 gmcgarry Exp $ +--- makefile.orig Tue Jun 5 19:16:00 2001 ++++ makefile Tue Jun 5 19:18:07 2001 +@@ -65,7 +65,8 @@ + $Bsparc$O \ + $Bstab$O \ + $Bx86$O \ +- $Bx86linux$O ++ $Bx86linux$O \ ++ $Bx86bsd$O + + $Brcc$E:: $Bmain$O $Blibrcc$A $(EXTRAOBJS) + $(LD) $(LDFLAGS) -o $@ $Bmain$O $(EXTRAOBJS) $Blibrcc$A $(EXTRALIBS) +@@ -111,6 +112,7 @@ + $Bsparc$O: $Bsparc.c; $(CC) $(CFLAGS) -c -Isrc -o $@ $Bsparc.c + $Bx86$O: $Bx86.c; $(CC) $(CFLAGS) -c -Isrc -o $@ $Bx86.c + $Bx86linux$O: $Bx86linux.c; $(CC) $(CFLAGS) -c -Isrc -o $@ $Bx86linux.c ++$Bx86bsd$O: $Bx86bsd.c; $(CC) $(CFLAGS) -c -Isrc -o $@ $Bx86bsd.c + + $Bdagcheck.c: $Blburg$E src/dagcheck.md; $Blburg src/dagcheck.md $@ + $Balpha.c: $Blburg$E src/alpha.md; $Blburg src/alpha.md $@ +@@ -118,6 +120,7 @@ + $Bsparc.c: $Blburg$E src/sparc.md; $Blburg src/sparc.md $@ + $Bx86.c: $Blburg$E src/x86.md; $Blburg src/x86.md $@ + $Bx86linux.c: $Blburg$E src/x86linux.md; $Blburg src/x86linux.md $@ ++$Bx86bsd.c: $Blburg$E src/x86bsd.md; $Blburg src/x86bsd.md $@ + + $Brcc.h: src/rcc.asdl; $(ASDL_HOME)/bin/asdlGen --c -d $B src/rcc.asdl + $Brcc$O: $Brcc.h; $(CC) $(CFLAGS) -c -Isrc -I$B -I$(ASDL_HOME)/include/asdlGen -o $@ $Brcc.c +@@ -231,7 +234,7 @@ + + clean:: testclean + $(RM) $B*$O +- $(RM) $Bdagcheck.c $Balpha.c $Bmips.c $Bx86.c $Bsparc.c $Bx86linux.c $Bgram.c ++ $(RM) $Bdagcheck.c $Balpha.c $Bmips.c $Bx86.c $Bsparc.c $Bx86linux.c $Bx86bsd.c $Bgram.c + $(RM) $Brcc.c $Brcc.h + $(RM) $Brcc1$E $Brcc1$E $B1rcc$E $B2rcc$E + $(RM) $B*.ilk +@@ -274,6 +277,7 @@ + $Bmips.c \ + $Bsparc.c \ + $Bx86linux.c \ ++ $Bx86bsd.c \ + $Bx86.c + + C=$Blcc -A -d0.6 -Wo-lccdir=$(BUILDDIR) -Isrc -I$(BUILDDIR) diff --git a/devel/lcc/patches/patch-ab b/devel/lcc/patches/patch-ab new file mode 100644 index 00000000000..ce95857c427 --- /dev/null +++ b/devel/lcc/patches/patch-ab @@ -0,0 +1,21 @@ +$NetBSD: patch-ab,v 1.1.1.1 2001/07/21 02:51:36 gmcgarry Exp $ +--- src/bind.c.orig Tue Sep 22 06:34:26 1998 ++++ src/bind.c Thu Jun 7 19:41:37 2001 +@@ -2,7 +2,7 @@ + extern Interface alphaIR; + extern Interface mipsebIR, mipselIR; + extern Interface sparcIR, solarisIR; +-extern Interface x86IR, x86linuxIR; ++extern Interface x86IR, x86linuxIR, x86bsdIR, x86bsdelfIR; + extern Interface symbolicIR, symbolic64IR; + extern Interface nullIR; + extern Interface bytecodeIR; +@@ -14,6 +14,8 @@ + "sparc/solaris", &solarisIR, + "x86/win32", &x86IR, + "x86/linux", &x86linuxIR, ++ "x86/netbsd", &x86bsdIR, ++ "x86/netbsdelf", &x86bsdelfIR, + "symbolic/osf", &symbolic64IR, + "symbolic/irix", &symbolicIR, + "symbolic", &symbolicIR, diff --git a/devel/lcc/patches/patch-ac b/devel/lcc/patches/patch-ac new file mode 100644 index 00000000000..318664bb0a4 --- /dev/null +++ b/devel/lcc/patches/patch-ac @@ -0,0 +1,46 @@ +$NetBSD: patch-ac,v 1.1.1.1 2001/07/21 02:51:36 gmcgarry Exp $ +--- etc/lcc.c.orig Tue Aug 22 19:56:56 2000 ++++ etc/lcc.c Tue Aug 22 21:24:43 2000 +@@ -552,6 +552,20 @@ + exit(n = 100); + } + ++/* parse -W[alp] argument, splitting at commas, a la gcc */ ++static List wappend (char *warg, List lst) { ++ if (*warg != ',') return append (warg, lst); ++ warg++; ++ do { ++ char *s = warg; ++ for (; *warg && *warg != ','; warg++) ++ ; ++ if (*warg) *warg++= '\0'; ++ if (*s) lst = append (s, lst); ++ } while (*warg); ++ return lst; ++} ++ + /* opt - process option in arg */ + static void opt(char *arg) { + switch (arg[1]) { /* multi-character options */ +@@ -563,7 +577,7 @@ + return; + break; + case 'p': +- plist = append(&arg[3], plist); ++ plist = wappend(&arg[3], plist); + return; + case 'f': + if (strcmp(&arg[3], "-C") || option("-b")) { +@@ -572,10 +586,10 @@ + } + break; /* and fall thru */ + case 'a': +- alist = append(&arg[3], alist); ++ alist = wappend(&arg[3], alist); + return; + case 'l': +- llist[0] = append(&arg[3], llist[0]); ++ llist[0] = wappend(&arg[3], llist[0]); + return; + } + fprintf(stderr, "%s: %s ignored\n", progname, arg); diff --git a/devel/lcc/pkg/COMMENT b/devel/lcc/pkg/COMMENT new file mode 100644 index 00000000000..7cd231f90a4 --- /dev/null +++ b/devel/lcc/pkg/COMMENT @@ -0,0 +1 @@ +lcc is a local ANSI C compiler for a variety of platforms. diff --git a/devel/lcc/pkg/DESCR b/devel/lcc/pkg/DESCR new file mode 100644 index 00000000000..5402c7b36cd --- /dev/null +++ b/devel/lcc/pkg/DESCR @@ -0,0 +1,3 @@ +This hierarchy is the distribution for lcc, the retargetable compiler +for ANSI C described in the book `A Retargetable C Compiler: Design and +Implementation' (Addison-Wesley, 1995, ISBN 0-8053-1670-1). diff --git a/devel/lcc/pkg/PLIST b/devel/lcc/pkg/PLIST new file mode 100644 index 00000000000..de5d1b7aac3 --- /dev/null +++ b/devel/lcc/pkg/PLIST @@ -0,0 +1,10 @@ +@comment $NetBSD: PLIST,v 1.1.1.1 2001/07/21 02:51:35 gmcgarry Exp $ +bin/lcc +libexec/bprint +libexec/cpp +libexec/lburg +libexec/rcc +share/lcc/include/stdarg.h +share/lcc/include/sys/cdefs.h +man/man1/lcc.1 +man/man1/bprint.1 |