Fixed github sdcc-gas issues #1, #2 and #4

Issue #1 was caused because code_name and data_name had been incorrectly
defined as const-qualified pointers, but this must be an exception for
the z80 backend, as stated by the comments.

Issue #2 has been solved by removing the --gas switch from SDCCmain.c,
renaming it to "--asm=" (as requested by PKK) and moved to STM8's main.c,
so the option is limited to those targets supporting it.

Issue #4 was because of SDCCglue.c, that generated local labels using
"!labeldef" instead of "!slabeldef", causing those __str_%d labels to be
printed as "__str_%d::" (the double colons stand for globa label according
to asxxx documentation) instead of "__str_%d":".

I ran the regression tests and most of them passed, but "wchar" returned another
"Multiple definition of..." error that I cannot explain so far. It is better than
nothing, though.
This commit is contained in:
Xavi Del Campo 2019-11-06 04:10:53 +01:00
parent 0290d8bd12
commit cf1d3aec55
10 changed files with 99 additions and 82 deletions

View File

@ -413,7 +413,7 @@ static const ASM_MAPPING _gas_mapping[] = {
{"areadata", ".section %s"},
{"areahome", ".section %s"},
{"ascii", ".ascii \"%s\""},
{"comm", ".comm %s, %d, %d"},
{"comm", ".comm %s, %d"},
{"local", ".local %s"},
{"db", ".byte"},
{"dbs", ".byte %s"},
@ -476,8 +476,8 @@ static const ASM_MAPPING _asxxxx_mapping[] = {
{"immedword", "#0x%04x"},
{"immedbyte", "#0x%02x"},
{"hashedstr", "#%s"},
{"lsbimmeds", "#<(%s)"},
{"msbimmeds", "#>(%s)"},
{"lsbimmeds", "#<%s"},
{"msbimmeds", "#>%s"},
{"module", ".module %s"},
{"global", ".globl %s"},
{"fileprelude", ""},
@ -529,8 +529,8 @@ static const ASM_MAPPING _asxxxx_smallpdk_mapping[] = {
{"immedword", "#0x%04x"},
{"immedbyte", "#0x%02x"},
{"hashedstr", "#%s"},
{"lsbimmeds", "#<(%s)"},
{"msbimmeds", "#>(%s)"},
{"lsbimmeds", "#<%s"},
{"msbimmeds", "#>%s"},
{"module", ".module %s"},
{"global", ".globl %s"},
{"fileprelude", ""},

View File

@ -672,7 +672,7 @@ resolveSymbols (ast * tree)
/* If entering a block with symbols defined, mark the symbols in-scope */
/* before continuing down the tree, and mark them out-of-scope again */
/* on the way back up */
/* on the way back up */
if (tree->type == EX_OP && tree->opval.op == BLOCK && tree->values.sym)
{
symbol * sym = tree->values.sym;
@ -691,7 +691,7 @@ resolveSymbols (ast * tree)
}
return tree;
}
resolveChildren:
resolveSymbols (tree->left);
resolveSymbols (tree->right);
@ -1176,7 +1176,7 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast * rootValue)
ps->implicit = 1;
lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (ps)));
lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
rast = decorateType (resolveSymbols (createIval (lAst, ps->type, NULL, rast, rootValue, 1)), RESULT_TYPE_NONE);
rast = decorateType (resolveSymbols (createIval (lAst, ps->type, NULL, rast, rootValue, 1)), RESULT_TYPE_NONE);
}
/* initialize this field */
@ -1389,7 +1389,7 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast * rootVal)
else
c = SPEC_CVAL (iexpr->etype).v_char32[symsize];
if (options.std_c99 && c == '\0' && size == symsize + 1)
{
{
if (!options.lessPedantic)
werrorfl (iexpr->filename, iexpr->lineno, W_STRING_CANNOT_BE_TERMINATED, name);
}
@ -1763,7 +1763,7 @@ processBlockVars (ast * tree, int *stack, int action)
sym = sym->next;
}
}
return tree;
}
@ -2459,7 +2459,7 @@ isInitiallyTrue (ast *initExpr, ast * condExpr)
return TRUE;
if (!initExpr)
return FALSE;
/* first check the initExpr */
if (IS_AST_OP (initExpr) && initExpr->opval.op == '=' && /* is assignment */
IS_AST_SYM_VALUE (initExpr->left))
@ -2494,7 +2494,7 @@ isInitiallyTrue (ast *initExpr, ast * condExpr)
return FALSE;
/* Replace the symbol with its initial value and see if the condition */
/* simplifies to a non-zero (TRUE) literal value */
/* simplifies to a non-zero (TRUE) literal value */
condExpr = copyAst (condExpr);
if (replLoopSymByVal (condExpr, sym, AST_VALUE (initExpr)))
{
@ -2558,7 +2558,7 @@ createDoFor (symbol * trueLabel, symbol * continueLabel, symbol * falseLabel,
}
else
loopExpr = createLabel (continueLabel, loopExpr);
/* now start putting them together */
forTree = newNode (NULLOP, initExpr, forBody);
forTree = newNode (NULLOP, forTree, loopExpr);
@ -2644,8 +2644,8 @@ getResultTypeFromType (sym_link * type)
/* BOOL and single bit BITFIELD are not interchangeable!
* There must be a cast to do this safely, in which case
* the previous IS_BOOLEAN test will handle it.
* the previous IS_BOOLEAN test will handle it.
if (blen <= 1)
return RESULT_TYPE_BOOL;
*/
@ -2916,7 +2916,7 @@ void
checkPtrCast (sym_link *newType, sym_link *orgType, bool implicit, bool orgIsNullPtrConstant)
{
int errors = 0;
if (IS_ARRAY (orgType))
{
value *val;
@ -2969,7 +2969,7 @@ checkPtrCast (sym_link *newType, sym_link *orgType, bool implicit, bool orgIsNul
}
else if (IS_GENPTR (newType) && IS_VOID (newType->next)) // cast to void* is always allowed
{
if (IS_FUNCPTR (orgType))
if (IS_FUNCPTR (orgType))
errors += werror (FUNCPTRSIZE > GPTRSIZE ? E_INCOMPAT_PTYPES : W_INCOMPAT_PTYPES);
}
else if (IS_GENPTR (orgType) && IS_VOID (orgType->next)) // cast from void* is always allowed - as long as we cast to a pointer to an object type
@ -3305,7 +3305,7 @@ rewriteAstNodeOp (ast *tree, int op, ast *left, ast *right)
tree->left = left;
tree->right = right;
tree->decorated = 0;
rewriteAstJoinSideEffects (tree, oLeft, oRight);
}
@ -3325,7 +3325,7 @@ rewriteAstNodeVal (ast *tree, value *val)
tree->right = NULL;
TETYPE (tree) = getSpec (TTYPE (tree) = tree->opval.val->type);
tree->decorated = 0;
rewriteAstJoinSideEffects (tree, oLeft, oRight);
}
@ -3805,7 +3805,7 @@ decorateType (ast *tree, RESULT_TYPE resultType)
if (otree != tree)
return decorateType (otree, RESULT_TYPE_NONE);
/* if right is a literal and has the same size with left,
/* if right is a literal and has the same size with left,
then also sync their signess to avoid unecessary cast */
if (IS_LITERAL (RTYPE (tree)) && getSize (RTYPE (tree)) == getSize (LTYPE (tree)))
SPEC_USIGN (RTYPE (tree)) = SPEC_USIGN (LTYPE (tree));
@ -4021,7 +4021,7 @@ decorateType (ast *tree, RESULT_TYPE resultType)
}
}
/* if right is a literal and has the same size with left,
/* if right is a literal and has the same size with left,
then also sync their signess to avoid unecessary cast */
if (IS_LITERAL (RTYPE (tree)) && getSize (RTYPE (tree)) == getSize (LTYPE (tree)))
SPEC_USIGN (RTYPE (tree)) = SPEC_USIGN (LTYPE (tree));
@ -5320,7 +5320,7 @@ decorateType (ast *tree, RESULT_TYPE resultType)
if (IS_LITERAL (LTYPE (tree)))
{
ast * heir;
++noAlloc;
tree->right = decorateType (tree->right, resultTypeProp);
--noAlloc;
@ -5329,7 +5329,7 @@ decorateType (ast *tree, RESULT_TYPE resultType)
heir = tree->right->left;
else
heir = tree->right->right;
heir = decorateType (heir, resultTypeProp);
if (IS_LITERAL (TETYPE (heir)))
TTYPE (heir) = valRecastLitVal (TTYPE (tree->right), valFromType (TETYPE (heir)))->type;
@ -5423,7 +5423,7 @@ decorateType (ast *tree, RESULT_TYPE resultType)
werror (E_NO_MATCH_IN_GENERIC);
goto errorTreeReturn;
}
tree = found_expr;
}
return tree;
@ -6323,7 +6323,7 @@ createFor (symbol * trueLabel, symbol * continueLabel, symbol * falseLabel,
/* attach condition label to condition */
condExpr = createLabel (condLabel, condExpr);
/* attach continue to forLoop expression & attach */
/* goto the forcond @ and of loopExpression */
loopExpr = newNode (NULLOP, loopExpr, newNode (GOTO, newAst_VALUE (symbolVal (condLabel)), NULL));
@ -6339,7 +6339,7 @@ createFor (symbol * trueLabel, symbol * continueLabel, symbol * falseLabel,
forTree = newNode (NULLOP, initExpr, condExpr);
forTree = newNode (NULLOP, forTree, forBody);
forTree = newNode (NULLOP, forTree, loopExpr);
/* the break label is already in the tree as a sibling */
/* to the original FOR node this tree is replacing */
return forTree;

View File

@ -35,8 +35,7 @@ symbol *interrupts[INTNO_MAX + 1];
static void emit_ds_comm( struct dbuf_s *oBuf,
const char *name,
unsigned int size,
unsigned int alignment);
unsigned int size);
void printIval (symbol *, sym_link *, initList *, struct dbuf_s *, bool check);
set *publics = NULL; /* public variables */
@ -124,22 +123,20 @@ aopLiteral (value *val, int offset)
static void
emitDebugSym (struct dbuf_s *oBuf, symbol * sym)
{
{
if (sym->level && sym->localof) /* symbol scope is local */
{
dbuf_printf (oBuf, "L%s.%s$", moduleName, sym->localof->name);
}
else if (IS_STATIC (sym->etype)) /* symbol scope is file */
{
dbuf_printf (oBuf, "F%s$", moduleName);
}
else /* symbol scope is global */
{
dbuf_printf (oBuf, "G$");
}
if (sym->level && sym->localof) /* symbol scope is local */
{
dbuf_printf (oBuf, "L%s.%s$", moduleName, sym->localof->name);
}
else if (IS_STATIC (sym->etype)) /* symbol scope is file */
{
dbuf_printf (oBuf, "F%s$", moduleName);
}
else /* symbol scope is global */
{
dbuf_printf (oBuf, "G$");
}
dbuf_printf (oBuf, "%s$%ld_%ld$%d", sym->name, sym->level / LEVEL_UNIT, sym->level % LEVEL_UNIT, sym->block);
}
dbuf_printf (oBuf, "%s$%ld_%ld$%d", sym->name, sym->level / LEVEL_UNIT, sym->level % LEVEL_UNIT, sym->block);
}
/*-----------------------------------------------------------------*/
@ -400,10 +397,12 @@ emitRegularMap (memmap *map, bool addPublics, bool arFlag)
else
if (options.gasOutput)
dbuf_tprintf (&map->oBuf, "!global\n", sym->rname);
else if (IS_STATIC (sym->etype))
dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
else
dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
emit_ds_comm(&map->oBuf, sym->rname, size & 0xffff, 1/* TBD */);
emit_ds_comm(&map->oBuf, sym->rname, size & 0xffff);
}
}
@ -1566,7 +1565,7 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s *oBu
{
if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
{
dbuf_tprintf (oBuf, "\t!lsbimmeds", val->name);
dbuf_tprintf (oBuf, "\tret !lsbimmeds", val->name);
dbuf_printf (oBuf, IN_CODESPACE (SPEC_OCLS (val->etype)) ? "\tret #>(%s + 0x8000)\n" : "\tret #0\n", val->name);
}
else if (port->use_dw_for_init)
@ -2008,7 +2007,10 @@ emitStaticSeg (memmap *map, struct dbuf_s *oBuf)
else
dbuf_tprintf(&code->oBuf, "\t!area\n", options.const_seg);
dbuf_tprintf (oBuf, "!labeldef\n", sym->rname);
if (IS_STATIC (sym->etype))
dbuf_tprintf (oBuf, "!slabeldef\n", sym->rname);
else
dbuf_tprintf (oBuf, "!labeldef\n", sym->rname);
if (IS_CHAR (sym->type->next))
printChar (oBuf, SPEC_CVAL (sym->etype).v_char, size);
@ -2028,7 +2030,7 @@ emitStaticSeg (memmap *map, struct dbuf_s *oBuf)
else
dbuf_printf (oBuf, "%s:\n", sym->rname);
emit_ds_comm(oBuf, sym->rname, size & 0xffff, 1/* TBD */);
emit_ds_comm(oBuf, sym->rname, size & 0xffff);
}
}
}
@ -2086,7 +2088,7 @@ emitMaps (void)
emitRegularMap (code, TRUE, FALSE);
if (options.const_seg)
dbuf_tprintf (&code->oBuf, "\t!area\n", CONST_NAME);
dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
emitStaticSeg (statsg, &code->oBuf);
if (port->genXINIT)
@ -2096,7 +2098,7 @@ emitMaps (void)
}
if (initializer)
{
dbuf_tprintf (&code->oBuf, "\t!area\n", INITIALIZER_NAME);
dbuf_tprintf (&code->oBuf, "\t!area\n", options.gasOutput ? INITIALIZER_NAME : initializer->sname);
emitStaticSeg (initializer, &code->oBuf);
}
dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
@ -2228,7 +2230,7 @@ emitOverlay (struct dbuf_s *aBuf)
if (elementsInSet (ovrset))
{
/* output the area information */
dbuf_printf (aBuf, "\t!area\t%s\n", port->mem.overlay_name); /* MOF */
dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name); /* MOF */
}
for (sym = setFirstItem (ovrset); sym; sym = setNextItem (ovrset))
@ -2293,7 +2295,7 @@ emitOverlay (struct dbuf_s *aBuf)
else
dbuf_tprintf (aBuf, "!slabeldef\n", sym->rname);
emit_ds_comm(aBuf, sym->rname, getSize (sym->type) & 0xffff, 1/* TBD */);
emit_ds_comm(aBuf, sym->rname, getSize (sym->type) & 0xffff);
}
}
}
@ -2523,17 +2525,17 @@ glue (void)
/* create the stack segment MOF */
if (mainf && IFFUNC_HASBODY (mainf->type))
{
const unsigned int size = 1;
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; Stack segment in internal ram \n");
fprintf (asmFile, "%s", iComments2);
if (!options.gasOutput)
{
const unsigned int size = 1;
tfprintf(asmFile, "\t!area\n", "SSEG");
tfprintf(asmFile, "\t!ds\n\n", size);
tfprintf(asmFile, "\t__start__stack:\n");
tfprintf(asmFile, "\t!ds\n\n", size);
}
}
@ -2714,7 +2716,7 @@ glue (void)
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; code\n");
fprintf (asmFile, "%s", iComments2);
tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
tfprintf (asmFile, "\t!areacode\n", options.code_seg);
dbuf_write_and_destroy (&code->oBuf, asmFile);
if (port->genAssemblerEnd)
@ -2761,11 +2763,10 @@ isTargetKeyword (const char *s)
static void emit_ds_comm( struct dbuf_s *const oBuf,
const char *const name,
const unsigned int size,
const unsigned int alignment)
const unsigned int size)
{
if (options.gasOutput)
dbuf_tprintf(oBuf, "\t!comm\n", name, size, alignment);
dbuf_tprintf(oBuf, "\t!comm\n", name, size);
else
dbuf_tprintf(oBuf, "\t!ds\n", size);
}

