Changed multi-line C comments into another style.

The left side doesn't look unbalanced.
This commit is contained in:
Greg King
2014-06-30 05:10:35 -04:00
parent 132d57f1ad
commit 0390c34e88
502 changed files with 8869 additions and 8884 deletions

View File

@@ -130,8 +130,8 @@ void ExpInsert (const char* Name, const ObjData* Module)
const ObjData* ExpFind (const char* Name)
/* Check for an identifier in the list. Return NULL if not found, otherwise
* return a pointer to the module, that exports the identifer.
*/
** return a pointer to the module, that exports the identifer.
*/
{
/* Get a pointer to the list with the symbols hash value */
HashEntry* L = HashTab [HashStr (Name) % HASHTAB_SIZE];

View File

@@ -59,8 +59,8 @@ void ExpInsert (const char* Name, const struct ObjData* Module);
const struct ObjData* ExpFind (const char* Name);
/* Check for an identifier in the list. Return NULL if not found, otherwise
* return a pointer to the module, that exports the identifer.
*/
** return a pointer to the module, that exports the identifer.
*/

View File

@@ -7,7 +7,7 @@
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@@ -84,10 +84,10 @@ void WriteVar (FILE* F, unsigned long V)
/* Write a variable sized value to the file in special encoding */
{
/* We will write the value to the file in 7 bit chunks. If the 8th bit
* is clear, we're done, if it is set, another chunk follows. This will
* allow us to encode smaller values with less bytes, at the expense of
* needing 5 bytes if a 32 bit value is written to file.
*/
** is clear, we're done, if it is set, another chunk follows. This will
** allow us to encode smaller values with less bytes, at the expense of
** needing 5 bytes if a 32 bit value is written to file.
*/
do {
unsigned char C = (V & 0x7F);
V >>= 7;
@@ -156,8 +156,8 @@ unsigned long ReadVar (FILE* F)
/* Read a variable size value from the file */
{
/* The value was written to the file in 7 bit chunks LSB first. If there
* are more bytes, bit 8 is set, otherwise it is clear.
*/
** are more bytes, bit 8 is set, otherwise it is clear.
*/
unsigned char C;
unsigned long V = 0;
unsigned Shift = 0;

View File

@@ -216,9 +216,9 @@ static void WriteIndex (void)
void LibOpen (const char* Name, int MustExist, int NeedTemp)
/* Open an existing library and a temporary copy. If MustExist is true, the
* old library is expected to exist. If NeedTemp is true, a temporary library
* is created.
*/
** old library is expected to exist. If NeedTemp is true, a temporary library
** is created.
*/
{
/* Remember the name */
LibName = xstrdup (Name);
@@ -268,8 +268,8 @@ void LibOpen (const char* Name, int MustExist, int NeedTemp)
unsigned long LibCopyTo (FILE* F, unsigned long Bytes)
/* Copy data from F to the temp library file, return the start position in
* the temporary library file.
*/
** the temporary library file.
*/
{
unsigned char Buf [4096];
@@ -311,8 +311,8 @@ void LibCopyFrom (unsigned long Pos, unsigned long Bytes, FILE* F)
static void LibCheckExports (ObjData* O)
/* Insert all exports from the given object file into the global list
* checking for duplicates.
*/
** checking for duplicates.
*/
{
unsigned I;
@@ -335,8 +335,8 @@ static void LibCheckExports (ObjData* O)
void LibClose (void)
/* Write remaining data, close both files and copy the temp file to the old
* filename
*/
** filename
*/
{
/* Do we have a temporary library? */
if (NewLib) {
@@ -346,9 +346,9 @@ void LibClose (void)
size_t Count;
/* Walk through the object file list, inserting exports into the
* export list checking for duplicates. Copy any data that is still
* in the old library into the new one.
*/
** export list checking for duplicates. Copy any data that is still
** in the old library into the new one.
*/
for (I = 0; I < CollCount (&ObjPool); ++I) {
/* Get a pointer to the object */

View File

@@ -61,22 +61,22 @@ extern const char* LibName;
void LibOpen (const char* Name, int MustExist, int NeedTemp);
/* Open an existing library and a temporary copy. If MustExist is true, the
* old library is expected to exist. If NeedTemp is true, a temporary library
* is created.
*/
** old library is expected to exist. If NeedTemp is true, a temporary library
** is created.
*/
unsigned long LibCopyTo (FILE* F, unsigned long Bytes);
/* Copy data from F to the temp library file, return the start position in
* the temporary library file.
*/
** the temporary library file.
*/
void LibCopyFrom (unsigned long Pos, unsigned long Bytes, FILE* F);
/* Copy data from the library file into another file */
void LibClose (void);
/* Write remaining data, close both files and copy the temp file to the old
* filename
*/
** filename
*/

View File

@@ -122,8 +122,8 @@ void ClearObjData (ObjData* O)
ObjData* FindObjData (const char* Module)
/* Search for the module with the given name and return it. Return NULL if the
* module is not in the list.
*/
** module is not in the list.
*/
{
unsigned I;

View File

@@ -97,8 +97,8 @@ void ClearObjData (ObjData* O);
ObjData* FindObjData (const char* Module);
/* Search for the module with the given name and return it. Return NULL if the
* module is not in the list.
*/
** module is not in the list.
*/
void DelObjData (const char* Module);
/* Delete the object module from the list */

View File

@@ -168,8 +168,8 @@ static void SkipLineInfoList (FILE* F)
void ObjReadData (FILE* F, ObjData* O)
/* Read object file data from the given file. The function expects the Name
* and Start fields to be valid. Header and basic data are read.
*/
** and Start fields to be valid. Header and basic data are read.
*/
{
unsigned long Count;
@@ -239,14 +239,14 @@ void ObjAdd (const char* Name)
Error ("Could not open `%s': %s", Name, strerror (errno));
}
/* Get the modification time of the object file. There a race condition
* here, since we cannot use fileno() (non standard identifier in standard
* header file), and therefore not fstat. When using stat with the
* file name, there's a risk that the file was deleted and recreated
* while it was open. Since mtime and size are only used to check
* if a file has changed in the debugger, we will ignore this problem
* here.
*/
/* Get the modification time of the object file. There's a race condition
** here, since we cannot use fileno() (non-standard identifier in standard
** header file), and therefore not fstat. When using stat with the
** file name, there's a risk that the file was deleted and recreated
** while it was open. Since mtime and size are only used to check
** if a file has changed in the debugger, we will ignore this problem
** here.
*/
if (FileStat (Name, &StatBuf) != 0) {
Error ("Cannot stat object file `%s': %s", Name, strerror (errno));
}
@@ -264,8 +264,8 @@ void ObjAdd (const char* Name)
O = NewObjData ();
} else {
/* Found - check the file modification times of the internal copy
* and the external one.
*/
** and the external one.
*/
if (difftime ((time_t)O->MTime, StatBuf.st_mtime) > 0.0) {
Warning ("Replacing module `%s' by older version in library `%s'",
O->Name, LibName);
@@ -289,8 +289,8 @@ void ObjAdd (const char* Name)
ObjReadData (Obj, O);
/* Copy the complete object data to the library file and update the
* starting offset
*/
** starting offset
*/
fseek (Obj, 0, SEEK_SET);
O->Start = LibCopyTo (Obj, O->Size);
@@ -323,8 +323,8 @@ void ObjExtract (const char* Name)
}
/* Copy the complete object file data from the library to the new object
* file.
*/
** file.
*/
LibCopyFrom (O->Start, O->Size, Obj);
/* Close the file */

View File

@@ -60,8 +60,8 @@ struct ObjData;
void ObjReadData (FILE* F, struct ObjData* O);
/* Read object file data from the given file. The function expects the Name
* and Start fields to be valid. Header and basic data are read.
*/
** and Start fields to be valid. Header and basic data are read.
*/
void ObjAdd (const char* Name);
/* Add an object file to the library */

View File

@@ -59,9 +59,9 @@ static const char AnonTag[] = "$anon";
StrBuf* AnonName (StrBuf* Buf, const char* Spec)
/* Get a name for an anonymous scope, variable or type. Size is the size of
* the buffer passed to the function, Spec will be used as part of the
* identifier if given. A pointer to the buffer is returned.
*/
** the buffer passed to the function, Spec will be used as part of the
** identifier if given. A pointer to the buffer is returned.
*/
{
static unsigned ACount = 0;
SB_Printf (Buf, "%s-%s-%04X", AnonTag, Spec, ++ACount);

View File

@@ -51,9 +51,9 @@
StrBuf* AnonName (StrBuf* Buf, const char* Spec);
/* Get a name for an anonymous scope, variable or type. Size is the size of
* the buffer passed to the function, Spec will be used as part of the
* identifier if given. A pointer to the buffer is returned.
*/
** the buffer passed to the function, Spec will be used as part of the
** identifier if given. A pointer to the buffer is returned.
*/
int IsAnonName (const StrBuf* Name);
/* Check if the given symbol name is that of an anonymous symbol */

View File

@@ -104,9 +104,9 @@ static int GetOverallIfCond (void)
/* Get the overall condition based on all conditions on the stack. */
{
/* Since the last entry contains the overall condition of the parent, we
* must check it in combination of the current condition. If there is no
* last entry, the overall condition is true.
*/
** must check it in combination of the current condition. If there is no
** last entry, the overall condition is true.
*/
return (IfCount == 0) ||
((IfStack[IfCount-1].Flags & (ifCond | ifParentCond)) == (ifCond | ifParentCond));
}
@@ -114,7 +114,7 @@ static int GetOverallIfCond (void)
static void CalcOverallIfCond (void)
/* Caclulate the overall condition based on all conditions on the stack. */
/* Calculate the overall condition, based on all conditions on the stack. */
{
IfCond = GetOverallIfCond ();
}
@@ -256,9 +256,9 @@ void DoConditionals (void)
NextTok ();
/* Ignore the new condition if we are inside a false .ELSE
* branch. This way we won't get any errors about undefined
* symbols or similar...
*/
** branch. This way we won't get any errors about undefined
** symbols or similar...
*/
if (IfCond) {
SetIfCond (D, ConstExpression ());
ExpectSep ();
@@ -273,8 +273,8 @@ void DoConditionals (void)
FreeIf ();
/* Be sure not to read the next token until the .IF stack
* has been cleanup up, since we may be at end of file.
*/
** has been cleanup up, since we may be at end of file.
*/
NextTok ();
ExpectSep ();
@@ -440,9 +440,9 @@ void DoConditionals (void)
int CheckConditionals (void)
/* Check if the current token is one that starts a conditional directive, and
* call DoConditionals if so. Return true if a conditional directive was found,
* return false otherwise.
*/
** call DoConditionals if so. Return true if a conditional directive was found,
** return false otherwise.
*/
{
switch (CurTok.Tok) {
case TOK_ELSE:
@@ -473,15 +473,15 @@ int CheckConditionals (void)
void CheckOpenIfs (void)
/* Called from the scanner before closing an input file. Will check for any
* open .ifs in this file.
*/
** open .ifs in this file.
*/
{
const LineInfo* LI;
while (1) {
/* Get the current file number and check if the topmost entry on the
* .IF stack was inserted with this file number
*/
** .IF stack was inserted with this file number
*/
IfDesc* D = GetCurrentIf ();
if (D == 0) {
/* There are no open .IFs */

View File

@@ -60,14 +60,14 @@ void DoConditionals (void);
int CheckConditionals (void);
/* Check if the current token is one that starts a conditional directive, and
* call DoConditionals if so. Return true if a conditional directive was found,
* return false otherwise.
*/
** call DoConditionals if so. Return true if a conditional directive was found,
** return false otherwise.
*/
void CheckOpenIfs (void);
/* Called from the scanner before closing an input file. Will check for any
* open .ifs in this file.
*/
** open .ifs in this file.
*/
unsigned GetIfStack (void);
/* Get the current .IF stack pointer */

View File

@@ -130,8 +130,8 @@ static unsigned HexValue (char C)
static int ValidateType (StrBuf* Type)
/* Check if the given type is valid and if so, return a string id for it. If
* the type isn't valid, return -1. Type is overwritten when checking.
*/
** the type isn't valid, return -1. Type is overwritten when checking.
*/
{
unsigned I;
const char* A;
@@ -311,8 +311,8 @@ void DbgInfoLine (void)
}
/* If a parameters follow, this is actual line info. If no parameters
* follow, the last line info is terminated.
*/
** follow, the last line info is terminated.
*/
if (CurTok.Tok == TOK_SEP) {
return;
}
@@ -445,10 +445,10 @@ void DbgInfoCheck (void)
/* Do checks on all hll debug info symbols when assembly is complete */
{
/* When parsing the debug statements for HLL symbols, we have already
* tagged the functions to their asm counterparts. This wasn't done for
* C symbols, since we will allow forward declarations. So we have to
* resolve the normal C symbols now.
*/
** tagged the functions to their asm counterparts. This wasn't done for
** C symbols, since we will allow forward declarations. So we have to
** resolve the normal C symbols now.
*/
unsigned I;
for (I = 0; I < CollCount (&HLLDbgSyms); ++I) {
@@ -456,8 +456,8 @@ void DbgInfoCheck (void)
HLLDbgSym* S = CollAtUnchecked (&HLLDbgSyms, I);
/* Ignore functions and auto symbols, because the later live on the
* stack and don't have corresponding asm symbols.
*/
** stack and don't have corresponding asm symbols.
*/
if (HLL_IS_FUNC (S->Flags) || HLL_GET_SC (S->Flags) == HLL_SC_AUTO) {
continue;
}
@@ -501,8 +501,8 @@ void WriteHLLDbgSyms (void)
unsigned SC = HLL_GET_SC (S->Flags);
/* Remember if the symbol has debug info attached
* ### This should go into DbgInfoCheck
*/
** ### This should go into DbgInfoCheck
*/
if (S->Sym && S->Sym->DebugSymId != ~0U) {
S->Flags |= HLL_DATA_SYM;
}

View File

@@ -157,12 +157,12 @@ void GetEA (EffAddr* A)
} else {
/* Remaining stuff:
*
* adr
* adr,x
* adr,y
* adr,s
*/
**
** adr
** adr,x
** adr,y
** adr,s
*/
A->Expr = Expression ();
if (CurTok.Tok == TOK_COMMA) {

View File

@@ -51,9 +51,9 @@
static long RegNum ()
/* Try to read a register number specified not as a register (Rx) but as a
* numeric value between 0 and 15. Return the register number or -1 on
* failure.
*/
** numeric value between 0 and 15. Return the register number or -1 on
** failure.
*/
{
long Val;
ExprNode* Expr = Expression ();
@@ -126,8 +126,8 @@ void GetSweet16EA (EffAddr* A)
A->AddrModeSet = AMSW16_BRA;
/* If the value is a constant between 0 and 15, it may also be a
* register number.
*/
** register number.
*/
if (IsConstExpr (A->Expr, &Reg) && Reg >= 0 && Reg <= 15) {
FreeExpr (A->Expr);
A->Reg = (unsigned) Reg;

View File

@@ -128,10 +128,10 @@ static void AddNotifications (const Collection* LineInfos)
unsigned Skipped;
/* The basic line info is always in slot zero. It has been used to
* output the actual error or warning. The following slots may contain
* more information. Check them and print additional notifications if
* they're present, but limit the number to a reasonable value.
*/
** output the actual error or warning. The following slots may contain
** more information. Check them and print additional notifications if
** they're present, but limit the number to a reasonable value.
*/
for (I = 1, Output = 0, Skipped = 0; I < CollCount (LineInfos); ++I) {
/* Get next line info */
const LineInfo* LI = CollConstAt (LineInfos, I);

View File

@@ -72,11 +72,11 @@
/* Since all expressions are first packed into expression trees, and each
* expression tree node is allocated on the heap, we add some type of special
* purpose memory allocation here: Instead of freeing the nodes, we save some
* number of freed nodes for later and remember them in a single linked list
* using the Left link.
*/
** expression tree node is allocated on the heap, we add some type of special
** purpose memory allocation here: Instead of freeing the nodes, we save some
** number of freed nodes for later and remember them in a single linked list
** using the Left link.
*/
#define MAX_FREE_NODES 64
static ExprNode* FreeExprNodes = 0;
static unsigned FreeNodeCount = 0;
@@ -172,9 +172,9 @@ int IsFarRange (long Val)
int IsEasyConst (const ExprNode* E, long* Val)
/* Do some light checking if the given node is a constant. Don't care if E is
* a complex expression. If E is a constant, return true and place its value
* into Val, provided that Val is not NULL.
*/
** a complex expression. If E is a constant, return true and place its value
** into Val, provided that Val is not NULL.
*/
{
/* Resolve symbols, follow symbol chains */
while (E->Op == EXPR_SYMBOL) {
@@ -322,8 +322,8 @@ static ExprNode* Symbol (SymEntry* S)
/* Mark the symbol as referenced */
SymRef (S);
/* If the symbol is a variable, return just its value, otherwise
* return a reference to the symbol.
*/
** return a reference to the symbol.
*/
if (SymIsVar (S)) {
return CloneExpr (GetSymExpr (S));
} else {
@@ -355,16 +355,16 @@ static ExprNode* FuncBlank (void)
/* Handle the .BLANK builtin function */
{
/* We have a list of tokens that ends with the closing paren. Skip
* the tokens, and count them. Allow optionally curly braces.
*/
** the tokens, and count them. Allow optionally curly braces.
*/
token_t Term = GetTokListTerm (TOK_RPAREN);
unsigned Count = 0;
while (CurTok.Tok != Term) {
/* Check for end of line or end of input. Since the calling function
* will check for the closing paren, we don't need to print an error
* here, just bail out.
*/
** will check for the closing paren, we don't need to print an error
** here, just bail out.
*/
if (TokIsSep (CurTok.Tok)) {
break;
}
@@ -458,9 +458,9 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
TokNode* Node;
/* A list of tokens follows. Read this list and remember it building a
* single linked list of tokens including attributes. The list is
* either enclosed in curly braces, or terminated by a comma.
*/
** single linked list of tokens including attributes. The list is
** either enclosed in curly braces, or terminated by a comma.
*/
token_t Term = GetTokListTerm (TOK_COMMA);
while (CurTok.Tok != Term) {
@@ -494,9 +494,9 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
}
/* Read the second list which is optionally enclosed in curly braces and
* terminated by the right parenthesis. Compare each token against the
* one in the first list.
*/
** terminated by the right parenthesis. Compare each token against the
** one in the first list.
*/
Term = GetTokListTerm (TOK_RPAREN);
Result = 1;
Node = Root;
@@ -674,8 +674,8 @@ static ExprNode* FuncSizeOf (void)
}
/* If ScopeName is empty, no explicit scope was specified. We have to
* search upper scope levels in this case.
*/
** search upper scope levels in this case.
*/
NoScope = SB_IsEmpty (&ScopeName);
/* First search for a scope with the given name */
@@ -686,8 +686,8 @@ static ExprNode* FuncSizeOf (void)
}
/* If we did find a scope with the name, read the symbol defining the
* size, otherwise search for a symbol entry with the name and scope.
*/
** size, otherwise search for a symbol entry with the name and scope.
*/
if (Scope) {
/* Yep, it's a scope */
SizeSym = GetSizeOfScope (Scope);
@@ -755,8 +755,8 @@ static ExprNode* FuncStrAt (void)
}
/* Get the char, handle as unsigned. Be sure to translate it into
* the target character set.
*/
** the target character set.
*/
C = TgtTranslateChar (SB_At (&Str, (unsigned)Index));
ExitPoint:
@@ -803,16 +803,16 @@ static ExprNode* FuncTCount (void)
/* Handle the .TCOUNT function */
{
/* We have a list of tokens that ends with the closing paren. Skip
* the tokens, and count them. Allow optionally curly braces.
*/
** the tokens, and count them. Allow optionally curly braces.
*/
token_t Term = GetTokListTerm (TOK_RPAREN);
int Count = 0;
while (CurTok.Tok != Term) {
/* Check for end of line or end of input. Since the calling function
* will check for the closing paren, we don't need to print an error
* here, just bail out.
*/
** will check for the closing paren, we don't need to print an error
** here, just bail out.
*/
if (TokIsSep (CurTok.Tok)) {
break;
}
@@ -1131,8 +1131,8 @@ static ExprNode* Term (void)
}
/* Generate a literal expression and delete the old left and
* right sides.
*/
** right sides.
*/
FreeExpr (Left);
FreeExpr (Right);
Root = GenLiteralExpr (Val);
@@ -1198,8 +1198,8 @@ static ExprNode* SimpleExpr (void)
}
/* Generate a literal expression and delete the old left and
* right sides.
*/
** right sides.
*/
FreeExpr (Left);
FreeExpr (Right);
Root = GenLiteralExpr (Val);
@@ -1264,8 +1264,8 @@ static ExprNode* BoolExpr (void)
}
/* Generate a literal expression and delete the old left and
* right sides.
*/
** right sides.
*/
FreeExpr (Left);
FreeExpr (Right);
Root = GenLiteralExpr (Val);
@@ -1327,8 +1327,8 @@ static ExprNode* Expr2 (void)
}
/* Generate a literal expression and delete the old left and
* right sides.
*/
** right sides.
*/
FreeExpr (Left);
FreeExpr (Right);
Root = GenLiteralExpr (Val);
@@ -1385,8 +1385,8 @@ static ExprNode* Expr1 (void)
}
/* Generate a literal expression and delete the old left and
* right sides.
*/
** right sides.
*/
FreeExpr (Left);
FreeExpr (Right);
Root = GenLiteralExpr (Val);
@@ -1453,8 +1453,8 @@ static ExprNode* Expr0 (void)
ExprNode* Expression (void)
/* Evaluate an expression, build the expression tree on the heap and return
* a pointer to the root of the tree.
*/
** a pointer to the root of the tree.
*/
{
return Expr0 ();
}
@@ -1463,9 +1463,9 @@ ExprNode* Expression (void)
long ConstExpression (void)
/* Parse an expression. Check if the expression is const, and print an error
* message if not. Return the value of the expression, or a dummy, if it is
* not constant.
*/
** message if not. Return the value of the expression, or a dummy, if it is
** not constant.
*/
{
long Val;
@@ -1620,8 +1620,8 @@ ExprNode* GenSwapExpr (ExprNode* Expr)
ExprNode* GenBranchExpr (unsigned Offs)
/* Return an expression that encodes the difference between current PC plus
* offset and the target expression (that is, Expression() - (*+Offs) ).
*/
** offset and the target expression (that is, Expression() - (*+Offs) ).
*/
{
ExprNode* N;
ExprNode* Root;
@@ -1637,11 +1637,11 @@ ExprNode* GenBranchExpr (unsigned Offs)
FreeExpr (N);
/* Generate the final expression:
* Val - (* + Offs)
* Val - ((Seg + PC) + Offs)
* Val - Seg - PC - Offs
* (Val - PC - Offs) - Seg
*/
** Val - (* + Offs)
** Val - ((Seg + PC) + Offs)
** Val - Seg - PC - Offs
** (Val - PC - Offs) - Seg
*/
Root = GenLiteralExpr (Val - GetPC () - Offs);
if (GetRelocMode ()) {
N = Root;
@@ -1653,11 +1653,11 @@ ExprNode* GenBranchExpr (unsigned Offs)
} else {
/* Generate the expression:
* N - (* + Offs)
* N - ((Seg + PC) + Offs)
* N - Seg - PC - Offs
* N - (PC + Offs) - Seg
*/
** N - (* + Offs)
** N - ((Seg + PC) + Offs)
** N - Seg - PC - Offs
** N - (PC + Offs) - Seg
*/
Root = NewExprNode (EXPR_MINUS);
Root->Left = N;
Root->Right = GenLiteralExpr (GetPC () + Offs);
@@ -1759,9 +1759,9 @@ ExprNode* GenNE (ExprNode* Expr, long Val)
int IsConstExpr (ExprNode* Expr, long* Val)
/* Return true if the given expression is a constant expression, that is, one
* with no references to external symbols. If Val is not NULL and the
* expression is constant, the constant value is stored here.
*/
** with no references to external symbols. If Val is not NULL and the
** expression is constant, the constant value is stored here.
*/
{
int IsConst;
@@ -1785,8 +1785,8 @@ int IsConstExpr (ExprNode* Expr, long* Val)
ExprNode* CloneExpr (ExprNode* Expr)
/* Clone the given expression tree. The function will simply clone symbol
* nodes, it will not resolve them.
*/
** nodes, it will not resolve them.
*/
{
ExprNode* Clone;
@@ -1843,8 +1843,8 @@ void WriteExpr (ExprNode* Expr)
}
/* If the is a leafnode, write the expression attribute, otherwise
* write the expression operands.
*/
** write the expression operands.
*/
switch (Expr->Op) {
case EXPR_LITERAL:
@@ -1884,12 +1884,12 @@ void WriteExpr (ExprNode* Expr)
void ExprGuessedAddrSize (const ExprNode* Expr, unsigned char AddrSize)
/* Mark the address size of the given expression tree as guessed. The address
* size passed as argument is the one NOT used, because the actual address
* size wasn't known. Example: Zero page addressing was not used because symbol
* is undefined, and absolute addressing was available.
* This function will actually parse the expression tree for undefined symbols,
* and mark these symbols accordingly.
*/
** size passed as argument is the one NOT used, because the actual address
** size wasn't known. Example: Zero page addressing was not used because symbol
** is undefined, and absolute addressing was available.
** This function will actually parse the expression tree for undefined symbols,
** and mark these symbols accordingly.
*/
{
/* Accept NULL expressions */
if (Expr == 0) {

View File

@@ -62,14 +62,14 @@ struct ExprDesc;
ExprNode* Expression (void);
/* Evaluate an expression, build the expression tree on the heap and return
* a pointer to the root of the tree.
*/
** a pointer to the root of the tree.
*/
long ConstExpression (void);
/* Parse an expression. Check if the expression is const, and print an error
* message if not. Return the value of the expression, or a dummy, if it is
* not constant.
*/
** message if not. Return the value of the expression, or a dummy, if it is
** not constant.
*/
void FreeExpr (ExprNode* Root);
/* Free the expression tree, Root is pointing to. */
@@ -97,8 +97,8 @@ ExprNode* GenSwapExpr (ExprNode* Expr);
ExprNode* GenBranchExpr (unsigned Offs);
/* Return an expression that encodes the difference between current PC plus
* offset and the target expression (that is, Expression() - (*+Offs) ).
*/
** offset and the target expression (that is, Expression() - (*+Offs) ).
*/
ExprNode* GenULabelExpr (unsigned Num);
/* Return an expression for an unnamed label with the given index */
@@ -120,9 +120,9 @@ ExprNode* GenNE (ExprNode* Expr, long Val);
int IsConstExpr (ExprNode* Expr, long* Val);
/* Return true if the given expression is a constant expression, that is, one
* with no references to external symbols. If Val is not NULL and the
* expression is constant, the constant value is stored here.
*/
** with no references to external symbols. If Val is not NULL and the
** expression is constant, the constant value is stored here.
*/
int IsByteExpr (ExprNode* Root);
/* Return true if this is a byte expression */
@@ -138,26 +138,26 @@ int IsFarRange (long Val);
int IsEasyConst (const ExprNode* E, long* Val);
/* Do some light checking if the given node is a constant. Don't care if E is
* a complex expression. If E is a constant, return true and place its value
* into Val, provided that Val is not NULL.
*/
** a complex expression. If E is a constant, return true and place its value
** into Val, provided that Val is not NULL.
*/
ExprNode* CloneExpr (ExprNode* Expr);
/* Clone the given expression tree. The function will simply clone symbol
* nodes, it will not resolve them.
*/
** nodes, it will not resolve them.
*/
void WriteExpr (ExprNode* Expr);
/* Write the given expression to the object file */
void ExprGuessedAddrSize (const ExprNode* Expr, unsigned char AddrSize);
/* Mark the address size of the given expression tree as guessed. The address
* size passed as argument is the one NOT used, because the actual address
* size wasn't known. Example: Zero page addressing was not used because symbol
* is undefined, and absolute addressing was available.
* This function will actually parse the expression tree for undefined symbols,
* and mark these symbols accordingly.
*/
** size passed as argument is the one NOT used, because the actual address
** size wasn't known. Example: Zero page addressing was not used because symbol
** is undefined, and absolute addressing was available.
** This function will actually parse the expression tree for undefined symbols,
** and mark these symbols accordingly.
*/
ExprNode* FuncBankByte (void);
/* Handle the .BANKBYTE builtin function */

View File

@@ -75,8 +75,8 @@ static const char* FeatureKeys[FEAT_COUNT] = {
feature_t FindFeature (const StrBuf* Key)
/* Find the feature in a table and return the corresponding enum value. If the
* feature is invalid, return FEAT_UNKNOWN.
*/
** feature is invalid, return FEAT_UNKNOWN.
*/
{
feature_t F;
@@ -96,9 +96,9 @@ feature_t FindFeature (const StrBuf* Key)
feature_t SetFeature (const StrBuf* Key)
/* Find the feature and set the corresponding flag if the feature is known.
* In any case, return the feature found. An invalid Key will return
* FEAT_UNKNOWN.
*/
** In any case, return the feature found. An invalid Key will return
** FEAT_UNKNOWN.
*/
{
/* Map the string to an enum value */
feature_t Feature = FindFeature (Key);

View File

@@ -80,14 +80,14 @@ typedef enum {
feature_t FindFeature (const StrBuf* Key);
/* Find the feature in a table and return the corresponding enum value. If the
* feature is invalid, return FEAT_UNKNOWN.
*/
** feature is invalid, return FEAT_UNKNOWN.
*/
feature_t SetFeature (const StrBuf* Key);
/* Find the feature and set the corresponding flag if the feature is known.
* In any case, return the feature found. An invalid Key will return
* FEAT_UNKNOWN.
*/
** In any case, return the feature found. An invalid Key will return
** FEAT_UNKNOWN.
*/

View File

@@ -66,9 +66,9 @@ static const void* HT_GetKey (const void* Entry);
static int HT_Compare (const void* Key1, const void* Key2);
/* Compare two keys. The function must return a value less than zero if
* Key1 is smaller than Key2, zero if both are equal, and a value greater
* than zero if Key1 is greater then Key2.
*/
** Key1 is smaller than Key2, zero if both are equal, and a value greater
** than zero if Key1 is greater then Key2.
*/
@@ -132,9 +132,9 @@ static const void* HT_GetKey (const void* Entry)
static int HT_Compare (const void* Key1, const void* Key2)
/* Compare two keys. The function must return a value less than zero if
* Key1 is smaller than Key2, zero if both are equal, and a value greater
* than zero if Key1 is greater then Key2.
*/
** Key1 is smaller than Key2, zero if both are equal, and a value greater
** than zero if Key1 is greater then Key2.
*/
{
return (int)*(const unsigned*)Key1 - (int)*(const unsigned*)Key2;
}
@@ -183,9 +183,9 @@ const StrBuf* GetFileName (unsigned Name)
if (Name == 0) {
/* Name was defined outside any file scope, use the name of the first
* file instead. Errors are then reported with a file position of
* line zero in the first file.
*/
** file instead. Errors are then reported with a file position of
** line zero in the first file.
*/
if (CollCount (&FileTab) == 0) {
/* No files defined until now */
return &ErrorMsg;
@@ -223,8 +223,8 @@ unsigned GetFileIndex (const StrBuf* Name)
unsigned AddFile (const StrBuf* Name, FileType Type,
unsigned long Size, unsigned long MTime)
/* Add a new file to the list of input files. Return the index of the file in
* the table.
*/
** the table.
*/
{
/* Create a new file entry and insert it into the tables */
FileEntry* F = NewFileEntry (GetStrBufId (Name), Type, Size, MTime);
@@ -295,8 +295,8 @@ static void WriteDep (FILE* F, FileType Types)
static void CreateDepFile (const char* Name, FileType Types)
/* Create a dependency file with the given name and place dependencies for
* all files with the given types there.
*/
** all files with the given types there.
*/
{
/* Open the file */
FILE* F = fopen (Name, "w");

View File

@@ -50,8 +50,8 @@
/* An enum that describes different types of input files. The members are
* choosen so that it is possible to combine them to bitsets
*/
** choosen so that it is possible to combine them to bitsets
*/
typedef enum {
FT_MAIN = 0x01, /* Main input file */
FT_INCLUDE = 0x02, /* Normal include file */
@@ -76,8 +76,8 @@ unsigned GetFileIndex (const StrBuf* Name);
unsigned AddFile (const StrBuf* Name, FileType Type,
unsigned long Size, unsigned long MTime);
/* Add a new file to the list of input files. Return the index of the file in
* the table.
*/
** the table.
*/
void WriteFiles (void);
/* Write the list of input files to the object file */

View File

@@ -49,8 +49,8 @@
Fragment* NewFragment (unsigned char Type, unsigned short Len)
/* Create, initialize and return a new fragment. The fragment will be inserted
* into the current segment.
*/
** into the current segment.
*/
{
/* Create a new fragment */
Fragment* F = xmalloc (sizeof (*F));

View File

@@ -76,8 +76,8 @@ struct Fragment {
Fragment* NewFragment (unsigned char Type, unsigned short Len);
/* Create, initialize and return a new fragment. The fragment will be inserted
* into the current segment.
*/
** into the current segment.
*/

View File

@@ -90,37 +90,37 @@ static void PutSEP (const InsDesc* Ins);
static void PutTAMn (const InsDesc* Ins);
/* Emit a TAMn instruction (HuC6280). Since this is a two byte instruction with
* implicit addressing mode, the opcode byte in the table is actually the
* second operand byte. The TAM instruction is the more generic form, it takes
* an immediate argument.
*/
** implicit addressing mode, the opcode byte in the table is actually the
** second operand byte. The TAM instruction is the more generic form, it takes
** an immediate argument.
*/
static void PutTMA (const InsDesc* Ins);
/* Emit a TMA instruction (HuC6280) with an immediate argument. Only one bit
* in the argument byte may be set.
*/
** in the argument byte may be set.
*/
static void PutTMAn (const InsDesc* Ins);
/* Emit a TMAn instruction (HuC6280). Since this is a two byte instruction with
* implicit addressing mode, the opcode byte in the table is actually the
* second operand byte. The TAM instruction is the more generic form, it takes
* an immediate argument.
*/
** implicit addressing mode, the opcode byte in the table is actually the
** second operand byte. The TAM instruction is the more generic form, it takes
** an immediate argument.
*/
static void PutTST (const InsDesc* Ins);
/* Emit a TST instruction (HuC6280). */
static void PutJMP (const InsDesc* Ins);
/* Handle the jump instruction for the 6502. Problem is that these chips have
* a bug: If the address crosses a page, the upper byte gets not corrected and
* the instruction will fail. The PutJmp function will add a linker assertion
* to check for this case and is otherwise identical to PutAll.
*/
** a bug: If the address crosses a page, the upper byte gets not corrected and
** the instruction will fail. The PutJmp function will add a linker assertion
** to check for this case and is otherwise identical to PutAll.
*/
static void PutRTS (const InsDesc* Ins attribute ((unused)));
/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
* the enclosing scope is FAR.
*/
** the enclosing scope is FAR.
*/
static void PutAll (const InsDesc* Ins);
/* Handle all other instructions */
@@ -783,8 +783,8 @@ static const InsTable* InsTabs[CPU_COUNT] = {
const InsTable* InsTab = (const InsTable*) &InsTab6502;
/* Table to build the effective 65xx opcode from a base opcode and an
* addressing mode.
*/
** addressing mode.
*/
static unsigned char EATab[10][AM65I_COUNT] = {
{ /* Table 0 */
0x00, 0x00, 0x05, 0x0D, 0x0F, 0x15, 0x1D, 0x1F,
@@ -849,8 +849,8 @@ static unsigned char EATab[10][AM65I_COUNT] = {
};
/* Table to build the effective SWEET16 opcode from a base opcode and an
* addressing mode.
*/
** addressing mode.
*/
static unsigned char Sweet16EATab[2][AMSW16I_COUNT] = {
{ /* Table 0 */
0x00, 0x00, 0x00, 0x00, 0x00,
@@ -910,21 +910,21 @@ static unsigned char Sweet16ExtBytes[AMSW16I_COUNT] = {
static int EvalEA (const InsDesc* Ins, EffAddr* A)
/* Evaluate the effective address. All fields in A will be valid after calling
* this function. The function returns true on success and false on errors.
*/
** this function. The function returns true on success and false on errors.
*/
{
/* Get the set of possible addressing modes */
GetEA (A);
/* From the possible addressing modes, remove the ones that are invalid
* for this instruction or CPU.
*/
** for this instruction or CPU.
*/
A->AddrModeSet &= Ins->AddrMode;
/* If we have an expression, check it and remove any addressing modes that
* are too small for the expression size. Since we have to study the
* expression anyway, do also replace it by a simpler one if possible.
*/
** are too small for the expression size. Since we have to study the
** expression anyway, do also replace it by a simpler one if possible.
*/
if (A->Expr) {
ExprDesc ED;
ED_Init (&ED);
@@ -937,10 +937,10 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A)
if (ED.AddrSize == ADDR_SIZE_DEFAULT) {
/* We don't know how big the expression is. If the instruction
* allows just one addressing mode, assume this as address size
* for the expression. Otherwise assume the default address size
* for data.
*/
** allows just one addressing mode, assume this as address size
** for the expression. Otherwise assume the default address size
** for data.
*/
if ((A->AddrModeSet & ~AM65_ALL_ZP) == 0) {
ED.AddrSize = ADDR_SIZE_ZP;
} else if ((A->AddrModeSet & ~AM65_ALL_ABS) == 0) {
@@ -950,12 +950,12 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A)
} else {
ED.AddrSize = DataAddrSize;
/* If the default address size of the data segment is unequal
* to zero page addressing, but zero page addressing is
* allowed by the instruction, mark all symbols in the
* expression tree. This mark will be checked at end of
* assembly, and a warning is issued, if a zero page symbol
* was guessed wrong here.
*/
** to zero page addressing, but zero page addressing is
** allowed by the instruction, mark all symbols in the
** expression tree. This mark will be checked at end of
** assembly, and a warning is issued, if a zero page symbol
** was guessed wrong here.
*/
if (ED.AddrSize > ADDR_SIZE_ZP && (A->AddrModeSet & AM65_SET_ZP)) {
ExprGuessedAddrSize (A->Expr, ADDR_SIZE_ZP);
}
@@ -987,11 +987,11 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A)
A->AddrModeBit = (0x01UL << A->AddrMode);
/* If the instruction has a one byte operand and immediate addressing is
* allowed but not used, check for an operand expression in the form
* <label or >label, where label is a far or absolute label. If found,
* emit a warning. This warning protects against a typo, where the '#'
* for the immediate operand is omitted.
*/
** allowed but not used, check for an operand expression in the form
** <label or >label, where label is a far or absolute label. If found,
** emit a warning. This warning protects against a typo, where the '#'
** for the immediate operand is omitted.
*/
if (A->Expr && (Ins->AddrMode & AM65_ALL_IMM) &&
(A->AddrModeSet & (AM65_DIR | AM65_ABS | AM65_ABS_LONG)) &&
ExtBytes[A->AddrMode] == 1) {
@@ -1011,8 +1011,8 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A)
A->Opcode = Ins->BaseCode | EATab[Ins->ExtCode][A->AddrMode];
/* If feature force_range is active, and we have immediate addressing mode,
* limit the expression to the maximum possible value.
*/
** limit the expression to the maximum possible value.
*/
if (A->AddrMode == AM65I_IMM_ACCU || A->AddrMode == AM65I_IMM_INDEX ||
A->AddrMode == AM65I_IMM_IMPLICIT) {
if (ForceRange && A->Expr) {
@@ -1043,9 +1043,9 @@ static void EmitCode (EffAddr* A)
case 2:
if (CPU == CPU_65816 && (A->AddrModeBit & (AM65_ABS | AM65_ABS_X | AM65_ABS_Y))) {
/* This is a 16 bit mode that uses an address. If in 65816,
* mode, force this address into 16 bit range to allow
* addressing inside a 64K segment.
*/
** mode, force this address into 16 bit range to allow
** addressing inside a 64K segment.
*/
Emit2 (A->Opcode, GenWordExpr (A->Expr));
} else {
Emit2 (A->Opcode, A->Expr);
@@ -1067,8 +1067,8 @@ static void EmitCode (EffAddr* A)
static long PutImmed8 (const InsDesc* Ins)
/* Parse and emit an immediate 8 bit instruction. Return the value of the
* operand if it's available and const.
*/
** operand if it's available and const.
*/
{
EffAddr A;
long Val = -1;
@@ -1210,10 +1210,10 @@ static void PutSEP (const InsDesc* Ins)
static void PutTAMn (const InsDesc* Ins)
/* Emit a TAMn instruction (HuC6280). Since this is a two byte instruction with
* implicit addressing mode, the opcode byte in the table is actually the
* second operand byte. The TAM instruction is the more generic form, it takes
* an immediate argument.
*/
** implicit addressing mode, the opcode byte in the table is actually the
** second operand byte. The TAM instruction is the more generic form, it takes
** an immediate argument.
*/
{
/* Emit the TAM opcode itself */
Emit0 (0x53);
@@ -1226,8 +1226,8 @@ static void PutTAMn (const InsDesc* Ins)
static void PutTMA (const InsDesc* Ins)
/* Emit a TMA instruction (HuC6280) with an immediate argument. Only one bit
* in the argument byte may be set.
*/
** in the argument byte may be set.
*/
{
/* Use the generic handler */
long Val = PutImmed8 (Ins);
@@ -1248,10 +1248,10 @@ static void PutTMA (const InsDesc* Ins)
static void PutTMAn (const InsDesc* Ins)
/* Emit a TMAn instruction (HuC6280). Since this is a two byte instruction with
* implicit addressing mode, the opcode byte in the table is actually the
* second operand byte. The TAM instruction is the more generic form, it takes
* an immediate argument.
*/
** implicit addressing mode, the opcode byte in the table is actually the
** second operand byte. The TAM instruction is the more generic form, it takes
** an immediate argument.
*/
{
/* Emit the TMA opcode itself */
Emit0 (0x43);
@@ -1303,10 +1303,10 @@ static void PutTST (const InsDesc* Ins)
static void PutJMP (const InsDesc* Ins)
/* Handle the jump instruction for the 6502. Problem is that these chips have
* a bug: If the address crosses a page, the upper byte gets not corrected and
* the instruction will fail. The PutJmp function will add a linker assertion
* to check for this case and is otherwise identical to PutAll.
*/
** a bug: If the address crosses a page, the upper byte gets not corrected and
** the instruction will fail. The PutJmp function will add a linker assertion
** to check for this case and is otherwise identical to PutAll.
*/
{
EffAddr A;
@@ -1317,9 +1317,9 @@ static void PutJMP (const InsDesc* Ins)
if (A.AddrModeBit & AM65_ABS_IND) {
/* Compare the low byte of the expression to 0xFF to check for
* a page cross. Be sure to use a copy of the expression otherwise
* things will go weird later.
*/
** a page cross. Be sure to use a copy of the expression otherwise
** things will go weird later.
*/
ExprNode* E = GenNE (GenByteExpr (CloneExpr (A.Expr)), 0xFF);
/* Generate the message */
@@ -1338,8 +1338,8 @@ static void PutJMP (const InsDesc* Ins)
static void PutRTS (const InsDesc* Ins attribute ((unused)))
/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
* the enclosing scope is FAR.
*/
** the enclosing scope is FAR.
*/
{
if (SmartMode && CurrentScope->AddrSize == ADDR_SIZE_FAR) {
Emit0 (0x6B); /* RTL */
@@ -1379,8 +1379,8 @@ static void PutSweet16 (const InsDesc* Ins)
GetSweet16EA (&A);
/* From the possible addressing modes, remove the ones that are invalid
* for this instruction or CPU.
*/
** for this instruction or CPU.
*/
A.AddrModeSet &= Ins->AddrMode;
/* Check if we have any adressing modes left */
@@ -1466,16 +1466,16 @@ cpu_t GetCPU (void)
int FindInstruction (const StrBuf* Ident)
/* Check if Ident is a valid mnemonic. If so, return the index in the
* instruction table. If not, return -1.
*/
** instruction table. If not, return -1.
*/
{
unsigned I;
const InsDesc* ID;
char Key[sizeof (ID->Mnemonic)];
/* Shortcut for the "none" CPU: If there are no instructions to search
* for, bail out early.
*/
** for, bail out early.
*/
if (InsTab->Count == 0) {
/* Not found */
return -1;
@@ -1485,8 +1485,8 @@ int FindInstruction (const StrBuf* Ident)
I = 0;
while (I < SB_GetLen (Ident)) {
/* If the identifier is longer than the longest mnemonic, it cannot
* be one.
*/
** be one.
*/
if (I >= sizeof (Key) - 1) {
/* Not found, no need for further action */
return -1;

View File

@@ -51,13 +51,13 @@
/* Constants for the addressing mode. If an opcode is available in zero page
* and absolut adressing mode, both bits are set. When checking for valid
* modes, the zeropage bit is checked first. Similar, the implicit bit is set
* on accu adressing modes, so the 'A' for accu adressing is not needed (but
* may be specified).
* When assembling for the 6502 or 65C02, all addressing modes that are not
* available on these CPUs are removed before doing any checks.
*/
** and absolut adressing mode, both bits are set. When checking for valid
** modes, the zeropage bit is checked first. Similar, the implicit bit is set
** on accu adressing modes, so the 'A' for accu adressing is not needed (but
** may be specified).
** When assembling for the 6502 or 65C02, all addressing modes that are not
** available on these CPUs are removed before doing any checks.
*/
#define AM65_IMPLICIT 0x00000003UL
#define AM65_ACCU 0x00000002UL
#define AM65_DIR 0x00000004UL
@@ -168,8 +168,8 @@ cpu_t GetCPU (void);
int FindInstruction (const StrBuf* Ident);
/* Check if Ident is a valid mnemonic. If so, return the index in the
* instruction table. If not, return -1.
*/
** instruction table. If not, return -1.
*/
void HandleInstruction (unsigned Index);
/* Handle the mnemonic with the given index */

View File

@@ -7,7 +7,7 @@
/* */
/* */
/* (C) 2000-2003 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@@ -120,12 +120,12 @@ void PopInput (void)
int InputFromStack (void)
/* Try to get input from the input stack. Return true if we had such input,
* return false otherwise.
*/
** return false otherwise.
*/
{
/* Repeatedly call the TOS routine until we have a token or if run out of
* routines.
*/
** routines.
*/
while (IStack) {
if (IStack->Func (IStack->Data) != 0) {
/* We have a token */
@@ -149,8 +149,8 @@ int HavePushedInput (void)
void CheckInputStack (void)
/* Called from the scanner before closing an input file. Will check for any
* stuff on the input stack.
*/
** stuff on the input stack.
*/
{
if (IStack) {
Error ("Open %s", IStack->Desc);

View File

@@ -52,16 +52,16 @@ void PopInput (void);
int InputFromStack (void);
/* Try to get input from the input stack. Return true if we had such input,
* return false otherwise.
*/
** return false otherwise.
*/
int HavePushedInput (void);
/* Return true if we have stacked input available, return false if not */
void CheckInputStack (void);
/* Called from the scanner before closing an input file. Will check for any
* stuff on the input stack.
*/
** stuff on the input stack.
*/

View File

@@ -65,9 +65,9 @@ static const void* HT_GetKey (const void* Entry);
static int HT_Compare (const void* Key1, const void* Key2);
/* Compare two keys. The function must return a value less than zero if
* Key1 is smaller than Key2, zero if both are equal, and a value greater
* than zero if Key1 is greater then Key2.
*/
** Key1 is smaller than Key2, zero if both are equal, and a value greater
** than zero if Key1 is greater then Key2.
*/
@@ -145,9 +145,9 @@ static const void* HT_GetKey (const void* Entry)
static int HT_Compare (const void* Key1, const void* Key2)
/* Compare two keys. The function must return a value less than zero if
* Key1 is smaller than Key2, zero if both are equal, and a value greater
* than zero if Key1 is greater then Key2.
*/
** Key1 is smaller than Key2, zero if both are equal, and a value greater
** than zero if Key1 is greater then Key2.
*/
{
/* Convert both parameters to FileInfoKey pointers */
const LineInfoKey* K1 = Key1;
@@ -272,8 +272,8 @@ void InitLineInfo (void)
CollGrow (&LineInfoList, 200);
/* Create a LineInfo for the default source. This is necessary to allow
* error message to be generated without any input file open.
*/
** error message to be generated without any input file open.
*/
AsmLineInfo = StartLine (&DefaultPos, LI_TYPE_ASM, 0);
}
@@ -289,9 +289,9 @@ void DoneLineInfo (void)
}
/* Walk over the entries in the hash table and sort them into used and
* unused ones. Add the used ones to the line info list and assign them
* an id.
*/
** unused ones. Add the used ones to the line info list and assign them
** an id.
*/
HT_Walk (&LineInfoTab, CheckLineInfo, 0);
}
@@ -304,14 +304,14 @@ void EndLine (LineInfo* LI)
CloseSpanList (&LI->OpenSpans);
/* Move the spans to the list of all spans for this line, then clear the
* list of open spans.
*/
** list of open spans.
*/
CollTransfer (&LI->Spans, &LI->OpenSpans);
CollDeleteAll (&LI->OpenSpans);
/* Line info is no longer active - remove it from the list of current
* line infos.
*/
** line infos.
*/
CollDeleteItem (&CurLineInfo, LI);
}
@@ -328,8 +328,8 @@ LineInfo* StartLine (const FilePos* Pos, unsigned Type, unsigned Count)
Key.Type = LI_MAKE_TYPE (Type, Count);
/* Try to find a line info with this position and type in the hash table.
* If so, reuse it. Otherwise create a new one.
*/
** If so, reuse it. Otherwise create a new one.
*/
LI = HT_Find (&LineInfoTab, &Key);
if (LI == 0) {
/* Allocate a new LineInfo */
@@ -350,9 +350,9 @@ LineInfo* StartLine (const FilePos* Pos, unsigned Type, unsigned Count)
void NewAsmLine (void)
/* Start a new assembler input line. Use this function when generating new
* line of LI_TYPE_ASM. It will check if line and/or file have actually
* changed, end the old and start the new line as necessary.
*/
** line of LI_TYPE_ASM. It will check if line and/or file have actually
** changed, end the old and start the new line as necessary.
*/
{
/* Check if we can reuse the old line */
if (AsmLineInfo) {
@@ -374,8 +374,8 @@ void NewAsmLine (void)
LineInfo* GetAsmLineInfo (void)
/* Return the line info for the current assembler file. The function will
* bump the reference counter before returning the line info.
*/
** bump the reference counter before returning the line info.
*/
{
++AsmLineInfo->RefCount;
return AsmLineInfo;
@@ -395,9 +395,9 @@ void ReleaseLineInfo (LineInfo* LI)
void GetFullLineInfo (Collection* LineInfos)
/* Return full line infos, that is line infos for currently active Slots. The
* infos will be added to the given collection, existing entries will be left
* intact. The reference count of all added entries will be increased.
*/
** infos will be added to the given collection, existing entries will be left
** intact. The reference count of all added entries will be increased.
*/
{
unsigned I;
@@ -414,8 +414,8 @@ void GetFullLineInfo (Collection* LineInfos)
void ReleaseFullLineInfo (Collection* LineInfos)
/* Decrease the reference count for a collection full of LineInfos, then clear
* the collection.
*/
** the collection.
*/
{
unsigned I;

View File

@@ -77,28 +77,28 @@ LineInfo* StartLine (const FilePos* Pos, unsigned Type, unsigned Count);
void NewAsmLine (void);
/* Start a new assembler input line. Use this function when generating new
* line of LI_TYPE_ASM. It will check if line and/or file have actually
* changed, end the old and start the new line as necessary.
*/
** line of LI_TYPE_ASM. It will check if line and/or file have actually
** changed, end the old and start the new line as necessary.
*/
LineInfo* GetAsmLineInfo (void);
/* Return the line info for the current assembler file. The function will
* bump the reference counter before returning the line info.
*/
** bump the reference counter before returning the line info.
*/
void ReleaseLineInfo (LineInfo* LI);
/* Decrease the reference count for a line info */
void GetFullLineInfo (Collection* LineInfos);
/* Return full line infos, that is line infos for currently active Slots. The
* infos will be added to the given collection, existing entries will be left
* intact. The reference count of all added entries will be increased.
*/
** infos will be added to the given collection, existing entries will be left
** intact. The reference count of all added entries will be increased.
*/
void ReleaseFullLineInfo (Collection* LineInfos);
/* Decrease the reference count for a collection full of LineInfos, then clear
* the collection.
*/
** the collection.
*/
const FilePos* GetSourcePos (const LineInfo* LI);
/* Return the source file position from the given line info */

View File

@@ -131,8 +131,8 @@ void EnableListing (void)
{
if (SB_GetLen (&ListingName) > 0) {
/* If we're about to enable the listing, do this for the current line
* also, so we will see the source line that did this.
*/
** also, so we will see the source line that did this.
*/
if (ListingEnabled++ == 0) {
LineCur->Output = 1;
}
@@ -172,9 +172,9 @@ void InitListingLine (void)
{
if (SB_GetLen (&ListingName) > 0) {
/* Make the last loaded line the current line */
/* ###### This code is a hack! We really need to do it right
* as soon as we know, how:-(
*/
/* ###### This code is a hack! We really need to do it right --
** as soon as we know how. :-(
*/
if (LineCur && LineCur->Next && LineCur->Next != LineLast) {
ListLine* L = LineCur;
do {
@@ -217,8 +217,8 @@ static char* AddHex (char* S, unsigned Val)
static void PrintPageHeader (FILE* F, const ListLine* L)
/* Print the header for a new page. It is assumed that the given line is the
* last line of the previous page.
*/
** last line of the previous page.
*/
{
/* Gte a pointer to the current input file */
const StrBuf* CurFile = GetFileName (L->File);
@@ -250,8 +250,8 @@ static void PrintLine (FILE* F, const char* Header, const char* Line, const List
++PageLines;
/* Switch to a new page if needed. Do not switch, if the current line is
* the last one, to avoid pages that consist of just the header.
*/
** the last one, to avoid pages that consist of just the header.
*/
if (PageLength > 0 && PageLines >= PageLength && L->Next != 0) {
/* Do a formfeed */
putc ('\f', F);
@@ -392,16 +392,16 @@ void CreateListing (void)
}
/* Output the data. The format of a listing line is:
*
* PPPPPPm I 11 22 33 44
*
* where
*
* PPPPPP is the PC
* m is the mode ('r' or empty)
* I is the include level
* 11 .. are code or data bytes
*/
**
** PPPPPPm I 11 22 33 44
**
** where
**
** PPPPPP is the PC
** m is the mode ('r' or empty)
** I is the include level
** 11 .. are code or data bytes
*/
Line = L->Line;
B = Buf;
while (Count) {
@@ -420,9 +420,9 @@ void CreateListing (void)
Count -= Chunk;
/* Increment the program counter. Since we don't need the PC stored
* in the LineList object for anything else, just increment this
* variable.
*/
** in the LineList object for anything else, just increment this
** variable.
*/
L->PC += Chunk;
/* Copy the bytes into the line */

View File

@@ -70,9 +70,9 @@ static const void* HT_GetKey (const void* Entry);
static int HT_Compare (const void* Key1, const void* Key2);
/* Compare two keys. The function must return a value less than zero if
* Key1 is smaller than Key2, zero if both are equal, and a value greater
* than zero if Key1 is greater then Key2.
*/
** Key1 is smaller than Key2, zero if both are equal, and a value greater
** than zero if Key1 is greater then Key2.
*/
@@ -176,9 +176,9 @@ static const void* HT_GetKey (const void* Entry)
static int HT_Compare (const void* Key1, const void* Key2)
/* Compare two keys. The function must return a value less than zero if
* Key1 is smaller than Key2, zero if both are equal, and a value greater
* than zero if Key1 is greater then Key2.
*/
** Key1 is smaller than Key2, zero if both are equal, and a value greater
** than zero if Key1 is greater then Key2.
*/
{
return SB_Compare (Key1, Key2);
}
@@ -399,8 +399,8 @@ void MacDef (unsigned Style)
return;
} else if (!UbiquitousIdents && FindInstruction (&CurTok.SVal) >= 0) {
/* The identifier is a name of a 6502 instruction, which is not
* allowed if not explicitly enabled.
*/
** allowed if not explicitly enabled.
*/
Error ("Cannot use an instruction as macro name");
MacSkipDef (Style);
return;
@@ -423,8 +423,8 @@ void MacDef (unsigned Style)
NextTok ();
/* If we have a DEFINE style macro, we may have parameters in braces,
* otherwise we may have parameters without braces.
*/
** otherwise we may have parameters without braces.
*/
if (Style == MAC_STYLE_CLASSIC) {
HaveParams = 1;
} else {
@@ -476,8 +476,8 @@ void MacDef (unsigned Style)
}
/* For class macros, we expect a separator token, for define style macros,
* we expect the closing paren.
*/
** we expect the closing paren.
*/
if (Style == MAC_STYLE_CLASSIC) {
ConsumeSep ();
} else if (HaveParams) {
@@ -485,10 +485,10 @@ void MacDef (unsigned Style)
}
/* Preparse the macro body. We will read the tokens until we reach end of
* file, or a .endmacro (or end of line for DEFINE style macros) and store
* them into an token list internal to the macro. For classic macros, there
* the .LOCAL command is detected and removed at this time.
*/
** file, or a .endmacro (or end of line for DEFINE style macros) and store
** them into an token list internal to the macro. For classic macros, there
** the .LOCAL command is detected and removed at this time.
*/
while (1) {
/* Check for end of macro */
@@ -597,8 +597,8 @@ Done:
void MacUndef (const StrBuf* Name, unsigned char Style)
/* Undefine the macro with the given name and style. A style mismatch is
* treated as if the macro didn't exist.
*/
** treated as if the macro didn't exist.
*/
{
/* Search for the macro */
Macro* M = HT_Find (&MacroTab, Name);
@@ -624,9 +624,9 @@ void MacUndef (const StrBuf* Name, unsigned char Style)
static int MacExpand (void* Data)
/* If we're currently expanding a macro, set the the scanner token and
* attribute to the next value and return true. If we are not expanding
* a macro, return false.
*/
** attribute to the next value and return true. If we are not expanding
** a macro, return false.
*/
{
/* Cast the Data pointer to the actual data structure */
MacExp* Mac = (MacExp*) Data;
@@ -645,8 +645,8 @@ static int MacExpand (void* Data)
}
/* We're expanding a macro. Check if we are expanding one of the
* macro parameters.
*/
** macro parameters.
*/
ExpandParam:
if (Mac->ParamExp) {
@@ -674,8 +674,8 @@ ExpandParam:
}
/* We're not expanding macro parameters. Check if we have tokens left from
* the macro itself.
*/
** the macro itself.
*/
if (Mac->Exp) {
/* Use next macro token */
@@ -716,10 +716,10 @@ ExpandParam:
while (I) {
if (SB_Compare (&CurTok.SVal, &I->Id) == 0) {
/* This is in fact a local symbol, change the name. Be sure
* to generate a local label name if the original name was
* a local label, and also generate a name that cannot be
* generated by a user.
*/
** to generate a local label name if the original name was
** a local label, and also generate a name that cannot be
** generated by a user.
*/
if (SB_At (&I->Id, 0) == LocalStart) {
/* Must generate a local symbol */
SB_Printf (&CurTok.SVal, "%cLOCAL-MACRO_SYMBOL-%04X",
@@ -753,14 +753,14 @@ ExpandParam:
Mac->Final = 0;
/* Problem: When a .define style macro is expanded within the call
* of a classic one, the latter may be terminated and removed while
* the expansion of the .define style macro is still active. Because
* line info slots are "stacked", this runs into a CHECK FAILED. For
* now, we will fix that by removing the .define style macro expansion
* immediately, once the final token is placed. The better solution
* would probably be to not require AllocLineInfoSlot/FreeLineInfoSlot
* to be called in FIFO order, but this is a bigger change.
*/
** of a classic one, the latter may be terminated and removed while
** the expansion of the .define style macro is still active. Because
** line info slots are "stacked", this runs into a CHECK FAILED. For
** now, we will fix that by removing the .define style macro expansion
** immediately, once the final token is placed. The better solution
** would probably be to not require AllocLineInfoSlot/FreeLineInfoSlot
** to be called in FIFO order, but this is a bigger change.
*/
/* End of macro expansion and pop the input function */
FreeMacExp (Mac);
PopInput ();
@@ -836,8 +836,8 @@ static void StartExpClassic (MacExp* E)
++E->ParamCount;
/* If the macro argument was enclosed in curly braces, end-of-line
* is an error. Skip the closing curly brace.
*/
** is an error. Skip the closing curly brace.
*/
if (Term == TOK_RCURLY) {
if (CurTok.Tok == TOK_SEP) {
Error ("End of line encountered within macro argument");
@@ -867,8 +867,8 @@ static void StartExpDefine (MacExp* E)
/* Start expanding a DEFINE style macro */
{
/* A define style macro must be called with as many actual parameters
* as there are formal ones. Get the parameter count.
*/
** as there are formal ones. Get the parameter count.
*/
unsigned Count = E->M->ParamCount;
/* Skip the current token */
@@ -915,8 +915,8 @@ static void StartExpDefine (MacExp* E)
++E->ParamCount;
/* If the macro argument was enclosed in curly braces, end-of-line
* is an error. Skip the closing curly brace.
*/
** is an error. Skip the closing curly brace.
*/
if (Term == TOK_RCURLY) {
if (TokIsSep (CurTok.Tok)) {
Error ("End of line encountered within macro argument");
@@ -936,10 +936,10 @@ static void StartExpDefine (MacExp* E)
}
/* Macro expansion will overwrite the current token. This is a problem
* for define style macros since these are called from the scanner level.
* To avoid it, remember the current token and re-insert it, once macro
* expansion is done.
*/
** for define style macros since these are called from the scanner level.
** To avoid it, remember the current token and re-insert it, once macro
** expansion is done.
*/
E->Final = NewTokNode ();
/* Insert a new token input function */
@@ -963,8 +963,8 @@ void MacExpandStart (Macro* M)
}
/* Don't allow too many nested macro expansions - otherwise it is possible
* to force an endless loop and assembler crash.
*/
** to force an endless loop and assembler crash.
*/
if (MacExpansions >= MAX_MACEXPANSIONS) {
Error ("Too many nested macro expansions");
return;
@@ -997,8 +997,8 @@ void MacAbort (void)
Macro* FindMacro (const StrBuf* Name)
/* Try to find the macro with the given name and return it. If no macro with
* this name was found, return NULL.
*/
** this name was found, return NULL.
*/
{
Macro* M = HT_Find (&MacroTab, Name);
return (M != 0 && M->Style == MAC_STYLE_CLASSIC)? M : 0;
@@ -1008,8 +1008,8 @@ Macro* FindMacro (const StrBuf* Name)
Macro* FindDefine (const StrBuf* Name)
/* Try to find the define style macro with the given name and return it. If no
* such macro was found, return NULL.
*/
** such macro was found, return NULL.
*/
{
Macro* M;
@@ -1043,8 +1043,8 @@ void DisableDefineStyleMacros (void)
void EnableDefineStyleMacros (void)
/* Re-enable define style macros previously disabled with
* DisableDefineStyleMacros.
*/
** DisableDefineStyleMacros.
*/
{
PRECONDITION (DisableDefines > 0);
--DisableDefines;

View File

@@ -75,8 +75,8 @@ void MacDef (unsigned Style);
void MacUndef (const struct StrBuf* Name, unsigned char Style);
/* Undefine the macro with the given name and style. A style mismatch is
* treated as if the macro didn't exist.
*/
** treated as if the macro didn't exist.
*/
void MacExpandStart (Macro* M);
/* Start expanding a macro */
@@ -86,13 +86,13 @@ void MacAbort (void);
Macro* FindMacro (const struct StrBuf* Name);
/* Try to find the macro with the given name and return it. If no macro with
* this name was found, return NULL.
*/
** this name was found, return NULL.
*/
Macro* FindDefine (const struct StrBuf* Name);
/* Try to find the define style macro with the given name and return it. If no
* such macro was found, return NULL.
*/
** such macro was found, return NULL.
*/
int InMacExpansion (void);
/* Return true if we're currently expanding a macro */
@@ -102,8 +102,8 @@ void DisableDefineStyleMacros (void);
void EnableDefineStyleMacros (void);
/* Re-enable define style macros previously disabled with
* DisableDefineStyleMacros.
*/
** DisableDefineStyleMacros.
*/

View File

@@ -519,8 +519,8 @@ static void OptListing (const char* Opt, const char* Arg)
/* Create a listing file */
{
/* Since the meaning of -l and --listing has changed, print an error if
* the filename is empty or begins with the option char.
*/
** the filename is empty or begins with the option char.
*/
if (Arg == 0 || *Arg == '\0' || *Arg == '-') {
Fatal ("The meaning of `%s' has changed. It does now "
"expect a file name as argument.", Opt);
@@ -635,8 +635,8 @@ static void OneLine (void)
int Instr = -1;
/* Initialize the new listing line if we are actually reading from file
* and not from internally pushed input.
*/
** and not from internally pushed input.
*/
if (!HavePushedInput ()) {
InitListingLine ();
}
@@ -648,8 +648,8 @@ static void OneLine (void)
}
/* If the first token on the line is an identifier, check for a macro or
* an instruction.
*/
** an instruction.
*/
if (CurTok.Tok == TOK_IDENT) {
if (UbiquitousIdents) {
/* Macros CAN be instructions, so check for them first */
@@ -667,9 +667,9 @@ static void OneLine (void)
}
/* Handle an identifier. This may be a cheap local symbol, or a fully
* scoped identifier which may start with a namespace token (for global
* namespace)
*/
** scoped identifier which may start with a namespace token (for global
** namespace)
*/
if (CurTok.Tok == TOK_LOCAL_IDENT ||
CurTok.Tok == TOK_NAMESPACE ||
(CurTok.Tok == TOK_IDENT && Instr < 0 && Mac == 0)) {
@@ -681,8 +681,8 @@ static void OneLine (void)
Sym = ParseAnySymName (SYM_ALLOC_NEW);
/* If a colon follows, this is a label definition. If there
* is no colon, it's an assignment.
*/
** is no colon, it's an assignment.
*/
if (CurTok.Tok == TOK_EQ || CurTok.Tok == TOK_ASSIGN) {
/* Determine the symbol flags from the assignment token */
@@ -709,8 +709,8 @@ static void OneLine (void)
Expr = GenLiteralExpr (ConstExpression ());
/* Define the symbol with the constant expression following
* the '='
*/
** the '='
*/
SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_VAR);
/* Don't allow anything after a symbol definition */
@@ -720,8 +720,8 @@ static void OneLine (void)
} else {
/* A label. Remember the current segment, so we can later
* determine the size of the data stored under the label.
*/
** determine the size of the data stored under the label.
*/
Seg = ActiveSeg;
PC = GetPC ();
@@ -729,9 +729,9 @@ static void OneLine (void)
SymDef (Sym, GenCurrentPC (), ADDR_SIZE_DEFAULT, SF_LABEL);
/* Skip the colon. If NoColonLabels is enabled, allow labels
* without a colon if there is no whitespace before the
* identifier.
*/
** without a colon if there is no whitespace before the
** identifier.
*/
if (CurTok.Tok != TOK_COLON) {
if (HadWS || !NoColonLabels) {
Error ("`:' expected");
@@ -746,8 +746,8 @@ static void OneLine (void)
}
/* If we come here, a new identifier may be waiting, which may
* be a macro or instruction.
*/
** be a macro or instruction.
*/
if (CurTok.Tok == TOK_IDENT) {
if (UbiquitousIdents) {
/* Macros CAN be instructions, so check for them first */
@@ -790,9 +790,9 @@ static void OneLine (void)
}
/* If we have defined a label, remember its size. Sym is also set by
* a symbol assignment, but in this case Done is false, so we don't
* come here.
*/
** a symbol assignment, but in this case Done is false, so we don't
** come here.
*/
if (Sym) {
unsigned long Size;
if (Seg == ActiveSeg) {
@@ -916,13 +916,13 @@ int main (int argc, char* argv [])
SegInit ();
/* Enter the base lexical level. We must do that here, since we may
* define symbols using -D.
*/
** define symbols using -D.
*/
SymEnterLevel (&GlobalNameSpace, SCOPE_FILE, ADDR_SIZE_DEFAULT, 0);
/* Initialize the line infos. Must be done here, since we need line infos
* for symbol definitions.
*/
** for symbol definitions.
*/
InitLineInfo ();
/* Check the parameters */
@@ -1104,8 +1104,8 @@ int main (int argc, char* argv [])
DoneLineInfo ();
/* If we didn't have any errors, create the object, listing and
* dependency files
*/
** dependency files
*/
if (ErrorCount == 0) {
CreateObjFile ();
if (SB_GetLen (&ListingName) > 0) {

View File

@@ -70,9 +70,9 @@ static unsigned RawMode = 0; /* Raw token mode flag/counter */
static int LookAtStrCon (void)
/* Make sure the next token is a string constant. If not, print an error
* messages skip the remainder of the line and return false. Otherwise return
* true.
*/
** messages skip the remainder of the line and return false. Otherwise return
** true.
*/
{
if (CurTok.Tok != TOK_STRCON) {
Error ("String constant expected");
@@ -93,10 +93,10 @@ static int LookAtStrCon (void)
static TokList* CollectTokens (unsigned Start, unsigned Count)
/* Read a list of tokens that is optionally enclosed in curly braces and
* terminated by a right paren. For all tokens starting at the one with index
* Start, and ending at (Start+Count-1), place them into a token list, and
* return this token list.
*/
** terminated by a right paren. For all tokens starting at the one with index
** Start, and ending at (Start+Count-1), place them into a token list, and
** return this token list.
*/
{
/* Create the token list */
@@ -176,8 +176,8 @@ static void FuncConcat (void)
}
/* We expect a closing parenthesis, but will not skip it but replace it
* by the string token just created.
*/
** by the string token just created.
*/
if (CurTok.Tok != TOK_RPAREN) {
Error ("`)' expected");
} else {
@@ -220,8 +220,8 @@ static void FuncIdent (void)
}
/* Check that the string contains a valid identifier. While doing so,
* determine if it is a cheap local, or global one.
*/
** determine if it is a cheap local, or global one.
*/
SB_Reset (&CurTok.SVal);
/* Check for a cheap local symbol */
@@ -248,8 +248,8 @@ static void FuncIdent (void)
}
/* If anything is ok, save and skip the string. Check that the next token
* is a right paren, then replace the token by an identifier token.
*/
** is a right paren, then replace the token by an identifier token.
*/
SB_Copy (&Buf, &CurTok.SVal);
NextTok ();
if (CurTok.Tok != TOK_RPAREN) {
@@ -289,12 +289,12 @@ static void FuncLeft (void)
List = CollectTokens (0, (unsigned) Count);
/* Since we want to insert the list before the now current token, we have
* to save the current token in some way and then skip it. To do this, we
* will add the current token at the end of the token list (so the list
* will never be empty), push the token list, and then skip the current
* token. This will replace the current token by the first token from the
* list (which will be the old current token in case the list was empty).
*/
** to save the current token in some way and then skip it. To do this, we
** will add the current token at the end of the token list (so the list
** will never be empty), push the token list, and then skip the current
** token. This will replace the current token by the first token from the
** list (which will be the old current token in case the list was empty).
*/
AddCurTok (List);
/* Insert it into the scanner feed */
@@ -320,8 +320,8 @@ static void FuncMid (void)
ConsumeLParen ();
/* Start argument. Since the start argument can get negative with
* expressions like ".tcount(arg)-2", we correct it to zero silently.
*/
** expressions like ".tcount(arg)-2", we correct it to zero silently.
*/
Start = ConstExpression ();
if (Start < 0 || Start > 100) {
Start = 0;
@@ -329,8 +329,8 @@ static void FuncMid (void)
ConsumeComma ();
/* Count argument. Similar as above, we will accept negative counts and
* correct them to zero silently.
*/
** correct them to zero silently.
*/
Count = ConstExpression ();
if (Count < 0) {
Count = 0;
@@ -341,12 +341,12 @@ static void FuncMid (void)
List = CollectTokens ((unsigned) Start, (unsigned) Count);
/* Since we want to insert the list before the now current token, we have
* to save the current token in some way and then skip it. To do this, we
* will add the current token at the end of the token list (so the list
* will never be empty), push the token list, and then skip the current
* token. This will replace the current token by the first token from the
* list (which will be the old current token in case the list was empty).
*/
** to save the current token in some way and then skip it. To do this, we
** will add the current token at the end of the token list (so the list
** will never be empty), push the token list, and then skip the current
** token. This will replace the current token by the first token from the
** list (which will be the old current token in case the list was empty).
*/
AddCurTok (List);
/* Insert it into the scanner feed */
@@ -396,12 +396,12 @@ static void FuncRight (void)
}
/* Since we want to insert the list before the now current token, we have
* to save the current token in some way and then skip it. To do this, we
* will add the current token at the end of the token list (so the list
* will never be empty), push the token list, and then skip the current
* token. This will replace the current token by the first token from the
* list (which will be the old current token in case the list was empty).
*/
** to save the current token in some way and then skip it. To do this, we
** will add the current token at the end of the token list (so the list
** will never be empty), push the token list, and then skip the current
** token. This will replace the current token by the first token from the
** list (which will be the old current token in case the list was empty).
*/
AddCurTok (List);
/* Insert it into the scanner feed */
@@ -474,15 +474,15 @@ static void FuncSPrintF (void)
break;
}
/* Since a format specifier follows, we do expect anotehr argument for
* the .sprintf function.
*/
/* Since a format specifier follows, we do expect another argument for
** the .sprintf function.
*/
ConsumeComma ();
/* We will copy the format spec into F1 checking for the things we
* support, and later use xsprintf to do the actual formatting. This
* is easier than adding another printf implementation...
*/
** support, and later use xsprintf to do the actual formatting. This
** is easier than adding another printf implementation...
*/
SB_Clear (&F1);
SB_AppendChar (&F1, '%');
@@ -522,8 +522,8 @@ static void FuncSPrintF (void)
case 'X':
case 'x':
/* Our ints are actually longs, so we use the 'l' modifier when
* calling xsprintf later. Terminate the format string.
*/
** calling xsprintf later. Terminate the format string.
*/
SB_AppendChar (&F1, 'l');
SB_AppendChar (&F1, SB_Get (&Format));
SB_Terminate (&F1);
@@ -576,8 +576,8 @@ static void FuncSPrintF (void)
}
/* Format this argument according to the spec. Be sure to pass
* an int as the char value.
*/
** an int as the char value.
*/
SB_Printf (&R1, SB_GetConstBuf (&F1), (int) IVal);
/* Append the formatted argument to the result */
@@ -597,8 +597,8 @@ static void FuncSPrintF (void)
SB_Terminate (&R);
/* We expect a closing parenthesis, but will not skip it but replace it
* by the string token just created.
*/
** by the string token just created.
*/
if (CurTok.Tok != TOK_RPAREN) {
Error ("`)' expected");
} else {
@@ -636,8 +636,8 @@ static void FuncString (void)
} else if (CurTok.Tok == TOK_NAMESPACE || CurTok.Tok == TOK_IDENT) {
/* Parse a fully qualified symbol name. We cannot use
* ParseScopedSymName here since the name may be invalid.
*/
** ParseScopedSymName here since the name may be invalid.
*/
int NameSpace;
do {
NameSpace = (CurTok.Tok == TOK_NAMESPACE);
@@ -657,8 +657,8 @@ static void FuncString (void)
}
/* We expect a closing parenthesis, but will not skip it but replace it
* by the string token just created.
*/
** by the string token just created.
*/
if (CurTok.Tok != TOK_RPAREN) {
Error ("`)' expected");
} else {
@@ -680,8 +680,8 @@ void NextTok (void)
NextRawTok ();
/* In raw mode, or when output is suppressed via conditional assembly,
* pass the token unchanged.
*/
** pass the token unchanged.
*/
if (RawMode == 0 && IfCond) {
/* Execute token handling functions */
@@ -787,8 +787,8 @@ void SkipUntilSep (void)
void ExpectSep (void)
/* Check if we've reached a line separator, and output an error if not. Do
* not skip the line separator.
*/
** not skip the line separator.
*/
{
if (!TokIsSep (CurTok.Tok)) {
ErrorSkip ("Unexpected trailing garbage characters");
@@ -799,11 +799,11 @@ void ExpectSep (void)
void EnterRawTokenMode (void)
/* Enter raw token mode. In raw mode, token handling functions are not
* executed, but the function tokens are passed untouched to the upper
* layer. Raw token mode is used when storing macro tokens for later
* use.
* Calls to EnterRawTokenMode and LeaveRawTokenMode may be nested.
*/
** executed, but the function tokens are passed untouched to the upper
** layer. Raw token mode is used when storing macro tokens for later
** use.
** Calls to EnterRawTokenMode and LeaveRawTokenMode may be nested.
*/
{
++RawMode;
}

View File

@@ -71,16 +71,16 @@ void SkipUntilSep (void);
void ExpectSep (void);
/* Check if we've reached a line separator, and output an error if not. Do
* not skip the line separator.
*/
** not skip the line separator.
*/
void EnterRawTokenMode (void);
/* Enter raw token mode. In raw mode, token handling functions are not
* executed, but the function tokens are passed untouched to the upper
* layer. Raw token mode is used when storing macro tokens for later
* use.
* Calls to EnterRawTokenMode and LeaveRawTokenMode may be nested.
*/
** executed, but the function tokens are passed untouched to the upper
** layer. Raw token mode is used when storing macro tokens for later
** use.
** Calls to EnterRawTokenMode and LeaveRawTokenMode may be nested.
*/
void LeaveRawTokenMode (void);
/* Leave raw token mode. */

View File

@@ -100,8 +100,8 @@ static ObjHeader Header = {
static void ObjWriteError (void)
/* Called on a write error. Will try to close and remove the file, then
* print a fatal error.
*/
** print a fatal error.
*/
{
/* Remember the error */
int Error = errno;
@@ -162,8 +162,8 @@ void ObjOpen (void)
/* Do we have a name for the output file? */
if (OutFile == 0) {
/* We don't have an output name explicitly given, construct one from
* the name of the input file.
*/
** the name of the input file.
*/
OutFile = MakeFilename (InFile, OBJ_EXT);
}
@@ -269,10 +269,10 @@ void ObjWriteVar (unsigned long V)
/* Write a variable sized value to the file in special encoding */
{
/* We will write the value to the file in 7 bit chunks. If the 8th bit
* is clear, we're done, if it is set, another chunk follows. This will
* allow us to encode smaller values with less bytes, at the expense of
* needing 5 bytes if a 32 bit value is written to file.
*/
** is clear, we're done, if it is set, another chunk follows. This will
** allow us to encode smaller values with less bytes, at the expense of
** needing 5 bytes if a 32 bit value is written to file.
*/
do {
unsigned char C = (V & 0x7F);
V >>= 7;
@@ -291,9 +291,9 @@ void ObjWriteStr (const char* S)
unsigned Len = strlen (S);
/* Write the string with the length preceeded (this is easier for
* the reading routine than the C format since the length is known in
* advance).
*/
** the reading routine than the C format since the length is known in
** advance).
*/
ObjWriteVar (Len);
ObjWriteData (S, Len);
}
@@ -304,9 +304,9 @@ void ObjWriteBuf (const StrBuf* S)
/* Write a string to the object file */
{
/* Write the string with the length preceeded (this is easier for
* the reading routine than the C format since the length is known in
* advance).
*/
** the reading routine than the C format since the length is known in
** advance).
*/
ObjWriteVar (SB_GetLen (S));
ObjWriteData (SB_GetConstBuf (S), SB_GetLen (S));
}

View File

@@ -112,12 +112,12 @@ static void DoUnexpected (void);
static void DoInvalid (void);
/* Handle a token that is invalid here, since it should have been handled on
* a much lower level of the expression hierarchy. Getting this sort of token
* means that the lower level code has bugs.
* This function differs to DoUnexpected in that the latter may be triggered
* by the user by using keywords in the wrong location. DoUnexpected is not
* an error in the assembler itself, while DoInvalid is.
*/
** a much lower level of the expression hierarchy. Getting this sort of token
** means that the lower level code has bugs.
** This function differs to DoUnexpected in that the latter may be triggered
** by the user by using keywords in the wrong location. DoUnexpected is not
** an error in the assembler itself, while DoInvalid is.
*/
@@ -129,8 +129,8 @@ static void DoInvalid (void);
static unsigned char OptionalAddrSize (void)
/* If a colon follows, parse an optional address size spec and return it.
* Otherwise return ADDR_SIZE_DEFAULT.
*/
** Otherwise return ADDR_SIZE_DEFAULT.
*/
{
unsigned AddrSize = ADDR_SIZE_DEFAULT;
if (CurTok.Tok == TOK_COLON) {
@@ -183,8 +183,8 @@ static void ExportWithAssign (SymEntry* Sym, unsigned char AddrSize, unsigned Fl
/* Allow to assign the value of an export in an .export statement */
{
/* The name and optional address size spec may be followed by an assignment
* or equal token.
*/
** or equal token.
*/
if (CurTok.Tok == TOK_ASSIGN || CurTok.Tok == TOK_EQ) {
/* Assignment means the symbol is a label */
@@ -249,8 +249,8 @@ static void ExportImport (void (*Func) (SymEntry*, unsigned char, unsigned),
static long IntArg (long Min, long Max)
/* Read an integer argument and check a range. Accept the token "unlimited"
* and return -1 in this case.
*/
** and return -1 in this case.
*/
{
if (CurTok.Tok == TOK_IDENT && SB_CompareStr (&CurTok.SVal, "unlimited") == 0) {
NextTok ();
@@ -301,9 +301,9 @@ static StrBuf* GenArrayType (StrBuf* Type, unsigned SpanSize,
const char* ElementType,
unsigned ElementTypeLen)
/* Create an array (or single data) of the given type. SpanSize is the size
* of the span, ElementType is a string that encodes the element data type.
* The function returns Type.
*/
** of the span, ElementType is a string that encodes the element data type.
** The function returns Type.
*/
{
/* Get the size of the element type */
unsigned ElementSize = GT_GET_SIZE (ElementType[0]);
@@ -504,8 +504,8 @@ static void DoAssert (void)
NextTok ();
/* We can have an optional message. If no message is present, use
* "Assertion failed".
*/
** "Assertion failed".
*/
if (CurTok.Tok == TOK_COMMA) {
/* Skip the comma */
@@ -518,8 +518,8 @@ static void DoAssert (void)
}
/* Translate the message into a string id. We can then skip the input
* string.
*/
** string.
*/
Msg = GetStrBufId (&CurTok.SVal);
NextTok ();
@@ -1253,14 +1253,14 @@ static void DoIncBin (void)
fseek (F, 0, SEEK_END);
Size = ftell (F);
/* Stat the file and remember the values. There a race condition here,
* since we cannot use fileno() (non standard identifier in standard
* header file), and therefore not fstat. When using stat with the
* file name, there's a risk that the file was deleted and recreated
* while it was open. Since mtime and size are only used to check
* if a file has changed in the debugger, we will ignore this problem
* here.
*/
/* Stat the file and remember the values. There's a race condition here,
** since we cannot use fileno() (non-standard identifier in standard
** header file), and therefore not fstat. When using stat with the
** file name, there's a risk that the file was deleted and recreated
** while it was open. Since mtime and size are only used to check
** if a file has changed in the debugger, we will ignore this problem
** here.
*/
SB_Terminate (&Name);
if (FileStat (SB_GetConstBuf (&Name), &StatBuf) != 0) {
Fatal ("Cannot stat input file `%m%p': %s", &Name, strerror (errno));
@@ -1364,12 +1364,12 @@ static void DoInterruptor (void)
static void DoInvalid (void)
/* Handle a token that is invalid here, since it should have been handled on
* a much lower level of the expression hierarchy. Getting this sort of token
* means that the lower level code has bugs.
* This function differs to DoUnexpected in that the latter may be triggered
* by the user by using keywords in the wrong location. DoUnexpected is not
* an error in the assembler itself, while DoInvalid is.
*/
** a much lower level of the expression hierarchy. Getting this sort of token
** means that the lower level code has bugs.
** This function differs to DoUnexpected in that the latter may be triggered
** by the user by using keywords in the wrong location. DoUnexpected is not
** an error in the assembler itself, while DoInvalid is.
*/
{
Internal ("Unexpected token: %m%p", &Keyword);
}
@@ -1494,8 +1494,8 @@ static void DoOut (void)
ErrorSkip ("String constant expected");
} else {
/* Output the string and be sure to flush the output to keep it in
* sync with any error messages if the output is redirected to a file.
*/
** sync with any error messages if the output is redirected to a file.
*/
printf ("%.*s\n",
(int) SB_GetLen (&CurTok.SVal),
SB_GetConstBuf (&CurTok.SVal));
@@ -1794,8 +1794,8 @@ static void DoSetCPU (void)
SetCPU (CPU);
/* Skip the identifier. If the CPU switch was successful, the scanner
* will treat the input now correctly for the new CPU.
*/
** will treat the input now correctly for the new CPU.
*/
NextTok ();
}
}
@@ -1861,10 +1861,10 @@ static void DoUnDef (void)
/* Undefine a define style macro */
{
/* The function is called with the .UNDEF token in place, because we need
* to disable .define macro expansions before reading the next token.
* Otherwise the name of the macro would be expanded, so we would never
* see it.
*/
** to disable .define macro expansions before reading the next token.
** Otherwise the name of the macro would be expanded, so we would never
** see it.
*/
DisableDefineStyleMacros ();
NextTok ();
EnableDefineStyleMacros ();

View File

@@ -55,8 +55,8 @@
static TokList* CollectRepeatTokens (void)
/* Collect all tokens inside the .REPEAT body in a token list and return
* this list. In case of errors, NULL is returned.
*/
** this list. In case of errors, NULL is returned.
*/
{
/* Create the token list */
TokList* List = NewTokList ();
@@ -97,8 +97,8 @@ static TokList* CollectRepeatTokens (void)
static void RepeatTokenCheck (TokList* L)
/* Called each time a token from a repeat token list is set. Is used to check
* for and replace identifiers that are the repeat counter.
*/
** for and replace identifiers that are the repeat counter.
*/
{
if (CurTok.Tok == TOK_IDENT &&
L->Data != 0 &&
@@ -161,8 +161,8 @@ void ParseRepeat (void)
List->Check = RepeatTokenCheck;
/* If the list is empty, or repeat count zero, there is nothing
* to repeat.
*/
** to repeat.
*/
if (List->Count == 0 || RepCount == 0) {
FreeTokList (List);
goto Done;

View File

@@ -313,8 +313,8 @@ static void UseCharSource (CharSource* S)
S->Func->NextChar (S);
/* Setup the next token so it will be skipped on the next call to
* NextRawTok().
*/
** NextRawTok().
*/
CurTok.Tok = TOK_SEP;
}
@@ -378,8 +378,8 @@ static void IFNextChar (CharSource* S)
}
/* No more data - add an empty line to the listing. This
* is a small hack needed to keep the PC output in sync.
*/
** is a small hack needed to keep the PC output in sync.
*/
NewListingLine (&EmptyStrBuf, S->V.File.Pos.Name, FCount);
C = EOF;
return;
@@ -401,9 +401,9 @@ static void IFNextChar (CharSource* S)
/* If we come here, we have a new input line. To avoid problems
* with strange line terminators, remove all whitespace from the
* end of the line, the add a single newline.
*/
** with strange line terminators, remove all whitespace from the
** end of the line, the add a single newline.
*/
Len = SB_GetLen (&S->V.File.Line);
while (Len > 0 && IsSpace (SB_AtUnchecked (&S->V.File.Line, Len-1))) {
--Len;
@@ -435,11 +435,11 @@ void IFDone (CharSource* S)
/* Close the current input file */
{
/* We're at the end of an include file. Check if we have any
* open .IFs, or any open token lists in this file. This
* enforcement is artificial, using conditionals that start
* in one file and end in another are uncommon, and don't
* allowing these things will help finding errors.
*/
** open .IFs, or any open token lists in this file. This
** enforcement is artificial, using conditionals that start
** in one file and end in another are uncommon, and don't
** allowing these things will help finding errors.
*/
CheckOpenIfs ();
/* If we've added search paths for this file, remove them */
@@ -454,8 +454,8 @@ void IFDone (CharSource* S)
SB_Done (&S->V.File.Line);
/* Close the input file and decrement the file count. We will ignore
* errors here, since we were just reading from the file.
*/
** errors here, since we were just reading from the file.
*/
(void) fclose (S->V.File.F);
--FCount;
}
@@ -473,8 +473,8 @@ static const CharSourceFunctions IFFunc = {
int NewInputFile (const char* Name)
/* Open a new input file. Returns true if the file could be successfully opened
* and false otherwise.
*/
** and false otherwise.
*/
{
int RetCode = 0; /* Return code. Assume an error. */
char* PathName = 0;
@@ -487,8 +487,8 @@ int NewInputFile (const char* Name)
/* If this is the main file, just try to open it. If it's an include file,
* search for it using the include path list.
*/
** search for it using the include path list.
*/
if (FCount == 0) {
/* Main file */
F = fopen (Name, "r");
@@ -497,8 +497,8 @@ int NewInputFile (const char* Name)
}
} else {
/* We are on include level. Search for the file in the include
* directories.
*/
** directories.
*/
PathName = SearchFile (IncSearchPath, Name);
if (PathName == 0 || (F = fopen (PathName, "r")) == 0) {
/* Not found or cannot open, print an error and bail out */
@@ -510,14 +510,14 @@ int NewInputFile (const char* Name)
Name = PathName;
}
/* Stat the file and remember the values. There a race condition here,
* since we cannot use fileno() (non standard identifier in standard
* header file), and therefore not fstat. When using stat with the
* file name, there's a risk that the file was deleted and recreated
* while it was open. Since mtime and size are only used to check
* if a file has changed in the debugger, we will ignore this problem
* here.
*/
/* Stat the file and remember the values. There's a race condition here,
** since we cannot use fileno() (non-standard identifier in standard
** header file), and therefore not fstat. When using stat with the
** file name, there's a risk that the file was deleted and recreated
** while it was open. Since mtime and size are only used to check
** if a file has changed in the debugger, we will ignore this problem
** here.
*/
if (FileStat (Name, &Buf) != 0) {
Fatal ("Cannot stat input file `%s': %s", Name, strerror (errno));
}
@@ -704,8 +704,8 @@ static int CmpDotKeyword (const void* K1, const void* K2)
static token_t FindDotKeyword (void)
/* Find the dot keyword in SVal. Return the corresponding token if found,
* return TOK_NONE if not found.
*/
** return TOK_NONE if not found.
*/
{
struct DotKeyword K;
struct DotKeyword* R;
@@ -733,10 +733,10 @@ static token_t FindDotKeyword (void)
static void ReadIdent (void)
/* Read an identifier from the current input position into Ident. Filling SVal
* starts at the current position with the next character in C. It is assumed
* that any characters already filled in are ok, and the character in C is
* checked.
*/
** starts at the current position with the next character in C. It is assumed
** that any characters already filled in are ok, and the character in C is
** checked.
*/
{
/* Read the identifier */
do {
@@ -787,8 +787,8 @@ static void ReadStringConst (int StringTerm)
static int Sweet16Reg (const StrBuf* Id)
/* Check if the given identifier is a sweet16 register. Return -1 if this is
* not the case, return the register number otherwise.
*/
** not the case, return the register number otherwise.
*/
{
unsigned RegNum;
char Check;
@@ -960,9 +960,9 @@ Again:
}
if (IsXDigit (C)) {
/* Buf is big enough to allow any decimal and hex number to
* overflow, so ignore excess digits here, they will be detected
* when we convert the value.
*/
** overflow, so ignore excess digits here, they will be detected
** when we convert the value.
*/
if (Digits < sizeof (Buf)) {
Buf[Digits++] = C;
}
@@ -1034,8 +1034,8 @@ Again:
}
/* An identifier with a dot. Check if it's a define style
* macro.
*/
** macro.
*/
if ((M = FindDefine (&CurTok.SVal)) != 0) {
/* This is a define style macro - expand it */
MacExpandStart (M);
@@ -1051,8 +1051,8 @@ Again:
}
/* Indirect op for sweet16 cpu. Must check this before checking for local
* symbols, because these may also use the '@' symbol.
*/
** symbols, because these may also use the '@' symbol.
*/
if (CPU == CPU_SWEET16 && C == '@') {
NextChar ();
CurTok.Tok = TOK_AT;
@@ -1084,8 +1084,8 @@ Again:
ReadIdent ();
/* Check for special names. Bail out if we have identified the type of
* the token. Go on if the token is an identifier.
*/
** the token. Go on if the token is an identifier.
*/
if (SB_GetLen (&CurTok.SVal) == 1) {
switch (toupper (SB_AtUnchecked (&CurTok.SVal, 0))) {
@@ -1357,9 +1357,9 @@ CharAgain:
case '\'':
/* Hack: If we allow ' as terminating character for strings, read
* the following stuff as a string, and check for a one character
* string later.
*/
** the following stuff as a string, and check for a one character
** string later.
*/
if (LooseStringTerm) {
ReadStringConst ('\'');
if (SB_GetLen (&CurTok.SVal) == 1) {
@@ -1424,8 +1424,8 @@ CharAgain:
}
/* If we go here, we could not identify the current character. Skip it
* and try again.
*/
** and try again.
*/
Error ("Invalid input character: 0x%02X", C & 0xFF);
NextChar ();
goto Again;
@@ -1435,10 +1435,10 @@ CharAgain:
int GetSubKey (const char** Keys, unsigned Count)
/* Search for a subkey in a table of keywords. The current token must be an
* identifier and all keys must be in upper case. The identifier will be
* uppercased in the process. The function returns the index of the keyword,
* or -1 if the keyword was not found.
*/
** identifier and all keys must be in upper case. The identifier will be
** uppercased in the process. The function returns the index of the keyword,
** or -1 if the keyword was not found.
*/
{
unsigned I;
@@ -1466,9 +1466,9 @@ int GetSubKey (const char** Keys, unsigned Count)
unsigned char ParseAddrSize (void)
/* Check if the next token is a keyword that denotes an address size specifier.
* If so, return the corresponding address size constant, otherwise output an
* error message and return ADDR_SIZE_DEFAULT.
*/
** If so, return the corresponding address size constant, otherwise output an
** error message and return ADDR_SIZE_DEFAULT.
*/
{
unsigned char AddrSize;

View File

@@ -69,8 +69,8 @@ int IsIdStart (int C);
int NewInputFile (const char* Name);
/* Open a new input file. Returns true if the file could be successfully opened
* and false otherwise.
*/
** and false otherwise.
*/
void NewInputData (char* Text, int Malloced);
/* Add a chunk of input data to the input stream */
@@ -86,16 +86,16 @@ void NextRawTok (void);
int GetSubKey (const char** Keys, unsigned Count);
/* Search for a subkey in a table of keywords. The current token must be an
* identifier and all keys must be in upper case. The identifier will be
* uppercased in the process. The function returns the index of the keyword,
* or -1 if the keyword was not found.
*/
** identifier and all keys must be in upper case. The identifier will be
** uppercased in the process. The function returns the index of the keyword,
** or -1 if the keyword was not found.
*/
unsigned char ParseAddrSize (void);
/* Check if the next token is a keyword that denotes an address size specifier.
* If so, return the corresponding address size constant, otherwise output an
* error message and return ADDR_SIZE_DEFAULT.
*/
** If so, return the corresponding address size constant, otherwise output an
** error message and return ADDR_SIZE_DEFAULT.
*/
void InitScanner (const char* InFile);
/* Initialize the scanner, open the given input file */

View File

@@ -68,8 +68,8 @@
/* If OrgPerSeg is false, all segments share the RelocMode flag and a PC
* used when in absolute mode. OrgPerSeg may be set by .feature org_per_seg
*/
** used when in absolute mode. OrgPerSeg may be set by .feature org_per_seg
*/
static int RelocMode = 1;
static unsigned long AbsPC = 0; /* PC if in absolute mode */
@@ -97,8 +97,8 @@ Segment* ActiveSeg;
static Segment* NewSegFromDef (SegDef* Def)
/* Create a new segment from a segment definition. Used only internally, no
* checks.
*/
** checks.
*/
{
/* Create a new segment */
Segment* S = xmalloc (sizeof (*S));
@@ -233,8 +233,8 @@ unsigned long GetPC (void)
void EnterAbsoluteMode (unsigned long PC)
/* Enter absolute (non relocatable mode). Depending on the OrgPerSeg flag,
* this will either switch the mode globally or for the current segment.
*/
** this will either switch the mode globally or for the current segment.
*/
{
if (OrgPerSeg) {
/* Relocatable mode is switched per segment */
@@ -265,8 +265,8 @@ int GetRelocMode (void)
void EnterRelocMode (void)
/* Enter relocatable mode. Depending on the OrgPerSeg flag, this will either
* switch the mode globally or for the current segment.
*/
** switch the mode globally or for the current segment.
*/
{
if (OrgPerSeg) {
/* Relocatable mode is switched per segment */
@@ -281,25 +281,25 @@ void EnterRelocMode (void)
void SegAlign (unsigned long Alignment, int FillVal)
/* Align the PC segment to Alignment. If FillVal is -1, emit fill fragments
* (the actual fill value will be determined by the linker), otherwise use
* the given value.
*/
** (the actual fill value will be determined by the linker), otherwise use
** the given value.
*/
{
unsigned char Data [4];
unsigned long CombinedAlignment;
unsigned long Count;
/* The segment must have the combined alignment of all separate alignments
* in the source. Calculate this alignment and check it for sanity.
*/
** in the source. Calculate this alignment and check it for sanity.
*/
CombinedAlignment = LeastCommonMultiple (ActiveSeg->Align, Alignment);
if (CombinedAlignment > MAX_ALIGNMENT) {
Error ("Combined alignment for active segment is %lu which exceeds %lu",
CombinedAlignment, MAX_ALIGNMENT);
/* Avoid creating large fills for an object file that is thrown away
* later.
*/
** later.
*/
Count = 1;
} else {
@@ -410,10 +410,10 @@ void SegDone (void)
} else if (RelaxChecks == 0) {
/* We cannot evaluate the expression now, leave the job for
* the linker. However, we can check if the address size
* matches the fragment size. Mismatches are errors in
* most situations.
*/
** the linker. However, we can check if the address size
** matches the fragment size. Mismatches are errors in
** most situations.
*/
if ((F->Len == 1 && ED.AddrSize > ADDR_SIZE_ZP) ||
(F->Len == 2 && ED.AddrSize > ADDR_SIZE_ABS) ||
(F->Len == 3 && ED.AddrSize > ADDR_SIZE_FAR)) {
@@ -496,9 +496,9 @@ void SetSegmentSizes (void)
/* Set the default segment sizes according to the memory model */
{
/* Initialize segment sizes. The segment definitions do already contain
* the correct values for the default case (near), so we must only change
* things that should be different.
*/
** the correct values for the default case (near), so we must only change
** things that should be different.
*/
switch (MemoryModel) {
case MMODEL_NEAR:
@@ -530,8 +530,8 @@ static void WriteOneSeg (Segment* Seg)
unsigned long EndPos;
/* Remember the file position, then write a dummy for the size of the
* following data
*/
** following data
*/
unsigned long SizePos = ObjGetFilePos ();
ObjWrite32 (0);
@@ -544,8 +544,8 @@ static void WriteOneSeg (Segment* Seg)
ObjWriteVar (Seg->FragCount); /* Number of fragments */
/* Now walk through the fragment list for this segment and write the
* fragments.
*/
** fragments.
*/
Frag = Seg->Root;
while (Frag) {

View File

@@ -131,9 +131,9 @@ INLINE unsigned char GetCurrentSegAddrSize (void)
void SegAlign (unsigned long Alignment, int FillVal);
/* Align the PC segment to Alignment. If FillVal is -1, emit fill fragments
* (the actual fill value will be determined by the linker), otherwise use
* the given value.
*/
** (the actual fill value will be determined by the linker), otherwise use
** the given value.
*/
unsigned char GetSegAddrSize (unsigned SegNum);
/* Return the address size of the segment with the given number */
@@ -146,13 +146,13 @@ int GetRelocMode (void);
void EnterAbsoluteMode (unsigned long AbsPC);
/* Enter absolute (non relocatable mode). Depending on the OrgPerSeg flag,
* this will either switch the mode globally or for the current segment.
*/
** this will either switch the mode globally or for the current segment.
*/
void EnterRelocMode (void);
/* Enter relocatable mode. Depending on the OrgPerSeg flag, this will either
* switch the mode globally or for the current segment.
*/
** switch the mode globally or for the current segment.
*/
void SegDone (void);
/* Check the segments for range and other errors. Do cleanup. */

View File

@@ -50,8 +50,8 @@
/* The name of the symbol used to encode the size. The name of this entry is
* choosen so that it cannot be accessed by the user.
*/
** choosen so that it cannot be accessed by the user.
*/
static const StrBuf SizeEntryName = LIT_STRBUF_INITIALIZER (".size");
@@ -64,8 +64,8 @@ static const StrBuf SizeEntryName = LIT_STRBUF_INITIALIZER (".size");
int IsSizeOfSymbol (const SymEntry* Sym)
/* Return true if the given symbol is the one that encodes the size of some
* entity. Sym may also be a NULL pointer in which case false is returned.
*/
** entity. Sym may also be a NULL pointer in which case false is returned.
*/
{
return (Sym != 0 && SB_Compare (GetSymName (Sym), &SizeEntryName) == 0);
}
@@ -74,8 +74,8 @@ int IsSizeOfSymbol (const SymEntry* Sym)
SymEntry* FindSizeOfScope (SymTable* Scope)
/* Get the size of a scope. The function returns the symbol table entry that
* encodes the size or NULL if there is no such entry.
*/
** encodes the size or NULL if there is no such entry.
*/
{
return SymFind (Scope, &SizeEntryName, SYM_FIND_EXISTING);
}
@@ -84,8 +84,8 @@ SymEntry* FindSizeOfScope (SymTable* Scope)
SymEntry* FindSizeOfSymbol (SymEntry* Sym)
/* Get the size of a symbol table entry. The function returns the symbol table
* entry that encodes the size of the symbol or NULL if there is no such entry.
*/
** entry that encodes the size of the symbol or NULL if there is no such entry.
*/
{
return SymFindLocal (Sym, &SizeEntryName, SYM_FIND_EXISTING);
}
@@ -94,8 +94,8 @@ SymEntry* FindSizeOfSymbol (SymEntry* Sym)
SymEntry* GetSizeOfScope (SymTable* Scope)
/* Get the size of a scope. The function returns the symbol table entry that
* encodes the size, and will create a new entry if it does not exist.
*/
** encodes the size, and will create a new entry if it does not exist.
*/
{
return SymFind (Scope, &SizeEntryName, SYM_ALLOC_NEW);
}
@@ -104,9 +104,9 @@ SymEntry* GetSizeOfScope (SymTable* Scope)
SymEntry* GetSizeOfSymbol (SymEntry* Sym)
/* Get the size of a symbol table entry. The function returns the symbol table
* entry that encodes the size of the symbol and will create a new one if it
* does not exist.
*/
** entry that encodes the size of the symbol and will create a new one if it
** does not exist.
*/
{
return SymFindLocal (Sym, &SizeEntryName, SYM_ALLOC_NEW);
}

View File

@@ -62,29 +62,29 @@ struct SymTable;
int IsSizeOfSymbol (const struct SymEntry* Sym);
/* Return true if the given symbol is the one that encodes the size of some
* entity. Sym may also be a NULL pointer in which case false is returned.
*/
** entity. Sym may also be a NULL pointer in which case false is returned.
*/
struct SymEntry* FindSizeOfScope (struct SymTable* Scope);
/* Get the size of a scope. The function returns the symbol table entry that
* encodes the size or NULL if there is no such entry.
*/
** encodes the size or NULL if there is no such entry.
*/
struct SymEntry* FindSizeOfSymbol (struct SymEntry* Sym);
/* Get the size of a symbol table entry. The function returns the symbol table
* entry that encodes the size of the symbol or NULL if there is no such entry.
*/
** entry that encodes the size of the symbol or NULL if there is no such entry.
*/
struct SymEntry* GetSizeOfScope (struct SymTable* Scope);
/* Get the size of a scope. The function returns the symbol table entry that
* encodes the size, and will create a new entry if it does not exist.
*/
** encodes the size, and will create a new entry if it does not exist.
*/
struct SymEntry* GetSizeOfSymbol (struct SymEntry* Sym);
/* Get the size of a symbol table entry. The function returns the symbol table
* entry that encodes the size of the symbol and will create a new one if it
* does not exist.
*/
** entry that encodes the size of the symbol and will create a new one if it
** does not exist.
*/
struct SymEntry* DefSizeOfScope (struct SymTable* Scope, long Size);
/* Define the size of a scope and return the size symbol */

View File

@@ -61,9 +61,9 @@ static const void* HT_GetKey (const void* Entry);
static int HT_Compare (const void* Key1, const void* Key2);
/* Compare two keys. The function must return a value less than zero if
* Key1 is smaller than Key2, zero if both are equal, and a value greater
* than zero if Key1 is greater then Key2.
*/
** Key1 is smaller than Key2, zero if both are equal, and a value greater
** than zero if Key1 is greater then Key2.
*/
@@ -113,9 +113,9 @@ static const void* HT_GetKey (const void* Entry)
static int HT_Compare (const void* Key1, const void* Key2)
/* Compare two keys. The function must return a value less than zero if
* Key1 is smaller than Key2, zero if both are equal, and a value greater
* than zero if Key1 is greater then Key2.
*/
** Key1 is smaller than Key2, zero if both are equal, and a value greater
** than zero if Key1 is greater then Key2.
*/
{
/* Convert both parameters to Span pointers */
const Span* S1 = Key1;
@@ -144,8 +144,8 @@ static int HT_Compare (const void* Key1, const void* Key2)
static Span* NewSpan (Segment* Seg, unsigned long Start, unsigned long End)
/* Create a new span. The segment is set to Seg, Start and End are set to the
* current PC of the segment.
*/
** current PC of the segment.
*/
{
/* Allocate memory */
Span* S = xmalloc (sizeof (Span));
@@ -174,13 +174,13 @@ static void FreeSpan (Span* S)
static Span* MergeSpan (Span* S)
/* Check if we have a span with the same data as S already. If so, free S and
* return the already existing one. If not, remember S and return it.
*/
** return the already existing one. If not, remember S and return it.
*/
{
/* Check if we have such a span already. If so use the existing
* one and free the one from the collection. If not, add the one to
* the hash table and return it.
*/
** one and free the one from the collection. If not, add the one to
** the hash table and return it.
*/
Span* E = HT_Find (&SpanTab, S);
if (E) {
/* If S has a type and E not, move the type */
@@ -223,9 +223,9 @@ Span* OpenSpan (void)
Span* CloseSpan (Span* S)
/* Close the given span. Be sure to replace the passed span by the one
* returned, since the span will get deleted if it is empty or may be
* replaced if a duplicate exists.
*/
** returned, since the span will get deleted if it is empty or may be
** replaced if a duplicate exists.
*/
{
/* Set the end offset */
if (S->Start == S->Seg->PC) {
@@ -237,9 +237,9 @@ Span* CloseSpan (Span* S)
S->End = S->Seg->PC;
/* Check if we have such a span already. If so use the existing
* one and free the one from the collection. If not, add the one to
* the hash table and return it.
*/
** one and free the one from the collection. If not, add the one to
** the hash table and return it.
*/
return MergeSpan (S);
}
}
@@ -248,9 +248,9 @@ Span* CloseSpan (Span* S)
void OpenSpanList (Collection* Spans)
/* Open a list of spans for all existing segments to the given collection of
* spans. The currently active segment will be inserted first with all others
* following.
*/
** spans. The currently active segment will be inserted first with all others
** following.
*/
{
unsigned I;
@@ -275,8 +275,8 @@ void OpenSpanList (Collection* Spans)
void CloseSpanList (Collection* Spans)
/* Close a list of spans. This will add new segments to the list, mark the end
* of existing ones, and remove empty spans from the list.
*/
** of existing ones, and remove empty spans from the list.
*/
{
unsigned I, J;
@@ -385,9 +385,9 @@ void WriteSpans (void)
CHECK (S->End > S->Start);
/* Write data for the span We will write the size instead of the
* end offset to save some bytes, since most spans are expected
* to be rather small.
*/
** end offset to save some bytes, since most spans are expected
** to be rather small.
*/
ObjWriteVar (S->Seg->Num);
ObjWriteVar (S->Start);
ObjWriteVar (S->End - S->Start);

View File

@@ -93,15 +93,15 @@ Span* OpenSpan (void);
Span* CloseSpan (Span* S);
/* Close the given span. Be sure to replace the passed span by the one
* returned, since the span will get deleted if it is empty or may be
* replaced if a duplicate exists.
*/
** returned, since the span will get deleted if it is empty or may be
** replaced if a duplicate exists.
*/
void OpenSpanList (Collection* Spans);
/* Open a list of spans for all existing segments to the given collection of
* spans. The currently active segment will be inserted first with all others
* following.
*/
** spans. The currently active segment will be inserted first with all others
** following.
*/
void CloseSpanList (Collection* Spans);
/* Close all open spans by setting PC to the current PC for the segment. */

View File

@@ -102,9 +102,9 @@ static long DoStructInternal (long Offs, unsigned Type)
long Size = 0;
/* Outside of other structs, we need a name. Inside another struct or
* union, the struct may be anonymous, in which case no new lexical level
* is started.
*/
** union, the struct may be anonymous, in which case no new lexical level
** is started.
*/
int Anon = (CurTok.Tok != TOK_IDENT);
if (!Anon) {
/* Enter a new scope, then skip the name */
@@ -137,8 +137,8 @@ static long DoStructInternal (long Offs, unsigned Type)
if (CurTok.Tok == TOK_IDENT) {
/* Beware: An identifier may also be a macro, in which case we have
* to start over.
*/
** to start over.
*/
Macro* M = FindMacro (&CurTok.SVal);
if (M) {
MacExpandStart (M);
@@ -245,11 +245,11 @@ static long DoStructInternal (long Offs, unsigned Type)
}
/* If this is not a anon struct, enter a special symbol named ".size"
* into the symbol table of the struct that holds the size of the
* struct. Since the symbol starts with a dot, it cannot be accessed
* by user code.
* Leave the struct scope level.
*/
** into the symbol table of the struct that holds the size of the
** struct. Since the symbol starts with a dot, it cannot be accessed
** by user code.
** Leave the struct scope level.
*/
if (!Anon) {
/* Add a symbol */
SymEntry* SizeSym = GetSizeOfScope (CurrentScope);

View File

@@ -107,8 +107,8 @@ int ED_IsConst (const ExprDesc* D)
static int ED_IsValid (const ExprDesc* D)
/* Return true if the expression is valid, that is, neither the ERROR nor the
* TOO_COMPLEX flags are set.
*/
** TOO_COMPLEX flags are set.
*/
{
return ((D->Flags & (ED_ERROR | ED_TOO_COMPLEX)) == 0);
}
@@ -164,22 +164,22 @@ static void ED_MergeAddrSize (ExprDesc* ED, const ExprDesc* Right)
{
if (ED->AddrSize == ADDR_SIZE_DEFAULT) {
/* If ED is valid, ADDR_SIZE_DEFAULT gets always overridden, otherwise
* it takes precedence over anything else.
*/
** it takes precedence over anything else.
*/
if (ED_IsValid (ED)) {
ED->AddrSize = Right->AddrSize;
}
} else if (Right->AddrSize == ADDR_SIZE_DEFAULT) {
/* If Right is valid, ADDR_SIZE_DEFAULT gets always overridden,
* otherwise it takes precedence over anything else.
*/
** otherwise it takes precedence over anything else.
*/
if (!ED_IsValid (Right)) {
ED->AddrSize = Right->AddrSize;
}
} else {
/* Neither ED nor Right has a default address size, use the larger of
* the two.
*/
** the two.
*/
if (Right->AddrSize > ED->AddrSize) {
ED->AddrSize = Right->AddrSize;
}
@@ -190,8 +190,8 @@ static void ED_MergeAddrSize (ExprDesc* ED, const ExprDesc* Right)
static ED_SymRef* ED_FindSymRef (ExprDesc* ED, SymEntry* Sym)
/* Find a symbol reference and return it. Return NULL if the reference does
* not exist.
*/
** not exist.
*/
{
unsigned I;
ED_SymRef* SymRef;
@@ -207,8 +207,8 @@ static ED_SymRef* ED_FindSymRef (ExprDesc* ED, SymEntry* Sym)
static ED_SecRef* ED_FindSecRef (ExprDesc* ED, unsigned Sec)
/* Find a section reference and return it. Return NULL if the reference does
* not exist.
*/
** not exist.
*/
{
unsigned I;
ED_SecRef* SecRef;
@@ -224,8 +224,8 @@ static ED_SecRef* ED_FindSecRef (ExprDesc* ED, unsigned Sec)
static ED_SymRef* ED_AllocSymRef (ExprDesc* ED, SymEntry* Sym)
/* Allocate a new symbol reference and return it. The count of the new
* reference will be set to zero, and the reference itself to Sym.
*/
** reference will be set to zero, and the reference itself to Sym.
*/
{
ED_SymRef* SymRef;
@@ -251,8 +251,8 @@ static ED_SymRef* ED_AllocSymRef (ExprDesc* ED, SymEntry* Sym)
static ED_SecRef* ED_AllocSecRef (ExprDesc* ED, unsigned Sec)
/* Allocate a new section reference and return it. The count of the new
* reference will be set to zero, and the reference itself to Sec.
*/
** reference will be set to zero, and the reference itself to Sec.
*/
{
ED_SecRef* SecRef;
@@ -278,8 +278,8 @@ static ED_SecRef* ED_AllocSecRef (ExprDesc* ED, unsigned Sec)
static ED_SymRef* ED_GetSymRef (ExprDesc* ED, SymEntry* Sym)
/* Get a symbol reference and return it. If the symbol reference does not
* exist, a new one is created and returned.
*/
** exist, a new one is created and returned.
*/
{
ED_SymRef* SymRef = ED_FindSymRef (ED, Sym);
if (SymRef == 0) {
@@ -292,8 +292,8 @@ static ED_SymRef* ED_GetSymRef (ExprDesc* ED, SymEntry* Sym)
static ED_SecRef* ED_GetSecRef (ExprDesc* ED, unsigned Sec)
/* Get a section reference and return it. If the section reference does not
* exist, a new one is created and returned.
*/
** exist, a new one is created and returned.
*/
{
ED_SecRef* SecRef = ED_FindSecRef (ED, Sec);
if (SecRef == 0) {
@@ -416,8 +416,8 @@ static void ED_Neg (ExprDesc* D)
static void ED_Move (ExprDesc* From, ExprDesc* To)
/* Move the data from one ExprDesc to another. Old data is freed, and From
* is prepared to that ED_Done may be called safely.
*/
** is prepared to that ED_Done may be called safely.
*/
{
/* Delete old data */
ED_Done (To);
@@ -460,12 +460,12 @@ static unsigned char GetConstAddrSize (long Val)
static void StudyBinaryExpr (ExprNode* Expr, ExprDesc* D)
/* Study a binary expression subtree. This is a helper function for StudyExpr
* used for operations that succeed when both operands are known and constant.
* It evaluates the two subtrees and checks if they are constant. If they
* aren't constant, it will set the TOO_COMPLEX flag, and merge references.
* Otherwise the first value is returned in D->Val, the second one in D->Right,
* so the actual operation can be done by the caller.
*/
** used for operations that succeed when both operands are known and constant.
** It evaluates the two subtrees and checks if they are constant. If they
** aren't constant, it will set the TOO_COMPLEX flag, and merge references.
** Otherwise the first value is returned in D->Val, the second one in D->Right,
** so the actual operation can be done by the caller.
*/
{
ExprDesc Right;
@@ -516,10 +516,10 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
SymEntry* Sym = Expr->V.Sym;
/* If the symbol is defined somewhere, it has an expression associated.
* In this case, just study the expression associated with the symbol,
* but mark the symbol so if we encounter it twice, we know that we have
* a circular reference.
*/
** In this case, just study the expression associated with the symbol,
** but mark the symbol so if we encounter it twice, we know that we have
** a circular reference.
*/
if (SymHasExpr (Sym)) {
if (SymHasUserMark (Sym)) {
@@ -542,9 +542,9 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
}
/* If the symbol has an explicit address size, use it. This may
* lead to range errors later (maybe even in the linker stage), if
* the user lied about the address size, but for now we trust him.
*/
** lead to range errors later (maybe even in the linker stage), if
** the user lied about the address size, but for now we trust him.
*/
AddrSize = GetSymAddrSize (Sym);
if (AddrSize != ADDR_SIZE_DEFAULT) {
D->AddrSize = AddrSize;
@@ -554,8 +554,8 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
} else if (SymIsImport (Sym)) {
/* The symbol is an import. Track the symbols used and update the
* address size.
*/
** address size.
*/
ED_SymRef* SymRef = ED_GetSymRef (D, Sym);
++SymRef->Count;
ED_UpdateAddrSize (D, GetSymAddrSize (Sym));
@@ -566,17 +566,17 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
SymTable* Parent;
/* The symbol is undefined. Track symbol usage but set the "too
* complex" flag, since we cannot evaluate the final result.
*/
** complex" flag, since we cannot evaluate the final result.
*/
ED_SymRef* SymRef = ED_GetSymRef (D, Sym);
++SymRef->Count;
ED_Invalidate (D);
/* Since the symbol may be a forward, and we may need a statement
* about the address size, check higher lexical levels for a symbol
* with the same name and use its address size if we find such a
* symbol which is defined.
*/
** about the address size, check higher lexical levels for a symbol
** with the same name and use its address size if we find such a
** symbol which is defined.
*/
AddrSize = GetSymAddrSize (Sym);
Parent = GetSymParentScope (Sym);
if (AddrSize == ADDR_SIZE_DEFAULT && Parent != 0) {
@@ -612,8 +612,8 @@ static void StudyULabel (ExprNode* Expr, ExprDesc* D)
/* Study an unnamed label expression node */
{
/* If we can resolve the label, study the expression associated with it,
* otherwise mark the expression as too complex to evaluate.
*/
** otherwise mark the expression as too complex to evaluate.
*/
if (ULabCanResolve ()) {
/* We can resolve the label */
StudyExprInternal (ULabResolve (Expr->V.IVal), D);
@@ -707,8 +707,8 @@ static void StudyMul (ExprNode* Expr, ExprDesc* D)
StudyExprInternal (Expr->Right, &Right);
/* We can handle the operation if at least one of both operands is const
* and the other one is valid.
*/
** and the other one is valid.
*/
if (ED_IsConst (D) && ED_IsValid (&Right)) {
/* Multiplicate both, result goes into Right */
@@ -1480,24 +1480,24 @@ void StudyExpr (ExprNode* Expr, ExprDesc* D)
}
/* If we don't have an address size, assign one if the expression is a
* constant.
*/
** constant.
*/
if (D->AddrSize == ADDR_SIZE_DEFAULT && ED_IsConst (D)) {
D->AddrSize = GetConstAddrSize (D->Val);
}
/* If the expression is valid, throw away the address size and recalculate
* it using the data we have. This is more exact than the on-the-fly
* calculation done when evaluating the tree, because symbols may have
* been removed from the expression, and the final numeric value is now
* known.
*/
** it using the data we have. This is more exact than the on-the-fly
** calculation done when evaluating the tree, because symbols may have
** been removed from the expression, and the final numeric value is now
** known.
*/
if (ED_IsValid (D)) {
unsigned char AddrSize;
/* If there are symbols or sections, use the largest one. If the
* expression resolves to a const, use the address size of the value.
*/
** expression resolves to a const, use the address size of the value.
*/
if (D->SymCount > 0 || D->SecCount > 0) {
D->AddrSize = ADDR_SIZE_DEFAULT;

View File

@@ -54,12 +54,12 @@
SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
/* Parse a (possibly scoped) identifer. The scope of the name must exist and
* is returned as function result, while the last part (the identifier) which
* may be either a symbol or a scope depending on the context is returned in
* Name. FullName is a string buffer that is used to store the full name of
* the identifier including the scope. It is used internally and may be used
* by the caller for error messages or similar.
*/
** is returned as function result, while the last part (the identifier) which
** may be either a symbol or a scope depending on the context is returned in
** Name. FullName is a string buffer that is used to store the full name of
** the identifier including the scope. It is used internally and may be used
** by the caller for error messages or similar.
*/
{
SymTable* Scope;
@@ -89,8 +89,8 @@ SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
SB_Append (FullName, Name);
/* The scope must exist, so search for it starting with the current
* scope.
*/
** scope.
*/
Scope = SymFindAnyScope (CurrentScope, Name);
if (Scope == 0) {
/* Scope not found */
@@ -125,8 +125,8 @@ SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
NextTok ();
/* If a namespace token follows, we search for another scope, otherwise
* the name is a symbol and we're done.
*/
** the name is a symbol and we're done.
*/
if (CurTok.Tok != TOK_NAMESPACE) {
/* Symbol */
return Scope;
@@ -153,8 +153,8 @@ SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
SymEntry* ParseScopedSymName (SymFindAction Action)
/* Parse a (possibly scoped) symbol name, search for it in the symbol table
* and return the symbol table entry.
*/
** and return the symbol table entry.
*/
{
StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
StrBuf Ident = STATIC_STRBUF_INITIALIZER;
@@ -171,12 +171,12 @@ SymEntry* ParseScopedSymName (SymFindAction Action)
SB_Done (&ScopeName);
/* Check if the scope is valid. Errors have already been diagnosed by
* the routine, so just exit.
*/
** the routine, so just exit.
*/
if (Scope) {
/* Search for the symbol and return it. If no scope was specified,
* search also in the upper levels.
*/
** search also in the upper levels.
*/
if (NoScope && (Action & SYM_ALLOC_NEW) == 0) {
Sym = SymFindAny (Scope, &Ident);
} else {
@@ -184,9 +184,9 @@ SymEntry* ParseScopedSymName (SymFindAction Action)
}
} else {
/* No scope ==> no symbol. To avoid errors in the calling routine that
* may not expect NULL to be returned if Action contains SYM_ALLOC_NEW,
* create a new symbol.
*/
** may not expect NULL to be returned if Action contains SYM_ALLOC_NEW,
** create a new symbol.
*/
if (Action & SYM_ALLOC_NEW) {
Sym = NewSymEntry (&Ident, SF_NONE);
} else {
@@ -205,8 +205,8 @@ SymEntry* ParseScopedSymName (SymFindAction Action)
SymTable* ParseScopedSymTable (void)
/* Parse a (possibly scoped) symbol table (scope) name, search for it in the
* symbol space and return the symbol table struct.
*/
** symbol space and return the symbol table struct.
*/
{
StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
StrBuf Name = STATIC_STRBUF_INITIALIZER;
@@ -223,9 +223,9 @@ SymTable* ParseScopedSymTable (void)
SB_Done (&ScopeName);
/* If we got no error, search for the child scope withint the enclosing one.
* Beware: If no explicit parent scope was specified, search in all upper
* levels.
*/
** Beware: If no explicit parent scope was specified, search in all upper
** levels.
*/
if (Scope) {
/* Search for the last scope */
if (NoScope) {
@@ -246,8 +246,8 @@ SymTable* ParseScopedSymTable (void)
SymEntry* ParseAnySymName (SymFindAction Action)
/* Parse a cheap local symbol or a a (possibly scoped) symbol name, search
* for it in the symbol table and return the symbol table entry.
*/
** for it in the symbol table and return the symbol table entry.
*/
{
SymEntry* Sym;

View File

@@ -61,27 +61,27 @@ struct StrBuf;
struct SymTable* ParseScopedIdent (struct StrBuf* Name, struct StrBuf* FullName);
/* Parse a (possibly scoped) identifer. The scope of the name must exist and
* is returned as function result, while the last part (the identifier) which
* may be either a symbol or a scope depending on the context is returned in
* Name. FullName is a string buffer that is used to store the full name of
* the identifier including the scope. It is used internally and may be used
* by the caller for error messages or similar.
*/
** is returned as function result, while the last part (the identifier) which
** may be either a symbol or a scope depending on the context is returned in
** Name. FullName is a string buffer that is used to store the full name of
** the identifier including the scope. It is used internally and may be used
** by the caller for error messages or similar.
*/
struct SymEntry* ParseScopedSymName (SymFindAction Action);
/* Parse a (possibly scoped) symbol name, search for it in the symbol table
* and return the symbol table entry.
*/
** and return the symbol table entry.
*/
struct SymTable* ParseScopedSymTable (void);
/* Parse a (possibly scoped) symbol table (scope) name, search for it in the
* symbol space and return the symbol table struct.
*/
** symbol space and return the symbol table struct.
*/
struct SymEntry* ParseAnySymName (SymFindAction Action);
/* Parse a cheap local symbol or a a (possibly scoped) symbol name, search
* for it in the symbol table and return the symbol table entry.
*/
** for it in the symbol table and return the symbol table entry.
*/

View File

@@ -115,12 +115,12 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E)
/* Search in the given tree for a name. If we find the symbol, the function
* will return 0 and put the entry pointer into E. If we did not find the
* symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
* E will be set to the last entry, and the result of the function is <0 if
* the entry should be inserted on the left side, and >0 if it should get
* inserted on the right side.
*/
** will return 0 and put the entry pointer into E. If we did not find the
** symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
** E will be set to the last entry, and the result of the function is <0 if
** the entry should be inserted on the left side, and >0 if it should get
** inserted on the right side.
*/
{
/* Is there a tree? */
if (T == 0) {
@@ -196,8 +196,8 @@ static void SymReplaceExprRefs (SymEntry* S)
CHECK (E->Op == EXPR_SYMBOL && E->V.Sym == S);
/* We cannot touch the root node, since there are pointers to it.
* Replace it by a literal node.
*/
** Replace it by a literal node.
*/
E->Op = EXPR_LITERAL;
E->V.IVal = Val;
}
@@ -234,8 +234,8 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
return;
}
/* Delete the current symbol expression, since it will get
* replaced
*/
** replaced
*/
FreeExpr (S->Expr);
S->Expr = 0;
}
@@ -255,17 +255,17 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
S->Expr = Expr;
/* In case of a variable symbol, walk over all expressions containing
* this symbol and replace the (sub-)expression by the literal value of
* the tree. Be sure to replace the expression node in place, since there
* may be pointers to it.
*/
** this symbol and replace the (sub-)expression by the literal value of
** the tree. Be sure to replace the expression node in place, since there
** may be pointers to it.
*/
if (Flags & SF_VAR) {
SymReplaceExprRefs (S);
}
/* If the symbol is marked as global, export it. Address size is checked
* below.
*/
** below.
*/
if (S->Flags & SF_GLOBAL) {
S->Flags = (S->Flags & ~SF_GLOBAL) | SF_EXPORT;
ReleaseFullLineInfo (&S->DefLines);
@@ -326,15 +326,15 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
}
/* If no address size is given, use the address size of the enclosing
* segment.
*/
** segment.
*/
if (AddrSize == ADDR_SIZE_DEFAULT) {
AddrSize = GetCurrentSegAddrSize ();
}
/* If the symbol is marked as import or global, check the address size,
* then do silently remove the global flag.
*/
** then do silently remove the global flag.
*/
if (S->Flags & SF_IMPORT) {
if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
@@ -355,9 +355,9 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->AddrSize = AddrSize;
/* Mark the position of the import as the position of the definition.
* Please note: In case of multiple .global or .import statements, the line
* infos add up.
*/
** Please note: In case of multiple .global or .import statements, the line
** infos add up.
*/
GetFullLineInfo (&S->DefLines);
}
@@ -379,8 +379,8 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
}
/* If the symbol was marked as global before, remove the global flag and
* proceed, but check the address size.
*/
** proceed, but check the address size.
*/
if (S->Flags & SF_GLOBAL) {
if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
@@ -388,14 +388,14 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->Flags &= ~SF_GLOBAL;
/* .GLOBAL remembers line infos in case an .IMPORT follows. We have
* to remove these here.
*/
** to remove these here.
*/
ReleaseFullLineInfo (&S->DefLines);
}
/* If the symbol was already marked as an export, but wasn't defined
* before, the address sizes in both definitions must match.
*/
** before, the address sizes in both definitions must match.
*/
if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) {
if (S->ExportSize != AddrSize) {
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
@@ -404,8 +404,8 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->ExportSize = AddrSize;
/* If the symbol is already defined, check symbol size against the
* exported size.
*/
** exported size.
*/
if (S->Flags & SF_DEFINED) {
if (S->ExportSize == ADDR_SIZE_DEFAULT) {
/* No export size given, use the real size of the symbol */
@@ -429,8 +429,8 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
/* Mark the given symbol as a global symbol, that is, as a symbol that is
* either imported or exported.
*/
** either imported or exported.
*/
{
if (S->Flags & SF_VAR) {
/* Variable symbols cannot be exported or imported */
@@ -439,8 +439,8 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
}
/* If the symbol is already marked as import, the address size must match.
* Apart from that, ignore the global declaration.
*/
** Apart from that, ignore the global declaration.
*/
if (S->Flags & SF_IMPORT) {
if (AddrSize == ADDR_SIZE_DEFAULT) {
/* Use the size of the current segment */
@@ -453,8 +453,8 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
}
/* If the symbol is already an export: If it is not defined, the address
* sizes must match.
*/
** sizes must match.
*/
if (S->Flags & SF_EXPORT) {
if ((S->Flags & SF_DEFINED) == 0) {
/* Symbol is undefined */
@@ -471,9 +471,9 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
}
/* If the symbol is already marked as global, the address size must match.
* Use the ExportSize here, since it contains the actual address size
* passed to this function.
*/
** Use the ExportSize here, since it contains the actual address size
** passed to this function.
*/
if (S->Flags & SF_GLOBAL) {
if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
@@ -482,10 +482,10 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
}
/* If we come here, the symbol was neither declared as export, import or
* global before. Check if it is already defined, in which case it will
* become an export. If it is not defined, mark it as global and remember
* the given address sizes.
*/
** global before. Check if it is already defined, in which case it will
** become an export. If it is not defined, mark it as global and remember
** the given address sizes.
*/
if (S->Flags & SF_DEFINED) {
/* The symbol is defined, export it */
S->ExportSize = AddrSize;
@@ -501,9 +501,9 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->Flags |= (SF_EXPORT | Flags);
} else {
/* Since we don't know if the symbol will get exported or imported,
* remember two different address sizes: One for an import in AddrSize,
* and the other one for an export in ExportSize.
*/
** remember two different address sizes: One for an import in AddrSize,
** and the other one for an export in ExportSize.
*/
S->AddrSize = AddrSize;
if (S->AddrSize == ADDR_SIZE_DEFAULT) {
/* Use the size of the current segment */
@@ -513,8 +513,8 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->Flags |= (SF_GLOBAL | Flags);
/* Remember the current location as location of definition in case
* an .IMPORT follows later.
*/
** an .IMPORT follows later.
*/
GetFullLineInfo (&S->DefLines);
}
}
@@ -523,8 +523,8 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Prio)
/* Mark the given symbol as a module constructor/destructor. This will also
* mark the symbol as an export. Initializers may never be zero page symbols.
*/
** mark the symbol as an export. Initializers may never be zero page symbols.
*/
{
/* Check the parameters */
#if (CD_TYPE_MIN != 0)
@@ -547,9 +547,9 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
}
/* If the symbol was already marked as an export or global, check if
* this was done specifiying the same address size. In case of a global
* declaration, silently remove the global flag.
*/
** this was done specifiying the same address size. In case of a global
** declaration, silently remove the global flag.
*/
if (S->Flags & (SF_EXPORT | SF_GLOBAL)) {
if (S->ExportSize != AddrSize) {
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
@@ -559,8 +559,8 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
S->ExportSize = AddrSize;
/* If the symbol is already defined, check symbol size against the
* exported size.
*/
** exported size.
*/
if (S->Flags & SF_DEFINED) {
if (S->ExportSize == ADDR_SIZE_DEFAULT) {
/* Use the real size of the symbol */
@@ -571,8 +571,8 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
}
/* If the symbol was already declared as a condes, check if the new
* priority value is the same as the old one.
*/
** priority value is the same as the old one.
*/
if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
if (S->ConDesPrio[Type] != Prio) {
Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
@@ -593,10 +593,10 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
void SymGuessedAddrSize (SymEntry* Sym, unsigned char AddrSize)
/* Mark the address size of the given symbol as guessed. The address size
* passed as argument is the one NOT used, because the actual address size
* wasn't known. Example: Zero page addressing was not used because symbol
* is undefined, and absolute addressing was available.
*/
** passed as argument is the one NOT used, because the actual address size
** wasn't known. Example: Zero page addressing was not used because symbol
** is undefined, and absolute addressing was available.
*/
{
/* We must have a valid address size passed */
PRECONDITION (AddrSize != ADDR_SIZE_DEFAULT);
@@ -619,8 +619,8 @@ void SymGuessedAddrSize (SymEntry* Sym, unsigned char AddrSize)
void SymExportFromGlobal (SymEntry* S)
/* Called at the end of assembly. Converts a global symbol that is defined
* into an export.
*/
** into an export.
*/
{
/* Remove the global flag and make the symbol an export */
S->Flags &= ~SF_GLOBAL;
@@ -631,8 +631,8 @@ void SymExportFromGlobal (SymEntry* S)
void SymImportFromGlobal (SymEntry* S)
/* Called at the end of assembly. Converts a global symbol that is undefined
* into an import.
*/
** into an import.
*/
{
/* Remove the global flag and make it an import */
S->Flags &= ~SF_GLOBAL;
@@ -643,8 +643,8 @@ void SymImportFromGlobal (SymEntry* S)
int SymIsConst (const SymEntry* S, long* Val)
/* Return true if the given symbol has a constant value. If Val is not NULL
* and the symbol has a constant value, store it's value there.
*/
** and the symbol has a constant value, store it's value there.
*/
{
/* Check for constness */
return (SymHasExpr (S) && IsConstExpr (S->Expr, Val));
@@ -654,16 +654,16 @@ int SymIsConst (const SymEntry* S, long* Val)
SymTable* GetSymParentScope (SymEntry* S)
/* Get the parent scope of the symbol (not the one it is defined in). Return
* NULL if the symbol is a cheap local, or defined on global level.
*/
** NULL if the symbol is a cheap local, or defined on global level.
*/
{
if ((S->Flags & SF_LOCAL) != 0) {
/* This is a cheap local symbol */
return 0;
} else if (S->Sym.Tab == 0) {
/* Symbol not in a table. This may happen if there have been errors
* before. Return NULL in this case to avoid further errors.
*/
** before. Return NULL in this case to avoid further errors.
*/
return 0;
} else {
/* This is a global symbol */
@@ -684,8 +684,8 @@ struct ExprNode* GetSymExpr (SymEntry* S)
const struct ExprNode* SymResolve (const SymEntry* S)
/* Helper function for DumpExpr. Resolves a symbol into an expression or return
* NULL. Do not call in other contexts!
*/
** NULL. Do not call in other contexts!
*/
{
return SymHasExpr (S)? S->Expr : 0;
}
@@ -694,8 +694,8 @@ const struct ExprNode* SymResolve (const SymEntry* S)
long GetSymVal (SymEntry* S)
/* Return the value of a symbol assuming it's constant. FAIL will be called
* in case the symbol is undefined or not constant.
*/
** in case the symbol is undefined or not constant.
*/
{
long Val;
CHECK (S != 0 && SymHasExpr (S) && IsConstExpr (GetSymExpr (S), &Val));
@@ -724,10 +724,10 @@ unsigned GetSymExportId (const SymEntry* S)
unsigned GetSymInfoFlags (const SymEntry* S, long* ConstVal)
/* Return a set of flags used when writing symbol information into a file.
* If the SYM_CONST bit is set, ConstVal will contain the constant value
* of the symbol. The result does not include the condes count.
* See common/symdefs.h for more information.
*/
** If the SYM_CONST bit is set, ConstVal will contain the constant value
** of the symbol. The result does not include the condes count.
** See common/symdefs.h for more information.
*/
{
/* Setup info flags */
unsigned Flags = 0;

View File

@@ -92,11 +92,11 @@ struct SymEntry {
Collection DefLines; /* Line infos for definition */
Collection RefLines; /* Line infos for references */
FilePos* GuessedUse[1]; /* File position where symbol
* address size was guessed, and the
* smallest possible addressing was NOT
* used. Currently only for zero page
* addressing
*/
** address size was guessed, and the
** smallest possible addressing was NOT
** used. Currently only for zero page
** addressing
*/
struct HLLDbgSym* HLLSym; /* Symbol from high level language */
unsigned Flags; /* Symbol flags */
unsigned DebugSymId; /* Debug symbol id */
@@ -130,12 +130,12 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags);
int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E);
/* Search in the given tree for a name. If we find the symbol, the function
* will return 0 and put the entry pointer into E. If we did not find the
* symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
* E will be set to the last entry, and the result of the function is <0 if
* the entry should be inserted on the left side, and >0 if it should get
* inserted on the right side.
*/
** will return 0 and put the entry pointer into E. If we did not find the
** symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
** E will be set to the last entry, and the result of the function is <0 if
** the entry should be inserted on the left side, and >0 if it should get
** inserted on the right side.
*/
#if defined(HAVE_INLINE)
INLINE void SymAddExprRef (SymEntry* Sym, struct ExprNode* Expr)
@@ -174,30 +174,30 @@ void SymExport (SymEntry* Sym, unsigned char AddrSize, unsigned Flags);
void SymGlobal (SymEntry* Sym, unsigned char AddrSize, unsigned Flags);
/* Mark the given symbol as a global symbol, that is, as a symbol that is
* either imported or exported.
*/
** either imported or exported.
*/
void SymConDes (SymEntry* Sym, unsigned char AddrSize, unsigned Type, unsigned Prio);
/* Mark the given symbol as a module constructor/destructor. This will also
* mark the symbol as an export. Initializers may never be zero page symbols.
*/
** mark the symbol as an export. Initializers may never be zero page symbols.
*/
void SymGuessedAddrSize (SymEntry* Sym, unsigned char AddrSize);
/* Mark the address size of the given symbol as guessed. The address size
* passed as argument is the one NOT used, because the actual address size
* wasn't known. Example: Zero page addressing was not used because symbol
* is undefined, and absolute addressing was available.
*/
** passed as argument is the one NOT used, because the actual address size
** wasn't known. Example: Zero page addressing was not used because symbol
** is undefined, and absolute addressing was available.
*/
void SymExportFromGlobal (SymEntry* S);
/* Called at the end of assembly. Converts a global symbol that is defined
* into an export.
*/
** into an export.
*/
void SymImportFromGlobal (SymEntry* S);
/* Called at the end of assembly. Converts a global symbol that is undefined
* into an import.
*/
** into an import.
*/
#if defined(HAVE_INLINE)
INLINE int SymIsDef (const SymEntry* S)
@@ -254,8 +254,8 @@ INLINE int SymIsVar (const SymEntry* S)
int SymIsConst (const SymEntry* Sym, long* Val);
/* Return true if the given symbol has a constant value. If Val is not NULL
* and the symbol has a constant value, store it's value there.
*/
** and the symbol has a constant value, store it's value there.
*/
#if defined(HAVE_INLINE)
INLINE int SymHasExpr (const SymEntry* S)
@@ -303,16 +303,16 @@ INLINE int SymHasUserMark (SymEntry* S)
struct SymTable* GetSymParentScope (SymEntry* S);
/* Get the parent scope of the symbol (not the one it is defined in). Return
* NULL if the symbol is a cheap local, or defined on global level.
*/
** NULL if the symbol is a cheap local, or defined on global level.
*/
struct ExprNode* GetSymExpr (SymEntry* Sym);
/* Get the expression for a non-const symbol */
const struct ExprNode* SymResolve (const SymEntry* Sym);
/* Helper function for DumpExpr. Resolves a symbol into an expression or return
* NULL. Do not call in other contexts!
*/
** NULL. Do not call in other contexts!
*/
#if defined(HAVE_INLINE)
INLINE const StrBuf* GetSymName (const SymEntry* S)
@@ -327,8 +327,8 @@ INLINE const StrBuf* GetSymName (const SymEntry* S)
#if defined(HAVE_INLINE)
INLINE unsigned char GetSymAddrSize (const SymEntry* S)
/* Return the address size of the symbol. Beware: This function will just
* return the AddrSize member, it will not look at the expression!
*/
** return the AddrSize member, it will not look at the expression!
*/
{
return S->AddrSize;
}
@@ -338,8 +338,8 @@ INLINE unsigned char GetSymAddrSize (const SymEntry* S)
long GetSymVal (SymEntry* Sym);
/* Return the value of a symbol assuming it's constant. FAIL will be called
* in case the symbol is undefined or not constant.
*/
** in case the symbol is undefined or not constant.
*/
unsigned GetSymImportId (const SymEntry* Sym);
/* Return the import id for the given symbol */
@@ -349,10 +349,10 @@ unsigned GetSymExportId (const SymEntry* Sym);
unsigned GetSymInfoFlags (const SymEntry* Sym, long* ConstVal);
/* Return a set of flags used when writing symbol information into a file.
* If the SYM_CONST bit is set, ConstVal will contain the constant value
* of the symbol. The result does not include the condes count.
* See common/symdefs.h for more information.
*/
** If the SYM_CONST bit is set, ConstVal will contain the constant value
** of the symbol. The result does not include the condes count.
** See common/symdefs.h for more information.
*/

View File

@@ -207,8 +207,8 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type,
}
/* If we have a current scope, search for the given name and create a
* new one if it doesn't exist. If this is the root scope, just create it.
*/
** new one if it doesn't exist. If this is the root scope, just create it.
*/
if (CurrentScope) {
/* Search for the scope, create a new one */
@@ -230,11 +230,11 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type,
CurrentScope->Label = ScopeLabel;
/* If this is a scope that allows to emit data into segments, add spans
* for all currently existing segments. Doing this for just a few scope
* types is not really necessary but an optimization, because it does not
* allocate memory for useless data (unhandled types here don't occupy
* space in any segment).
*/
** for all currently existing segments. Doing this for just a few scope
** types is not really necessary but an optimization, because it does not
** allocate memory for useless data (unhandled types here don't occupy
** space in any segment).
*/
if (CurrentScope->Type <= SCOPE_HAS_DATA) {
OpenSpanList (&CurrentScope->Spans);
}
@@ -246,17 +246,17 @@ void SymLeaveLevel (void)
/* Leave the current lexical level */
{
/* If this is a scope that allows to emit data into segments, close the
* open the spans.
*/
** open the spans.
*/
if (CurrentScope->Type <= SCOPE_HAS_DATA) {
CloseSpanList (&CurrentScope->Spans);
}
/* If we have spans, the first one is the segment that was active, when the
* scope was opened. Set the size of the scope to the number of data bytes
* emitted into this segment. If we have an owner symbol set the size of
* this symbol, too.
*/
** scope was opened. Set the size of the scope to the number of data bytes
** emitted into this segment. If we have an owner symbol set the size of
** this symbol, too.
*/
if (CollCount (&CurrentScope->Spans) > 0) {
const Span* S = CollAtUnchecked (&CurrentScope->Spans, 0);
unsigned long Size = GetSpanSize (S);
@@ -304,9 +304,9 @@ SymTable* SymFindScope (SymTable* Parent, const StrBuf* Name, SymFindAction Acti
SymTable* SymFindAnyScope (SymTable* Parent, const StrBuf* Name)
/* Find a scope in the given or any of its parent scopes. The function will
* never create a new symbol, since this can only be done in one specific
* scope.
*/
** never create a new symbol, since this can only be done in one specific
** scope.
*/
{
SymTable* Scope;
do {
@@ -325,9 +325,9 @@ SymTable* SymFindAnyScope (SymTable* Parent, const StrBuf* Name)
SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* Name, SymFindAction Action)
/* Find a cheap local symbol. If Action contains SYM_ALLOC_NEW and the entry is
* not found, create a new one. Return the entry found, or the new entry
* created, or - in case Action is SYM_FIND_EXISTING - return 0.
*/
** not found, create a new one. Return the entry found, or the new entry
** created, or - in case Action is SYM_FIND_EXISTING - return 0.
*/
{
SymEntry* S;
@@ -375,10 +375,10 @@ SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* Name, SymFindAction Acti
SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, SymFindAction Action)
/* Find a new symbol table entry in the given table. If Action contains
* SYM_ALLOC_NEW and the entry is not found, create a new one. Return the
* entry found, or the new entry created, or - in case Action is
* SYM_FIND_EXISTING - return 0.
*/
** SYM_ALLOC_NEW and the entry is not found, create a new one. Return the
** entry found, or the new entry created, or - in case Action is
** SYM_FIND_EXISTING - return 0.
*/
{
SymEntry* S;
@@ -399,9 +399,9 @@ SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, SymFindAction Action)
if (Action & SYM_ALLOC_NEW) {
/* Otherwise create a new entry, insert and return it. If the scope is
* already closed, mark the symbol as fixed so it won't be resolved
* by a symbol in the enclosing scopes later.
*/
** already closed, mark the symbol as fixed so it won't be resolved
** by a symbol in the enclosing scopes later.
*/
SymEntry* N = NewSymEntry (Name, SF_NONE);
if (SymTabIsClosed (Scope)) {
N->Flags |= SF_FIXED;
@@ -427,9 +427,9 @@ SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, SymFindAction Action)
SymEntry* SymFindAny (SymTable* Scope, const StrBuf* Name)
/* Find a symbol in the given or any of its parent scopes. The function will
* never create a new symbol, since this can only be done in one specific
* scope.
*/
** never create a new symbol, since this can only be done in one specific
** scope.
*/
{
/* Generate the name hash */
unsigned Hash = HashBuf (Name);
@@ -438,9 +438,9 @@ SymEntry* SymFindAny (SymTable* Scope, const StrBuf* Name)
SymEntry* Sym;
do {
/* Search in the current table. Ignore entries flagged with SF_UNUSED,
* because for such symbols there is a real entry in one of the parent
* scopes.
*/
** because for such symbols there is a real entry in one of the parent
** scopes.
*/
if (SymSearchTree (Scope->Table[Hash % Scope->TableSlots], Name, &Sym) == 0) {
if (Sym->Flags & SF_UNUSED) {
Sym = 0;
@@ -467,15 +467,15 @@ static void SymCheckUndefined (SymEntry* S)
/* Handle an undefined symbol */
{
/* Undefined symbol. It may be...
*
* - An undefined symbol in a nested lexical level. If the symbol is not
* fixed to this level, search for the symbol in the higher levels and
* make the entry a trampoline entry if we find one.
*
* - If the symbol is not found, it is a real undefined symbol. If the
* AutoImport flag is set, make it an import. If the AutoImport flag is
* not set, it's an error.
*/
**
** - An undefined symbol in a nested lexical level. If the symbol is not
** fixed to this level, search for the symbol in the higher levels and
** make the entry a trampoline entry if we find one.
**
** - If the symbol is not found, it is a real undefined symbol. If the
** AutoImport flag is set, make it an import. If the AutoImport flag is
** not set, it's an error.
*/
SymEntry* Sym = 0;
if ((S->Flags & SF_FIXED) == 0) {
SymTable* Tab = GetSymParentScope (S);
@@ -483,8 +483,8 @@ static void SymCheckUndefined (SymEntry* S)
Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING | SYM_CHECK_ONLY);
if (Sym && (Sym->Flags & (SF_DEFINED | SF_IMPORT)) != 0) {
/* We've found a symbol in a higher level that is
* either defined in the source, or an import.
*/
** either defined in the source, or an import.
*/
break;
}
/* No matching symbol found in this level. Look further */
@@ -495,9 +495,9 @@ static void SymCheckUndefined (SymEntry* S)
if (Sym) {
/* We found the symbol in a higher level. Transfer the flags and
* address size from the local symbol to that in the higher level
* and check for problems.
*/
** address size from the local symbol to that in the higher level
** and check for problems.
*/
if (S->Flags & SF_EXPORT) {
if (Sym->Flags & SF_IMPORT) {
/* The symbol is already marked as import */
@@ -574,13 +574,13 @@ void SymCheck (void)
}
/* First pass: Walk through all symbols, checking for undefined's and
* changing them to trampoline symbols or make them imports.
*/
** changing them to trampoline symbols or make them imports.
*/
S = SymList;
while (S) {
/* If the symbol is marked as global, mark it as export, if it is
* already defined, otherwise mark it as import.
*/
** already defined, otherwise mark it as import.
*/
if (S->Flags & SF_GLOBAL) {
if (S->Flags & SF_DEFINED) {
SymExportFromGlobal (S);
@@ -600,10 +600,10 @@ void SymCheck (void)
}
/* Second pass: Walk again through the symbols. Count exports and imports
* and set address sizes where this has not happened before. Ignore
* undefined's, since we handled them in the last pass, and ignore unused
* symbols, since we handled them in the last pass, too.
*/
** and set address sizes where this has not happened before. Ignore
** undefined's, since we handled them in the last pass, and ignore unused
** symbols, since we handled them in the last pass, too.
*/
S = SymList;
while (S) {
if ((S->Flags & SF_UNUSED) == 0 &&
@@ -639,8 +639,8 @@ void SymCheck (void)
}
/* If the symbol is defined but has an unknown address size,
* recalculate it.
*/
** recalculate it.
*/
if (SymHasExpr (S) && S->AddrSize == ADDR_SIZE_DEFAULT) {
ExprDesc ED;
ED_Init (&ED);
@@ -663,9 +663,9 @@ void SymCheck (void)
}
/* If the address size of the symbol was guessed, check the guess
* against the actual address size and print a warning if the two
* differ.
*/
** against the actual address size and print a warning if the two
** differ.
*/
if (S->AddrSize != ADDR_SIZE_DEFAULT) {
/* Do we have data for this address size? */
if (S->AddrSize <= sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0])) {
@@ -725,10 +725,10 @@ void WriteImports (void)
ObjWriteVar (ImportCount);
/* Walk throught list and write all valid imports to the file. An import
* is considered valid, if it is either referenced, or the forced bit is
* set. Otherwise, the import is ignored (no need to link in something
* that isn't used).
*/
** is considered valid, if it is either referenced, or the forced bit is
** set. Otherwise, the import is ignored (no need to link in something
** that isn't used).
*/
S = SymList;
while (S) {
if ((S->Flags & (SF_UNUSED | SF_IMPORT)) == SF_IMPORT &&
@@ -770,8 +770,8 @@ void WriteExports (void)
unsigned SymFlags = GetSymInfoFlags (S, &ConstVal);
/* Check if this symbol has a size. If so, remember it in the
* flags.
*/
** flags.
*/
long Size;
SymEntry* SizeSym = FindSizeOfSymbol (S);
if (SizeSym != 0 && SymIsConst (SizeSym, &Size)) {
@@ -855,8 +855,8 @@ void WriteDbgSyms (void)
ObjWriteVar (Count);
/* Walk through list and write all symbols to the file. Ignore size
* symbols.
*/
** symbols.
*/
S = SymList;
while (S) {
if (IsDbgSym (S)) {
@@ -866,8 +866,8 @@ void WriteDbgSyms (void)
unsigned SymFlags = GetSymInfoFlags (S, &ConstVal);
/* Check if this symbol has a size. If so, remember it in the
* flags.
*/
** flags.
*/
long Size;
SymEntry* SizeSym = FindSizeOfSymbol (S);
if (SizeSym != 0 && SymIsConst (SizeSym, &Size)) {
@@ -881,8 +881,8 @@ void WriteDbgSyms (void)
ObjWrite8 (S->AddrSize);
/* Write the id of the parent. For normal symbols, this is a
* scope (symbol table), for cheap locals, it's a symbol.
*/
** scope (symbol table), for cheap locals, it's a symbol.
*/
if (SYM_IS_STD (SymFlags)) {
ObjWriteVar (S->Sym.Tab->Id);
} else {
@@ -959,8 +959,8 @@ void WriteScopes (void)
unsigned Flags = 0;
/* Check if this scope has a size. If so, remember it in the
* flags.
*/
** flags.
*/
long Size;
SymEntry* SizeSym = FindSizeOfScope (S);
if (SizeSym != 0 && SymIsConst (SizeSym, &Size)) {

View File

@@ -112,28 +112,28 @@ SymTable* SymFindScope (SymTable* Parent, const StrBuf* Name, SymFindAction Acti
SymTable* SymFindAnyScope (SymTable* Parent, const StrBuf* Name);
/* Find a scope in the given or any of its parent scopes. The function will
* never create a new symbol, since this can only be done in one specific
* scope.
*/
** never create a new symbol, since this can only be done in one specific
** scope.
*/
SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* Name, SymFindAction Action);
/* Find a cheap local symbol. If Action contains SYM_ALLOC_NEW and the entry is
* not found, create a new one. Return the entry found, or the new entry
* created, or - in case Action is SYM_FIND_EXISTING - return 0.
*/
** not found, create a new one. Return the entry found, or the new entry
** created, or - in case Action is SYM_FIND_EXISTING - return 0.
*/
SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, SymFindAction Action);
/* Find a new symbol table entry in the given table. If Action contains
* SYM_ALLOC_NEW and the entry is not found, create a new one. Return the
* entry found, or the new entry created, or - in case Action is
* SYM_FIND_EXISTING - return 0.
*/
** SYM_ALLOC_NEW and the entry is not found, create a new one. Return the
** entry found, or the new entry created, or - in case Action is
** SYM_FIND_EXISTING - return 0.
*/
SymEntry* SymFindAny (SymTable* Scope, const StrBuf* Name);
/* Find a symbol in the given or any of its parent scopes. The function will
* never create a new symbol, since this can only be done in one specific
* scope.
*/
** never create a new symbol, since this can only be done in one specific
** scope.
*/
#if defined(HAVE_INLINE)
INLINE unsigned char GetSymTabType (const SymTable* S)

View File

@@ -62,8 +62,8 @@ int TokHasIVal (token_t Tok)
void CopyToken (Token* Dst, const Token* Src)
/* Copy a token from Src to Dst. The current value of Dst.SVal is free'd,
* so Dst must be initialized.
*/
** so Dst must be initialized.
*/
{
/* Copy the fields */
Dst->Tok = Src->Tok;

View File

@@ -306,8 +306,8 @@ INLINE int TokIsSep (enum token_t T)
void CopyToken (Token* Dst, const Token* Src);
/* Copy a token. The current value of Dst.SVal is free'd, so Dst must be
* initialized.
*/
** initialized.
*/

View File

@@ -180,9 +180,9 @@ void FreeTokList (TokList* List)
enum token_t GetTokListTerm (enum token_t Term)
/* Determine if the following token list is enclosed in curly braces. This is
* the case if the next token is the opening brace. If so, skip it and return
* a closing brace, otherwise return Term.
*/
** the case if the next token is the opening brace. If so, skip it and return
** a closing brace, otherwise return Term.
*/
{
if (CurTok.Tok == TOK_LCURLY) {
NextTok ();
@@ -216,16 +216,16 @@ void AddCurTok (TokList* List)
static int ReplayTokList (void* List)
/* Function that gets the next token from a token list and sets it. This
* function may be used together with the PushInput function from the istack
* module.
*/
** function may be used together with the PushInput function from the istack
** module.
*/
{
/* Cast the generic pointer to an actual list */
TokList* L = List;
/* If there are no more tokens, decrement the repeat counter. If it goes
* zero, delete the list and remove the function from the stack.
*/
** zero, delete the list and remove the function from the stack.
*/
if (L->Last == 0) {
if (++L->RepCount >= L->RepMax) {
/* Done with this list */
@@ -249,8 +249,8 @@ static int ReplayTokList (void* List)
L->LI = StartLine (&CurTok.Pos, LI_TYPE_ASM, PushCounter);
/* If a check function is defined, call it, so it may look at the token
* just set and changed it as apropriate.
*/
** just set and changed it as apropriate.
*/
if (L->Check) {
L->Check (L);
}
@@ -266,9 +266,9 @@ static int ReplayTokList (void* List)
void PushTokList (TokList* List, const char* Desc)
/* Push a token list to be used as input for InputFromStack. This includes
* several initializations needed in the token list structure, so don't use
* PushInput directly.
*/
** several initializations needed in the token list structure, so don't use
** PushInput directly.
*/
{
/* If the list is empty, just delete it and bail out */
if (List->Count == 0) {

View File

@@ -111,18 +111,18 @@ void FreeTokList (TokList* T);
token_t GetTokListTerm (token_t Term);
/* Determine if the following token list is enclosed in curly braces. This is
* the case if the next token is the opening brace. If so, skip it and return
* a closing brace, otherwise return Term.
*/
** the case if the next token is the opening brace. If so, skip it and return
** a closing brace, otherwise return Term.
*/
void AddCurTok (TokList* T);
/* Add the current token to the token list */
void PushTokList (TokList* List, const char* Desc);
/* Push a token list to be used as input for InputFromStack. This includes
* several initializations needed in the token list structure, so don't use
* PushInput directly.
*/
** several initializations needed in the token list structure, so don't use
** PushInput directly.
*/

View File

@@ -75,8 +75,8 @@ static unsigned ULabDefCount = 0; /* Number of defined labels */
static ULabel* NewULabel (ExprNode* Val)
/* Create a new ULabel and insert it into the collection. The created label
* structure is returned.
*/
** structure is returned.
*/
{
/* Allocate memory for the ULabel structure */
ULabel* L = xmalloc (sizeof (ULabel));
@@ -98,11 +98,11 @@ static ULabel* NewULabel (ExprNode* Val)
ExprNode* ULabRef (int Which)
/* Get an unnamed label. If Which is negative, it is a backreference (a
* reference to an already defined label), and the function will return a
* segment relative expression. If Which is positive, it is a forward ref,
* and the function will return a expression node for an unnamed label that
* must be resolved later.
*/
** reference to an already defined label), and the function will return a
** segment relative expression. If Which is positive, it is a forward ref,
** and the function will return a expression node for an unnamed label that
** must be resolved later.
*/
{
int Index;
ULabel* L;
@@ -139,8 +139,8 @@ ExprNode* ULabRef (int Which)
++L->Ref;
/* If the label is already defined, return its value, otherwise return
* just a reference.
*/
** just a reference.
*/
if (L->Val) {
return CloneExpr (L->Val);
} else {
@@ -155,9 +155,9 @@ void ULabDef (void)
{
if (ULabDefCount < CollCount (&ULabList)) {
/* We did already have a forward reference to this label, so has
* already been generated, but doesn't have a value. Use the current
* PC for the label value.
*/
** already been generated, but doesn't have a value. Use the current
** PC for the label value.
*/
ULabel* L = CollAtUnchecked (&ULabList, ULabDefCount);
CHECK (L->Val == 0);
L->Val = GenCurrentPC ();
@@ -185,9 +185,9 @@ int ULabCanResolve (void)
ExprNode* ULabResolve (unsigned Index)
/* Return a valid expression for the unnamed label with the given index. This
* is used to resolve unnamed labels when assembly is done, so it is an error
* if a label is still undefined in this phase.
*/
** is used to resolve unnamed labels when assembly is done, so it is an error
** if a label is still undefined in this phase.
*/
{
/* Get the label and check that it is defined */
ULabel* L = CollAt (&ULabList, Index);
@@ -201,8 +201,8 @@ ExprNode* ULabResolve (unsigned Index)
void ULabDone (void)
/* Run through all unnamed labels, check for anomalies and errors and do
* necessary cleanups.
*/
** necessary cleanups.
*/
{
/* Check if there are undefined labels */
unsigned I = ULabDefCount;
@@ -213,8 +213,8 @@ void ULabDone (void)
}
/* Walk over all labels and emit a warning if any unreferenced ones
* are found. Remove line infos because they're no longer needed.
*/
** are found. Remove line infos because they're no longer needed.
*/
for (I = 0; I < CollCount (&ULabList); ++I) {
ULabel* L = CollAtUnchecked (&ULabList, I);
if (L->Ref == 0) {

View File

@@ -46,11 +46,11 @@
ExprNode* ULabRef (int Which);
/* Get an unnamed label. If Which is negative, it is a backreference (a
* reference to an already defined label), and the function will return a
* segment relative expression. If Which is positive, it is a forward ref,
* and the function will return a expression node for an unnamed label that
* must be resolved later.
*/
** reference to an already defined label), and the function will return a
** segment relative expression. If Which is positive, it is a forward ref,
** and the function will return a expression node for an unnamed label that
** must be resolved later.
*/
void ULabDef (void);
/* Define an unnamed label at the current PC */
@@ -60,14 +60,14 @@ int ULabCanResolve (void);
ExprNode* ULabResolve (unsigned Index);
/* Return a valid expression for the unnamed label with the given index. This
* is used to resolve unnamed labels when assembly is done, so it is an error
* if a label is still undefined in this phase.
*/
** is used to resolve unnamed labels when assembly is done, so it is an error
** if a label is still undefined in this phase.
*/
void ULabDone (void);
/* Run through all unnamed labels, check for anomalies and errors and do
* necessary cleanups.
*/
** necessary cleanups.
*/

View File

@@ -63,8 +63,8 @@ static const char AnonTag[] = "$anon";
char* AnonName (char* Buf, const char* Spec)
/* Get a name for an anonymous variable or type. The given buffer is expected
* to be IDENTSIZE characters long. A pointer to the buffer is returned.
*/
** to be IDENTSIZE characters long. A pointer to the buffer is returned.
*/
{
static unsigned ACount = 0;
xsprintf (Buf, IDENTSIZE, "%s-%s-%04X", AnonTag, Spec, ++ACount);

View File

@@ -46,8 +46,8 @@
char* AnonName (char* Buf, const char* Spec);
/* Get a name for an anonymous variable or type. The given buffer is expected
* to be IDENTSIZE characters long. A pointer to the buffer is returned.
*/
** to be IDENTSIZE characters long. A pointer to the buffer is returned.
*/
int IsAnonName (const char* Name);
/* Check if the given symbol name is that of an anonymous symbol */

View File

@@ -86,8 +86,8 @@ void RemoveCode (const CodeMark* M)
void MoveCode (const CodeMark* Start, const CodeMark* End, const CodeMark* Target)
/* Move the code between Start (inclusive) and End (exclusive) to
* (before) Target. The code marks aren't updated.
*/
** (before) Target. The code marks aren't updated.
*/
{
CS_MoveEntries (CS->Code, Start->Pos, End->Pos - Start->Pos, Target->Pos);
}

View File

@@ -76,8 +76,8 @@ void RemoveCode (const CodeMark* M);
void MoveCode (const CodeMark* Start, const CodeMark* End, const CodeMark* Target);
/* Move the code between Start (inclusive) and End (exclusive) to
* (before) Target. The code marks aren't updated.
*/
** (before) Target. The code marks aren't updated.
*/
int CodeRangeIsEmpty (const CodeMark* Start, const CodeMark* End);
/* Return true if the given code range is empty (no code between Start and End) */

View File

@@ -70,9 +70,9 @@ unsigned GetLocalLabel (void)
const char* LocalLabelName (unsigned L)
/* Make a label name from the given label number. The label name will be
* created in static storage and overwritten when calling the function
* again.
*/
** created in static storage and overwritten when calling the function
** again.
*/
{
static char Buf[64];
sprintf (Buf, "L%04X", L);

View File

@@ -49,9 +49,9 @@ unsigned GetLocalLabel (void);
const char* LocalLabelName (unsigned L);
/* Make a label name from the given label number. The label name will be
* created in static storage and overwritten when calling the function
* again.
*/
** created in static storage and overwritten when calling the function
** again.
*/
int IsLocalLabelName (const char* Name);
/* Return true if Name is the name of a local label */

View File

@@ -69,8 +69,8 @@ static void AsmRangeError (unsigned Arg)
static void AsmErrorSkip (void)
/* Called in case of an error, skips tokens until the closing paren or a
* semicolon is reached.
*/
** semicolon is reached.
*/
{
static const token_t TokenList[] = { TOK_RPAREN, TOK_SEMI };
SkipTokens (TokenList, sizeof(TokenList) / sizeof(TokenList[0]));
@@ -80,8 +80,8 @@ static void AsmErrorSkip (void)
static SymEntry* AsmGetSym (unsigned Arg, unsigned Type)
/* Find the symbol with the name currently in NextTok. The symbol must be of
* the given type. On errors, NULL is returned.
*/
** the given type. On errors, NULL is returned.
*/
{
SymEntry* Sym;
@@ -257,9 +257,9 @@ static void ParseLVarArg (StrBuf* T, unsigned Arg)
}
/* The symbol may be a parameter to a variadic function. In this case, we
* don't have a fixed stack offset, so check it and bail out with an error
* if this is the case.
*/
** don't have a fixed stack offset, so check it and bail out with an error
** if this is the case.
*/
if ((Sym->Flags & SC_PARAM) == SC_PARAM && F_IsVariadic (CurrentFunc)) {
Error ("Argument %u has no fixed stack offset", Arg);
AsmErrorSkip ();
@@ -352,16 +352,16 @@ static void ParseAsm (void)
NextToken ();
/* Parse the statement. It may contain several lines and one or more
* of the following place holders:
* %b - Numerical 8 bit value
* %w - Numerical 16 bit value
* %l - Numerical 32 bit value
* %v - Assembler name of a (global) variable
* %o - Stack offset of a (local) variable
* %g - Assembler name of a C label
* %s - Any argument converted to a string (almost)
* %% - The % sign
*/
** of the following place holders:
** %b - Numerical 8 bit value
** %w - Numerical 16 bit value
** %l - Numerical 32 bit value
** %v - Assembler name of a (global) variable
** %o - Stack offset of a (local) variable
** %g - Assembler name of a C label
** %s - Any argument converted to a string (almost)
** %% - The % sign
*/
Arg = 0;
while ((C = SB_Get (&S)) != '\0') {
@@ -415,9 +415,9 @@ Done:
void AsmStatement (void)
/* This function parses ASM statements. The syntax of the ASM directive
* looks like the one defined for C++ (C has no ASM directive), that is,
* a string literal in parenthesis.
*/
** looks like the one defined for C++ (C has no ASM directive), that is,
** a string literal in parenthesis.
*/
{
/* Skip the ASM */
NextToken ();
@@ -434,8 +434,8 @@ void AsmStatement (void)
Error ("String literal expected");
/* Try some smart error recovery: Skip tokens until we reach the
* enclosing paren, or a semicolon.
*/
** enclosing paren, or a semicolon.
*/
AsmErrorSkip ();
} else {

View File

@@ -46,9 +46,9 @@
void AsmStatement (void);
/* This function parses ASM statements. The syntax of the ASM directive
* looks like the one defined for C++ (C has no ASM directive), that is,
* a string literal in parenthesis.
*/
** looks like the one defined for C++ (C has no ASM directive), that is,
** a string literal in parenthesis.
*/

View File

@@ -75,18 +75,18 @@ void Assignment (ExprDesc* Expr)
NextToken ();
/* cc65 does not have full support for handling structs by value. Since
* assigning structs is one of the more useful operations from this
* family, allow it here.
*/
** assigning structs is one of the more useful operations from this
** family, allow it here.
*/
if (IsClassStruct (ltype)) {
/* Get the size of the left hand side. */
unsigned Size = SizeOf (ltype);
/* If the size is that of a basic type (char, int, long), we will copy
* the struct using the primary register, otherwise we use memcpy. In
* the former case, push the address only if really needed.
*/
** the struct using the primary register, otherwise we use memcpy. In
** the former case, push the address only if really needed.
*/
int UseReg = 1;
Type* stype;
switch (Size) {
@@ -143,10 +143,10 @@ void Assignment (ExprDesc* Expr)
} else {
/* We have an rvalue. This can only happen if a function returns
* a struct, since there is no other way to generate an expression
* that as a struct as an rvalue result. We allow only 1, 2, and 4
* byte sized structs and do direct assignment.
*/
** a struct, since there is no other way to generate an expression
** that has a struct as an rvalue result. We allow only 1, 2, and 4
** byte sized structs, and do direct assignment.
*/
if (UseReg) {
/* Do the store */
Store (Expr, stype);
@@ -168,8 +168,8 @@ void Assignment (ExprDesc* Expr)
unsigned Flags;
/* If the bit-field fits within one byte, do the following operations
* with bytes.
*/
** with bytes.
*/
if (Expr->BitOffs / CHAR_BITS == (Expr->BitOffs + Expr->BitWidth - 1) / CHAR_BITS) {
Expr->Type = type_uchar;
}
@@ -197,14 +197,14 @@ void Assignment (ExprDesc* Expr)
MarkedExprWithCheck (hie1, &Expr2);
/* Do type conversion if necessary. Beware: Do not use char type
* here!
*/
** here!
*/
TypeConversion (&Expr2, ltype);
/* Special treatment if the value is constant. */
/* Beware: Expr2 may contain side effects, so there must not be
* code generated for Expr2.
*/
** code generated for Expr2.
*/
if (ED_IsConstAbsInt (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) {
/* Get the value and apply the mask */
@@ -214,8 +214,8 @@ void Assignment (ExprDesc* Expr)
RemoveCode (&PushPos);
/* If the value is equal to the mask now, all bits are one, and we
* can remove the mask operation from above.
*/
** can remove the mask operation from above.
*/
if (Val == Mask) {
RemoveCode (&AndPos);
}

View File

@@ -94,10 +94,10 @@ void FreeCaseNodeColl (Collection* Nodes)
int SearchCaseNode (const Collection* Nodes, unsigned char Key, int* Index)
/* Search for a node in the given collection. If the node has been found,
* set Index to the index of the node and return true. If the node was not
* found, set Index the the insertion position of the node and return
* false.
*/
** set Index to the index of the node and return true. If the node was not
** found, set Index the the insertion position of the node and return
** false.
*/
{
/* Do a binary search */
int First = 0;
@@ -134,8 +134,8 @@ int SearchCaseNode (const Collection* Nodes, unsigned char Key, int* Index)
unsigned InsertCaseValue (Collection* Nodes, unsigned long Val, unsigned Depth)
/* Insert a new case value into a CaseNode tree with the given depth. Return
* the code label for the value.
*/
** the code label for the value.
*/
{
CaseNode* N = 0;
unsigned CaseLabel = GetLocalLabel (); /* Code label */
@@ -155,8 +155,8 @@ unsigned InsertCaseValue (Collection* Nodes, unsigned long Val, unsigned Depth)
CollInsert (Nodes, N, Index);
/* If this is not the last round, create the collection for
* the subnodes, otherwise get a label for the code.
*/
** the subnodes, otherwise get a label for the code.
*/
if (Depth > 0) {
N->Nodes = NewCollection ();
} else {
@@ -168,8 +168,8 @@ unsigned InsertCaseValue (Collection* Nodes, unsigned long Val, unsigned Depth)
N = CollAt (Nodes, Index);
/* If this is the last round and we found a node, we have a
* duplicate case label in a switch.
*/
** duplicate case label in a switch.
*/
if (Depth == 0) {
Error ("Duplicate case label");
}

View File

@@ -115,15 +115,15 @@ void FreeCaseNodeColl (Collection* Nodes);
int SearchCaseNode (const Collection* Nodes, unsigned char Key, int* Index);
/* Search for a node in the given collection. If the node has been found,
* set Index to the index of the node and return true. If the node was not
* found, set Index the the insertion position of the node and return
* false.
*/
** set Index to the index of the node and return true. If the node was not
** found, set Index the the insertion position of the node and return
** false.
*/
unsigned InsertCaseValue (Collection* Nodes, unsigned long Val, unsigned Depth);
/* Insert a new case value into a CaseNode tree with the given depth. Return
* the code label for the value.
*/
** the code label for the value.
*/

View File

@@ -96,8 +96,8 @@ static char* GetArgCopy (const char* Arg)
static int NumArg (const char* Arg, unsigned long* Num)
/* If the given argument is numerical, convert it and return true. Otherwise
* set Num to zero and return false.
*/
** set Num to zero and return false.
*/
{
char* End;
unsigned long Val;
@@ -113,8 +113,8 @@ static int NumArg (const char* Arg, unsigned long* Num)
}
/* Convert the value. strtol is not exactly what we want here, but it's
* cheap and may be replaced by something fancier later.
*/
** cheap and may be replaced by something fancier later.
*/
Val = strtoul (Arg, &End, Base);
/* Check if the conversion was successful */
@@ -141,16 +141,16 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D)
const ZPInfo* Info;
/* If this is a subroutine call, or a jump to an external function,
* lookup the information about this function and use it. The jump itself
* does not change any registers, so we don't need to use the data from D.
*/
** lookup the information about this function and use it. The jump itself
** does not change any registers, so we don't need to use the data from D.
*/
if ((E->Info & (OF_UBRA | OF_CALL)) != 0 && E->JumpTo == 0) {
/* A subroutine call or jump to external symbol (function exit) */
GetFuncInfo (E->Arg, &E->Use, &E->Chg);
} else {
/* Some other instruction. Use the values from the opcode description
* plus addressing mode info.
*/
** plus addressing mode info.
*/
E->Use = D->Use | GetAMUseInfo (E->AM);
E->Chg = D->Chg;
@@ -218,11 +218,11 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D)
const char* MakeHexArg (unsigned Num)
/* Convert Num into a string in the form $XY, suitable for passing it as an
* argument to NewCodeEntry, and return a pointer to the string.
* BEWARE: The function returns a pointer to a static buffer, so the value is
* gone if you call it twice (and apart from that it's not thread and signal
* safe).
*/
** argument to NewCodeEntry, and return a pointer to the string.
** BEWARE: The function returns a pointer to a static buffer, so the value is
** gone if you call it twice (and apart from that it's not thread and signal
** safe).
*/
{
static char Buf[16];
xsprintf (Buf, sizeof (Buf), "$%02X", (unsigned char) Num);
@@ -288,8 +288,8 @@ void FreeCodeEntry (CodeEntry* E)
void CE_ReplaceOPC (CodeEntry* E, opc_t OPC)
/* Replace the opcode of the instruction. This will also replace related info,
* Size, Use and Chg, but it will NOT update any arguments or labels.
*/
** Size, Use and Chg, but it will NOT update any arguments or labels.
*/
{
/* Get the opcode descriptor */
const OPCDesc* D = GetOPCDesc (OPC);
@@ -325,9 +325,9 @@ void CE_AttachLabel (CodeEntry* E, CodeLabel* L)
void CE_ClearJumpTo (CodeEntry* E)
/* Clear the JumpTo entry and the argument (which contained the name of the
* label). Note: The function will not clear the backpointer from the label,
* so use it with care.
*/
** label). Note: The function will not clear the backpointer from the label,
** so use it with care.
*/
{
/* Clear the JumpTo entry */
E->JumpTo = 0;
@@ -366,8 +366,8 @@ void CE_SetArg (CodeEntry* E, const char* Arg)
void CE_SetNumArg (CodeEntry* E, long Num)
/* Set a new numeric argument for the given code entry that must already
* have a numeric argument.
*/
** have a numeric argument.
*/
{
char Buf[16];
@@ -404,8 +404,8 @@ int CE_IsConstImm (const CodeEntry* E)
int CE_IsKnownImm (const CodeEntry* E, unsigned long Num)
/* Return true if the argument of E is a constant immediate value that is
* equal to Num.
*/
** equal to Num.
*/
{
return (E->AM == AM65_IMM && CE_HasNumArg (E) && E->Num == Num);
}
@@ -414,12 +414,12 @@ int CE_IsKnownImm (const CodeEntry* E, unsigned long Num)
int CE_UseLoadFlags (CodeEntry* E)
/* Return true if the instruction uses any flags that are set by a load of
* a register (N and Z).
*/
** a register (N and Z).
*/
{
/* Follow unconditional branches, but beware of endless loops. After this,
* E will point to the first entry that is not a branch.
*/
** E will point to the first entry that is not a branch.
*/
if (E->Info & OF_UBRA) {
Collection C = AUTO_COLLECTION_INITIALIZER;
@@ -491,8 +491,8 @@ void CE_FreeRegInfo (CodeEntry* E)
void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
/* Generate register info for this instruction. If an old info exists, it is
* overwritten.
*/
** overwritten.
*/
{
/* Pointers to the register contents */
RegContents* In;
@@ -522,8 +522,8 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
case OP65_ADC:
/* We don't know the value of the carry, so the result is
* always unknown.
*/
** always unknown.
*/
Out->RegA = UNKNOWN_REGVAL;
break;

View File

@@ -90,11 +90,11 @@ struct CodeEntry {
const char* MakeHexArg (unsigned Num);
/* Convert Num into a string in the form $XY, suitable for passing it as an
* argument to NewCodeEntry, and return a pointer to the string.
* BEWARE: The function returns a pointer to a static buffer, so the value is
* gone if you call it twice (and apart from that it's not thread and signal
* safe).
*/
** argument to NewCodeEntry, and return a pointer to the string.
** BEWARE: The function returns a pointer to a static buffer, so the value is
** gone if you call it twice (and apart from that it's not thread and signal
** safe).
*/
CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg,
CodeLabel* JumpTo, LineInfo* LI);
@@ -105,8 +105,8 @@ void FreeCodeEntry (CodeEntry* E);
void CE_ReplaceOPC (CodeEntry* E, opc_t OPC);
/* Replace the opcode of the instruction. This will also replace related info,
* Size, Use and Chg, but it will NOT update any arguments or labels.
*/
** Size, Use and Chg, but it will NOT update any arguments or labels.
*/
int CodeEntriesAreEqual (const CodeEntry* E1, const CodeEntry* E2);
/* Check if both code entries are equal */
@@ -116,9 +116,9 @@ void CE_AttachLabel (CodeEntry* E, CodeLabel* L);
void CE_ClearJumpTo (CodeEntry* E);
/* Clear the JumpTo entry and the argument (which contained the name of the
* label). Note: The function will not clear the backpointer from the label,
* so use it with care.
*/
** label). Note: The function will not clear the backpointer from the label,
** so use it with care.
*/
#if defined(HAVE_INLINE)
INLINE int CE_HasLabel (const CodeEntry* E)
@@ -198,16 +198,16 @@ void CE_SetArg (CodeEntry* E, const char* Arg);
void CE_SetNumArg (CodeEntry* E, long Num);
/* Set a new numeric argument for the given code entry that must already
* have a numeric argument.
*/
** have a numeric argument.
*/
int CE_IsConstImm (const CodeEntry* E);
/* Return true if the argument of E is a constant immediate value */
int CE_IsKnownImm (const CodeEntry* E, unsigned long Num);
/* Return true if the argument of E is a constant immediate value that is
* equal to Num.
*/
** equal to Num.
*/
#if defined(HAVE_INLINE)
INLINE int CE_IsCallTo (const CodeEntry* E, const char* Name)
@@ -221,16 +221,16 @@ INLINE int CE_IsCallTo (const CodeEntry* E, const char* Name)
int CE_UseLoadFlags (CodeEntry* E);
/* Return true if the instruction uses any flags that are set by a load of
* a register (N and Z).
*/
** a register (N and Z).
*/
void CE_FreeRegInfo (CodeEntry* E);
/* Free an existing register info struct */
void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs);
/* Generate register info for this instruction. If an old info exists, it is
* overwritten.
*/
** overwritten.
*/
void CE_Output (const CodeEntry* E);
/* Output the code entry to the output file */

View File

@@ -192,8 +192,8 @@ void g_fileinfo (const char* Name, unsigned long Size, unsigned long MTime)
{
if (DebugInfo) {
/* We have to place this into the global text segment, so it will
* appear before all .dbg line statements.
*/
** appear before all .dbg line statements.
*/
TS_AddLine (GS->Text, "\t.dbg\t\tfile, \"%s\", %lu, %lu", Name, Size, MTime);
}
}
@@ -298,15 +298,15 @@ int push (unsigned flags)
static unsigned MakeByteOffs (unsigned Flags, unsigned Offs)
/* The value in Offs is an offset to an address in a/x. Make sure, an object
* of the type given in Flags can be loaded or stored into this address by
* adding part of the offset to the address in ax, so that the remaining
* offset fits into an index register. Return the remaining offset.
*/
** of the type given in Flags can be loaded or stored into this address by
** adding part of the offset to the address in ax, so that the remaining
** offset fits into an index register. Return the remaining offset.
*/
{
/* If the offset is too large for a byte register, add the high byte
* of the offset to the primary. Beware: We need a special correction
* if the offset in the low byte will overflow in the operation.
*/
** of the offset to the primary. Beware: We need a special correction
** if the offset in the low byte will overflow in the operation.
*/
unsigned O = Offs & ~0xFFU;
if ((Offs & 0xFF) > 256 - sizeofarg (Flags)) {
/* We need to add the low byte also */
@@ -351,8 +351,8 @@ void g_aliasdatalabel (unsigned label, unsigned baselabel, long offs)
/* Define label as a local alias for baselabel+offs */
{
/* We need an intermediate buffer here since LocalLabelName uses a
* static buffer which changes with each call.
*/
** static buffer which changes with each call.
*/
StrBuf L = AUTO_STRBUF_INITIALIZER;
SB_AppendStr (&L, LocalLabelName (label));
SB_Terminate (&L);
@@ -427,10 +427,10 @@ void g_importmainargs (void)
/* Remember the argument size of a function. The variable is set by g_enter
* and used by g_leave. If the functions gets its argument size by the caller
* (variable param list or function without prototype), g_enter will set the
* value to -1.
*/
** and used by g_leave. If the function gets its argument size by the caller
** (variable param list or function without prototype), g_enter will set the
** value to -1.
*/
static int funcargs;
@@ -602,9 +602,9 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes)
} else if (StackOffs <= RegOffs) {
/* More bytes, but the relation between the register offset in the
* register bank and the stack offset allows us to generate short
* code that uses just one index register.
*/
** register bank and the stack offset allows us to generate short
** code that uses just one index register.
*/
unsigned Label = GetLocalLabel ();
AddCodeLine ("ldy #$%02X", StackOffs);
g_defcodelabel (Label);
@@ -616,9 +616,9 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes)
} else {
/* Ok, this is the generic code. We need to save X because the
* caller will only save A.
*/
/* OK, this is the generic code. We need to save X because the
** caller will only save A.
*/
unsigned Label = GetLocalLabel ();
AddCodeLine ("stx tmp1");
AddCodeLine ("ldy #$%02X", (unsigned char) (StackOffs + Bytes - 1));
@@ -840,13 +840,13 @@ void g_getlocal (unsigned Flags, int Offs)
void g_getind (unsigned Flags, unsigned Offs)
/* Fetch the specified object type indirect through the primary register
* into the primary register
*/
** into the primary register
*/
{
/* If the offset is greater than 255, add the part that is > 255 to
* the primary. This way we get an easy addition and use the low byte
* as the offset
*/
** the primary. This way we get an easy addition and use the low byte
** as the offset
*/
Offs = MakeByteOffs (Flags, Offs);
/* Handle the indirect fetch */
@@ -958,8 +958,8 @@ void g_leasp (int Offs)
void g_leavariadic (int Offs)
/* Fetch the address of a parameter in a variadic function into the primary
* register
*/
** register
*/
{
unsigned ArgSizeOffs;
@@ -967,8 +967,8 @@ void g_leavariadic (int Offs)
Offs -= StackPtr;
/* Get the offset of the parameter which is stored at sp+0 on function
* entry and check if this offset is reachable with a byte offset.
*/
** entry and check if this offset is reachable with a byte offset.
*/
CHECK (StackPtr <= 0);
ArgSizeOffs = -StackPtr;
CheckLocalOffs (ArgSizeOffs);
@@ -1106,14 +1106,14 @@ void g_putlocal (unsigned Flags, int Offs, long Val)
void g_putind (unsigned Flags, unsigned Offs)
/* Store the specified object type in the primary register at the address
* on the top of the stack
*/
** on the top of the stack
*/
{
/* We can handle offsets below $100 directly, larger offsets must be added
* to the address. Since a/x is in use, best code is achieved by adding
* just the high byte. Be sure to check if the low byte will overflow while
* while storing.
*/
** to the address. Since a/x is in use, best code is achieved by adding
** just the high byte. Be sure to check if the low byte will overflow while
** while storing.
*/
if ((Offs & 0xFF) > 256 - sizeofarg (Flags | CF_FORCECHAR)) {
/* Overflow - we need to add the low byte also */
@@ -1321,9 +1321,9 @@ void g_reglong (unsigned Flags)
unsigned g_typeadjust (unsigned lhs, unsigned rhs)
/* Adjust the integer operands before doing a binary operation. lhs is a flags
* value, that corresponds to the value on TOS, rhs corresponds to the value
* in (e)ax. The return value is the the flags value for the resulting type.
*/
** value, that corresponds to the value on TOS, rhs corresponds to the value
** in (e)ax. The return value is the the flags value for the resulting type.
*/
{
unsigned ltype, rtype;
unsigned result;
@@ -1352,11 +1352,11 @@ unsigned g_typeadjust (unsigned lhs, unsigned rhs)
}
/* Determine the result type for the operation:
* - The result is const if both operands are const.
* - The result is unsigned if one of the operands is unsigned.
* - The result is long if one of the operands is long.
* - Otherwise the result is int sized.
*/
** - The result is const if both operands are const.
** - The result is unsigned if one of the operands is unsigned.
** - The result is long if one of the operands is long.
** - Otherwise the result is int sized.
*/
result = (lhs & CF_CONST) & (rhs & CF_CONST);
result |= (lhs & CF_UNSIGNED) | (rhs & CF_UNSIGNED);
if (rtype == CF_LONG || ltype == CF_LONG) {
@@ -1371,8 +1371,8 @@ unsigned g_typeadjust (unsigned lhs, unsigned rhs)
unsigned g_typecast (unsigned lhs, unsigned rhs)
/* Cast the value in the primary register to the operand size that is flagged
* by the lhs value. Return the result value.
*/
** by the lhs value. Return the result value.
*/
{
unsigned ltype, rtype;
@@ -1392,17 +1392,17 @@ unsigned g_typecast (unsigned lhs, unsigned rhs)
}
/* Do not need any other action. If the left type is int, and the primary
* register is long, it will be automagically truncated. If the right hand
* side is const, it is not located in the primary register and handled by
* the expression parser code.
*/
** register is long, it will be automagically truncated. If the right hand
** side is const, it is not located in the primary register and handled by
** the expression parser code.
*/
/* Result is const if the right hand side was const */
lhs |= (rhs & CF_CONST);
/* The resulting type is that of the left hand side (that's why you called
* this function :-)
*/
** this function :-)
*/
return lhs;
}
@@ -1410,10 +1410,10 @@ unsigned g_typecast (unsigned lhs, unsigned rhs)
void g_scale (unsigned flags, long val)
/* Scale the value in the primary register by the given value. If val is positive,
* scale up, is val is negative, scale down. This function is used to scale
* the operands or results of pointer arithmetic by the size of the type, the
* pointer points to.
*/
** scale up, is val is negative, scale down. This function is used to scale
** the operands or results of pointer arithmetic by the size of the type, the
** pointer points to.
*/
{
int p2;
@@ -1813,9 +1813,9 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val)
/* Emit += for the location with address in ax */
{
/* If the offset is too large for a byte register, add the high byte
* of the offset to the primary. Beware: We need a special correction
* if the offset in the low byte will overflow in the operation.
*/
** of the offset to the primary. Beware: We need a special correction
** if the offset in the low byte will overflow in the operation.
*/
offs = MakeByteOffs (flags, offs);
/* Check the size and determine operation */
@@ -2009,9 +2009,9 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val)
/* Emit -= for the location with address in ax */
{
/* If the offset is too large for a byte register, add the high byte
* of the offset to the primary. Beware: We need a special correction
* if the offset in the low byte will overflow in the operation.
*/
** of the offset to the primary. Beware: We need a special correction
** if the offset in the low byte will overflow in the operation.
*/
offs = MakeByteOffs (flags, offs);
/* Check the size and determine operation */
@@ -2168,8 +2168,8 @@ void g_restore (unsigned flags)
void g_cmp (unsigned flags, unsigned long val)
/* Immidiate compare. The primary register will not be changed, Z flag
* will be set.
*/
** will be set.
*/
{
unsigned L;
@@ -2204,11 +2204,11 @@ void g_cmp (unsigned flags, unsigned long val)
static void oper (unsigned Flags, unsigned long Val, const char** Subs)
/* Encode a binary operation. subs is a pointer to four strings:
* 0 --> Operate on ints
* 1 --> Operate on unsigneds
* 2 --> Operate on longs
* 3 --> Operate on unsigned longs
*/
** 0 --> Operate on ints
** 1 --> Operate on unsigneds
** 2 --> Operate on longs
** 3 --> Operate on unsigned longs
*/
{
/* Determine the offset into the array */
if (Flags & CF_UNSIGNED) {
@@ -2326,8 +2326,8 @@ void g_push (unsigned flags, unsigned long val)
void g_swap (unsigned flags)
/* Swap the primary register and the top of the stack. flags give the type
* of *both* values (must have same size).
*/
** of *both* values (must have same size).
*/
{
switch (flags & CF_TYPEMASK) {
@@ -2421,8 +2421,8 @@ void g_drop (unsigned Space)
{
if (Space > 255) {
/* Inline the code since calling addysp repeatedly is quite some
* overhead.
*/
** overhead.
*/
AddCodeLine ("pha");
AddCodeLine ("lda #$%02X", (unsigned char) Space);
AddCodeLine ("clc");
@@ -2450,8 +2450,8 @@ void g_space (int Space)
g_drop (-Space);
} else if (Space > 255) {
/* Inline the code since calling subysp repeatedly is quite some
* overhead.
*/
** overhead.
*/
AddCodeLine ("pha");
AddCodeLine ("lda sp");
AddCodeLine ("sec");
@@ -2547,8 +2547,8 @@ void g_mul (unsigned flags, unsigned long val)
}
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
switch (flags & CF_TYPEMASK) {
@@ -2624,8 +2624,8 @@ void g_mul (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff.
*/
** into the normal, non-optimized stuff.
*/
flags &= ~CF_FORCECHAR; /* Handle chars as ints */
g_push (flags & ~CF_CONST, 0);
@@ -2695,8 +2695,8 @@ void g_or (unsigned flags, unsigned long val)
};
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
switch (flags & CF_TYPEMASK) {
@@ -2744,9 +2744,9 @@ void g_or (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
flags &= ~CF_FORCECHAR;
g_push (flags & ~CF_CONST, 0);
}
@@ -2766,8 +2766,8 @@ void g_xor (unsigned flags, unsigned long val)
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
switch (flags & CF_TYPEMASK) {
@@ -2812,9 +2812,9 @@ void g_xor (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
flags &= ~CF_FORCECHAR;
g_push (flags & ~CF_CONST, 0);
}
@@ -2833,8 +2833,8 @@ void g_and (unsigned Flags, unsigned long Val)
};
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (Flags & CF_CONST) {
switch (Flags & CF_TYPEMASK) {
@@ -2904,9 +2904,9 @@ void g_and (unsigned Flags, unsigned long Val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
Flags &= ~CF_FORCECHAR;
g_push (Flags & ~CF_CONST, 0);
}
@@ -2925,8 +2925,8 @@ void g_asr (unsigned flags, unsigned long val)
};
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
switch (flags & CF_TYPEMASK) {
@@ -3035,9 +3035,9 @@ void g_asr (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
flags &= ~CF_FORCECHAR;
g_push (flags & ~CF_CONST, 0);
}
@@ -3057,8 +3057,8 @@ void g_asl (unsigned flags, unsigned long val)
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
switch (flags & CF_TYPEMASK) {
@@ -3134,9 +3134,9 @@ void g_asl (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
flags &= ~CF_FORCECHAR;
g_push (flags & ~CF_CONST, 0);
}
@@ -3419,10 +3419,10 @@ void g_dec (unsigned flags, unsigned long val)
/*
* Following are the conditional operators. They compare the TOS against
* the primary and put a literal 1 in the primary if the condition is
* true, otherwise they clear the primary register
*/
** Following are the conditional operators. They compare the TOS against
** the primary and put a literal 1 in the primary if the condition is
** true, otherwise they clear the primary register
*/
@@ -3436,8 +3436,8 @@ void g_eq (unsigned flags, unsigned long val)
unsigned L;
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
switch (flags & CF_TYPEMASK) {
@@ -3467,9 +3467,9 @@ void g_eq (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
flags &= ~CF_FORCECHAR;
g_push (flags & ~CF_CONST, 0);
}
@@ -3490,8 +3490,8 @@ void g_ne (unsigned flags, unsigned long val)
unsigned L;
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
switch (flags & CF_TYPEMASK) {
@@ -3521,9 +3521,9 @@ void g_ne (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
flags &= ~CF_FORCECHAR;
g_push (flags & ~CF_CONST, 0);
}
@@ -3544,14 +3544,14 @@ void g_lt (unsigned flags, unsigned long val)
unsigned Label;
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
/* Because the handling of the overflow flag is too complex for
* inlining, we can handle only unsigned compares, and signed
* compares against zero here.
*/
** inlining, we can handle only unsigned compares, and signed
** compares against zero here.
*/
if (flags & CF_UNSIGNED) {
/* Give a warning in some special cases */
@@ -3683,9 +3683,9 @@ void g_lt (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
flags &= ~CF_FORCECHAR;
g_push (flags & ~CF_CONST, 0);
}
@@ -3705,8 +3705,8 @@ void g_le (unsigned flags, unsigned long val)
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
/* Look at the type */
@@ -3718,8 +3718,8 @@ void g_le (unsigned flags, unsigned long val)
/* Unsigned compare */
if (val < 0xFF) {
/* Use < instead of <= because the former gives
* better code on the 6502 than the latter.
*/
** better code on the 6502 than the latter.
*/
g_lt (flags, val+1);
} else {
/* Always true */
@@ -3730,8 +3730,8 @@ void g_le (unsigned flags, unsigned long val)
/* Signed compare */
if ((long) val < 0x7F) {
/* Use < instead of <= because the former gives
* better code on the 6502 than the latter.
*/
** better code on the 6502 than the latter.
*/
g_lt (flags, val+1);
} else {
/* Always true */
@@ -3748,8 +3748,8 @@ void g_le (unsigned flags, unsigned long val)
/* Unsigned compare */
if (val < 0xFFFF) {
/* Use < instead of <= because the former gives
* better code on the 6502 than the latter.
*/
** better code on the 6502 than the latter.
*/
g_lt (flags, val+1);
} else {
/* Always true */
@@ -3773,8 +3773,8 @@ void g_le (unsigned flags, unsigned long val)
/* Unsigned compare */
if (val < 0xFFFFFFFF) {
/* Use < instead of <= because the former gives
* better code on the 6502 than the latter.
*/
** better code on the 6502 than the latter.
*/
g_lt (flags, val+1);
} else {
/* Always true */
@@ -3798,9 +3798,9 @@ void g_le (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
flags &= ~CF_FORCECHAR;
g_push (flags & ~CF_CONST, 0);
}
@@ -3820,8 +3820,8 @@ void g_gt (unsigned flags, unsigned long val)
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
/* Look at the type */
@@ -3832,14 +3832,14 @@ void g_gt (unsigned flags, unsigned long val)
if (flags & CF_UNSIGNED) {
if (val == 0) {
/* If we have a compare > 0, we will replace it by
* != 0 here, since both are identical but the
* latter is easier to optimize.
*/
** != 0 here, since both are identical but the
** latter is easier to optimize.
*/
g_ne (flags, val);
} else if (val < 0xFF) {
/* Use >= instead of > because the former gives
* better code on the 6502 than the latter.
*/
** better code on the 6502 than the latter.
*/
g_ge (flags, val+1);
} else {
/* Never true */
@@ -3849,8 +3849,8 @@ void g_gt (unsigned flags, unsigned long val)
} else {
if ((long) val < 0x7F) {
/* Use >= instead of > because the former gives
* better code on the 6502 than the latter.
*/
** better code on the 6502 than the latter.
*/
g_ge (flags, val+1);
} else {
/* Never true */
@@ -3867,14 +3867,14 @@ void g_gt (unsigned flags, unsigned long val)
/* Unsigned compare */
if (val == 0) {
/* If we have a compare > 0, we will replace it by
* != 0 here, since both are identical but the latter
* is easier to optimize.
*/
** != 0 here, since both are identical but the latter
** is easier to optimize.
*/
g_ne (flags, val);
} else if (val < 0xFFFF) {
/* Use >= instead of > because the former gives better
* code on the 6502 than the latter.
*/
** code on the 6502 than the latter.
*/
g_ge (flags, val+1);
} else {
/* Never true */
@@ -3898,14 +3898,14 @@ void g_gt (unsigned flags, unsigned long val)
/* Unsigned compare */
if (val == 0) {
/* If we have a compare > 0, we will replace it by
* != 0 here, since both are identical but the latter
* is easier to optimize.
*/
** != 0 here, since both are identical but the latter
** is easier to optimize.
*/
g_ne (flags, val);
} else if (val < 0xFFFFFFFF) {
/* Use >= instead of > because the former gives better
* code on the 6502 than the latter.
*/
** code on the 6502 than the latter.
*/
g_ge (flags, val+1);
} else {
/* Never true */
@@ -3929,9 +3929,9 @@ void g_gt (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
flags &= ~CF_FORCECHAR;
g_push (flags & ~CF_CONST, 0);
}
@@ -3953,14 +3953,14 @@ void g_ge (unsigned flags, unsigned long val)
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
** in the primary register.
*/
if (flags & CF_CONST) {
/* Because the handling of the overflow flag is too complex for
* inlining, we can handle only unsigned compares, and signed
* compares against zero here.
*/
** inlining, we can handle only unsigned compares, and signed
** compares against zero here.
*/
if (flags & CF_UNSIGNED) {
/* Give a warning in some special cases */
@@ -4087,9 +4087,9 @@ void g_ge (unsigned flags, unsigned long val)
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
** into the normal, non-optimized stuff. Note: The standard stuff will
** always work with ints.
*/
flags &= ~CF_FORCECHAR;
g_push (flags & ~CF_CONST, 0);
}

View File

@@ -53,11 +53,11 @@
/* Code generator flags.
* Note: The type flags are designed so that a smaller type may override a
* larger one by or'ing it into the existing one.
* Note^2: The actual type including the sign flag is in the lower bits, so
* we can mask the information and use them as a table index.
*/
** Note: The type flags are designed so that a smaller type may override a
** larger one by or'ing it into the existing one.
** Note^2: The actual type including the sign flag is in the lower bits, so
** we can mask the information and use them as a table index.
*/
#define CF_NONE 0x0000 /* No special flags */
/* Values for the actual type */
@@ -208,21 +208,21 @@ void g_reglong (unsigned Flags);
unsigned g_typeadjust (unsigned lhs, unsigned rhs);
/* Adjust the integer operands before doing a binary operation. lhs is a flags
* value, that corresponds to the value on TOS, rhs corresponds to the value
* in (e)ax. The return value is the the flags value for the resulting type.
*/
** value, that corresponds to the value on TOS, rhs corresponds to the value
** in (e)ax. The return value is the the flags value for the resulting type.
*/
unsigned g_typecast (unsigned lhs, unsigned rhs);
/* Cast the value in the primary register to the operand size that is flagged
* by the lhs value. Return the result value.
*/
** by the lhs value. Return the result value.
*/
void g_scale (unsigned flags, long val);
/* Scale the value in the primary register by the given value. If val is positive,
* scale up, is val is negative, scale down. This function is used to scale
* the operands or results of pointer arithmetic by the size of the type, the
* pointer points to.
*/
** scale up, is val is negative, scale down. This function is used to scale
** the operands or results of pointer arithmetic by the size of the type, the
** pointer points to.
*/
@@ -274,16 +274,16 @@ void g_getlocal (unsigned Flags, int Offs);
void g_getind (unsigned Flags, unsigned Offs);
/* Fetch the specified object type indirect through the primary register
* into the primary register
*/
** into the primary register
*/
void g_leasp (int Offs);
/* Fetch the address of the specified symbol into the primary register */
void g_leavariadic (int Offs);
/* Fetch the address of a parameter in a variadic function into the primary
* register
*/
** register
*/
@@ -301,8 +301,8 @@ void g_putlocal (unsigned Flags, int Offs, long Val);
void g_putind (unsigned flags, unsigned offs);
/* Store the specified object type in the primary register at the address
* on the top of the stack
*/
** on the top of the stack
*/
@@ -376,8 +376,8 @@ void g_restore (unsigned flags);
void g_cmp (unsigned flags, unsigned long val);
/* Immidiate compare. The primary register will not be changed, Z flag
* will be set.
*/
** will be set.
*/
void g_test (unsigned flags);
/* Test the value in the primary and set the condition codes */
@@ -387,8 +387,8 @@ void g_push (unsigned flags, unsigned long val);
void g_swap (unsigned flags);
/* Swap the primary register and the top of the stack. flags give the type
* of *both* values (must have same size).
*/
** of *both* values (must have same size).
*/
void g_call (unsigned Flags, const char* Label, unsigned ArgSize);
/* Call the specified subroutine name */

View File

@@ -64,8 +64,8 @@ static const char CmpSuffixTab [][4] = {
};
/* Table listing the function names and code info values for known internally
* used functions. This table should get auto-generated in the future.
*/
** used functions. This table should get auto-generated in the future.
*/
typedef struct FuncInfo FuncInfo;
struct FuncInfo {
const char* Name; /* Function name */
@@ -74,9 +74,9 @@ struct FuncInfo {
};
/* Note for the shift functions: Shifts are done modulo 32, so all shift
* routines are marked to use only the A register. The remainder is ignored
* anyway.
*/
** routines are marked to use only the A register. The remainder is ignored
** anyway.
*/
static const FuncInfo FuncInfoTable[] = {
{ "addeq0sp", REG_AX, REG_AXY },
{ "addeqysp", REG_AXY, REG_AXY },
@@ -376,15 +376,15 @@ static int CompareFuncInfo (const void* Key, const void* Info)
void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg)
/* For the given function, lookup register information and store it into
* the given variables. If the function is unknown, assume it will use and
* load all registers.
*/
** the given variables. If the function is unknown, assume it will use and
** load all registers.
*/
{
/* If the function name starts with an underline, it is an external
* function. Search for it in the symbol table. If the function does
* not start with an underline, it may be a runtime support function.
* Search for it in the list of builtin functions.
*/
** function. Search for it in the symbol table. If the function does
** not start with an underline, it may be a runtime support function.
** Search for it in the list of builtin functions.
*/
if (Name[0] == '_') {
/* Search in the symbol table, skip the leading underscore */
@@ -396,11 +396,11 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg)
FuncDesc* D = E->V.F.Func;
/* A function may use the A or A/X registers if it is a fastcall
* function. If it is not a fastcall function but a variadic one,
* it will use the Y register (the parameter size is passed here).
* In all other cases, no registers are used. However, we assume
* that any function will destroy all registers.
*/
** function. If it is not a fastcall function but a variadic one,
** it will use the Y register (the parameter size is passed here).
** In all other cases, no registers are used. However, we assume
** that any function will destroy all registers.
*/
if (IsQualFastcall (E->Type) && D->ParamCount > 0) {
/* Will use registers depending on the last param */
unsigned LastParamSize = CheckedSizeOf (D->LastParam->Type);
@@ -428,9 +428,9 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg)
} else if (IsDigit (Name[0]) || Name[0] == '$') {
/* A call to a numeric address. Assume that anything gets used and
* destroyed. This is not a real problem, since numeric addresses
* are used mostly in inline assembly anyway.
*/
** destroyed. This is not a real problem, since numeric addresses
** are used mostly in inline assembly anyway.
*/
*Use = REG_ALL;
*Chg = REG_ALL;
return;
@@ -448,10 +448,10 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg)
*Chg = Info->Chg;
} else {
/* It's an internal function we have no information for. If in
* debug mode, output an additional warning, so we have a chance
* to fix it. Otherwise assume that the internal function will
* use and change all registers.
*/
** debug mode, output an additional warning, so we have a chance
** to fix it. Otherwise assume that the internal function will
** use and change all registers.
*/
if (Debug) {
fprintf (stderr, "No info about internal function `%s'\n", Name);
}
@@ -462,8 +462,8 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg)
}
/* Function not found - assume that the primary register is input, and all
* registers are changed
*/
** registers are changed
*/
*Use = REG_EAXY;
*Chg = REG_ALL;
}
@@ -478,8 +478,8 @@ static int CompareZPInfo (const void* Name, const void* Info)
const ZPInfo* E = (const ZPInfo*) Info;
/* Do the compare. Be careful because of the length (Info may contain
* more than just the zeropage name).
*/
** more than just the zeropage name).
*/
if (E->Len == 0) {
/* Do a full compare */
return strcmp (N, E->Name);
@@ -498,8 +498,8 @@ static int CompareZPInfo (const void* Name, const void* Info)
const ZPInfo* GetZPInfo (const char* Name)
/* If the given name is a zero page symbol, return a pointer to the info
* struct for this symbol, otherwise return NULL.
*/
** struct for this symbol, otherwise return NULL.
*/
{
/* Search for the zp location in the list */
return bsearch (Name, ZPInfoTable, ZPInfoCount,
@@ -523,8 +523,8 @@ static unsigned GetRegInfo2 (CodeSeg* S,
unsigned R;
/* Check if we have already visited the current code entry. If so,
* bail out.
*/
** bail out.
*/
if (CE_HasMark (E)) {
break;
}
@@ -542,8 +542,8 @@ static unsigned GetRegInfo2 (CodeSeg* S,
}
if (R != REG_NONE) {
/* We are not interested in the use of any register that has been
* used before.
*/
** used before.
*/
R &= ~Unused;
/* Remember the remaining registers */
Used |= R;
@@ -552,8 +552,8 @@ static unsigned GetRegInfo2 (CodeSeg* S,
/* Evaluate the changed registers */
if ((R = E->Chg) != REG_NONE) {
/* We are not interested in the use of any register that has been
* used before.
*/
** used before.
*/
R &= ~Used;
/* Remember the remaining registers */
Unused |= R;
@@ -570,8 +570,8 @@ static unsigned GetRegInfo2 (CodeSeg* S,
}
/* If we have an unconditional branch, follow this branch if possible,
* otherwise we're done.
*/
** otherwise we're done.
*/
if ((E->Info & OF_UBRA) != 0) {
/* Does this jump have a valid target? */
@@ -587,9 +587,9 @@ static unsigned GetRegInfo2 (CodeSeg* S,
}
/* In case of conditional branches, follow the branch if possible and
* follow the normal flow (branch not taken) afterwards. If we cannot
* follow the branch, we're done.
*/
** follow the normal flow (branch not taken) afterwards. If we cannot
** follow the branch, we're done.
*/
} else if ((E->Info & OF_CBRA) != 0) {
/* Recursively determine register usage at the branch target */
@@ -604,8 +604,8 @@ static unsigned GetRegInfo2 (CodeSeg* S,
} else {
/* Jump to external label. This will effectively exit the
* function, so we use the exitregs information here.
*/
** function, so we use the exitregs information here.
*/
U1 = S->ExitRegs;
}
@@ -677,8 +677,8 @@ static unsigned GetRegInfo1 (CodeSeg* S,
unsigned GetRegInfo (struct CodeSeg* S, unsigned Index, unsigned Wanted)
/* Determine register usage information for the instructions starting at the
* given index.
*/
** given index.
*/
{
CodeEntry* E;
Collection Visited; /* Visited entries */
@@ -748,9 +748,9 @@ int RegEAXUsed (struct CodeSeg* S, unsigned Index)
unsigned GetKnownReg (unsigned Use, const RegContents* RC)
/* Return the register or zero page location from the set in Use, thats
* contents are known. If Use does not contain any register, or if the
* register in question does not have a known value, return REG_NONE.
*/
** contents are known. If Use does not contain any register, or if the
** register in question does not have a known value, return REG_NONE.
*/
{
if ((Use & REG_A) != 0) {
return (RC == 0 || RC->RegA >= 0)? REG_A : REG_NONE;
@@ -796,9 +796,9 @@ static cmp_t FindCmpCond (const char* Code, unsigned CodeLen)
cmp_t FindBoolCmpCond (const char* Name)
/* Check if the given string is the name of one of the boolean transformer
* subroutine, and if so, return the condition that is evaluated by this
* routine. Return CMP_INV if the condition is not recognised.
*/
** subroutine, and if so, return the condition that is evaluated by this
** routine. Return CMP_INV if the condition is not recognised.
*/
{
/* Check for the correct subroutine name */
if (strncmp (Name, "bool", 4) == 0) {
@@ -814,8 +814,8 @@ cmp_t FindBoolCmpCond (const char* Name)
cmp_t FindTosCmpCond (const char* Name)
/* Check if this is a call to one of the TOS compare functions (tosgtax).
* Return the condition code or CMP_INV on failure.
*/
** Return the condition code or CMP_INV on failure.
*/
{
unsigned Len = strlen (Name);

View File

@@ -128,19 +128,19 @@ typedef enum {
void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg);
/* For the given function, lookup register information and store it into
* the given variables. If the function is unknown, assume it will use and
* load all registers.
*/
** the given variables. If the function is unknown, assume it will use and
** load all registers.
*/
const ZPInfo* GetZPInfo (const char* Name);
/* If the given name is a zero page symbol, return a pointer to the info
* struct for this symbol, otherwise return NULL.
*/
** struct for this symbol, otherwise return NULL.
*/
unsigned GetRegInfo (struct CodeSeg* S, unsigned Index, unsigned Wanted);
/* Determine register usage information for the instructions starting at the
* given index.
*/
** given index.
*/
int RegAUsed (struct CodeSeg* S, unsigned Index);
/* Check if the value in A is used. */
@@ -159,20 +159,20 @@ int RegEAXUsed (struct CodeSeg* S, unsigned Index);
unsigned GetKnownReg (unsigned Use, const struct RegContents* RC);
/* Return the register or zero page location from the set in Use, thats
* contents are known. If Use does not contain any register, or if the
* register in question does not have a known value, return REG_NONE.
*/
** contents are known. If Use does not contain any register, or if the
** register in question does not have a known value, return REG_NONE.
*/
cmp_t FindBoolCmpCond (const char* Name);
/* Check if the given string is the name of one of the boolean transformer
* subroutine, and if so, return the condition that is evaluated by this
* routine. Return CMP_INV if the condition is not recognised.
*/
** subroutine, and if so, return the condition that is evaluated by this
** routine. Return CMP_INV if the condition is not recognised.
*/
cmp_t FindTosCmpCond (const char* Name);
/* Check if this is a call to one of the TOS compare functions (tosgtax).
* Return the condition code or CMP_INV on failure.
*/
** Return the condition code or CMP_INV on failure.
*/

View File

@@ -101,8 +101,8 @@ void CL_AddRef (CodeLabel* L, struct CodeEntry* E)
void CL_MoveRefs (CodeLabel* OldLabel, CodeLabel* NewLabel)
/* Move all references to OldLabel to point to NewLabel. OldLabel will have no
* more references on return.
*/
** more references on return.
*/
{
/* Walk through all instructions referencing the old label */
unsigned Count = CL_GetRefCount (OldLabel);

View File

@@ -108,8 +108,8 @@ void CL_AddRef (CodeLabel* L, struct CodeEntry* E);
void CL_MoveRefs (CodeLabel* OldLabel, CodeLabel* NewLabel);
/* Move all references to OldLabel to point to NewLabel. OldLabel will have no
* more references on return.
*/
** more references on return.
*/
void CL_Output (const CodeLabel* L);
/* Output the code label to the output file */

View File

@@ -80,8 +80,8 @@
static unsigned OptLoad1 (CodeSeg* S)
/* Search for a call to ldaxysp where X is not used later and replace it by
* a load of just the A register.
*/
** a load of just the A register.
*/
{
unsigned I;
unsigned Changes = 0;
@@ -161,8 +161,8 @@ static unsigned OptLoad2 (CodeSeg* S)
!RegXUsed (S, I+3)) {
/* A/X are stored into memory somewhere and X is not used
* later
*/
** later
*/
/* lda (sp),y */
X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI);
@@ -251,8 +251,8 @@ static unsigned OptLoad3 (CodeSeg* S)
CodeEntry* N;
/* If we had a preceeding load that is identical, remove this one.
* If it is not identical, or we didn't have one, remember it.
*/
** If it is not identical, or we didn't have one, remember it.
*/
if (Load != 0 &&
E->OPC == Load->OPC &&
E->AM == Load->AM &&
@@ -299,21 +299,21 @@ static unsigned OptLoad3 (CodeSeg* S)
static unsigned OptDecouple (CodeSeg* S)
/* Decouple operations, that is, do the following replacements:
*
* dex -> ldx #imm
* inx -> ldx #imm
* dey -> ldy #imm
* iny -> ldy #imm
* tax -> ldx #imm
* txa -> lda #imm
* tay -> ldy #imm
* tya -> lda #imm
* lda zp -> lda #imm
* ldx zp -> ldx #imm
* ldy zp -> ldy #imm
*
* Provided that the register values are known of course.
*/
**
** dex -> ldx #imm
** inx -> ldx #imm
** dey -> ldy #imm
** iny -> ldy #imm
** tax -> ldx #imm
** txa -> lda #imm
** tay -> ldy #imm
** tya -> lda #imm
** lda zp -> lda #imm
** ldx zp -> ldx #imm
** ldy zp -> ldy #imm
**
** Provided that the register values are known of course.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -529,9 +529,9 @@ static unsigned OptDecouple (CodeSeg* S)
static unsigned IsDecSP (const CodeEntry* E)
/* Check if this is an insn that decrements the stack pointer. If so, return
* the decrement. If not, return zero.
* The function expects E to be a subroutine call.
*/
** the decrement. If not, return zero.
** The function expects E to be a subroutine call.
*/
{
if (strncmp (E->Arg, "decsp", 5) == 0) {
if (E->Arg[5] >= '1' && E->Arg[5] <= '8') {
@@ -549,8 +549,8 @@ static unsigned IsDecSP (const CodeEntry* E)
static unsigned OptStackPtrOps (CodeSeg* S)
/* Merge adjacent calls to decsp into one. NOTE: This function won't merge all
* known cases!
*/
** known cases!
*/
{
unsigned Changes = 0;
unsigned I;
@@ -851,8 +851,8 @@ static int CmpOptStep (const void* Key, const void* Func)
static OptFunc* FindOptFunc (const char* Name)
/* Find an optimizer step by name in the table and return a pointer. Return
* NULL if no such step is found.
*/
** NULL if no such step is found.
*/
{
/* Search for the function in the list */
OptFunc** O = bsearch (Name, OptFuncs, OPTFUNC_COUNT, sizeof (OptFuncs[0]), CmpOptStep);
@@ -863,8 +863,8 @@ static OptFunc* FindOptFunc (const char* Name)
static OptFunc* GetOptFunc (const char* Name)
/* Find an optimizer step by name in the table and return a pointer. Print an
* error and call AbEnd if not found.
*/
** error and call AbEnd if not found.
*/
{
/* Search for the function in the list */
OptFunc* F = FindOptFunc (Name);
@@ -1074,8 +1074,8 @@ static unsigned RunOptFunc (CodeSeg* S, OptFunc* F, unsigned Max)
unsigned Changes, C;
/* Don't run the function if it is disabled or if it is prohibited by the
* code size factor
*/
** code size factor
*/
if (F->Disabled || F->CodeSizeFactor > S->CodeSizeFactor) {
return 0;
}
@@ -1113,10 +1113,10 @@ static unsigned RunOptFunc (CodeSeg* S, OptFunc* F, unsigned Max)
static unsigned RunOptGroup1 (CodeSeg* S)
/* Run the first group of optimization steps. These steps translate known
* patterns emitted by the code generator into more optimal patterns. Order
* of the steps is important, because some of the steps done earlier cover
* the same patterns as later steps as subpatterns.
*/
** patterns emitted by the code generator into more optimal patterns. Order
** of the steps is important, because some of the steps done earlier cover
** the same patterns as later steps as subpatterns.
*/
{
unsigned Changes = 0;
@@ -1168,10 +1168,10 @@ static unsigned RunOptGroup1 (CodeSeg* S)
static unsigned RunOptGroup2 (CodeSeg* S)
/* Run one group of optimization steps. This step involves just decoupling
* instructions by replacing them by instructions that do not depend on
* previous instructions. This makes it easier to find instructions that
* aren't used.
*/
** instructions by replacing them by instructions that do not depend on
** previous instructions. This makes it easier to find instructions that
** aren't used.
*/
{
unsigned Changes = 0;
@@ -1185,9 +1185,9 @@ static unsigned RunOptGroup2 (CodeSeg* S)
static unsigned RunOptGroup3 (CodeSeg* S)
/* Run one group of optimization steps. These steps depend on each other,
* that means that one step may allow another step to do additional work,
* so we will repeat the steps as long as we see any changes.
*/
** that means that one step may allow another step to do additional work,
** so we will repeat the steps as long as we see any changes.
*/
{
unsigned Changes, C;
@@ -1254,8 +1254,8 @@ static unsigned RunOptGroup3 (CodeSeg* S)
static unsigned RunOptGroup4 (CodeSeg* S)
/* Run another round of pattern replacements. These are done late, since there
* may be better replacements before.
*/
** may be better replacements before.
*/
{
unsigned Changes = 0;
@@ -1287,9 +1287,9 @@ static unsigned RunOptGroup5 (CodeSeg* S)
Changes += RunOptFunc (S, &DOpt65C02Stores, 1);
if (Changes) {
/* The 65C02 replacement codes do often make the use of a register
* value unnecessary, so if we have changes, run another load
* removal pass.
*/
** value unnecessary, so if we have changes, run another load
** removal pass.
*/
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
}
}
@@ -1302,18 +1302,18 @@ static unsigned RunOptGroup5 (CodeSeg* S)
static unsigned RunOptGroup6 (CodeSeg* S)
/* This one is quite special. It tries to replace "lda (sp),y" by "lda (sp,x)".
* The latter is ony cycle slower, but if we're able to remove the necessary
* load of the Y register, because X is zero anyway, we gain 1 cycle and
* shorten the code by one (transfer) or two bytes (load). So what we do is
* to replace the insns, remove unused loads, and then change back all insns
* where Y is still zero (meaning that the load has not been removed).
*/
** The latter is ony cycle slower, but if we're able to remove the necessary
** load of the Y register, because X is zero anyway, we gain 1 cycle and
** shorten the code by one (transfer) or two bytes (load). So what we do is
** to replace the insns, remove unused loads, and then change back all insns
** where Y is still zero (meaning that the load has not been removed).
*/
{
unsigned Changes = 0;
/* This group will only run for a standard 6502, because the 65C02 has a
* better addressing mode that covers this case.
*/
** better addressing mode that covers this case.
*/
if ((CPUIsets[CPU] & CPU_ISET_65SC02) == 0) {
Changes += RunOptFunc (S, &DOptIndLoads1, 1);
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
@@ -1328,21 +1328,21 @@ static unsigned RunOptGroup6 (CodeSeg* S)
static unsigned RunOptGroup7 (CodeSeg* S)
/* The last group of optimization steps. Adjust branches, do size optimizations.
*/
*/
{
unsigned Changes = 0;
unsigned C;
/* Optimize for size, that is replace operations by shorter ones, even
* if this does hinder further optimizations (no problem since we're
* done soon).
*/
** if this does hinder further optimizations (no problem since we're
** done soon).
*/
C = RunOptFunc (S, &DOptSize1, 1);
if (C) {
Changes += C;
/* Run some optimization passes again, since the size optimizations
* may have opened new oportunities.
*/
** may have opened new oportunities.
*/
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
Changes += RunOptFunc (S, &DOptUnusedStores, 1);
Changes += RunOptFunc (S, &DOptJumpTarget1, 5);
@@ -1353,8 +1353,8 @@ static unsigned RunOptGroup7 (CodeSeg* S)
if (C) {
Changes += C;
/* Run some optimization passes again, since the size optimizations
* may have opened new oportunities.
*/
** may have opened new oportunities.
*/
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
Changes += RunOptFunc (S, &DOptJumpTarget1, 5);
Changes += RunOptFunc (S, &DOptStore5, 1);
@@ -1366,8 +1366,8 @@ static unsigned RunOptGroup7 (CodeSeg* S)
Changes += RunOptFunc (S, &DOptBranchDist, 3);
/* Replace conditional branches to RTS. If we had changes, we must run dead
* code elimination again, since the change may have introduced dead code.
*/
** code elimination again, since the change may have introduced dead code.
*/
C = RunOptFunc (S, &DOptRTSJumps2, 1);
Changes += C;
if (C) {

View File

@@ -87,8 +87,8 @@ static void CS_PrintFunctionHeader (const CodeSeg* S)
static void CS_MoveLabelsToEntry (CodeSeg* S, CodeEntry* E)
/* Move all labels from the label pool to the given entry and remove them
* from the pool.
*/
** from the pool.
*/
{
/* Transfer the labels if we have any */
unsigned I;
@@ -203,8 +203,8 @@ static const char* SkipSpace (const char* S)
static const char* ReadToken (const char* L, const char* Term,
char* Buf, unsigned BufSize)
/* Read the next token into Buf, return the updated line pointer. The
* token is terminated by one of the characters given in term.
*/
** token is terminated by one of the characters given in term.
*/
{
/* Read/copy the token */
unsigned I = 0;
@@ -214,8 +214,8 @@ static const char* ReadToken (const char* L, const char* Term,
Buf[I] = *L;
} else if (I == BufSize-1) {
/* Cannot store this character, this is an input error (maybe
* identifier too long or similar).
*/
** identifier too long or similar).
*/
Error ("ASM code error: syntax error");
}
++I;
@@ -238,11 +238,11 @@ static const char* ReadToken (const char* L, const char* Term,
static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
/* Parse an instruction nnd generate a code entry from it. If the line contains
* errors, output an error message and return NULL.
* For simplicity, we don't accept the broad range of input a "real" assembler
* does. The instruction and the argument are expected to be separated by
* white space, for example.
*/
** errors, output an error message and return NULL.
** For simplicity, we don't accept the broad range of input a "real" assembler
** does. The instruction and the argument are expected to be separated by
** white space, for example.
*/
{
char Mnemo[IDENTSIZE+10];
const OPCDesc* OPC;
@@ -265,8 +265,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
CS_AddLabel (S, Mnemo);
/* If we have reached end of line, bail out, otherwise a mnemonic
* may follow.
*/
** may follow.
*/
if (*L == '\0') {
return 0;
}
@@ -415,10 +415,10 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
}
/* If the instruction is a branch, check for the label and generate it
* if it does not exist. This may lead to unused labels (if the label
* is actually an external one) which are removed by the CS_MergeLabels
* function later.
*/
** if it does not exist. This may lead to unused labels (if the label
** is actually an external one) which are removed by the CS_MergeLabels
** function later.
*/
Label = 0;
if (AM == AM65_BRA) {
@@ -434,8 +434,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
}
/* We do now have the addressing mode in AM. Allocate a new CodeEntry
* structure and initialize it.
*/
** structure and initialize it.
*/
E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI);
/* Return the new code entry */
@@ -469,8 +469,8 @@ CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func)
}
/* If we have a function given, get the return type of the function.
* Assume ANY return type besides void will use the A and X registers.
*/
** Assume ANY return type besides void will use the A and X registers.
*/
if (S->Func && !IsTypeVoid ((RetType = GetFuncReturn (Func->Type)))) {
if (SizeOf (RetType) == SizeOf (type_long)) {
S->ExitRegs = REG_EAX;
@@ -564,8 +564,8 @@ void CS_AddLine (CodeSeg* S, LineInfo* LI, const char* Format, ...)
void CS_InsertEntry (CodeSeg* S, struct CodeEntry* E, unsigned Index)
/* Insert the code entry at the index given. Following code entries will be
* moved to slots with higher indices.
*/
** moved to slots with higher indices.
*/
{
/* Insert the entry into the collection */
CollInsert (&S->Entries, E, Index);
@@ -575,27 +575,27 @@ void CS_InsertEntry (CodeSeg* S, struct CodeEntry* E, unsigned Index)
void CS_DelEntry (CodeSeg* S, unsigned Index)
/* Delete an entry from the code segment. This includes moving any associated
* labels, removing references to labels and even removing the referenced labels
* if the reference count drops to zero.
* Note: Labels are moved forward if possible, that is, they are moved to the
* next insn (not the preceeding one).
*/
** labels, removing references to labels and even removing the referenced labels
** if the reference count drops to zero.
** Note: Labels are moved forward if possible, that is, they are moved to the
** next insn (not the preceeding one).
*/
{
/* Get the code entry for the given index */
CodeEntry* E = CS_GetEntry (S, Index);
/* If the entry has a labels, we have to move this label to the next insn.
* If there is no next insn, move the label into the code segement label
* pool. The operation is further complicated by the fact that the next
* insn may already have a label. In that case change all reference to
* this label and delete the label instead of moving it.
*/
** If there is no next insn, move the label into the code segement label
** pool. The operation is further complicated by the fact that the next
** insn may already have a label. In that case change all reference to
** this label and delete the label instead of moving it.
*/
unsigned Count = CE_GetLabelCount (E);
if (Count > 0) {
/* The instruction has labels attached. Check if there is a next
* instruction.
*/
** instruction.
*/
if (Index == CS_GetEntryCount (S)-1) {
/* No next instruction, move to the codeseg label pool */
@@ -613,8 +613,8 @@ void CS_DelEntry (CodeSeg* S, unsigned Index)
}
/* If this insn references a label, remove the reference. And, if the
* the reference count for this label drops to zero, remove this label.
*/
** the reference count for this label drops to zero, remove this label.
*/
if (E->JumpTo) {
/* Remove the reference */
CS_RemoveLabelRef (S, E);
@@ -631,12 +631,12 @@ void CS_DelEntry (CodeSeg* S, unsigned Index)
void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count)
/* Delete a range of code entries. This includes removing references to labels,
* labels attached to the entries and so on.
*/
** labels attached to the entries and so on.
*/
{
/* Start deleting the entries from the rear, because this involves less
* memory moving.
*/
** memory moving.
*/
while (Count--) {
CS_DelEntry (S, Start + Count);
}
@@ -646,14 +646,14 @@ void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count)
void CS_MoveEntries (CodeSeg* S, unsigned Start, unsigned Count, unsigned NewPos)
/* Move a range of entries from one position to another. Start is the index
* of the first entry to move, Count is the number of entries and NewPos is
* the index of the target entry. The entry with the index Start will later
* have the index NewPos. All entries with indices NewPos and above are
* moved to higher indices. If the code block is moved to the end of the
* current code, and if pending labels exist, these labels will get attached
* to the first instruction of the moved block (the first one after the
* current code end)
*/
** of the first entry to move, Count is the number of entries and NewPos is
** the index of the target entry. The entry with the index Start will later
** have the index NewPos. All entries with indices NewPos and above are
** moved to higher indices. If the code block is moved to the end of the
** current code, and if pending labels exist, these labels will get attached
** to the first instruction of the moved block (the first one after the
** current code end)
*/
{
/* Transparently handle an empty range */
if (Count == 0) {
@@ -661,8 +661,8 @@ void CS_MoveEntries (CodeSeg* S, unsigned Start, unsigned Count, unsigned NewPos
}
/* If NewPos is at the end of the code segment, move any labels from the
* label pool to the first instruction of the moved range.
*/
** label pool to the first instruction of the moved range.
*/
if (NewPos == CS_GetEntryCount (S)) {
CS_MoveLabelsToEntry (S, CS_GetEntry (S, Start));
}
@@ -675,8 +675,8 @@ void CS_MoveEntries (CodeSeg* S, unsigned Start, unsigned Count, unsigned NewPos
struct CodeEntry* CS_GetPrevEntry (CodeSeg* S, unsigned Index)
/* Get the code entry preceeding the one with the index Index. If there is no
* preceeding code entry, return NULL.
*/
** preceeding code entry, return NULL.
*/
{
if (Index == 0) {
/* This is the first entry */
@@ -691,8 +691,8 @@ struct CodeEntry* CS_GetPrevEntry (CodeSeg* S, unsigned Index)
struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index)
/* Get the code entry following the one with the index Index. If there is no
* following code entry, return NULL.
*/
** following code entry, return NULL.
*/
{
if (Index >= CollCount (&S->Entries)-1) {
/* This is the last entry */
@@ -708,8 +708,8 @@ struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index)
int CS_GetEntries (CodeSeg* S, struct CodeEntry** List,
unsigned Start, unsigned Count)
/* Get Count code entries into List starting at index start. Return true if
* we got the lines, return false if not enough lines were available.
*/
** we got the lines, return false if not enough lines were available.
*/
{
/* Check if enough entries are available */
if (Start + Count > CollCount (&S->Entries)) {
@@ -739,9 +739,9 @@ unsigned CS_GetEntryIndex (CodeSeg* S, struct CodeEntry* E)
int CS_RangeHasLabel (CodeSeg* S, unsigned Start, unsigned Count)
/* Return true if any of the code entries in the given range has a label
* attached. If the code segment does not span the given range, check the
* possible span instead.
*/
** attached. If the code segment does not span the given range, check the
** possible span instead.
*/
{
unsigned EntryCount = CS_GetEntryCount(S);
@@ -752,8 +752,8 @@ int CS_RangeHasLabel (CodeSeg* S, unsigned Start, unsigned Count)
}
/* Check each entry. Since we have validated the index above, we may
* use the unchecked access function in the loop which is faster.
*/
** use the unchecked access function in the loop which is faster.
*/
while (Count--) {
const CodeEntry* E = CollAtUnchecked (&S->Entries, Start++);
if (CE_HasLabel (E)) {
@@ -805,8 +805,8 @@ CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name)
CodeLabel* CS_GenLabel (CodeSeg* S, struct CodeEntry* E)
/* If the code entry E does already have a label, return it. Otherwise
* create a new label, attach it to E and return it.
*/
** create a new label, attach it to E and return it.
*/
{
CodeLabel* L;
@@ -856,10 +856,10 @@ void CS_DelLabel (CodeSeg* S, CodeLabel* L)
CollDeleteAll (&L->JumpFrom);
/* Remove the reference to the owning instruction if it has one. The
* function may be called for a label without an owner when deleting
* unfinished parts of the code. This is unfortunate since it allows
* errors to slip through.
*/
** function may be called for a label without an owner when deleting
** unfinished parts of the code. This is unfortunate since it allows
** errors to slip through.
*/
if (L->Owner) {
CollDeleteItem (&L->Owner->Labels, L);
}
@@ -872,16 +872,16 @@ void CS_DelLabel (CodeSeg* S, CodeLabel* L)
void CS_MergeLabels (CodeSeg* S)
/* Merge code labels. That means: For each instruction, remove all labels but
* one and adjust references accordingly.
*/
** one and adjust references accordingly.
*/
{
unsigned I;
unsigned J;
/* First, remove all labels from the label symbol table that don't have an
* owner (this means that they are actually external labels but we didn't
* know that previously since they may have also been forward references).
*/
** owner (this means that they are actually external labels but we didn't
** know that previously since they may have also been forward references).
*/
for (I = 0; I < CS_LABEL_HASH_SIZE; ++I) {
/* Get the first label in this hash chain */
@@ -898,9 +898,9 @@ void CS_MergeLabels (CodeSeg* S)
/* Get the entry referencing this label */
CodeEntry* E = CL_GetRef (X, J);
/* And remove the reference. Do NOT call CE_ClearJumpTo
* here, because this will also clear the label name,
* which is not what we want.
*/
** here, because this will also clear the label name,
** which is not what we want.
*/
E->JumpTo = 0;
}
@@ -937,10 +937,10 @@ void CS_MergeLabels (CodeSeg* S)
RefLab = CE_GetLabel (E, 0);
/* Walk through the remaining labels and change references to these
* labels to a reference to the one and only label. Delete the labels
* that are no longer used. To increase performance, walk backwards
* through the list.
*/
** labels to a reference to the one and only label. Delete the labels
** that are no longer used. To increase performance, walk backwards
** through the list.
*/
for (J = LabelCount-1; J >= 1; --J) {
/* Get the next label */
@@ -954,9 +954,9 @@ void CS_MergeLabels (CodeSeg* S)
}
/* The reference label is the only remaining label. Check if there
* are any references to this label, and delete it if this is not
* the case.
*/
** are any references to this label, and delete it if this is not
** the case.
*/
if (CollCount (&RefLab->JumpFrom) == 0) {
/* Delete the label */
CS_DelLabel (S, RefLab);
@@ -968,10 +968,10 @@ void CS_MergeLabels (CodeSeg* S)
void CS_MoveLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New)
/* Move all labels from Old to New. The routine will move the labels itself
* if New does not have any labels, and move references if there is at least
* a label for new. If references are moved, the old label is deleted
* afterwards.
*/
** if New does not have any labels, and move references if there is at least
** a label for new. If references are moved, the old label is deleted
** afterwards.
*/
{
/* Get the number of labels to move */
unsigned OldLabelCount = CE_GetLabelCount (Old);
@@ -1011,10 +1011,10 @@ void CS_MoveLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New)
void CS_RemoveLabelRef (CodeSeg* S, struct CodeEntry* E)
/* Remove the reference between E and the label it jumps to. The reference
* will be removed on both sides and E->JumpTo will be 0 after that. If
* the reference was the only one for the label, the label will get
* deleted.
*/
** will be removed on both sides and E->JumpTo will be 0 after that. If
** the reference was the only one for the label, the label will get
** deleted.
*/
{
/* Get a pointer to the label and make sure it exists */
CodeLabel* L = E->JumpTo;
@@ -1036,9 +1036,9 @@ void CS_RemoveLabelRef (CodeSeg* S, struct CodeEntry* E)
void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L)
/* Change the reference of E to L instead of the current one. If this
* was the only reference to the old label, the old label will get
* deleted.
*/
** was the only reference to the old label, the old label will get
** deleted.
*/
{
/* Get the old label */
CodeLabel* OldLabel = E->JumpTo;
@@ -1057,10 +1057,10 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L)
void CS_DelCodeRange (CodeSeg* S, unsigned First, unsigned Last)
/* Delete all entries between first and last, both inclusive. The function
* can only handle basic blocks (First is the only entry, Last the only exit)
* and no open labels. It will call FAIL if any of these preconditions are
* violated.
*/
** can only handle basic blocks (First is the only entry, Last the only exit)
** and no open labels. It will call FAIL if any of these preconditions are
** violated.
*/
{
unsigned I;
CodeEntry* FirstEntry;
@@ -1069,17 +1069,17 @@ void CS_DelCodeRange (CodeSeg* S, unsigned First, unsigned Last)
CHECK (First <= Last && Last < CS_GetEntryCount (S));
/* If Last is actually the last insn, call CS_DelCodeAfter instead, which
* is more flexible in this case.
*/
** is more flexible in this case.
*/
if (Last == CS_GetEntryCount (S) - 1) {
CS_DelCodeAfter (S, First);
return;
}
/* Get the first entry and check if it has any labels. If it has, move
* them to the insn following Last. If Last is the last insn of the code
* segment, make them ownerless and move them to the label pool.
*/
** them to the insn following Last. If Last is the last insn of the code
** segment, make them ownerless and move them to the label pool.
*/
FirstEntry = CS_GetEntry (S, First);
if (CE_HasLabel (FirstEntry)) {
/* Get the entry following last */
@@ -1094,8 +1094,8 @@ void CS_DelCodeRange (CodeSeg* S, unsigned First, unsigned Last)
}
/* First pass: Delete all references to labels. If the reference count
* for a label drops to zero, delete it.
*/
** for a label drops to zero, delete it.
*/
for (I = Last; I >= First; --I) {
/* Get the next entry */
@@ -1114,9 +1114,9 @@ void CS_DelCodeRange (CodeSeg* S, unsigned First, unsigned Last)
}
/* Second pass: Delete the instructions. If a label attached to an
* instruction still has references, it must be references from outside
* the deleted area, which is an error.
*/
** instruction still has references, it must be references from outside
** the deleted area, which is an error.
*/
for (I = Last; I >= First; --I) {
/* Get the next entry */
@@ -1142,8 +1142,8 @@ void CS_DelCodeAfter (CodeSeg* S, unsigned Last)
unsigned Count = CS_GetEntryCount (S);
/* First pass: Delete all references to labels. If the reference count
* for a label drops to zero, delete it.
*/
** for a label drops to zero, delete it.
*/
unsigned C = Count;
while (Last < C--) {
@@ -1153,8 +1153,8 @@ void CS_DelCodeAfter (CodeSeg* S, unsigned Last)
/* Check if this entry has a label reference */
if (E->JumpTo) {
/* If the label is a label in the label pool and this is the last
* reference to the label, remove the label from the pool.
*/
** reference to the label, remove the label from the pool.
*/
CodeLabel* L = E->JumpTo;
int Index = CollIndex (&S->Labels, L);
if (Index >= 0 && CollCount (&L->JumpFrom) == 1) {
@@ -1169,10 +1169,10 @@ void CS_DelCodeAfter (CodeSeg* S, unsigned Last)
}
/* Second pass: Delete the instructions. If a label attached to an
* instruction still has references, it must be references from outside
* the deleted area. Don't delete the label in this case, just make it
* ownerless and move it to the label pool.
*/
** instruction still has references, it must be references from outside
** the deleted area. Don't delete the label in this case, just make it
** ownerless and move it to the label pool.
*/
C = Count;
while (Last < C--) {
@@ -1207,10 +1207,10 @@ void CS_ResetMarks (CodeSeg* S, unsigned First, unsigned Last)
int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last)
/* Check if the given code segment range is a basic block. That is, check if
* First is the only entrance and Last is the only exit. This means that no
* jump/branch inside the block may jump to an insn below First or after(!)
* Last, and that no insn may jump into this block from the outside.
*/
** First is the only entrance and Last is the only exit. This means that no
** jump/branch inside the block may jump to an insn below First or after(!)
** Last, and that no insn may jump into this block from the outside.
*/
{
unsigned I;
@@ -1221,8 +1221,8 @@ int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last)
CS_ResetMarks (S, First, Last);
/* Second pass: Walk over the range checking all labels. Note: There may be
* label on the first insn which is ok.
*/
** label on the first insn which is ok.
*/
I = First + 1;
while (I <= Last) {
@@ -1230,8 +1230,8 @@ int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last)
CodeEntry* E = CS_GetEntry (S, I);
/* Check if this entry has one or more labels, if so, check which
* entries jump to this label.
*/
** entries jump to this label.
*/
unsigned LabelCount = CE_GetLabelCount (E);
unsigned LabelIndex;
for (LabelIndex = 0; LabelIndex < LabelCount; ++LabelIndex) {
@@ -1240,8 +1240,8 @@ int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last)
CodeLabel* L = CE_GetLabel (E, LabelIndex);
/* Walk over all entries that jump to this label. Check for each
* of the entries if it is out of the range.
*/
** of the entries if it is out of the range.
*/
unsigned RefCount = CL_GetRefCount (L);
unsigned RefIndex;
for (RefIndex = 0; RefIndex < RefCount; ++RefIndex) {
@@ -1250,10 +1250,10 @@ int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last)
CodeEntry* Ref = CL_GetRef (L, RefIndex);
/* Walk over out complete range and check if we find the
* refering entry. This is cheaper than using CS_GetEntryIndex,
* because CS_GetEntryIndex will search the complete code
* segment and not just our range.
*/
** refering entry. This is cheaper than using CS_GetEntryIndex,
** because CS_GetEntryIndex will search the complete code
** segment and not just our range.
*/
unsigned J;
for (J = First; J <= Last; ++J) {
if (Ref == CS_GetEntry (S, J)) {
@@ -1262,17 +1262,17 @@ int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last)
}
if (J > Last) {
/* We did not find the entry. This means that the jump to
* out code segment entry E came from outside the range,
* which in turn means that the given range is not a basic
* block.
*/
** out code segment entry E came from outside the range,
** which in turn means that the given range is not a basic
** block.
*/
CS_ResetMarks (S, First, Last);
return 0;
}
/* If we come here, we found the entry. Mark it, so we know
* that the branch to the label is in range.
*/
** that the branch to the label is in range.
*/
CE_SetMark (Ref);
}
}
@@ -1282,9 +1282,9 @@ int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last)
}
/* Third pass: Walk again over the range and check all branches. If we
* find a branch that is not marked, its target is not inside the range
* (since we checked all the labels in the range before).
*/
** find a branch that is not marked, its target is not inside the range
** (since we checked all the labels in the range before).
*/
I = First;
while (I <= Last) {
@@ -1295,8 +1295,8 @@ int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last)
if (E->Info & (OF_UBRA | OF_CBRA)) {
if (!CE_HasMark (E)) {
/* No mark means not a basic block. Before bailing out, be sure
* to remove the marks from the remaining entries.
*/
** to remove the marks from the remaining entries.
*/
CS_ResetMarks (S, I+1, Last);
return 0;
}
@@ -1317,18 +1317,18 @@ int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last)
void CS_OutputPrologue (const CodeSeg* S)
/* If the given code segment is a code segment for a function, output the
* assembler prologue into the file. That is: Output a comment header, switch
* to the correct segment and enter the local function scope. If the code
* segment is global, do nothing.
*/
** assembler prologue into the file. That is: Output a comment header, switch
** to the correct segment and enter the local function scope. If the code
** segment is global, do nothing.
*/
{
/* Get the function associated with the code segment */
SymEntry* Func = S->Func;
/* If the code segment is associated with a function, print a function
* header and enter a local scope. Be sure to switch to the correct
* segment before outputing the function label.
*/
** header and enter a local scope. Be sure to switch to the correct
** segment before outputing the function label.
*/
if (Func) {
/* Get the function descriptor */
CS_PrintFunctionHeader (S);
@@ -1347,8 +1347,8 @@ void CS_OutputPrologue (const CodeSeg* S)
void CS_OutputEpilogue (const CodeSeg* S)
/* If the given code segment is a code segment for a function, output the
* assembler epilogue into the file. That is: Close the local function scope.
*/
** assembler epilogue into the file. That is: Close the local function scope.
*/
{
if (S->Func) {
WriteOutput ("\n.endproc\n\n");
@@ -1383,16 +1383,16 @@ void CS_Output (CodeSeg* S)
/* Get the next entry */
const CodeEntry* E = CollConstAt (&S->Entries, I);
/* Check if the line info has changed. If so, output the source line
* if the option is enabled and output debug line info if the debug
* option is enabled.
*/
** if the option is enabled and output debug line info if the debug
** option is enabled.
*/
if (E->LI != LI) {
/* Line info has changed, remember the new line info */
LI = E->LI;
/* Add the source line as a comment. Beware: When line continuation
* was used, the line may contain newlines.
*/
** was used, the line may contain newlines.
*/
if (AddSource) {
const char* L = LI->Line;
WriteOutput (";\n; ");
@@ -1466,8 +1466,8 @@ void CS_GenRegInfo (CodeSeg* S)
CurrentRegs = &Regs;
/* Walk over all insns and note just the changes from one insn to the
* next one.
*/
** next one.
*/
WasJump = 0;
for (I = 0; I < CS_GetEntryCount (S); ++I) {
@@ -1481,13 +1481,13 @@ void CS_GenRegInfo (CodeSeg* S)
if (LabelCount > 0) {
/* Loop over all entry points that jump here. If these entry
* points already have register info, check if all values are
* known and identical. If all values are identical, and the
* preceeding instruction was not an unconditional branch, check
* if the register value on exit of the preceeding instruction
* is also identical. If all these values are identical, the
* value of a register is known, otherwise it is unknown.
*/
** points already have register info, check if all values are
** known and identical. If all values are identical, and the
** preceeding instruction was not an unconditional branch, check
** if the register value on exit of the preceeding instruction
** is also identical. If all these values are identical, the
** value of a register is known, otherwise it is unknown.
*/
CodeLabel* Label = CE_GetLabel (E, 0);
unsigned Entry;
if (WasJump) {
@@ -1509,11 +1509,11 @@ void CS_GenRegInfo (CodeSeg* S)
CodeEntry* J = CL_GetRef (Label, Entry);
if (J->RI == 0) {
/* No register info for this entry. This means that the
* instruction that jumps here is at higher addresses and
* the jump is a backward jump. We need a second run to
* get the register info right in this case. Until then,
* assume unknown register contents.
*/
** instruction that jumps here is at higher addresses and
** the jump is a backward jump. We need a second run to
** get the register info right in this case. Until then,
** assume unknown register contents.
*/
Done = 0;
RC_Invalidate (&Regs);
break;
@@ -1554,9 +1554,9 @@ void CS_GenRegInfo (CodeSeg* S)
CurrentRegs = &E->RI->Out;
/* If this insn is a branch on zero flag, we may have more info on
* register contents for one of both flow directions, but only if
* there is a previous instruction.
*/
** register contents for one of both flow directions, but only if
** there is a previous instruction.
*/
if ((E->Info & OF_ZBRA) != 0 && (P = CS_GetPrevEntry (S, I)) != 0) {
/* Get the branch condition */
@@ -1584,8 +1584,8 @@ void CS_GenRegInfo (CodeSeg* S)
case OP65_CMP:
/* If this is an immidiate compare, the A register has
* the value of the compare later.
*/
** the value of the compare later.
*/
if (CE_IsConstImm (P)) {
if (BC == BC_EQ) {
E->RI->Out2.RegA = (unsigned char)P->Num;
@@ -1597,8 +1597,8 @@ void CS_GenRegInfo (CodeSeg* S)
case OP65_CPX:
/* If this is an immidiate compare, the X register has
* the value of the compare later.
*/
** the value of the compare later.
*/
if (CE_IsConstImm (P)) {
if (BC == BC_EQ) {
E->RI->Out2.RegX = (unsigned char)P->Num;
@@ -1610,8 +1610,8 @@ void CS_GenRegInfo (CodeSeg* S)
case OP65_CPY:
/* If this is an immidiate compare, the Y register has
* the value of the compare later.
*/
** the value of the compare later.
*/
if (CE_IsConstImm (P)) {
if (BC == BC_EQ) {
E->RI->Out2.RegY = (unsigned char)P->Num;
@@ -1648,9 +1648,9 @@ void CS_GenRegInfo (CodeSeg* S)
case OP65_TAX:
case OP65_TXA:
/* If the branch is a beq, both A and X are zero at the
* branch target, otherwise they are zero at the next
* insn.
*/
** branch target, otherwise they are zero at the next
** insn.
*/
if (BC == BC_EQ) {
E->RI->Out2.RegA = E->RI->Out2.RegX = 0;
} else {
@@ -1661,9 +1661,9 @@ void CS_GenRegInfo (CodeSeg* S)
case OP65_TAY:
case OP65_TYA:
/* If the branch is a beq, both A and Y are zero at the
* branch target, otherwise they are zero at the next
* insn.
*/
** branch target, otherwise they are zero at the next
** insn.
*/
if (BC == BC_EQ) {
E->RI->Out2.RegA = E->RI->Out2.RegY = 0;
} else {

View File

@@ -118,38 +118,38 @@ INLINE unsigned CS_GetEntryCount (const CodeSeg* S)
void CS_InsertEntry (CodeSeg* S, struct CodeEntry* E, unsigned Index);
/* Insert the code entry at the index given. Following code entries will be
* moved to slots with higher indices.
*/
** moved to slots with higher indices.
*/
void CS_DelEntry (CodeSeg* S, unsigned Index);
/* Delete an entry from the code segment. This includes moving any associated
* labels, removing references to labels and even removing the referenced labels
* if the reference count drops to zero.
* Note: Labels are moved forward if possible, that is, they are moved to the
* next insn (not the preceeding one).
*/
** labels, removing references to labels and even removing the referenced labels
** if the reference count drops to zero.
** Note: Labels are moved forward if possible, that is, they are moved to the
** next insn (not the preceeding one).
*/
void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count);
/* Delete a range of code entries. This includes removing references to labels,
* labels attached to the entries and so on.
*/
** labels attached to the entries and so on.
*/
void CS_MoveEntries (CodeSeg* S, unsigned Start, unsigned Count, unsigned NewPos);
/* Move a range of entries from one position to another. Start is the index
* of the first entry to move, Count is the number of entries and NewPos is
* the index of the target entry. The entry with the index Start will later
* have the index NewPos. All entries with indices NewPos and above are
* moved to higher indices. If the code block is moved to the end of the
* current code, and if pending labels exist, these labels will get attached
* to the first instruction of the moved block (the first one after the
* current code end)
*/
** of the first entry to move, Count is the number of entries and NewPos is
** the index of the target entry. The entry with the index Start will later
** have the index NewPos. All entries with indices NewPos and above are
** moved to higher indices. If the code block is moved to the end of the
** current code, and if pending labels exist, these labels will get attached
** to the first instruction of the moved block (the first one after the
** current code end)
*/
#if defined(HAVE_INLINE)
INLINE void CS_MoveEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos)
/* Move an entry from one position to another. OldPos is the current position
* of the entry, NewPos is the new position of the entry.
*/
** of the entry, NewPos is the new position of the entry.
*/
{
CollMove (&S->Entries, OldPos, NewPos);
}
@@ -169,34 +169,34 @@ INLINE struct CodeEntry* CS_GetEntry (CodeSeg* S, unsigned Index)
struct CodeEntry* CS_GetPrevEntry (CodeSeg* S, unsigned Index);
/* Get the code entry preceeding the one with the index Index. If there is no
* preceeding code entry, return NULL.
*/
** preceeding code entry, return NULL.
*/
struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index);
/* Get the code entry following the one with the index Index. If there is no
* following code entry, return NULL.
*/
** following code entry, return NULL.
*/
int CS_GetEntries (CodeSeg* S, struct CodeEntry** List,
unsigned Start, unsigned Count);
/* Get Count code entries into List starting at index start. Return true if
* we got the lines, return false if not enough lines were available.
*/
** we got the lines, return false if not enough lines were available.
*/
unsigned CS_GetEntryIndex (CodeSeg* S, struct CodeEntry* E);
/* Return the index of a code entry */
int CS_RangeHasLabel (CodeSeg* S, unsigned Start, unsigned Count);
/* Return true if any of the code entries in the given range has a label
* attached. If the code segment does not span the given range, check the
* possible span instead.
*/
** attached. If the code segment does not span the given range, check the
** possible span instead.
*/
#if defined(HAVE_INLINE)
INLINE int CS_HavePendingLabel (const CodeSeg* S)
/* Return true if there are open labels that will get attached to the next
* instruction that is added.
*/
** instruction that is added.
*/
{
return (CollCount (&S->Labels) > 0);
}
@@ -209,43 +209,43 @@ CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name);
CodeLabel* CS_GenLabel (CodeSeg* S, struct CodeEntry* E);
/* If the code entry E does already have a label, return it. Otherwise
* create a new label, attach it to E and return it.
*/
** create a new label, attach it to E and return it.
*/
void CS_DelLabel (CodeSeg* S, CodeLabel* L);
/* Remove references from this label and delete it. */
void CS_MergeLabels (CodeSeg* S);
/* Merge code labels. That means: For each instruction, remove all labels but
* one and adjust references accordingly.
*/
** one and adjust references accordingly.
*/
void CS_MoveLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New);
/* Move all labels from Old to New. The routine will move the labels itself
* if New does not have any labels, and move references if there is at least
* a label for new. If references are moved, the old label is deleted
* afterwards.
*/
** if New does not have any labels, and move references if there is at least
** a label for new. If references are moved, the old label is deleted
** afterwards.
*/
void CS_RemoveLabelRef (CodeSeg* S, struct CodeEntry* E);
/* Remove the reference between E and the label it jumps to. The reference
* will be removed on both sides and E->JumpTo will be 0 after that. If
* the reference was the only one for the label, the label will get
* deleted.
*/
** will be removed on both sides and E->JumpTo will be 0 after that. If
** the reference was the only one for the label, the label will get
** deleted.
*/
void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L);
/* Change the reference of E to L instead of the current one. If this
* was the only reference to the old label, the old label will get
* deleted.
*/
** was the only reference to the old label, the old label will get
** deleted.
*/
void CS_DelCodeRange (CodeSeg* S, unsigned First, unsigned Last);
/* Delete all entries between first and last, both inclusive. The function
* can only handle basic blocks (First is the only entry, Last the only exit)
* and no open labels. It will call FAIL if any of these preconditions are
* violated.
*/
** can only handle basic blocks (First is the only entry, Last the only exit)
** and no open labels. It will call FAIL if any of these preconditions are
** violated.
*/
void CS_DelCodeAfter (CodeSeg* S, unsigned Last);
/* Delete all entries including the given one */
@@ -268,22 +268,22 @@ INLINE void CS_ResetAllMarks (CodeSeg* S)
int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last);
/* Check if the given code segment range is a basic block. That is, check if
* First is the only entrance and Last is the only exit. This means that no
* jump/branch inside the block may jump to an insn below First or after(!)
* Last, and that no insn may jump into this block from the outside.
*/
** First is the only entrance and Last is the only exit. This means that no
** jump/branch inside the block may jump to an insn below First or after(!)
** Last, and that no insn may jump into this block from the outside.
*/
void CS_OutputPrologue (const CodeSeg* S);
/* If the given code segment is a code segment for a function, output the
* assembler prologue into the file. That is: Output a comment header, switch
* to the correct segment and enter the local function scope. If the code
* segment is global, do nothing.
*/
** assembler prologue into the file. That is: Output a comment header, switch
** to the correct segment and enter the local function scope. If the code
** segment is global, do nothing.
*/
void CS_OutputEpilogue (const CodeSeg* S);
/* If the given code segment is a code segment for a function, output the
* assembler epilogue into the file. That is: Close the local function scope.
*/
** assembler epilogue into the file. That is: Close the local function scope.
*/
void CS_Output (CodeSeg* S);
/* Output the code segment data to a file */

View File

@@ -141,14 +141,14 @@ static void Parse (void)
}
/* Check if we must reserve storage for the variable. We do this,
*
* - if it is not a typedef or function,
* - if we don't had a storage class given ("int i")
* - if the storage class is explicitly specified as static,
* - or if there is an initialization.
*
* This means that "extern int i;" will not get storage allocated.
*/
**
** - if it is not a typedef or function,
** - if we don't had a storage class given ("int i")
** - if the storage class is explicitly specified as static,
** - or if there is an initialization.
**
** This means that "extern int i;" will not get storage allocated.
*/
if ((Decl.StorageClass & SC_FUNC) != SC_FUNC &&
(Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF &&
((Spec.Flags & DS_DEF_STORAGE) != 0 ||
@@ -161,10 +161,10 @@ static void Parse (void)
}
/* If this is a function declarator that is not followed by a comma
* or semicolon, it must be followed by a function body. If this is
* the case, convert an empty parameter list into one accepting no
* parameters (same as void) as required by the standard.
*/
** or semicolon, it must be followed by a function body. If this is
** the case, convert an empty parameter list into one accepting no
** parameters (same as void) as required by the standard.
*/
if ((Decl.StorageClass & SC_FUNC) != 0 &&
(CurTok.Tok != TOK_COMMA) &&
(CurTok.Tok != TOK_SEMI)) {
@@ -191,8 +191,8 @@ static void Parse (void)
if (CurTok.Tok == TOK_ASSIGN) {
/* We cannot initialize types of unknown size, or
* void types in non ANSI mode.
*/
** void types in ISO modes.
*/
if (Size == 0) {
if (!IsTypeVoid (Decl.Type)) {
if (!IsTypeArray (Decl.Type)) {
@@ -206,9 +206,9 @@ static void Parse (void)
}
/* Switch to the data or rodata segment. For arrays, check
* the element qualifiers, since not the array but its
* elements are const.
*/
** the element qualifiers, since not the array but its
** elements are const.
*/
if (IsQualConst (GetBaseElementType (Decl.Type))) {
g_userodata ();
} else {
@@ -303,8 +303,8 @@ void Compile (const char* FileName)
struct tm* TM;
/* Since strftime is locale dependent, we need the abbreviated month names
* in english.
*/
** in english.
*/
static const char MonthNames[12][4] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
@@ -320,9 +320,9 @@ void Compile (const char* FileName)
DefineNumericMacro ("__CC65_STD__", IS_Get (&Standard));
/* Optimization macros. Since no source code has been parsed for now, the
* IS_Get functions access the values in effect now, regardless of any
* changes using #pragma later.
*/
** IS_Get functions access the values in effect now, regardless of any
** changes using #pragma later.
*/
if (IS_Get (&Optimize)) {
long CodeSize = IS_Get (&CodeSizeFactor);
DefineNumericMacro ("__OPT__", 1);

View File

@@ -51,29 +51,29 @@
unsigned OptAdd1 (CodeSeg* S)
/* Search for the sequence
*
* ldy #xx
* jsr ldaxysp
* jsr pushax
* ldy #yy
* jsr ldaxysp
* jsr tosaddax
*
* and replace it by:
*
* ldy #xx-1
* lda (sp),y
* ldy #yy-3
* clc
* adc (sp),y
* pha
* ldy #xx
* lda (sp),y
* ldy #yy-2
* adc (sp),y
* tax
* pla
*/
**
** ldy #xx
** jsr ldaxysp
** jsr pushax
** ldy #yy
** jsr ldaxysp
** jsr tosaddax
**
** and replace it by:
**
** ldy #xx-1
** lda (sp),y
** ldy #yy-3
** clc
** adc (sp),y
** pha
** ldy #xx
** lda (sp),y
** ldy #yy-2
** adc (sp),y
** tax
** pla
*/
{
unsigned Changes = 0;
@@ -172,28 +172,28 @@ unsigned OptAdd1 (CodeSeg* S)
unsigned OptAdd2 (CodeSeg* S)
/* Search for the sequence
*
* ldy #xx
* jsr ldaxysp
* ldy #yy
* jsr addeqysp
*
* and replace it by:
*
* ldy #xx-1
* lda (sp),y
* ldy #yy
* clc
* adc (sp),y
* sta (sp),y
* ldy #xx
* lda (sp),y
* ldy #yy+1
* adc (sp),y
* sta (sp),y
*
* provided that a/x is not used later.
*/
**
** ldy #xx
** jsr ldaxysp
** ldy #yy
** jsr addeqysp
**
** and replace it by:
**
** ldy #xx-1
** lda (sp),y
** ldy #yy
** clc
** adc (sp),y
** sta (sp),y
** ldy #xx
** lda (sp),y
** ldy #yy+1
** adc (sp),y
** sta (sp),y
**
** provided that a/x is not used later.
*/
{
unsigned Changes = 0;
@@ -288,20 +288,20 @@ unsigned OptAdd2 (CodeSeg* S)
unsigned OptAdd3 (CodeSeg* S)
/* Search for the sequence
*
* jsr pushax
* ldx #$00
* lda xxx
* jsr tosaddax
*
* and replace it by
*
* clc
* adc xxx
* bcc L1
* inx
* L1:
*/
**
** jsr pushax
** ldx #$00
** lda xxx
** jsr tosaddax
**
** and replace it by
**
** clc
** adc xxx
** bcc L1
** inx
** L1:
*/
{
unsigned Changes = 0;
@@ -364,22 +364,22 @@ unsigned OptAdd3 (CodeSeg* S)
unsigned OptAdd4 (CodeSeg* S)
/* Search for the sequence
*
* jsr pushax
* lda xxx
* ldx yyy
* jsr tosaddax
*
* and replace it by
*
* clc
* adc xxx
* pha
* txa
* adc yyy
* tax
* pla
*/
**
** jsr pushax
** lda xxx
** ldx yyy
** jsr tosaddax
**
** and replace it by
**
** clc
** adc xxx
** pha
** txa
** adc yyy
** tax
** pla
*/
{
unsigned Changes = 0;
@@ -453,8 +453,8 @@ unsigned OptAdd4 (CodeSeg* S)
unsigned OptAdd5 (CodeSeg* S)
/* Search for a call to incaxn and replace it by an 8 bit add if the X register
* is not used later.
*/
** is not used later.
*/
{
unsigned Changes = 0;
@@ -506,14 +506,14 @@ unsigned OptAdd5 (CodeSeg* S)
unsigned OptAdd6 (CodeSeg* S)
/* Search for the sequence
*
* adc ...
* bcc L
* inx
* L:
*
* and remove the handling of the high byte if X is not used later.
*/
**
** adc ...
** bcc L
** inx
** L:
**
** and remove the handling of the high byte if X is not used later.
*/
{
unsigned Changes = 0;

View File

@@ -7,7 +7,7 @@
/* */
/* */
/* (C) 2001-2005, Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@@ -51,102 +51,102 @@
unsigned OptAdd1 (CodeSeg* S);
/* Search for the sequence
*
* jsr pushax
* ldy xxx
* ldx #$00
* lda (sp),y
* jsr tosaddax
*
* and replace it by:
*
* ldy xxx-2
* clc
* adc (sp),y
* bcc L
* inx
* L:
*/
**
** jsr pushax
** ldy xxx
** ldx #$00
** lda (sp),y
** jsr tosaddax
**
** and replace it by:
**
** ldy xxx-2
** clc
** adc (sp),y
** bcc L
** inx
** L:
*/
unsigned OptAdd2 (CodeSeg* S);
/* Search for the sequence
*
* ldy #xx
* lda (sp),y
* tax
* dey
* lda (sp),y
* ldy #$yy
* jsr addeqysp
*
* and replace it by:
*
* ldy #xx-1
* lda (sp),y
* ldy #yy
* clc
* adc (sp),y
* sta (sp),y
* ldy #xx
* lda (sp),y
* ldy #yy+1
* adc (sp),y
* sta (sp),y
*
* provided that a/x is not used later.
*/
**
** ldy #xx
** lda (sp),y
** tax
** dey
** lda (sp),y
** ldy #$yy
** jsr addeqysp
**
** and replace it by:
**
** ldy #xx-1
** lda (sp),y
** ldy #yy
** clc
** adc (sp),y
** sta (sp),y
** ldy #xx
** lda (sp),y
** ldy #yy+1
** adc (sp),y
** sta (sp),y
**
** provided that a/x is not used later.
*/
unsigned OptAdd3 (CodeSeg* S);
/* Search for the sequence
*
* jsr pushax
* ldx #$00
* lda xxx
* jsr tosaddax
*
* and replace it by
*
* clc
* adc xxx
* bcc L1
* inx
* L1:
*/
**
** jsr pushax
** ldx #$00
** lda xxx
** jsr tosaddax
**
** and replace it by
**
** clc
** adc xxx
** bcc L1
** inx
** L1:
*/
unsigned OptAdd4 (CodeSeg* S);
/* Search for the sequence
*
* jsr pushax
* lda xxx
* ldx yyy
* jsr tosaddax
*
* and replace it by
*
* clc
* adc xxx
* pha
* txa
* adc yyy
* tax
* pla
*/
**
** jsr pushax
** lda xxx
** ldx yyy
** jsr tosaddax
**
** and replace it by
**
** clc
** adc xxx
** pha
** txa
** adc yyy
** tax
** pla
*/
unsigned OptAdd5 (CodeSeg* S);
/* Search for a call to incaxn and replace it by an 8 bit add if the X register
* is not used later.
*/
** is not used later.
*/
unsigned OptAdd6 (CodeSeg* S);
/* Search for the sequence
*
* adc ...
* bcc L
* inx
* L:
*
* and remove the handling of the high byte if X is not used later.
*/
**
** adc ...
** bcc L
** inx
** L:
**
** and remove the handling of the high byte if X is not used later.
*/

View File

@@ -75,9 +75,9 @@ unsigned Opt65C02Ind (CodeSeg* S)
CodeEntry* E = CS_GetEntry (S, I);
/* Check for addressing mode indirect indexed Y where Y is zero.
* Note: All opcodes that are available as (zp),y are also available
* as (zp), so we can ignore the actual opcode here.
*/
** Note: All opcodes that are available as (zp),y are also available
** as (zp), so we can ignore the actual opcode here.
*/
if (E->AM == AM65_ZP_INDY && E->RI->In.RegY == 0) {
/* Replace it by indirect addressing mode */
@@ -187,8 +187,8 @@ unsigned Opt65C02Stores (CodeSeg* S)
CodeEntry* E = CS_GetEntry (S, I);
/* Check for a store with a register value of zero and an addressing
* mode available with STZ.
*/
** mode available with STZ.
*/
if (((E->OPC == OP65_STA && E->RI->In.RegA == 0) ||
(E->OPC == OP65_STX && E->RI->In.RegX == 0) ||
(E->OPC == OP65_STY && E->RI->In.RegY == 0)) &&

View File

@@ -66,11 +66,11 @@ static const unsigned char CmpInvertTab [] = {
static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
/* Helper function for the replacement of routines that return a boolean
* followed by a conditional jump. Instead of the boolean value, the condition
* codes are evaluated directly.
* I is the index of the conditional branch, the sequence is already checked
* to be correct.
*/
** followed by a conditional jump. Instead of the boolean value, the condition
** codes are evaluated directly.
** I is the index of the conditional branch, the sequence is already checked
** to be correct.
*/
{
CodeEntry* N;
CodeLabel* L;
@@ -91,10 +91,10 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
case CMP_GT:
/* Replace by
* beq @L
* jpl Target
* @L: ...
*/
** beq @L
** jpl Target
** @L: ...
*/
if ((N = CS_GetNextEntry (S, I)) == 0) {
/* No such entry */
Internal ("Invalid program flow");
@@ -115,9 +115,9 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
case CMP_LE:
/* Replace by
* jmi Target
* jeq Target
*/
** jmi Target
** jeq Target
*/
CE_ReplaceOPC (E, OP65_JMI);
L = E->JumpTo;
N = NewCodeEntry (OP65_JEQ, AM65_BRA, L->Name, L, E->LI);
@@ -126,10 +126,10 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
case CMP_UGT:
/* Replace by
* beq @L
* jcs Target
* @L: ...
*/
** beq @L
** jcs Target
** @L: ...
*/
if ((N = CS_GetNextEntry (S, I)) == 0) {
/* No such entry */
Internal ("Invalid program flow");
@@ -150,9 +150,9 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
case CMP_ULE:
/* Replace by
* jcc Target
* jeq Target
*/
** jcc Target
** jeq Target
*/
CE_ReplaceOPC (E, OP65_JCC);
L = E->JumpTo;
N = NewCodeEntry (OP65_JEQ, AM65_BRA, L->Name, L, E->LI);
@@ -169,10 +169,10 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
static int IsImmCmp16 (CodeEntry** L)
/* Check if the instructions at L are an immidiate compare of a/x:
*
*
*/
/* Check if the instructions at L are an immediate compare of a/x:
**
**
*/
{
return (L[0]->OPC == OP65_CPX &&
L[0]->AM == AM65_IMM &&
@@ -213,8 +213,8 @@ static int GetCmpRegVal (const CodeEntry* E)
unsigned OptBoolTrans (CodeSeg* S)
/* Try to remove the call to boolean transformer routines where the call is
* not really needed.
*/
** not really needed.
*/
{
unsigned Changes = 0;
@@ -235,11 +235,11 @@ unsigned OptBoolTrans (CodeSeg* S)
(N->Info & OF_ZBRA) != 0) {
/* Make the boolean transformer unnecessary by changing the
* the conditional jump to evaluate the condition flags that
* are set after the compare directly. Note: jeq jumps if
* the condition is not met, jne jumps if the condition is met.
* Invert the code if we jump on condition not met.
*/
** the conditional jump to evaluate the condition flags that
** are set after the compare directly. Note: jeq jumps if
** the condition is not met, jne jumps if the condition is met.
** Invert the code if we jump on condition not met.
*/
if (GetBranchCond (N->OPC) == BC_EQ) {
/* Jumps if condition false, invert condition */
Cond = CmpInvertTab [Cond];
@@ -275,15 +275,15 @@ unsigned OptBoolTrans (CodeSeg* S)
unsigned OptCmp1 (CodeSeg* S)
/* Search for the sequence
*
* ldx xx
* stx tmp1
* ora tmp1
*
* and replace it by
*
* ora xx
*/
**
** ldx xx
** stx tmp1
** ora tmp1
**
** and replace it by
**
** ora xx
*/
{
unsigned Changes = 0;
@@ -332,16 +332,16 @@ unsigned OptCmp1 (CodeSeg* S)
unsigned OptCmp2 (CodeSeg* S)
/* Search for the sequence
*
* stx xx
* stx tmp1
* ora tmp1
*
* and replace it by
*
* stx xx
* ora xx
*/
**
** stx xx
** stx tmp1
** ora tmp1
**
** and replace it by
**
** stx xx
** ora xx
*/
{
unsigned Changes = 0;
@@ -387,17 +387,17 @@ unsigned OptCmp2 (CodeSeg* S)
unsigned OptCmp3 (CodeSeg* S)
/* Search for
*
* lda/and/ora/eor ...
* cmp #$00
* jeq/jne
* or
* lda/and/ora/eor ...
* cmp #$00
* jsr boolxx
*
* and remove the cmp.
*/
**
** lda/and/ora/eor ...
** cmp #$00
** jeq/jne
** or
** lda/and/ora/eor ...
** cmp #$00
** jsr boolxx
**
** and remove the cmp.
*/
{
unsigned Changes = 0;
@@ -432,9 +432,9 @@ unsigned OptCmp3 (CodeSeg* S)
int Delete = 0;
/* Check for the call to boolxx. We only remove the compare if
* the carry flag is not evaluated later, because the load will
* not set the carry flag.
*/
** the carry flag is not evaluated later, because the load will
** not set the carry flag.
*/
if (L[2]->OPC == OP65_JSR) {
switch (FindBoolCmpCond (L[2]->Arg)) {
@@ -459,10 +459,10 @@ unsigned OptCmp3 (CodeSeg* S)
} else if ((L[2]->Info & OF_FBRA) != 0) {
/* The following insn branches on the condition of the load,
* so the compare instruction might be removed. For safety,
* do some more checks if the carry isn't used later, since
* the compare does set the carry, but the load does not.
*/
** so the compare instruction might be removed. For safety,
** do some more checks if the carry isn't used later, since
** the compare does set the carry, but the load does not.
*/
CodeEntry* E;
CodeEntry* N;
if ((E = CS_GetNextEntry (S, I+2)) != 0 &&
@@ -476,9 +476,9 @@ unsigned OptCmp3 (CodeSeg* S)
FindBoolCmpCond (N->Arg) == CMP_INV)) {
/* The following insn branches on the condition of a load,
* and there's no use of the carry flag in sight, so the
* compare instruction can be removed.
*/
** and there's no use of the carry flag in sight, so the
** compare instruction can be removed.
*/
Delete = 1;
}
}
@@ -503,24 +503,24 @@ unsigned OptCmp3 (CodeSeg* S)
unsigned OptCmp4 (CodeSeg* S)
/* Search for
*
* lda x
* ldx y
* cpx #a
* bne L1
* cmp #b
* L1: jne/jeq L2
*
* If a is zero, we may remove the compare. If a and b are both zero, we may
* replace it by the sequence
*
* lda x
* ora x+1
* jne/jeq ...
*
* L1 may be either the label at the branch instruction, or the target label
* of this instruction.
*/
**
** lda x
** ldx y
** cpx #a
** bne L1
** cmp #b
** L1: jne/jeq L2
**
** If a is zero, we may remove the compare. If a and b are both zero, we may
** replace it by the sequence
**
** lda x
** ora x+1
** jne/jeq ...
**
** L1 may be either the label at the branch instruction, or the target label
** of this instruction.
*/
{
unsigned Changes = 0;
@@ -547,9 +547,9 @@ unsigned OptCmp4 (CodeSeg* S)
CS_DelEntries (S, I+2, 3);
} else {
/* Move the lda instruction after the first branch. This will
* improve speed, since the load is delayed after the first
* test.
*/
** improve speed, since the load is delayed after the first
** test.
*/
CS_MoveEntry (S, I, I+4);
/* We will replace the ldx/cpx by lda/cmp */
@@ -557,8 +557,8 @@ unsigned OptCmp4 (CodeSeg* S)
CE_ReplaceOPC (L[1], OP65_CMP);
/* Beware: If the first LDA instruction had a label, we have
* to move this label to the top of the sequence again.
*/
** to move this label to the top of the sequence again.
*/
if (CE_HasLabel (E)) {
CS_MoveLabels (S, E, L[0]);
}
@@ -581,14 +581,14 @@ unsigned OptCmp4 (CodeSeg* S)
unsigned OptCmp5 (CodeSeg* S)
/* Optimize compares of local variables:
*
* ldy #o
* jsr ldaxysp
* cpx #a
* bne L1
* cmp #b
* jne/jeq L2
*/
**
** ldy #o
** jsr ldaxysp
** cpx #a
** bne L1
** cmp #b
** jne/jeq L2
*/
{
unsigned Changes = 0;
@@ -615,12 +615,12 @@ unsigned OptCmp5 (CodeSeg* S)
char Buf[20];
/* The value is zero, we may use the simple code version:
* ldy #o-1
* lda (sp),y
* ldy #o
* ora (sp),y
* jne/jeq ...
*/
** ldy #o-1
** lda (sp),y
** ldy #o
** ora (sp),y
** jne/jeq ...
*/
sprintf (Buf, "$%02X", (int)(L[0]->Num-1));
X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI);
CS_InsertEntry (S, X, I+1);
@@ -643,17 +643,17 @@ unsigned OptCmp5 (CodeSeg* S)
char Buf[20];
/* Change the code to just use the A register. Move the load
* of the low byte after the first branch if possible:
*
* ldy #o
* lda (sp),y
* cmp #a
* bne L1
* ldy #o-1
* lda (sp),y
* cmp #b
* jne/jeq ...
*/
** of the low byte after the first branch if possible:
**
** ldy #o
** lda (sp),y
** cmp #a
** bne L1
** ldy #o-1
** lda (sp),y
** cmp #b
** jne/jeq ...
*/
X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI);
CS_InsertEntry (S, X, I+3);
@@ -690,10 +690,10 @@ unsigned OptCmp5 (CodeSeg* S)
unsigned OptCmp6 (CodeSeg* S)
/* Search for calls to compare subroutines followed by a conditional branch
* and replace them by cheaper versions, since the branch means that the
* boolean value returned by these routines is not needed (we may also check
* that explicitly, but for the current code generator it is always true).
*/
** and replace them by cheaper versions, since the branch means that the
** boolean value returned by these routines is not needed (we may also check
** that explicitly, but for the current code generator it is always true).
*/
{
unsigned Changes = 0;
@@ -715,12 +715,12 @@ unsigned OptCmp6 (CodeSeg* S)
!CE_HasLabel (N)) {
/* The tos... functions will return a boolean value in a/x and
* the Z flag says if this value is zero or not. We will call
* a cheaper subroutine instead, one that does not return a
* boolean value but only valid flags. Note: jeq jumps if
* the condition is not met, jne jumps if the condition is met.
* Invert the code if we jump on condition not met.
*/
** the Z flag says if this value is zero or not. We will call
** a cheaper subroutine instead, one that does not return a
** boolean value but only valid flags. Note: jeq jumps if
** the condition is not met, jne jumps if the condition is met.
** Invert the code if we jump on condition not met.
*/
if (GetBranchCond (N->OPC) == BC_EQ) {
/* Jumps if condition false, invert condition */
Cond = CmpInvertTab [Cond];
@@ -752,8 +752,8 @@ unsigned OptCmp6 (CodeSeg* S)
unsigned OptCmp7 (CodeSeg* S)
/* Search for a sequence ldx/txa/branch and remove the txa if A is not
* used later.
*/
** used later.
*/
{
unsigned Changes = 0;
@@ -796,8 +796,8 @@ unsigned OptCmp7 (CodeSeg* S)
unsigned OptCmp8 (CodeSeg* S)
/* Check for register compares where the contents of the register and therefore
* the result of the compare is known.
*/
** the result of the compare is known.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -817,8 +817,8 @@ unsigned OptCmp8 (CodeSeg* S)
CE_IsConstImm (E)) {
/* We are able to evaluate the compare at compile time. Check if
* one or more branches are ahead.
*/
** one or more branches are ahead.
*/
unsigned JumpsChanged = 0;
CodeEntry* N;
while ((N = CS_GetNextEntry (S, I)) != 0 && /* Followed by something.. */
@@ -855,10 +855,10 @@ unsigned OptCmp8 (CodeSeg* S)
case BC_VC:
case BC_VS:
/* Not set by the compare operation, bail out (Note:
* Just skipping anything here is rather stupid, but
* the sequence is never generated by the compiler,
* so it's quite safe to skip).
*/
** Just skipping anything here is rather stupid, but
** the sequence is never generated by the compiler,
** so it's quite safe to skip).
*/
goto NextEntry;
default:
@@ -867,9 +867,9 @@ unsigned OptCmp8 (CodeSeg* S)
}
/* If the condition is false, we may remove the jump. Otherwise
* the branch will always be taken, so we may replace it by a
* jump (and bail out).
*/
** the branch will always be taken, so we may replace it by a
** jump (and bail out).
*/
if (!Cond) {
CS_DelEntry (S, I+1);
} else {
@@ -906,16 +906,16 @@ NextEntry:
unsigned OptCmp9 (CodeSeg* S)
/* Search for the sequence
*
* sbc xx
* bvs/bvc L
* eor #$80
* L: asl a
* bcc/bcs somewhere
*
* If A is not used later (which should be the case), we can branch on the N
* flag instead of the carry flag and remove the asl.
*/
**
** sbc xx
** bvs/bvc L
** eor #$80
** L: asl a
** bcc/bcs somewhere
**
** If A is not used later (which should be the case), we can branch on the N
** flag instead of the carry flag and remove the asl.
*/
{
unsigned Changes = 0;
unsigned I;

View File

@@ -51,8 +51,8 @@
unsigned OptBoolTrans (CodeSeg* S);
/* Try to remove the call to boolean transformer routines where the call is
* not really needed.
*/
** not really needed.
*/
@@ -64,107 +64,107 @@ unsigned OptBoolTrans (CodeSeg* S);
unsigned OptCmp1 (CodeSeg* S);
/* Search for the sequence
*
* ldx xx
* stx tmp1
* ora tmp1
*
* and replace it by
*
* ora xx
*/
**
** ldx xx
** stx tmp1
** ora tmp1
**
** and replace it by
**
** ora xx
*/
unsigned OptCmp2 (CodeSeg* S);
/* Search for the sequence
*
* stx xx
* stx tmp1
* ora tmp1
*
* and replace it by
*
* stx xx
* ora xx
*/
**
** stx xx
** stx tmp1
** ora tmp1
**
** and replace it by
**
** stx xx
** ora xx
*/
unsigned OptCmp3 (CodeSeg* S);
/* Search for
*
* lda/and/ora/eor ...
* cmp #$00
* jeq/jne
* or
* lda/and/ora/eor ...
* cmp #$00
* jsr boolxx
*
* and remove the cmp.
*/
**
** lda/and/ora/eor ...
** cmp #$00
** jeq/jne
** or
** lda/and/ora/eor ...
** cmp #$00
** jsr boolxx
**
** and remove the cmp.
*/
unsigned OptCmp4 (CodeSeg* S);
/* Search for
*
* lda x
* ldx y
* cpx #a
* bne L1
* cmp #b
* jne/jeq L2
*
* If a is zero, we may remove the compare. If a and b are both zero, we may
* replace it by the sequence
*
* lda x
* ora x+1
* jne/jeq ...
*
* L1 may be either the label at the branch instruction, or the target label
* of this instruction.
*/
**
** lda x
** ldx y
** cpx #a
** bne L1
** cmp #b
** jne/jeq L2
**
** If a is zero, we may remove the compare. If a and b are both zero, we may
** replace it by the sequence
**
** lda x
** ora x+1
** jne/jeq ...
**
** L1 may be either the label at the branch instruction, or the target label
** of this instruction.
*/
unsigned OptCmp5 (CodeSeg* S);
/* Optimize compares of local variables:
*
* ldy #o
* lda (sp),y
* tax
* dey
* lda (sp),y
* cpx #a
* bne L1
* cmp #b
* jne/jeq L2
*/
**
** ldy #o
** lda (sp),y
** tax
** dey
** lda (sp),y
** cpx #a
** bne L1
** cmp #b
** jne/jeq L2
*/
unsigned OptCmp6 (CodeSeg* S);
/* Search for calls to compare subroutines followed by a conditional branch
* and replace them by cheaper versions, since the branch means that the
* boolean value returned by these routines is not needed (we may also check
* that explicitly, but for the current code generator it is always true).
*/
** and replace them by cheaper versions, since the branch means that the
** boolean value returned by these routines is not needed (we may also check
** that explicitly, but for the current code generator it is always true).
*/
unsigned OptCmp7 (CodeSeg* S);
/* Search for a sequence ldx/txa/branch and remove the txa if A is not
* used later.
*/
** used later.
*/
unsigned OptCmp8 (CodeSeg* S);
/* Check for register compares where the contents of the register and therefore
* the result of the compare is known.
*/
** the result of the compare is known.
*/
unsigned OptCmp9 (CodeSeg* S);
/* Search for the sequence
*
* sbc xx
* bvs/bvc L
* eor #$80
* L: asl a
* bcc/bcs somewhere
*
* If A is not used later (which should be the case), we can branch on the N
* flag instead of the carry flag and remove the asl.
*/
**
** sbc xx
** bvs/bvc L
** eor #$80
** L: asl a
** bcc/bcs somewhere
**
** If A is not used later (which should be the case), we can branch on the N
** flag instead of the carry flag and remove the asl.
*/

View File

@@ -66,15 +66,15 @@ static int MemAccess (CodeSeg* S, unsigned From, unsigned To, const CodeEntry* N
/* If the argument of N is a zero page location that ends with "+1", we
* must also check for word accesses to the location without +1.
*/
** must also check for word accesses to the location without +1.
*/
if (N->AM == AM65_ZP && NLen > 2 && strcmp (N->Arg + NLen - 2, "+1") == 0) {
What |= Base;
}
/* If the argument is zero page indirect, we must also check for accesses
* to "arg+1"
*/
** to "arg+1"
*/
if (N->AM == AM65_ZP_INDY || N->AM == AM65_ZPX_IND || N->AM == AM65_ZP_IND) {
What |= Word;
}
@@ -86,8 +86,8 @@ static int MemAccess (CodeSeg* S, unsigned From, unsigned To, const CodeEntry* N
CodeEntry* E = CS_GetEntry (S, From);
/* Check if there is an argument and if this argument equals Arg in
* some variants.
*/
** some variants.
*/
if (E->Arg[0] != '\0') {
unsigned ELen;
@@ -126,8 +126,8 @@ static int MemAccess (CodeSeg* S, unsigned From, unsigned To, const CodeEntry* N
static int GetBranchDist (CodeSeg* S, unsigned From, CodeEntry* To)
/* Get the branch distance between the two entries and return it. The distance
* will be negative for backward jumps and positive for forward jumps.
*/
** will be negative for backward jumps and positive for forward jumps.
*/
{
/* Get the index of the branch target */
unsigned TI = CS_GetEntryIndex (S, To);
@@ -265,8 +265,8 @@ unsigned OptRTSJumps2 (CodeSeg* S)
/* Get the jump target and the next entry. There's always a next
* entry, because we don't cover the last entry in the loop.
*/
** entry, because we don't cover the last entry in the loop.
*/
CodeEntry* X = 0;
CodeEntry* T = E->JumpTo->Owner;
CodeEntry* N = CS_GetNextEntry (S, I);
@@ -275,15 +275,15 @@ unsigned OptRTSJumps2 (CodeSeg* S)
if (T->OPC == OP65_RTS) {
/* It's a jump to RTS. Create a conditional branch around an
* RTS insn.
*/
** RTS insn.
*/
X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, T->LI);
} else if (T->OPC == OP65_JMP && T->JumpTo == 0) {
/* It's a jump to a label outside the function. Create a
* conditional branch around a jump to the external label.
*/
** conditional branch around a jump to the external label.
*/
X = NewCodeEntry (OP65_JMP, AM65_ABS, T->Arg, T->JumpTo, T->LI);
}
@@ -298,8 +298,8 @@ unsigned OptRTSJumps2 (CodeSeg* S)
CS_InsertEntry (S, X, I+1);
/* Create a conditional branch with the inverse condition
* around the replacement insn
*/
** around the replacement insn
*/
/* Get the new branch opcode */
NewBranch = MakeShortBranch (GetInverseBranch (E->OPC));
@@ -350,8 +350,8 @@ unsigned OptDeadJumps (CodeSeg* S)
CodeEntry* E = CS_GetEntry (S, I);
/* Check if it's a branch, if it has a local target, and if the target
* is the next instruction.
*/
** is the next instruction.
*/
if (E->AM == AM65_BRA &&
E->JumpTo &&
E->JumpTo->Owner == CS_GetNextEntry (S, I)) {
@@ -384,8 +384,8 @@ unsigned OptDeadJumps (CodeSeg* S)
unsigned OptDeadCode (CodeSeg* S)
/* Remove dead code (code that follows an unconditional jump or an rts/rti
* and has no label)
*/
** and has no label)
*/
{
unsigned Changes = 0;
@@ -400,9 +400,9 @@ unsigned OptDeadCode (CodeSeg* S)
CodeEntry* E = CS_GetEntry (S, I);
/* Check if it's an unconditional branch, and if the next entry has
* no labels attached, or if the label is just used so that the insn
* can jump to itself.
*/
** no labels attached, or if the label is just used so that the insn
** can jump to itself.
*/
if ((E->Info & OF_DEAD) != 0 && /* Dead code follows */
(N = CS_GetNextEntry (S, I)) != 0 && /* Has next entry */
(!CE_HasLabel (N) || /* Don't has a label */
@@ -439,11 +439,11 @@ unsigned OptDeadCode (CodeSeg* S)
unsigned OptJumpCascades (CodeSeg* S)
/* Optimize jump cascades (jumps to jumps). In such a case, the jump is
* replaced by a jump to the final location. This will in some cases produce
* worse code, because some jump targets are no longer reachable by short
* branches, but this is quite rare, so there are more advantages than
* disadvantages.
*/
** replaced by a jump to the final location. This will in some cases produce
** worse code, because some jump targets are no longer reachable by short
** branches, but this is quite rare, so there are more advantages than
** disadvantages.
*/
{
unsigned Changes = 0;
@@ -458,17 +458,17 @@ unsigned OptJumpCascades (CodeSeg* S)
CodeEntry* E = CS_GetEntry (S, I);
/* Check:
* - if it's a branch,
* - if it has a jump label,
* - if this jump label is not attached to the instruction itself,
* - if the target instruction is itself a branch,
* - if either the first branch is unconditional or the target of
* the second branch is internal to the function.
* The latter condition will avoid conditional branches to targets
* outside of the function (usually incspx), which won't simplify the
* code, since conditional far branches are emulated by a short branch
* around a jump.
*/
** - if it's a branch,
** - if it has a jump label,
** - if this jump label is not attached to the instruction itself,
** - if the target instruction is itself a branch,
** - if either the first branch is unconditional or the target of
** the second branch is internal to the function.
** The latter condition will avoid conditional branches to targets
** outside of the function (usually incspx), which won't simplify the
** code, since conditional far branches are emulated by a short branch
** around a jump.
*/
if ((E->Info & OF_BRA) != 0 &&
(OldLabel = E->JumpTo) != 0 &&
(N = OldLabel->Owner) != E &&
@@ -476,27 +476,27 @@ unsigned OptJumpCascades (CodeSeg* S)
((E->Info & OF_CBRA) == 0 ||
N->JumpTo != 0)) {
/* Check if we can use the final target label. This is the case,
* if the target branch is an absolut branch, or if it is a
* conditional branch checking the same condition as the first one.
*/
/* Check if we can use the final target label. That is the case,
** if the target branch is an absolute branch; or, if it is a
** conditional branch checking the same condition as the first one.
*/
if ((N->Info & OF_UBRA) != 0 ||
((E->Info & OF_CBRA) != 0 &&
GetBranchCond (E->OPC) == GetBranchCond (N->OPC))) {
/* This is a jump cascade and we may jump to the final target,
* provided that the other insn does not jump to itself. If
* this is the case, we can also jump to ourselves, otherwise
* insert a jump to the new instruction and remove the old one.
*/
** provided that the other insn does not jump to itself. If
** this is the case, we can also jump to ourselves, otherwise
** insert a jump to the new instruction and remove the old one.
*/
CodeEntry* X;
CodeLabel* LN = N->JumpTo;
if (LN != 0 && LN->Owner == N) {
/* We found a jump to a jump to itself. Replace our jump
* by a jump to itself.
*/
** by a jump to itself.
*/
CodeLabel* LE = CS_GenLabel (S, E);
X = NewCodeEntry (E->OPC, E->AM, LE->Name, LE, E->LI);
@@ -517,10 +517,10 @@ unsigned OptJumpCascades (CodeSeg* S)
++Changes;
/* Check if both are conditional branches, and the condition of
* the second is the inverse of that of the first. In this case,
* the second branch will never be taken, and we may jump directly
* to the instruction behind this one.
*/
** the second is the inverse of that of the first. In this case,
** the second branch will never be taken, and we may jump directly
** to the instruction behind this one.
*/
} else if ((E->Info & OF_CBRA) != 0 && (N->Info & OF_CBRA) != 0) {
CodeEntry* X; /* Instruction behind N */
@@ -537,8 +537,8 @@ unsigned OptJumpCascades (CodeSeg* S)
}
/* We may jump behind this conditional branch. Get the
* pointer to the next instruction
*/
** pointer to the next instruction
*/
if ((X = CS_GetNextEntry (S, CS_GetEntryIndex (S, N))) == 0) {
/* N is the last entry, bail out */
goto NextEntry;
@@ -575,9 +575,9 @@ NextEntry:
unsigned OptRTS (CodeSeg* S)
/* Optimize subroutine calls followed by an RTS. The subroutine call will get
* replaced by a jump. Don't bother to delete the RTS if it does not have a
* label, the dead code elimination should take care of it.
*/
** replaced by a jump. Don't bother to delete the RTS if it does not have a
** label, the dead code elimination should take care of it.
*/
{
unsigned Changes = 0;
@@ -623,10 +623,10 @@ unsigned OptRTS (CodeSeg* S)
unsigned OptJumpTarget1 (CodeSeg* S)
/* If the instruction preceeding an unconditional branch is the same as the
* instruction preceeding the jump target, the jump target may be moved
* one entry back. This is a size optimization, since the instruction before
* the branch gets removed.
*/
** instruction preceeding the jump target, the jump target may be moved
** one entry back. This is a size optimization, since the instruction before
** the branch gets removed.
*/
{
unsigned Changes = 0;
CodeEntry* E1; /* Entry 1 */
@@ -642,8 +642,8 @@ unsigned OptJumpTarget1 (CodeSeg* S)
E2 = CS_GetNextEntry (S, I);
/* Check if we have a jump or branch without a label attached, and
* a jump target, which is not attached to the jump itself
*/
** a jump target, which is not attached to the jump itself
*/
if (E2 != 0 &&
(E2->Info & OF_UBRA) != 0 &&
!CE_HasLabel (E2) &&
@@ -658,8 +658,8 @@ unsigned OptJumpTarget1 (CodeSeg* S)
}
/* The entry preceeding the branch target may not be the branch
* insn.
*/
** insn.
*/
if (T1 == E2) {
goto NextEntry;
}
@@ -674,17 +674,17 @@ unsigned OptJumpTarget1 (CodeSeg* S)
}
/* Get the label for the instruction preceeding the jump target.
* This routine will create a new label if the instruction does
* not already have one.
*/
** This routine will create a new label if the instruction does
** not already have one.
*/
TL1 = CS_GenLabel (S, T1);
/* Change the jump target to point to this new label */
CS_MoveLabelRef (S, E2, TL1);
/* If the instruction preceeding the jump has labels attached,
* move references to this label to the new label.
*/
** move references to this label to the new label.
*/
if (CE_HasLabel (E1)) {
CS_MoveLabels (S, E1, T1);
}
@@ -710,8 +710,8 @@ NextEntry:
unsigned OptJumpTarget2 (CodeSeg* S)
/* If a bcs jumps to a sec insn or a bcc jumps to clc, skip this insn, since
* it's job is already done.
*/
** it's job is already done.
*/
{
unsigned Changes = 0;
@@ -748,8 +748,8 @@ unsigned OptJumpTarget2 (CodeSeg* S)
}
/* Get the owner insn of the jump target and check if it's the one, we
* will skip if present.
*/
** will skip if present.
*/
T = E->JumpTo->Owner;
if (T->OPC != OPC) {
goto NextEntry;
@@ -763,9 +763,9 @@ unsigned OptJumpTarget2 (CodeSeg* S)
}
/* Get the label for the instruction following the jump target.
* This routine will create a new label if the instruction does
* not already have one.
*/
** This routine will create a new label if the instruction does
** not already have one.
*/
L = CS_GenLabel (S, N);
/* Change the jump target to point to this new label */
@@ -787,9 +787,9 @@ NextEntry:
unsigned OptJumpTarget3 (CodeSeg* S)
/* Jumps to load instructions of a register, that do already have the matching
* register contents may skip the load instruction, since it's job is already
* done.
*/
** register contents may skip the load instruction, since it's job is already
** done.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -804,8 +804,8 @@ unsigned OptJumpTarget3 (CodeSeg* S)
CodeEntry* E = CS_GetEntry (S, I);
/* Check if this is a load insn with a label and the next insn is not
* a conditional branch that needs the flags from the load.
*/
** a conditional branch that needs the flags from the load.
*/
if ((E->Info & OF_LOAD) != 0 &&
CE_IsConstImm (E) &&
CE_HasLabel (E) &&
@@ -825,9 +825,9 @@ unsigned OptJumpTarget3 (CodeSeg* S)
CodeLabel* L = CE_GetLabel (E, J);
/* Loop over all insn that reference this label. Since we may
* eventually remove a reference in the loop, we must loop
* from end down to start.
*/
** eventually remove a reference in the loop, we must loop
** from end down to start.
*/
for (K = CL_GetRefCount (L) - 1; K >= 0; --K) {
/* Get the entry that jumps here */
@@ -839,9 +839,9 @@ unsigned OptJumpTarget3 (CodeSeg* S)
/* Check if the outgoing value is the one thats's loaded */
if (Val == (unsigned char) E->Num) {
/* Ok, skip the insn. First, generate a label for the
* next insn after E.
*/
/* OK, skip the insn. First, generate a label for the
** next insn after E.
*/
if (LN == 0) {
LN = CS_GenLabel (S, N);
}
@@ -875,16 +875,16 @@ unsigned OptJumpTarget3 (CodeSeg* S)
unsigned OptCondBranches1 (CodeSeg* S)
/* Performs several optimization steps:
*
* - If an immidiate load of a register is followed by a conditional jump that
* is never taken because the load of the register sets the flags in such a
* manner, remove the conditional branch.
* - If the conditional branch is always taken because of the register load,
* replace it by a jmp.
* - If a conditional branch jumps around an unconditional branch, remove the
* conditional branch and make the jump a conditional branch with the
* inverse condition of the first one.
*/
**
** - If an immediate load of a register is followed by a conditional jump that
** is never taken because the load of the register sets the flags in such a
** manner, remove the conditional branch.
** - If the conditional branch is always taken because of the register load,
** replace it by a jmp.
** - If a conditional branch jumps around an unconditional branch, remove the
** conditional branch and make the jump a conditional branch with the
** inverse condition of the first one.
*/
{
unsigned Changes = 0;
@@ -940,11 +940,11 @@ unsigned OptCondBranches1 (CodeSeg* S)
(N = CS_GetNextEntry (S, I)) != 0 && /* There is a following entry */
(N->Info & OF_UBRA) != 0 && /* ..which is an uncond branch, */
!CE_HasLabel (N) && /* ..has no label attached */
L->Owner == CS_GetNextEntry (S, I+1)) {/* ..and jump target follows */
L->Owner == CS_GetNextEntry (S, I+1)) { /* ..and jump target follows */
/* Replace the jump by a conditional branch with the inverse branch
* condition than the branch around it.
*/
** condition than the branch around it.
*/
CE_ReplaceOPC (N, GetInverseBranch (E->OPC));
/* Remove the conditional branch */
@@ -968,8 +968,8 @@ unsigned OptCondBranches1 (CodeSeg* S)
unsigned OptCondBranches2 (CodeSeg* S)
/* If on entry to a "rol a" instruction the accu is zero, and a beq/bne follows,
* we can remove the rol and branch on the state of the carry flag.
*/
** we can remove the rol and branch on the state of the carry flag.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -1103,8 +1103,8 @@ unsigned OptUnusedStores (CodeSeg* S)
(E->Chg & REG_ZP) != 0) {
/* Check for the zero page location. We know that there cannot be
* more than one zero page location involved in the store.
*/
** more than one zero page location involved in the store.
*/
unsigned R = E->Chg & REG_ZP;
/* Get register usage and check if the register value is used later */
@@ -1185,9 +1185,9 @@ unsigned OptDupLoads (CodeSeg* S)
case OP65_STA:
/* If we store into a known zero page location, and this
* location does already contain the value to be stored,
* remove the store.
*/
** location does already contain the value to be stored,
** remove the store.
*/
if (RegValIsKnown (In->RegA) && /* Value of A is known */
E->AM == AM65_ZP && /* Store into zp */
In->RegA == ZPRegVal (E->Chg, In)) { /* Value identical */
@@ -1198,9 +1198,9 @@ unsigned OptDupLoads (CodeSeg* S)
case OP65_STX:
/* If we store into a known zero page location, and this
* location does already contain the value to be stored,
* remove the store.
*/
** location does already contain the value to be stored,
** remove the store.
*/
if (RegValIsKnown (In->RegX) && /* Value of A is known */
E->AM == AM65_ZP && /* Store into zp */
In->RegX == ZPRegVal (E->Chg, In)) { /* Value identical */
@@ -1208,11 +1208,11 @@ unsigned OptDupLoads (CodeSeg* S)
Delete = 1;
/* If the value in the X register is known and the same as
* that in the A register, replace the store by a STA. The
* optimizer will then remove the load instruction for X
* later. STX does support the zeropage,y addressing mode,
* so be sure to check for that.
*/
** that in the A register, replace the store by a STA. The
** optimizer will then remove the load instruction for X
** later. STX does support the zeropage,y addressing mode,
** so be sure to check for that.
*/
} else if (RegValIsKnown (In->RegX) &&
In->RegX == In->RegA &&
E->AM != AM65_ABSY &&
@@ -1224,9 +1224,9 @@ unsigned OptDupLoads (CodeSeg* S)
case OP65_STY:
/* If we store into a known zero page location, and this
* location does already contain the value to be stored,
* remove the store.
*/
** location does already contain the value to be stored,
** remove the store.
*/
if (RegValIsKnown (In->RegY) && /* Value of Y is known */
E->AM == AM65_ZP && /* Store into zp */
In->RegY == ZPRegVal (E->Chg, In)) { /* Value identical */
@@ -1234,12 +1234,12 @@ unsigned OptDupLoads (CodeSeg* S)
Delete = 1;
/* If the value in the Y register is known and the same as
* that in the A register, replace the store by a STA. The
* optimizer will then remove the load instruction for Y
* later. If replacement by A is not possible try a
* replacement by X, but check for invalid addressing modes
* in this case.
*/
** that in the A register, replace the store by a STA. The
** optimizer will then remove the load instruction for Y
** later. If replacement by A is not possible try a
** replacement by X, but check for invalid addressing modes
** in this case.
*/
} else if (RegValIsKnown (In->RegY)) {
if (In->RegY == In->RegA) {
CE_ReplaceOPC (E, OP65_STA);
@@ -1253,9 +1253,9 @@ unsigned OptDupLoads (CodeSeg* S)
case OP65_STZ:
/* If we store into a known zero page location, and this
* location does already contain the value to be stored,
* remove the store.
*/
** location does already contain the value to be stored,
** remove the store.
*/
if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0 && E->AM == AM65_ZP) {
if (ZPRegVal (E->Chg, In) == 0) {
Delete = 1;
@@ -1348,8 +1348,8 @@ unsigned OptStoreLoad (CodeSeg* S)
CodeEntry* E = CS_GetEntry (S, I);
/* Check if it is a store instruction followed by a load from the
* same address which is itself not followed by a conditional branch.
*/
** same address which is itself not followed by a conditional branch.
*/
if ((E->Info & OF_STORE) != 0 &&
(N = CS_GetNextEntry (S, I)) != 0 &&
!CE_HasLabel (N) &&
@@ -1409,9 +1409,9 @@ unsigned OptTransfers1 (CodeSeg* S)
(E->OPC == OP65_TYA && N->OPC == OP65_TAY && !RegAUsed (S, I+2))) {
/* If the next insn is a conditional branch, check if the insn
* preceeding the first xfr will set the flags right, otherwise we
* may not remove the sequence.
*/
** preceeding the first xfr will set the flags right, otherwise we
** may not remove the sequence.
*/
if ((X = CS_GetNextEntry (S, I+1)) == 0) {
goto NextEntry;
}
@@ -1450,8 +1450,8 @@ NextEntry:
unsigned OptTransfers2 (CodeSeg* S)
/* Replace loads followed by a register transfer by a load with the second
* register if possible.
*/
** register if possible.
*/
{
unsigned Changes = 0;
@@ -1465,8 +1465,8 @@ unsigned OptTransfers2 (CodeSeg* S)
CodeEntry* E = CS_GetEntry (S, I);
/* Check if we have a load followed by a transfer where the loaded
* register is not used later.
*/
** register is not used later.
*/
if ((E->Info & OF_LOAD) != 0 &&
(N = CS_GetNextEntry (S, I)) != 0 &&
!CE_HasLabel (N) &&
@@ -1499,8 +1499,8 @@ unsigned OptTransfers2 (CodeSeg* S)
X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, N->LI);
} else if (E->OPC == OP65_LDX && N->OPC == OP65_TXA) {
/* LDX/TXA. LDA doesn't support zp,y, so we must map it to
* abs,y instead.
*/
** abs,y instead.
*/
am_t AM = (E->AM == AM65_ZPY)? AM65_ABSY : E->AM;
X = NewCodeEntry (OP65_LDA, AM, E->Arg, 0, N->LI);
}
@@ -1526,8 +1526,8 @@ unsigned OptTransfers2 (CodeSeg* S)
unsigned OptTransfers3 (CodeSeg* S)
/* Replace a register transfer followed by a store of the second register by a
* store of the first register if this is possible.
*/
** store of the first register if this is possible.
*/
{
unsigned Changes = 0;
unsigned UsedRegs = REG_NONE; /* Track used registers */
@@ -1544,8 +1544,8 @@ unsigned OptTransfers3 (CodeSeg* S)
} State = Initialize;
/* Walk over the entries. Look for a xfer instruction that is followed by
* a store later, where the value of the register is not used later.
*/
** a store later, where the value of the register is not used later.
*/
unsigned I = 0;
while (I < CS_GetEntryCount (S)) {
@@ -1570,8 +1570,8 @@ unsigned OptTransfers3 (CodeSeg* S)
case FoundXfer:
/* If we find a conditional jump, abort the sequence, since
* handling them makes things really complicated.
*/
** handling them makes things really complicated.
*/
if (E->Info & OF_CBRA) {
/* Switch back to searching */
@@ -1582,8 +1582,8 @@ unsigned OptTransfers3 (CodeSeg* S)
} else if ((E->Use & XferEntry->Chg) != 0) {
/* It it's a store instruction, and the block is a basic
* block, proceed. Otherwise restart
*/
** block, proceed. Otherwise restart
*/
if ((E->Info & OF_STORE) != 0 &&
CS_IsBasicBlock (S, Xfer, I)) {
Store = I;
@@ -1598,9 +1598,9 @@ unsigned OptTransfers3 (CodeSeg* S)
} else if (E->Chg & XferEntry->Chg) {
/* We *may* add code here to remove the transfer, but I'm
* currently not sure about the consequences, so I won't
* do that and bail out instead.
*/
** currently not sure about the consequences, so I won't
** do that and bail out instead.
*/
I = Xfer;
State = Initialize;
@@ -1619,9 +1619,9 @@ unsigned OptTransfers3 (CodeSeg* S)
case FoundStore:
/* We are at the instruction behind the store. If the register
* isn't used later, and we have an address mode match, we can
* replace the transfer by a store and remove the store here.
*/
** isn't used later, and we have an address mode match, we can
** replace the transfer by a store and remove the store here.
*/
if ((GetRegInfo (S, I, XferEntry->Chg) & XferEntry->Chg) == 0 &&
(StoreEntry->AM == AM65_ABS ||
StoreEntry->AM == AM65_ZP) &&
@@ -1710,8 +1710,8 @@ unsigned OptTransfers3 (CodeSeg* S)
unsigned OptTransfers4 (CodeSeg* S)
/* Replace a load of a register followed by a transfer insn of the same register
* by a load of the second register if possible.
*/
** by a load of the second register if possible.
*/
{
unsigned Changes = 0;
unsigned Load = 0; /* Index of load insn */
@@ -1726,8 +1726,8 @@ unsigned OptTransfers4 (CodeSeg* S)
} State = Search;
/* Walk over the entries. Look for a load instruction that is followed by
* a load later.
*/
** a load later.
*/
unsigned I = 0;
while (I < CS_GetEntryCount (S)) {
@@ -1747,8 +1747,8 @@ unsigned OptTransfers4 (CodeSeg* S)
case FoundLoad:
/* If we find a conditional jump, abort the sequence, since
* handling them makes things really complicated.
*/
** handling them makes things really complicated.
*/
if (E->Info & OF_CBRA) {
/* Switch back to searching */
@@ -1759,8 +1759,8 @@ unsigned OptTransfers4 (CodeSeg* S)
} else if ((E->Use & LoadEntry->Chg) != 0) {
/* It it's a xfer instruction, and the block is a basic
* block, proceed. Otherwise restart
*/
** block, proceed. Otherwise restart
*/
if ((E->Info & OF_XFR) != 0 &&
CS_IsBasicBlock (S, Load, I)) {
Xfer = I;
@@ -1775,9 +1775,9 @@ unsigned OptTransfers4 (CodeSeg* S)
} else if (E->Chg & LoadEntry->Chg) {
/* We *may* add code here to remove the load, but I'm
* currently not sure about the consequences, so I won't
* do that and bail out instead.
*/
** currently not sure about the consequences, so I won't
** do that and bail out instead.
*/
I = Load;
State = Search;
}
@@ -1785,9 +1785,9 @@ unsigned OptTransfers4 (CodeSeg* S)
case FoundXfer:
/* We are at the instruction behind the xfer. If the register
* isn't used later, and we have an address mode match, we can
* replace the transfer by a load and remove the initial load.
*/
** isn't used later, and we have an address mode match, we can
** replace the transfer by a load and remove the initial load.
*/
if ((GetRegInfo (S, I, LoadEntry->Chg) & LoadEntry->Chg) == 0 &&
(LoadEntry->AM == AM65_ABS ||
LoadEntry->AM == AM65_ZP ||
@@ -1880,14 +1880,14 @@ unsigned OptPushPop (CodeSeg* S)
} State = Searching;
/* Walk over the entries. Look for a push instruction that is followed by
* a pop later, where the pop is not followed by an conditional branch,
* and where the value of the A register is not used later on.
* Look out for the following problems:
*
* - There may be another PHA/PLA inside the sequence: Restart it.
* - If the PLA has a label, all jumps to this label must be inside
* the sequence, otherwise we cannot remove the PHA/PLA.
*/
** a pop later, where the pop is not followed by an conditional branch,
** and where the value of the A register is not used later on.
** Look out for the following problems:
**
** - There may be another PHA/PLA inside the sequence: Restart it.
** - If the PLA has a label, all jumps to this label must be inside
** the sequence, otherwise we cannot remove the PHA/PLA.
*/
unsigned I = 0;
while (I < CS_GetEntryCount (S)) {
@@ -1916,8 +1916,8 @@ unsigned OptPushPop (CodeSeg* S)
/* Found a matching pop */
Pop = I;
/* Check that the block between Push and Pop is a basic
* block (one entry, one exit). Otherwise ignore it.
*/
** block (one entry, one exit). Otherwise ignore it.
*/
if (CS_IsBasicBlock (S, Push, Pop)) {
State = FoundPop;
} else {
@@ -1931,16 +1931,16 @@ unsigned OptPushPop (CodeSeg* S)
case FoundPop:
/* We're at the instruction after the PLA.
* Check for the following conditions:
* - If this instruction is a store of A that doesn't use
* another register, if the instruction does not have a
* label, and A is not used later, we may replace the PHA
* by the store and remove pla if several other conditions
* are met.
* - If this instruction is not a conditional branch, and A
* is either unused later, or not changed by the code
* between push and pop, we may remove PHA and PLA.
*/
** Check for the following conditions:
** - If this instruction is a store of A that doesn't use
** another register, if the instruction does not have a
** label, and A is not used later, we may replace the PHA
** by the store and remove pla if several other conditions
** are met.
** - If this instruction is not a conditional branch, and A
** is either unused later, or not changed by the code
** between push and pop, we may remove PHA and PLA.
*/
if (E->OPC == OP65_STA &&
(E->AM == AM65_ABS || E->AM == AM65_ZP) &&
!CE_HasLabel (E) &&
@@ -1995,8 +1995,8 @@ unsigned OptPushPop (CodeSeg* S)
unsigned OptPrecalc (CodeSeg* S)
/* Replace immediate operations with the accu where the current contents are
* known by a load of the final value.
*/
** known by a load of the final value.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -2052,11 +2052,11 @@ unsigned OptPrecalc (CodeSeg* S)
case OP65_ADC:
case OP65_SBC:
/* If this is an operation with an immediate operand of zero,
* and the register is zero, the operation won't give us any
* results we don't already have (including the flags), so
* remove it. Something like this is generated as a result of
* a compare where parts of the values are known to be zero.
*/
** and the register is zero, the operation won't give us any
** results we don't already have (including the flags), so
** remove it. Something like this is generated as a result of
** a compare where parts of the values are known to be zero.
*/
if (In->RegA == 0 && CE_IsKnownImm (E, 0x00)) {
/* 0-0 or 0+0 -> remove */
CS_DelEntry (S, I);
@@ -2198,15 +2198,15 @@ unsigned OptBranchDist (CodeSeg* S)
unsigned OptIndLoads1 (CodeSeg* S)
/* Change
*
* lda (zp),y
*
* into
*
* lda (zp,x)
*
* provided that x and y are both zero.
*/
**
** lda (zp),y
**
** into
**
** lda (zp,x)
**
** provided that x and y are both zero.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -2246,15 +2246,15 @@ unsigned OptIndLoads1 (CodeSeg* S)
unsigned OptIndLoads2 (CodeSeg* S)
/* Change
*
* lda (zp,x)
*
* into
*
* lda (zp),y
*
* provided that x and y are both zero.
*/
**
** lda (zp,x)
**
** into
**
** lda (zp),y
**
** provided that x and y are both zero.
*/
{
unsigned Changes = 0;
unsigned I;

View File

@@ -60,51 +60,51 @@ unsigned OptDeadJumps (CodeSeg* S);
unsigned OptDeadCode (CodeSeg* S);
/* Remove dead code (code that follows an unconditional jump or an rts/rti
* and has no label)
*/
** and has no label)
*/
unsigned OptJumpCascades (CodeSeg* S);
/* Optimize jump cascades (jumps to jumps). In such a case, the jump is
* replaced by a jump to the final location. This will in some cases produce
* worse code, because some jump targets are no longer reachable by short
* branches, but this is quite rare, so there are more advantages than
* disadvantages.
*/
** replaced by a jump to the final location. This will in some cases produce
** worse code, because some jump targets are no longer reachable by short
** branches, but this is quite rare, so there are more advantages than
** disadvantages.
*/
unsigned OptRTS (CodeSeg* S);
/* Optimize subroutine calls followed by an RTS. The subroutine call will get
* replaced by a jump. Don't bother to delete the RTS if it does not have a
* label, the dead code elimination should take care of it.
*/
** replaced by a jump. Don't bother to delete the RTS if it does not have a
** label, the dead code elimination should take care of it.
*/
unsigned OptJumpTarget1 (CodeSeg* S);
/* If the instruction preceeding an unconditional branch is the same as the
* instruction preceeding the jump target, the jump target may be moved
* one entry back. This is a size optimization, since the instruction before
* the branch gets removed.
*/
** instruction preceeding the jump target, the jump target may be moved
** one entry back. This is a size optimization, since the instruction before
** the branch gets removed.
*/
unsigned OptJumpTarget2 (CodeSeg* S);
/* If a bcs jumps to a sec insn or a bcc jumps to clc, skip this insn, since
* it's job is already done.
*/
** it's job is already done.
*/
unsigned OptJumpTarget3 (CodeSeg* S);
/* Jumps to load instructions of a register, that do already have the matching
* register contents may skip the load instruction, since it's job is already
* done.
*/
** register contents may skip the load instruction, since it's job is already
** done.
*/
unsigned OptCondBranches1 (CodeSeg* S);
/* If an immidiate load of a register is followed by a conditional jump that
* is never taken because the load of the register sets the flags in such a
* manner, remove the conditional branch.
*/
** is never taken because the load of the register sets the flags in such a
** manner, remove the conditional branch.
*/
unsigned OptCondBranches2 (CodeSeg* S);
/* If on entry to a "rol a" instruction the accu is zero, and a beq/bne follows,
* we can remove the rol and branch on the state of the carry.
*/
** we can remove the rol and branch on the state of the carry.
*/
unsigned OptUnusedLoads (CodeSeg* S);
/* Remove loads of registers where the value loaded is not used later. */
@@ -123,53 +123,53 @@ unsigned OptTransfers1 (CodeSeg* S);
unsigned OptTransfers2 (CodeSeg* S);
/* Replace loads followed by a register transfer by a load with the second
* register if possible.
*/
** register if possible.
*/
unsigned OptTransfers3 (CodeSeg* S);
/* Replace a register transfer followed by a store of the second register by a
* store of the first register if this is possible.
*/
** store of the first register if this is possible.
*/
unsigned OptTransfers4 (CodeSeg* S);
/* Replace a load of a register followed by a transfer insn of the same register
* by a load of the second register if possible.
*/
** by a load of the second register if possible.
*/
unsigned OptPushPop (CodeSeg* S);
/* Remove a PHA/PLA sequence were A is not used later */
unsigned OptPrecalc (CodeSeg* S);
/* Replace immediate operations with the accu where the current contents are
* known by a load of the final value.
*/
** known by a load of the final value.
*/
unsigned OptBranchDist (CodeSeg* S);
/* Change branches for the distance needed. */
unsigned OptIndLoads1 (CodeSeg* S);
/* Change
*
* lda (zp),y
*
* into
*
* lda (zp,x)
*
* provided that x and y are both zero.
*/
**
** lda (zp),y
**
** into
**
** lda (zp,x)
**
** provided that x and y are both zero.
*/
unsigned OptIndLoads2 (CodeSeg* S);
/* Change
*
* lda (zp,x)
*
* into
*
* lda (zp),y
*
* provided that x and y are both zero.
*/
**
** lda (zp,x)
**
** into
**
** lda (zp),y
**
** provided that x and y are both zero.
*/

View File

@@ -48,13 +48,13 @@
unsigned OptBNegA1 (CodeSeg* S)
/* Check for
*
* ldx #$00
* lda ..
* jsr bnega
*
* Remove the ldx if the lda does not use it.
*/
**
** ldx #$00
** lda ..
** jsr bnega
**
** Remove the ldx if the lda does not use it.
*/
{
unsigned Changes = 0;
@@ -100,13 +100,13 @@ unsigned OptBNegA1 (CodeSeg* S)
unsigned OptBNegA2 (CodeSeg* S)
/* Check for
*
* lda ..
* jsr bnega
* jeq/jne ..
*
* Adjust the conditional branch and remove the call to the subroutine.
*/
**
** lda ..
** jsr bnega
** jeq/jne ..
**
** Adjust the conditional branch and remove the call to the subroutine.
*/
{
unsigned Changes = 0;
@@ -167,9 +167,9 @@ unsigned OptBNegA2 (CodeSeg* S)
unsigned OptBNegAX1 (CodeSeg* S)
/* On a call to bnegax, if X is zero, the result depends only on the value in
* A, so change the call to a call to bnega. This will get further optimized
* later if possible.
*/
** A, so change the call to a call to bnega. This will get further optimized
** later if possible.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -205,20 +205,20 @@ unsigned OptBNegAX1 (CodeSeg* S)
unsigned OptBNegAX2 (CodeSeg* S)
/* Search for the sequence:
*
* ldy #xx
* jsr ldaxysp
* jsr bnegax
* jne/jeq ...
*
* and replace it by
*
* ldy #xx
* lda (sp),y
* dey
* ora (sp),y
* jeq/jne ...
*/
**
** ldy #xx
** jsr ldaxysp
** jsr bnegax
** jne/jeq ...
**
** and replace it by
**
** ldy #xx
** lda (sp),y
** dey
** ora (sp),y
** jeq/jne ...
*/
{
unsigned Changes = 0;
@@ -278,18 +278,18 @@ unsigned OptBNegAX2 (CodeSeg* S)
unsigned OptBNegAX3 (CodeSeg* S)
/* Search for the sequence:
*
* lda xx
* ldx yy
* jsr bnegax
* jne/jeq ...
*
* and replace it by
*
* lda xx
* ora xx+1
* jeq/jne ...
*/
**
** lda xx
** ldx yy
** jsr bnegax
** jne/jeq ...
**
** and replace it by
**
** lda xx
** ora xx+1
** jeq/jne ...
*/
{
unsigned Changes = 0;
@@ -339,17 +339,17 @@ unsigned OptBNegAX3 (CodeSeg* S)
unsigned OptBNegAX4 (CodeSeg* S)
/* Search for the sequence:
*
* jsr xxx
* jsr bnega(x)
* jeq/jne ...
*
* and replace it by:
*
* jsr xxx
* <boolean test>
* jne/jeq ...
*/
**
** jsr xxx
** jsr bnega(x)
** jeq/jne ...
**
** and replace it by:
**
** jsr xxx
** <boolean test>
** jne/jeq ...
*/
{
unsigned Changes = 0;
@@ -419,13 +419,13 @@ unsigned OptBNegAX4 (CodeSeg* S)
unsigned OptNegAX1 (CodeSeg* S)
/* Search for a call to negax and replace it by
*
* eor #$FF
* clc
* adc #$01
*
* if X isn't used later.
*/
**
** eor #$FF
** clc
** adc #$01
**
** if X isn't used later.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -475,17 +475,17 @@ unsigned OptNegAX1 (CodeSeg* S)
unsigned OptNegAX2 (CodeSeg* S)
/* Search for a call to negax and replace it by
*
* ldx #$FF
* eor #$FF
* clc
* adc #$01
* bne L1
* inx
* L1:
*
* if X is known and zero on entry.
*/
**
** ldx #$FF
** eor #$FF
** clc
** adc #$01
** bne L1
** inx
** L1:
**
** if X is known and zero on entry.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -565,11 +565,11 @@ unsigned OptNegAX2 (CodeSeg* S)
unsigned OptComplAX1 (CodeSeg* S)
/* Search for a call to complax and replace it by
*
* eor #$FF
*
* if X isn't used later.
*/
**
** eor #$FF
**
** if X isn't used later.
*/
{
unsigned Changes = 0;
unsigned I;

View File

@@ -51,23 +51,23 @@
unsigned OptBNegA1 (CodeSeg* S);
/* Check for
*
* ldx #$00
* lda ..
* jsr bnega
*
* Remove the ldx if the lda does not use it.
*/
**
** ldx #$00
** lda ..
** jsr bnega
**
** Remove the ldx if the lda does not use it.
*/
unsigned OptBNegA2 (CodeSeg* S);
/* Check for
*
* lda ..
* jsr bnega
* jeq/jne ..
*
* Adjust the conditional branch and remove the call to the subroutine.
*/
**
** lda ..
** jsr bnega
** jeq/jne ..
**
** Adjust the conditional branch and remove the call to the subroutine.
*/
@@ -79,56 +79,56 @@ unsigned OptBNegA2 (CodeSeg* S);
unsigned OptBNegAX1 (CodeSeg* S);
/* On a call to bnegax, if X is zero, the result depends only on the value in
* A, so change the call to a call to bnega. This will get further optimized
* later if possible.
*/
** A, so change the call to a call to bnega. This will get further optimized
** later if possible.
*/
unsigned OptBNegAX2 (CodeSeg* S);
/* Search for the sequence:
*
* lda (xx),y
* tax
* dey
* lda (xx),y
* jsr bnegax
* jne/jeq ...
*
* and replace it by
*
* lda (xx),y
* dey
* ora (xx),y
* jeq/jne ...
*/
**
** lda (xx),y
** tax
** dey
** lda (xx),y
** jsr bnegax
** jne/jeq ...
**
** and replace it by
**
** lda (xx),y
** dey
** ora (xx),y
** jeq/jne ...
*/
unsigned OptBNegAX3 (CodeSeg* S);
/* Search for the sequence:
*
* lda xx
* ldx yy
* jsr bnegax
* jne/jeq ...
*
* and replace it by
*
* lda xx
* ora xx+1
* jeq/jne ...
*/
**
** lda xx
** ldx yy
** jsr bnegax
** jne/jeq ...
**
** and replace it by
**
** lda xx
** ora xx+1
** jeq/jne ...
*/
unsigned OptBNegAX4 (CodeSeg* S);
/* Search for the sequence:
*
* jsr xxx
* jsr bnega(x)
* jeq/jne ...
*
* and replace it by:
*
* jsr xxx
* <boolean test>
* jne/jeq ...
*/
**
** jsr xxx
** jsr bnega(x)
** jeq/jne ...
**
** and replace it by:
**
** jsr xxx
** <boolean test>
** jne/jeq ...
*/
@@ -140,27 +140,27 @@ unsigned OptBNegAX4 (CodeSeg* S);
unsigned OptNegAX1 (CodeSeg* S);
/* Search for a call to negax and replace it by
*
* eor #$FF
* clc
* adc #$01
*
* if X isn't used later.
*/
**
** eor #$FF
** clc
** adc #$01
**
** if X isn't used later.
*/
unsigned OptNegAX2 (CodeSeg* S);
/* Search for a call to negax and replace it by
*
* ldx #$FF
* eor #$FF
* clc
* adc #$01
* bne L1
* inx
* L1:
*
* if X is known and zero on entry.
*/
**
** ldx #$FF
** eor #$FF
** clc
** adc #$01
** bne L1
** inx
** L1:
**
** if X is known and zero on entry.
*/
@@ -172,11 +172,11 @@ unsigned OptNegAX2 (CodeSeg* S);
unsigned OptComplAX1 (CodeSeg* S);
/* Search for a call to complax and replace it by
*
* eor #$FF
*
* if X isn't used later.
*/
**
** eor #$FF
**
** if X isn't used later.
*/

View File

@@ -53,28 +53,28 @@
unsigned OptPtrLoad1 (CodeSeg* S)
/* Search for the sequence:
*
* clc
* adc xxx
* tay
* txa
* adc yyy
* tax
* tya
* ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* sta ptr1
* txa
* clc
* adc yyy
* sta ptr1+1
* ldy xxx
* ldx #$00
* lda (ptr1),y
*/
**
** clc
** adc xxx
** tay
** txa
** adc yyy
** tax
** tya
** ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** sta ptr1
** txa
** clc
** adc yyy
** sta ptr1+1
** ldy xxx
** ldx #$00
** lda (ptr1),y
*/
{
unsigned Changes = 0;
@@ -115,9 +115,9 @@ unsigned OptPtrLoad1 (CodeSeg* S)
CS_InsertEntry (S, X, IP++);
/* If the instruction before the clc is a ldx, replace the
* txa by an lda with the same location of the ldx. Otherwise
* transfer the value in X to A.
*/
** txa by an lda with the same location of the ldx. Otherwise
** transfer the value in X to A.
*/
if ((P = CS_GetPrevEntry (S, I)) != 0 &&
P->OPC == OP65_LDX &&
!CE_HasLabel (P)) {
@@ -172,29 +172,29 @@ unsigned OptPtrLoad1 (CodeSeg* S)
unsigned OptPtrLoad2 (CodeSeg* S)
/* Search for the sequence:
*
* adc xxx
* pha
* txa
* iny
* adc yyy
* tax
* pla
* ldy
* jsr ldauidx
*
* and replace it by:
*
* adc xxx
* sta ptr1
* txa
* iny
* adc yyy
* sta ptr1+1
* ldy
* ldx #$00
* lda (ptr1),y
*/
**
** adc xxx
** pha
** txa
** iny
** adc yyy
** tax
** pla
** ldy
** jsr ldauidx
**
** and replace it by:
**
** adc xxx
** sta ptr1
** txa
** iny
** adc yyy
** sta ptr1+1
** ldy
** ldx #$00
** lda (ptr1),y
*/
{
unsigned Changes = 0;
@@ -260,22 +260,22 @@ unsigned OptPtrLoad2 (CodeSeg* S)
unsigned OptPtrLoad3 (CodeSeg* S)
/* Search for the sequence:
*
* lda #<(label+0)
* ldx #>(label+0)
* clc
* adc xxx
* bcc L
* inx
* L: ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* ldy xxx
* ldx #$00
* lda label,y
*/
**
** lda #<(label+0)
** ldx #>(label+0)
** clc
** adc xxx
** bcc L
** inx
** L: ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** ldy xxx
** ldx #$00
** lda label,y
*/
{
unsigned Changes = 0;
@@ -319,8 +319,8 @@ unsigned OptPtrLoad3 (CodeSeg* S)
char* Label;
/* We will create all the new stuff behind the current one so
* we keep the line references.
*/
** we keep the line references.
*/
X = NewCodeEntry (OP65_LDY, L[3]->AM, L[3]->Arg, 0, L[0]->LI);
CS_InsertEntry (S, X, I+8);
@@ -354,25 +354,25 @@ unsigned OptPtrLoad3 (CodeSeg* S)
unsigned OptPtrLoad4 (CodeSeg* S)
/* Search for the sequence:
*
* lda #<(label+0)
* ldx #>(label+0)
* ldy #$xx
* clc
* adc (sp),y
* bcc L
* inx
* L: ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* ldy #$xx
* lda (sp),y
* tay
* ldx #$00
* lda label,y
*/
**
** lda #<(label+0)
** ldx #>(label+0)
** ldy #$xx
** clc
** adc (sp),y
** bcc L
** inx
** L: ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** ldy #$xx
** lda (sp),y
** tay
** ldx #$00
** lda label,y
*/
{
unsigned Changes = 0;
@@ -463,22 +463,22 @@ unsigned OptPtrLoad4 (CodeSeg* S)
unsigned OptPtrLoad5 (CodeSeg* S)
/* Search for the sequence:
*
* jsr pushax
* ldx #$00
* lda yyy
* jsr tosaddax
* ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy yyy
* ldx #$00
* lda (ptr1),y
*/
**
** jsr pushax
** ldx #$00
** lda yyy
** jsr tosaddax
** ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy yyy
** ldx #$00
** lda (ptr1),y
*/
{
unsigned Changes = 0;
@@ -549,25 +549,25 @@ unsigned OptPtrLoad5 (CodeSeg* S)
unsigned OptPtrLoad6 (CodeSeg* S)
/* Search for the sequence:
*
* jsr pushax
* ldy #xxx
* ldx #$00
* lda (sp),y
* jsr tosaddax
* ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy #xxx-2
* lda (sp),y
* tay
* ldx #$00
* lda (ptr1),y
*/
**
** jsr pushax
** ldy #xxx
** ldx #$00
** lda (sp),y
** jsr tosaddax
** ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy #xxx-2
** lda (sp),y
** tay
** ldx #$00
** lda (ptr1),y
*/
{
unsigned Changes = 0;
@@ -650,35 +650,35 @@ unsigned OptPtrLoad6 (CodeSeg* S)
unsigned OptPtrLoad7 (CodeSeg* S)
/* Search for the sequence:
*
* jsr aslax1/shlax1
* clc
* adc xxx
* tay
* txa
* adc yyy
* tax
* tya
* ldy zzz
* jsr ldaxidx
*
* and replace it by:
*
* stx tmp1
* asl a
* rol tmp1
* clc
* adc xxx
* sta ptr1
* lda tmp1
* adc yyy
* sta ptr1+1
* ldy zzz
* lda (ptr1),y
* tax
* dey
* lda (ptr1),y
*/
**
** jsr aslax1/shlax1
** clc
** adc xxx
** tay
** txa
** adc yyy
** tax
** tya
** ldy zzz
** jsr ldaxidx
**
** and replace it by:
**
** stx tmp1
** asl a
** rol tmp1
** clc
** adc xxx
** sta ptr1
** lda tmp1
** adc yyy
** sta ptr1+1
** ldy zzz
** lda (ptr1),y
** tax
** dey
** lda (ptr1),y
*/
{
unsigned Changes = 0;
unsigned I;
@@ -715,15 +715,15 @@ unsigned OptPtrLoad7 (CodeSeg* S)
/* If X is zero on entry to aslax1, we can generate:
*
* asl a
* bcc L1
* inx
* L1: clc
*
* instead of the code above. "lda tmp1" needs to be changed
* to "txa" in this case.
*/
**
** asl a
** bcc L1
** inx
** L1: clc
**
** instead of the code above. "lda tmp1" needs to be changed
** to "txa" in this case.
*/
int ShortCode = (L[0]->RI->In.RegX == 0);
if (ShortCode) {
@@ -838,22 +838,22 @@ unsigned OptPtrLoad7 (CodeSeg* S)
unsigned OptPtrLoad11 (CodeSeg* S)
/* Search for the sequence:
*
* clc
* adc xxx
* bcc L
* inx
* L: ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* ldy xxx
* sta ptr1
* stx ptr1+1
* ldx #$00
* lda (ptr1),y
*/
**
** clc
** adc xxx
** bcc L
** inx
** L: ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** ldy xxx
** sta ptr1
** stx ptr1+1
** ldx #$00
** lda (ptr1),y
*/
{
unsigned Changes = 0;
@@ -884,8 +884,8 @@ unsigned OptPtrLoad11 (CodeSeg* S)
CodeEntry* X;
/* We will create all the new stuff behind the current one so
* we keep the line references.
*/
** we keep the line references.
*/
X = NewCodeEntry (OP65_LDY, L[1]->AM, L[1]->Arg, 0, L[0]->LI);
CS_InsertEntry (S, X, I+6);
@@ -925,35 +925,35 @@ unsigned OptPtrLoad11 (CodeSeg* S)
unsigned OptPtrLoad12 (CodeSeg* S)
/* Search for the sequence:
*
* lda regbank+n
* ldx regbank+n+1
* sta regsave
* stx regsave+1
* clc
* adc #$01
* bcc L0005
* inx
* L: sta regbank+n
* stx regbank+n+1
* lda regsave
* ldx regsave+1
* ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* ldy #$00
* ldx #$00
* lda (regbank+n),y
* inc regbank+n
* bne L1
* inc regbank+n+1
* L1: tay <- only if flags are used
*
* This function must execute before OptPtrLoad7!
*
*/
**
** lda regbank+n
** ldx regbank+n+1
** sta regsave
** stx regsave+1
** clc
** adc #$01
** bcc L0005
** inx
** L: sta regbank+n
** stx regbank+n+1
** lda regsave
** ldx regsave+1
** ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** ldy #$00
** ldx #$00
** lda (regbank+n),y
** inc regbank+n
** bne L1
** inc regbank+n+1
** L1: tay <- only if flags are used
**
** This function must execute before OptPtrLoad7!
**
*/
{
unsigned Changes = 0;
@@ -1012,17 +1012,17 @@ unsigned OptPtrLoad12 (CodeSeg* S)
CodeLabel* Label;
/* Check if the instruction following the sequence uses the flags
* set by the load. If so, insert a test of the value in the
* accumulator.
*/
** set by the load. If so, insert a test of the value in the
** accumulator.
*/
if (CE_UseLoadFlags (L[14])) {
X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[13]->LI);
CS_InsertEntry (S, X, I+14);
}
/* Attach a label to L[14]. This may be either the just inserted
* instruction, or the one following the sequence.
*/
** instruction, or the one following the sequence.
*/
Label = CS_GenLabel (S, L[14]);
/* ldy #$xx */
@@ -1070,18 +1070,18 @@ unsigned OptPtrLoad12 (CodeSeg* S)
unsigned OptPtrLoad13 (CodeSeg* S)
/* Search for the sequence:
*
* lda zp
* ldx zp+1
* ldy xx
* jsr ldauidx
*
* and replace it by:
*
* ldy xx
* ldx #$00
* lda (zp),y
*/
**
** lda zp
** ldx zp+1
** ldy xx
** jsr ldauidx
**
** and replace it by:
**
** ldy xx
** ldx #$00
** lda (zp),y
*/
{
unsigned Changes = 0;
@@ -1138,23 +1138,22 @@ unsigned OptPtrLoad13 (CodeSeg* S)
unsigned OptPtrLoad14 (CodeSeg* S)
/* Search for the sequence:
*
* lda zp
* ldx zp+1
* (anything that doesn't change a/x)
* ldy xx
* jsr ldauidx
*
* and replace it by:
*
* lda zp
* ldx zp+1
* (anything that doesn't change a/x)
* ldy xx
* ldx #$00
* lda (zp),y
*
*/
**
** lda zp
** ldx zp+1
** (anything that doesn't change a/x)
** ldy xx
** jsr ldauidx
**
** and replace it by:
**
** lda zp
** ldx zp+1
** (anything that doesn't change a/x)
** ldy xx
** ldx #$00
** lda (zp),y
*/
{
unsigned Changes = 0;
unsigned I;
@@ -1212,24 +1211,24 @@ unsigned OptPtrLoad14 (CodeSeg* S)
unsigned OptPtrLoad15 (CodeSeg* S)
/* Search for the sequence:
*
* lda zp
* ldx zp+1
* jsr pushax <- optional
* ldy xx
* jsr ldaxidx
*
* and replace it by:
*
* lda zp <- only if
* ldx zp+1 <- call to
* jsr pushax <- pushax present
* ldy xx
* lda (zp),y
* tax
* dey
* lda (zp),y
*/
**
** lda zp
** ldx zp+1
** jsr pushax <- optional
** ldy xx
** jsr ldaxidx
**
** and replace it by:
**
** lda zp <- only if
** ldx zp+1 <- call to
** jsr pushax <- pushax present
** ldy xx
** lda (zp),y
** tax
** dey
** lda (zp),y
*/
{
unsigned Changes = 0;
@@ -1300,20 +1299,20 @@ unsigned OptPtrLoad15 (CodeSeg* S)
unsigned OptPtrLoad16 (CodeSeg* S)
/* Search for the sequence
*
* ldy ...
* jsr ldauidx
*
* and replace it by:
*
* stx ptr1+1
* sta ptr1
* ldy ...
* ldx #$00
* lda (ptr1),y
*
* This step must be executed *after* OptPtrLoad1!
*/
**
** ldy ...
** jsr ldauidx
**
** and replace it by:
**
** stx ptr1+1
** sta ptr1
** ldy ...
** ldx #$00
** lda (ptr1),y
**
** This step must be executed *after* OptPtrLoad1!
*/
{
unsigned Changes = 0;
@@ -1375,25 +1374,25 @@ unsigned OptPtrLoad16 (CodeSeg* S)
unsigned OptPtrLoad17 (CodeSeg* S)
/* Search for the sequence
*
* ldy ...
* jsr ldaxidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy ...
* lda (ptr1),y
* tax
* dey
* lda (ptr1),y
*
* This step must be executed *after* OptPtrLoad9! While code size increases
* by more than 200%, inlining will greatly improve visibility for the
* optimizer, so often part of the code gets improved later. So we will mark
* the step with less than 200% so it gets executed when -Oi is in effect.
*/
**
** ldy ...
** jsr ldaxidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy ...
** lda (ptr1),y
** tax
** dey
** lda (ptr1),y
**
** This step must be executed *after* OptPtrLoad9! While code size increases
** by more than 200%, inlining will greatly improve visibility for the
** optimizer, so often part of the code gets improved later. So we will mark
** the step with less than 200% so it gets executed when -Oi is in effect.
*/
{
unsigned Changes = 0;

View File

@@ -51,310 +51,310 @@
unsigned OptPtrLoad1 (CodeSeg* S);
/* Search for the sequence:
*
* clc
* adc xxx
* tay
* txa
* adc yyy
* tax
* tya
* ldy
* jsr ldauidx
*
* and replace it by:
*
* clc
* adc xxx
* sta ptr1
* txa
* adc yyy
* sta ptr1+1
* ldy
* ldx #$00
* lda (ptr1),y
*/
**
** clc
** adc xxx
** tay
** txa
** adc yyy
** tax
** tya
** ldy
** jsr ldauidx
**
** and replace it by:
**
** clc
** adc xxx
** sta ptr1
** txa
** adc yyy
** sta ptr1+1
** ldy
** ldx #$00
** lda (ptr1),y
*/
unsigned OptPtrLoad2 (CodeSeg* S);
/* Search for the sequence:
*
* adc xxx
* pha
* txa
* iny
* adc yyy
* tax
* pla
* ldy
* jsr ldauidx
*
* and replace it by:
*
* adc xxx
* sta ptr1
* txa
* iny
* adc yyy
* sta ptr1+1
* ldy
* ldx #$00
* lda (ptr1),y
*/
**
** adc xxx
** pha
** txa
** iny
** adc yyy
** tax
** pla
** ldy
** jsr ldauidx
**
** and replace it by:
**
** adc xxx
** sta ptr1
** txa
** iny
** adc yyy
** sta ptr1+1
** ldy
** ldx #$00
** lda (ptr1),y
*/
unsigned OptPtrLoad3 (CodeSeg* S);
/* Search for the sequence:
*
* lda #<(label+0)
* ldx #>(label+0)
* clc
* adc xxx
* bcc L
* inx
* L: ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* ldy xxx
* ldx #$00
* lda label,y
*/
**
** lda #<(label+0)
** ldx #>(label+0)
** clc
** adc xxx
** bcc L
** inx
** L: ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** ldy xxx
** ldx #$00
** lda label,y
*/
unsigned OptPtrLoad4 (CodeSeg* S);
/* Search for the sequence:
*
* lda #<(label+0)
* ldx #>(label+0)
* ldy #$xx
* clc
* adc (sp),y
* bcc L
* inx
* L: ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* ldy #$xx
* lda (sp),y
* tay
* ldx #$00
* lda label,y
*/
**
** lda #<(label+0)
** ldx #>(label+0)
** ldy #$xx
** clc
** adc (sp),y
** bcc L
** inx
** L: ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** ldy #$xx
** lda (sp),y
** tay
** ldx #$00
** lda label,y
*/
unsigned OptPtrLoad5 (CodeSeg* S);
/* Search for the sequence:
*
* jsr pushax
* ldx #$00
* lda yyy
* jsr tosaddax
* ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy yyy
* lda (ptr1),y
*/
**
** jsr pushax
** ldx #$00
** lda yyy
** jsr tosaddax
** ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy yyy
** lda (ptr1),y
*/
unsigned OptPtrLoad6 (CodeSeg* S);
/* Search for the sequence:
*
* jsr pushax
* ldy xxx
* ldx #$00
* lda (sp),y
* jsr tosaddax
* ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy xxx
* lda (sp),y
* tay
* lda (ptr1),y
*/
**
** jsr pushax
** ldy xxx
** ldx #$00
** lda (sp),y
** jsr tosaddax
** ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy xxx
** lda (sp),y
** tay
** lda (ptr1),y
*/
unsigned OptPtrLoad7 (CodeSeg* S);
/* Search for the sequence:
*
* jsr aslax1/shlax1
* clc
* adc xxx
* tay
* txa
* adc yyy
* tax
* tya
* ldy zzz
* jsr ldaxidx
*
* and replace it by:
*
* stx tmp1
* asl a
* rol tmp1
* clc
* adc xxx
* sta ptr1
* lda tmp1
* adc yyy
* sta ptr1+1
* ldy zzz
* lda (ptr1),y
* tax
* dey
* lda (ptr1),y
*/
**
** jsr aslax1/shlax1
** clc
** adc xxx
** tay
** txa
** adc yyy
** tax
** tya
** ldy zzz
** jsr ldaxidx
**
** and replace it by:
**
** stx tmp1
** asl a
** rol tmp1
** clc
** adc xxx
** sta ptr1
** lda tmp1
** adc yyy
** sta ptr1+1
** ldy zzz
** lda (ptr1),y
** tax
** dey
** lda (ptr1),y
*/
unsigned OptPtrLoad11 (CodeSeg* S);
/* Search for the sequence:
*
* clc
* adc xxx
* bcc L
* inx
* L: ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* ldy xxx
* sta ptr1
* stx ptr1+1
* ldx #$00
* lda (ptr1),y
*/
**
** clc
** adc xxx
** bcc L
** inx
** L: ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** ldy xxx
** sta ptr1
** stx ptr1+1
** ldx #$00
** lda (ptr1),y
*/
unsigned OptPtrLoad12 (CodeSeg* S);
/* Search for the sequence:
*
* lda regbank+n
* ldx regbank+n+1
* sta regsave
* stx regsave+1
* clc
* adc #$01
* bcc L0005
* inx
* L: sta regbank+n
* stx regbank+n+1
* lda regsave
* ldx regsave+1
* ldy #$00
* jsr ldauidx
*
* and replace it by:
*
* ldy #$00
* ldx #$00
* lda (regbank+n),y
* inc regbank+n
* bne L1
* inc regbank+n+1
* L1: tay <- only if flags are used
*
* This function must execute before OptPtrLoad7!
*
*/
**
** lda regbank+n
** ldx regbank+n+1
** sta regsave
** stx regsave+1
** clc
** adc #$01
** bcc L0005
** inx
** L: sta regbank+n
** stx regbank+n+1
** lda regsave
** ldx regsave+1
** ldy #$00
** jsr ldauidx
**
** and replace it by:
**
** ldy #$00
** ldx #$00
** lda (regbank+n),y
** inc regbank+n
** bne L1
** inc regbank+n+1
** L1: tay <- only if flags are used
**
** This function must execute before OptPtrLoad7!
**
*/
unsigned OptPtrLoad13 (CodeSeg* S);
/* Search for the sequence:
*
* lda zp
* ldx zp+1
* ldy xx
* jsr ldauidx
*
* and replace it by:
*
* ldy xx
* ldx #$00
* lda (zp),y
*/
**
** lda zp
** ldx zp+1
** ldy xx
** jsr ldauidx
**
** and replace it by:
**
** ldy xx
** ldx #$00
** lda (zp),y
*/
unsigned OptPtrLoad14 (CodeSeg* S);
/* Search for the sequence:
*
* lda zp
* ldx zp+1
* (anything that doesn't change a/x)
* ldy xx
* jsr ldauidx
*
* and replace it by:
*
* lda zp
* ldx zp+1
* (anything that doesn't change a/x)
* ldy xx
* ldx #$00
* lda (zp),y
*
* Must execute before OptPtrLoad10!
*/
**
** lda zp
** ldx zp+1
** (anything that doesn't change a/x)
** ldy xx
** jsr ldauidx
**
** and replace it by:
**
** lda zp
** ldx zp+1
** (anything that doesn't change a/x)
** ldy xx
** ldx #$00
** lda (zp),y
**
** Must execute before OptPtrLoad10!
*/
unsigned OptPtrLoad15 (CodeSeg* S);
/* Search for the sequence:
*
* lda zp
* ldx zp+1
* ldy xx
* jsr ldaxidx
*
* and replace it by:
*
* ldy xx
* lda (zp),y
* tax
* dey
* lda (zp),y
*/
**
** lda zp
** ldx zp+1
** ldy xx
** jsr ldaxidx
**
** and replace it by:
**
** ldy xx
** lda (zp),y
** tax
** dey
** lda (zp),y
*/
unsigned OptPtrLoad16 (CodeSeg* S);
/* Search for the sequence
*
* ldy ...
* jsr ldauidx
*
* and replace it by:
*
* ldy ...
* stx ptr1+1
* sta ptr1
* ldx #$00
* lda (ptr1),y
*
* This step must be executed *after* OptPtrLoad1!
*/
**
** ldy ...
** jsr ldauidx
**
** and replace it by:
**
** ldy ...
** stx ptr1+1
** sta ptr1
** ldx #$00
** lda (ptr1),y
**
** This step must be executed *after* OptPtrLoad1!
*/
unsigned OptPtrLoad17 (CodeSeg* S);
/* Search for the sequence
*
* ldy ...
* jsr ldaxidx
*
* and replace it by:
*
* ldy ...
* sta ptr1
* stx ptr1+1
* lda (ptr1),y
* tax
* dey
* lda (ptr1),y
*
* This step must be executed *after* OptPtrLoad9! While code size increases
* by more than 200%, inlining will greatly improve visibility for the
* optimizer, so often part of the code gets improved later. So we will mark
* the step with less than 200% so it gets executed when -Oi is in effect.
*/
**
** ldy ...
** jsr ldaxidx
**
** and replace it by:
**
** ldy ...
** sta ptr1
** stx ptr1+1
** lda (ptr1),y
** tax
** dey
** lda (ptr1),y
**
** This step must be executed *after* OptPtrLoad9! While code size increases
** by more than 200%, inlining will greatly improve visibility for the
** optimizer, so often part of the code gets improved later. So we will mark
** the step with less than 200% so it gets executed when -Oi is in effect.
*/

View File

@@ -97,9 +97,9 @@ static unsigned OptPtrStore1Sub (CodeSeg* S, unsigned I, CodeEntry** const L)
static const char* LoadAXZP (CodeSeg* S, unsigned I)
/* If the two instructions preceeding S/I are a load of A/X from a two byte
* zero byte location, return the name of the zero page location. Otherwise
* return NULL.
*/
** zero byte location, return the name of the zero page location. Otherwise
** return NULL.
*/
{
CodeEntry* L[2];
unsigned Len;
@@ -131,11 +131,11 @@ static const char* LoadAXZP (CodeSeg* S, unsigned I)
static const char* LoadAXImm (CodeSeg* S, unsigned I)
/* If the instructions preceeding S/I are a load of A/X of a constant value
* or a word sized address label, return the address of the location as a
* string.
* Beware: In case of a numeric value, the result is returned in static
* storage which is overwritten with each call.
*/
** or a word sized address label, return the address of the location as a
** string.
** Beware: In case of a numeric value, the result is returned in static
** storage which is overwritten with each call.
*/
{
static StrBuf Buf = STATIC_STRBUF_INITIALIZER;
CodeEntry* L[2];
@@ -162,9 +162,9 @@ static const char* LoadAXImm (CodeSeg* S, unsigned I)
}
/* Search back for the two instructions loading A and X. Abort
* the search if the registers are changed in any other way or
* if a label is reached while we don't have both loads.
*/
** the search if the registers are changed in any other way or
** if a label is reached while we don't have both loads.
*/
ALoad = 0;
XLoad = 0;
while (I-- > 0) {
@@ -223,49 +223,49 @@ static const char* LoadAXImm (CodeSeg* S, unsigned I)
unsigned OptPtrStore1 (CodeSeg* S)
/* Search for the sequence:
*
* clc
* adc xxx
* bcc L
* inx
* L: jsr pushax
* ldx #$00
* lda yyy
* ldy #$00
* jsr staspidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy xxx
* ldx #$00
* lda yyy
* sta (ptr1),y
*
* or by
*
* ldy xxx
* ldx #$00
* lda yyy
* sta (zp),y
*
* or by
*
* ldy xxx
* ldx #$00
* lda yyy
* sta label,y
*
* or by
*
* ldy xxx
* ldx #$00
* lda yyy
* sta $xxxx,y
*
* depending on the code preceeding the sequence above.
*/
**
** clc
** adc xxx
** bcc L
** inx
** L: jsr pushax
** ldx #$00
** lda yyy
** ldy #$00
** jsr staspidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy xxx
** ldx #$00
** lda yyy
** sta (ptr1),y
**
** or by
**
** ldy xxx
** ldx #$00
** lda yyy
** sta (zp),y
**
** or by
**
** ldy xxx
** ldx #$00
** lda yyy
** sta label,y
**
** or by
**
** ldy xxx
** ldx #$00
** lda yyy
** sta $xxxx,y
**
** depending on the code preceeding the sequence above.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -309,22 +309,22 @@ unsigned OptPtrStore1 (CodeSeg* S)
unsigned IP = I + 9;
if ((Loc = LoadAXZP (S, I)) != 0) {
/* If the sequence is preceeded by a load of a ZP value,
* we can use this ZP value as a pointer using ZP
* indirect Y addressing.
*/
** we can use this ZP value as a pointer using ZP
** indirect Y addressing.
*/
AM = AM65_ZP_INDY;
} else if ((Loc = LoadAXImm (S, I)) != 0) {
/* If the sequence is preceeded by a load of an immediate
* value, we can use this absolute value as an address
* using absolute indexed Y addressing.
*/
** value, we can use this absolute value as an address
** using absolute indexed Y addressing.
*/
AM = AM65_ABSY;
}
/* If we don't have a store location, we use ptr1 with zp
* indirect Y addressing. We must store the value in A/X into
* ptr1 in this case.
*/
** indirect Y addressing. We must store the value in A/X into
** ptr1 in this case.
*/
if (Loc == 0) {
/* Must use ptr1 */
@@ -340,10 +340,10 @@ unsigned OptPtrStore1 (CodeSeg* S)
}
/* If the index is loaded from (zp),y, we cannot do that directly.
* Note: In this case, the Y register will contain the correct
* value after removing the old code, so we don't need to load
* it here.
*/
** Note: In this case, the Y register will contain the correct
** value after removing the old code, so we don't need to load
** it here.
*/
if (L[1]->AM == AM65_ZP_INDY) {
X = NewCodeEntry (OP65_LDA, L[1]->AM, L[1]->Arg, 0, L[1]->LI);
CS_InsertEntry (S, X, IP++);
@@ -388,54 +388,54 @@ unsigned OptPtrStore1 (CodeSeg* S)
unsigned OptPtrStore2 (CodeSeg* S)
/* Search for the sequence:
*
* clc
* adc xxx
* bcc L
* inx
* L: jsr pushax
* ldy yyy
* ldx #$00
* lda (sp),y
* ldy #$00
* jsr staspidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy yyy-2
* ldx #$00
* lda (sp),y
* ldy xxx
* sta (ptr1),y
*
* or by
*
* ldy yyy-2
* ldx #$00
* lda (sp),y
* ldy xxx
* sta (zp),y
*
* or by
*
* ldy yyy-2
* ldx #$00
* lda (sp),y
* ldy xxx
* sta label,y
*
* or by
*
* ldy yyy-2
* ldx #$00
* lda (sp),y
* ldy xxx
* sta $xxxx,y
*
* depending on the code preceeding the sequence above.
*/
**
** clc
** adc xxx
** bcc L
** inx
** L: jsr pushax
** ldy yyy
** ldx #$00
** lda (sp),y
** ldy #$00
** jsr staspidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy yyy-2
** ldx #$00
** lda (sp),y
** ldy xxx
** sta (ptr1),y
**
** or by
**
** ldy yyy-2
** ldx #$00
** lda (sp),y
** ldy xxx
** sta (zp),y
**
** or by
**
** ldy yyy-2
** ldx #$00
** lda (sp),y
** ldy xxx
** sta label,y
**
** or by
**
** ldy yyy-2
** ldx #$00
** lda (sp),y
** ldy xxx
** sta $xxxx,y
**
** depending on the code preceeding the sequence above.
*/
{
unsigned Changes = 0;
unsigned I;
@@ -486,22 +486,22 @@ unsigned OptPtrStore2 (CodeSeg* S)
unsigned IP = I + 10;
if ((Loc = LoadAXZP (S, I)) != 0) {
/* If the sequence is preceeded by a load of a ZP value,
* we can use this ZP value as a pointer using ZP
* indirect Y addressing.
*/
** we can use this ZP value as a pointer using ZP
** indirect Y addressing.
*/
AM = AM65_ZP_INDY;
} else if ((Loc = LoadAXImm (S, I)) != 0) {
/* If the sequence is preceeded by a load of an immediate
* value, we can use this absolute value as an address
* using absolute indexed Y addressing.
*/
** value, we can use this absolute value as an address
** using absolute indexed Y addressing.
*/
AM = AM65_ABSY;
}
/* If we don't have a store location, we use ptr1 with zp
* indirect Y addressing. We must store the value in A/X into
* ptr1 in this case.
*/
** indirect Y addressing. We must store the value in A/X into
** ptr1 in this case.
*/
if (Loc == 0) {
/* Must use ptr1 */
@@ -517,20 +517,20 @@ unsigned OptPtrStore2 (CodeSeg* S)
}
/* Generate four different replacements depending on the addressing
* mode of the store and from where the index is loaded:
*
* 1. If the index is not loaded ZP indirect Y, we can use Y for
* the store index.
*
* 2. If the index is loaded ZP indirect Y and we store absolute
* indexed, we need Y to load the index and will therefore
* use X as index for the store. The disadvantage is that we
* need to reload X later.
*
* 3. If the index is loaded ZP indirect Y and we store ZP indirect
* Y, we must use Y for load and store and must therefore save
* the A register when loading Y the second time.
*/
** mode of the store and from where the index is loaded:
**
** 1. If the index is not loaded ZP indirect Y, we can use Y for
** the store index.
**
** 2. If the index is loaded ZP indirect Y and we store absolute
** indexed, we need Y to load the index and will therefore
** use X as index for the store. The disadvantage is that we
** need to reload X later.
**
** 3. If the index is loaded ZP indirect Y and we store ZP indirect
** Y, we must use Y for load and store and must therefore save
** the A register when loading Y the second time.
*/
if (L[1]->AM != AM65_ZP_INDY) {
/* Case 1 */
@@ -630,29 +630,28 @@ unsigned OptPtrStore2 (CodeSeg* S)
unsigned OptPtrStore3 (CodeSeg* S)
/* Search for the sequence:
*
* jsr pushax
* ldy xxx
* jsr ldauidx
* subop
* ldy yyy
* jsr staspidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy xxx
* ldx #$00
* lda (ptr1),y
* subop
* ldy yyy
* sta (ptr1),y
*
* In case a/x is loaded from the register bank before the pushax, we can even
* use the register bank instead of ptr1.
*
*/
**
** jsr pushax
** ldy xxx
** jsr ldauidx
** subop
** ldy yyy
** jsr staspidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy xxx
** ldx #$00
** lda (ptr1),y
** subop
** ldy yyy
** sta (ptr1),y
**
** In case a/x is loaded from the register bank before the pushax, we can even
** use the register bank instead of ptr1.
*/
{
unsigned Changes = 0;
@@ -689,10 +688,10 @@ unsigned OptPtrStore3 (CodeSeg* S)
/* Get the preceeding two instructions and check them. We check
* for:
* lda regbank+n
* ldx regbank+n+1
*/
** for:
** lda regbank+n
** ldx regbank+n+1
*/
if (I > 1) {
CodeEntry* P[2];
P[0] = CS_GetEntry (S, I-2);
@@ -740,8 +739,8 @@ unsigned OptPtrStore3 (CodeSeg* S)
}
/* Delete more old code. Do it here to keep a label attached to
* entry I in place.
*/
** entry I in place.
*/
CS_DelEntry (S, I); /* jsr pushax */
/* Remember, we had changes */

View File

@@ -51,126 +51,125 @@
unsigned OptPtrStore1 (CodeSeg* S);
/* Search for the sequence:
*
* clc
* adc xxx
* bcc L
* inx
* L: jsr pushax
* ldx #$00
* lda yyy
* ldy #$00
* jsr staspidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy xxx
* ldx #$00
* lda yyy
* sta (ptr1),y
*
* or by
*
* ldy xxx
* ldx #$00
* lda yyy
* sta (zp),y
*
* or by
*
* ldy xxx
* ldx #$00
* lda yyy
* sta label,y
*
* or by
*
* ldy xxx
* ldx #$00
* lda yyy
* sta $xxxx,y
*
* depending on the two instructions preceeding the sequence above.
*/
**
** clc
** adc xxx
** bcc L
** inx
** L: jsr pushax
** ldx #$00
** lda yyy
** ldy #$00
** jsr staspidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy xxx
** ldx #$00
** lda yyy
** sta (ptr1),y
**
** or by
**
** ldy xxx
** ldx #$00
** lda yyy
** sta (zp),y
**
** or by
**
** ldy xxx
** ldx #$00
** lda yyy
** sta label,y
**
** or by
**
** ldy xxx
** ldx #$00
** lda yyy
** sta $xxxx,y
**
** depending on the two instructions preceeding the sequence above.
*/
unsigned OptPtrStore2 (CodeSeg* S);
/* Search for the sequence:
*
* clc
* adc xxx
* bcc L
* inx
* L: jsr pushax
* ldy yyy
* ldx #$00
* lda (sp),y
* ldy #$00
* jsr staspidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy yyy-2
* ldx #$00
* lda (sp),y
* ldy xxx
* sta (ptr1),y
*
* or by
*
* ldy yyy-2
* ldx #$00
* lda (sp),y
* ldy xxx
* sta (zp),y
*
* or by
*
* ldy yyy-2
* ldx #$00
* lda (sp),y
* ldy xxx
* sta label,y
*
* or by
*
* ldy yyy-2
* ldx #$00
* lda (sp),y
* ldy xxx
* sta $xxxx,y
*
* depending on the code preceeding the sequence above.
*/
**
** clc
** adc xxx
** bcc L
** inx
** L: jsr pushax
** ldy yyy
** ldx #$00
** lda (sp),y
** ldy #$00
** jsr staspidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy yyy-2
** ldx #$00
** lda (sp),y
** ldy xxx
** sta (ptr1),y
**
** or by
**
** ldy yyy-2
** ldx #$00
** lda (sp),y
** ldy xxx
** sta (zp),y
**
** or by
**
** ldy yyy-2
** ldx #$00
** lda (sp),y
** ldy xxx
** sta label,y
**
** or by
**
** ldy yyy-2
** ldx #$00
** lda (sp),y
** ldy xxx
** sta $xxxx,y
**
** depending on the code preceeding the sequence above.
*/
unsigned OptPtrStore3 (CodeSeg* S);
/* Search for the sequence:
*
* jsr pushax
* ldy xxx
* jsr ldauidx
* subop
* ldy yyy
* jsr staspidx
*
* and replace it by:
*
* sta ptr1
* stx ptr1+1
* ldy xxx
* ldx #$00
* lda (ptr1),y
* subop
* ldy yyy
* sta (ptr1),y
*
* In case a/x is loaded from the register bank before the pushax, we can even
* use the register bank instead of ptr1.
*
*/
**
** jsr pushax
** ldy xxx
** jsr ldauidx
** subop
** ldy yyy
** jsr staspidx
**
** and replace it by:
**
** sta ptr1
** stx ptr1+1
** ldy xxx
** ldx #$00
** lda (ptr1),y
** subop
** ldy yyy
** sta (ptr1),y
**
** In case a/x is loaded from the register bank before the pushax, we can even
** use the register bank instead of ptr1.
*/

View File

@@ -48,17 +48,17 @@
unsigned OptPush1 (CodeSeg* S)
/* Given a sequence
*
* jsr ldaxysp
* jsr pushax
*
* If a/x are not used later, and Y is known, replace that by
*
* ldy #xx+2
* jsr pushwysp
*
* saving 3 bytes and several cycles.
*/
**
** jsr ldaxysp
** jsr pushax
**
** If a/x are not used later, and Y is known, replace that by
**
** ldy #xx+2
** jsr pushwysp
**
** saving 3 bytes and several cycles.
*/
{
unsigned I;
unsigned Changes = 0;
@@ -115,15 +115,14 @@ unsigned OptPush1 (CodeSeg* S)
unsigned OptPush2 (CodeSeg* S)
/* A sequence
*
* jsr ldaxidx
* jsr pushax
*
* may get replaced by
*
* jsr pushwidx
*
*/
**
** jsr ldaxidx
** jsr pushax
**
** may get replaced by
**
** jsr pushwidx
*/
{
unsigned I;
unsigned Changes = 0;

View File

@@ -51,30 +51,29 @@
unsigned OptPush1 (CodeSeg* S);
/* Given a sequence
*
* ldy #xx
* jsr ldaxysp
* jsr pushax
*
* If a/x are not used later, replace that by
*
* ldy #xx+2
* jsr pushwysp
*
* saving 3 bytes and several cycles.
*/
**
** ldy #xx
** jsr ldaxysp
** jsr pushax
**
** If a/x are not used later, replace that by
**
** ldy #xx+2
** jsr pushwysp
**
** saving 3 bytes and several cycles.
*/
unsigned OptPush2 (CodeSeg* S);
/* A sequence
*
* jsr ldaxidx
* jsr pushax
*
* may get replaced by
*
* jsr pushwidx
*
*/
**
** jsr ldaxidx
** jsr pushax
**
** may get replaced by
**
** jsr pushwidx
*/

Some files were not shown because too many files have changed in this diff Show More