diff options
Diffstat (limited to 'usr.bin/pcc/i386/code.c')
-rw-r--r-- | usr.bin/pcc/i386/code.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/usr.bin/pcc/i386/code.c b/usr.bin/pcc/i386/code.c new file mode 100644 index 00000000000..14b4f65a5b1 --- /dev/null +++ b/usr.bin/pcc/i386/code.c @@ -0,0 +1,213 @@ +/* $OpenBSD: code.c,v 1.1 2007/10/22 13:39:37 otto Exp $ */ +/* + * Copyright (c) 2003 Anders Magnusson (ragge@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); +} |