Esempio n. 1
0
/** \brief Set the argument offsets for a function, then kick off compiling
 *  of the function
 *
 *  \param prevarg  - Last argument
 *  \param currfn   - Current function
 */
void setlocvar(SYMBOL *prevarg,SYMBOL *currfn)
{
    int lgh,where;
    int *iptr;
    SYMBOL *copyarg;
    int argnumber;
    char buffer2[120];
    unsigned char tester;

	lgh = 0;  /* Initialise it */
    if ( prevarg != NULL && currfn->prototyped == 0 ) {
        StoreFunctionSignature(prevarg);
    }

    argnumber=currfn->prototyped;
    /*
     *      If we have filled up our number of arguments, then pretend
     *      we don't have any..nasty, nasty
     */
    if (argnumber==(MAXARGS-1)) argnumber=0;
    else   if (argnumber) argnumber=1;
    /*
     *      Dump some info about defining the function etc
     */
    if (verbose){
        toconsole();
        outstr("Defining function: "); outstr(currfn->name); nl();
        tofile();
    }

    nl();prefix();outname(currfn->name,dopref(currfn));col();nl();  /* print function name */

    infunc=1;       /* In a function for sure! */
    copyarg=prevarg;

    if ( ( (currfn->flags&SHARED) && makeshare ) || sharedfile ) {
        /* Shared library definition, offset the stack */
        where= 2 +shareoffset;
    } else
        where = 2 ;
    /* If we use frame pointer we preserve previous framepointer on entry
     * to each function
     */
#ifdef USEFRAME
	if (useframe) where+=2;
#endif
    while ( prevarg ) {
        lgh = 2 ;      /* Default length */
        /* This is strange, previously double check for ->type */
        if ( prevarg->type == LONG && prevarg->ident != POINTER )
            lgh=4;
        if ( prevarg->type == DOUBLE && prevarg->ident != POINTER )
            lgh=6;
		/* Far pointers */
		if ( (prevarg->flags&FARPTR)==FARPTR && prevarg->ident == POINTER)
			lgh=4;
        prevarg->size=lgh;
#ifdef CODSWALLOP
        /* All pointers are pushed onto the stack for functions as 4 bytes, if
         * needed, near pointers are padded out to compensate for this by dummy
         * loading with zero, this allows us to have one set of routines to
         * cope with this and hence solve a lot of duplication
         */
        if (prevarg->ident == POINTER && lpointer) lgh=4;
        prevarg->size=lgh;
#endif
        /*
         * Check the definition against prototypes here...
         */
        if (argnumber) {
            tester=CalcArgValue(prevarg->type,prevarg->ident,prevarg->flags);
            if (currfn->args[argnumber] != tester ) {
                if (currfn->args[argnumber] != PELLIPSES ) {
                    if (currfn->args[argnumber] == 0 ) {
                        warning(W_2MADECL);
                    } else {
                        if ( (currfn->args[argnumber]&PMASKSIGN) == (tester&PMASKSIGN) ) {
                            warning(W_SIGNARG);
                        } else {
                            error(E_ARGMIS1,currfn->name,currfn->prototyped-argnumber+1, ExpandArgValue(tester,buffer2,prevarg->tag_idx) );
                            error(E_ARGMIS2,ExpandArgValue(currfn->args[argnumber],buffer2, currfn->tagarg[argnumber]));
                        }
                    }
                }
            }
            argnumber++;
        }
        iptr = &prevarg->offset.i ;
        prevarg = prevarg->offset.p ;           /* follow ptr to prev. arg */
        *iptr = where ;                                         /* insert offset */
        where += lgh ;                                          /* calculate next offset */
    }
#ifdef USEFRAME
	pushframe();
#endif
	currfn->handled=YES;
    if (currfn->prototyped==1 && (currfn->flags&REGCALL) ) {
        /*
         * Fast call routine..
         */
        if (lgh==2) zpush();
        else if (lgh==4) lpush();
        else if (lgh==6) dpush();
        /* erk, if not matched, dodgy type! */
        copyarg->offset.i=-lgh;
        where=2;
    }

    stackargs=where;
    lstdecl=0;       /* Set number of local statics to zero */
    if ( statement() != STRETURN ) {
        if (lstdecl) postlabel(lstlab);
        lstdecl=0;
        /* do a statement, but if it's a return, skip */
        /* cleaning up the stack */
        leave(NO,NO) ;
    }
    CleanGoto();
    /* Asz80 needs a label at the end to sort out local symbols */
	if (asxx) {
        nl();prefix();
		outstr("smce_");
		outname(currfn->name,NO);
		col();nl();
	}
#ifdef INBUILT_OPTIMIZER
    generate();
#endif
    infunc = 0 ;                    /* not in fn. any more */
}
Esempio n. 2
0
void 
#endif

