/* $Id: code.c,v 1.3 2009/02/08 16:41:35 ragge 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" int lastloc = -1; /* * Define everything needed to print out some data (or text). * This means segment, alignment, visibility, etc. */ void defloc(struct symtab *sp) { static char *loctbl[] = { "text", "data", "data" }; TWORD t; char *n; int s; if (sp == NULL) { lastloc = -1; return; } t = sp->stype; s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA; if (s != lastloc) printf(" .%s\n", loctbl[s]); lastloc = s; while (ISARY(t)) t = DECREF(t); n = sp->soname ? sp->soname : exname(sp->sname); if (sp->sclass == EXTDEF) printf(" .globl %s\n", n); if (ISFTN(sp->stype) || talign(sp->stype, sp->ssue) > ALCHAR) printf(".even\n"); if (sp->slevel == 0) { printf("%s:\n", n); } else { printf(LABFMT ":\n", sp->soffset); } } /* * code for the end of a function * deals with struct return here */ void efcode() { NODE *p, *q; if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN) return; /* Create struct assignment */ q = block(OREG, NIL, NIL, PTR+STRTY, 0, cftnsp->ssue); q->n_rval = R5; q->n_lval = 8; /* return buffer offset */ q = buildtree(UMUL, q, NIL); p = block(REG, NIL, NIL, PTR+STRTY, 0, cftnsp->ssue); p = buildtree(UMUL, p, NIL); p = buildtree(ASSIGN, q, p); ecomp(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 **sp, int cnt) { struct symtab *sp2; NODE *n; int i; if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) { /* Function returns struct, adjust arg offset */ for (i = 0; i < cnt; i++) sp[i]->soffset += SZPOINT(INT); } if (xtemps == 0) return; /* put arguments in temporaries */ for (i = 0; i < cnt; i++) { if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY || cisreg(sp[i]->stype) == 0) continue; sp2 = sp[i]; n = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->ssue); n = buildtree(ASSIGN, n, nametree(sp2)); sp[i]->soffset = regno(n->n_left); sp[i]->sflags |= STNODE; ecomp(n); } } /* * 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() { } /* * Called with a function call with arguments as argument. * This is done early in buildtree() and only done once. * Returns p. */ NODE * funcode(NODE *p) { NODE *r, *l; /* 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 = 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) { l = talloc(); *l = *r; r->n_op = FUNARG; r->n_left = l; r->n_type = l->n_type; } return p; } /* * 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) { } /* * XXX - fix genswitch. */ int mygenswitch(int num, TWORD type, struct swents **p, int n) { return 0; }