From fdded33097f3a584221abfc63fb4d370baca08d2 Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 001/355] Made it easier to support 0-size structs in the future. --- src/cc65/compile.c | 10 ++++++---- src/cc65/datatype.c | 12 ++++++++++-- src/cc65/locals.c | 12 ++++++------ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 85c9bd5a4..d1f78098d 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -218,14 +218,16 @@ static void Parse (void) ** void types in ISO modes. */ if (Size == 0) { - if (!IsTypeVoid (Decl.Type)) { + if (!IsEmptiableObjectType (Decl.Type)) { if (!IsTypeArray (Decl.Type)) { /* Size is unknown and not an array */ - Error ("Variable '%s' has unknown size", Decl.Ident); + Error ("Cannot initialize variable '%s' of unknown size", Decl.Ident); } } else if (IS_Get (&Standard) != STD_CC65) { /* We cannot declare variables of type void */ - Error ("Illegal type for variable '%s'", Decl.Ident); + Error ("Illegal type '%s' for variable '%s'", + GetFullTypeName (Decl.Type), + Decl.Ident); } } @@ -253,7 +255,7 @@ static void Parse (void) /* We cannot declare variables of type void */ Error ("Illegal type for variable '%s'", Decl.Ident); Entry->Flags &= ~(SC_STORAGE | SC_DEF); - } else if (Size == 0 && SymIsDef (Entry)) { + } else if (Size == 0 && SymIsDef (Entry) && !IsEmptiableObjectType (Decl.Type)) { /* Size is unknown. Is it an array? */ if (!IsTypeArray (Decl.Type)) { Error ("Variable '%s' has unknown size", Decl.Ident); diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index e43af238e..b69a44dd0 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -805,7 +805,11 @@ unsigned CheckedSizeOf (const Type* T) { unsigned Size = SizeOf (T); if (Size == 0) { - Error ("Size of type '%s' is unknown", GetFullTypeName (T)); + if (HasUnknownSize (T + 1)) { + Error ("Size of type '%s' is unknown", GetFullTypeName (T)); + } else { + Error ("Size of type '%s' is 0", GetFullTypeName (T)); + } Size = SIZEOF_CHAR; /* Don't return zero */ } return Size; @@ -821,7 +825,11 @@ unsigned CheckedPSizeOf (const Type* T) { unsigned Size = PSizeOf (T); if (Size == 0) { - Error ("Size of type '%s' is unknown", GetFullTypeName (T + 1)); + if (HasUnknownSize (T + 1)) { + Error ("Pointer to type '%s' of unknown size", GetFullTypeName (T + 1)); + } else { + Error ("Pointer to type '%s' of 0 size", GetFullTypeName (T + 1)); + } Size = SIZEOF_CHAR; /* Don't return zero */ } return Size; diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 297994455..ad36bded0 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -174,8 +174,8 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg) Sym->Flags |= SC_REF; } - /* Cannot allocate a variable of zero size */ - if (Size == 0) { + /* Cannot allocate a variable of unknown size */ + if (HasUnknownSize (Sym->Type)) { if (IsTypeArray (Decl->Type)) { Error ("Array '%s' has unknown size", Decl->Ident); } else { @@ -370,8 +370,8 @@ static void ParseAutoDecl (Declaration* Decl) } } - /* Cannot allocate a variable of zero size */ - if (Size == 0) { + /* Cannot allocate an incomplete variable */ + if (HasUnknownSize (Sym->Type)) { if (IsTypeArray (Decl->Type)) { Error ("Array '%s' has unknown size", Decl->Ident); } else { @@ -428,8 +428,8 @@ static void ParseStaticDecl (Declaration* Decl) } - /* Cannot allocate a variable of zero size */ - if (Size == 0) { + /* Cannot allocate an incomplete variable */ + if (HasUnknownSize (Sym->Type)) { if (IsTypeArray (Decl->Type)) { Error ("Array '%s' has unknown size", Decl->Ident); } else { From 5fa7b90e051d126153fc6f9b8f723286f70a1784 Mon Sep 17 00:00:00 2001 From: Polluks Date: Sun, 29 Nov 2020 17:10:34 +0100 Subject: [PATCH 002/355] crt0 clean-up --- libsrc/atari5200/crt0.s | 1 - libsrc/c16/crt0.s | 1 - libsrc/c64/crt0.s | 1 - libsrc/pet/crt0.s | 1 - libsrc/plus4/crt0.s | 2 -- libsrc/supervision/crt0.s | 2 -- libsrc/telestrat/crt0.s | 1 - libsrc/vic20/crt0.s | 1 - 8 files changed, 10 deletions(-) diff --git a/libsrc/atari5200/crt0.s b/libsrc/atari5200/crt0.s index ee3d0de4f..9538d3bb4 100644 --- a/libsrc/atari5200/crt0.s +++ b/libsrc/atari5200/crt0.s @@ -13,7 +13,6 @@ .import zerobss, copydata .include "zeropage.inc" - .include "atari5200.inc" start: diff --git a/libsrc/c16/crt0.s b/libsrc/c16/crt0.s index bee81a113..1df1e5c62 100644 --- a/libsrc/c16/crt0.s +++ b/libsrc/c16/crt0.s @@ -13,7 +13,6 @@ .importzp ST .include "zeropage.inc" - .include "plus4.inc" ; ------------------------------------------------------------------------ ; Startup code diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s index 7bd294ca7..4e5c7c9d4 100644 --- a/libsrc/c64/crt0.s +++ b/libsrc/c64/crt0.s @@ -13,7 +13,6 @@ .importzp ST .include "zeropage.inc" - .include "c64.inc" ; ------------------------------------------------------------------------ diff --git a/libsrc/pet/crt0.s b/libsrc/pet/crt0.s index 520a147f7..e56a7eca4 100644 --- a/libsrc/pet/crt0.s +++ b/libsrc/pet/crt0.s @@ -12,7 +12,6 @@ .include "zeropage.inc" .include "pet.inc" - .include "../cbm/cbm.inc" ; ------------------------------------------------------------------------ ; Startup code diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index 2262b4c42..6b44a2b7e 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -198,5 +198,3 @@ irqcount: .byte 0 .segment "INIT" zpsave: .res zpspace - - diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index ac61c8215..203c681b8 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -78,5 +78,3 @@ not_dma: .word nmi .word reset32kcode .word irq - - diff --git a/libsrc/telestrat/crt0.s b/libsrc/telestrat/crt0.s index 59b1ea642..df75520ce 100644 --- a/libsrc/telestrat/crt0.s +++ b/libsrc/telestrat/crt0.s @@ -12,7 +12,6 @@ .import __MAIN_START__, __MAIN_SIZE__ .include "zeropage.inc" - .include "telestrat.inc" ; ------------------------------------------------------------------------ ; Place the startup code in a special segment. diff --git a/libsrc/vic20/crt0.s b/libsrc/vic20/crt0.s index 68ab3ed12..c5486063b 100644 --- a/libsrc/vic20/crt0.s +++ b/libsrc/vic20/crt0.s @@ -13,7 +13,6 @@ .importzp ST .include "zeropage.inc" - .include "vic20.inc" ; ------------------------------------------------------------------------ ; Startup code From 7f05bd797f92564b230346d6cceb97260f0d0353 Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 21 Feb 2021 16:36:29 +0800 Subject: [PATCH 003/355] Now the compiler tracks code that has no observable effect. --- src/cc65/assignment.c | 12 +++++++ src/cc65/expr.c | 77 +++++++++++++++++++++++++++++++++++++++---- src/cc65/exprdesc.h | 14 ++++++++ src/cc65/loadexpr.c | 4 +++ src/cc65/shiftexpr.c | 3 ++ src/cc65/stdfunc.c | 9 +++++ src/cc65/stmt.c | 11 ++++--- 7 files changed, 119 insertions(+), 11 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index e6d1e4526..0a8bc2b21 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -605,6 +605,12 @@ void OpAssign (const GenDesc* Gen, ExprDesc* Expr, const char* Op) /* Normal straight 'op=' */ OpAssignArithmetic (Gen, Expr, Op); } + + /* Expression has had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; + + /* Propagate viral flags */ + ED_PropagateFrom (Expr, &Expr2); } @@ -725,4 +731,10 @@ void OpAddSubAssign (const GenDesc* Gen, ExprDesc *Expr, const char* Op) /* Expression is an rvalue in the primary now */ ED_FinalizeRValLoad (Expr); + + /* Expression has had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; + + /* Propagate viral flags */ + ED_PropagateFrom (Expr, &Expr2); } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0275e61a3..621f16c15 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -649,6 +649,9 @@ void DoDeferred (unsigned Flags, ExprDesc* Expr) /* Sufficient to pop the processor flags */ AddCodeLine ("plp"); } + + /* Expression has had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; } @@ -822,6 +825,9 @@ static unsigned FunctionArgList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) } } + /* Propagate viral flags */ + ED_PropagateFrom (ED, &Expr); + /* Check for end of argument list */ if (CurTok.Tok != TOK_COMMA) { break; @@ -1064,6 +1070,9 @@ static void FunctionCall (ExprDesc* Expr) } Expr->Type = ReturnType; + + /* We assume all function calls had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; } @@ -1273,7 +1282,7 @@ static void Primary (ExprDesc* E) case TOK_ASM: /* ASM statement */ AsmStatement (); - E->Flags = E_RTYPE_RVAL | E_EVAL_MAYBE_UNUSED; + E->Flags = E_RTYPE_RVAL | E_EVAL_MAYBE_UNUSED | E_SIDE_EFFECTS; E->Type = type_void; break; @@ -1658,6 +1667,9 @@ static void PreInc (ExprDesc* Expr) /* Result is an expression, no reference */ ED_FinalizeRValLoad (Expr); + + /* Expression has had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; } @@ -1685,6 +1697,9 @@ static void PreDec (ExprDesc* Expr) /* Result is an expression, no reference */ ED_FinalizeRValLoad (Expr); + + /* Expression has had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; } @@ -1721,6 +1736,9 @@ static void PostInc (ExprDesc* Expr) LoadExpr (CF_NONE, Expr); AddCodeLine ("inc %s", ED_GetLabelName (Expr, 0)); + /* Expression has had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; + } else { if (ED_IsLocPrimaryOrExpr (Expr)) { @@ -1728,6 +1746,9 @@ static void PostInc (ExprDesc* Expr) /* Do the increment */ DoInc (Expr, OA_NEED_OLD); + /* Expression has had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; + } else { /* Defer the increment until after the value of this expression is used */ @@ -1771,6 +1792,9 @@ static void PostDec (ExprDesc* Expr) LoadExpr (CF_NONE, Expr); AddCodeLine ("dec %s", ED_GetLabelName (Expr, 0)); + /* Expression has had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; + } else { if (ED_IsLocPrimaryOrExpr (Expr)) { @@ -1778,6 +1802,9 @@ static void PostDec (ExprDesc* Expr) /* Do the decrement */ DoDec (Expr, OA_NEED_OLD); + /* Expression has had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; + } else { /* Defer the decrement until after the value of this expression is used */ @@ -2238,6 +2265,9 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ /* We have an rvalue in the primary now */ ED_FinalizeRValLoad (Expr); } + + /* Propagate viral flags */ + ED_PropagateFrom (Expr, &Expr2); } } @@ -2659,6 +2689,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* Result type is always boolean */ Done: Expr->Type = type_bool; + + /* Propagate viral flags */ + ED_PropagateFrom (Expr, &Expr2); } } @@ -3075,6 +3108,9 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Condition code not set */ ED_MarkAsUntested (Expr); + + /* Propagate viral flags */ + ED_PropagateFrom (Expr, &Expr2); } @@ -3352,6 +3388,9 @@ static void parsesub (ExprDesc* Expr) /* Condition code not set */ ED_MarkAsUntested (Expr); + + /* Propagate viral flags */ + ED_PropagateFrom (Expr, &Expr2); } @@ -3603,6 +3642,12 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) } } } + + /* Propagate viral flags */ + if ((Expr->Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + ED_PropagateFrom (Expr, &Expr2); + } + } /* Last expression */ @@ -3768,6 +3813,11 @@ static void hieOr (ExprDesc *Expr) } } + /* Propagate viral flags */ + if ((Expr->Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + ED_PropagateFrom (Expr, &Expr2); + } + } /* Convert to bool */ @@ -4059,6 +4109,14 @@ static void hieQuest (ExprDesc* Expr) /* Setup the target expression */ Expr->Type = ResultType; + + /* Propagate viral flags */ + if ((Expr2.Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + ED_PropagateFrom (Expr, &Expr2); + } + if ((Expr3.Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + ED_PropagateFrom (Expr, &Expr3); + } } } @@ -4140,22 +4198,29 @@ void hie0 (ExprDesc *Expr) ** emit a warning. */ GetCodePos (&End); - if (!ED_MayHaveNoEffect (Expr) && - CodeRangeIsEmpty (&Start, &End) && - IS_Get (&WarnNoEffect) && + if (!ED_MayHaveNoEffect (Expr) && + (CodeRangeIsEmpty (&Start, &End) || + (Expr->Flags & E_SIDE_EFFECTS) == 0) && + IS_Get (&WarnNoEffect) && PrevErrorCount == ErrorCount) { - Warning ("Expression result unused"); + Warning ("Left-hand operand of comma expression has no effect"); } PrevErrorCount = ErrorCount; /* Remember the current code position */ GetCodePos (&Start); + /* Keep viral flags propagated from subexpressions */ + Flags |= Expr->Flags & E_MASK_VIRAL; + /* Reset the expression */ ED_Init (Expr); - Expr->Flags = Flags; + Expr->Flags = Flags & ~E_MASK_VIRAL; NextToken (); hie1 (Expr); + + /* Propagate viral flags */ + Expr->Flags |= Flags & E_MASK_VIRAL; } } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 13eb36e5e..f1f121cc4 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -125,6 +125,7 @@ enum { E_LOADED = 0x1000, /* Expression is loaded in primary */ E_CC_SET = 0x2000, /* Condition codes are set */ E_HAVE_MARKS = 0x4000, /* Code marks are valid */ + E_SIDE_EFFECTS = 0x8000, /* Expression has had side effects */ /* Optimization hints */ E_MASK_NEED = 0x030000, @@ -181,6 +182,9 @@ enum { /* Expression result must be known to the compiler and generate no code to load */ E_EVAL_C_CONST = E_EVAL_COMPILER_KNOWN | E_EVAL_NO_CODE, + /* Flags to combine from subexpressions */ + E_MASK_VIRAL = E_SIDE_EFFECTS, + /* Flags to keep in subexpressions of most operations other than ternary */ E_MASK_KEEP_SUBEXPR = E_MASK_EVAL, @@ -467,6 +471,16 @@ INLINE int ED_MayHaveNoEffect (const ExprDesc* Expr) # define ED_MayHaveNoEffect(Expr) (((Expr)->Flags & E_EVAL_MAYBE_UNUSED) == E_EVAL_MAYBE_UNUSED) #endif +#if defined(HAVE_INLINE) +INLINE void ED_PropagateFrom (ExprDesc* Expr, const ExprDesc* SubExpr) +/* Propagate viral flags from subexpression */ +{ + Expr->Flags |= SubExpr->Flags & E_MASK_VIRAL; +} +#else +# define ED_PropagateFrom(Expr, SubExpr) (void)((Expr)->Flags |= (SubExpr)->Flags & E_MASK_VIRAL) +#endif + #if defined(HAVE_INLINE) INLINE int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr) /* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */ diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 4b7f8e279..ccd694e35 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -277,4 +277,8 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) } } + if (ED_IsLVal (Expr) && IsQualVolatile (Expr->Type)) { + /* Expression has had side effects */ + Expr->Flags |= E_SIDE_EFFECTS; + } } diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index f7385ace1..eb879a475 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -237,5 +237,8 @@ MakeRVal: /* Set the type of the result */ Expr->Type = ResultType; + + /* Propagate from subexpressions */ + Expr->Flags |= Expr2.Flags & E_MASK_VIRAL; } } diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 37566a455..5ed5ce671 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -185,6 +185,9 @@ static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Use the type of the argument for the push */ Arg->Flags |= TypeOf (Arg->Expr.Type); + + /* Propagate from subexpressions */ + Expr->Flags |= Arg->Expr.Flags & E_MASK_VIRAL; } @@ -1365,6 +1368,9 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ExitPoint: /* We expect the closing brace */ ConsumeRParen (); + + /* Propagate from subexpressions */ + Expr->Flags |= Arg.Flags & E_MASK_VIRAL; } @@ -1405,4 +1411,7 @@ void HandleStdFunc (int Index, FuncDesc* F, ExprDesc* lval) /* Call the handler function */ D->Handler (F, lval); + + /* We assume all function calls had side effects */ + lval->Flags |= E_SIDE_EFFECTS; } diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 022a8475c..a08197c09 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -613,12 +613,13 @@ static void Statement (int* PendingToken) ** void, emit a warning. */ GetCodePos (&End); - if (!ED_YetToLoad (&Expr) && - !ED_MayHaveNoEffect (&Expr) && - CodeRangeIsEmpty (&Start, &End) && - IS_Get (&WarnNoEffect) && + if (!ED_YetToLoad (&Expr) && + !ED_MayHaveNoEffect (&Expr) && + (CodeRangeIsEmpty (&Start, &End) || + (Expr.Flags & E_SIDE_EFFECTS) == 0) && + IS_Get (&WarnNoEffect) && PrevErrorCount == ErrorCount) { - Warning ("Expression result unused"); + Warning ("Statement has no effect"); } CheckSemi (PendingToken); } From 40b26f406061fc0b05da571da2b6dee3464b2390 Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 22 Feb 2021 13:47:32 +0800 Subject: [PATCH 004/355] Now the compiler removes code that has no observable effect. --- src/cc65/expr.c | 22 ++++++++++++++-------- src/cc65/stmt.c | 23 ++++++++++++++--------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 621f16c15..d12bc1519 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -4194,19 +4194,25 @@ void hie0 (ExprDesc *Expr) /* Append deferred inc/dec at sequence point */ DoDeferred (SQP_KEEP_NONE, Expr); - /* If the expression didn't generate code or isn't cast to type void, - ** emit a warning. + /* If the expression has no observable effect and isn't cast to type + ** void, emit a warning and remove useless code if any. */ GetCodePos (&End); - if (!ED_MayHaveNoEffect (Expr) && - (CodeRangeIsEmpty (&Start, &End) || - (Expr->Flags & E_SIDE_EFFECTS) == 0) && - IS_Get (&WarnNoEffect) && - PrevErrorCount == ErrorCount) { - Warning ("Left-hand operand of comma expression has no effect"); + if (CodeRangeIsEmpty (&Start, &End) || + (Expr->Flags & E_SIDE_EFFECTS) == 0) { + + if (!ED_MayHaveNoEffect (Expr) && + IS_Get (&WarnNoEffect) && + PrevErrorCount == ErrorCount) { + Warning ("Left-hand operand of comma expression has no effect"); + } + + /* Remove code with no effect */ + RemoveCode (&Start); } PrevErrorCount = ErrorCount; + /* Remember the current code position */ GetCodePos (&Start); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index a08197c09..7355e88a8 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -609,18 +609,23 @@ static void Statement (int* PendingToken) Expr.Flags |= E_NEED_NONE; Expression0 (&Expr); - /* If the statement didn't generate code, and is not of type - ** void, emit a warning. + /* If the statement has no observable effect and isn't cast to type + ** void, emit a warning and remove useless code if any. */ GetCodePos (&End); - if (!ED_YetToLoad (&Expr) && - !ED_MayHaveNoEffect (&Expr) && - (CodeRangeIsEmpty (&Start, &End) || - (Expr.Flags & E_SIDE_EFFECTS) == 0) && - IS_Get (&WarnNoEffect) && - PrevErrorCount == ErrorCount) { - Warning ("Statement has no effect"); + if (CodeRangeIsEmpty (&Start, &End) || + (Expr.Flags & E_SIDE_EFFECTS) == 0) { + + if (!ED_MayHaveNoEffect (&Expr) && + IS_Get (&WarnNoEffect) && + PrevErrorCount == ErrorCount) { + Warning ("Statement has no effect"); + } + + /* Remove code with no effect */ + RemoveCode (&Start); } + CheckSemi (PendingToken); } From f9812930c1420646b33b785379333f2529dd0969 Mon Sep 17 00:00:00 2001 From: acqn Date: Tue, 30 Mar 2021 16:47:57 +0800 Subject: [PATCH 005/355] More detailed diagnostic info about conflicted function types. --- src/cc65/symtab.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index b4c97e962..aa4a9a44a 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -728,6 +728,7 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags /* New type must be compatible with the composite prototype */ if (IsDistinctRedef (E_Type, T, TC_EQUAL, TCF_MASK_QUAL)) { Error ("Conflicting function types for '%s'", Entry->Name); + TypeCompatibilityDiagnostic (T, E_Type, 0, "'%s' vs '%s'"); Entry = 0; } else { /* Refine the existing composite prototype with this new From 2583dfb71a0ee028db3520aeb4ff6ace2fa30644 Mon Sep 17 00:00:00 2001 From: polluks2 <74630735+polluks2@users.noreply.github.com> Date: Sun, 4 Apr 2021 03:13:45 +0200 Subject: [PATCH 006/355] Update README.md Commander X16 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3d78fda50..2c84b7430 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ including - the Oric Telestrat. - the Lynx console. - the Ohio Scientific Challenger 1P. +- the Commander X16. The libraries are fairly portable, so creating a version for other 6502s shouldn't be too much work. From e9545d68ee5208b7ece65bf08e260603bd9a9894 Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 17 Apr 2021 11:43:03 +0800 Subject: [PATCH 007/355] Minor clean-ups and typo fixes. --- src/cc65/assignment.c | 15 --------------- src/cc65/expr.c | 9 +-------- src/cc65/expr.h | 9 ++++++++- src/cc65/swstmt.c | 2 +- 4 files changed, 10 insertions(+), 25 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index e6d1e4526..d565551ea 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -49,21 +49,6 @@ -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Map a generator function and its attributes to a token */ -typedef struct GenDesc { - token_t Tok; /* Token to map to */ - unsigned Flags; /* Flags for generator function */ - void (*Func) (unsigned, unsigned long); /* Generator func */ -} GenDesc; - - - /*****************************************************************************/ /* Code */ /*****************************************************************************/ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0275e61a3..dc45b108d 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -48,13 +48,6 @@ -/* Map a generator function and its attributes to a token */ -typedef struct GenDesc { - token_t Tok; /* Token to map to */ - unsigned Flags; /* Flags for generator function */ - void (*Func) (unsigned, unsigned long); /* Generator func */ -} GenDesc; - /* Descriptors for the operations */ static GenDesc GenPASGN = { TOK_PLUS_ASSIGN, GEN_NOPUSH, g_add }; static GenDesc GenSASGN = { TOK_MINUS_ASSIGN, GEN_NOPUSH, g_sub }; @@ -243,7 +236,7 @@ static const GenDesc* FindGen (token_t Tok, const GenDesc* Table) /* Find a token in a generator table */ { while (Table->Tok != TOK_INVALID) { - if (Table->Tok == Tok) { + if ((token_t)Table->Tok == Tok) { return Table; } ++Table; diff --git a/src/cc65/expr.h b/src/cc65/expr.h index 841edcb62..abdf8ab0d 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -26,13 +26,20 @@ #define SQP_KEEP_NONE 0x00 #define SQP_KEEP_TEST 0x01U #define SQP_KEEP_EAX 0x02U -#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */ +#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */ /* Generator attributes */ #define GEN_NOPUSH 0x01 /* Don't push lhs */ #define GEN_COMM 0x02 /* Operator is commutative */ #define GEN_NOFUNC 0x04 /* Not allowed for function pointers */ +/* Map a generator function and its attributes to a token */ +typedef struct GenDesc { + long Tok; /* Token to map to */ + unsigned Flags; /* Flags for generator function */ + void (*Func) (unsigned, unsigned long); /* Generator func */ +} GenDesc; + /*****************************************************************************/ diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index ee0bd1a85..00555ffc3 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -206,7 +206,7 @@ void SwitchStatement (void) void CaseLabel (void) -/* Handle a case sabel */ +/* Handle a case label */ { ExprDesc CaseExpr; /* Case label expression */ long Val; /* Case label value */ From 924fcf5d0690f8d0eb761d98d88f372107c9d924 Mon Sep 17 00:00:00 2001 From: acqn Date: Tue, 8 Jun 2021 09:32:58 +0800 Subject: [PATCH 008/355] Replaced several occurance of PtrConversion() with StdConversion(). Variadic arguments of functions should be default-promoted. --- src/cc65/datatype.c | 19 +++++++++++++++++++ src/cc65/datatype.h | 6 ++++++ src/cc65/expr.c | 9 +++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index b69a44dd0..6d9afa403 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1007,6 +1007,25 @@ const Type* PtrConversion (const Type* T) +const Type* StdConversion (const Type* T) +/* If the type is a function, convert it to pointer to function. If the +** expression is an array, convert it to pointer to first element. If the +** type is an integer, do integeral promotion. Otherwise return T. +*/ +{ + if (IsTypeFunc (T)) { + return AddressOf (T); + } else if (IsTypeArray (T)) { + return AddressOf (GetElementType (T)); + } else if (IsClassInt (T)) { + return IntPromotion (T); + } else { + return T; + } +} + + + const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index c60023944..e8ba7b6c0 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -368,6 +368,12 @@ const Type* PtrConversion (const Type* T); ** return T. */ +const Type* StdConversion (const Type* T); +/* If the type is a function, convert it to pointer to function. If the +** expression is an array, convert it to pointer to first element. If the +** type is an integer, do integeral promotion. Otherwise return T. +*/ + const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. diff --git a/src/cc65/expr.c b/src/cc65/expr.c index dc45b108d..dc2374190 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -765,9 +765,10 @@ static unsigned FunctionArgList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) } else { /* No prototype available. Convert array to "pointer to first - ** element", and function to "pointer to function". + ** element", function to "pointer to function" and do integral + ** promotion if necessary. */ - Expr.Type = PtrConversion (Expr.Type); + TypeConversion (&Expr, StdConversion (Expr.Type)); } @@ -3062,7 +3063,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) Error ("Invalid operands for binary operator '+'"); } else { /* Array and function types must be converted to pointer types */ - Expr->Type = PtrConversion (Expr->Type); + Expr->Type = StdConversion (Expr->Type); } } @@ -3341,7 +3342,7 @@ static void parsesub (ExprDesc* Expr) } /* Result type is either a pointer or an integer */ - Expr->Type = PtrConversion (Expr->Type); + Expr->Type = StdConversion (Expr->Type); /* Condition code not set */ ED_MarkAsUntested (Expr); From 2d014383cd13a96bdad1af8350da8b197c96dec5 Mon Sep 17 00:00:00 2001 From: acqn Date: Tue, 8 Jun 2021 00:43:26 +0800 Subject: [PATCH 009/355] Replaced certain usage of "(New-)PointerTo()" with "AddressOf()". --- src/cc65/expr.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index dc2374190..9c12741ec 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1127,7 +1127,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = NewPointerTo (type_void); + E->Type = type_void_p; NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1946,7 +1946,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = NewPointerTo (Expr->Type); + Expr->Type = AddressOf (Expr->Type); break; case TOK_SIZEOF: @@ -2265,9 +2265,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ Tok = CurTok.Tok; NextToken (); - /* If lhs is a function, convert it to pointer to function */ + /* If lhs is a function, convert it to the address of the function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = NewPointerTo (Expr->Type); + Expr->Type = AddressOf (Expr->Type); } /* Get the lhs on stack */ @@ -2287,9 +2287,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* Get the right hand side */ MarkedExprWithCheck (hienext, &Expr2); - /* If rhs is a function, convert it to pointer to function */ + /* If rhs is a function, convert it to the address of the function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = NewPointerTo (Expr2.Type); + Expr2.Type = AddressOf (Expr2.Type); } /* Check for a numeric constant expression */ From aac03eae6f3746dd21c5d26c551b93b5729578b3 Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 16 May 2021 19:08:42 +0800 Subject: [PATCH 010/355] Better future-proof bit-masking. --- src/cc65/typeconv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index a7528a2f8..c72b2c5eb 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -143,10 +143,10 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Do the integer constant <-> absolute address conversion if necessary */ if (IsClassPtr (NewType)) { - Expr->Flags &= ~E_LOC_NONE; + Expr->Flags &= ~E_MASK_LOC; Expr->Flags |= E_LOC_ABS | E_ADDRESS_OF; } else if (IsClassInt (NewType)) { - Expr->Flags &= ~(E_LOC_ABS | E_ADDRESS_OF); + Expr->Flags &= ~(E_MASK_LOC | E_ADDRESS_OF); Expr->Flags |= E_LOC_NONE; } From 6a3b9a9880599acc38fd721a24c5864ec3194a3e Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 16 May 2021 19:08:42 +0800 Subject: [PATCH 011/355] E_ADDRESS_OF logic fix. --- src/cc65/exprdesc.c | 5 ++--- src/cc65/exprdesc.h | 3 +-- src/cc65/loadexpr.c | 1 + 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index 3d7b7c384..7d0ace004 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -93,8 +93,7 @@ int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr) int ED_IsIndExpr (const ExprDesc* Expr) /* Check if the expression is a reference to its value */ { - return (Expr->Flags & E_ADDRESS_OF) == 0 && - !ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr); + return (Expr->Flags & E_ADDRESS_OF) == 0 && !ED_IsLocNone (Expr); } #endif @@ -282,7 +281,7 @@ ExprDesc* ED_AddrExpr (ExprDesc* Expr) case E_LOC_EXPR: Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE); - Expr->Flags |= E_LOC_PRIMARY | E_RTYPE_RVAL; + Expr->Flags |= E_ADDRESS_OF | E_LOC_PRIMARY | E_RTYPE_RVAL; break; default: diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 13eb36e5e..f2b66ee56 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -493,8 +493,7 @@ INLINE int ED_IsAddrExpr (const ExprDesc* Expr) INLINE int ED_IsIndExpr (const ExprDesc* Expr) /* Check if the expression is a reference to its value */ { - return (Expr->Flags & E_ADDRESS_OF) == 0 && - !ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr); + return (Expr->Flags & E_ADDRESS_OF) == 0 && !ED_IsLocNone (Expr); } #else int ED_IsIndExpr (const ExprDesc* Expr); diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 4b7f8e279..c5badc1b3 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -92,6 +92,7 @@ static void LoadAddress (unsigned Flags, ExprDesc* Expr) g_leasp (Expr->IVal); break; + case E_LOC_PRIMARY: case E_LOC_EXPR: if (Expr->IVal != 0) { /* We have an expression in the primary plus a constant From f5dacda69b84b2a2f6c7df3b42021016af3df4f1 Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 16 May 2021 19:08:43 +0800 Subject: [PATCH 012/355] NoCodeConstExpr() fix to avoid exessive error messages. --- src/cc65/expr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0275e61a3..cd1f780ea 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -4217,7 +4217,8 @@ ExprDesc NoCodeConstExpr (void (*Func) (ExprDesc*)) if (!ED_IsConst (&Expr) || !ED_CodeRangeIsEmpty (&Expr)) { Error ("Constant expression expected"); /* To avoid any compiler errors, make the expression a valid const */ - ED_MakeConstAbsInt (&Expr, 1); + Expr.Flags &= E_MASK_RTYPE | E_MASK_KEEP_RESULT; + Expr.Flags |= E_LOC_NONE; } /* Return by value */ From fb7b880dc02cde747de55be1e69f4ba9f08ae286 Mon Sep 17 00:00:00 2001 From: polluks2 <74630735+polluks2@users.noreply.github.com> Date: Thu, 9 Sep 2021 11:05:39 +0200 Subject: [PATCH 013/355] Create c-cpp.yml --- .github/workflows/c-cpp.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml new file mode 100644 index 000000000..e3233268f --- /dev/null +++ b/.github/workflows/c-cpp.yml @@ -0,0 +1,23 @@ +name: C/C++ CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: configure + run: ./configure + - name: make + run: make + - name: make check + run: make check + - name: make distcheck + run: make distcheck From fd8d51497c0867f42e3e9ff0a472cb9ad63ecd18 Mon Sep 17 00:00:00 2001 From: empathicqubit Date: Fri, 10 Sep 2021 21:09:22 +0200 Subject: [PATCH 014/355] Add --debug-tables option and output struct and union fields --- src/cc65/global.c | 7 +++-- src/cc65/global.h | 1 + src/cc65/main.c | 8 ++++- src/cc65/symtab.c | 74 +++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 77 insertions(+), 13 deletions(-) diff --git a/src/cc65/global.c b/src/cc65/global.c index a337549fe..8b9838dc5 100644 --- a/src/cc65/global.c +++ b/src/cc65/global.c @@ -66,6 +66,7 @@ IntStack CodeSizeFactor = INTSTACK(100);/* Size factor for generated code */ IntStack DataAlignment = INTSTACK(1); /* Alignment for data */ /* File names */ -StrBuf DepName = STATIC_STRBUF_INITIALIZER; /* Name of dependencies file */ -StrBuf FullDepName = STATIC_STRBUF_INITIALIZER; /* Name of full dependencies file */ -StrBuf DepTarget = STATIC_STRBUF_INITIALIZER; /* Name of dependency target */ +StrBuf DepName = STATIC_STRBUF_INITIALIZER; /* Name of dependencies file */ +StrBuf FullDepName = STATIC_STRBUF_INITIALIZER; /* Name of full dependencies file */ +StrBuf DepTarget = STATIC_STRBUF_INITIALIZER; /* Name of dependency target */ +StrBuf DebugTableName = STATIC_STRBUF_INITIALIZER; /* Name of debug table dump file */ diff --git a/src/cc65/global.h b/src/cc65/global.h index b9bcf5550..266035346 100644 --- a/src/cc65/global.h +++ b/src/cc65/global.h @@ -77,6 +77,7 @@ extern IntStack DataAlignment; /* Alignment for data */ extern StrBuf DepName; /* Name of dependencies file */ extern StrBuf FullDepName; /* Name of full dependencies file */ extern StrBuf DepTarget; /* Name of dependency target */ +extern StrBuf DebugTableName; /* Name of debug table dump file */ diff --git a/src/cc65/main.c b/src/cc65/main.c index 5d1fd7487..38c4b4c9d 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -114,6 +114,7 @@ static void Usage (void) " --create-full-dep name\tCreate a full make dependency file\n" " --data-name seg\t\tSet the name of the DATA segment\n" " --debug\t\t\tDebug mode\n" + " --debug-tables name\t\tWrite symbol table debug info to a file\n" " --debug-info\t\t\tAdd debug info to object file\n" " --debug-opt name\t\tDebug optimization steps\n" " --debug-opt-output\t\tDebug output of each optimization step\n" @@ -490,7 +491,11 @@ static void OptDebug (const char* Opt attribute ((unused)), ++Debug; } - +static void OptDebugTables (const char* Opt, const char* Arg) +/* Dump tables to file */ +{ + FileNameOption (Opt, Arg, &DebugTableName); +} static void OptDebugInfo (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) @@ -861,6 +866,7 @@ int main (int argc, char* argv[]) { "--create-full-dep", 1, OptCreateFullDep }, { "--data-name", 1, OptDataName }, { "--debug", 0, OptDebug }, + { "--debug-tables", 1, OptDebugTables }, { "--debug-info", 0, OptDebugInfo }, { "--debug-opt", 1, OptDebugOpt }, { "--debug-opt-output", 0, OptDebugOptOutput }, diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 5d7bd1436..64016339c 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -37,6 +37,7 @@ #include #include #include +#include /* common */ #include "check.h" @@ -68,8 +69,6 @@ /* Data */ /*****************************************************************************/ - - /* An empty symbol table */ SymTable EmptySymTab = { 0, /* PrevTab */ @@ -98,6 +97,7 @@ static SymTable* LabelTab = 0; static SymTable* SPAdjustTab = 0; static SymTable* FailSafeTab = 0; /* For errors */ +static FILE* DebugTableFile = 0; /*****************************************************************************/ /* struct SymTable */ @@ -219,11 +219,25 @@ unsigned GetLexicalLevel (void) return LexicalLevel; } - - void EnterGlobalLevel (void) /* Enter the program global lexical level */ { + const char* OutName = NULL; + if (!SB_IsEmpty (&DebugTableName)) { + OutName = SB_GetConstBuf (&DebugTableName); + } + + if (OutName) { + /* Open the table file */ + DebugTableFile = fopen (OutName, "w"); + if (DebugTableFile == 0) { + Error ("Cannot create table dump file '%s': %s", OutName, strerror (errno)); + } + } + else if (Debug) { + DebugTableFile = stdout; + } + /* Safety */ PRECONDITION (++LexicalLevel == LEX_LEVEL_GLOBAL); @@ -240,8 +254,6 @@ void EnterGlobalLevel (void) FailSafeTab = NewSymTable (SYMTAB_SIZE_GLOBAL); } - - void LeaveGlobalLevel (void) /* Leave the program global lexical level */ { @@ -252,9 +264,41 @@ void LeaveGlobalLevel (void) CheckSymTable (SymTab0); /* Dump the tables if requested */ - if (Debug) { - PrintSymTable (SymTab0, stdout, "Global symbol table"); - PrintSymTable (TagTab0, stdout, "Global tag table"); + if (DebugTableFile) { + SymEntry* Entry; + StrBuf* Header; + + PrintSymTable (SymTab0, DebugTableFile, "Global symbol table"); + PrintSymTable (TagTab0, DebugTableFile, "Global tag table"); + + Entry = TagTab0->SymHead; + if (Entry) { + fputs ("\nGlobal struct and union definitions", DebugTableFile); + fputs ("\n=========================\n", DebugTableFile); + + do { + if (!((Entry->Flags & SC_STRUCT) || (Entry->Flags & SC_UNION)) || !Entry->V.S.SymTab) { + continue; + } + + Header = NewStrBuf(); + if(Entry->Flags & SC_STRUCT) { + SB_AppendStr (Header, "SC_STRUCT: "); + } + else { + SB_AppendStr (Header, "SC_UNION: "); + } + SB_AppendStr (Header, Entry->Name); + SB_Terminate (Header); + + PrintSymTable (Entry->V.S.SymTab, DebugTableFile, SB_GetConstBuf (Header)); + } while ((Entry = Entry->NextSym)); + } + + /* Close the file */ + if (DebugTableFile != stdout && fclose (DebugTableFile) != 0) { + Error ("Error closing table dump file '%s': %s", SB_GetConstBuf(&DebugTableName), strerror (errno)); + } } /* Don't delete the symbol and struct tables! */ @@ -337,6 +381,18 @@ void LeaveFunctionLevel (void) CheckSymTable (SymTab); CheckSymTable (LabelTab); + /* Dump the tables if requested */ + if (DebugTableFile) { + StrBuf* SymbolHeader = NewStrBuf(); + + SB_AppendStr (SymbolHeader, "SC_FUNC: "); + SB_AppendStr (SymbolHeader, CurrentFunc->FuncEntry->AsmName); + SB_AppendStr (SymbolHeader, ": Symbol table"); + SB_Terminate (SymbolHeader); + + PrintSymTable (SymTab, DebugTableFile, SB_GetConstBuf(SymbolHeader)); + } + /* Drop the label table if it is empty */ if (LabelTab->SymCount == 0) { FreeSymTable (LabelTab); From 622d2c4e39f948056e87bb8fd1d03993895e582d Mon Sep 17 00:00:00 2001 From: Wayne Parham Date: Wed, 24 Nov 2021 14:30:19 -0600 Subject: [PATCH 015/355] Added Sym-1 link to documentation doc/index.sgml --- doc/index.sgml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/index.sgml b/doc/index.sgml index 01325529d..3bb085bf6 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -172,6 +172,9 @@ Topics specific to the Watara Supervision Console. + + Topics specific to the Synertek Systems Sym-1. + Topics specific to the Oric Telestrat. From 2d96f79bc732bf5ba36f9dc05cf425aa0e54a9da Mon Sep 17 00:00:00 2001 From: acqn Date: Wed, 1 Dec 2021 09:45:17 +0800 Subject: [PATCH 016/355] Added and used new utility type functions for bit-fields. Fixed GetUnderlyingTypeCode() for bit-fields with widths > 16. --- src/cc65/assignment.c | 34 ++++------------------ src/cc65/datatype.c | 66 ++++++++++++++++++++++++++++++++++++++++--- src/cc65/datatype.h | 6 ++++ src/cc65/expr.c | 4 +-- src/cc65/loadexpr.c | 36 ++++++++++------------- src/cc65/loadexpr.h | 5 +++- 6 files changed, 95 insertions(+), 56 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 05a6d9a96..e6d1e4526 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -156,19 +156,8 @@ void DoIncDecBitField (ExprDesc* Expr, long Val, unsigned KeepResult) unsigned ChunkFlags; const Type* ChunkType; - /* If the bit-field fits within one byte, do the following operations - ** with bytes. - */ - if ((Expr->Type->A.B.Width - 1U) / CHAR_BITS == - (Expr->Type->A.B.Offs + Expr->Type->A.B.Width - 1U) / CHAR_BITS) { - ChunkType = GetUnderlyingType (Expr->Type); - } else { - /* We use the declarartion integer type as the chunk type. - ** Note: A bit-field will not occupy bits located in bytes more than - ** that of its declaration type in cc65. So this is OK. - */ - ChunkType = Expr->Type + 1; - } + /* Determine the type to operate on the whole byte chunk containing the bit-field */ + ChunkType = GetBitFieldChunkType (Expr->Type); /* Determine code generator flags */ Flags = TypeOf (Expr->Type) | CF_FORCECHAR; @@ -254,19 +243,8 @@ static void OpAssignBitField (const GenDesc* Gen, ExprDesc* Expr, const char* Op ED_Init (&Expr2); Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* If the bit-field fits within one byte, do the following operations - ** with bytes. - */ - if ((Expr->Type->A.B.Width - 1U) / CHAR_BITS == - (Expr->Type->A.B.Offs + Expr->Type->A.B.Width - 1U) / CHAR_BITS) { - ChunkType = GetUnderlyingType (Expr->Type); - } else { - /* We use the declarartion integer type as the chunk type. - ** Note: A bit-field will not occupy bits located in bytes more than - ** that of its declaration type in cc65. So this is OK. - */ - ChunkType = Expr->Type + 1; - } + /* Determine the type to operate on the whole byte chunk containing the bit-field */ + ChunkType = GetBitFieldChunkType (Expr->Type); /* Determine code generator flags */ Flags = TypeOf (Expr->Type) | CF_FORCECHAR; @@ -620,8 +598,8 @@ void OpAssign (const GenDesc* Gen, ExprDesc* Expr, const char* Op) if (IsClassStruct (ltype)) { /* Copy the struct or union by value */ CopyStruct (Expr, &Expr2); - } else if (IsTypeBitField (ltype)) { - /* Special care is needed for bit-field 'op=' */ + } else if (IsTypeFragBitField (ltype)) { + /* Special care is needed for bit-fields if they don't fit in full bytes */ OpAssignBitField (Gen, Expr, Op); } else { /* Normal straight 'op=' */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index cc313bd21..bb7c40476 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -551,6 +551,24 @@ unsigned long GetIntegerTypeMax (const Type* Type) +static unsigned GetBitFieldMinimalTypeSize (unsigned BitWidth) +/* Return the size of the smallest integer type that may have BitWidth bits */ +{ + /* Since all integer types supported in cc65 for bit-fields have sizes that + ** are powers of 2, we can just use this bit-twiddling trick. + */ + unsigned V = (int)(BitWidth - 1U) / (int)CHAR_BITS; + V |= V >> 1; + V |= V >> 2; + V |= V >> 4; + V |= V >> 8; + V |= V >> 16; + + /* Return the result size */ + return V + 1U; +} + + static unsigned TypeOfBySize (unsigned Size) /* Get the code generator replacement type of the object by its size */ { @@ -591,8 +609,7 @@ const Type* GetUnderlyingType (const Type* Type) ** bit-field, instead of the type used in the declaration, the truly ** underlying of the bit-field. */ - unsigned Size = (int)(Type->A.B.Width - 1) / (int)CHAR_BITS + 1; - switch (Size) { + switch (GetBitFieldMinimalTypeSize (Type->A.B.Width)) { case SIZEOF_CHAR: Type = IsSignSigned (Type) ? type_schar : type_uchar; break; case SIZEOF_INT: Type = IsSignSigned (Type) ? type_int : type_uint; break; case SIZEOF_LONG: Type = IsSignSigned (Type) ? type_long : type_ulong; break; @@ -646,8 +663,7 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) ** bit-field, instead of the type used in the declaration, the truly ** underlying of the bit-field. */ - unsigned Size = (int)(Type->A.B.Width - 1) / (int)CHAR_BITS + 1; - switch (Size) { + switch (GetBitFieldMinimalTypeSize (Type->A.B.Width)) { case SIZEOF_CHAR: Underlying = T_CHAR; break; case SIZEOF_INT: Underlying = T_INT; break; case SIZEOF_LONG: Underlying = T_LONG; break; @@ -663,6 +679,39 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) +const Type* GetBitFieldChunkType (const Type* Type) +/* Get the type needed to operate on the byte chunk containing the bit-field */ +{ + unsigned ChunkSize; + if ((Type->A.B.Width - 1U) / CHAR_BITS == + (Type->A.B.Offs + Type->A.B.Width - 1U) / CHAR_BITS) { + /* T bit-field fits within its underlying type */ + return GetUnderlyingType (Type); + } + + ChunkSize = GetBitFieldMinimalTypeSize (Type->A.B.Offs + Type->A.B.Width); + if (ChunkSize < SizeOf (Type + 1)) { + /* The end of the bit-field is offset by some bits so that it requires + ** more bytes to be accessed as a whole than its underlying type does. + ** Note: In cc65 the bit offset is always less than CHAR_BITS. + */ + switch (ChunkSize) { + case SIZEOF_CHAR: return IsSignSigned (Type) ? type_schar : type_uchar; + case SIZEOF_INT: return IsSignSigned (Type) ? type_int : type_uint; + case SIZEOF_LONG: return IsSignSigned (Type) ? type_long : type_ulong; + default: return IsSignSigned (Type) ? type_int : type_uint; + } + } + + /* We can always use the declarartion integer type as the chunk type. + ** Note: A bit-field will not occupy bits located in bytes more than that + ** of its declaration type in cc65. So this is OK. + */ + return Type + 1; +} + + + unsigned SizeOf (const Type* T) /* Compute size of object represented by type array. */ { @@ -1127,6 +1176,15 @@ Type* NewBitFieldType (const Type* T, unsigned BitOffs, unsigned BitWidth) +int IsTypeFragBitField (const Type* T) +/* Return true if this is a bit-field that shares byte space with other fields */ +{ + return IsTypeBitField (T) && + (T->A.B.Offs != 0 || T->A.B.Width != CHAR_BITS * SizeOf (T)); +} + + + int IsClassObject (const Type* T) /* Return true if this is a fully described object type */ { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e36d7c82e..c60023944 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -313,6 +313,9 @@ TypeCode GetUnderlyingTypeCode (const Type* Type); ** Return TCode if it is not scalar. */ +const Type* GetBitFieldChunkType (const Type* Type); +/* Get the type needed to operate on the byte chunk containing the bit-field */ + unsigned SizeOf (const Type* T); /* Compute size of object represented by type array. */ @@ -556,6 +559,9 @@ INLINE int IsTypeBitField (const Type* T) # define IsTypeBitField(T) (IsTypeSignedBitField (T) || IsTypeUnsignedBitField (T)) #endif +int IsTypeFragBitField (const Type* T); +/* Return true if this is a bit-field that shares byte space with other fields */ + #if defined(HAVE_INLINE) INLINE int IsTypeStruct (const Type* T) /* Return true if this is a struct type */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 7343702ea..3b3754665 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -398,7 +398,7 @@ static void DoInc (ExprDesc* Expr, unsigned KeepResult) Val = IsTypePtr (Expr->Type) ? CheckedSizeOf (Expr->Type + 1) : 1; /* Special treatment is needed for bit-fields */ - if (IsTypeBitField (Expr->Type)) { + if (IsTypeFragBitField (Expr->Type)) { DoIncDecBitField (Expr, Val, KeepResult); return; } @@ -485,7 +485,7 @@ static void DoDec (ExprDesc* Expr, unsigned KeepResult) Val = IsTypePtr (Expr->Type) ? CheckedSizeOf (Expr->Type + 1) : 1; /* Special treatment is needed for bit-fields */ - if (IsTypeBitField (Expr->Type)) { + if (IsTypeFragBitField (Expr->Type)) { DoIncDecBitField (Expr, -Val, KeepResult); return; } diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index a742087b7..4b7f8e279 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -110,6 +110,8 @@ static void LoadAddress (unsigned Flags, ExprDesc* Expr) void LoadExpr (unsigned Flags, struct ExprDesc* Expr) /* Load an expression into the primary register if it is not already there. +** If Flags contains any CF_TYPEMASK bits, it then overrides the codegen type +** info that would be otherwise taken from the expression type. ** Note: This function can't modify the content in Expr since there are many ** instances of the "GetCodePos + LoadExpr (maybe indirectly) + RemoveCode" ** code pattern here and there which assumes that Expr should be unchanged, @@ -125,32 +127,24 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) int AdjustBitField = 0; unsigned BitFieldFullWidthFlags = 0; if ((Flags & CF_TYPEMASK) == 0) { - if (IsTypeBitField (Expr->Type)) { - unsigned EndBit = Expr->Type->A.B.Offs + Expr->Type->A.B.Width; - AdjustBitField = Expr->Type->A.B.Offs != 0 || (EndBit != CHAR_BITS && EndBit != INT_BITS); - - /* TODO: This probably needs to be guarded by AdjustBitField when long bit-fields are - ** supported. - */ - Flags |= (EndBit <= CHAR_BITS) ? CF_CHAR : CF_INT; - if (IsSignUnsigned (Expr->Type)) { - Flags |= CF_UNSIGNED; - } + if (IsTypeFragBitField (Expr->Type)) { + /* We need to adjust the bits in this case. */ + AdjustBitField = 1; /* Flags we need operate on the whole bit-field, without CF_FORCECHAR. */ - BitFieldFullWidthFlags = Flags; + BitFieldFullWidthFlags = Flags | TypeOf (Expr->Type); + + /* Flags we need operate on the whole chunk containing the bit-field. */ + Flags |= TypeOf (GetBitFieldChunkType (Expr->Type)); /* If we're adjusting, then only load a char (not an int) and do only char ops; - ** We will clear the high byte in the adjustment. CF_FORCECHAR does nothing if the - ** type is not CF_CHAR. + ** We will clear the high byte in the adjustment. CF_FORCECHAR does nothing if + ** the type is not CF_CHAR; + ** If adjusting, then we're sign extending manually, so do everything unsigned + ** to make shifts faster. */ - if (AdjustBitField) { - /* If adjusting, then we're sign extending manually, so do everything unsigned - ** to make shifts faster. - */ - Flags |= CF_UNSIGNED | CF_FORCECHAR; - BitFieldFullWidthFlags |= CF_UNSIGNED; - } + Flags |= CF_UNSIGNED | CF_FORCECHAR; + BitFieldFullWidthFlags |= CF_UNSIGNED; } else { /* If Expr is an incomplete ESY type, bail out */ if (IsIncompleteESUType (Expr->Type)) { diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index c9e70e1f6..90862e33a 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -55,7 +55,10 @@ struct ExprDesc; void LoadExpr (unsigned Flags, struct ExprDesc* Expr); -/* Load an expression into the primary register if it is not already there. */ +/* Load an expression into the primary register if it is not already there. +** If Flags contains any CF_TYPEMASK bits, it then overrides the codegen type +** info that would be otherwise taken from the expression type. +*/ From 970607cde5c0afc96fd8af35b4fdf27173a2a986 Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 5 Dec 2021 12:21:01 +0800 Subject: [PATCH 017/355] Optimized g_testbitfield() and g_extractbitfield() with enhanced support for long bit-fields. --- src/cc65/codegen.c | 295 ++++++++++++++++++++++++++++++++++----------- src/cc65/codegen.h | 4 +- 2 files changed, 229 insertions(+), 70 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 5bfc6696b..c79863d0e 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -43,6 +43,7 @@ #include "addrsize.h" #include "check.h" #include "cpu.h" +#include "shift.h" #include "strbuf.h" #include "xmalloc.h" #include "xsprintf.h" @@ -4560,110 +4561,268 @@ void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size) void g_testbitfield (unsigned Flags, unsigned BitOffs, unsigned BitWidth) -/* Test bit-field in ax. */ +/* Test bit-field in primary. */ { - unsigned EndBit = BitOffs + BitWidth; + /* Since the end is inclusive and cannot be negative here, we subtract 1 from the sum */ + unsigned MSBit = BitOffs + BitWidth - 1U; + unsigned Bytes = MSBit / CHAR_BITS + 1U - BitOffs / CHAR_BITS; + unsigned HeadMask = (0xFF << (BitOffs % CHAR_BITS)) & 0xFF; + unsigned TailMask = ((1U << (MSBit % CHAR_BITS + 1U)) - 1U) & 0xFF; + unsigned UntestedBytes = ((1U << Bytes) - 1U) << (BitOffs / CHAR_BITS); + + /* We don't use these flags for now. Could CF_NOKEEP be potentially interesting? */ + Flags &= ~CF_STYPEMASK; /* If we need to do a test, then we avoid shifting (ASR only shifts one bit at a time, - ** so is slow) and just AND with the appropriate mask, then test the result of that. + ** so is slow) and just AND the head and tail bytes with the appropriate mask, then + ** OR the results with the rest bytes. */ - - /* Avoid overly large shift on host platform. */ - if (EndBit == sizeof (unsigned long) * CHAR_BIT) { - g_and (Flags | CF_CONST, (~0UL << BitOffs)); - } else { - g_and (Flags | CF_CONST, ((1UL << EndBit) - 1) & (~0UL << BitOffs)); + if (Bytes == 1) { + HeadMask = TailMask = HeadMask & TailMask; } - /* TODO: When long bit-fields are supported, an optimization to test only 3 bytes when - ** EndBit <= 24 is possible. - */ - g_test (Flags | CF_CONST); + /* Get the head byte */ + switch (BitOffs / CHAR_BITS) { + case 0: + if (HeadMask == 0xFF && Bytes == 1) { + AddCodeLine ("tax"); + UntestedBytes &= ~0x1; + } + break; + case 1: + if (HeadMask != 0xFF || TailMask == 0xFF) { + AddCodeLine ("txa"); + UntestedBytes &= ~0x2; + } + break; + case 2: + if (HeadMask != 0xFF || TailMask == 0xFF) { + AddCodeLine ("lda sreg"); + UntestedBytes &= ~0x4; + } + break; + case 3: + /* In this case we'd have HeadMask == TailMask and only 1 byte, but anyways... */ + if (HeadMask != 0xFF || TailMask == 0xFF) { + AddCodeLine ("lda sreg+1"); + UntestedBytes &= ~0x8; + } + break; + default: + break; + } + + /* Keep in mind that the head is NOT always "Byte 0" */ + if (HeadMask != 0xFF) { + AddCodeLine ("and #$%02X", HeadMask); + /* Abuse the "Byte 0" flag so that this head content will be saved by the routine */ + UntestedBytes |= 0x1; + } + + /* If there is only 1 byte to test, we have done with it */ + if (Bytes == 1) { + return; + } + + /* Handle the tail byte */ + if (TailMask != 0xFF) { + /* If we have to do any more masking operation, register A will be used for that, + ** and its current content in it must be saved. + */ + if (UntestedBytes & 0x1) { + AddCodeLine ("sta tmp1"); + } + + /* Test the tail byte */ + switch (MSBit / CHAR_BITS) { + case 1: + AddCodeLine ("txa"); + UntestedBytes &= ~0x2; + break; + case 2: + AddCodeLine ("lda sreg"); + UntestedBytes &= ~0x4; + break; + case 3: + AddCodeLine ("lda sreg+1"); + UntestedBytes &= ~0x8; + break; + default: + break; + } + AddCodeLine ("and #$%02X", TailMask); + + if (UntestedBytes & 0x1) { + AddCodeLine ("ora tmp1"); + } + } + + /* OR the rest bytes together, which could never need masking */ + if (UntestedBytes & 0x2) { + AddCodeLine ("stx tmp1"); + AddCodeLine ("ora tmp1"); + } + if (UntestedBytes & 0x4) { + AddCodeLine ("ora sreg"); + } + if (UntestedBytes & 0x8) { + AddCodeLine ("ora sreg+1"); + } } void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, unsigned BitOffs, unsigned BitWidth) -/* Extract bits from bit-field in ax. */ +/* Extract bits from bit-field in primary. */ { unsigned EndBit = BitOffs + BitWidth; + unsigned long ZeroExtendMask = 0; /* Zero if we don't need to zero-extend. */ /* Shift right by the bit offset; no code is emitted if BitOffs is zero */ g_asr (Flags | CF_CONST, BitOffs); - /* Since we have now shifted down, we could do char ops when the width fits in a char, but we - ** also need to clear (or set) the high byte since we've been using CF_FORCECHAR up to now. - */ - unsigned Mask = (1U << BitWidth) - 1; - /* To zero-extend, we will and by the width if the field doesn't end on a char or ** int boundary. If it does end on a boundary, then zeros will have already been shifted in, ** but we need to clear the high byte for char. g_and emits no code if the mask is all ones. ** This is here so the signed and unsigned branches can use it. */ - unsigned ZeroExtendMask = 0; /* Zero if we don't need to zero-extend. */ if (EndBit == CHAR_BITS) { /* We need to clear the high byte, since CF_FORCECHAR was set. */ ZeroExtendMask = 0xFF; - } else if (EndBit != INT_BITS) { - ZeroExtendMask = (1U << BitWidth) - 1; + } else if (EndBit != INT_BITS && EndBit != LONG_BITS) { + ZeroExtendMask = shl_l (1UL, BitWidth) - 1UL; } /* Handle signed bit-fields. */ if (IsSigned) { - /* Save .A because the sign-bit test will destroy it. */ - AddCodeLine ("tay"); - - /* Check sign bit */ unsigned SignBitPos = BitWidth - 1U; unsigned SignBitByte = SignBitPos / CHAR_BITS; unsigned SignBitPosInByte = SignBitPos % CHAR_BITS; - unsigned SignBitMask = 1U << SignBitPosInByte; - /* Move the correct byte to .A. This can be only .X for now, - ** but more cases will be needed to support long. - */ - switch (SignBitByte) { - case 0: - break; - case 1: - AddCodeLine ("txa"); - break; - default: - FAIL ("Invalid Byte for sign bit"); - } - - /* Test the sign bit */ - AddCodeLine ("and #$%02X", SignBitMask); - unsigned ZeroExtendLabel = GetLocalLabel (); - AddCodeLine ("beq %s", LocalLabelName (ZeroExtendLabel)); - - /* Get back .A and sign-extend if required; operating on the full result needs - ** to sign-extend into the high byte, too. - */ - AddCodeLine ("tya"); - g_or (FullWidthFlags | CF_CONST, ~Mask); - - /* We can generate a branch, instead of a jump, here because we know - ** that only a few instructions will be put between here and where - ** DoneLabel will be defined. - */ - unsigned DoneLabel = GetLocalLabel (); - g_branch (DoneLabel); - - /* Get back .A, then zero-extend. We need to duplicate the TYA, rather than move it before - ** the branch to share with the other label, because TYA changes some condition codes. - */ - g_defcodelabel (ZeroExtendLabel); - AddCodeLine ("tya"); - - /* Zero the upper bits, the same as the unsigned path. */ if (ZeroExtendMask != 0) { - g_and (FullWidthFlags | CF_CONST, ZeroExtendMask); - } + /* The universal trick is: + ** x = bits & bit_mask + ** m = 1 << (bit_width - 1) + ** r = (x ^ m) - m + ** which works for long as well. + */ - g_defcodelabel (DoneLabel); + if (SignBitByte + 1U == sizeofarg (FullWidthFlags)) { + /* We can just sign-extend on the high byte if it is the only affected one */ + unsigned char SignBitMask = (1UL << SignBitPosInByte) & 0xFF; + unsigned char Mask = ((2UL << (SignBitPos % CHAR_BITS)) - 1UL) & 0xFF; + + /* Move the correct byte to .A */ + switch (SignBitByte) { + case 0: + break; + case 1: + AddCodeLine ("tay"); + AddCodeLine ("txa"); + break; + case 3: + AddCodeLine ("tay"); + AddCodeLine ("lda sreg+1"); + break; + default: + FAIL ("Invalid Byte for sign bit"); + } + + /* Use .A to do the ops on the correct byte */ + AddCodeLine ("and #$%02X", Mask); + AddCodeLine ("eor #$%02X", SignBitMask); + AddCodeLine ("sec"); + AddCodeLine ("sbc #$%02X", SignBitMask); + + /* Move the correct byte from .A */ + switch (SignBitByte) { + case 0: + break; + case 1: + AddCodeLine ("tax"); + AddCodeLine ("tya"); + break; + case 3: + AddCodeLine ("sta sreg+1"); + AddCodeLine ("tya"); + break; + default: + FAIL ("Invalid Byte for sign bit"); + } + } else { + unsigned long SignBitMask = 1UL << SignBitPos; + unsigned long Mask = (2UL << SignBitPos) - 1UL; + g_and (FullWidthFlags | CF_CONST, Mask); + g_xor (FullWidthFlags | CF_CONST, SignBitMask); + g_dec (FullWidthFlags | CF_CONST, SignBitMask); + } + } else { + unsigned char SignBitMask = (1UL << SignBitPosInByte) & 0xFF; + unsigned ZeroExtendLabel = GetLocalLabel (); + + /* Save .A because the sign-bit test will destroy it. */ + AddCodeLine ("tay"); + + /* Move the correct byte to .A */ + switch (SignBitByte) { + case 0: + break; + case 1: + AddCodeLine ("txa"); + break; + case 3: + AddCodeLine ("lda sreg+1"); + break; + default: + FAIL ("Invalid Byte for sign bit"); + } + + /* Test the sign bit */ + AddCodeLine ("and #$%02X", SignBitMask); + AddCodeLine ("beq %s", LocalLabelName (ZeroExtendLabel)); + + if (SignBitByte + 1U == sizeofarg (FullWidthFlags)) { + /* We can just sign-extend on the high byte if it is the only affected one */ + unsigned char Mask = ~((2UL << (SignBitPos % CHAR_BITS)) - 1UL) & 0xFF; + + /* Use .A to do the ops on the correct byte */ + switch (SignBitByte) { + case 0: + AddCodeLine ("tya"); + AddCodeLine ("ora #$%02X", Mask); + /* We could jump over the following tya instead, but that wouldn't be faster + ** than taking this extra tay and then the tya. + */ + AddCodeLine ("tay"); + break; + case 1: + AddCodeLine ("txa"); + AddCodeLine ("ora #$%02X", Mask); + AddCodeLine ("tax"); + break; + case 3: + AddCodeLine ("lda sreg+1"); + AddCodeLine ("ora #$%02X", Mask); + AddCodeLine ("sta sreg+1"); + break; + default: + FAIL ("Invalid Byte for sign bit"); + } + } else { + /* Since we are going to get back .A later anyways, we may just do the op on the + ** higher bytes with whatever content currently in it. + */ + unsigned long Mask = ~((2UL << SignBitPos) - 1UL); + g_or (FullWidthFlags | CF_CONST, Mask); + } + + /* Get back .A. We need to duplicate the TYA, rather than move it before + ** the branch to share with the other label, because TYA changes some condition codes. + */ + g_defcodelabel (ZeroExtendLabel); + AddCodeLine ("tya"); + } } else { /* Unsigned bit-field, needs only zero-extension. */ if (ZeroExtendMask != 0) { diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index 1de71e7d3..cb62d78bd 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -486,11 +486,11 @@ void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size); /*****************************************************************************/ void g_testbitfield (unsigned Flags, unsigned BitOffs, unsigned BitWidth); -/* Test bit-field in ax. */ +/* Test bit-field in primary. */ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, unsigned BitOffs, unsigned BitWidth); -/* Extract bits from bit-field in ax. */ +/* Extract bits from bit-field in primary. */ /*****************************************************************************/ /* Switch statement */ From b35a9d97a6953cb13a7215c369ff3b66ef440287 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Sun, 12 Dec 2021 23:41:19 +0100 Subject: [PATCH 018/355] Updated URL and improved consistency. --- doc/apple2.sgml | 4 ++-- doc/apple2enh.sgml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index bd01b68dc..cf83dacc9 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -33,7 +33,7 @@ more information. The standard binary file format generated by the linker for the Apple ][ target is an file. +url="https://nulib.com/library/AppleSingle_AppleDouble.pdf"> file. The default load address is $803. , but uses the heap either explicitly or implicitly (i.e. by loading a driver) then -the memory from $800 to $2000 can be added to the heap by calling +the memory from $800 to $1FFF can be added to the heap by calling file. +url="https://nulib.com/library/AppleSingle_AppleDouble.pdf"> file. The default load address is $803. , but uses the heap either explicitly or implicitly (i.e. by loading a driver) then -the memory from $800 to $2000 can be added to the heap by calling +the memory from $800 to $1FFF can be added to the heap by calling Date: Sun, 12 Dec 2021 12:27:55 -0500 Subject: [PATCH 019/355] Changed a big script into separate named steps. It makes the job log easier to navigate. Also, Pull Requests don't need a Zip file. --- .github/workflows/build-on-pull-request.yml | 37 ++++++++------ .github/workflows/snapshot-on-push-master.yml | 48 ++++++++++++------- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 53f79fef4..da9216a3d 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -1,6 +1,6 @@ name: Build Pull Request on: [pull_request] -concurrency: +concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -8,11 +8,11 @@ jobs: build_linux: name: Build and Test (Linux) runs-on: ubuntu-latest - + steps: - shell: bash run: git config --global core.autocrlf input - + - name: Checkout Source uses: actions/checkout@v2 @@ -21,28 +21,35 @@ jobs: run: | sudo apt-get update sudo apt-get install linuxdoc-tools linuxdoc-tools-info binutils-mingw-w64-i686 gcc-mingw-w64-i686 sshpass - - - name: Build - id: build + + - name: Build the tools. shell: bash + run: make -j2 bin USER_CFLAGS=-Werror + - name: Build the platform libraries. + shell: bash + run: make -j2 lib QUIET=1 + - name: Run the regression tests. + shell: bash + run: make test QUIET=1 + - name: Test that the samples can be built. + shell: bash + run: make -j2 samples + - name: Build the document files. + shell: bash + run: make -j2 doc + - name: Build 32-bit Windows versions of the tools. run: | - make -j2 bin USER_CFLAGS=-Werror - make -j2 lib QUIET=1 - make test QUIET=1 - make -j2 samples make -C src clean make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- - make -C samples clean - make -j2 doc zip build_windows: name: Build (Windows) runs-on: windows-latest - + steps: - shell: bash run: git config --global core.autocrlf input - + - name: Checkout Source uses: actions/checkout@v2 @@ -51,6 +58,6 @@ jobs: - name: Build app (debug) run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug - + - name: Build app (release) run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index aefc7f2f5..e10904357 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -1,9 +1,9 @@ -name: Snapshot Build +name: Snapshot Build on: push: branches: master -concurrency: +concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -11,11 +11,11 @@ jobs: build_windows: name: Build (Windows) runs-on: windows-latest - + steps: - shell: bash run: git config --global core.autocrlf input - + - name: Checkout Source uses: actions/checkout@v2 @@ -24,7 +24,7 @@ jobs: - name: Build app (debug) run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug - + - name: Build app (release) run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release @@ -32,11 +32,11 @@ jobs: name: Build, Test and Snaphot (Linux) runs-on: ubuntu-latest needs: build_windows - + steps: - shell: bash run: git config --global core.autocrlf input - + - name: Checkout Source uses: actions/checkout@v2 @@ -45,25 +45,37 @@ jobs: run: | sudo apt-get update sudo apt-get install linuxdoc-tools linuxdoc-tools-info binutils-mingw-w64-i686 gcc-mingw-w64-i686 sshpass - - - name: Build - id: build + + - name: Build the tools. shell: bash + run: make -j2 bin USER_CFLAGS=-Werror + - name: Build the platform libraries. + shell: bash + run: make -j2 lib QUIET=1 + - name: Run the regression tests. + shell: bash + run: make test QUIET=1 + - name: Test that the samples can be built. + shell: bash + run: make -j2 samples + - name: Remove the output from the samples tests. + shell: bash + run: make -C samples clean + - name: Build the document files. + shell: bash + run: make -j2 doc + - name: Build and package 32-bit Windows versions of the tools. run: | - make -j2 bin USER_CFLAGS=-Werror - make -j2 lib QUIET=1 - make test QUIET=1 - make -j2 samples make -C src clean make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- - make -C samples clean - make -j2 doc zip - + make zip + mv cc65.zip cc65-win32.zip + - name: Upload Snapshot Zip uses: actions/upload-artifact@v2 with: name: cc65-snapshot-win32.zip - path: cc65.zip + path: cc65-win32.zip # TODO: Update docs at https://github.com/cc65/doc # TODO: Publish snapshot zip at https://github.com/cc65/cc65.github.io From 33cf8608b752c810d39141bb73373fea7647aeec Mon Sep 17 00:00:00 2001 From: Greg King Date: Sun, 12 Dec 2021 12:35:27 -0500 Subject: [PATCH 020/355] Removed unneeded package names. sshpass isn't needed because the Windows packages are put on Github. linuxdoc-tools is a dependency of linuxdoc-tools-info. The binutils package is a dependency of the gcc package. --- .github/workflows/build-on-pull-request.yml | 2 +- .github/workflows/snapshot-on-push-master.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index da9216a3d..c3214c308 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -20,7 +20,7 @@ jobs: shell: bash run: | sudo apt-get update - sudo apt-get install linuxdoc-tools linuxdoc-tools-info binutils-mingw-w64-i686 gcc-mingw-w64-i686 sshpass + sudo apt-get install linuxdoc-tools-info gcc-mingw-w64-i686 - name: Build the tools. shell: bash diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index e10904357..3f138e492 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -44,7 +44,7 @@ jobs: shell: bash run: | sudo apt-get update - sudo apt-get install linuxdoc-tools linuxdoc-tools-info binutils-mingw-w64-i686 gcc-mingw-w64-i686 sshpass + sudo apt-get install linuxdoc-tools-info gcc-mingw-w64-i686 - name: Build the tools. shell: bash From 366701e066b17bda85320f8e311f71a8dfad2834 Mon Sep 17 00:00:00 2001 From: Greg King Date: Sun, 12 Dec 2021 13:42:25 -0500 Subject: [PATCH 021/355] Added a 64-bit Windows cross-compile. That compiler catches pointer-integer width mismatches that other compilers ignore. --- .github/workflows/build-on-pull-request.yml | 6 +++--- .github/workflows/snapshot-on-push-master.yml | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index c3214c308..fe99c4673 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -20,7 +20,7 @@ jobs: shell: bash run: | sudo apt-get update - sudo apt-get install linuxdoc-tools-info gcc-mingw-w64-i686 + sudo apt-get install linuxdoc-tools-info gcc-mingw-w64-x86-64 - name: Build the tools. shell: bash @@ -37,10 +37,10 @@ jobs: - name: Build the document files. shell: bash run: make -j2 doc - - name: Build 32-bit Windows versions of the tools. + - name: Build 64-bit Windows versions of the tools. run: | make -C src clean - make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- + make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=x86_64-w64-mingw32- build_windows: name: Build (Windows) diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index 3f138e492..c8d36488d 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -44,7 +44,7 @@ jobs: shell: bash run: | sudo apt-get update - sudo apt-get install linuxdoc-tools-info gcc-mingw-w64-i686 + sudo apt-get install linuxdoc-tools-info gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 - name: Build the tools. shell: bash @@ -64,6 +64,12 @@ jobs: - name: Build the document files. shell: bash run: make -j2 doc + - name: Build and package 64-bit Windows versions of the tools. + run: | + make -C src clean + make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=x86_64-w64-mingw32- + make zip + mv cc65.zip cc65-win64.zip - name: Build and package 32-bit Windows versions of the tools. run: | make -C src clean @@ -71,11 +77,16 @@ jobs: make zip mv cc65.zip cc65-win32.zip - - name: Upload Snapshot Zip + - name: Upload a 32-bit Snapshot Zip uses: actions/upload-artifact@v2 with: name: cc65-snapshot-win32.zip path: cc65-win32.zip + - name: Upload a 64-bit Snapshot Zip + uses: actions/upload-artifact@v2 + with: + name: cc65-snapshot-win64.zip + path: cc65-win64.zip # TODO: Update docs at https://github.com/cc65/doc # TODO: Publish snapshot zip at https://github.com/cc65/cc65.github.io From 325ff9667e924dd80acb24983791d7aa24cd2dad Mon Sep 17 00:00:00 2001 From: Greg King Date: Sun, 12 Dec 2021 17:36:03 -0500 Subject: [PATCH 022/355] Used (size_t), instead of (long) where converting between pointers and integers. (long) still is 32 bits on 64-bit Windows! --- src/cc65/locals.c | 2 +- src/cc65/symentry.h | 2 +- src/cc65/symtab.c | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cc65/locals.c b/src/cc65/locals.c index c2e314485..d3902f329 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -286,7 +286,7 @@ static void ParseAutoDecl (Declaration* Decl) ** We abuse the Collection somewhat by using it to store line ** numbers. */ - CollReplace (&CurrentFunc->LocalsBlockStack, (void *)(long)GetCurrentLine (), + CollReplace (&CurrentFunc->LocalsBlockStack, (void *)(size_t)GetCurrentLine (), CollCount (&CurrentFunc->LocalsBlockStack) - 1); } else { diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index bb87c7472..bcf586510 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -115,7 +115,7 @@ struct CodeEntry; typedef struct DefOrRef DefOrRef; struct DefOrRef { unsigned Line; - long LocalsBlockId; + size_t LocalsBlockId; unsigned Flags; int StackPtr; unsigned Depth; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 5d7bd1436..3de0bb460 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -951,7 +951,7 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) DOR = xmalloc (sizeof (DefOrRef)); CollAppend (E->V.L.DefsOrRefs, DOR); DOR->Line = GetCurrentLine (); - DOR->LocalsBlockId = (long)CollLast (&CurrentFunc->LocalsBlockStack); + DOR->LocalsBlockId = (size_t)CollLast (&CurrentFunc->LocalsBlockStack); DOR->Flags = Flags; DOR->StackPtr = StackPtr; DOR->Depth = CollCount (&CurrentFunc->LocalsBlockStack); @@ -1013,9 +1013,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Are we jumping into a block with initalization of an object that ** has automatic storage duration? Let's emit a warning. */ - if ((long)CollLast (AIC) != DOR->LocalsBlockId && + if ((size_t)CollLast (AIC) != DOR->LocalsBlockId && (CollCount (AIC) < DOR->Depth || - (long)CollAt (AIC, DOR->Depth - 1) != DOR->LocalsBlockId)) { + (size_t)CollAt (AIC, DOR->Depth - 1) != DOR->LocalsBlockId)) { Warning ("Goto at line %d to label %s jumps into a block with " "initialization of an object that has automatic storage duration", GetCurrentLine (), Name); @@ -1044,9 +1044,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Are we jumping into a block with initalization of an object that ** has automatic storage duration? Let's emit a warning. */ - if ((long)CollLast (AIC) != DOR->LocalsBlockId && + if ((size_t)CollLast (AIC) != DOR->LocalsBlockId && (CollCount (AIC) >= DOR->Depth || - (long)CollLast (AIC) >= (long)DOR->Line)) + (size_t)CollLast (AIC) >= (size_t)DOR->Line)) Warning ("Goto at line %d to label %s jumps into a block with " "initialization of an object that has automatic storage duration", DOR->Line, Name); From 230f4d3807a99c6037c73ac7a5cd7e5c8deb8766 Mon Sep 17 00:00:00 2001 From: Greg King Date: Sun, 12 Dec 2021 23:54:17 -0500 Subject: [PATCH 023/355] Install system packages before checking out the repo. --- .github/workflows/build-on-pull-request.yml | 11 +++++------ .github/workflows/snapshot-on-push-master.yml | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index fe99c4673..f5477d191 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -10,18 +10,17 @@ jobs: runs-on: ubuntu-latest steps: - - shell: bash - run: git config --global core.autocrlf input - - - name: Checkout Source - uses: actions/checkout@v2 - - name: Install Dependencies shell: bash run: | sudo apt-get update sudo apt-get install linuxdoc-tools-info gcc-mingw-w64-x86-64 + - shell: bash + run: git config --global core.autocrlf input + - name: Checkout Source + uses: actions/checkout@v2 + - name: Build the tools. shell: bash run: make -j2 bin USER_CFLAGS=-Werror diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index c8d36488d..110edbbf0 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -34,18 +34,17 @@ jobs: needs: build_windows steps: - - shell: bash - run: git config --global core.autocrlf input - - - name: Checkout Source - uses: actions/checkout@v2 - - name: Install Dependencies shell: bash run: | sudo apt-get update sudo apt-get install linuxdoc-tools-info gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 + - shell: bash + run: git config --global core.autocrlf input + - name: Checkout Source + uses: actions/checkout@v2 + - name: Build the tools. shell: bash run: make -j2 bin USER_CFLAGS=-Werror From 9e9b3dbacad05c1ee39e8246ba7f0cacfc43e4f6 Mon Sep 17 00:00:00 2001 From: polluks2 <74630735+polluks2@users.noreply.github.com> Date: Mon, 13 Dec 2021 17:14:57 +0100 Subject: [PATCH 024/355] Fixed typo --- src/ld65/scanner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c index 256d47f07..718951aa5 100644 --- a/src/ld65/scanner.c +++ b/src/ld65/scanner.c @@ -196,7 +196,7 @@ static void StrVal (void) default: CfgWarning (&CfgErrorPos, - "Unkown escape sequence '%%%c'", C); + "Unknown escape sequence '%%%c'", C); SB_AppendChar (&CfgSVal, '%'); SB_AppendChar (&CfgSVal, C); NextChar (); From 1d3318c2476b99c76a7990fe8ec23438a116c6da Mon Sep 17 00:00:00 2001 From: polluks2 <74630735+polluks2@users.noreply.github.com> Date: Mon, 13 Dec 2021 17:20:56 +0100 Subject: [PATCH 025/355] Fixed many typos --- src/dbginfo/dbginfo.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dbginfo/dbginfo.c b/src/dbginfo/dbginfo.c index 42001ed07..fdebe6910 100644 --- a/src/dbginfo/dbginfo.c +++ b/src/dbginfo/dbginfo.c @@ -183,7 +183,7 @@ typedef struct DbgInfo DbgInfo; struct DbgInfo { /* First we have all items in collections sorted by id. The ids are - ** continous, so an access by id is almost as cheap as an array access. + ** continuous, so an access by id is almost as cheap as an array access. ** The collections are also used when the objects are deleted, so they're ** actually the ones that "own" the items. */ @@ -680,7 +680,7 @@ static char* SB_StrDup (const StrBuf* B) static Collection* CollInit (Collection* C) /* Initialize a collection and return it. */ { - /* Intialize the fields. */ + /* Initialize the fields. */ C->Count = 0; C->Size = 0; C->Items = 0; @@ -1349,7 +1349,7 @@ static int CompareFileInfoByName (const void* L, const void* R) static LibInfo* NewLibInfo (const StrBuf* Name) -/* Create a new LibInfo struct, intialize and return it */ +/* Create a new LibInfo struct, initialize and return it */ { /* Allocate memory */ LibInfo* L = xmalloc (sizeof (LibInfo) + SB_GetLen (Name)); @@ -1463,7 +1463,7 @@ static int CompareLineInfoByLine (const void* L, const void* R) static ModInfo* NewModInfo (const StrBuf* Name) -/* Create a new ModInfo struct, intialize and return it */ +/* Create a new ModInfo struct, initialize and return it */ { /* Allocate memory */ ModInfo* M = xmalloc (sizeof (ModInfo) + SB_GetLen (Name)); @@ -1536,7 +1536,7 @@ static int CompareModInfoByName (const void* L, const void* R) static ScopeInfo* NewScopeInfo (const StrBuf* Name) -/* Create a new ScopeInfo struct, intialize and return it */ +/* Create a new ScopeInfo struct, initialize and return it */ { /* Allocate memory */ ScopeInfo* S = xmalloc (sizeof (ScopeInfo) + SB_GetLen (Name)); @@ -1697,7 +1697,7 @@ static int CompareSegInfoByName (const void* L, const void* R) static SpanInfo* NewSpanInfo (void) -/* Create a new SpanInfo struct, intialize and return it */ +/* Create a new SpanInfo struct, initialize and return it */ { /* Allocate memory */ SpanInfo* S = xmalloc (sizeof (SpanInfo)); @@ -1779,7 +1779,7 @@ static int CompareSpanInfoByAddr (const void* L, const void* R) static SymInfo* NewSymInfo (const StrBuf* Name) -/* Create a new SymInfo struct, intialize and return it */ +/* Create a new SymInfo struct, initialize and return it */ { /* Allocate memory */ SymInfo* S = xmalloc (sizeof (SymInfo) + SB_GetLen (Name)); @@ -2147,7 +2147,7 @@ static TypeInfo* ParseTypeString (InputData* D, StrBuf* Type) I += GT_GET_SIZE (A[I]) + 1; } else { /* Unknown type in type string */ - ParseError (D, CC65_ERROR, "Unkown type in type value"); + ParseError (D, CC65_ERROR, "Unknown type in type value"); return 0; } break; @@ -2733,7 +2733,7 @@ static int StrConstFollows (InputData* D) static int Consume (InputData* D, Token Tok, const char* Name) -/* Check for a token and consume it. Return true if the token was comsumed, +/* Check for a token and consume it. Return true if the token was consumed, ** return false otherwise. */ { @@ -6936,7 +6936,7 @@ const cc65_scopeinfo* cc65_scope_byspan (cc65_dbginfo Handle, unsigned SpanId) const cc65_scopeinfo* cc65_childscopes_byid (cc65_dbginfo Handle, unsigned Id) /* Return the direct child scopes of a scope with a given id. The function ** returns NULL if no scope with this id was found, otherwise a list of the -** direct childs. +** direct children. */ { const DbgInfo* Info; From 1cdd4676b25762f4257287a389349c68960905d0 Mon Sep 17 00:00:00 2001 From: polluks2 Date: Tue, 14 Dec 2021 13:13:16 +0100 Subject: [PATCH 026/355] Fixed many typos --- doc/apple2.sgml | 2 +- doc/apple2enh.sgml | 2 +- doc/atari.sgml | 12 ++++++------ doc/atari5200.sgml | 2 +- doc/ca65.sgml | 2 +- doc/cc65.sgml | 6 +++--- doc/cl65.sgml | 4 ++-- doc/co65.sgml | 4 ++-- doc/coding.sgml | 2 +- doc/da65.sgml | 2 +- doc/debugging.sgml | 6 +++--- doc/geos.sgml | 4 ++-- doc/grc65.sgml | 6 +++--- doc/intro.sgml | 2 +- doc/ld65.sgml | 2 +- doc/smc.sgml | 4 ++-- 16 files changed, 31 insertions(+), 31 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index cf83dacc9..09052ade1 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -73,7 +73,7 @@ system takes care of actually moving the code into the Language Card. The amount of memory available in the Language Card for generated code depends on the parameters. There are -several usefull settings: +several useful settings: diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 8b61df91c..a105cb47a 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -73,7 +73,7 @@ system takes care of actually moving the code into the Language Card. The amount of memory available in the Language Card for generated code depends on the parameters. There are -several usefull settings: +several useful settings: diff --git a/doc/atari.sgml b/doc/atari.sgml index 903895d17..85dcaaf5e 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -131,7 +131,7 @@ With the default load address of $2400 this gives a usable memory range o [$2400-$CFFF]. Please note that the first load chunk (which checks the system -compatibilty and available memory) will always be loaded at +compatibility and available memory) will always be loaded at $2E00, regardless of the specified start address. This address can only be changed by a custom linker config file. @@ -305,7 +305,7 @@ The names are the usual ones you can find in system reference manuals. Example: ... -Please note that memory location 762/$2FA is called " -Please inspect the The old "HEADER" memory description contained six bytes: $FFFF -and the first and last memory addess of the program. For the "system -check" load chunk this had to be split into two memory assigments. The +and the first and last memory address of the program. For the "system +check" load chunk this had to be split into two memory assignments The "HEADER" now only contains the $FFFF. The main program's first and last memory address were moved to a new segment, called "MAINHDR", which in the new linker config file goes into its own memory area (also diff --git a/doc/atari5200.sgml b/doc/atari5200.sgml index c7e5be73e..599ffe3c9 100644 --- a/doc/atari5200.sgml +++ b/doc/atari5200.sgml @@ -237,7 +237,7 @@ The runtime library provides a default game name which is "cc65 compiled". To change that, one has to link a file which puts data into the " .export __CART_NAME__: absolute = 1 .macpack atari diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 8ae8eabd9..0638ab08c 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -301,7 +301,7 @@ Here is a description of all the command line options: compiler, see there for a list. Depending on the target, the default CPU type is also set. This can be - overriden by using the / option. + overridden by using the / option.