dumpfns()
{
    int ident,type,storage;
    SYMBOL *ptr;
    FILE    *fp;

#ifdef HEADERFILE
    outstr(";\tHeader file for file:\t");
    outstr(Filename);
    outstr("\n;\n;\tEven if empty do not delete!!!\n");
    outstr(";\n;\t***START OF HEADER DEFNS***\n\n");
#else
    outstr("\n\n; --- Start of Scope Defns ---\n\n");
#endif
    if (!glbcnt)
        return;

/* Start at the start! */
    glbptr=STARTGLB;

    ptr=STARTGLB;
    while (ptr < ENDGLB) {
        if (ptr->name[0] != 0 && ptr->name[0] != '0' ) {
            ident=ptr->ident;
         if (ident==FUNCTIONP) ident=FUNCTION;
            type =ptr->type;
            storage=ptr->storage;
            if ( ident == FUNCTION && ptr->size != 0 ) {
                outstr("\tdefc\t");
                outname(ptr->name,1);
                ot("=\t");
                outdec(ptr->size);
                nl();
            } else {
                if (ident == FUNCTION && storage!=LSTATIC ) {
                    if (storage==EXTERNAL) {
                        if (ptr->flags&LIBRARY) {
                            GlobalPrefix(LIB);
                            if ( (ptr->flags&SHARED) && useshare ){
                                outstr(ptr->name); outstr("_sl\n");
                                GlobalPrefix(LIB);
                            }
                        } else {
                            GlobalPrefix(XREF);
                        }
                    } else {
                        if (ptr->offset.i == FUNCTION || ptr->storage==DECLEXTN )
                            GlobalPrefix(XDEF);
                        else
                            GlobalPrefix(XREF);
                    }
                    outname(ptr->name,dopref(ptr));
                    nl();
                } else {
                    if (storage == EXTERNP) {
                        GlobalPrefix(XDEF);
                        outname(ptr->name,1);
                        nl();
                        outstr("\tdefc\t");
                        outname(ptr->name,1);
                        ot("=\t");
                        outdec(ptr->size);
                        nl();
                    } else  if (ident != ENUM && type !=ENUM && ident != MACRO && storage != LSTATIC && storage != LSTKEXT && storage!=TYPDEF ) {
                        if (storage == EXTERNAL)
                            GlobalPrefix(XREF);
                        else 
                            GlobalPrefix(XDEF);
                        outname(ptr->name,1);
                        nl();
                    }
                }
            }
        }
        ++ptr;
    }
/*
 *      If a module requires floating point then previously we wrote
 *      it out to the header file. However, if the module didn't
 *      contain main() then important routines wouldn't be included.
 *      So, if main didn't need float, but ours did we couldn't
 *      compile correctly.
 *
 *      The solution was to separate startup code, and then define
 *      a new file to which all the math type headers would be
 *      appended.
 *
 *      This file is zcc_opt.def in the source code directory.
 *
 */

    if ( (fp=fopen("zcc_opt.def","a")) == NULL ) {
        error(E_ZCCOPT);
    }
/* Now output the org */
    if (zorg) {
        fprintf(fp,"\nIF !DEFINED_myzorg\n");
        fprintf(fp,"\tDEFINE DEFINED_myzorg\n");
        fprintf(fp,"\tdefc myzorg = %u\n",zorg);
        fprintf(fp,"ENDIF");
    }
    if (appz88) {
        int k,value=0;
        fprintf(fp,"\nIF !NEED_appstartup\n");
        fprintf(fp,"\tDEFINE\tNEED_appstartup\n");
        if (safedata != -1 )
            fprintf(fp,"\tdefc safedata = %d\n",safedata);
        if (intuition)
            fprintf(fp,"\tdefc intuition = 1\n");
        if (farheapsz != -1) {
            fprintf(fp,"\tDEFINE DEFINED_farheapsz\n");
            fprintf(fp,"\tdefc farheapsz = %d\n",farheapsz);
        }
 
        if (reqpag != -1 ) {
            fprintf(fp,"\tdefc reqpag = %d\n",reqpag);
            value=reqpag;
        }
        else {
/*
 * Consider the malloc pool as well, if defined we need 32 (standard) +
 * size of malloc - this is a little kludgy, hence the tuning command
 * line option
 */
            if ( (k=findmac("HEAPSIZE"))) {
                sscanf(&macq[k],"%d",&value);
                if (value != 0 ) value/=256;
            }
            value+=32;
            fprintf(fp,"\tdefc reqpag = %d\n",value);
        }
        if (value > 32) expanded=YES;
        fprintf(fp,"\tdefc NEED_expanded = %d\n",expanded);
        fprintf(fp,"ENDIF\n\n");

    }
    if (incfloat) {
        fprintf(fp,"\nIF !NEED_floatpack\n");
        fprintf(fp,"\tDEFINE\tNEED_floatpack\n");
        fprintf(fp,"ENDIF\n\n");
    }
    if (mathz88) {
        fprintf(fp,"\nIF !NEED_mathz88\n");
        fprintf(fp,"\tDEFINE\tNEED_mathz88\n");
        fprintf(fp,"ENDIF\n\n");
    }
    if (lpointer) {
        fprintf(fp,"\nIF !NEED_farpointer\n");
        fprintf(fp,"\tDEFINE NEED_farpointer\n");
        fprintf(fp,"ENDIF\n\n");
    }
    if (startup) {
        fprintf(fp,"\nIF !DEFINED_startup\n");
        fprintf(fp,"\tDEFINE DEFINED_startup\n");
        fprintf(fp,"\tdefc startup=%d\n",startup);
        fprintf(fp,"ENDIF\n\n");
    }
/*
 * Now, we're gonna use #pragma define _FAR_PTR to indicate whether we need
 * far stuff - this has to go with a -D_FAR_PTR from the compile line
 * as well for everything to work just right, so if we find this then
 * we can indicate to the startup code via zcc_opt.def what the scam
 * is - this could be used for eg. to allocate space for file structures
 * etc
 */
    if ( (ptr=findglb("_FAR_PTR")) && ptr->ident==MACRO ) {
        fprintf(fp,"\nIF !NEED_farstartup\n");
        fprintf(fp,"\tDEFINE NEED_farstartup\n");
        fprintf(fp,"ENDIF\n\n");
    }

    fclose(fp);

   if ( defvars != 0 )
      WriteDefined("defvarsaddr",defvars);

   switch(printflevel) {
    case 1:  
        WriteDefined("ministdio",0);
        break;
    case 2:
        WriteDefined("complexstdio",0);
        break;
    case 3:
        WriteDefined("floatstdio",0);
        break;
   }
 

/*
 * DO_inline is obsolete, but it may have a use sometime..
 */
    if (doinline)
        outstr("\tDEFINE\tDO_inline\n");
    outstr("\n\n; --- End of Scope Defns ---\n\n");
}
Esempio n. 3
0
/*
 * evaluate one initialiser
 *
 * if dump is TRUE, dump literal immediately
 * save character string in litq to dump later
 * this is used for structures and arrays of pointers to char, so that the
 * struct or array is built immediately and the char strings are dumped later
 */
