/** * dump struct data * @param symbol struct variable * @param position position of the struct in the array, or zero */ int dump_struct (SYMBOL *symbol, int position) { int dumped_bytes = 0; int i, number_of_members, value; number_of_members = tag_table[symbol->tagidx].number_of_members; for (i = 0; i < number_of_members; i++) { // i is the index of current member, get type int member_type = member_table[tag_table[symbol->tagidx].member_idx + i].type; if (member_type == CCHAR || member_type == CUCHAR) { defbyte(); dumped_bytes += 1; } else { /* XXX: compound types? */ defword(); dumped_bytes += 2; } if (position < get_size(symbol->name)) { // dump data value = get_item_at(symbol->name, position * number_of_members + i, &tag_table[symbol->tagidx]); outdec(value); } else { // dump zero, no more data available outdec(0); } nl(); } return (dumped_bytes); }
/* * report errors */ void errorsummary (void) { if (ncmp) error("missing closing bracket"); nl(); comment(); outdec(errcnt); if (errcnt) errfile = YES; outstr(" error(s) in compilation"); nl(); comment(); ot("literal pool:"); outdec(litptr); nl(); comment(); ot("constant pool:"); outdec(const_size); nl(); comment(); ot("global pool:"); outdec(glbptr - rglbptr); nl(); comment(); ot("Macro pool:"); outdec(macptr); nl(); pl(errcnt ? "Error(s)" : "No errors"); }
/* The output function for an ELF hash table. The hash table is an * array of 32-bit values. The first two array elements indicate the * length of the following subsections. Line breaks are inserted to * indicate where the subsections start and end. */ static void outhashtable(void const *ptr, long size, int ndx) { Elf64_Word const *entries = ptr; long count = size / sizeof *entries; long i; (void)ndx; beginblock(TRUE); if (count <= 2 || (long)(entries[0] + entries[1] + 2) != count) { for (i = 0 ; i < count ; ++i) outdec(entries[i]); } else { outdec(entries[0]); outdec(entries[1]); linebreak(); i = 2; if (entries[0] > 0) { for ( ; i < (long)(2 + entries[0]) ; ++i) outdec(entries[i]); linebreak(); } for ( ; i < count ; ++i) outdec(entries[i]); } endblock(); }
void dumplits( int size, int pr_label , int queueptr,int queuelab, unsigned char *queue) { int j, k,lit ; if ( queueptr ) { if ( pr_label ) { output_section("rodata_compiler"); // output_section("text"); prefix(); queuelabel(queuelab) ; col() ; nl(); } k = 0 ; while ( k < queueptr ) { /* pseudo-op to define byte */ if (infunc) j=1; else j=10; if (size == 1) defbyte(); else if (size == 4) deflong(); else if (size == 0 ) { defmesg(); j=30; } else defword(); while ( j-- ) { if (size==0) { lit=getint(queue+k,1); if (lit >= 32 && lit <= 126 && lit != '"' && lit != '\\' ) outbyte(lit); else { outstr("\"\n"); defbyte(); outdec(lit); nl(); lit=0; } k++; if ( j == 0 || k >=queueptr || lit == 0 ) { if (lit) outbyte('"'); nl(); break; } } else { outdec(getint(queue+k, size)); k += size ; if ( j == 0 || k >= queueptr ) { nl(); /* need <cr> */ break; } outbyte(','); /* separate bytes */ } } } output_section("code_compiler"); // output_section("code"); } nl(); }
/* * dump the literal pool */ void dumplits (void) { long j, k; if ((litptr == 0) && (const_nb == 0)) return; outstr("\t.data\n"); outstr("\t.bank CONST_BANK\n"); if (litptr) { outlabel(litlab); col(); k = 0; while (k < litptr) { defbyte(); j = 8; while (j--) { outdec(litq[k++] & 0xFF); if ((j == 0) | (k >= litptr)) { nl(); break; } outbyte(','); } } } if (const_nb) dump_const(); }
/* * dump switch table */ void dumpsw (INTPTR_T *ws) /*int ws[];*/ { INTPTR_T i,j; // gdata (); gnlabel (ws[WSTAB]); if (ws[WSCASEP] != swstp) { j = ws[WSCASEP]; while (j < swstp) { defword (); i = 4; while (i--) { outdec (swstcase[j]); outbyte (','); outlabel (swstlab[j++]); if ((i == 0) | (j >= swstp)) { newl (); break; } outbyte (','); } } } defword (); outlabel (ws[WSDEF]); outstr (",0"); newl(); // gtext (); }
void doset_sprpalstatement(void) { /* syntax is number of the first palette to alter : integer name of the data for loading palettes : identifier [ number of palette to load : integer ] if last argument is missing, 1 is assumed */ flush_ins(); /* David, optimize.c related */ ot("_set_sprpal\t"); outconst(); if (outcomma()) return; if (outnameunderline()) return; if (!match(",")) { outstr(",#"); outdec(1); } else { outbyte(','); outconst(); } newl(); needbrack(")"); }
void doload_spritesstatement(void) { /* syntax is offset in vram to load data at : integer name of the data to transfert : identifier number of sprites (of size 32x64) to load : integer */ flush_ins(); /* David, optimize.c related */ ot("load_sprites\t"); outconst(); if (outcomma()) return; if (outnameunderline()) return; if (!match(",")) { outstr(",#"); outdec(1); } else { outbyte(','); outconst(); } newl(); needbrack(")"); }
int constant(LVALUE *lval) { constype=CINT; conssign=dosigned; lval->is_const = 1 ; /* assume constant will be found */ if ( fnumber(&lval->const_val) ) { lval->val_type=DOUBLE; if ( doublestrings ) { immedlit(litlab); outdec(lval->const_val); nl(); callrts("__atof2"); WriteDefined("math_atof",1); } else { immedlit(dublab); outdec(lval->const_val); nl(); callrts("dload"); } lval->is_const = 0 ; /* floating point not constant */ lval->flags=0; return(1); } else if ( number(&lval->const_val) || pstr(&lval->const_val) ) { /* Insert long stuff/long pointer here? */ if ( (unsigned long )lval->const_val >= 65536LU ) constype = LONG; lval->val_type = constype ; lval->flags = (lval->flags&MKSIGN)|conssign; if (constype == LONG) vlongconst(lval->const_val); else vconst(lval->const_val); return(1); } else if ( tstr(&lval->const_val) ) { lval->is_const = 0 ; /* string address not constant */ lval->ptr_type=CCHAR; /* djm 9/3/99 */ lval->val_type=CINT; lval->flags=0; immedlit(litlab); } else { lval->is_const = 0 ; return(0); } outdec(lval->const_val); nl(); return(1); }
static void outdec(unsigned long n) { if (n >= 10) { outdec(n / 10); n %= 10; } outchar((unsigned char)(n + '0')); }
/* * dump zeroes for default initial value * (or rather, get loader to do it for us) */ int dumpzero(int size, int count) { if (count <= 0) return (0); defstorage() ; outdec(size*count) ; /* outstr("dumpzero"); */ nl(); return(size*count); }
/* The GNU hash table is an array of 32-bit values. (Although in a * 64-bit ELF file the mask subpart consists of 64-bit values. But an * array cannot change its type midway through, so in this case the * mask values are split across two array entries.) */ static void outgnuhash(void const *ptr, long size, int ndx) { Elf64_Word const *entries = ptr; long count = size / sizeof *entries; int buckets, masks; int i, n; (void)ndx; if (count < 4) { outwords(ptr, size, ndx); return; } buckets = entries[0]; masks = entries[2]; if (iself64()) masks *= 2; if (4 + masks + buckets > count) { outwords(ptr, size, ndx); return; } beginblock(TRUE); for (i = 0 ; i < 4 ; ++i) outdec(entries[i]); n = i; if (masks) { linebreak(); for (i = 0 ; i < masks ; ++i) outf("0x%08lX", entries[n + i]); n += i; } if (buckets) { linebreak(); for (i = 0 ; i < buckets ; ++i) outdec(entries[n + i]); n += i; } if (n < count) { linebreak(); for (i = n ; i < count ; ++i) outf("0x%08lX", entries[i]); } endblock(); }
errorsummary() { /* see if anything left hanging... */ if (ncmp) error("missing closing bracket"); /* open compound statement ... */ nl(); comment(); outdec(errcnt); /* total # errors */ outstr(" errors in compilation."); nl(); }
int outconst(void) { INTPTR_T dummy; number(&dummy); outbyte('#'); outdec(dummy); return 0; }
/* The output function for note sections. The format of a note section * varies with the type of note, the only constant part being that it * starts with an Elf*_Nhdr struct, and is usually followed by a * string. However, each subpart is guaranteed to be a multiple of 4 * bytes, so notes are displayed as arrays of 32-bit values. Line * breaks are inserted to indicate the beginning of a note header. * Note sections in core files are rather different, so in that case a * completely different function is called instead. */ void outnote(void const *ptr, long size, int ndx) { Elf64_Word const *words = ptr; long count = size / sizeof *words; long i; int namesize, descsize, tag; (void)ndx; if (iscorefile()) { iself64() ? outnote64(ptr, size, ndx) : outnote32(ptr, size, ndx); return; } beginblock(TRUE); i = 0; while (i < count) { namesize = (words[i] + 3) / 4; descsize = (words[i + 1] + 3) / 4; linebreak(); outdec(words[i++]); outdec(words[i++]); tag = words[i++]; outdefint(tag, "NT_GNU_"); while (namesize-- && i < count) outhex(words[i++]); if (descsize == 0) continue; #ifdef NT_GNU_ABI_TAG if (tag == NT_GNU_ABI_TAG) { outdefint(words[i++], "ELF_NOTE_OS_"); --descsize; } #endif while (descsize-- && i < count) outhex(words[i++]); } endblock(); }
/* * dump the constant pool * */ void dump_const (void) { long i, j, k; long size; /* long c; */ if (const_nb) { const_ptr = const_var; for (i = 0; i < const_nb; i++) { size = const_ptr->size; cptr = const_ptr->sym; cptr->storage = EXTERN; prefix(); outstr(cptr->name); outstr(":"); nl(); j = const_ptr->data; while (size) { k = const_val[j++]; if ((cptr->type == CCHAR || cptr->type == CUCHAR) && cptr->ident != POINTER && !(cptr->ident == ARRAY && cptr->ptr_order > 0)) { defbyte(); const_size += 1; } else { defword(); const_size += 2; } if ((k == -1) || (k >= MAX_CONST_DATA)) outstr("0"); else if (k <= -1024) { k = (-k) - 1024; outlabel(litlab); outbyte('+'); outdec(k); } else outstr(&const_data[k]); nl(); size--; } const_ptr++; } } }
void #endif dumpvars() { int ident,type,storage; SYMBOL *ptr; if (!glbcnt) return; /* Start at the start! */ glbptr=STARTGLB; outstr("; --- Start of Static Variables ---\n\n"); /* Two different handlings, if an application then use defvars construct * if not, then just drop em using defs! * * Even more handlings...if asz80 used we dump into data sectio */ output_section("bss_compiler"); // output_section("bss"); ptr=STARTGLB; while (ptr < ENDGLB) { if (ptr->name[0] != 0 && ptr->name[0] != '0' ) { ident=ptr->ident; type =ptr->type; storage=ptr->storage; if (ident !=ENUM && type !=ENUM && ident != MACRO && ident != FUNCTION && storage != EXTERNAL && storage != DECLEXTN && storage != EXTERNP && storage != LSTKEXT && storage!=TYPDEF ) { prefix(); outname(ptr->name,1); col(); defstorage(); outdec(ptr->size); nl(); } } ++ptr; } /* Switch back to standard section */ output_section("code_compiler"); // output_section("code"); }
dumplits() {int j,k; if (litptr==0) return; /* if nothing there, exit...*/ printlabel(litlab);col(); /* print literal label */ k=0; /* init an index... */ while (k < litptr) /* to loop with */ {defbyte(); /* pseudo-op to define byte */ j=10; /* max bytes per line */ while(j--) {outdec((litq[k++]&127)); if ((j==0) | (k>=litptr)) {nl(); /* need <cr> */ break; } outbyte(','); /* separate bytes */ } } }
static void dumpfinal (void) { int i; if (leaf_cnt) { outstr("leaf_loc: .ds "); outdec(leaf_size); nl(); for (i = 0; i < leaf_cnt; i++) { outstr("__"); outstr(leaf_functions[i]); outstr("_lend:\n"); } } if (data) { fclose(data); outstr("huc_data:\n"); outstr("___huc_data:\n"); outstr(data_buf); outstr("huc_data_end:\n"); outstr("___huc_data_end:\n"); } if (globals_h_in_process != 1) outstr("__heap_start:\n"); if (rodata) { fclose(rodata); ol(".data"); ol(".bank CONST_BANK"); outstr("huc_rodata:\n"); outstr("___huc_rodata:\n"); outstr(rodata_buf); outstr("huc_rodata_end:\n"); outstr("___huc_rodata_end:\n"); } fseek(output, output_globdef, SEEK_SET); if (have_irq_handler || have_sirq_handler) outstr("HAVE_IRQ = 1\n"); if (have_sirq_handler) outstr("HAVE_SIRQ = 1\n"); if (have_init_data) outstr("HAVE_INIT = 1\n"); }
dumpglbs() { int j; if(glbflag==0)return; /* don't if user said no */ cptr=startglb; while(cptr < glbptr) {if(cptr[ident]!=function) /* do if anything but function */ {outstr(cptr);col(); /* output name as label... */ defstorage(); /* define storage */ j=((cptr[offset]&255)+ ((cptr[offset+1]&255)<<8)); /* calc # bytes */ if((cptr[type]==cint)| (cptr[ident]==pointer)) j=j+1; outdec(j); /* need that many */ nl(); } cptr=cptr+symsiz; } }
/* * initialise structure */ int str_init(TAG_SYMBOL *tag) { int dim, flag; int sz, usz, numelements = 0; SYMBOL *ptr; int nodata = NO; ptr = tag->ptr; while (ptr < tag->end) { numelements++; dim = ptr->size; sz = getstsize(ptr,NO); if ( nodata == NO ) { if ( rcmatch('{') ) { needchar('{'); while (dim) { if ( ptr->type == STRUCT ) { if ( ptr->ident == ARRAY ) /* array of struct */ needchar('{'); str_init(tag); if ( ptr->ident == ARRAY ) { --dim; needchar('}'); } } else { init(sz, ptr->ident, &dim, 1, 1,1); } if (cmatch(',') == 0) break; blanks(); } needchar('}'); dumpzero(sz,dim); } else { init(sz, ptr->ident, &dim, ptr->more, 1, 1); } /* Pad out afterwards */ } else { /* Run out of data for this initialisation, set blank */ defstorage(); outdec(dim * getstsize(ptr,YES)); nl(); } usz = (ptr->size ? ptr->size : 1 ) * getstsize(ptr,YES); ++ptr; flag = NO; while (ptr->offset.i == 0 && ptr < tag->end) { if (getstsize(ptr,YES) * (ptr->size ? ptr->size : 1 ) > usz) { usz = getstsize(ptr,YES) * (ptr->size ? ptr->size : 1 ) ; flag = YES; } ++ptr; } /* Pad out the union */ if (usz != sz && flag) { defstorage(); outdec(usz - sz); nl(); } if (cmatch(',') == 0 && ptr != tag->end) { nodata = YES; } } return numelements; }
void dopsdinc(void) { INTPTR_T dummy; /* Used in the qstr function, I don't know its utility yet */ int numericarg = 0; /* Number of numeric arg to test validity */ if (amatch("pal",3)) { if (!match("(")) error("missing ("); ol(".data"); ol(".dw $0"); readstr(); /* read the label name */ prefix(); outstr(litq2); outstr(":\n"); addglb_far(litq2, CINT); if (!match(",")) { error("missing ,"); kill_line(); return; } ot(".incpal \""); if (readqstr() == 0) /* read the filename */ { error("bad filename in incpal"); kill_line(); return; } outstr(litq2); outstr("\""); if (match(",")) outstr(","); numericarg = 0; while (!match(")")) { numericarg++; number(&dummy); outdec(dummy); if (match(",")) outstr(","); } newl(); ol(".code"); if (numericarg>2) error("Maximum 2 numeric arg for incpal(name,\"filename\" [,start_pal] [,nb_pal])"); kill_line(); } else if (amatch("bin",3)) { if (!match("(")) error("missing ("); ol(".data"); ol(".dw $0"); readstr(); /* read the label name */ prefix(); outstr(litq2); outstr(":\n"); addglb_far(litq2, CCHAR); if (!match(",")) { error("missing ,"); kill_line(); return; } ot(".incbin \""); if (readqstr() == 0) /* read the filename */ { error("bad filename in incbin"); kill_line(); return; } outstr(litq2); outstr("\"\n"); if (!match(")")) error("missing )"); newl(); ol(".code"); kill_line(); } else if (amatch("bat",3)) { if (!match("(")) error("missing ("); ol(".data"); ol(".dw $0"); readstr(); /* read the label name */ prefix(); outstr(litq2); outstr(":\n"); addglb_far(litq2, CINT); if (!match(",")) { error("missing ,"); kill_line(); return; } ot(".incbat \""); if (readqstr() == 0) { error("bad filename in incbat"); kill_line(); return; } outstr(litq2); outstr("\""); if (match(",")) outstr(","); numericarg = 0; while (!match(")")) { numericarg++; number(&dummy); outdec(dummy); if (match(",")) outstr(","); } newl(); ol(".code"); if ((numericarg!=1) && (numericarg!=3) && (numericarg!=5)) error("Either 1,3 or 5 numeric arguments are needed for incbat statement"); kill_line(); } else if (amatch("spr",3)) { if (!match("(")) error("missing ("); ol(".data"); ol(".dw $0"); readstr(); /* read the label name */ prefix(); outstr(litq2); outstr(":\n"); addglb_far(litq2, CINT); if (!match(",")) { error("missing ,"); kill_line(); return; } ot(".incspr \""); if (readqstr() == 0) { error("bad filename in incspr"); kill_line(); return; } outstr(litq2); outstr("\""); if (match(",")) outstr(","); numericarg = 0; while (!match(")")) { numericarg++; number(&dummy); outdec(dummy); if (match(",")) outstr(","); } newl(); ol(".code"); if ((numericarg!=0) && (numericarg!=2) && (numericarg!=4)) error("Either 0,2 or 4 numeric arguments are needed for incspr statement"); kill_line(); } else if (amatch("chr",3)) { if (!match("(")) error("missing ("); ol(".data"); ol(".dw $0800"); readstr(); /* read the label name */ prefix(); outstr(litq2); outstr(":\n"); addglb_far(litq2, CINT); if (!match(",")) { error("missing ,"); kill_line(); return; } ot(".incchr \""); if (readqstr() == 0) { error("bad filename in incchr"); kill_line(); return; } outstr(litq2); outstr("\""); if (match(",")) outstr(","); numericarg = 0; while (!match(")")) { numericarg++; number(&dummy); outdec(dummy); if (match(",")) outstr(","); } newl(); ol(".code"); if ((numericarg!=0) && (numericarg!=2) && (numericarg!=4)) error("Either 0,2 or 4 numeric arguments are needed for incchr statement"); kill_line(); } else if (amatch("chr_ex",6)) { do_inc_ex(8); } else if (amatch("tile",4)) { if (!match("(")) error("missing ("); ol(".data"); ol(".dw $1000"); readstr(); /* read the label name */ prefix(); outstr(litq2); outstr(":\n"); addglb_far(litq2, CINT); if (!match(",")) { error("missing ,"); kill_line(); return; } ot(".inctile \""); if (readqstr() == 0) { error("bad filename in inctile"); kill_line(); return; } outstr(litq2); outstr("\""); if (match(",")) outstr(","); numericarg = 0; while (!match(")")) { numericarg++; number(&dummy); outdec(dummy); if (match(",")) outstr(","); } newl(); ol(".code"); if ((numericarg!=0) && (numericarg!=2) && (numericarg!=4)) error("Either 0,2 or 4 numeric arguments are needed for inctile statement"); kill_line(); } else if (amatch("tile_ex",7)) { do_inc_ex(16); } else { error("Unknown include directive"); kill_line(); } return; }
void dopsddef(void) { int numericarg = 0; INTPTR_T dummy; INTPTR_T dummy_array[16]; int i; if (amatch("pal",3)) { if (!match("(")) error("missing ("); readstr(); /* read the label name */ addglb_far(litq2, CINT); if (!match(",")) { error("missing ',' in #defpal"); kill_line(); return; } numericarg = 0; while (!match(")")) { number(&dummy_array[numericarg]); numericarg++; if (numericarg>16) error("No more than 16 colors can be defined at once"); match(","); } ol(".data"); prefix(); outstr(litq2); outstr(":"); ot(".defpal "); for (i = 0; i < numericarg; i++) { outhexfix(dummy_array[i],3); if (i < numericarg - 1) { outstr(","); if (i == 7) { outstr(" \\\n"); ot("\t"); } } } newl(); ol(".code"); kill_line(); } else if (amatch("chr",3)) { if (!match("(")) error("missing ("); ol(".data"); readstr(); /* read the label name */ prefix(); outstr(litq2); outstr(":"); addglb_far(litq2, CINT); if (!match(",")) { error("missing ,"); kill_line(); return; } ot(".defchr "); numericarg = 0; while (!match(")")) { numericarg++; number(&dummy); switch (numericarg) { case 1: outhexfix(dummy,4); outstr(","); break; case 2: outdec(dummy); outstr(",\\"); newl(); break; case 10: outhexfix(dummy,8); break; default: outhexfix(dummy,8); outstr(",\\"); newl(); } match(","); } newl(); ol(".code"); if (numericarg!=10) error("You must enter the VRAM address, the default palette and 8 values for pattern"); kill_line(); } else if (amatch("spr",3)) { if (!match("(")) error("missing ("); ol(".data"); readstr(); /* read the label name */ prefix(); outstr(litq2); outstr(":"); addglb_far(litq2, CINT); if (!match(",")) { error("missing ,"); kill_line(); return; } ot(".defspr "); numericarg = 0; while (!match(")")) { numericarg++; number(&dummy); switch (numericarg) { case 1: outhexfix(dummy,4); outstr(","); break; case 2: outdec(dummy); outstr(",\\"); newl(); break; case 34: outhexfix(dummy,8); break; default: outhexfix(dummy,8); outstr(","); if (!(numericarg & 1)) { outstr("\\"); newl(); } } match(","); } newl(); ol(".code"); if (numericarg!=34) error("You must enter the VRAM address, the default palette and 32 values for pattern"); kill_line(); } else { error("Unknown define directive"); kill_line(); } return; }
void do_inc_ex(int type) { int end; int i; INTPTR_T j; int num; int nb_tile; char label[NAMESIZE]; char label2[NAMESIZE]; char str[NAMESIZE+32]; struct { char fname[FILENAMESIZE]; INTPTR_T arg[5]; } tiles[16]; if(!match("(")) { error("missing '('"); kill_line(); return; } readstr(); /* read the label name */ strcpy(label, litq2); strcpy(label2, litq2); strcpy(str, "__data__"); for(i = (int)strlen(label2), j = 0; i < NAMEMAX; i++) label2[i] = str[j++]; label2[i] = '\0'; addglb(label2, ARRAY, CINT, 0, EXTERN); addglb(label, ARRAY, CINT, 0, EXTERN); if(!match(",")) { error("comma missing"); kill_line(); return; } end = 0; num = 0; nb_tile = 0; while (!end) { // if (match("\\")); if(!readqstr()) { error("not a file name"); kill_line(); return; } if(!match(",")) { error("comma missing"); kill_line(); return; } strcpy(tiles[num].fname, litq2); for (i = 0; i < 5; i++) { // if (match("\\")); if(!number(&tiles[num].arg[i])) { error("not a number"); kill_line(); return; } if (match(")")) { if (i == 4) { kill_line(); end = 1; break; } else { error("arg missing"); kill_line(); return; } } if(!match(",")) { error("comma missing"); kill_line(); return; } while((ch() == ' ') || (ch() == '\t')) gch(); if (ch() == '\0') { error("arg missing"); kill_line(); return; } } nb_tile += tiles[num].arg[2] * tiles[num].arg[3]; num++; if (num == 16) { if(!end) { error("too many args (max 16 files)"); kill_line(); return; } } } /* create const array to hold extra infos */ new_const(); const_val[const_val_idx++] = const_data_idx; /* number of tile */ sprintf(str, "%i", nb_tile); add_buffer(str, '('); const_data[const_data_idx++] = '\0'; const_val[const_val_idx++] = const_data_idx; /* tile size */ sprintf(str, "%i", type); add_buffer(str, '('); const_data[const_data_idx++] = '\0'; const_val[const_val_idx++] = const_data_idx; /* tile bank */ sprintf(str, "BANK(_%s)", label2); add_buffer(str, '('); const_data[const_data_idx++] = '\0'; const_val[const_val_idx++] = const_data_idx; /* tile addr */ sprintf(str, " _%s", label2); add_buffer(str, '('); const_data[const_data_idx++] = '\0'; const_val[const_val_idx++] = -(litptr + 1024); /* pal idx table addr */ add_const(CINT); /* create pal idx table */ for(i = 0; i < num; i++) { j = tiles[i].arg[2] * tiles[i].arg[3]; while (j) { j--; if (litptr < LITMAX) litq[litptr++] = (tiles[i].arg[4] << 4); } } /* dump incchr/tile cmds */ ol(".data"); if (type == 8) ol(".dw $0800"); else ol(".dw $1000"); prefix(); outstr(label2); outstr(":\n"); for(i = 0; i < num; i++) { if (type == 8) ot(".incchr \""); else ot(".inctile \""); outstr(tiles[i].fname); outstr("\""); for (j = 0; j < 4; j++) { outstr(","); outdec(tiles[i].arg[j]); } newl(); } ol(".code"); kill_line(); }
/* * print specified number as label */ void outlabel (INTPTR_T label) { olprfix (); outdec (label); }
/* * dump all static variables */ void dumpglbs (void) { long i = 1; int dim, list_size, line_count; int j; FILE *save = output; if (!data) data = fmemopen(data_buf, DATABUFSIZE, "w"); if (!rodata) rodata = fmemopen(rodata_buf, DATABUFSIZE, "w"); /* This is done in several passes: Pass 0: Dump initialization data into const bank. Pass 1: Define space for uninitialized data. Pass 2: Define space for initialized data. */ if (glbflag) { int pass = 0; next: i = 1; for (cptr = rglbptr; cptr < glbptr; cptr++) { if (cptr->ident != FUNCTION) { // ppubext(cptr); if ((cptr->storage & WRITTEN) == 0 && /* Not yet written to file */ cptr->storage != EXTERN) { dim = cptr->offset; if (find_symbol_initials(cptr->name)) { // has initials /* dump initialization data */ if (pass == 1) /* initialized data not handled in pass 1 */ continue; else if (pass == 2) { /* define space for initialized data */ output = data; if (cptr->storage != LSTATIC) prefix(); outstr(cptr->name); outstr(":\t"); defstorage(); outdec(cptr->size); nl(); cptr->storage |= WRITTEN; output = save; continue; } /* output initialization data into const bank */ output = rodata; have_init_data = 1; list_size = 0; line_count = 0; list_size = get_size(cptr->name); if (cptr->type == CSTRUCT) list_size /= tag_table[cptr->tagidx].number_of_members; if (dim == -1) dim = list_size; int item; /* dim is an item count for non-compound types and a byte size for compound types; dump_struct() wants an item number, so we have to count both to get the right members out. */ for (j = item = 0; j < dim; j++, item++) { if (cptr->type == CSTRUCT) j += dump_struct(cptr, item) - 1; else { if (line_count % 10 == 0) { nl(); if (cptr->type == CCHAR || cptr->type == CUCHAR) defbyte(); else defword(); } if (j < list_size) { // dump data int value = get_item_at(cptr->name, j, &tag_table[cptr->tagidx]); outdec(value); } else { // dump zero, no more data available outdec(0); } line_count++; if (line_count % 10 == 0) line_count = 0; else { if (j < dim - 1) outbyte(','); } } } nl(); output = save; } else { if (pass == 0) continue; /* define space in bss */ if (i) { i = 0; nl(); gdata(); } if (cptr->storage != LSTATIC) prefix(); outstr(cptr->name); outstr(":\t"); defstorage(); outdec(cptr->size); nl(); cptr->storage |= WRITTEN; } } } else { // fpubext(cptr); } } if (++pass < 3) goto next; } if (i) { nl(); gdata(); } output = save; }
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; } } }