コード例 #1
0
ファイル: expr.c プロジェクト: AntiheroSoftware/cc65
void FreeExpr (ExprNode* Root)
/* Free the expression, Root is pointing to. */
{
    if (Root) {
        FreeExpr (Root->Left);
        FreeExpr (Root->Right);
        FreeExprNode (Root);
    }
}
コード例 #2
0
ファイル: objcode.c プロジェクト: eakmeister/cc65
void Emit1 (unsigned char OPC, ExprNode* Value)
/* Emit an instruction with an one byte argument */
{
    long V;
    Fragment* F;

    if (IsEasyConst (Value, &V)) {

        /* Must be in byte range */
        if (!IsByteRange (V)) {
            Error ("Range error (%ld not in [0..255])", V);
        }

        /* Create a literal fragment */
        F = GenFragment (FRAG_LITERAL, 2);
        F->V.Data[0] = OPC;
        F->V.Data[1] = (unsigned char) V;
        FreeExpr (Value);

    } else {

        /* Emit the opcode */
        Emit0 (OPC);

        /* Emit the argument as an expression */
        F = GenFragment (FRAG_EXPR, 1);
        F->V.Expr = Value;
    }
}
コード例 #3
0
ファイル: exports.c プロジェクト: Aliandrana/snesdev
void FreeExport (Export* E)
/* Free an export. NOTE: This won't remove the export from the exports table,
 * so it may only be called for unused exports (exports from modules that
 * aren't referenced).
 */
{
    /* Safety */
    PRECONDITION ((E->Flags & EXP_INLIST) == 0);

    /* Free the export expression */
    FreeExpr (E->Expr);

    /* Free the struct */
    xfree (E);
}
コード例 #4
0
ファイル: objcode.c プロジェクト: eakmeister/cc65
void Emit2 (unsigned char OPC, ExprNode* Value)
/* Emit an instruction with a two byte argument */
{
    long V;
    Fragment* F;

    if (IsEasyConst (Value, &V)) {

        /* Must be in byte range */
        if (!IsWordRange (V)) {
            Error ("Range error (%ld not in [0..65535])", V);
        }

        /* Create a literal fragment */
        F = GenFragment (FRAG_LITERAL, 3);
        F->V.Data[0] = OPC;
        F->V.Data[1] = (unsigned char) V;
        F->V.Data[2] = (unsigned char) (V >> 8);
        FreeExpr (Value);

    } else {
コード例 #5
0
ファイル: segment.c プロジェクト: eakmeister/cc65
void SegDone (void)
/* Check the segments for range and other errors. Do cleanup. */
{
    static const unsigned long U_Hi[4] = {
       	0x000000FFUL, 0x0000FFFFUL, 0x00FFFFFFUL, 0xFFFFFFFFUL
    };
    static const long S_Hi[4] = {
       	0x0000007FL, 0x00007FFFL, 0x007FFFFFL, 0x7FFFFFFFL
    };

    unsigned I;
    for (I = 0; I < CollCount (&SegmentList); ++I) {
        Segment* S = CollAtUnchecked (&SegmentList, I);
     	Fragment* F = S->Root;
     	while (F) {
       	    if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {

                /* We have an expression, study it */
                ExprDesc ED;
                ED_Init (&ED);
                StudyExpr (F->V.Expr, &ED);

                /* Check if the expression is constant */
                if (ED_IsConst (&ED)) {

     	       	    unsigned J;

       	       	    /* The expression is constant. Check for range errors. */
                    CHECK (F->Len <= 4);
                    if (F->Type == FRAG_SEXPR) {
                        long Hi = S_Hi[F->Len-1];
                        long Lo = ~Hi;
                        if (ED.Val > Hi || ED.Val < Lo) {
                            LIError (&F->LI,
                                     "Range error (%ld not in [%ld..%ld])",
                                     ED.Val, Lo, Hi);
                        }
                    } else {
                        if (((unsigned long)ED.Val) > U_Hi[F->Len-1]) {
                            LIError (&F->LI,
                                     "Range error (%lu not in [0..%lu])",
                                     (unsigned long)ED.Val, U_Hi[F->Len-1]);
                        }
                    }

                    /* We don't need the expression tree any longer */
                    FreeExpr (F->V.Expr);

     	     	    /* Convert the fragment into a literal fragment */
     	     	    for (J = 0; J < F->Len; ++J) {
     	     	       	F->V.Data[J] = ED.Val & 0xFF;
     	     	       	ED.Val >>= 8;
     	     	    }
     	     	    F->Type = FRAG_LITERAL;

      	     	} 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.
      	    	     */
                    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)) {
      	       	        LIError (&F->LI, "Range error");
      	     	    }
     	    	}

                /* Release memory allocated for the expression decriptor */
                ED_Done (&ED);
     	    }
コード例 #6
0
ファイル: condasm.c プロジェクト: MonteCarlos/cc65
void DoConditionals (void)
/* Catch all for conditional directives */
{
    IfDesc* D;

    do {

        switch (CurTok.Tok) {

            case TOK_ELSE:
                D = GetCurrentIf ();

                /* Allow an .ELSE */
                ElseClause (D, ".ELSE");

                /* Remember the data for the .ELSE */
                if (D) {
                    ReleaseFullLineInfo (&D->LineInfos);
                    GetFullLineInfo (&D->LineInfos);
                    D->Name = ".ELSE";
                }

                /* Calculate the new overall condition */
                CalcOverallIfCond ();

                /* Skip .ELSE */
                NextTok ();
                ExpectSep ();
                break;

            case TOK_ELSEIF:
                D = GetCurrentIf ();
                /* Handle as if there was an .ELSE first */
                ElseClause (D, ".ELSEIF");

                /* Calculate the new overall if condition */
                CalcOverallIfCond ();

                /* Allocate and prepare a new descriptor */
                D = AllocIf (".ELSEIF", 0);
                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...
                */
                if (IfCond) {
                    SetIfCond (D, ConstExpression ());
                    ExpectSep ();
                }

                /* Get the new overall condition */
                CalcOverallIfCond ();
                break;

            case TOK_ENDIF:
                /* We're done with this .IF.. - remove the descriptor(s) */
                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.
                */
                NextTok ();
                ExpectSep ();

                /* Get the new overall condition */
                CalcOverallIfCond ();
                break;

            case TOK_IF:
                D = AllocIf (".IF", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, ConstExpression ());
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFBLANK:
                D = AllocIf (".IFBLANK", 1);
                NextTok ();
                if (IfCond) {
                    if (TokIsSep (CurTok.Tok)) {
                        SetIfCond (D, 1);
                    } else {
                        SetIfCond (D, 0);
                        SkipUntilSep ();
                    }
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFCONST:
                D = AllocIf (".IFCONST", 1);
                NextTok ();
                if (IfCond) {
                    ExprNode* Expr = Expression();
                    SetIfCond (D, IsConstExpr (Expr, 0));
                    FreeExpr (Expr);
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFDEF:
                D = AllocIf (".IFDEF", 1);
                NextTok ();
                if (IfCond) {
                    SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
                    SetIfCond (D, Sym != 0 && SymIsDef (Sym));
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFNBLANK:
                D = AllocIf (".IFNBLANK", 1);
                NextTok ();
                if (IfCond) {
                    if (TokIsSep (CurTok.Tok)) {
                        SetIfCond (D, 0);
                    } else {
                        SetIfCond (D, 1);
                        SkipUntilSep ();
                    }
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFNCONST:
                D = AllocIf (".IFNCONST", 1);
                NextTok ();
                if (IfCond) {
                    ExprNode* Expr = Expression();
                    SetIfCond (D, !IsConstExpr (Expr, 0));
                    FreeExpr (Expr);
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFNDEF:
                D = AllocIf (".IFNDEF", 1);
                NextTok ();
                if (IfCond) {
                    SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
                    SetIfCond (D, Sym == 0 || !SymIsDef (Sym));
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFNREF:
                D = AllocIf (".IFNREF", 1);
                NextTok ();
                if (IfCond) {
                    SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
                    SetIfCond (D, Sym == 0 || !SymIsRef (Sym));
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFP02:
                D = AllocIf (".IFP02", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, GetCPU() == CPU_6502);
                }
                ExpectSep ();
                CalcOverallIfCond ();
                break;

            case TOK_IFP4510:
                D = AllocIf (".IFP4510", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, GetCPU() == CPU_4510);
                }
                ExpectSep ();
                CalcOverallIfCond ();
                break;

            case TOK_IFP816:
                D = AllocIf (".IFP816", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, GetCPU() == CPU_65816);
                }
                ExpectSep ();
                CalcOverallIfCond ();
                break;

            case TOK_IFPC02:
                D = AllocIf (".IFPC02", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, GetCPU() == CPU_65C02);
                }
                ExpectSep ();
                CalcOverallIfCond ();
                break;

            case TOK_IFPSC02:
                D = AllocIf (".IFPSC02", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, GetCPU() == CPU_65SC02);
                }
                ExpectSep ();
                CalcOverallIfCond ();
                break;

            case TOK_IFREF:
                D = AllocIf (".IFREF", 1);
                NextTok ();
                if (IfCond) {
                    SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
                    SetIfCond (D, Sym != 0 && SymIsRef (Sym));
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            default:
                /* Skip tokens */
                NextTok ();

        }

    } while (IfCond == 0 && CurTok.Tok != TOK_EOF);
}
コード例 #7
0
ファイル: symentry.c プロジェクト: Aliandrana/cc65
void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags)
/* Define a new symbol */
{
    if (S->Flags & SF_IMPORT) {
        /* Defined symbol is marked as imported external symbol */
        Error ("Symbol `%m%p' is already an import", GetSymName (S));
        return;
    }
    if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) {
        /* Variable symbols cannot be exports or globals */
        Error ("Var symbol `%m%p' cannot be an export or global symbol", GetSymName (S));
        return;
    }
    if (S->Flags & SF_DEFINED) {
        /* Multiple definition. In case of a variable, this is legal. */
        if ((S->Flags & SF_VAR) == 0) {
            Error ("Symbol `%m%p' is already defined", GetSymName (S));
            S->Flags |= SF_MULTDEF;
            return;
        } else {
            /* Redefinition must also be a variable symbol */
            if ((Flags & SF_VAR) == 0) {
                Error ("Symbol `%m%p' is already different kind", GetSymName (S));
                return;
            }
            /* Delete the current symbol expression, since it will get
            ** replaced
            */
            FreeExpr (S->Expr);
            S->Expr = 0;
        }
    }

    /* Map a default address size to a real value */
    if (AddrSize == ADDR_SIZE_DEFAULT) {
        /* ### Must go! Delay address size calculation until end of assembly! */
        ExprDesc ED;
        ED_Init (&ED);
        StudyExpr (Expr, &ED);
        AddrSize = ED.AddrSize;
        ED_Done (&ED);
    }

    /* Set the symbol value */
    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.
    */
    if (Flags & SF_VAR) {
        SymReplaceExprRefs (S);
    }

    /* If the symbol is marked as global, export it. Address size is checked
    ** below.
    */
    if (S->Flags & SF_GLOBAL) {
        S->Flags = (S->Flags & ~SF_GLOBAL) | SF_EXPORT;
        ReleaseFullLineInfo (&S->DefLines);
    }

    /* Mark the symbol as defined and use the given address size */
    S->Flags |= (SF_DEFINED | Flags);
    S->AddrSize = AddrSize;

    /* Remember the line info of the symbol definition */
    GetFullLineInfo (&S->DefLines);

    /* If the symbol is exported, check the address sizes */
    if (S->Flags & SF_EXPORT) {
        if (S->ExportSize == ADDR_SIZE_DEFAULT) {
            /* Use the real size of the symbol */
            S->ExportSize = S->AddrSize;
        } else if (S->AddrSize > S->ExportSize) {
            /* We're exporting a symbol smaller than it actually is */
            Warning (1, "Symbol `%m%p' is %s but exported %s",
                     GetSymName (S), AddrSizeToStr (S->AddrSize),
                     AddrSizeToStr (S->ExportSize));
        }
    }

    /* If this is not a local symbol, remember it as the last global one */
    if ((S->Flags & SF_LOCAL) == 0) {
        SymLast = S;
    }
}
コード例 #8
0
ファイル: segment.c プロジェクト: Aliandrana/snesdev
void SegCheck (void)
/* Check the segments for range and other errors */
{
    Segment* S = SegmentList;
    while (S) {
     	Fragment* F = S->Root;
     	while (F) {
       	    if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {

                /* We have an expression, study it */
                ExprDesc ED;
                ED_Init (&ED);
                StudyExpr (F->V.Expr, &ED);

                /* Try to simplify it before looking further */
                F->V.Expr = SimplifyExpr (F->V.Expr, &ED);

                /* Check if the expression is constant */
                if (ED_IsConst (&ED)) {

       	       	    /* The expression is constant. Check for range errors. */
     	       	    int Abs = (F->Type != FRAG_SEXPR);
                    long Val = ED.Val;
     	       	    unsigned I;

     	       	    if (F->Len == 1) {
     	       	   	if (Abs) {
     	       	   	    /* Absolute value */
     	       	   	    if (Val > 255) {
     	       	       	     	PError (&F->Pos, "Range error (%ld not in [0..255])", Val);
     	       	   	    }
     	       	   	} else {
     	     	   	    /* PC relative value */
     	     	   	    if (Val < -128 || Val > 127) {
     	       	       	     	PError (&F->Pos, "Range error (%ld not in [-128..127])", Val);
     	     	   	    }
     	     	   	}
     	       	    } else if (F->Len == 2) {
     	     	    	if (Abs) {
     	     	   	    /* Absolute value */
     	     	   	    if (Val > 65535) {
     	       	       	     	PError (&F->Pos, "Range error (%ld not in [0..65535])", Val);
     	     	   	    }
     	     	   	} else {
     	     	   	    /* PC relative value */
     	     	   	    if (Val < -32768 || Val > 32767) {
     	       	       	     	PError (&F->Pos, "Range error (%ld not in [-32768..32767])", Val);
     	       		    }
     	     		}
     	     	    }

                    /* We don't need the expression tree any longer */
                    FreeExpr (F->V.Expr);

     	     	    /* Convert the fragment into a literal fragment */
     	     	    for (I = 0; I < F->Len; ++I) {
     	     	       	F->V.Data [I] = Val & 0xFF;
     	     	       	Val >>= 8;
     	     	    }
     	     	    F->Type = FRAG_LITERAL;

     	     	} else if (ED.AddrSize != ADDR_SIZE_DEFAULT) {

     	     	    /* We cannot evaluate the expression now, leave the job for
     	     	     * the linker. However, we can check if the address size
                     * matches the fragment size, and we will do so.
     		     */
                    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)) {
     	       	        PError (&F->Pos, "Range error");
     	     	    }
     		}

                /* Release memory allocated for the expression decriptor */
                ED_Done (&ED);
     	    }