void init(int size, int ident, int *dim, int more, int dump, int is_struct)
{
    int32_t value;
    int     sz;			/* number of chars in queue */
/*
 * djm 14/3/99 We have to rewrite this bit (ugh!) so that we store
 * our literal in a temporary queue, then if needed, we then dump
 * it out..
 */

    if ((sz = qstr(&value)) != -1 ) {
        sz++;
#if 0
        if (ident == VARIABLE || (size != 1 && more != CCHAR))
            error(E_ASSIGN);
#endif
#ifdef INIT_TEST
        outstr("ident=");
        outdec(ident);
        outstr("size=");
        outdec(size);
        outstr("more=");
        outdec(more);
        outstr("dim=");
        outdec(*dim);
        outstr("sz=");
        outdec(sz);
        nl();
#endif
        if (ident == ARRAY && more == 0) {
/*
 * Dump the literals where they are, padding out as appropriate
 */
            if (*dim != -1 && sz > *dim) {
/*
 * Ooops, initialised to long a string!
 */
                warning(W_INIT2LONG);
                sz = *dim;
                gltptr = sz;
                *(glbq + sz - 1) = '\0';	/* Terminate string */
            }
            dumplits(((size == 1) ? 0 : size), NO, gltptr, glblab, glbq);
            *dim -= sz;
            gltptr = 0;
            dumpzero(size, *dim);
            return;
        } else {
/*
 * Store the literals in the queue!
 */
            storeq(sz, glbq, &value);
            gltptr = 0;
            defword();
            printlabel(litlab);
            outbyte('+');
            outdec(value);
            nl();
            --*dim;
            return;
        }
    }
/*
 * djm, catch label names in structures (for (*name)() initialisation
 */
    else {
        char sname[NAMEMAX + 1];
        SYMBOL *ptr;
        if (symname(sname)  && strcmp(sname,"sizeof") ) {	/* We have got something.. */
            if ((ptr = findglb(sname))) {
                /* Actually found sommat..very good! */
                if (ident == POINTER || (ident == ARRAY && more)) {
                    defword();
                    outname(ptr->name, dopref(ptr));
                    nl();
                    --*dim;
                } else if (ptr->type == ENUM) {
                    value = ptr->size;
                    goto constdecl;
                } else {
                    error(E_DDECL);
                }
            } else
                error(E_UNSYMB, sname);
        } else if (rcmatch('}')) {
#if 0
            dumpzero(size,*dim);
#endif
        } else if (constexpr(&value, 1)) {
        constdecl:
            if (ident == POINTER) {
                /* 24/1/03 dom - We want to be able to assign values to
                   pointers or they're a bit useless..
                */
#if 0
                /* the only constant which can be assigned to a pointer is 0 */
                if (value != 0)
                    warning(W_ASSPTR);
#endif
                size = 2;
                dump = YES;
            }
            if (dump) {
                /* struct member or array of pointer to char */
                if (size == 4) {
/* there appears to be a bug in z80asm regarding defl */
                    defbyte();
                    outdec((value % 65536UL) % 256);
                    outbyte(',');
                    outdec((value % 65536UL) / 256);
                    outbyte(',');
                    outdec((value / 65536UL) % 256);
                    outbyte(',');
                    outdec((value / 65536UL) / 256);
                } else {
                    if (size == 1)
                        defbyte();
                    else
                        defword();
                    outdec(value);
                }
                nl();
                /* Dump out a train of zeros as appropriate */
                if (ident == ARRAY && more == 0) {		 
                    dumpzero(size,(*dim)-1);
                }

            } else
                stowlit(value, size);
            --*dim;
        }
    }
}