/*-----------------------------------------------------------------*/ FILE * createDumpFile (int id) { struct _dumpFiles *dumpFilesPtr = dumpFiles; static int dumpIndex = 0; static char dumpIndexStr[32]; while (dumpFilesPtr->id) { if (dumpFilesPtr->id == id) break; dumpFilesPtr++; } if (!dumpFilesPtr->id) { fprintf (stdout, "internal error: createDumpFile: unknown dump file.\n"); exit (1); } sprintf (dumpIndexStr, ".%d", dumpIndex); dumpIndex++; if (!dumpFilesPtr->filePtr) { // not used before, create it struct dbuf_s dumpFileName; dbuf_init (&dumpFileName, PATH_MAX); dbuf_append_str (&dumpFileName, dstFileName); #ifdef _DEBUG dbuf_append_str (&dumpFileName, dumpIndexStr); #endif dbuf_append_str (&dumpFileName, dumpFilesPtr->ext); if (!(dumpFilesPtr->filePtr = fopen (dbuf_c_str (&dumpFileName), "w"))) { werror (E_FILE_OPEN_ERR, dbuf_c_str (&dumpFileName)); dbuf_destroy (&dumpFileName); exit (1); } dbuf_destroy (&dumpFileName); } #if 0 fprintf (dumpFilesPtr->filePtr, "Dump file index: %d\n", dumpIndex); #endif return dumpFilesPtr->filePtr; }
/*-----------------------------------------------------------------*/ const char * format_opcode (const char *inst, const char *fmt, va_list ap) { struct dbuf_s dbuf; dbuf_init (&dbuf, INITIAL_INLINEASM); if (inst && *inst) { dbuf_append_str (&dbuf, inst); if (fmt && *fmt) { dbuf_append_char (&dbuf, '\t'); dbuf_tvprintf (&dbuf, fmt, ap); } } else { if (fmt && *fmt) { dbuf_tvprintf (&dbuf, fmt, ap); } } return dbuf_detach_c_str (&dbuf); }
/** * construct new filename based on base_name and replace extension */ char * construct_filename( const char * base_name, const char * ext ) { char * pfile ; char * ppath ; struct dbuf_s dbuf ; char * ret ; pfile = filename( base_name ) ; ppath = dirname( base_name ) ; dbuf_init( &dbuf, 128 ) ; dbuf_append_str( &dbuf, ppath ) ; dbuf_append_str( &dbuf, pfile ) ; dbuf_append_str( &dbuf, ext ) ; ret = dbuf_detach( &dbuf ); free( ppath ) ; free( pfile ) ; return ret ; }
static void _gbz80_rgblink (void) { FILE *lnkfile; struct dbuf_s lnkFileName; char *buffer; dbuf_init (&lnkFileName, PATH_MAX); /* first we need to create the <filename>.lnk file */ dbuf_append_str (&lnkFileName, dstFileName); dbuf_append_str (&lnkFileName, ".lk"); if (!(lnkfile = fopen (dbuf_c_str (&lnkFileName), "w"))) { werror (E_FILE_OPEN_ERR, dbuf_c_str (&lnkFileName)); dbuf_destroy (&lnkFileName); exit (1); } dbuf_destroy (&lnkFileName); fprintf (lnkfile, "[Objects]\n"); fprintf (lnkfile, "%s.rel\n", dstFileName); fputStrSet (lnkfile, relFilesSet); fprintf (lnkfile, "\n[Libraries]\n"); /* additional libraries if any */ fputStrSet (lnkfile, libFilesSet); fprintf (lnkfile, "\n[Output]\n" "%s.gb", dstFileName); fclose (lnkfile); buffer = buildCmdLine (port->linker.cmd, dstFileName, NULL, NULL, NULL); /* call the linker */ if (sdcc_system (buffer)) { Safe_free (buffer); perror ("Cannot exec linker"); exit (1); } Safe_free (buffer); }
/*-----------------------------------------------------------------*/ static void printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf) { symbol *sym; if (!map) return; if (!map->syms) return; for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) { if (sym->level == 0) continue; if (sym->localof != func) continue; dbuf_printf (oBuf, ";%-25s Allocated ", sym->name); /* if assigned to registers */ if (!sym->allocreq && sym->reqv) { int i; sym = OP_SYMBOL (sym->reqv); if (!sym->isspilt || sym->remat) { dbuf_append_str (oBuf, "to registers "); for (i = 0; i < 4 && sym->regs[i]; i++) dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i])); dbuf_append_char (oBuf, '\n'); continue; } else { sym = sym->usl.spillLoc; } } /* if on stack */ if (sym->onStack) { dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack); continue; } /* otherwise give rname */ dbuf_printf (oBuf, "with name '%s'\n", sym->rname); } }
/*-----------------------------------------------------------------*/ void printAllocInfo (symbol * func, struct dbuf_s * oBuf) { #define BREAKLINE ";------------------------------------------------------------\n" int cnt = 0; set *ovrset; set *tempOverlaySyms; if (!func) return; /* must be called after register allocation is complete */ dbuf_append_str (oBuf, BREAKLINE); dbuf_printf (oBuf, ";Allocation info for local variables in function '%s'\n", func->name); dbuf_append_str (oBuf, BREAKLINE); cnt += printAllocInfoSeg (xstack, func, oBuf); cnt += printAllocInfoSeg (istack, func, oBuf); cnt += printAllocInfoSeg (code, func, oBuf); cnt += printAllocInfoSeg (data, func, oBuf); cnt += printAllocInfoSeg (xdata, func, oBuf); cnt += printAllocInfoSeg (idata, func, oBuf); cnt += printAllocInfoSeg (sfr, func, oBuf); cnt += printAllocInfoSeg (sfrbit, func, oBuf); tempOverlaySyms = overlay->syms; /* search the set of overlay sets for local variables/parameters */ for (ovrset = setFirstItem (ovrSetSets); ovrset; ovrset = setNextItem (ovrSetSets)) { overlay->syms = ovrset; cnt += printAllocInfoSeg (overlay, func, oBuf); } overlay->syms = tempOverlaySyms; if (cnt) dbuf_append_str (oBuf, BREAKLINE); }
/*-----------------------------------------------------------------*/ void printLine (lineNode * head, struct dbuf_s *oBuf) { iCode *last_ic = NULL; bool debug_iCode_tracking = (getenv ("DEBUG_ICODE_TRACKING") != NULL); while (head) { if (head->ic != last_ic) { last_ic = head->ic; if (debug_iCode_tracking) { if (head->ic) dbuf_printf (oBuf, "; block = %d, seq = %d\n", head->ic->block, head->ic->seq); else dbuf_append_str (oBuf, "; iCode lost\n"); } } /* don't indent comments & labels */ if (head->line && (head->isComment || head->isLabel)) { dbuf_printf (oBuf, "%s\n", head->line); } else { if (head->isInline && *head->line == '#') { /* comment out preprocessor directives in inline asm */ dbuf_append_char (oBuf, ';'); } dbuf_printf (oBuf, "\t%s\n", head->line); } head = head->next; } }
/*-----------------------------------------------------------------*/ static int printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf) { symbol *sym; int flg = FALSE; if (!map || !map->syms) return 0; for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) { if (sym->level == 0) continue; if (sym->localof != func) continue; dbuf_printf (oBuf, ";%-25s Allocated ", sym->name); flg = TRUE; /* if assigned to registers */ if (!sym->allocreq && sym->reqv) { int i; sym = OP_SYMBOL (sym->reqv); if (!sym->isspilt || sym->remat) { dbuf_append_str (oBuf, "to registers "); for (i = 0; i < 4 && sym->regs[i]; i++) dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i])); dbuf_append_char (oBuf, '\n'); continue; } else { sym = sym->usl.spillLoc; } } /* if on stack */ if (sym->onStack) { int stack_offset = 0; if (options.omitFramePtr) { if (SPEC_OCLS (sym->etype)->paged) stack_offset = func->xstack; else stack_offset = func->stack; } dbuf_printf (oBuf, "to stack - %s %+d\n", SYM_BP (sym), sym->stack - stack_offset); continue; } /* otherwise give rname */ dbuf_printf (oBuf, "with name '%s'\n", sym->rname); } return flg; }
static void _pic14_do_link (void) { /* * link command format: * {linker} {incdirs} {lflags} -o {outfile} {spec_ofiles} {ofiles} {libs} * */ #define LFRM "{linker} {incdirs} {sysincdirs} {lflags} -w -r -o {outfile} {user_ofile} {spec_ofiles} {ofiles} {libs}" hTab *linkValues = NULL; char *lcmd; set *tSet = NULL; int ret; char * procName; shash_add (&linkValues, "linker", "gplink"); /* LIBRARY SEARCH DIRS */ mergeSets (&tSet, libPathsSet); mergeSets (&tSet, libDirsSet); shash_add (&linkValues, "incdirs", joinStrSet (processStrSet (tSet, "-I", NULL, shell_escape))); joinStrSet (processStrSet (libDirsSet, "-I", NULL, shell_escape)); shash_add (&linkValues, "sysincdirs", joinStrSet (processStrSet (libDirsSet, "-I", NULL, shell_escape))); shash_add (&linkValues, "lflags", joinStrSet (linkOptionsSet)); { char *s = shell_escape (fullDstFileName ? fullDstFileName : dstFileName); shash_add (&linkValues, "outfile", s); Safe_free (s); } if (fullSrcFileName) { struct dbuf_s dbuf; char *s; dbuf_init (&dbuf, 128); dbuf_append_str (&dbuf, fullDstFileName ? fullDstFileName : dstFileName); dbuf_append (&dbuf, ".o", 2); s = shell_escape (dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); shash_add (&linkValues, "user_ofile", s); Safe_free (s); } shash_add (&linkValues, "ofiles", joinStrSet (processStrSet (relFilesSet, NULL, NULL, shell_escape))); /* LIBRARIES */ procName = processor_base_name (); if (!procName) procName = "16f877"; addSet (&libFilesSet, Safe_strdup (pic14_getPIC()->isEnhancedCore ? "libsdcce.lib" : "libsdcc.lib")); { struct dbuf_s dbuf; dbuf_init (&dbuf, 128); dbuf_append (&dbuf, "pic", sizeof ("pic") - 1); dbuf_append_str (&dbuf, procName); dbuf_append (&dbuf, ".lib", sizeof (".lib") - 1); addSet (&libFilesSet, dbuf_detach_c_str (&dbuf)); } shash_add (&linkValues, "libs", joinStrSet (processStrSet (libFilesSet, NULL, NULL, shell_escape))); lcmd = msprintf(linkValues, LFRM); ret = sdcc_system (lcmd); Safe_free (lcmd); if (ret) exit (1); }
static void _setValues(void) { const char *s; if (options.nostdlib == FALSE) { const char *s; char path[PATH_MAX]; struct dbuf_s dbuf; dbuf_init(&dbuf, PATH_MAX); for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet)) { buildCmdLine2(path, sizeof path, "-k\"%s" DIR_SEPARATOR_STRING "{port}\" ", s); dbuf_append_str(&dbuf, path); } buildCmdLine2(path, sizeof path, "-l\"{port}.lib\"", s); dbuf_append_str(&dbuf, path); setMainValue ("z80libspec", dbuf_c_str(&dbuf)); dbuf_destroy(&dbuf); for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet)) { struct stat stat_buf; buildCmdLine2(path, sizeof path, "%s" DIR_SEPARATOR_STRING "{port}" DIR_SEPARATOR_STRING "crt0{objext}", s); if (stat(path, &stat_buf) == 0) break; } if (s == NULL) setMainValue ("z80crt0", "\"crt0{objext}\""); else { char *buf; size_t len = strlen(path) + 3; buf = Safe_alloc(len); SNPRINTF(buf, len, "\"%s\"", path); setMainValue("z80crt0", buf); Safe_free(buf); } } else { setMainValue ("z80libspec", ""); setMainValue ("z80crt0", ""); } setMainValue ("z80extralibfiles", (s = joinStrSet(libFilesSet))); Safe_free((void *)s); setMainValue ("z80extralibpaths", (s = joinStrSet(libPathsSet))); Safe_free((void *)s); if (IS_GB) { setMainValue ("z80outputtypeflag", "-Z"); setMainValue ("z80outext", ".gb"); } else { setMainValue ("z80outputtypeflag", "-i"); setMainValue ("z80outext", ".ihx"); } setMainValue ("stdobjdstfilename" , "{dstfilename}{objext}"); setMainValue ("stdlinkdstfilename", "{dstfilename}{z80outext}"); setMainValue ("z80extraobj", (s = joinStrSet(relFilesSet))); Safe_free((void *)s); sprintf (buffer, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc); setMainValue ("z80bases", buffer); }
static int do_pragma(int id, const char *name, const char *cp) { struct pragma_token_s token; int err = 0; int processed = 1; init_pragma_token(&token); switch (id) { case P_BANK: { struct dbuf_s buffer; dbuf_init(&buffer, 128); cp = get_pragma_token(cp, &token); switch (token.type) { case TOKEN_EOL: err = 1; break; case TOKEN_INT: switch (_G.asmType) { case ASM_TYPE_ASXXXX: dbuf_printf (&buffer, "CODE_%d", token.val.int_val); break; case ASM_TYPE_RGBDS: dbuf_printf (&buffer, "CODE,BANK[%d]", token.val.int_val); break; case ASM_TYPE_ISAS: /* PENDING: what to use for ISAS? */ dbuf_printf (&buffer, "CODE,BANK(%d)", token.val.int_val); break; default: wassert (0); } break; default: { const char *str = get_pragma_string (&token); dbuf_append_str (&buffer, (0 == strcmp("BASE", str)) ? "HOME" : str); } break; } cp = get_pragma_token (cp, &token); if (TOKEN_EOL != token.type) { err = 1; break; } dbuf_c_str (&buffer); /* ugly, see comment in src/port.h (borutr) */ gbz80_port.mem.code_name = dbuf_detach (&buffer); code->sname = gbz80_port.mem.code_name; options.code_seg = (char *)gbz80_port.mem.code_name; } break; case P_PORTMODE: { /*.p.t.20030716 - adding pragma to manipulate z80 i/o port addressing modes */ const char *str; cp = get_pragma_token (cp, &token); if (TOKEN_EOL == token.type) { err = 1; break; } str = get_pragma_string (&token); cp = get_pragma_token (cp, &token); if (TOKEN_EOL != token.type) { err = 1; break; } if (!strcmp(str, "z80")) { z80_opts.port_mode = 80; } else if(!strcmp(str, "z180")) { z80_opts.port_mode = 180; } else if(!strcmp(str, "save")) { z80_opts.port_back = z80_opts.port_mode; } else if(!strcmp(str, "restore" )) { z80_opts.port_mode = z80_opts.port_back; } else err = 1; } break; case P_CODESEG: case P_CONSTSEG: { char *segname; cp = get_pragma_token (cp, &token); if (token.type == TOKEN_EOL) { err = 1; break; } segname = Safe_strdup (get_pragma_string(&token)); cp = get_pragma_token (cp, &token); if (token.type != TOKEN_EOL) { Safe_free (segname); err = 1; break; } if (id == P_CODESEG) { if (options.code_seg) Safe_free(options.code_seg); options.code_seg = segname; } else { if (options.const_seg) Safe_free(options.const_seg); options.const_seg = segname; } } break; default: processed = 0; break; } get_pragma_token(cp, &token); if (1 == err) werror(W_BAD_PRAGMA_ARGUMENTS, name); free_pragma_token(&token); return processed; }
static void _setValues (void) { const char *s; struct dbuf_s dbuf; if (options.nostdlib == FALSE) { const char *s; char *path; struct dbuf_s dbuf; dbuf_init (&dbuf, PATH_MAX); for (s = setFirstItem (libDirsSet); s != NULL; s = setNextItem (libDirsSet)) { path = buildCmdLine2 ("-k\"%s" DIR_SEPARATOR_STRING "{port}\" ", s); dbuf_append_str (&dbuf, path); Safe_free (path); } path = buildCmdLine2 ("-l\"{port}.lib\"", s); dbuf_append_str (&dbuf, path); Safe_free (path); setMainValue ("z80libspec", dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); for (s = setFirstItem (libDirsSet); s != NULL; s = setNextItem (libDirsSet)) { struct stat stat_buf; path = buildCmdLine2 ("%s" DIR_SEPARATOR_STRING "{port}" DIR_SEPARATOR_STRING "crt0{objext}", s); if (stat (path, &stat_buf) == 0) { Safe_free (path); break; } else Safe_free (path); } if (s == NULL) setMainValue ("z80crt0", "\"crt0{objext}\""); else { struct dbuf_s dbuf; dbuf_init (&dbuf, 128); dbuf_printf (&dbuf, "\"%s\"", path); setMainValue ("z80crt0", dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); } } else { setMainValue ("z80libspec", ""); setMainValue ("z80crt0", ""); } setMainValue ("z80extralibfiles", (s = joinStrSet (libFilesSet))); Safe_free ((void *) s); setMainValue ("z80extralibpaths", (s = joinStrSet (libPathsSet))); Safe_free ((void *) s); if (IS_GB) { setMainValue ("z80outputtypeflag", "-Z"); setMainValue ("z80outext", ".gb"); } else { setMainValue ("z80outputtypeflag", "-i"); setMainValue ("z80outext", ".ihx"); } setMainValue ("stdobjdstfilename", "{dstfilename}{objext}"); setMainValue ("stdlinkdstfilename", "{dstfilename}{z80outext}"); setMainValue ("z80extraobj", (s = joinStrSet (relFilesSet))); Safe_free ((void *) s); dbuf_init (&dbuf, 128); dbuf_printf (&dbuf, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc); setMainValue ("z80bases", dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); /* For the old register allocator (with the new one we decide to omit the frame pointer for each function individually) */ if (!IS_GB && options.omitFramePtr) port->stack.call_overhead = 2; }