mirror of
https://github.com/cc65/cc65.git
synced 2024-06-09 22:29:35 +00:00
Merge branch 'master' into ca65_long_jsr_jmp_rts
This commit is contained in:
commit
12fc59351e
|
@ -125,6 +125,7 @@ Long options:
|
||||||
--target sys Set the target system
|
--target sys Set the target system
|
||||||
--verbose Increase verbosity
|
--verbose Increase verbosity
|
||||||
--version Print the assembler version
|
--version Print the assembler version
|
||||||
|
--warnings-as-errors Treat warnings as errors
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
|
@ -359,6 +360,13 @@ Here is a description of all the command line options:
|
||||||
warning level is 1, and it would probably be silly to set it to
|
warning level is 1, and it would probably be silly to set it to
|
||||||
something lower.
|
something lower.
|
||||||
|
|
||||||
|
|
||||||
|
<label id="option--warnings-as-errors">
|
||||||
|
<tag><tt>--warnings-as-errors</tt></tag>
|
||||||
|
|
||||||
|
An error will be generated if any warnings were produced.
|
||||||
|
|
||||||
|
|
||||||
</descrip>
|
</descrip>
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
|
@ -2019,7 +2027,7 @@ Here's a list of all control commands and a description, what they do:
|
||||||
|
|
||||||
<sect1><tt>.A16</tt><label id=".A16"><p>
|
<sect1><tt>.A16</tt><label id=".A16"><p>
|
||||||
|
|
||||||
Valid only in 65816 mode. Switch the accumulator to 16 bit.
|
Valid only in 65816 mode. Assume the accumulator is 16 bit.
|
||||||
|
|
||||||
Note: This command will not emit any code, it will tell the assembler to
|
Note: This command will not emit any code, it will tell the assembler to
|
||||||
create 16 bit operands for immediate accumulator addressing mode.
|
create 16 bit operands for immediate accumulator addressing mode.
|
||||||
|
@ -2029,7 +2037,7 @@ Here's a list of all control commands and a description, what they do:
|
||||||
|
|
||||||
<sect1><tt>.A8</tt><label id=".A8"><p>
|
<sect1><tt>.A8</tt><label id=".A8"><p>
|
||||||
|
|
||||||
Valid only in 65816 mode. Switch the accumulator to 8 bit.
|
Valid only in 65816 mode. Assume the accumulator is 8 bit.
|
||||||
|
|
||||||
Note: This command will not emit any code, it will tell the assembler to
|
Note: This command will not emit any code, it will tell the assembler to
|
||||||
create 8 bit operands for immediate accu addressing mode.
|
create 8 bit operands for immediate accu addressing mode.
|
||||||
|
@ -2112,15 +2120,15 @@ Here's a list of all control commands and a description, what they do:
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
the assembler will force a segment alignment to the least common multiple of
|
the assembler will force a segment alignment to the least common multiple of
|
||||||
15, 18 and 251 - which is 22590. To protect the user against errors, the
|
15, 18 and 251 - which is 22590. To protect the user against errors, when the
|
||||||
assembler will issue a warning when the combined alignment exceeds 256. The
|
combined alignment is larger than the explicitly requested alignments,
|
||||||
command line option <tt><ref id="option--large-alignment"
|
the assembler will issue a warning if it also exceeds 256. The command line
|
||||||
name="--large-alignment"></tt> will disable this warning.
|
option <tt><ref id="option--large-alignment" name="--large-alignment"></tt>
|
||||||
|
will disable this warning.
|
||||||
|
|
||||||
Please note that with alignments that are a power of two (which were the
|
Please note that with only alignments that are a power of two, a warning will
|
||||||
only alignments possible in older versions of the assembler), the problem is
|
never occur, because the least common multiple of powers to the same base is
|
||||||
less severe, because the least common multiple of powers to the same base is
|
always simply the larger one.
|
||||||
always the larger one.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3053,7 +3061,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
|
||||||
|
|
||||||
<sect1><tt>.I16</tt><label id=".I16"><p>
|
<sect1><tt>.I16</tt><label id=".I16"><p>
|
||||||
|
|
||||||
Valid only in 65816 mode. Switch the index registers to 16 bit.
|
Valid only in 65816 mode. Assume the index registers are 16 bit.
|
||||||
|
|
||||||
Note: This command will not emit any code, it will tell the assembler to
|
Note: This command will not emit any code, it will tell the assembler to
|
||||||
create 16 bit operands for immediate operands.
|
create 16 bit operands for immediate operands.
|
||||||
|
@ -3064,7 +3072,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
|
||||||
|
|
||||||
<sect1><tt>.I8</tt><label id=".I8"><p>
|
<sect1><tt>.I8</tt><label id=".I8"><p>
|
||||||
|
|
||||||
Valid only in 65816 mode. Switch the index registers to 8 bit.
|
Valid only in 65816 mode. Assume the index registers are 8 bit.
|
||||||
|
|
||||||
Note: This command will not emit any code, it will tell the assembler to
|
Note: This command will not emit any code, it will tell the assembler to
|
||||||
create 8 bit operands for immediate operands.
|
create 8 bit operands for immediate operands.
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
|
|
||||||
<abstract>
|
<abstract>
|
||||||
Internal details of cc65 code generation,
|
Internal details of cc65 code generation,
|
||||||
such as calling assembly functions from C.
|
such as the expected linker configuration,
|
||||||
|
and calling assembly functions from C.
|
||||||
</abstract>
|
</abstract>
|
||||||
|
|
||||||
<!-- Table of contents -->
|
<!-- Table of contents -->
|
||||||
|
@ -16,6 +17,76 @@ such as calling assembly functions from C.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect>Linker configuration<p>
|
||||||
|
|
||||||
|
The C libraries and code generation depend directly on a suitable linker configuration.
|
||||||
|
There are premade configuration files in the <tt/cfg// directory, normally chosen by the
|
||||||
|
linker's selected target. These can be used as a template for customization.
|
||||||
|
|
||||||
|
The C libraries depend on several special segments to be defined in your linker configuration.
|
||||||
|
Generated code will also use some of them by default.
|
||||||
|
Some platform libraries have additional special segments.
|
||||||
|
|
||||||
|
Memory areas are free to be defined in a way that is appropriate to each platform,
|
||||||
|
and the segments they contain are used as a layer of semantics and abstraction,
|
||||||
|
to allow much of the reorganization to be done with the linker config,
|
||||||
|
rather than requiring platform-specific code source changes.
|
||||||
|
|
||||||
|
<sect1><tt/ZEROPAGE/ segment<p>
|
||||||
|
|
||||||
|
Used by the C library and generated code for efficient internal and temporary state storage,
|
||||||
|
also called "pseudo-registers".
|
||||||
|
|
||||||
|
<sect1><tt/STARTUP/ segment<p>
|
||||||
|
|
||||||
|
Used by each platform instance of the C library in <tt/crt0.s/ to contain the entry point
|
||||||
|
of the program.
|
||||||
|
|
||||||
|
The startup module will export <tt/__STARTUP__ : absolute = 1/ to force the linker to
|
||||||
|
always include <tt/crt0.s/ from the library.
|
||||||
|
|
||||||
|
<sect1><tt/CODE/ segment<p>
|
||||||
|
|
||||||
|
The default segment for generated code, and most C library code will be located here.
|
||||||
|
|
||||||
|
Use <tt/#pragma code-name/ to redirect generated code to another segment.
|
||||||
|
|
||||||
|
<sect1><tt/BSS/ segment<p>
|
||||||
|
|
||||||
|
Used for uninitialized variables.
|
||||||
|
Originally an acronym for "Block Started by Symbol", but the meaning of this is now obscure.
|
||||||
|
|
||||||
|
Use <tt/#pragma bss-name/ to redirect uninitialized variables to another segment.
|
||||||
|
|
||||||
|
<sect1><tt/DATA/ segment<p>
|
||||||
|
|
||||||
|
Used for initialized variables.
|
||||||
|
|
||||||
|
On some platforms, this may be initialized as part of the program loading process,
|
||||||
|
but on others it may have a separate <tt/LOAD/ and <tt/RUN/ address,
|
||||||
|
allowing <tt/copydata/ to copy the initialization from the loaded location
|
||||||
|
into their run destination in RAM.
|
||||||
|
|
||||||
|
Use <tt/#pragma data-name/ to redirect initialized variables to another segment.
|
||||||
|
|
||||||
|
<sect1><tt/RODATA/ segment<p>
|
||||||
|
|
||||||
|
Used for read-only (constant) data.
|
||||||
|
|
||||||
|
Use <tt/#pragma rodata-name/ to redirect constant data to another segment.
|
||||||
|
|
||||||
|
<sect1><tt/FEATURES/ table<p>
|
||||||
|
|
||||||
|
This currently defines table locations for the <tt/CONDES/
|
||||||
|
constructor, destructor, and interruptor features.
|
||||||
|
Some platform libraries use these.
|
||||||
|
|
||||||
|
The constructors will be called with <tt/initlib/ at startup,
|
||||||
|
and the destructors with <tt/donelib/ at program exit.
|
||||||
|
Interruptors are called with <tt/callirq/.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<sect>Calling assembly functions from C<p>
|
<sect>Calling assembly functions from C<p>
|
||||||
|
|
||||||
<sect1>Calling conventions<p>
|
<sect1>Calling conventions<p>
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
Contains hints on creating the most effective code with cc65.
|
Contains hints on creating the most effective code with cc65.
|
||||||
|
|
||||||
<tag><htmlurl url="cc65-intern.html" name="cc65-intern.html"></tag>
|
<tag><htmlurl url="cc65-intern.html" name="cc65-intern.html"></tag>
|
||||||
Describes internal details of cc65, such as calling conventions.
|
Describes internal details of cc65: linker configuration, calling conventions, etc.
|
||||||
|
|
||||||
<tag><htmlurl url="using-make.html" name="using-make.html"></tag>
|
<tag><htmlurl url="using-make.html" name="using-make.html"></tag>
|
||||||
Build programs, using the GNU Make utility.
|
Build programs, using the GNU Make utility.
|
||||||
|
|
|
@ -90,6 +90,7 @@ Long options:
|
||||||
--start-group Start a library group
|
--start-group Start a library group
|
||||||
--target sys Set the target system
|
--target sys Set the target system
|
||||||
--version Print the linker version
|
--version Print the linker version
|
||||||
|
--warnings-as-errors Treat warnings as errors
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
|
@ -330,6 +331,13 @@ Here is a description of all of the command-line options:
|
||||||
directory, in the list of directories specified using <tt/--obj-path/, in
|
directory, in the list of directories specified using <tt/--obj-path/, in
|
||||||
directories given by environment variables, and in a built-in default directory.
|
directories given by environment variables, and in a built-in default directory.
|
||||||
|
|
||||||
|
|
||||||
|
<label id="option--warnings-as-errors">
|
||||||
|
<tag><tt>--warnings-as-errors</tt></tag>
|
||||||
|
|
||||||
|
An error will be generated if any warnings were produced.
|
||||||
|
|
||||||
|
|
||||||
</descrip>
|
</descrip>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ unsigned char LargeAlignment = 0; /* Don't warn about large alignments */
|
||||||
unsigned char RelaxChecks = 0; /* Relax a few assembler checks */
|
unsigned char RelaxChecks = 0; /* Relax a few assembler checks */
|
||||||
unsigned char StringEscapes = 0; /* Allow C-style escapes in strings */
|
unsigned char StringEscapes = 0; /* Allow C-style escapes in strings */
|
||||||
unsigned char LongJsrJmpRts = 0; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
|
unsigned char LongJsrJmpRts = 0; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
|
||||||
|
unsigned char WarningsAsErrors = 0; /* Error if any warnings */
|
||||||
|
|
||||||
/* Emulation features */
|
/* Emulation features */
|
||||||
unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */
|
unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */
|
||||||
|
|
|
@ -70,6 +70,7 @@ extern unsigned char LargeAlignment; /* Don't warn about large alignments
|
||||||
extern unsigned char RelaxChecks; /* Relax a few assembler checks */
|
extern unsigned char RelaxChecks; /* Relax a few assembler checks */
|
||||||
extern unsigned char StringEscapes; /* Allow C-style escapes in strings */
|
extern unsigned char StringEscapes; /* Allow C-style escapes in strings */
|
||||||
extern unsigned char LongJsrJmpRts; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
|
extern unsigned char LongJsrJmpRts; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
|
||||||
|
extern unsigned char WarningsAsErrors; /* Error if any warnings */
|
||||||
|
|
||||||
/* Emulation features */
|
/* Emulation features */
|
||||||
extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */
|
extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */
|
||||||
|
|
|
@ -656,6 +656,15 @@ static void OptVersion (const char* Opt attribute ((unused)),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
|
/* Generate an error if any warnings occur */
|
||||||
|
{
|
||||||
|
WarningsAsErrors = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void DoPCAssign (void)
|
static void DoPCAssign (void)
|
||||||
/* Start absolute code */
|
/* Start absolute code */
|
||||||
{
|
{
|
||||||
|
@ -919,27 +928,28 @@ int main (int argc, char* argv [])
|
||||||
{
|
{
|
||||||
/* Program long options */
|
/* Program long options */
|
||||||
static const LongOpt OptTab[] = {
|
static const LongOpt OptTab[] = {
|
||||||
{ "--auto-import", 0, OptAutoImport },
|
{ "--auto-import", 0, OptAutoImport },
|
||||||
{ "--bin-include-dir", 1, OptBinIncludeDir },
|
{ "--bin-include-dir", 1, OptBinIncludeDir },
|
||||||
{ "--cpu", 1, OptCPU },
|
{ "--cpu", 1, OptCPU },
|
||||||
{ "--create-dep", 1, OptCreateDep },
|
{ "--create-dep", 1, OptCreateDep },
|
||||||
{ "--create-full-dep", 1, OptCreateFullDep },
|
{ "--create-full-dep", 1, OptCreateFullDep },
|
||||||
{ "--debug", 0, OptDebug },
|
{ "--debug", 0, OptDebug },
|
||||||
{ "--debug-info", 0, OptDebugInfo },
|
{ "--debug-info", 0, OptDebugInfo },
|
||||||
{ "--feature", 1, OptFeature },
|
{ "--feature", 1, OptFeature },
|
||||||
{ "--help", 0, OptHelp },
|
{ "--help", 0, OptHelp },
|
||||||
{ "--ignore-case", 0, OptIgnoreCase },
|
{ "--ignore-case", 0, OptIgnoreCase },
|
||||||
{ "--include-dir", 1, OptIncludeDir },
|
{ "--include-dir", 1, OptIncludeDir },
|
||||||
{ "--large-alignment", 0, OptLargeAlignment },
|
{ "--large-alignment", 0, OptLargeAlignment },
|
||||||
{ "--list-bytes", 1, OptListBytes },
|
{ "--list-bytes", 1, OptListBytes },
|
||||||
{ "--listing", 1, OptListing },
|
{ "--listing", 1, OptListing },
|
||||||
{ "--memory-model", 1, OptMemoryModel },
|
{ "--memory-model", 1, OptMemoryModel },
|
||||||
{ "--pagelength", 1, OptPageLength },
|
{ "--pagelength", 1, OptPageLength },
|
||||||
{ "--relax-checks", 0, OptRelaxChecks },
|
{ "--relax-checks", 0, OptRelaxChecks },
|
||||||
{ "--smart", 0, OptSmart },
|
{ "--smart", 0, OptSmart },
|
||||||
{ "--target", 1, OptTarget },
|
{ "--target", 1, OptTarget },
|
||||||
{ "--verbose", 0, OptVerbose },
|
{ "--verbose", 0, OptVerbose },
|
||||||
{ "--version", 0, OptVersion },
|
{ "--version", 0, OptVersion },
|
||||||
|
{ "--warnings-as-errors", 0, OptWarningsAsErrors },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Name of the global name space */
|
/* Name of the global name space */
|
||||||
|
@ -1144,6 +1154,10 @@ int main (int argc, char* argv [])
|
||||||
SegDump ();
|
SegDump ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WarningCount > 0 && WarningsAsErrors) {
|
||||||
|
Error("Warnings as errors");
|
||||||
|
}
|
||||||
|
|
||||||
/* If we didn't have an errors, finish off the line infos */
|
/* If we didn't have an errors, finish off the line infos */
|
||||||
DoneLineInfo ();
|
DoneLineInfo ();
|
||||||
|
|
||||||
|
|
|
@ -306,7 +306,7 @@ void SegAlign (unsigned long Alignment, int FillVal)
|
||||||
ActiveSeg->Align = CombinedAlignment;
|
ActiveSeg->Align = CombinedAlignment;
|
||||||
|
|
||||||
/* Output a warning for larger alignments if not suppressed */
|
/* Output a warning for larger alignments if not suppressed */
|
||||||
if (CombinedAlignment >= LARGE_ALIGNMENT && !LargeAlignment) {
|
if (CombinedAlignment >= LARGE_ALIGNMENT && CombinedAlignment > ActiveSeg->Align && CombinedAlignment > Alignment && !LargeAlignment) {
|
||||||
Warning (0, "Combined alignment is suspiciously large (%lu)",
|
Warning (0, "Combined alignment is suspiciously large (%lu)",
|
||||||
CombinedAlignment);
|
CombinedAlignment);
|
||||||
}
|
}
|
||||||
|
|
|
@ -570,7 +570,18 @@ void SymCheck (void)
|
||||||
|
|
||||||
/* Check for open scopes */
|
/* Check for open scopes */
|
||||||
if (CurrentScope->Parent != 0) {
|
if (CurrentScope->Parent != 0) {
|
||||||
Error ("Local scope was not closed");
|
if (CurrentScope->Label) {
|
||||||
|
/* proc has a label indicating the line it was opened. */
|
||||||
|
LIError (&CurrentScope->Label->DefLines,
|
||||||
|
"Local proc '%s' was not closed",
|
||||||
|
GetString (CurrentScope->Name));
|
||||||
|
} else {
|
||||||
|
/* scope has no label to track a line number, uses end-of-document line instead.
|
||||||
|
** Anonymous scopes will reveal their internal automatic name.
|
||||||
|
*/
|
||||||
|
Error ("Local scope '%s' was not closed",
|
||||||
|
GetString (CurrentScope->Name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First pass: Walk through all symbols, checking for undefined's and
|
/* First pass: Walk through all symbols, checking for undefined's and
|
||||||
|
|
|
@ -1153,6 +1153,8 @@ static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer)
|
||||||
|
|
||||||
/* Save lhs into zeropage */
|
/* Save lhs into zeropage */
|
||||||
AddStoreLhsA (D);
|
AddStoreLhsA (D);
|
||||||
|
/* AddStoreLhsA may have moved the OpIndex, recalculate insertion point to prevent label migration. */
|
||||||
|
D->IP = D->OpIndex + 1;
|
||||||
|
|
||||||
/* cmp */
|
/* cmp */
|
||||||
X = NewCodeEntry (OP65_CMP, AM65_ZP, D->ZPLo, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_CMP, AM65_ZP, D->ZPLo, 0, D->OpEntry->LI);
|
||||||
|
@ -1206,6 +1208,8 @@ static unsigned Opt_a_tosicmp (StackOpData* D)
|
||||||
/* RHS src is not directly comparable */
|
/* RHS src is not directly comparable */
|
||||||
X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
|
||||||
InsertEntry (D, X, D->Rhs.A.ChgIndex + 1);
|
InsertEntry (D, X, D->Rhs.A.ChgIndex + 1);
|
||||||
|
/* RHS insertion may have moved the OpIndex, recalculate insertion point to prevent label migration. */
|
||||||
|
D->IP = D->OpIndex + 1;
|
||||||
|
|
||||||
/* Cmp with stored RHS */
|
/* Cmp with stored RHS */
|
||||||
X = NewCodeEntry (OP65_CMP, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_CMP, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
|
||||||
|
|
|
@ -46,6 +46,17 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Statistics */
|
||||||
|
unsigned WarningCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -66,6 +77,9 @@ void Warning (const char* Format, ...)
|
||||||
fprintf (stderr, "%s: Warning: %s\n", ProgName, SB_GetConstBuf (&S));
|
fprintf (stderr, "%s: Warning: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||||
|
|
||||||
SB_Done (&S);
|
SB_Done (&S);
|
||||||
|
|
||||||
|
/* Count warnings */
|
||||||
|
++WarningCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,17 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Statistics */
|
||||||
|
extern unsigned WarningCount;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -43,19 +43,20 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* OutputName = "a.out"; /* Name of output file */
|
const char* OutputName = "a.out"; /* Name of output file */
|
||||||
unsigned OutputNameUsed = 0; /* Output name was used by %O */
|
unsigned OutputNameUsed = 0; /* Output name was used by %O */
|
||||||
|
|
||||||
unsigned ModuleId = 0; /* Id for o65 module */
|
unsigned ModuleId = 0; /* Id for o65 module */
|
||||||
|
|
||||||
/* Start address */
|
/* Start address */
|
||||||
unsigned char HaveStartAddr = 0; /* Start address not given */
|
unsigned char HaveStartAddr = 0; /* Start address not given */
|
||||||
unsigned long StartAddr = 0x200; /* Start address */
|
unsigned long StartAddr = 0x200; /* Start address */
|
||||||
|
|
||||||
unsigned char VerboseMap = 0; /* Verbose map file */
|
unsigned char VerboseMap = 0; /* Verbose map file */
|
||||||
unsigned char AllowMultDef = 0; /* Allow multiple definitions */
|
unsigned char AllowMultDef = 0; /* Allow multiple definitions */
|
||||||
unsigned char LargeAlignment = 0; /* Don't warn about large alignments */
|
unsigned char LargeAlignment = 0; /* Don't warn about large alignments */
|
||||||
|
unsigned char WarningsAsErrors = 0; /* Error if any warnings */
|
||||||
|
|
||||||
const char* MapFileName = 0; /* Name of the map file */
|
const char* MapFileName = 0; /* Name of the map file */
|
||||||
const char* LabelFileName = 0; /* Name of the label file */
|
const char* LabelFileName = 0; /* Name of the label file */
|
||||||
const char* DbgFileName = 0; /* Name of the debug file */
|
const char* DbgFileName = 0; /* Name of the debug file */
|
||||||
|
|
|
@ -44,21 +44,22 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern const char* OutputName; /* Name of output file */
|
extern const char* OutputName; /* Name of output file */
|
||||||
extern unsigned OutputNameUsed; /* Output name was used by %O */
|
extern unsigned OutputNameUsed; /* Output name was used by %O */
|
||||||
|
|
||||||
extern unsigned ModuleId; /* Id for o65 module */
|
extern unsigned ModuleId; /* Id for o65 module */
|
||||||
|
|
||||||
extern unsigned char HaveStartAddr; /* True if start address was given */
|
extern unsigned char HaveStartAddr; /* True if start address was given */
|
||||||
extern unsigned long StartAddr; /* Start address */
|
extern unsigned long StartAddr; /* Start address */
|
||||||
|
|
||||||
extern unsigned char VerboseMap; /* Verbose map file */
|
extern unsigned char VerboseMap; /* Verbose map file */
|
||||||
extern unsigned char AllowMultDef; /* Allow multiple definitions */
|
extern unsigned char AllowMultDef; /* Allow multiple definitions */
|
||||||
extern unsigned char LargeAlignment; /* Don't warn about large alignments */
|
extern unsigned char LargeAlignment; /* Don't warn about large alignments */
|
||||||
|
extern unsigned char WarningsAsErrors; /* Error if any warnings */
|
||||||
|
|
||||||
extern const char* MapFileName; /* Name of the map file */
|
extern const char* MapFileName; /* Name of the map file */
|
||||||
extern const char* LabelFileName; /* Name of the label file */
|
extern const char* LabelFileName; /* Name of the label file */
|
||||||
extern const char* DbgFileName; /* Name of the debug file */
|
extern const char* DbgFileName; /* Name of the debug file */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -559,6 +559,15 @@ static void OptVersion (const char* Opt attribute ((unused)),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
|
/* Generate an error if any warnings occur */
|
||||||
|
{
|
||||||
|
WarningsAsErrors = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptMultDef (const char* Opt attribute ((unused)),
|
static void OptMultDef (const char* Opt attribute ((unused)),
|
||||||
const char* Arg attribute ((unused)))
|
const char* Arg attribute ((unused)))
|
||||||
/* Set flag to allow multiple definitions of a global symbol */
|
/* Set flag to allow multiple definitions of a global symbol */
|
||||||
|
@ -637,6 +646,7 @@ static void ParseCommandLine(void)
|
||||||
{ "--start-group", 0, CmdlOptStartGroup },
|
{ "--start-group", 0, CmdlOptStartGroup },
|
||||||
{ "--target", 1, CmdlOptTarget },
|
{ "--target", 1, CmdlOptTarget },
|
||||||
{ "--version", 0, OptVersion },
|
{ "--version", 0, OptVersion },
|
||||||
|
{ "--warnings-as-errors", 0, OptWarningsAsErrors },
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
@ -845,6 +855,10 @@ int main (int argc, char* argv [])
|
||||||
(MemoryAreaOverflows > 1) ? 's' : ' ');
|
(MemoryAreaOverflows > 1) ? 's' : ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WarningCount > 0 && WarningsAsErrors) {
|
||||||
|
Error("Warnings as errors");
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the output file */
|
/* Create the output file */
|
||||||
CfgWriteTarget ();
|
CfgWriteTarget ();
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,9 @@ void CfgWarning (const FilePos* Pos, const char* Format, ...)
|
||||||
Warning ("%s:%u: %s",
|
Warning ("%s:%u: %s",
|
||||||
GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf));
|
GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf));
|
||||||
SB_Done (&Buf);
|
SB_Done (&Buf);
|
||||||
|
|
||||||
|
/* Count warnings */
|
||||||
|
++WarningCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ Section* ReadSection (FILE* F, ObjData* O)
|
||||||
"%lu. Last module requiring alignment was '%s'.",
|
"%lu. Last module requiring alignment was '%s'.",
|
||||||
GetString (Name), Alignment, MAX_ALIGNMENT,
|
GetString (Name), Alignment, MAX_ALIGNMENT,
|
||||||
GetObjFileName (O));
|
GetObjFileName (O));
|
||||||
} else if (Alignment >= LARGE_ALIGNMENT && !LargeAlignment) {
|
} else if (Alignment >= LARGE_ALIGNMENT && Alignment > S->Alignment && Alignment > Sec->Alignment && !LargeAlignment) {
|
||||||
Warning ("Combined alignment for segment '%s' is suspiciously "
|
Warning ("Combined alignment for segment '%s' is suspiciously "
|
||||||
"large (%lu). Last module requiring alignment was '%s'.",
|
"large (%lu). Last module requiring alignment was '%s'.",
|
||||||
GetString (Name), Alignment, GetObjFileName (O));
|
GetString (Name), Alignment, GetObjFileName (O));
|
||||||
|
|
40
test/val/bug1989.c
Normal file
40
test/val/bug1989.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
/* bug #1989 - OptStackOps Opt_a_toscmpbool bypassed a comparison, discovered in 544a49c */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
unsigned char i,r,j;
|
||||||
|
|
||||||
|
void fail() // for the r=0 case, the == comparison was getting jumped over by OptStackOps
|
||||||
|
{
|
||||||
|
if ((i & 0x1f) == (r ? 0 : 16)) j -=8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pass()
|
||||||
|
{
|
||||||
|
if ((i & 0x1f) == (unsigned char)(r ? 0 : 16)) j -= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test(unsigned char ti, unsigned char tr, unsigned char tj)
|
||||||
|
{
|
||||||
|
unsigned char rj;
|
||||||
|
i = ti;
|
||||||
|
r = tr;
|
||||||
|
j = tj;
|
||||||
|
pass();
|
||||||
|
rj = j;
|
||||||
|
i = ti;
|
||||||
|
r = tr;
|
||||||
|
j = tj;
|
||||||
|
fail();
|
||||||
|
if (j != rj) exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
test( 1,0,33);
|
||||||
|
test( 0,0,33);
|
||||||
|
test( 1,1,33);
|
||||||
|
test(16,1,33);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user