/** \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®CALL) ) { /* * 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 */ }
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"); }
/* * 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; } } }