View File

@ -175,7 +175,6 @@ static const OPTION optionsTable[] = {
{'M', NULL, NULL, "Preprocessor option"},
{'W', NULL, NULL, "Pass through options to the pre-processor (p), assembler (a) or linker (l)"},
{'S', NULL, &noAssemble, "Compile only; do not assemble or link"},
{0 , "--gas", &options.gasOutput, "Compile in GAS (GNU Assembler) format."},
{0 , OPTION_FUNCTION_SECTIONS, &options.function_sections, "Place each function into a separate section. Useful for link-time dead code elimination."},
{0 , OPTION_DATA_SECTIONS, &options.data_sections, "Place each static variable into a separate section. Useful for link-time dead code elimination."},
{'c', "--compile-only", &options.cc_only, "Compile and assemble, but do not link"},

View File

@ -145,7 +145,7 @@ initMem ()
DEBUG-NAME - 'C'
POINTER-TYPE - CPOINTER
*/
code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, DATA_NAME, 'C', CPOINTER);
code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
/* home segment ;
SFRSPACE - NO

View File

@ -50,8 +50,8 @@ extern FILE *junkFile;
#define ISTACK_NAME port->mem.istack_name
#define CODE_NAME (options.gasOutput ? ".text" : port->mem.code_name)
#define DATA_NAME (options.gasOutput ? ".bss" : port->mem.data_name)
#define INITIALIZED_NAME port->mem.data_name
#define INITIALIZER_NAME (options.gasOutput ? ".data" : port->mem.data_name)
#define INITIALIZED_NAME (options.gasOutput ? port->mem.data_name : port->mem.initialized_name)
#define INITIALIZER_NAME (options.gasOutput ? ".data" : port->mem.initializer_name)
#define IDATA_NAME port->mem.idata_name
#define PDATA_NAME port->mem.pdata_name
#define XDATA_NAME port->mem.xdata_name

View File

@ -206,17 +206,17 @@ _hc08_genAssemblerPreamble (FILE * of)
symbol *mainExists=newSymbol("main", 0);
mainExists->block=0;
fprintf (of, "\t.area %s\n",HOME_NAME);
fprintf (of, "\t.area GSINIT0 (CODE)\n");
fprintf (of, "\t.area %s\n",port->mem.static_name);
fprintf (of, "\t.area %s\n",port->mem.post_static_name);
fprintf (of, "\t.area %s\n",CODE_NAME);
fprintf (of, "\t.area %s\n",port->mem.xinit_name);
fprintf (of, "\t.area %s\n",port->mem.const_name);
fprintf (of, "\t.area %s\n",port->mem.data_name);
fprintf (of, "\t.area %s\n",port->mem.overlay_name);
fprintf (of, "\t.area %s\n",port->mem.xdata_name);
fprintf (of, "\t.area %s\n",port->mem.xidata_name);
tfprintf (of, "\t!area\n",HOME_NAME);
tfprintf (of, "\t!area\n", "GSINIT0 (CODE)");
tfprintf (of, "\t!area\n",port->mem.static_name);
tfprintf (of, "\t!area\n",port->mem.post_static_name);
tfprintf (of, "\t!area\n",CODE_NAME);
tfprintf (of, "\t!area\n",port->mem.xinit_name);
tfprintf (of, "\t!area\n",port->mem.const_name);
tfprintf (of, "\t!area\n",port->mem.data_name);
tfprintf (of, "\t!area\n",port->mem.overlay_name);
tfprintf (of, "\t!area\n",port->mem.xdata_name);
tfprintf (of, "\t!area\n",port->mem.xidata_name);
if ((mainExists=findSymWithLevel(SymbolTab, mainExists)))
{
@ -592,7 +592,7 @@ hc08_instructionSize(const char *inst, const char *op1, const char *op2)
int size;
long offset;
char * endnum = NULL;
opcode = bsearch (inst, hc08opcodeDataTable,
sizeof(hc08opcodeDataTable)/sizeof(hc08opcodedata),
sizeof(hc08opcodedata), hc08_opcodeCompare);
@ -603,15 +603,15 @@ hc08_instructionSize(const char *inst, const char *op1, const char *op2)
{
case HC08OP_INH: /* Inherent addressing mode */
return 1;
case HC08OP_BSC: /* Bit set/clear direct addressing mode */
case HC08OP_BR: /* Branch (1 byte signed offset) */
case HC08OP_IM1: /* 1 byte immediate addressing mode */
return 2;
case HC08OP_BTB: /* Bit test direct addressing mode and branch */
return 3;
case HC08OP_RMW: /* read/modify/write instructions */
if (!op2[0]) /* if not ,x or ,sp must be direct addressing mode */
return 2;
@ -620,7 +620,7 @@ hc08_instructionSize(const char *inst, const char *op1, const char *op2)
if (op2[0] == 'x') /* if ,x with offset */
return 2;
return 3; /* Otherwise, must be ,sp with offset */
case HC08OP_STD: /* standard instruction */
if (!op2[0])
{

View File

@ -384,9 +384,9 @@ pic14emitOverlay (struct dbuf_s * aBuf)
/* I don't think this applies to us. We are using gpasm. CRF */
dbuf_printf (aBuf, ";\t.area _DUMMY\n");
dbuf_tprintf (aBuf, ";\t!area\n", "_DUMMY");
/* output the area informtion */
dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
dbuf_tprintf (aBuf, ";\t!area\t\n", port->mem.overlay_name); /* MOF */
}
for (sym = setFirstItem (ovrset); sym;

View File

@ -217,8 +217,8 @@ typedef struct
* due to ugly implementation in gbz80 target;
* this should be fixed in src/z80/main.c (borutr)
*/
const char *const code_name;
const char *const data_name;
const char *code_name;
const char *data_name;
const char *const idata_name;
const char *const pdata_name;
const char *const xdata_name;

View File

@ -36,6 +36,7 @@
#define OPTION_CODE_SEG "--codeseg"
#define OPTION_CONST_SEG "--constseg"
#define OPTION_ELF "--out-fmt-elf"
#define OPTION_ASM "--asm="
extern DEBUGFILE dwarf2DebugFile;
extern int dwarf2FinalizeFile(FILE *);
@ -46,6 +47,7 @@ static OPTION stm8_options[] = {
{0, OPTION_CODE_SEG, &options.code_seg, "<name> use this name for the code segment", CLAT_STRING},
{0, OPTION_CONST_SEG, &options.const_seg, "<name> use this name for the const segment", CLAT_STRING},
{0, OPTION_ELF, NULL, "Output executable in ELF format (deprecated)"},
{0, OPTION_ASM, NULL, "Define assembler name (asxxxx/gas)"},
{0}
};
@ -179,6 +181,21 @@ stm8_parseOptions (int *pargc, char **argv, int *i)
debugFile = &dwarf2DebugFile;
return TRUE;
}
else if (!strncmp (argv[*i], OPTION_ASM, sizeof (OPTION_ASM) - 1))
{
char *asmblr = getStringArg (OPTION_ASM, argv, i, *pargc);
if (!strcmp (asmblr, "gas"))
{
options.gasOutput = true;
return TRUE;
}
else if (!strcmp (asmblr, "asxxxx"))
{
options.gasOutput = false;
return TRUE;
}
}
return FALSE;
}